it-swarm.com.de

Ist ein Entity Body für eine HTTP DELETE-Anfrage zulässig?

Bei der Ausgabe einer HTTP-DELETE-Anforderung sollte der Anforderungs-URI die zu löschende Ressource vollständig identifizieren. Ist es jedoch zulässig, zusätzliche Metadaten als Teil des Entitätskörpers der Anforderung hinzuzufügen?

564
Haacked

Die Spezifikation verbietet oder entmutigt sie nicht ausdrücklich, daher neige ich dazu, zu sagen, dass dies erlaubt ist.

Microsoft sieht es auf die gleiche Weise (ich höre Murmeln im Publikum), heißt es in dem MSDN-Artikel über die DELETE-Methode von ADO.NET Data Services Framework :

Wenn eine DELETE-Anforderung einen Entity-Body enthält, wird der Body ignoriert [...]

Zusätzlich dazu hat RFC2616 (HTTP 1.1) zu Anfragen zu sagen:

  • ein entity-body ist nur vorhanden, wenn ein message-body vorhanden ist (Abschnitt 7.2)
  • das Vorhandensein eines message-body wird durch die Einfügung eines Content-Length- oder Transfer-Encoding-Headers signalisiert (Abschnitt 4.3).
  • ein message-body darf nicht enthalten sein, wenn die Angabe der Anforderungsmethode das Senden eines entity-body nicht zulässt (Abschnitt 4.3).
  • ein entity-body ist nur in TRACE-Anforderungen ausdrücklich verboten. Alle anderen Anforderungstypen sind nicht eingeschränkt (Abschnitt 9 und 9.8).

Für Antworten wurde dies definiert:

  • ob ein message-body enthalten ist, hängt von dem Antwortstatus der Anforderungsmethode und ab (Abschnitt 4.3).
  • ein message-body ist in den Antworten auf HEAD -Anfragen ausdrücklich verboten (insbesondere Abschnitt 9 und 9.4).
  • ein Nachrichtentext ist in 1xx (informativ), 204 (kein Inhalt) und 304 (nicht modifiziert) Antworten ausdrücklich verboten (Abschnitt 4.3).
  • alle anderen Antworten enthalten einen Nachrichtentext, der jedoch eine Länge von null haben kann (Abschnitt 4.3).
467
Tomalak

Die letzte Aktualisierung der HTTP 1.1-Spezifikation ( RFC 7231 ) erlaubt explizit einem Entity Body in einer DELETE-Anforderung

Eine Payload innerhalb einer DELETE-Anforderungsnachricht hat keine definierte Semantik. Das Senden eines Payload-Body für eine DELETE-Anforderung kann dazu führen, dass einige vorhandene Implementierungen die Anforderung zurückweisen.

134
grzes

Einige Versionen von Tomcat und Jetty scheinen einen Entity-Body zu ignorieren, wenn er vorhanden ist. Was kann ein Ärgernis sein, wenn Sie beabsichtigen, es zu erhalten.

52
evan.leonard

Ein Grund für die Verwendung des Hauptteils in einer Löschanforderung ist die optimistische Parallelitätssteuerung.

Sie lesen Version 1 eines Datensatzes.

GET /some-resource/1
200 OK { id:1, status:"unimportant", version:1 }

Ihr Kollege liest Version 1 des Datensatzes.

GET /some-resource/1
200 OK { id:1, status:"unimportant", version:1 }

Ihr Kollege ändert den Datensatz und aktualisiert die Datenbank, wodurch die Version auf 2 aktualisiert wird:

PUT /some-resource/1 { id:1, status:"important", version:1 }
200 OK { id:1, status:"important", version:2 }

Sie versuchen den Datensatz zu löschen:

DELETE /some-resource/1 { id:1, version:1 }
409 Conflict

Sie sollten eine optimistische Sperrausnahme erhalten. Lesen Sie den Datensatz erneut, stellen Sie fest, dass er wichtig ist, und löschen Sie ihn möglicherweise nicht.

Ein weiterer Grund besteht darin, mehrere Datensätze gleichzeitig zu löschen (beispielsweise ein Raster mit Kontrollkästchen für die Zeilenauswahl).

