¿Se requiere una solicitud HTTP PUT para incluir un cuerpo?


92

Tengo problemas para encontrar una especificación definida de esto en el estándar. Tengo un cliente HTTP que no incluye un Content-Length: 0encabezado cuando hago una solicitud PUT donde no especifico un cuerpo, y un servidor que se confunde con tales solicitudes, y me pregunto a qué programa debería culpar.


¿Por qué editaría una pregunta de 2009 si puedo preguntar?
zmuci

@zmuci ¿Para un mejor formato?
Константин Ван

Respuestas:


83

Las solicitudes HTTP tienen un cuerpo si tienen un encabezado Content-Length o Transfer-Encoding ( RFC 2616 4.3 ). Si la solicitud no tiene ninguno, no tiene cuerpo y su servidor debe tratarlo como tal.

Dicho esto, es inusual que una solicitud PUT no tenga cuerpo, por lo que si estuviera diseñando un cliente que realmente quisiera enviar un cuerpo vacío, pasaría Content-Length: 0. De hecho, dependiendo de la lectura de POST. y las definiciones del método PUT ( RFC 2616 9.5, 9.6 ) se podría argumentar que se implica que el cuerpo es obligatorio, pero una forma razonable de no manejar ningún cuerpo sería asumir un cuerpo de longitud cero.


Como implican los códigos de estado HTTP 200 ("OK"), 201 ("Creado") y 204 ("Sin contenido"), una PUTsolicitud es básicamente para crear o actualizar un archivo en el servidor. Y no hay nada ilegítimo en que un archivo esté vacío, ¿no?
Константин Ван


5
@bdonlan, dijiste que un PUT con un cuerpo vacío es inusual, pero si quiero habilitar o deshabilitar un usuario, no necesitaré un cuerpo en mi solicitud, en realidad, las solicitudes PUT podrían ser "/ users / {id} / enable" o "/ users / {id} / disable".
Vinicius de Almeida

@ViniciusdeAlmeida Esos recursos no serían apropiados si intenta adherirse a los estándares REST. disabley enableson verbos. Probablemente preferiría usarlo PATCHen el /users/{id}punto final en ese caso.
aplasta el

42

Sin responder la pregunta, pero afirmando cómo jaxrs me permite el uso frecuente de PUT sin cuerpo:

Ejemplo de colocación sin cuerpo: otorgue al usuario un permiso adicional.

PUT / admin / users / {username} / permiso / {permiso}


2
¡Exactamente mi problema! Llegué a la misma conclusión. Pero estrictamente hablando, esto va en contra de RFC, donde, aunque no se menciona explícitamente, se dice que el cuerpo existe. Podría causar problemas, pero en mi experiencia, todos los servidores / marcos web modernos funcionarían.
Agoston Horvath

Estoy en un caso similar, necesito una API para asociar un recurso existente a un usuario. Podría usar un usuario POST /: userId / resources con resourceId en el cuerpo. O más bien, encajaría en un PUT users /: userid / resources /: resourceId. La gran diferencia aquí es que se supone que la primera API no es idempotente, por lo que podría asociar el mismo recurso a un usuario dos veces. la llamada PUT debe restablecer la asociación anterior
Carmine Ingaldi

5

El estándar IETF no requiere un cuerpo, aunque la longitud del contenido debe ser 0 si no hay cuerpo. Utilice el método que sea apropiado para lo que está haciendo. Si tuviera que ponerlo en código, dado

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

y una variable remota llamada r.

Una publicación es equivalente a

r=f();

Un put es equivalente a

r=x;

y un get es equivalente a

x=r;

1
Este es el ejemplo más claro de PUT vs POST que he leído, aunque fuera de tema
ilusión digital

Si la solicitud tiene un encabezado Content-Length, entonces tiene un cuerpo. Puede ser un cuerpo vacío, pero sigue siendo un cuerpo. En contraste con una solicitud sin encabezado Content-Length, que no tiene cuerpo, ni siquiera uno vacío. Entonces sí, una solicitud PUT, técnicamente, estrictamente, debe tener un cuerpo. Siempre.
Paul Groke

Además, su analogía POST me resulta totalmente confusa. Si trato de quedarme con el resto de su analogía, debería ser más como si el servidor tuviera un int f(int* resource, int body);y luego se invocaría POST, lo f(&r, x);que puede hacer o no hacer rlo que el servidor considere apropiado. Pero también puede devolver cosas, así que ... tal vez más como y = f(&r, x);.
Paul Groke

0

¿Qué se PUT (en el sentido verbal) en el servidor si no hay contenido? La especificación se refiere al contenido como "la entidad adjunta", pero una solicitud sin contenido no tendría una entidad adjunta y, por lo tanto, nada para poner en el servidor.

A menos que, por supuesto, no desee PONER nada en el servidor, en cuyo caso probablemente desee un DELETE en su lugar.


1
lo que su colocación podría estar codificado en URL en lugar de en el cuerpo
MikeT

1
PUT empty es simplemente declarar que el recurso con la identidad dada debe existir en el servidor aunque no tiene contenido además de la identidad en sí. Esa es una semántica completamente diferente de DELETE.
Imre Pühvel

Imagine que desea PONER un recurso pero acepta todos los valores predeterminados del lado del servidor. ¿Eso sería Content-Length: 0o { }en JSON como el cuerpo?
Luke Puplett

1
Así que no tienes un solo archivo vacío en tu computadora, ¿verdad?
Константин Ван

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.