- From: Matthew Kerwin <matthew@kerwin.net.au>
- Date: Mon, 1 Sep 2014 11:57:48 +1000
- To: Greg Wilkins <gregw@intalio.com>
- Cc: "Roy T. Fielding" <fielding@gbiv.com>, HTTP Working Group <ietf-http-wg@w3.org>
- Message-ID: <CACweHNCZGnDuFkGtkSv3i1yM-qiEjZ4ZrPCdf2g-VX8YEcjsXQ@mail.gmail.com>
On 1 September 2014 10:34, Greg Wilkins <gregw@intalio.com> wrote: > > On 1 September 2014 09:34, Matthew Kerwin <matthew@kerwin.net.au> wrote: > >> Repeating myself again, but: what do you think of an option C: remove >> Flags from the general frame header, and add individual Flags fields to >> whichever frame types require them? > > > Matthew, in general I think the framing layer should only know about > framing concerns and should be neutral towards any semantics conveyed in > the frame payloads. So in principal, yes I agree than general flags (and > probably frame types other than those needed by framing) can easily be put > into the payload. > > However, END_STREAM is a-priori a framing concern, so I don't think it > should be moved to the frame payload or be a function of frame type. I > would have preferred the framing layer was designed without HTTP semantic > knowledge and was able to transport arbitrary bidirection flow controlled > streams, perhaps with segments defined so that > flushing/forwarding/segmentation behaviour can be guaranteed to a level > needed. Other than what is required to achieve that, I see no reason > that the framing layer should know any more about what it is transporting, > even to the extent that it really should not know the difference between a > header and data frame. > > tl;dr: see the diagram below Allow me to try to reconstruct what you're saying via my thought processes: If the framing machine were frame-type-agnostic, all frame types could carry the END_STREAM flag, but it would only have meaning when associated with a non-zero stream id. Of those types that can have a non-zero stream id: * DATA and HEADERS define an END_STREAM flag. * PRIORITY, RST_STREAM, PUSH_PROMISE and WINDOW_UPDATE don't. * CONTINUATION is snafu so I'm not touching it Of those that don't define the flag, it could be argued that it's because it doesn't make much sense; RST_STREAM can't *not* end the stream, and a WINDOW_UPDATE or PP that does is silly. Maybe there's some small value in the case of PRIORITY, but it still smells a bit silly. So in theory we could reword the spec to say: the flag is defined and MUST be zero -- which may add more validation requirements to the receivers, but it doesn't change the general thrust of framing/streams. Thus, at one level of thinking we can say that all frame types that have a non-zero stream id define the END_STREAM flag, so we're on our way to writing a generic framer that doesn't need to delve too deeply into the types. Except that SETTINGS and PING have an ACK flag that occupies the same bit as the END_STREAM flag. So the framer has to inspect either the frame type or maybe the stream id before it can interpret the flag. So it's not generic. To move things forward we could borrow from Roy's option B and move the END_STREAM bit from Flags to somewhere else, and then use my option C and move the remaining flags to the payload. Since both END_STREAM and Stream Identifier are stream-related parameters, and we happen to have a reserved bit sitting right at the top of the stream identifier, why not shove END_STREAM there? I'll note that our generic framer may still have some responsibility in inspecting END_HEADERS and barfing on bad CONTINUATIONing, but that whole mess is, as I said earlier, AFU, so whatever. But at least with this proposal, continuation becomes the only exception to an otherwise fairly sensible system. tl;dr: ``` 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 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Type (8) | Length (24) | +-+-------------+-----------------------------------------------+ |E| Stream Identifier (31) | +=+=============================================================+ | Frame Payload (0...) ... +---------------------------------------------------------------+ Frame Layout The fields of the frame header are defined as: Length: The length of the frame payload expressed as an unsigned 24-bit integer. Values greater than 214 (16,384) MUST NOT be sent unless the receiver has set a larger value for SETTINGS_MAX_FRAME_SIZE. The 8 octets of the frame header are not included in this value. Type: The 8-bit type of the frame. The frame type determines the format and semantics of the frame. Implementations MUST ignore and discard any frame that has a type that is unknown. E: This bit being set indicates that this frame is the last that the endpoint will send for the identified stream. Setting this flag causes the stream to enter one of the "half closed" states or the "closed" state (Section 5.1). This bit MUST remain unset (0) when sending unless explicitly allowed by the frame type definition. Stream Identifier: A 31-bit stream identifier (see Section 5.1.1). The value 0 is reserved for frames that are associated with the connection as a whole as opposed to an individual stream. The structure and content of the frame payload is dependent entirely on the frame type. ``` ...and move the frame field (minus END_STREAM) to the payload, if and when it's required. -- Matthew Kerwin http://matthew.kerwin.net.au/
Received on Monday, 1 September 2014 01:58:17 UTC