Ist eine HTTP-PUT-Anforderung erforderlich, um einen Text einzuschließen?

89

Ich habe Probleme, eine bestimmte Spezifikation im Standard zu finden. Ich habe einen HTTP-Client, der keinen Content-Length: 0Header enthält, wenn ich eine PUT-Anforderung ausführe, bei der ich keinen Text angegeben habe, und einen Server, der durch solche Anforderungen verwirrt wird, und ich frage mich, welches Programm ich beschuldigen soll.

Marijn
quelle
Warum würden Sie eine Frage aus dem Jahr 2009 bearbeiten, wenn ich fragen darf?
Zmuci
@zmuci Für eine bessere Formatierung?
8онстантин Ван

Antworten:

79

HTTP-Anforderungen haben einen Hauptteil, wenn sie einen Content-Length- oder Transfer-Encoding-Header haben ( RFC 2616 4.3 ). Wenn die Anforderung keine hat, hat sie keinen Text, und Ihr Server sollte sie als solche behandeln.

Das heißt, es ist ungewöhnlich, dass eine PUT-Anfrage keinen Body hat. Wenn ich also einen Client entwerfe, der wirklich einen leeren Body senden möchte, würde ich Content-Length: 0 übergeben. In der Tat, abhängig von der Lesart des POST und PUT-Methodendefinitionen ( RFC 2616 9.5, 9.6 ) könnte man argumentieren, dass der Körper impliziert sein muss - aber ein vernünftiger Weg, mit keinem Körper umzugehen, wäre die Annahme eines Körpers mit der Länge Null.

bdonlan
quelle
Wie die HTTP-Statuscodes 200 ("OK"), 201 ("Erstellt") und 204 ("Kein Inhalt") implizieren, besteht eine PUTAnforderung im Wesentlichen darin, eine Datei auf dem Server zu erstellen oder zu aktualisieren. Und es ist nichts Unzulässiges daran, dass eine Datei leer ist, nicht wahr?
8онстантин Ван
Neue Links: 3.3.1. Transfer-Encoding und 3.3.2. Inhaltslänge
Alexis Wilke
4
@bdonlan Sie sagten, dass ein PUT mit einem leeren Körper ungewöhnlich ist, aber wenn ich einen Benutzer aktivieren oder deaktivieren möchte, benötige ich keinen Körper auf meiner Anfrage, tatsächlich könnten die PUT-Anfragen "/ users / {id} / enable" sein. oder "/ users / {id} / disable".
Vinicius de Almeida
42

Nicht die Frage beantworten, sondern behaupten, wie ich mit jaxrs häufig körperlose PUTs verwenden kann:

Beispiel für körperloses Put: Geben Sie dem Benutzer eine zusätzliche Berechtigung.

PUT / admin / users / {Benutzername} / Erlaubnis / {Erlaubnis}

Gesegneter Geek
quelle
2
Genau mein Problem! Ich bin zu dem gleichen Schluss gekommen. Streng genommen widerspricht dies jedoch RFC, wo, obwohl nicht ausdrücklich erwähnt, die Stelle als existierend bezeichnet wird. Es könnte Probleme verursachen, aber meiner Erfahrung nach würden alle modernen Webserver / Frameworks funktionieren.
Agoston Horvath
In einem ähnlichen Fall benötige ich eine API, um einem Benutzer eine vorhandene Ressource zuzuordnen. Ich könnte eine POST users /: userId / resources mit resourceId im Body verwenden. Oder besser gesagt, es passt zu einem PUT-Benutzer /: Benutzer-ID / Ressourcen /: Ressourcen-ID. Der große Unterschied besteht darin, dass die firt-API nicht idempotent sein soll, sodass ich einem Benutzer zweimal dieselbe Ressource zuordnen kann. Der PUT-Aufruf sollte die vorherige Zuordnung zurücksetzen
Carmine Ingaldi,
5

Ein Body ist nach dem IETF-Standard nicht erforderlich, obwohl die Inhaltslänge 0 sein sollte, wenn kein Body vorhanden ist. Verwenden Sie die Methode, die für Ihre Arbeit geeignet ist. Wenn Sie es in Code setzen würden, gegeben

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

und eine entfernte Variable namens r.

Ein Beitrag entspricht

r=f();

Ein Put entspricht

r=x;

und ein get ist gleichbedeutend mit

x=r;
ABC
quelle
1
Dies ist das klarste Beispiel für PUT vs POST, das ich je gelesen habe, obwohl es nicht zum Thema gehört
digitale Illusion
Wenn die Anforderung einen Content-Length-Header hat, hat sie einen Body. Es mag ein leerer Körper sein, aber immer noch ein Körper. Im Gegensatz zu einer Anfrage ohne Content-Length-Header, die überhaupt keinen Body hat, nicht einmal einen leeren. Also ja, eine PUT-Anfrage muss technisch gesehen unbedingt einen Körper haben. Immer.
Paul Groke
Auch Ihre POST-Analogie ist für mich völlig verwirrend. Wenn ich versuche, beim Rest Ihrer Analogie zu bleiben, sollte es eher so sein, als hätte der Server eine int f(int* resource, int body);und dann würde POST aufrufen f(&r, x);- was mit dem tun kann oder nicht, rwas der Server für angemessen hält. Aber es kann auch Sachen zurückgeben, also ... vielleicht eher so y = f(&r, x);.
Paul Groke
-1

Was ist PUT (im Verbsinn) auf dem Server, wenn kein Inhalt vorhanden ist? Die Spezifikation bezieht sich auf den Inhalt als "die eingeschlossene Entität", aber eine Anforderung ohne Inhalt hätte keine eingeschlossene Entität und daher nichts, was auf den Server gestellt werden könnte.

Es sei denn, Sie wollten natürlich nichts auf den Server stellen. In diesem Fall möchten Sie wahrscheinlich stattdessen ein LÖSCHEN.

Rob Hruska
quelle
1
Was Ihr Putten könnte URL-codiert sein und nicht im Körper
MikeT
1
PUT leer erklärt lediglich, dass die Ressource mit der angegebenen Identität auf dem Server vorhanden sein muss, obwohl sie außer der Identität selbst keinen Inhalt enthält. Das ist eine völlig andere Semantik als DELETE.
Imre Pühvel
Stellen Sie sich vor, Sie möchten eine Ressource PUTEN, aber alle serverseitigen Standardeinstellungen akzeptieren. Das wäre Content-Length: 0oder { }in JSON als Körper?
Luke Puplett
Sie haben also keine einzige leere Datei auf Ihrem Computer, oder?
8онстантин Ван