Re: Distinguishing 0-byte request body in HTTP/2

Hi,

Thank you very much for the clarification.

So to paraphrase, the general rule for handling request body is
defined in section 3.3.3 of RFC 7230 as:

   6.  If this is a request message and none of the above are true, then
       the message body length is zero (no message body is present).

which means that in HTTP, there is no distinction between a request
with zero-length body and a request _without_ a body.

That means it is completely up to the HTTP client to whether or not to
send `content-length: 0` for such requests, though each implementation
may decide to send or not, depending on interoperability issues that
might exist.

2016-09-15 8:21 GMT+09:00 Mark Nottingham <mnot@mnot.net>:
> The rules in <http://httpwg.org/specs/rfc7230.html#message.body.length> still apply:
>
>  - Any response to a HEAD has no body
>  - Any 1xx, 204 and 304 response has no body
>  - A 2xx response to a CONNECT has no body (because it's no longer HTTP after the header fields)
>  - Otherwise, the message has a body which might be 0-length.
>
> We intentionally made the set of messages without a body unable to be extended; see <http://httpwg.org/specs/rfc7231.html#considerations.for.new.methods>:
>
> """
> Since message parsing (Section 3.3 of [RFC7230]) needs to be independent of method semantics (aside from responses to HEAD), definitions of new methods cannot change the parsing algorithm or prohibit the presence of a message body on either the request or the response message. Definitions of new methods can specify that only a zero-length message body is allowed by requiring a Content-Length header field with a value of "0".
> """
>
> and <http://httpwg.org/specs/rfc7231.html#considerations.for.new.status.codes>:
>
> """
> To allow existing parsers to process the response message, new status codes cannot disallow a payload, although they can mandate a zero-length payload body.
> """
>
> Cheers,
>
>
>> On 15 Sep 2016, at 7:17 AM, Kazuho Oku <kazuhooku@gmail.com> wrote:
>>
>> Hi,
>>
>> Is there any way for a H2 server to distinguish between a request
>> without a body and a request with 0-byte body?
>>
>> In HTTP/1, the distinction has been possible by looking for a
>> content-length or a transfer-encoding header. And H1 applications have
>> been actually looking for the headers to see if a request is
>> accompanied by a body by checking the existence of these headers.
>>
>> OTOH, HTTP/2 does not seem to provide a method to distinguish between the two.
>>
>> A HTTP/2 client is allowed to send a request accompanied by a body
>> without using the content-length header. It is also allowed to send a
>> HEADERS frame with END_STREAM flag set in case the size of the body is
>> zero-byte, omitting the DATA frame.
>>
>> In such case, a request with zero-byte body becomes indistinguishable
>> from a request without a body.
>>
>> The fact becomes an issue when we need to transcode a HTTP/2 request
>> to a HTTP/1 request (e.g. when a H2 proxy transmits a request to an H1
>> server running upstream), because, some applications try to see if a
>> POST request is accompanied by a body by checking the existence of
>> content-length or transfer-encoding header, or to assert that a GET
>> request is _not_ accompanied by a body by checking the non-existence
>> of the headers.
>>
>> As a mitigation, it is certainly possible for a H2 proxy transcoding
>> to H1 to use the method of the request to see if content-length or
>> transfer-encoding header should be set in such case. But my
>> understanding is that generally speaking in HTTP whether if a request
>> is accompanied by a body is orthogonal to which method is being used.
>>
>> Could somebody clarify what I am missing, or provide a method I should
>> use to accommodate the issue?
>>
>> --
>> Kazuho Oku
>>
>
> --
> Mark Nottingham   https://www.mnot.net/
>



-- 
Kazuho Oku

Received on Thursday, 15 September 2016 00:10:20 UTC