DELETE /messages
[{id:1, version:2},
{id:99, version:3}]
204 No Content

Beachten Sie, dass jede Nachricht eine eigene Version hat. Vielleicht können Sie mehrere Versionen mit mehreren Kopfzeilen angeben, aber bei George ist dies einfacher und bequemer. 

Dies funktioniert in Tomcat (7.0.52) und Spring MVC (4.05), möglicherweise auch in früheren Versionen:

@RestController
public class TestController {

    @RequestMapping(value="/echo-delete", method = RequestMethod.DELETE)
    SomeBean echoDelete(@RequestBody SomeBean someBean) {
        return someBean;
    }
}
45
Neil McGuigan

Mir scheint, dass RFC 2616 dies nicht spezifiziert.

Aus Abschnitt 4.3:

Das Vorhandensein eines Nachrichtentexts in einer Anfrage wird durch die .__ signalisiert. Einfügen eines Header-Felds mit Inhaltslänge oder Übertragungskodierung in die Nachrichtenköpfe der Anforderung. Ein Nachrichtentext darf NICHT in .__ enthalten sein. eine Anforderung, wenn die Spezifikation der Anforderungsmethode (Abschnitt 5.1.1) erlaubt das Senden eines Entitätskörpers in Anforderungen nicht. Ein Server sollte einen Nachrichtentext bei jeder Anfrage lesen und weiterleiten; wenn die Anforderungsmethode enthält keine definierte Semantik für einen Entitätskörper, dann die Nachrichtentext sollte bei der Bearbeitung der Anfrage ignoriert werden.

Und Abschnitt 9.7:

Die DELETE-Methode fordert an, dass der Origin-Server die Ressource löscht identifiziert durch die Request-URI. Diese Methode kann von Menschen überschrieben werden Eingriffe (oder andere Mittel) auf dem Origin-Server. Der Client kann nicht Es kann sichergestellt werden, dass die Operation ausgeführt wurde, auch wenn die Der vom Origin-Server zurückgegebene Statuscode zeigt an, dass die Aktion wurde erfolgreich abgeschlossen. Der Server sollte jedoch nicht Erfolg angeben, es sei denn, zum Zeitpunkt der Antwort ist es beabsichtigt, die Ressource zu löschen oder in einen nicht erreichbaren Bereich zu verschieben Standort.

Eine erfolgreiche Antwort SOLLTE 200 (OK) sein, wenn die Antwort ein .__ enthält. Entität, die den Status beschreibt, 202 (Accepted), wenn für die Aktion nicht noch erlassen oder 204 (Kein Inhalt), wenn die Aktion umgesetzt wurde Die Antwort enthält jedoch keine Entität.

Wenn die Anforderung einen Cache durchläuft, identifiziert der Request-URI eine oder mehrere derzeit zwischengespeicherte Entitäten, sollten diese Einträge .__ sein. als abgestanden behandelt. Antworten auf diese Methode sind nicht cachefähig.c

Es ist also nicht ausdrücklich erlaubt oder nicht zulässig, und es besteht die Möglichkeit, dass ein Proxy den Nachrichtentext entfernt (obwohl er ihn lesen und weiterleiten sollte).

27
Adam Rosenfield

Nur ein Hinweis, wenn Sie in Ihrer DELETE-Anfrage einen Body angeben und einen Google Cloud HTTPS-Lastausgleich verwenden, wird Ihre Anfrage mit einem 400-Fehler zurückgewiesen. Ich schlug meinen Kopf gegen eine Wand und stellte fest, dass Google aus irgendeinem Grund eine DELETE-Anfrage mit einem Körper für eine missgebildete Anfrage hält.

14
Ben Fried

Es scheint, dass ElasticSearch dies verwendet: https://www.elastic.co/guide/de/elasticsearch/reference/5.x/search-request-scroll.html#_clear_scroll_api

Was bedeutet, dass Netty dies unterstützt.

Wie in Kommentaren erwähnt, ist dies möglicherweise nicht mehr der Fall

7

Dies ist nicht definiert

