notes on http2 draft

Patrick McManus <> Tue, 21 May 2013 15:04 UTC

Return-Path: <>
Received: from localhost (localhost []) by (Postfix) with ESMTP id 9EF4F21F986A for <>; Tue, 21 May 2013 08:04:20 -0700 (PDT)
X-Virus-Scanned: amavisd-new at
X-Spam-Flag: NO
X-Spam-Score: -9.402
X-Spam-Status: No, score=-9.402 tagged_above=-999 required=5 tests=[AWL=0.573, BAYES_00=-2.599, FM_FORGED_GMAIL=0.622, HTML_MESSAGE=0.001, RCVD_IN_DNSWL_HI=-8]
Received: from ([]) by localhost ( []) (amavisd-new, port 10024) with ESMTP id Ft3Nd2TdKW9G for <>; Tue, 21 May 2013 08:04:15 -0700 (PDT)
Received: from ( []) by (Postfix) with ESMTP id 05F5321F9862 for <>; Tue, 21 May 2013 08:04:14 -0700 (PDT)
Received: from lists by with local (Exim 4.72) (envelope-from <>) id 1Ueo5G-0004Mq-U5 for; Tue, 21 May 2013 15:02:38 +0000
Resent-Date: Tue, 21 May 2013 15:02:38 +0000
Resent-Message-Id: <>
Received: from ([]) by with esmtp (Exim 4.72) (envelope-from <>) id 1Ueo50-0004Km-HA for; Tue, 21 May 2013 15:02:22 +0000
Received: from ([]) by with esmtps (TLS1.0:RSA_ARCFOUR_SHA1:16) (Exim 4.72) (envelope-from <>) id 1Ueo4x-0000mW-RX for; Tue, 21 May 2013 15:02:22 +0000
Received: by with SMTP id wp18so841982obc.21 for <>; Tue, 21 May 2013 08:01:54 -0700 (PDT)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;; s=20120113; h=mime-version:sender:date:x-google-sender-auth:message-id:subject :from:to:content-type; bh=9rocHGpStVy83ztmc9U3P8i5Pu7tBi36zhVSweI1UGI=; b=uGjE7MQoEH/FcYa9s1Hw2cqVJxsqfIkOhzRHuofdrZ6bSYsLf+XoIrRc5Uru5ngHgb e/nQ91Hh5dxoEGFjHWTOKKmtg+RgZorcw3rG1uZMSC7RiRTKoW57MBTk0Urjb2/XbD// fkIn3PM+pFLlqCyeYWy5YULKo3FyG3Au7Tu/I8pcdGKZKlIRsY4ktH2m5/7HJ6bJZNLe pkCmvZA2N6vl4nRuR6DmdjViyT1v1xWLaoLmQy65GDbBl72v44inbX6bkF63yAwQ4/He hc56IWnyZsipnJdzpNgmIMXOBo+40MDrvsjeXOX8Crn2l2YTBhcZO0/QbHi7D8FbIJzJ A0Ew==
MIME-Version: 1.0
X-Received: by with SMTP id z1mr1689400oem.134.1369148513861; Tue, 21 May 2013 08:01:53 -0700 (PDT)
Received: by with HTTP; Tue, 21 May 2013 08:01:53 -0700 (PDT)
Date: Tue, 21 May 2013 11:01:53 -0400
X-Google-Sender-Auth: SwrQYWrJEDw-6nFwpfIiaJlGguw
Message-ID: <>
From: Patrick McManus <>
To: HTTP Working Group <>
Content-Type: multipart/alternative; boundary=001a11c2103ed0452f04dd3bba24
Received-SPF: pass client-ip=;;
X-W3C-Hub-Spam-Status: No, score=-3.3
X-W3C-Hub-Spam-Report: AWL=-2.637, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, FREEMAIL_FROM=0.001, HTML_MESSAGE=0.001, RCVD_IN_DNSWL_LOW=-0.7, SPF_PASS=-0.001
X-W3C-Scan-Sig: 1Ueo4x-0000mW-RX b666ca4a292e9c53cb9c725151632e2d
Subject: notes on http2 draft
Archived-At: <>
X-Mailing-List: <> archive/latest/18048
Precedence: list
List-Id: <>
List-Help: <>
List-Post: <>
List-Unsubscribe: <>

Hi All - While I've certainly closely followed the deltas to the http/2
draft I haven't actually sat down and read the thing end to end in a while.
As I have a conflict and won't be able to join you all in CA in June, I sat
down today  to do a full read through and have some feedback on the current
state of the draft. There is a mixture of pure editorial here as well as
some more subtstantive opinion stuff.

First, I want to say thanks to the editors - overall this document is great
progress in terms of readbility and organization.
*Section 1.
*Furthermore, HTTP/1.1 header fields are often repetitive and verbose,
which, in addition to generating more or larger network packets, can cause
the small initial TCP congestion window to quickly. This can result in
excessive latency when multiple requests are made on a new TCP connection.*

Furthermore, HTTP/1.1 header fields are often repetitive and verbose,
which, in addition to generating more or larger network packets, can cause
the small initial TCP congestion window to quickly fill. This can result in
excessive latency when multiple requests are made on a single new TCP

