h2 frame layout

This comment is in reference to section 4.1 of

  http://tools.ietf.org/id/draft-ietf-httpbis-http2-14.txt

> 4.1.  Frame Format
> 
>    All frames begin with a fixed 9-octet header followed by a variable-
>    length payload.
> 
>      0                   1                   2                   3
>      0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
>     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
>     |                 Length (24)                   |
>     +---------------+---------------+---------------+
>     |   Type (8)    |   Flags (8)   |
>     +-+-+-----------+---------------+-------------------------------+
>     |R|                 Stream Identifier (31)                      |
>     +=+=============================================================+
>     |                   Frame Payload (0...)                      ...
>     +---------------------------------------------------------------+
> 
>                                Frame Layout

I think this has become a bit moth-eaten over time as the WG has
adjusted field lengths and perhaps added or removed a few.
I also find the use of a bit array with magic gaps to be editorially
bizarre, but this message is about the actual bits.

I should be shocked that folks are "not concerned" about the use
of a 9-octet header and the resulting effect on data alignment, but it
is true that it won't matter much to character-oriented Web traffic.
Nevertheless, I'd expect HTTP/2 to at least make an effort here
given the number of APIs that don't process character traffic.

Looking at the current spec, I think we can do better.

  1) There are only 10 defined frame types and 2 useful flags.
  2) The length is the most random of these fields and used last.
  3) The stream identifier is the least random and used first.
  4) Why are we reserving the high bit of an unsigned field?

My suggestion is that the frame layout be changed to either

  0                   1                   2                   3
  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 |                   Stream Identifier (32)                      |
 +---------------+-----------------------------------------------+
 |Type(4)|Flag(4)|   Payload Length (24)                         |
 +=+=============================================================+
 |                   Frame Payload (0...)                      ...
 +---------------------------------------------------------------+

or

  0                   1                   2                   3
  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 |                   Stream Identifier (32)                      |
 +---------------+-----------------------------------------------+
 | Frame Type(8) |   Payload Length (24)                         |
 +=+=============================================================+
 |                   Frame Payload (0...)                      ...
 +---------------------------------------------------------------+


Rationale for both:

  11% reduction in per-frame overhead
  A fixed 64bit layout is faster to parse than 72bits.
  A sender doesn't have to worry about 64bit alignment.
  A receiver is likely to partition based on stream id first.

Rationale for A:

  If we need more than 6 additional frame types, we might as well
    skip to a new protocol version.
  If we need more than 4 flags per frame, we should use another type.
  The useful flags are END_STREAM and END_HEADERS and they could be
    defined in general (independent of frame type).

Rationale for B:

  The current usage of frame flags in spec-14 is frightening.
  In all cases, they can and should be separate frame types.

  END_STREAM:  Orthogonal. Could be moved to the reserved bit or made
    another frame type (an extra 8 bytes at end of stream is better
    than the extra 8 flag bits per frame).

  END_HEADERS: Orthogonal. Could be just another frame type or moved
    to the beginning of the frame payload in Headers, Continuation,
    and Push_Promise.

  PADDED: Padding is just a form of ignored data and should
  be a PADDING type.  We can then remove those optional fields from the
  other frame types.  Optional fields at the beginning of otherwise fixed
  frames is parser hell.

  Header PRIORITY: What do headers have to do with frame priority?
  Why here and not on DATA?  We should instead have different
  frame types for MY_PRIORITY (this is how I am sending/reading) and
  YOUR_PRIORITY (this is how I want you to prioritize sending/reading).
  We can then remove those optional fields from the other frame types.

  Settings ACK: send an ACK frame type instead (and remove the additional
  complexity of processing requirements in the Settings type).

  Ping ACK: send a PONG type.


Alternative A would just make the protocol more efficient and faster to
parse at the cost of some extensibility. B would significantly simplify the
protocol and the spec.  Some combination of the two is also possible
(e.g., 6 bits for type and 2 flag bits for END_STREAM and END_HEADERS).

Alternatively, if END_STREAM is moved to the reserved bit E, then it
would look like:

  0                   1                   2                   3
  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 |E|                 Stream Identifier (31)                      |
 +---------------+-----------------------------------------------+
 | Frame Type(8) |   Payload Length (24)                         |
 +=+=============================================================+
 |                   Frame Payload (0...)                      ...
 +---------------------------------------------------------------+


Yes, I know this suggestion comes late in the process.  I was busy.

Cheers,

Roy T. Fielding                     <http://roy.gbiv.com/>
Senior Principal Scientist, Adobe   <http://www.adobe.com/>

Received on Friday, 29 August 2014 22:50:21 UTC