Re: Stuck in a train -- reading HTTP/2 draft.

On 18/06/2014 11:39 a.m., Matthew Kerwin wrote:
> On 18 June 2014 06:28, Poul-Henning Kamp wrote:
> 
>> Martin Thomson writes:
>>
>>>>> It's also pretty non-obvious why we need CONTINUATION in the
>>>>> first place:  Why not simply send HEADERS until one of them has
>>>>> the END_HEADERS bit set ?
>>>
>>>
>> http://http2.github.io/faq/#why-the-rules-around-continuation-on-headers-frames
>>
>> I'm not asking why we need multiple frames, that's painfully obvious
>> when the cookie mistake is retained.
>>
>> I'm asking why the frames have different names ?
>>
>> Rather than
>>
>>         HEADERS
>>         CONTINUATION * N
>>         CONTINUATION + END_HEADERS
>>
>> I would do
>>
>>         HEADERS * N
>>         HEADERS + END_HEADERS
>>
>> Since I don't see how CONTINUATION differs from HEADERS in any way
>> other way than name and type number.
>>
>>
> Actually, when you account for things like stream dependency (which
> shouldn't be included in continued headers), and continuations on
> PUSH_PROMISE, you end up with:
> 
>     HEADERS
>     [HEADERS - PRIORITY] * N
>     HEADERS - PRIORITY + END_HEADERS
> 
>     PUSH_PROMISE
>     [HEADERS - PRIORITY] * N
>     HEADERS - PRIORITY + END_HEADERS
> 
> That's pretty complicated. I've also ignored padding, which is currently
> not included in CONTINUATION frames. (Note: I've made PP followed by H
> because subsequent PP frames would waste four bytes on the promised stream
> id.)
> 
> 
> Eliminating one frame type would simplify the RFC text and
>> implementations, (Ref: Antoine de Saint Exupéry's wisdom that
>> "Perfection is finally attained not when there is no longer anything
>> to add, but when there is no longer anything to take away.")
>>
>>
> That quote also applies to the DRY principle, and not all of us are
> pretending PUSH_PROMISE doesn't exist.
> 
> 
> 
>>>>> Page 36: SETTINGS synchronization
>>>>> ---------------------------------
>>
>>> That's not true.  You send SETTINGS, you carry on.  You only lose RTTs
>>> if you want to apply tight limits and then open them again.
>>
>> 99% of those ACKs will be ignored.
>>
>> I propose that the remaining 1% could get the exact same functionality
>> by sending SETTINGS + PING and wait for the pong.
>>
>> That means less wasted bandwidth, less RFC text and less implementation
>> source code.
>> ​​
>>
>> And the explicit acknowledgement allows for different implementation
>>> strategies.
>>
>> Using PING to get the acknowledgement and only when the strategy
>> actually calls for an ack, while saving RFC text and source code
>> gives you the same flexibility.
>>
>> ​
> Your preference seems to be for reusing and overloading existing frames,
> while personally I find the current approach (single-purpose, single-use
> frame types) simpler. That's a taste issue, so we're allowed to disagree,
> and neither is "better."
> 
> If you want to prioritise bandwidth, we could add a new "SEND_ACK" flag to
> SETTINGS. It doesn't add much complexity, and it saves traffic on all those
> unneeded 8-byte ACKs.
> 
> Incidentally, PING/PONG costs an extra 16 bytes each way, while
> SETTINGS/ACK costs 0+8, so for the cases where you do care about the
> acknowledgement, ping is a relative waste of bandwidth.
> 
> 
> 
>>>>> Page 51:  To strict ordering ?
>>>>> ------------------------------
>>>>>
>>>>>   Other frames (from any stream) MUST NOT occur between either HEADERS
>>>>>   frame and the following CONTINUATION frames (if present), nor between
>>>>>   CONTINUATION frames.
>>>>>
>>>>> Isn't this needlessly strict ?  No harm would come from DATA frames
>>>>> or SETTING frames being stuffed in there.
>>>>>
>>>>> All this trouble could be avoided by only submitting headers for
>>>>> decompression, as a unit, when the END_HEADERS have been received.
>>>
>>> That creates a nice state exhaustion/denial of service opportunity
>>> that we decided not to permit.
>>
>> I really don't understand that answer:  Buffering the compressed
>> header will take up less space than buffering the uncompressed
>> header ?
>>
>>
> Who's buffering headers? The whole point is that we're streaming them
> through the HPACK context, *not* buffering them.

Most middleware proxies are buffering them un-compressed for the entire
duration of the end-to-end transaction. Having to buffer in compressed
form for a short period of frames is small by comparison.

Particularly given that a) RST_STREAM can be issued as necessary to free
up impatient clients, b) well behaved clients will treat HEADERS and
continuation as a block anyway and not consume resources for long.

> 
> Well, you might be buffering them, if your API emits headers to the
> application in a single blob, rather than streaming them up. That's nothing
> to do with the spec, though.

API - irrelevant.
application - irrelevant.
middleware - very, very relevant.

This is exactly why the protocol design made by browser people for
communication directly to server is seing so may complaints from the
middleware people.

The network substrate over which the HTTP traffic flows has to retain
the header details in parsed form for logging and transaction handling,
caching, failure recovery, etc, etc.


> 
>>>>> Page 51: Gibberish
>>>>> ------------------
>>>>>
>>>>> This needs to be translated to human readable form:
>>>>>
>>>>>   Otherwise, frames MAY be interspersed on the stream between these
>>>>>   frames, but those frames do not carry HTTP semantics.  In particular,
>>>>>   HEADERS frames (and any CONTINUATION frames that follow) other than
>>>>>   the first and optional last frames in this sequence do not carry HTTP
>>>>>   semantics.
>>>
>>> Improved text gratefully accepted.
>>
>> I'd happy attempt if I had any idea what it atttempts to say, but I
>> literally looked a that paragraph for 10 minutes without finding out.
>>
>> If nobody else knows, you should strike it.
>>
>>
> I wouldn't do much to change it, just some minor disambiguation:
> 
> ```
>    ​Otherwise, frames MAY be interspersed on the stream between these
> header blocks and DATA frames, but those interstitial frames do not carry

"these" and "those" is unnecessary methinks.

> HTTP semantics. In particular, interstitial HEADERS frames (and any
> CONTINUATION frames that follow) do not carry HTTP semantics.
> ```
> 
> Personally I'd really like someone to add something there to explain what
> non-semantic metadata _means_, maybe with an example. This could also clear
> up some of my residual issues with segments.
> 


Amos

Received on Wednesday, 18 June 2014 07:02:45 UTC