Esta afirmação é correta? O método HTTP GET sempre não possui um corpo de mensagem

Esta afirmação é correta? O método HTTP GET sempre não possui um corpo de mensagem. Eu não encontrei nenhuma parte da RFC 2616 explicitamente dizer isso.

E se isso não for verdade, então em que circunstâncias um pedido HTTP GET includeá um corpo de mensagem

Nem o restclient nem o console REST suportam isso, mas o curl faz isso.

A especificação original do HTTP 1.1 diz na seção 4.3

Um corpo de mensagem NÃO DEVE ser incluído em uma solicitação se a especificação do método de solicitação (seção 5.1.1) não permitir o envio de um corpo de entidade em solicitações.

A seção 5.1.1 nos redireciona para a seção 9.x para os vários methods. Nenhum deles proíbe explicitamente a inclusão de um corpo de mensagem. Contudo…

Seção 5.2 diz

O recurso exato identificado por uma solicitação da Internet é determinado examinando-se o campo Request-URI e o header do host.

e a seção 9.3 diz

O método GET significa recuperar qualquer informação (na forma de uma entidade) é identificada pelo Request-URI.

Que juntos sugerem que, ao processar uma solicitação GET, não é necessário que um servidor examine qualquer outra coisa que o campo Request-URI e Host header.

Em resumo, a especificação HTTP não impede que você envie um corpo de mensagem com GET, mas há ambiguidade suficiente para que não me surpreenda se não fosse suportado por todos os servidores.

O antigo RFC2616 foi substituído e foi substituído por vários RFCs (7230-7237).

A nova RFC 7230 no HTTP / 1.1 diz claramente sobre o corpo da mensagem:

O corpo da mensagem (se houver) de uma mensagem HTTP é usado para transportar
corpo de carga útil dessa solicitação ou resposta. O corpo da mensagem é
idêntico ao corpo da carga, a menos que uma codificação de transferência tenha sido
aplicado, conforme descrito na Seção 3.3.1.

  message-body = *OCTET 

As regras para quando um corpo de mensagem é permitido em uma mensagem são diferentes para solicitações e respostas.

A presença de um corpo de mensagem em uma solicitação é sinalizada por um
Campo de header Content-Length ou Transfer-Encoding. Solicitar mensagem
enquadramento é independente da semântica do método , mesmo se o método
não define nenhum uso para um corpo de mensagem.

Então, um novo padrão responde claramente à pergunta inicial. Mas existem alguns softwares antigos que podem ignorar o corpo da mensagem no pedido GET, então você precisa ser cauteloso e verificar este caso.

Eu me deparei com isso em elasticsearch, onde uma solicitação GET com o corpo da mensagem é usada para testar analisadores – https://www.elastic.co/guide/en/elasticsearch/guide/master/analysis-intro.html

Essencialmente, este é um pedido que não altera nada no lado do servidor, mas requer uma longa mensagem de texto para ser passada como input. Parece um uso adequado da solicitação GET com um corpo da mensagem.

Eu acho que a especificação permite que você adicione um corpo da mensagem, então a resposta para a sua pergunta deve ser Não (mas com ressalvas).

Vamos primeiro verificar a especificação (estou citando o RFC 7231 , o RFC 7232 e o RFC 7234 , já que o RFC 2616 referido em outras respostas foi obsoleto por eles).

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

Observe que a parte “Um corpo de mensagem NÃO DEVE ser incluído em uma solicitação se a especificação do método de solicitação (seção 5.1.1) não permitir o envio de um corpo de entidade em solicitações”. presente no antigo RFC 2616 foi removido.

Também o RFC 7231 diz isso sobre o assunto :

 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. 

Então, na minha opinião, isso significa que você pode adicionar um corpo de mensagem a uma solicitação GET (e isso deve responder à sua pergunta original), mas você precisa ser cuidadoso. O caso mencionado nas especificações não é o único que você precisa saber, muitas ferramentas, clientes e servidores simplesmente não esperam um corpo de mensagem e podem se comportar mal. Por exemplo, no Chrome, XMLHttpRequest soltará o corpo da mensagem para GETs.

Outra questão é a do caching. De acordo com a 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. 

Isso significa que solicitações com corpos diferentes, mas com o mesmo url (e possivelmente headers selecionados), serão consideradas com a mesma resposta por um cache, mesmo que o corpo da mensagem tenha sido encaminhado corretamente para o servidor.

No final, acho que, se possível, você deve evitar usar corpos de mensagens em GETs, a menos que

  • Você controla o cliente
  • Você controla o servidor
  • Você sabe de possíveis proxies, caches que podem ficar no caminho
  • Você desativa o cache na resposta (na verdade, você pode (ab) usar headers para poder armazenar em cache, mas não investiguei a ideia corretamente).