Subject: CONTINUATION Frame Size

From: James M Snell <[email-masked]>
Date: Mon, 12 Aug 2013 16:11:05 -0700

https://github.com/http2/http2-spec/issues/229

Because sequences of header continuations are required to be
contiguous without any interleaving or multiplexing or whatnot... it
really does not make sense to limit CONTINUATION frames carrying HTTP
headers to 16383 octets, as that needlessly just increases the
encoding overhead for continuations. If the END_HEADERS flag is not
set, we ought to allow frame sizes up to the maximum allowed (65,535)
to eliminate this additional overhead.

- James

---

From: Martin Thomson <[email-masked]>
Date: Tue, 13 Aug 2013 00:32:00 +0100

On 13 August 2013 00:11, James M Snell <[email-masked]> wrote:
> If the END_HEADERS flag is not

Interesting observation.  Would you make the same allowance for
HEADERS and PUSH_PROMISE too?  Those are actually more likely to need
this.

That said, I'm not certain that I want this, it seems like an another
set of if() statements that could be avoided.  After all, we
determined that the framing overhead was tolerable.  And it's not like
we want to *encourage* the use of big headers.

---

From: James M Snell <[email-masked]>
Date: Mon, 12 Aug 2013 16:57:07 -0700

> HEADERS and PUSH_PROMISE too?  Those are actually more likely to need

No, I would keep HEADERS and PUSH_PROMISE as is.. I considered that,
but we really don't want to encourage use of big headers as you say..
a HEADERS or PUSH_PROMISE for HTTP ought to be limited to 16k and
ought to require CONTINUATION frames for anything above that limit,
but the CONTINUATION frames ought to be allowed to extend to 65k to
avoid the additional encoding overhead ... this balances the concerns
and ought not cause any problems (the code we have for parsing
continuation frames would actually get to omit an if statement...
;-)...)

- James

---

From: Roberto Peon <[email-masked]>
Date: Mon, 12 Aug 2013 17:08:04 -0700

The secondary benefit of having a limit small enough to deal with
serialization delays for DATA frames is that the continuation stuff will be
regularly-enough exercised for HEADERS that we'll have confidence that it
works.
This is a significant benefit-- getting bugs out of something like this is
not a small thing in terms of importance. The overhead here is pretty
insignificant...
-=R

---

From: James M Snell <[email-masked]>
Date: Mon, 12 Aug 2013 17:17:29 -0700

Hmm... I'm not so sure that "having smaller sizes means our
subroutines run more often" is really all that great of a
justification for a protocol design. Also, I'm not sure I follow what
you're saying with regards to DATA frames given that those don't have
anything to do with CONTINUATION (unless I'm missing something).

Right now, if I have 49,149 octets worth of header data, I'm required
to write out three frames, with 24-bytes of overhead; with this change
I would write out two frames with 16-bytes of overhead. Sure, it's
only an 8-byte difference but I still doubt "squashing bugs" is really
a significant consideration here.

---

From: Patrick McManus <[email-masked]>
Date: Mon, 12 Aug 2013 20:28:00 -0400

headers that don't fit in the base frame, especially with compression, are
an outside edge case. Its an important edge case to have an answer for so
that we can maintain HTTP/1 gateways and such cases do indeed exist, but
from a performance standpoint its definitely an uninteresting edge case. It
doesn't make sense to me to create an exception in order to optimize that.

If we thought it was more than an edge case then we would need to rethink
the multiplexing rules for them, rather than carving out exceptions for
large frames, because massive headers will interfere with prioritization.
But in the end its not worth it because the continuation frame is really
just there for correctness.

-P

---

From: "Manger, James H" <[email-masked]>
Date: Tue, 13 Aug 2013 11:13:10 +1000

> contiguous without any interleaving or multiplexing or whatnot...

The solution isn't to allow CONTINUATION frames to be bigger.
The solution is to fix the compression so it doesn't prevent
interleaving with frames from other streams.

--
James Manger

---

From: James M Snell <[email-masked]>
Date: Mon, 12 Aug 2013 18:21:52 -0700

To be certain, I agree with you 100%... however, I've been told that
wasn't an option and that continuation frames MUST be contiguous...
although I personally don't buy it.

---

From: Martin Thomson <[email-masked]>
Date: Tue, 13 Aug 2013 18:00:03 +0100

On 13 August 2013 02:21, James M Snell <[email-masked]> wrote:
> I've been told that [HEADERS interleaving]

As long as HEADERS depend on some sort of state, then it is easier to
require exclusive access to that state (mutex style) rather than deal
with potential concurrency issues.  Until it is proven otherwise, it
might be reasonable to assume that any scheme permitting interleaving
is only going to be more complicated than the current scheme.  I am,
of course, happy to be shown a scheme that enables interleaving
without increasing complexity.

---

From: "Manger, James H" <[email-masked]>
Date: Wed, 14 Aug 2013 16:24:52 +1000

> > I've been told that [HEADERS interleaving] wasn't an option and that
> > continuation frames MUST be contiguous...
From: Martin Thomson [mailto:[email-masked]]
> is only going to be more complicated than the current scheme.  I am, of
> course, happy to be shown a scheme that enables interleaving without
> increasing complexity.

A mutex on HEADERS state should not prevent interleaving with DATA on other streams.

Even a mutex feels unnecessary. Break a huge header (lots of name/value pairs) into parts (each part is still a collection of name/value pairs so it looks like a header); then send the parts using the compress-into-a-frame process. Now interleaving around a frame for a part has no more restrictions than interleaving around a frame for a complete header.

There is one extra complexity: to support single header name/value pairs that can't fit in a frame.

--
James Manger

---

From: Martin Thomson <[email-masked]>
Date: Wed, 14 Aug 2013 17:37:09 +0100

> There is one extra complexity: to support single header name/value pairs that can't fit in a frame.

That's the problem that the current scheme chooses to solve, not the
other.  The compress-into-a-frame with separate frames is more
complicated.  (I'll admit, not by much, but then some is always
greater than none.)

Here's my understanding of how we reached the current design:  We
don't want headers to overflow their allocated space.  Nor do we
expect them to for most uses of the protocol.  It's an edge case.  We
acknowledge the need to accommodate these edge cases, but the
complexity overhead any accommodation imposes has to be the absolute
minimum.