Hidden Complexity in HTTP GET

If you have never read an RFC, I can tell you that they can sometimes be frustrating documents. They spell out the explicit details of how something is supposed to work. There is a lot of nuance in the descriptions and sometimes it implies a fact in a way that is non-intuitive. I started digging into some RFCs when someone mentioned the request body in a HTTP GET. I had never heard of a body with a HTTP GET before and was curious.

First up was the RFC for HTTP 1.1, which is a beast to read. The immediately relevant section was 4.3 on message bodies, which contains the following:

if the request method does not include defined semantics for an entity-body, then the message-body SHOULD be ignored when handling the request

That seems to me to say you can but you also shouldn’t. I’m curious why the use of SHOULD and not a MUST. I managed to dig up this post by Roy Fielding that implies it should have been a MUST to me. Continuing on this train of thought eventually led me to RFC 2119 about the usages of keywords in other RFCs. On the subject of SHOULD it said:

This word, or the adjective “RECOMMENDED”, mean that there may exist valid reasons in particular circumstances to ignore a particular item, but the full implications must be understood and carefully weighed before choosing a different course.

I still don’t have a good answer as to why it was allowed; it could have something to do with simplifying the parser, but I don’t have any evidence to back this up.

I ended up digging through the updates to the initial RFC and found RFC 7231 in which I found the following:

A payload within a GET request message has no defined semantics; sending a payload body on a GET request might cause some existing implementations to reject the request.

That definitely represents all of the normal expectations I’ve had for a GET request. So it was never formally prohibited, but it seems that many implementations don’t allow it. That matches with the working usage of HTTP GET I had been familiar with. I ran into this wonderful quote on MDN about XMLHttpRequest

If the request method is GET or HEAD, the argument is ignored and request body is set to null.

To me this says Firefox would block these sorts of requests from being issued in Javascript. You’d think that if this were true, any sort of browser based application wouldn’t have a get request with a body. That isn’t the case, though the Elasticsearch documentation describes how they do use lots of GET requests to do searches with bodies, but that they also support POST requests because of the compatability issues with doing so.

When I started this line of inquiry I never really expected to find this level of nuance. As an added bonus, after this experience and exploration, I’ll feel less afraid to dig into RFCs like these again.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s