Eine Payload innerhalb einer DELETE-Anforderungsnachricht hat keine definierte Semantik; Das Senden eines Payload-Body für eine DELETE-Anforderung kann dazu führen, dass einige vorhandene Implementierungen, um die Anfrage abzulehnen.
https://tools.ietf.org/html/rfc7231#page-29

6
Simon Jin

Es ist erwähnenswert, dass die OpenAPI-Spezifikation für Version 3.0 die Unterstützung für DELETE-Methoden mit einem Rumpf eingestellt hat:

siehe hier und hier für Referenzen

Dies kann Ihre Implementierung, Dokumentation oder Verwendung dieser APIs in der Zukunft beeinträchtigen.

5
Clever Human

Für den Fall, dass jemand dieses Problem testet, wird Nein nicht allgemein unterstützt.

Ich teste gerade mit Sahi Pro und es ist sehr offensichtlich, dass ein http DELETE-Aufruf alle angegebenen Körperdaten entfernt (eine große Liste von IDs, die gemäß dem Endpunktentwurf in großen Mengen zu löschen sind).

Ich war mehrmals mit ihnen in Kontakt und sandte drei separate Pakete mit Scrips, Bildern und Protokollen ein, die sie überprüfen sollten, und sie haben dies immer noch nicht bestätigt. Ein fehlgeschlagener Patch und eine versäumte Telefonkonferenz durch ihren Support später, und ich habe immer noch keine solide Antwort erhalten.

Ich bin sicher, dass Sahi dies nicht unterstützt, und ich könnte mir vorstellen, dass viele andere Tools folgen.

3
parker

Ich denke nicht, dass eine gute Antwort auf diese Frage veröffentlicht wurde, obwohl es viele großartige Kommentare zu vorhandenen Antworten gegeben hat. Ich werde den Kern dieser Kommentare in eine neue Antwort heben:

Dieser Absatz aus RFC7231 wurde einige Male zitiert, was es zusammenfasst.

Eine Nutzlast in einer DELETE-Anforderungsnachricht hat keine definierte Semantik. Das Senden eines Nutzlastkörpers für eine DELETE-Anforderung kann dazu führen, dass einige vorhandene Implementierungen die Anforderung ablehnen.

Was ich bei den anderen Antworten vermisst habe, war die Implikation. Ja, es ist erlaubt, einen Body in DELETE-Anfragen aufzunehmen, aber es ist semantisch bedeutungslos. Was dies wirklich bedeutet, ist, dass das Ausgeben einer DELETE-Anforderung mit einem Anforderungshauptteil semantisch dem Nichteinschließen eines Anforderungshauptteils äquivalent ist.

Das Einfügen eines Anforderungshauptteils sollte keine Auswirkung auf die Anforderung haben, daher ist das Einfügen nie sinnvoll.

tl; dr: Technisch gesehen ist eine DELETE-Anforderung mit einem Anforderungshauptteil zulässig, dies ist jedoch niemals sinnvoll.

2
Evert

Ich konnte die DELETE-Operation mit einem Request-Body implementieren. Ich habe AWS Lambda und AWS API Gateway verwendet und die Sprache Go verwendet.

1
Dattatray

Die Verwendung von DELETE mit einem Body ist riskant ... Ich bevorzuge diesen Ansatz für Listenoperationen gegenüber REST:

Regelmäßiger Betrieb

GET/objects/ Liefert alle Objekte

GET/object /ID Liefert ein Objekt mit der angegebenen ID

POST/objects Fügt ein neues Objekt hinzu

PUT/object /ID Fügt ein Objekt mit der angegebenen ID hinzu, aktualisiert ein Objekt

DELETE/object /ID Löscht das Objekt mit der angegebenen ID

Alle benutzerdefinierten Aktionen sind POST

POST/objects / addList Fügt eine Liste oder ein Array von Objekten hinzu, die in body enthalten sind.

POST/objects / deleteList Löscht eine Liste von Objekten in body

POST/objects / customQuery Erstellt eine Liste basierend auf einer benutzerdefinierten Abfrage in body

Wenn ein Client Ihre erweiterten Operationen nicht unterstützt, kann er normal arbeiten.

0
Eliezer Garza