45

Is this statement correct? HTTP GET method always has no message body. I didn't find any part of RFC2616 explicitly say this.

And if this is not true, then in what circumstances will an Http GET request include a message body

PeopleMoutainPeopleSea
  • 1,410
  • 1
  • 12
  • 22
  • 3
    Possible duplicate of [HTTP GET with request body](http://stackoverflow.com/questions/978061/http-get-with-request-body) – mpromonet Feb 09 '16 at 18:20

4 Answers4

43

Neither restclient nor REST console support this but curl does.

The original HTTP 1.1 specification says in section 4.3

A message-body MUST NOT be included in a request if the specification of the request method (section 5.1.1) does not allow sending an entity-body in requests.

Section 5.1.1 redirects us to section 9.x for the various methods. None of them explicitly prohibit the inclusion of a message body. However...

Section 5.2 says

The exact resource identified by an Internet request is determined by examining both the Request-URI and the Host header field.

and Section 9.3 says

The GET method means retrieve whatever information (in the form of an entity) is identified by the Request-URI.

Which together suggest that when processing a GET request, a server is not required to examine anything other that the Request-URI and Host header field.

In summary, the HTTP spec doesn't prevent you from sending a message-body with GET, but there is sufficient ambiguity that it wouldn't surprise me if it was not supported by all servers.

kubanczyk
  • 3,448
  • 30
  • 45
Dave Durbin
  • 3,339
  • 18
  • 31
  • 1
    Important to note that while the HTTP specification does not explicitly prohibit the use of a body in GET requests, it's meaningless. HTTP also does not prevent you from clapping your hands when doing a POST request, but it does not influence its operation. – Evert Mar 03 '15 at 01:29
  • 1
    Tangential to this point, GET requests are very often something that one may want to bookmark or copy and paste to a friend. You can't exactly do that when implementing with request body, whether that be GET or POST. In this case, it might be more prudent to make the query parameter key names something less descriptive but terse, vs implementing via POST when hitting the upper limit on length. – saneshark May 28 '15 at 04:48
  • 1
    @evert I don't get what you are saying. The OP is writing a REST API... In REST, the methods have meaning: `GET` -> read/find/select, `POST` -> create, `PUT` -> update, `DELETE` -> delete. But what if your selection criteria are too big to fit in the URL? E.g. I want the details for this list of 500 record IDs... To use POST is contrary to the meaning in REST... We want to select data, not create it. But 500 IDs won't comfortably fit in the URL.... So that is where the desire comes from. I think the spec suggests it's ok to make his *server* accept a body for a `GET` request. – Stijn de Witt Feb 03 '16 at 10:04
  • @StijndeWitt absolutely not, and it would be a terrible idea. Most intermediates actually completely drop the `GET` request body. Caching headers would also fail to function, because the outcome would be dependent on the request body (which should be ignored) `GET` is solely for retrieving a representation based on the url and a set of accept headers. Nothing more. – Evert Feb 03 '16 at 17:59
  • If you *think* you want the request you are describing and you insist on making a REST service, you should _create_ a report with your conditions using `POST` or `PUT` (kind of like a materialized view) and then fetch it's results for example. Or you need to rethink your media-types and resources. – Evert Feb 03 '16 at 18:00
  • The way you split up your methods is also wrong, because `PUT` is also used for creating new resources. `POST` is a bit more like a hack because you don't want clients to determine the new resource uri, but you lose idempotence. – Evert Feb 03 '16 at 18:02
  • @Evert "Most intermediates actually completely drop the GET request body" That's a very important point you are making. Do you have examples of such intermediaries? – Stijn de Witt Feb 04 '16 at 18:29
  • It bothers me that including a request body with GET requests is frowned upon and impossible due to some hardware stripping the body on such requests (if this is true). It is not always feasible to include all information in the URI. E.g. an API endpoint which takes an unbounded number of ids (e.g. GUIDs) and returns those entities. The URI could be `/some-entity?id=...&id=...&id=...`. This becomes unwieldy as the number of ids grow and web servers may truncate or return an error status if the URI is too long. Much easier to include an array in the GET request body with all of the ids. – Josh M. Aug 14 '17 at 13:04
  • Please see @alexander.polomdov's answer which supercedes this as the spec has changed. Having said that the spec defines how things actually work. You can achieve what you want using a POST so no need to use a GET. – Dave Durbin Aug 15 '17 at 20:53
14

The old RFC2616 has been superseded and it was replaced by multiple RFCs (7230-7237).

New RFC 7230 on HTTP/1.1 clearly says about message body:

The message body (if any) of an HTTP message is used to carry the
payload body of that request or response. The message body is
identical to the payload body unless a transfer coding has been
applied, as described in Section 3.3.1.

 message-body = *OCTET

The rules for when a message body is allowed in a message differ for requests and responses.

The presence of a message body in a request is signaled by a
Content-Length or Transfer-Encoding header field. Request message
framing is independent of method semantics
, even if the method does
not define any use for a message body.

So new standard clearly answer the initial question. But there are some old software which can ignore message-body into GET request, so you need be cautious and check this case.

alexander.polomodov
  • 4,849
  • 14
  • 35
  • 42
  • 5
    You say "clearly" twice, but it's not so clear to me. I think you're saying "Whether there is a body is solely dependent on the existence of the `Content-Length` and/or `Transfer-Encoding` headers"? – Tyler Collier May 06 '16 at 17:11
8

I came across this in elasticsearch where a GET request with message body is used for testing analyzers - https://www.elastic.co/guide/en/elasticsearch/guide/master/analysis-intro.html

Essentially this is a request that does not change anything on the server side, but it requires a long text message to be passed as input. Seems like an apt use of GET request with a message body.

5

I think the specification allows you to add a message body, so the answer to your question should be No (but with caveats).

Let's first check the specification (I am quoting from RFC 7231, RFC 7232 and RFC 7234, since RFC 2616 referred in other answers has been obsoleted by them).

From RFC 7230:

The presence of a message body in a request is signaled by a
Content-Length or Transfer-Encoding header field. Request message
framing is independent of method semantics, even if the method does
not define any use for a message body.

Note that the part "A message-body MUST NOT be included in a request if the specification of the request method (section 5.1.1) does not allow sending an entity-body in requests." present in the old RFC 2616 has been removed.

Also RFC 7231 says this on the subject:

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.

So, in my opinion this means that you can add a message body to a GET request, (and this should answer your original question), but you have to be careful. The case mentioned in the specs is not the only one you have to be aware, many tools, client and servers are simply not expecting a message body and may misbehave. For example in Chrome, XMLHttpRequest will drop the message body for GETs.

Another issues is the one of caching. According to RFC 7234.

The primary cache key consists of the request method and target URI   
[...]
If a request target is subject to content negotiation, its cache
entry might consist of multiple stored responses, each differentiated
by a secondary key for the values of the original request's selecting
header fields.

This means that requests with different bodies but same url (and possibly selected headers), will be considered having the same response by a cache, even if the message body has been previously correctly forwarded to the server.

In the end I think that if possible you should avoid using message bodies in GETs, unless

  • You control the client
  • You control the server
  • You know of potential proxies, caches that may get in the way
  • You disable caching in the response (you may in fact be able to (ab)use headers to be able to cache, but I haven't investigated properly the idea).
Marco Righele
  • 2,343
  • 3
  • 20
  • 21