Re: Bodies on GET (again) - was Re: RFC7234: Can a request body form part of a "cache key"?

On Thu, Jul 28, 2016 at 01:25:00AM +0000, Adrien de Croy wrote:
> 
> bodies on GET is a can of worms.
> 
> how can GET be idempotent if we allow bodies on GET and say they have no
> defined semantics within HTTP?
> 
> Is GET with Content-Length: 0 semantically different to GET with no
> Content-Length header since the body has no defined semantics in http?

Normally it is the same except that it indicates that the sender considers
there's an empty body instead of no body, and that it might be aware of
this possibility to send a body and is probably able to put something else
there. Just like servers expect to see a content-length 0 for POSTs even
if there's nothing to send because they want to see an empty body instead
of no body. By the way 7230 says this :

   A user agent SHOULD send a Content-Length in a request message when
   no Transfer-Encoding is sent and the request method defines a meaning
   for an enclosed payload body.  For example, a Content-Length header
   field is normally sent in a POST request even when the value is 0
   (indicating an empty payload body).  A user agent SHOULD NOT send a
   Content-Length header field when the request message does not contain
   a payload body and the method semantics do not anticipate such a
   body.

> Is it therefore appropriate to strip Content-Length: 0 from GET requests?

I don't see why it would not be. The framing remains exactly the same,
you're just telling the server that you're not aware of any body. Don't
forget that there's no such thing as as content length. What matters is
the size of the payload body, which in terms of framing is always there
right after the headers except when you establish a tunnel or when you
get a response which explicitly doesn't support a body (response to HEAD,
204, 304). For the semantics however the body is not always there. The
body size can be communicated in different ways, including the use of
Transfer-Encoding. It is suggested somewhere in 7230 that content-length
should be avoided when not expected, so I think that what your proxy is
doing probably slightly improves interoperability. Just found it here :

   A user agent SHOULD NOT send a
   Content-Length header field when the request message does not contain
   a payload body and the method semantics do not anticipate such a
   body.

> Seems like the potential for request smuggling is large with bodies on GET.

Yep, but not with content-length 0. Request smuggling is a framing issue.

> Shouldn't we just ban them?  I'm sure this has been discussed at length on
> here many times before.

Its been discussed in the past. Banning them causes more harm than not banning
them because it creates expectations on recipient that such a body doesn't
exist so it doesn't need to be checked. That's precisely what introduces
request smuggling. It's better to consider that content-length or
transfer-encoding are used for the framing and apply similarly to all known
and unknown methods. By the way this subject is covered here in 7231 :

   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".


> Maybe at least be a little stronger in the language?
> 
> e.g. clients SHOULD not send bodies on GET.

I tend to think that the way it is done right now ensures that nobody is
willing to make shortcuts in their parsers and that's important. However
what we could have done (I thought we had it but can't find it) would be
to mention that a server MAY reject a GET with a body. That's more
dissuasive for clients and that still indicates that the server is not
allowed to be lazy on this.

Willy

Received on Thursday, 28 July 2016 06:33:32 UTC