message:**A complete sequence of frames.*

I'm not sure that does a lot for me as a definition. It should at least say
something about them sharing the same stream ID.. or am I describing a
stream? Is a message a unidirectional stream? as I said.. it doesn't do a
lot as a definition. The document refers to "window update messages" and
"goaway messages" but I think it means frames in those cases.. it also
talks about "receiver of a message" sending WINDOW_UPDATE which makes it
sound like a message is any data frame (not the complete sequence of
them)... and then again we also talk about "HTTP Messages" which are
something distinct..

I suggest we scrub the term message from the document (and this section)
except when it refers to HTTP messages.

3.2 Connection Magic

Can we make that bikeshed a multiple of 4 bytes long to at least
conveniently align the SETTINGS frame that follows?


* Implementations MUST ignore unsupported and unrecognized frame types. *

I think invalid frame types should be session errors of the MUST NOT send
variety. I know the list has been talking about this lately and I haven't
had an opportunity to chime in. Be liberal in what you receive is overrated
and often fraught with security problems - we can rev the protocol with
ALPN at Internet scale in order to sanely guide extensions as needed. I
know design committees love open ended extensions so my view won't pervail,
but this is exactly the kind of thing that leads to interop doom.


*Implementations with limited resources might not be capable of processing
large frame sizes. Such implementations MAY choose to place additional
limits on the maximum frame size. However, all implementations MUST be
capable of receiving and processing frames containing at least 8192 octets
of data.
I'm pretty confident we are just inventing complexity here for no good
reason. The tiny universe of implementations that can cope with 8KB but not
64KB is not worth the complexity. One of the advantages of going with a 16
bit frame size is that it should be small enough for everything to handle

If there is reason to believe 64KB is too big for a population large enough
to care about (remembering of course that HTTP/2 is not a ticket to
Internet admission - if you're really so small that you can't read 64KB
frames the muxing of HTTP/2 is going to be a real challenge too; you're
probably best left using a different protocol. Just coap :)), then let's
lower the max frame size instead of reinventing Path MTU Discovery
complexity. But I think we can just drop this section and require everyone
to deal with 64KB.


*A "stream" is an independent, bi-directional sequence of frames*

Due to the (expected) compression requirements the frames aren't really
independent of other streams. I know this mistake comes up pretty commonly
on spdy-dev from new implementers of that protocol, so it probably helps to
avoid saying independent here. (section 5.3 does it too).


*Rather, new streams are established by sending a frame whose stream
identifier field references a previously unused stream identifier. *

That's a little too loose. Streams are created by the client through
HEADERS+PRIORITY (4.2.2) and by the server through PUSH_PROMISE. The text
as-is makes it sound more free flowing than that.

*The identifier of a newly established stream MUST be numerically greater
than all previously established streams from that endpoint within the
HTTP/2.0 connection, unless the identifier has been reserved using a
PUSH_PROMISE (Section 3.8.5<>)

Likewise, PUSH_PROMISE really creates the stream (4.3.1) from the server..
I don't see a reason for the caveat here.


I thought one of the takeaways at Tokyo was to define a change-priority
frame.. Can we do that now? is the intention to use a H+P without any
headers at any point in the stream? If so, I think that should be called
out so that server implementation's don't freak out at seeing H+P at
strange points in the stream.. and I think there is some language in 4.2.2
that could be interpreted as meaning certain colon headers are required to
be in every H+P


*The PUSH_PROMISE frame (type=0x5) is used to notify the peer endpoint in
advance of streams the sender intends to initiate.*

I think I must have missed something on list about this. Why is the
language here general (peer, sender).. why define this so that clients can
generate PUSH_PROMISE ?

*After a receiver reads in a frame that marks the end of a stream (for
example, a data stream with a FINAL flag set), it ceases transmission of
WINDOW_UPDATE frames. A sender is not required to maintain the available
flow control window for streams that it is no longer sending on. *

First - since this is a spec, that should be "it MAY/SHOULD/MUST cease
transmission of WINDOW_UPDATE frames". I suggest MUST.

Second - The language isn't clear if this applies to session windows or
just the stream window. I think it is just the stream window and the
receiver still needs to ack^H^H^HWINDOW_UPDATE the session window after the
FINAL flag, but we should say explicitly.


*User-agents MUST support gzip compression. Regardless of the
Accept-Encoding sent by the user-agent, the server may always send content
encoded with gzip or deflate encoding.
Still valid?]*

I support that still being valid. This is an important performance property
to rely on.

also 4.2.2

*The client initiates a request by sending a HEADERS+PRIORITY frame [...]
if the server receives a data frame prior to a HEADERS or HEADERS+PRIORITY

I think that means just "prior to a HEADERS+PRIORITY frame" which is what
is required to open the stream...

*The server responds to a client request using the same stream identifier
that was used by the request. An HTTP response begins with a HEADERS frame.
[...] If the client receives a data frame prior to a HEADERS or

Again, I think that means "prior to a HEADERS" [NOT "or H+P"]. Can server's
send H+P frames? If so, why? and if there is a compelling why, why can't
the response begin with H+P?

hope that helps.