Subject: Comments on draft-ietf-httpbis-http2-04

From: Michael Sweet <[email-masked]>
Date: Tue, 09 Jul 2013 13:12:19 -0400

All,

A couple quick comments on draft-ietf-httpbis-http2-04...

In section 8.1.1 Examples I see the following:

   All HTTP Requests that include a body SHOULD include the "content-
   length" header field.  If a server receives a request where the sum
   of the DATA frame payload lengths does not equal the value of the
   "content-length" header field, the server MUST return a 400 (Bad
   Request) error.

I am uncomfortable with this wording primarily because a lot of POST usage consists of streamed content - my particular interest is obviously printing, but any streamed content will necessarily not be able to provide a content-length header field. So instead I would suggest the following two paragraphs instead:

    All HTTP requests that include a body of known length MUST include the "content-length" header field. If a server receives a request where the sum of the DATA frame payload lengths does not equal the value of the "content-length" header field, the server MUST return a 400 (Bad Request) error.

    All HTTP requests that include a body of unknown length MUST NOT include the "content-length" header field. Servers MUST support receiving requests without a "content-length" header field and MUST return a 413 (Request Entity Too Large) error if the body is too large to process.

This clearly defines how clients stream content to servers and defines the error handling required.  And it makes the conformance requirements less squishy...

My other comment is that I don't see any discussion of the Expect header, nor do I see a issue on Github... But this is something that gets used extensively in printing to avoid sending gigabytes of print data to a printer that needs authentication for certain operations...  Perhaps something to add to section 8.1.1, e.g.:

Use of Expect with 100 (Continue) response:

    POST /ipp/print HTTP/1.1            HEADERS
    Host; printer.example.org      ==>    - END_STREAM
    Content-Type: application/ipp         + END_HEADERS
    Transfer-Encoding: chunked              :method = post
    Expect: 100-continue                    :scheme = ipp
                                            :host = printer.example.org
                                            :path = /ipp/print
                                            content-type = application/ipp
                                            expect = 100-continue

    HTTP/1.1 100 Continue          ==>  HEADERS
                                          - END_STREAM
                                          + END_HEADERS
                                            :status = 100

    {binary data from client}      ==>  DATA
                                          + END_STREAM
                                            {binary data}

    HTTP/1.1 200 OK                ==>  HEADERS
    Content-Type: application/ipp         - END_STREAM
    Transfer-Encoding: chunked            + END_HEADERS
                                            :status = 200
    {binary data from server}               content-type = application/ipp

                                        DATA
                                          + END_STREAM
                                            {binary data}

Failed response needing authentication:

    POST /ipp/print HTTP/1.1            HEADERS
    Host; printer.example.org      ==>    - END_STREAM
    Content-Type: application/ipp         + END_HEADERS
    Transfer-Encoding: chunked              :method = post
    Expect: 100-continue                    :scheme = ipp
                                            :host = printer.example.org
                                            :path = /ipp/print
                                            content-type = application/ipp
                                            expect = 100-continue

    HTTP/1.1 401 Unauthorized      ==>  HEADERS
    Content-Type: text/html               - END_STREAM
    Content-Length: 123                   + END_HEADERS
    WWW-Authenticate: Basic ...             :status = 401
                                            www-authenticate = Basic ...
    {HTML error message from server}

Then we'd also need a clarification in section 8.1.3 to allow a single HEADERS response frame with :status = 100.

_________________________________________________________
Michael Sweet, Senior Printing System Engineer, PWG Chair

---

From: Martin Thomson <[email-masked]>
Date: Tue, 9 Jul 2013 12:40:24 -0700

On 9 July 2013 10:12, Michael Sweet <[email-masked]> wrote:
> I am uncomfortable with this wording primarily because a lot of POST usage
> consists of streamed content - my particular interest is obviously printing,
> but any streamed content will necessarily not be able to provide a
> content-length header field. So instead I would suggest the following two
> paragraphs instead:

I think that your edits capture the spirit of what was intended by the
existing text, with far less ambiguity.  Unless I get objections,
those can be integrated.

> My other comment is that I don't see any discussion of the Expect header,
> nor do I see a issue on Github...

There was a brief discussion at the last interim.  The feature is in
serious jeopardy.  See #18:
https://github.com/http2/http2-spec/issues/18

---

From: Jeff Pinner <[email-masked]>
Date: Tue, 9 Jul 2013 12:50:33 -0700

I would prefer we say something to the effect of:

If a server receives a request with a "Content-Length" header and
the sum of the DATA frame payload lengths does not equal the value
of the "content-length" header field, the server MUST return a 400 (Bad
Request) error.

and remove any other MUSTs and SHOULDs. By the way, I would like to note
that this is different than how the HTTP/1.1 spec handles
Tranfser-Encoding. From RFC2616 Sec 4.4:

If a message is received with both a Transfer-Encoding header field and a
Content-Length header field, the latter MUST be ignored.

- Jeff

---

From: Michael Sweet <[email-masked]>
Date: Tue, 09 Jul 2013 16:35:46 -0400

Martin,

On Jul 9, 2013, at 3:40 PM, Martin Thomson <[email-masked]> wrote:
> ...

Not much discussion there; adding my comments...

