Une requête HTTP PUT est-elle requise pour inclure un corps?

92

J'ai du mal à trouver une spécification précise de cela dans la norme. J'ai un client HTTP qui n'inclut pas d'en- Content-Length: 0tête lorsque je fais une demande PUT où je ne spécifie pas de corps, et un serveur qui est confus par de telles demandes, et je me demande quel programme je dois blâmer.

Marijn
la source
Pourquoi éditeriez-vous une question de 2009 si je peux la poser?
zmuci
@zmuci Pour un meilleur formatage?
Константин Ван

Réponses:

83

Les requêtes HTTP ont un corps si elles ont un en-tête Content-Length ou Transfer-Encoding ( RFC 2616 4.3 ). Si la requête n'a ni l'un ni l'autre, elle n'a pas de corps et votre serveur doit la traiter comme telle.

Cela dit, il est inhabituel qu'une requête PUT n'ait pas de corps, et donc si je concevais un client qui voulait vraiment envoyer un corps vide, je passerais Content-Length: 0. En effet, en fonction de la lecture du POST et les définitions de la méthode PUT ( RFC 2616 9.5, 9.6 ), on pourrait soutenir que le corps est implicitement requis - mais une manière raisonnable de ne gérer aucun corps serait de supposer un corps de longueur nulle.

bdonlan
la source
Comme l'indiquent les codes d'état HTTP 200 («OK»), 201 («Créé») et 204 («Pas de contenu»), une PUTrequête est essentiellement destinée à créer ou mettre à jour un fichier sur le serveur. Et il n'y a rien d' illégitime dans le fait qu'un fichier soit vide, n'est-ce pas?
Константин Ван
Nouveaux liens: 3.3.1. Transfer-Encoding et 3.3.2. Content-Length
Alexis Wilke
5
@bdonlan vous avez dit qu'un PUT avec un corps vide est inhabituel, mais si je veux activer ou désactiver un utilisateur, je n'aurai pas besoin d'un corps à ma demande, en fait les requêtes PUT pourraient être "/ users / {id} / enable" ou "/ users / {id} / disable".
Vinicius de Almeida
@ViniciusdeAlmeida Ces ressources ne seraient pas appropriées si vous essayez de respecter les normes REST. disableet enablesont des verbes. Je préférerais probablement utiliser PATCHsur le /users/{id}point final dans ce cas.
écraser
42

Ne pas répondre à la question, mais affirmer comment jaxrs me permet d'utiliser fréquemment des PUT sans corps:

Exemple de mise sans corps: donnez à l'utilisateur une autorisation supplémentaire.

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

Geek béni
la source
2
Exactement mon problème! Je suis arrivé à la même conclusion. Mais à proprement parler, cela va à l'encontre de RFC, où, bien que cela ne soit pas explicitement mentionné, le corps est considéré comme existant. Cela pourrait causer des problèmes, mais d'après mon expérience, tous les serveurs / frameworks Web modernes fonctionneraient.
Agoston Horvath
Je suis dans un cas similaire, j'ai besoin d'une API pour associer une ressource existante à un utilisateur. Je pourrais utiliser un POST users /: userId / resources avec resourceId dans le corps. Ou plutôt, il conviendrait à un PUT users /: userid / resources /: resourceId. La grande différence ici est que la première API est censée être non idempotente, donc je pourrais associer la même ressource à un utilisateur deux fois. l'appel PUT devrait réinitialiser l'association précédente
Carmine Ingaldi
5

Un corps n'est pas requis par la norme IETF, bien que la longueur du contenu soit égale à 0 s'il n'y a pas de corps. Utilisez la méthode qui convient à ce que vous faites. Si vous deviez le mettre dans le code, étant donné

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

et une variable distante appelée r.

Un message équivaut à

r=f();

Un put équivaut à

r=x;

et un get équivaut à

x=r;
abc
la source
1
C'est l'exemple le plus clair de PUT vs POST que j'ai jamais lu, bien que hors sujet
illusion numérique
Si la demande a un en-tête Content-Length, elle a un corps. Ce peut être un corps vide, mais toujours un corps. Contrairement à une requête sans en-tête Content-Length, qui n'a pas du tout de corps, même pas vide. Alors oui, une demande PUT, techniquement, strictement, doit avoir un corps. Toujours.
Paul Groke
De plus, votre analogie avec POST me déroute totalement. Si j'essaie de rester avec le reste de votre analogie, cela devrait être plus comme si le serveur avait un int f(int* resource, int body);et puis POST invoquerait f(&r, x);- ce qui peut faire ou ne pas faire à rtout ce que le serveur juge approprié. Mais il peut aussi renvoyer des trucs, alors ... peut-être plus y = f(&r, x);.
Paul Groke
0

Qu'est-ce que PUT (au sens du verbe) sur le serveur s'il n'y a pas de contenu? La spécification fait référence au contenu comme "l'entité incluse", mais une demande sans contenu n'aurait aucune entité incluse, et donc rien à mettre sur le serveur.

À moins, bien sûr, que vous ne vouliez rien METTRE sur le serveur, auquel cas vous voudriez probablement un DELETE à la place.

Rob Hruska
la source
1
ce que votre mise pourrait être une URL encodée plutôt que dans le corps
MikeT
1
PUT vide déclare simplement que la ressource avec une identité donnée doit exister sur le serveur bien qu'elle n'ait aucun contenu en dehors de l'identité elle-même. C'est une sémantique complètement différente de DELETE.
Imre Pühvel
Imaginez que vous vouliez METTRE une ressource mais accepter toutes les valeurs par défaut côté serveur. Ce serait Content-Length: 0ou { }en JSON en tant que corps?
Luke Puplett
1
Vous n'avez donc pas un seul fichier vide sur votre ordinateur, n'est-ce pas ?
Константин Ван