É necessária uma solicitação HTTP PUT para incluir um corpo?

93

Estou tendo problemas para encontrar uma especificação definitiva disso no padrão. Tenho um cliente HTTP que não inclui um Content-Length: 0cabeçalho ao fazer uma solicitação PUT em que não especifico um corpo e um servidor que fica confuso com essas solicitações, e estou me perguntando de qual programa devo culpar.

Marijn
fonte
Por que você editaria uma pergunta de 2009 se eu pudesse perguntar?
zmuci
@zmuci Para uma melhor formatação?
Константин Ван

Respostas:

83

As solicitações HTTP têm um corpo se tiverem um cabeçalho Content-Length ou Transfer-Encoding ( RFC 2616 4.3 ). Se a solicitação não tiver nenhum dos dois, não terá corpo e seu servidor deverá tratá-lo como tal.

Dito isso, é incomum que uma solicitação PUT não tenha corpo e, portanto, se eu estivesse projetando um cliente que realmente quisesse enviar um corpo vazio, aprovaria Content-Length: 0. De fato, dependendo da leitura do POST. e definições do método PUT ( RFC 2616 9.5, 9.6 ) pode-se argumentar que o corpo está implícito como sendo necessário - mas uma maneira razoável de não manipular nenhum corpo seria assumir um corpo de comprimento zero.

bdonlan
fonte
Como os códigos de status HTTP 200 (“OK”), 201 (“Criado”) e 204 (“Sem conteúdo”) implicam, uma PUTsolicitação é basicamente para criar ou atualizar um arquivo no servidor. E não há nada de ilegítimo em um arquivo estar vazio, não é?
Константин Ван
Novos links: 3.3.1. Transfer-Encoding e 3.3.2. Content-Length
Alexis Wilke
5
@bdonlan você disse que um PUT com um corpo vazio é incomum, mas se eu quiser habilitar ou desabilitar um usuário não vou precisar de um corpo na minha solicitação, na verdade as solicitações PUT podem ser "/ users / {id} / enable" ou "/ users / {id} / disable".
Vinicius de Almeida
@ViniciusdeAlmeida Esses recursos não seriam apropriados se você está tentando aderir aos padrões REST. disablee enablesão verbos. Eu provavelmente preferiria usar PATCHno /users/{id}ponto de extremidade nesse caso.
esmagamento de
43

Não respondendo à pergunta, mas afirmando como jaxrs me permite o uso frequente de PUTs sem corpo:

Exemplo de colocação sem corpo: Dê ao usuário uma permissão adicional.

PUT / admin / users / {username} / permission / {permission}

Abençoado Geek
fonte
2
Exatamente meu problema! Eu cheguei à mesma conclusão. Mas, estritamente falando, isso vai contra o RFC, onde, embora não seja explicitamente mencionado, o corpo é referido como existente. Isso poderia causar problemas, mas, na minha experiência, todos os servidores / estruturas da web modernos funcionariam.
Agoston Horvath
Estou em um caso semelhante, preciso de uma API para associar um recurso existente a um usuário. Eu poderia usar um POST users /: userId / resources com resourceId no corpo. Ou melhor, caberia um PUT users /: userid / resources /: resourceId. A grande diferença aqui é que a primeira API deve ser não idempotente, então eu poderia associar o mesmo recurso a um usuário duas vezes. a chamada PUT deve zerar a associação anterior
Carmine Ingaldi
5

Um corpo não é exigido pelo padrão IETF, embora o comprimento do conteúdo deva ser 0 se não houver corpo. Use o método apropriado para o que você está fazendo. Se você fosse colocá-lo em código, dado

int x;
int f(){ return x; }

e uma variável remota chamada r.

Uma postagem é equivalente a

r=f();

Uma opção de venda é equivalente a

r=x;

e get é equivalente a

x=r;
abc
fonte
1
Este é o exemplo mais claro de PUT vs POST que já li, embora fora do tópico
ilusão digital
Se a solicitação tiver um cabeçalho Content-Length, ela terá um corpo. Pode ser um corpo vazio, mas ainda é um corpo. Em contraste com uma solicitação sem cabeçalho Content-Length, que não tem corpo, nem mesmo vazio. Então sim, um pedido PUT, tecnicamente, estritamente, tem que ter um corpo. Sempre.
Paul Groke de
Além disso, sua analogia com o POST é totalmente confusa para mim. Se eu tentar ficar com o resto de sua analogia, deve ser mais como se o servidor tivesse um int f(int* resource, int body);e então o POST chamaria f(&r, x);- o que pode fazer ou não ro que o servidor achar apropriado. Mas também pode retornar coisas, então ... talvez mais como y = f(&r, x);.
Paul Groke de
0

O que está sendo PUT (no sentido verbal) no servidor se não houver conteúdo? A especificação se refere ao conteúdo como "a entidade fechada", mas uma solicitação sem conteúdo não teria nenhuma entidade fechada e, portanto, nada para colocar no servidor.

A menos, é claro, que você não quisesse COLOCAR nada no servidor; nesse caso, você provavelmente desejaria EXCLUIR.

Rob Hruska
fonte
1
o que sua colocação pode ser codificada em URL em vez de no corpo
MikeT
1
PUT vazio está apenas declarando que o recurso com a identidade fornecida deve existir no servidor, embora não tenha conteúdo além da própria identidade. Isso é semântica completamente diferente de DELETE.
Imre Pühvel de
Imagine que você deseja PUT um recurso, mas aceita todos os padrões do lado do servidor. Isso seria Content-Length: 0ou { }em JSON como o corpo?
Luke Puplett
1
Então você não tem um único arquivo vazio no seu computador, tem?
Константин Ван
A "entidade fechada" precisa estar no corpo?
Blessed Geek