An alternative is to simply do away with it and have the server respond as soon as it wants with the 401 status - with flow control the client won't get too far ahead of the server, and with streams we don't have to deal with the expense of closing the connection and bringing a new one up (something that you need to do with HTTP/1.1 if Expect isn't supported by the server...)

Either way we should say something about it to give guidance/recommendations on HTTP/1.1 solutions that are adding support for HTTP/2.0...

---

From: Michael Sweet <[email-masked]>
Date: Tue, 09 Jul 2013 16:45:30 -0400

Jeff,

There is a long history of HTTP/1.1 servers that did not support Transfer-Encoding: chunked, and the PWG and others have spent a good 15 years harassing those (non-) implementors to get them to conform so we can do something other than print static files... :/

So whether or not we have MUSTs in the sentence, I think it is important to clearly identify the migration path from HTTP/1.1 chunking to HTTP/2.0 frames.  Making the jump from HTTP/1.1 to HTTP/2.0 will be a major effort for most vendors, and given past performance I'd like to avoid any ambiguous language that leads to implementation bugs and interoperability issues - it makes for some messy code when such mistakes are put in ROMs that can't be updated...

On Jul 9, 2013, at 3:50 PM, Jeff Pinner <[email-masked]> wrote:

> and remove any other MUSTs and SHOULDs. By the way, I would like to note that this is different than how the HTTP/1.1 spec handles Tranfser-Encoding. From RFC2616 Sec 4.4:
> 
> If a message is received with both a Transfer-Encoding header field and a Content-Length header field, the latter MUST be ignored.
> 
> - Jeff
> 
> 
> On Tue, Jul 9, 2013 at 12:40 PM, Martin Thomson <[email-masked]> wrote:

---

From: Jeff Pinner <[email-masked]>
Date: Tue, 9 Jul 2013 13:59:08 -0700

I am all for adding text to the "Additional HTTP
Requirements/Considerations" sections that discuss how to upgrade from
HTTP/1.1 to HTTP/2.0, including what to do about how to handle specific
headers, Expect and Content-Length / Transfer-Encoding included. This would
be useful not just to implementers migrating to HTTP/2.0 but also to
proxies that upgrade/downgrade the protocol version.

That being said, the requirements around Message Length in HTTP/1.1 are
non-trivial and given that we want to support interoperability, I'd like to
minimize adding additional requirements (especially those with conflicting
semantics) in the HTTP/2.0 spec.

P.S. the httpbis messaging draft states:

If a message is received with both a Transfer-Encoding and a
       Content-Length header field, the Transfer-Encoding overrides the
       Content-Length.  Such a message might indicate an attempt to
       perform request or response smuggling (bypass of security-related
       checks on message routing or content) and thus ought to be
       handled as an error.  A sender MUST remove the received Content-
       Length field prior to forwarding such a message downstream.

it would be nice to strengthen that language so that it matches the
new HTTP/2.0 requirement.

On Tue, Jul 9, 2013 at 1:45 PM, Michael Sweet <[email-masked]> wrote:

> Jeff,
>
> There is a long history of HTTP/1.1 servers that did not support
> Transfer-Encoding: chunked, and the PWG and others have spent a good 15
> years harassing those (non-) implementors to get them to conform so we can
> do something other than print static files... :/
>
> So whether or not we have MUSTs in the sentence, I think it is important
> to clearly identify the migration path from HTTP/1.1 chunking to HTTP/2.0
> frames.  Making the jump from HTTP/1.1 to HTTP/2.0 will be a major effort
> for most vendors, and given past performance I'd like to avoid any
> ambiguous language that leads to implementation bugs and interoperability
> issues - it makes for some messy code when such mistakes are put in ROMs
> that can't be updated...
>
>

---

From: Julian Reschke <[email-masked]>
Date: Wed, 10 Jul 2013 13:33:12 +0200

On 2013-07-09 22:59, Jeff Pinner wrote:
> headers, Expect and Content-Length / Transfer-Encoding included. This
> would be useful not just to implementers migrating to HTTP/2.0 but also
> to proxies that upgrade/downgrade the protocol version.
>
> non-trivial and given that we want to support interoperability, I'd like
> to minimize adding additional requirements (especially those with
> conflicting semantics) in the HTTP/2.0 spec.
>
> it would be nice to strengthen that language so that it matches the new HTTP/2.0 requirement.
> ...

My 2 cents: HTTPbis says what it says based on a long discussion of the 
topic. IMHO simply saying "should be aligned with whatever 2.0 says" is 
not sufficient to change that.

Best regards, Julian

---

From: Jeff Pinner <[email-masked]>
Date: Wed, 10 Jul 2013 07:42:58 -0700

Julian, if you recall (or have easily accessible) I'd love to hear the
rational for the "ought to be handled as an error" line as opposed to a
"SHOULD return a 400" or "MUST return a 400."

Perhaps it is due to some subtlety that should lead us to reconsider the
2.0 requirement? Or perhaps it is due to legacy implementations and it
could guide us in wording to add to a HTTP/1.1 <--> HTTP/2.0 section?

- Jeff

On Wed, Jul 10, 2013 at 4:33 AM, Julian Reschke <[email-masked]>wrote:

> topic. IMHO simply saying "should be aligned with whatever 2.0 says" is not
> sufficient to change that.
>
> Best regards, Julian
>

---

From: Julian Reschke <[email-masked]>
Date: Wed, 10 Jul 2013 16:53:59 +0200

> could guide us in wording to add to a HTTP/1.1 <--> HTTP/2.0 section?

Generally, when we say "ought to" it's because it's a really good idea, 
but for some reason we really can't require it. In this particular case 
I suspect that it's a problem common enough so that existing UAs simply 
can't enforce it (the error handling).

Best regards, Julian

---

From: Martin Thomson <[email-masked]>
Date: Wed, 10 Jul 2013 09:55:11 -0700

> sufficient to change that.

If there is any aligning to do, HTTP/2.0 is definitely where the
changes will occur.  No question.

However, we don't need to inherit the baggage of HTTP/1.1.  HTTP/2.0
can tighten up these constraints.  At least for now, we can be
completely intolerant of buggy software.  The current text, with
adjustments to wording much like Jeff or Michael have suggested, seems
in line with that philosophy.