Zum Hauptinhalt springen

8. Repräsentationsdaten und Metadaten (Representation Data and Metadata)

8.1. Repräsentationsdaten (Representation Data)

Die mit einer HTTP-Nachricht verbundenen Repräsentationsdaten werden entweder als Inhalt der Nachricht bereitgestellt oder durch die Nachrichtensemantik und die Ziel-URI referenziert. Die Repräsentationsdaten liegen in einem Format und einer Kodierung vor, die durch die Repräsentations-Metadaten-Header-Felder definiert sind.

Der Datentyp der Repräsentationsdaten wird über die Header-Felder Content-Type und Content-Encoding bestimmt. Diese definieren ein zweischichtiges, geordnetes Kodierungsmodell:

representation-data := Content-Encoding( Content-Type( data ) )

8.2. Repräsentations-Metadaten (Representation Metadata)

Repräsentations-Header-Felder liefern Metadaten über die Repräsentation. Wenn eine Nachricht Inhalt enthält, beschreiben die Repräsentations-Header-Felder, wie diese Daten zu interpretieren sind. In einer Antwort auf eine HEAD-Anfrage beschreiben die Repräsentations-Header-Felder die Repräsentationsdaten, die im Inhalt enthalten gewesen wären, wenn dieselbe Anfrage ein GET gewesen wäre.

8.3. Content-Type

Das「Content-Type」-Header-Feld gibt den Medientyp der zugehörigen Repräsentation an: entweder die im Nachrichteninhalt eingeschlossene Repräsentation oder die ausgewählte Repräsentation, wie durch die Nachrichtensemantik bestimmt. Der angegebene Medientyp definiert sowohl das Datenformat als auch die Art und Weise, wie diese Daten von einem Empfänger verarbeitet werden sollen, im Rahmen der empfangenen Nachrichtensemantik, nachdem alle durch Content-Encoding angegebenen Inhaltskodierungen dekodiert wurden.

Content-Type = media-type

Medientypen sind in Abschnitt 8.3.1 definiert. Ein Beispiel für das Feld ist

Content-Type: text/html; charset=ISO-8859-4

Ein Sender, der eine Nachricht mit Inhalt generiert, SOLLTE (SHOULD) ein Content-Type-Header-Feld in dieser Nachricht generieren, es sei denn, der Sender kennt den beabsichtigten Medientyp der eingeschlossenen Repräsentation nicht. Wenn kein Content-Type-Header-Feld vorhanden ist, KANN (MAY) der Empfänger entweder einen Medientyp von「application/octet-stream」([RFC2046], Abschnitt 4.5.1) annehmen oder die Daten untersuchen, um deren Typ zu bestimmen.

In der Praxis konfigurieren Ressourcenbesitzer ihren Ursprungsserver nicht immer ordnungsgemäß, um den korrekten Content-Type für eine gegebene Repräsentation bereitzustellen. Einige User-Agents untersuchen den Inhalt und überschreiben in bestimmten Fällen den empfangenen Typ (siehe zum Beispiel [Sniffing]). Dieses「MIME-Sniffing」birgt das Risiko, falsche Schlussfolgerungen über die Daten zu ziehen, was den Benutzer zusätzlichen Sicherheitsrisiken aussetzen kann (z. B.「Rechteausweitung」). Darüber hinaus ist es oft der Fall, dass verschiedene Medientypen dasselbe Datenformat verwenden, sich aber nur in der beabsichtigten Verarbeitung dieser Daten unterscheiden, was durch alleinige Untersuchung der Daten nicht unterschieden werden kann. Wenn Sniffing implementiert wird, werden Implementierer ermutigt, dem Benutzer eine Möglichkeit zu bieten, es zu deaktivieren.

Obwohl Content-Type als Singleton-Feld definiert ist, wird es manchmal fälschlicherweise mehrfach generiert, was zu einem kombinierten Feldwert führt, der wie eine Liste aussieht. Empfänger versuchen oft, diesen Fehler zu behandeln, indem sie das letzte syntaktisch gültige Mitglied der Liste verwenden, was zu potenziellen Interoperabilitäts- und Sicherheitsproblemen führen kann, wenn verschiedene Implementierungen unterschiedliche Fehlerbehandlungsverhalten haben.

8.3.1. Medientyp (Media Type)

HTTP verwendet Medientypen [RFC2046] in den Header-Feldern Content-Type (Abschnitt 8.3) und Accept (Abschnitt 12.5.1), um offene und erweiterbare Datentypung und Typverhandlung bereitzustellen. Medientypen definieren sowohl ein Datenformat als auch verschiedene Verarbeitungsmodelle: wie diese Daten im Einklang mit dem Nachrichtenkontext verarbeitet werden.

media-type = type "/" subtype parameters
type = token
subtype = token

Dem type/subtype KÖNNEN (MAY) durch Semikolon getrennte Parameter (Abschnitt 5.6.6) in Form von Name/Wert-Paaren folgen. Das Vorhandensein oder Fehlen eines Parameters kann für die Verarbeitung eines Medientyps bedeutsam sein, abhängig von seiner Definition im Medientyp-Register.

Ein Parameterwert, der der Token-Produktion entspricht, kann ohne Anführungszeichen übertragen werden. Ein Parameterwert mit einem ungültigen Zeichen (d. h., der nicht der Token-Produktion entspricht) MUSS (MUST) jedoch beim Senden mit doppelten Anführungszeichen (Abschnitt 5.6.4) versehen werden.

parameter      = parameter-name "=" parameter-value
parameter-name = token
parameter-value = ( token / quoted-string )

Hinweis: Einige Empfänger von Medientyp-Parametern behandeln sie groß-/kleinschreibungssensitiv. Es wird allgemein empfohlen, Kleinbuchstaben für Parameternamen zu verwenden und die gebräuchlichste Schreibweise für Parameterwerte zu verwenden.

Medientypen sollten bei der IANA gemäß den in [BCP13] definierten Verfahren registriert werden.

Hinweis: Im Gegensatz zu einigen ähnlichen Konstrukten in anderen Header-Feldern erlauben Medientyp-Parameter keine Leerzeichen (auch keine「schlechten」) um das「=」-Zeichen herum.

8.3.2. Charset

HTTP verwendet Charset-Namen in den Header-Feldern Content-Type (Abschnitt 8.3) und Accept-Charset (veraltet; Abschnitt 12.5.2), um das Zeichenkodierungsschema einer textuellen Repräsentation anzugeben oder zu verhandeln. Ein Charset wird durch ein groß-/kleinschreibungsunabhängiges Token identifiziert.

charset = token

Charset-Namen sollten im IANA「Character Sets」-Register (http://www.iana.org/assignments/character-sets) gemäß den in Abschnitt 2 von [RFC2978] definierten Verfahren registriert werden.

Hinweis: Der「charset」-Parameter eines Medientyps kann je nach der spezifischen Medientyp-Definition unterschiedliche Semantiken haben.

Der「charset」-Parameter wird oft mit Medientypen für Textinhalte verwendet. Während Standards, die solche Medientypen definieren, die Verwendung eines bestimmten Charsets vorschreiben sollten, wenn dies die Interoperabilität verbessern könnte, werden Benutzer und Implementierer von HTTP nachdrücklich ermutigt, ein Charset explizit anzugeben, wenn es die Interpretation des empfangenen Inhalts beeinflusst, auch wenn die Medientyp-Definition in Abwesenheit des Charset-Parameters ein Charset vorsieht (wie es bei「text」-Medientypen oft der Fall ist).

8.3.3. Multipart-Typen (Multipart Types)

MIME bietet eine Reihe von「multipart」-Typen – Kapselungen einer oder mehrerer Repräsentationen innerhalb eines einzelnen Nachrichteninhalts. Alle Multipart-Typen teilen eine gemeinsame Syntax, wie in Abschnitt 5.1 von [RFC2046] definiert, und enthalten einen Boundary-Parameter als Teil des Medientyp-Wertes. Der Nachrichteninhalt ist selbst ein Protokollelement; ein Sender MUSS (MUST) nur CRLF generieren, um Zeilenumbrüche zwischen Körperteilen darzustellen.

HTTP-Nachrichtenframing verwendet die Multipart-Boundary nicht als Indikator für die Nachrichtenkörperlänge, obwohl sie von Implementierungen verwendet werden kann, die den Inhalt generieren oder verarbeiten. Beispielsweise wird der「multipart/form-data」-Typ oft verwendet, um Formulardaten in einer Anfrage zu übertragen, wie in [RFC7578] beschrieben, und der「multipart/byteranges」-Typ wird von dieser Spezifikation für die Verwendung in einigen 206 (Partial Content)-Antworten definiert (siehe Abschnitt 15.3.7).

8.4. Content-Encoding

Das「Content-Encoding」-Header-Feld gibt an, welche Inhaltskodierungen auf die Repräsentation angewendet wurden, über diejenigen hinaus, die dem Medientyp inhärent sind, und somit welche Dekodierungsmechanismen angewendet werden müssen, um Daten im Medientyp zu erhalten, auf den das Content-Type-Header-Feld verweist. Content-Encoding wird hauptsächlich verwendet, um die Komprimierung der Daten einer Repräsentation zu ermöglichen, ohne die Identität ihres zugrunde liegenden Medientyps zu verlieren.

Content-Encoding = #content-coding

Ein Beispiel für seine Verwendung ist

Content-Encoding: gzip

Wenn eine oder mehrere Kodierungen auf eine Repräsentation angewendet wurden, MUSS (MUST) der Sender, der die Kodierungen angewendet hat, ein Content-Encoding-Header-Feld generieren, das die Inhaltskodierungen in der Reihenfolge auflistet, in der sie angewendet wurden. Beachten Sie, dass die Kodierung namens「identity」für ihre spezielle Rolle in Accept-Encoding reserviert ist und daher NICHT (SHOULD NOT) eingeschlossen werden sollte.

Zusätzliche Informationen über die Kodierungsparameter können durch andere Header-Felder bereitgestellt werden, die nicht von dieser Spezifikation definiert sind.

Im Gegensatz zu Transfer-Encoding (Abschnitt 6.1 von [HTTP/1.1]) sind die in Content-Encoding aufgelisteten Kodierungen eine Eigenschaft der Repräsentation; die Repräsentation wird in Bezug auf die kodierte Form definiert, und alle anderen Metadaten über die Repräsentation beziehen sich auf die kodierte Form, sofern in der Metadaten-Definition nicht anders angegeben. Typischerweise wird die Repräsentation erst kurz vor dem Rendern oder einer analogen Verwendung dekodiert.

Wenn der Medientyp eine inhärente Kodierung enthält, wie z. B. ein Datenformat, das immer komprimiert ist, würde diese Kodierung nicht in Content-Encoding wiederholt werden, auch wenn sie zufällig derselbe Algorithmus wie eine der Inhaltskodierungen ist. Eine solche Inhaltskodierung würde nur aufgelistet werden, wenn sie aus irgendeinem bizarren Grund ein zweites Mal angewendet wird, um die Repräsentation zu bilden. Ebenso kann ein Ursprungsserver wählen, dieselben Daten als mehrere Repräsentationen zu veröffentlichen, die sich nur darin unterscheiden, ob die Kodierung als Teil von Content-Type oder Content-Encoding definiert ist, da einige User-Agents in ihrer Behandlung jeder Antwort unterschiedlich reagieren (z. B. einen「Speichern unter...」-Dialog öffnen anstatt automatische Dekompression und Rendering von Inhalten).

Ein Ursprungsserver KANN (MAY) mit einem Statuscode von 415 (Unsupported Media Type) antworten, wenn eine Repräsentation in der Anfragenachricht eine Inhaltskodierung aufweist, die nicht akzeptabel ist.

8.4.1. Inhaltskodierungen (Content Codings)

Inhaltskodierungswerte geben eine Kodierungstransformation an, die auf eine Repräsentation angewendet wurde oder angewendet werden kann. Inhaltskodierungen werden hauptsächlich verwendet, um die Komprimierung oder anderweitig nützliche Transformation einer Repräsentation zu ermöglichen, ohne die Identität ihres zugrunde liegenden Medientyps und ohne Informationsverlust zu verlieren. Häufig wird die Repräsentation in kodierter Form gespeichert, direkt übertragen und nur vom endgültigen Empfänger dekodiert.

content-coding   = token

Alle Inhaltskodierungen sind groß-/kleinschreibungsunabhängig und sollten im「HTTP Content Coding Registry」registriert werden, wie in Abschnitt 16.6.1 definiert. Sie werden in den Header-Feldern Accept-Encoding (Abschnitt 12.5.3) und Content-Encoding (Abschnitt 8.4) verwendet.

Die folgenden Inhaltskodierungen sind durch diese Spezifikation definiert:

  • compress (und x-compress): Siehe Abschnitt 8.4.1.1.
  • deflate: Siehe Abschnitt 8.4.1.2.
  • gzip (und x-gzip): Siehe Abschnitt 8.4.1.3.

8.4.1.1. Compress-Kodierung

Die「compress」-Kodierung ist eine adaptive Lempel-Ziv-Welch (LZW)-Kodierung [Welch], die üblicherweise vom UNIX-Dateikomprimierungsprogramm「compress」erzeugt wird. Ein Empfänger SOLLTE (SHOULD)「x-compress」als äquivalent zu「compress」betrachten.

8.4.1.2. Deflate-Kodierung

Die「deflate」-Kodierung ist ein「zlib」-Datenformat [RFC1950], das einen「deflate」-komprimierten Datenstrom [RFC1951] enthält, der eine Kombination des Lempel-Ziv (LZ77)-Komprimierungsalgorithmus und Huffman-Kodierung verwendet.

Hinweis: Einige nicht-konforme Implementierungen senden die「deflate」-komprimierten Daten ohne den zlib-Wrapper.

8.4.1.3. Gzip-Kodierung

Die「gzip」-Kodierung ist eine LZ77-Kodierung mit einer 32-Bit-Zyklischen Redundanzprüfung (CRC), die üblicherweise vom gzip-Dateikomprimierungsprogramm [RFC1952] erzeugt wird. Ein Empfänger SOLLTE (SHOULD)「x-gzip」als äquivalent zu「gzip」betrachten.

8.5. Content-Language

Das「Content-Language」-Header-Feld beschreibt die natürliche(n) Sprache(n) der beabsichtigten Zielgruppe für die Repräsentation. Beachten Sie, dass dies möglicherweise nicht allen in der Repräsentation verwendeten Sprachen entspricht.

Content-Language = #language-tag

Sprach-Tags sind in Abschnitt 8.5.1 definiert. Der Hauptzweck von Content-Language besteht darin, einem Benutzer die Identifizierung und Unterscheidung von Repräsentationen entsprechend den eigenen bevorzugten Sprachen des Benutzers zu ermöglichen. Wenn der Inhalt also nur für ein dänischkundiges Publikum bestimmt ist, ist das entsprechende Feld

Content-Language: da

Wenn kein Content-Language angegeben ist, ist die Standardannahme, dass der Inhalt für alle Sprachzielgruppen bestimmt ist. Dies kann bedeuten, dass der Sender ihn nicht als spezifisch für eine natürliche Sprache betrachtet, oder dass der Sender nicht weiß, für welche Sprache er bestimmt ist.

Mehrere Sprachen KÖNNEN (MAY) für Inhalte aufgelistet werden, die für mehrere Zielgruppen bestimmt sind. Beispielsweise würde eine Darstellung des「Treaty of Waitangi」, die gleichzeitig in den ursprünglichen Maori- und englischen Versionen präsentiert wird, erfordern

Content-Language: mi, en

Jedoch bedeutet die bloße Tatsache, dass mehrere Sprachen in einer Repräsentation vorhanden sind, nicht, dass sie für mehrere sprachliche Zielgruppen bestimmt ist. Ein Beispiel wäre ein Spracheinführungsbuch für Anfänger, wie「A First Lesson in Latin」, das eindeutig für die Verwendung durch ein englischkundiges Publikum bestimmt ist. In diesem Fall sollte Content-Language ordnungsgemäß nur「en」enthalten.

Content-Language KANN (MAY) auf jeden Medientyp angewendet werden – es ist nicht auf Textdokumente beschränkt.

8.5.1. Sprach-Tags (Language Tags)

Ein Sprach-Tag, wie in [RFC5646] definiert, identifiziert eine natürliche Sprache, die von Menschen gesprochen, geschrieben oder anderweitig übermittelt wird, um Informationen an andere Menschen zu kommunizieren. Computersprachen sind explizit ausgeschlossen.

HTTP verwendet Sprach-Tags in den Header-Feldern Accept-Language und Content-Language. Accept-Language verwendet die breitere language-range-Produktion, die in Abschnitt 12.5.4 definiert ist, während Content-Language die unten definierte language-tag-Produktion verwendet.

language-tag = <Language-Tag, siehe [RFC5646], Abschnitt 2.1>

Ein Sprach-Tag ist eine Sequenz von einem oder mehreren groß-/kleinschreibungsunabhängigen Sub-Tags, die jeweils durch ein Bindestrich-Zeichen ("-", %x2D) getrennt sind. In den meisten Fällen besteht ein Sprach-Tag aus einem primären Sprach-Sub-Tag, das eine breite Familie verwandter Sprachen identifiziert (z. B.「en」= Englisch), und dem optional eine Reihe von Sub-Tags folgt, die den Bereich dieser Sprache verfeinern oder eingrenzen (z. B.「en-CA」= die Varietät des Englischen, wie sie in Kanada kommuniziert wird). Leerzeichen sind innerhalb eines Sprach-Tags nicht zulässig. Beispiel-Tags umfassen:

fr, en-US, es-419, az-Arab, x-pig-latin, man-Nkoo-GN

Siehe [RFC5646] für weitere Informationen.

8.6. Content-Length

Das「Content-Length」-Header-Feld gibt die Datenlänge der zugehörigen Repräsentation als dezimale nichtnegative Ganzzahl von Oktetten an. Beim Übertragen einer Repräsentation als Inhalt bezieht sich Content-Length speziell auf die Menge der eingeschlossenen Daten, sodass sie zur Abgrenzung des Framings verwendet werden kann (z. B. Abschnitt 6.2 von [HTTP/1.1]). In anderen Fällen, in denen eine vollständige Repräsentation erwartet wird, bezieht sich Content-Length auf die aktuell ausgewählte Länge der Repräsentation.

Content-Length = 1*DIGIT

Ein Beispiel ist

Content-Length: 3495

Ein User-Agent SOLLTE (SHOULD) Content-Length in einer Anfrage senden, wenn die Methode eine Bedeutung für eingeschlossenen Inhalt definiert und er kein Transfer-Encoding sendet. Beispielsweise wird ein Content-Length-Header-Feld normalerweise in einer POST-Anfrage gesendet, selbst wenn der Wert 0 ist (was leeren Inhalt anzeigt).

Ein User-Agent SOLLTE NICHT (SHOULD NOT) ein Content-Length-Header-Feld senden, wenn die Anfragenachricht keinen Inhalt enthält und die Methodensemantik solche Daten nicht erwartet.

Ein Server KANN (MAY) ein Content-Length-Header-Feld in einer Antwort auf eine HEAD-Anfrage senden (Abschnitt 9.3.2); ein Server DARF NICHT (MUST NOT) Content-Length in einer solchen Antwort senden, es sei denn, sein Feldwert entspricht der dezimalen Anzahl von Oktetten, die im Inhalt einer Antwort gesendet worden wären, wenn dieselbe Anfrage die GET-Methode verwendet hätte.

Ein Server KANN (MAY) ein Content-Length-Header-Feld in einer 304 (Not Modified)-Antwort auf eine bedingte GET-Anfrage senden (Abschnitt 15.4.5); ein Server DARF NICHT (MUST NOT) Content-Length in einer solchen Antwort senden, es sei denn, sein Feldwert entspricht der dezimalen Anzahl von Oktetten, die im Inhalt einer 200 (OK)-Antwort auf dieselbe Anfrage gesendet worden wären.

Ein Server DARF NICHT (MUST NOT) ein Content-Length-Header-Feld in einer Antwort mit einem Statuscode von 1xx (Informational) oder 204 (No Content) senden. Ein Server DARF NICHT (MUST NOT) ein Content-Length-Header-Feld in einer 2xx (Successful)-Antwort auf eine CONNECT-Anfrage senden (Abschnitt 9.3.6).

Abgesehen von den oben definierten Fällen SOLLTE (SHOULD) ein Ursprungsserver in Abwesenheit von Transfer-Encoding ein Content-Length-Header-Feld senden, wenn die Inhaltsgröße vor dem Senden des vollständigen Header-Abschnitts bekannt ist. Dies ermöglicht nachgelagerten Empfängern, den Übertragungsfortschritt zu messen, ihre eigenen Framing-Grenzen zu kennen und die Verbindung für nachfolgende Anfragen wiederzuverwenden.

Da Content-Length für die Nachrichtenbegrenzung in HTTP/1.1 verwendet wird, kann sein Feldwert beeinflussen, wie die Nachricht von Empfängern geparst wird, selbst wenn das Nachrichtenframing nicht den HTTP/1.1-Regeln unterliegt. Wenn der Wert nicht der tatsächlichen Datenlänge der Repräsentation entspricht, können die Ergebnisse von schlechtem Nachrichtenframing bis zu potenzieller Request Smuggling oder Response Splitting reichen, abhängig von den Umständen.

Ein Sender DARF NICHT (MUST NOT) ein Content-Length-Header-Feld in einer Nachricht senden, die ein Transfer-Encoding-Header-Feld enthält.

Hinweis: Die Verwendung von Content-Length durch HTTP für Nachrichtenframing unterscheidet sich erheblich von der Verwendung desselben Feldes in MIME, wo es ein optionales Feld ist, das nur innerhalb des「message/external-body」-Medientyps verwendet wird.

8.7. Content-Location

Das「Content-Location」-Header-Feld verweist auf eine URI, die als Identifikator für eine bestimmte Ressource verwendet werden kann, die der Repräsentation im Inhalt dieser Nachricht entspricht. Mit anderen Worten, wenn man zum Zeitpunkt der Erzeugung dieser Nachricht eine GET-Anfrage an diese URI durchführen würde, würde eine 200 (OK)-Antwort dieselbe Repräsentation enthalten, die als Inhalt in dieser Nachricht eingeschlossen ist.

Content-Location = absolute-URI / partial-URI

Der Content-Location-Wert ist kein Ersatz für die Ziel-URI (Abschnitt 7.1). Es sind Repräsentations-Metadaten. Es hat dieselbe Syntax und Semantik wie das Header-Feld desselben Namens, das für MIME-Körperteile in Abschnitt 4 von [RFC2557] definiert ist. Sein Auftreten in einer HTTP-Nachricht hat jedoch einige spezielle Implikationen für HTTP-Empfänger.

Wenn Content-Location in einer 2xx (Successful)-Antwortnachricht enthalten ist und sein Wert auf eine URI mit demselben Schema, derselben Authority und demselben Pfad wie die Ziel-URI verweist, KANN (MAY) der Empfänger den Inhalt als aktuelle Repräsentation dieser Zielressource betrachten. Für eine GET (Abschnitt 9.3.1)- oder HEAD (Abschnitt 9.3.2)-Anfrage ist dies dasselbe wie die Standardsemantik, wenn kein Content-Location vom Server bereitgestellt wird. Für eine zustandsändernde Anfrage wie PUT (Abschnitt 9.3.4) oder POST (Abschnitt 9.3.3) impliziert es, dass der Antwortinhalt des Servers eine aktuelle Repräsentation dieser Zielressource enthält, wodurch sie von Repräsentationen unterschieden wird, die möglicherweise nur über die Aktion berichten (z. B.「Es hat funktioniert!」). Dies ermöglicht es Authoring-Anwendungen, ihre lokalen Kopien zu aktualisieren, ohne eine nachfolgende GET-Anfrage zu benötigen.

Wenn Content-Location in einer 2xx (Successful)-Antwortnachricht enthalten ist und sein Feldwert auf eine URI verweist, die sich von der Ziel-URI unterscheidet, behauptet der Ursprungsserver, dass die URI ein Identifikator für eine andere Ressource ist, die der eingeschlossenen Repräsentation entspricht. Eine solche Behauptung kann nur vertraut werden, wenn beide Identifikatoren denselben Ressourcenbesitzer teilen, was nicht programmatisch über HTTP bestimmt werden kann.

  • Für eine Antwort auf eine GET- oder HEAD-Anfrage ist dies ein Hinweis darauf, dass die Ziel-URI auf eine Ressource verweist, die einer Inhaltsverhandlung unterliegt, und der Content-Location-Feldwert ein spezifischerer Identifikator für die ausgewählte Repräsentation ist.

  • Für eine 201 (Created)-Antwort auf eine POST-Anfrage ist der Content-Location-Feldwert eine Referenz auf die Ressource, die die aktuelle Repräsentation enthält, die der neuen Ressource entspricht.

Andernfalls zeigt ein solcher Content-Location an, dass dieser Inhalt eine Repräsentation ist, die über den Status der angeforderten Aktion berichtet, und dass derselbe Bericht (für zukünftigen Zugriff mit GET) unter der angegebenen URI verfügbar ist. Beispielsweise kann eine Kauftransaktion, die über eine POST-Anfrage durchgeführt wird, ein Belegdokument als Inhalt der 200 (OK)-Antwort enthalten; der Content-Location-Feldwert bietet einen Identifikator zum Abrufen einer Kopie desselben Belegs in der Zukunft.

Ein User-Agent, der Content-Location in einer Anfragenachricht sendet, gibt an, dass sein Wert darauf verweist, wo der User-Agent den Inhalt der eingeschlossenen Repräsentation ursprünglich erhalten hat (vor allen Änderungen, die von diesem User-Agent vorgenommen wurden). Mit anderen Worten, der User-Agent bietet einen Rückverweis auf die Quelle der ursprünglichen Repräsentation.

Ein Ursprungsserver, der ein Content-Location-Feld in einer Anfragenachricht empfängt, MUSS (MUST) die Informationen als transienten Anfrage-Kontext und nicht als mit der Repräsentation zu speichernde Metadaten behandeln. Ein Ursprungsserver KANN (MAY) diesen Kontext verwenden, um die Verarbeitung der Anfrage zu leiten oder ihn für andere Zwecke zu speichern, wie z. B. innerhalb von Quellenverweisen oder Versionierungs-Metadaten. Ein Ursprungsserver DARF (MUST NOT) jedoch solche Kontextinformationen verwenden, um die Anfrage-Semantik zu ändern.

Wenn beispielsweise ein Client eine PUT-Anfrage an eine verhandelte Ressource stellt und der Ursprungsserver dieses PUT akzeptiert (ohne Umleitung), wird erwartet, dass der neue Zustand dieser Ressource mit der einen im PUT gelieferten Repräsentation übereinstimmt; Content-Location kann nicht als Form eines Reverse-Content-Selection-Identifikators verwendet werden, um nur eine der verhandelten Repräsentationen zu aktualisieren. Wenn der User-Agent die letztere Semantik gewollt hätte, hätte er das PUT direkt auf die Content-Location-URI angewendet.

8.8. Validator-Felder (Validator Fields)

Ressourcen-Metadaten werden als「Validator」bezeichnet, wenn sie innerhalb einer Vorbedingung (Abschnitt 13) verwendet werden können, um eine bedingte Anfrage durchzuführen (Abschnitt 13.1).

Validator-Felder übermitteln einen aktuellen Validator für die ausgewählte Repräsentation (Abschnitt 3.2).

In Antworten auf sichere Anfragen beschreiben Validator-Felder die ausgewählte Repräsentation (Abschnitt 3.2). Beachten Sie, dass die ausgewählte Repräsentation für eine gegebene Antwort je nach Statuscode-Semantik nicht notwendigerweise dieselbe ist wie die als Antwortinhalt eingeschlossene Repräsentation.

In einer erfolgreichen Antwort auf eine zustandsändernde Anfrage beschreiben Validator-Felder die neue Repräsentation, die die vorherige ausgewählte Repräsentation als Ergebnis der Verarbeitung der Anfrage ersetzt hat.

Beispielsweise kommuniziert ein ETag-Header-Feld in einer 201 (Created)-Antwort einen Validator für die durch die Anfrage erstellte Ressource, und ein ETag-Header-Feld in einer 200 (OK)-Antwort auf PUT kommuniziert einen Validator für die neue Repräsentation, die die vorherige ausgewählte Repräsentation als Ergebnis der PUT-Anfrage ersetzt hat.

Diese Spezifikation definiert zwei Formen von Metadaten, die üblicherweise verwendet werden, um den Ressourcenzustand zu beobachten und Vorbedingungen bei Anfragen zu testen: Änderungsdaten (Abschnitt 8.8.2) und opake Entity-Tags (Abschnitt 8.8.3). Zusätzliche Informationen über verschiedene Design-Überlegungen finden Sie in Abschnitt 13.2.

8.8.1. Schwach versus Stark (Weak versus Strong)

Validatoren gibt es in zwei Varianten: stark oder schwach. Schwache Validatoren sind einfach zu generieren, aber für Vergleiche weit weniger nützlich. Starke Validatoren sind ideal für Vergleiche, können aber sehr schwierig (und gelegentlich unmöglich) effizient zu generieren sein. Anstatt zu verlangen, dass alle Formen von Ressourcen derselben Stärke des Validators entsprechen, legt HTTP den Typ des verwendeten Validators offen und erlegt Beschränkungen auf, wann schwache Validatoren als Vorbedingungen verwendet werden können.

Ein「starker Validator」ist Repräsentations-Metadaten, die ihren Wert ändern, wann immer eine Änderung in den Repräsentationsdaten auftritt, die im Inhalt einer 200 (OK)-Antwort auf GET beobachtbar wäre.

Ein starker Validator kann sich aus anderen Gründen ändern als einer Änderung in den Repräsentationsdaten, wie z. B. wenn ein semantisch signifikanter Teil der Repräsentations-Metadaten geändert wird (z. B. Content-Type), aber es liegt im besten Interesse des Ursprungsservers, den Wert nur zu ändern, wenn es notwendig ist, die von entfernten Caches und Authoring-Tools gehaltenen gespeicherten Antworten zu invalidieren.

Cache-Einträge können beliebig lange Zeiträume bestehen, unabhängig von Ablaufzeiten. Daher kann ein Cache versuchen, einen Eintrag unter Verwendung eines Validators zu validieren, den er in der fernen Vergangenheit erhalten hat. Ein starker Validator ist über alle Versionen aller mit einer bestimmten Ressource verbundenen Repräsentationen im Laufe der Zeit eindeutig. Es gibt jedoch keine Implikation der Eindeutigkeit über Repräsentationen verschiedener Ressourcen hinweg (d. h., derselbe starke Validator kann gleichzeitig für Repräsentationen mehrerer Ressourcen verwendet werden und impliziert nicht, dass diese Repräsentationen äquivalent sind).

In der Praxis werden verschiedene starke Validatoren verwendet. Die besten basieren auf strikter Revisionskontrolle, wobei jede Änderung an einer Repräsentation immer dazu führt, dass ein eindeutiger Knotenname und Revisionsidentifikator zugewiesen wird, bevor die Repräsentation für GET zugänglich gemacht wird. Eine kollisionsresistente Hash-Funktion, die auf die Repräsentationsdaten angewendet wird, ist ebenfalls ausreichend, wenn die Daten vor dem Senden des Antwort-Header-Abschnitts verfügbar sind und das Digest nicht jedes Mal neu berechnet werden muss, wenn eine Validierungsanfrage empfangen wird. Wenn eine Ressource jedoch unterschiedliche Repräsentationen hat, die sich nur in ihren Metadaten unterscheiden, wie es bei der Inhaltsverhandlung über Medientypen auftreten kann, die zufällig dasselbe Datenformat teilen, muss der Ursprungsserver zusätzliche Informationen in den Validator einbeziehen, um diese Repräsentationen zu unterscheiden.

Im Gegensatz dazu ist ein「schwacher Validator」Repräsentations-Metadaten, die sich möglicherweise nicht bei jeder Änderung der Repräsentationsdaten ändern. Diese Schwäche kann auf Einschränkungen bei der Berechnung des Werts (z. B. Taktauflösung), auf die Unfähigkeit, Eindeutigkeit für alle möglichen Repräsentationen der Ressource zu gewährleisten, oder auf den Wunsch zurückzuführen sein, Repräsentationen nach einem selbstbestimmten Satz von Äquivalenzen anstatt eindeutiger Datensequenzen zu gruppieren.

Ein Ursprungsserver SOLLTE (SHOULD) ein schwaches Entity-Tag ändern, wann immer er frühere Repräsentationen als nicht akzeptabel als Ersatz für die aktuelle Repräsentation betrachtet. Mit anderen Worten, ein schwaches Entity-Tag sollte sich ändern, wann immer der Ursprungsserver möchte, dass Caches alte Antworten invalidieren.

Beispielsweise kann die Repräsentation eines Wetterberichts, der seinen Inhalt jede Sekunde basierend auf dynamischen Messungen ändert, in Sätze äquivalenter Repräsentationen (aus der Sicht des Ursprungsservers) mit demselben schwachen Validator gruppiert werden, um es zwischengespeicherten Repräsentationen zu ermöglichen, für einen angemessenen Zeitraum gültig zu sein (möglicherweise dynamisch angepasst basierend auf Serverlast oder Wetterqualität). Ebenso kann eine Änderungszeit einer Repräsentation, wenn sie nur mit einer Auflösung von einer Sekunde definiert ist, ein schwacher Validator sein, wenn es möglich ist, dass die Repräsentation zweimal während einer einzelnen Sekunde geändert und zwischen diesen Änderungen abgerufen wird.

Ebenso ist ein Validator schwach, wenn er von zwei oder mehr Repräsentationen einer gegebenen Ressource zur gleichen Zeit geteilt wird, es sei denn, diese Repräsentationen haben identische Repräsentationsdaten. Wenn beispielsweise der Ursprungsserver denselben Validator für eine Repräsentation mit angewendeter gzip-Inhaltskodierung sendet wie für eine Repräsentation ohne Inhaltskodierung, ist dieser Validator schwach. Zwei gleichzeitige Repräsentationen können jedoch denselben starken Validator teilen, wenn sie sich nur in den Repräsentations-Metadaten unterscheiden, wie z. B. wenn zwei verschiedene Medientypen für dieselben Repräsentationsdaten verfügbar sind.

Starke Validatoren sind für alle bedingten Anfragen verwendbar, einschließlich Cache-Validierung, Teilinhaltsbereiche und「Lost Update」-Vermeidung. Schwache Validatoren sind nur verwendbar, wenn der Client keine exakte Gleichheit mit zuvor erhaltenen Repräsentationsdaten erfordert, wie z. B. bei der Validierung eines Cache-Eintrags oder der Begrenzung einer Webdurchquerung auf kürzliche Änderungen.

8.8.2. Last-Modified

Das「Last-Modified」-Header-Feld in einer Antwort liefert einen Zeitstempel, der das Datum und die Uhrzeit angibt, zu denen der Ursprungsserver glaubt, dass die ausgewählte Repräsentation zuletzt geändert wurde, wie am Ende der Verarbeitung der Anfrage bestimmt.

Last-Modified = HTTP-date

Ein Beispiel für seine Verwendung ist

Last-Modified: Tue, 15 Nov 1994 12:45:26 GMT

8.8.2.1. Erzeugung (Generation)

Ein Ursprungsserver SOLLTE (SHOULD) Last-Modified für jede ausgewählte Repräsentation senden, für die ein Datum der letzten Änderung vernünftig und konsistent bestimmt werden kann, da seine Verwendung in bedingten Anfragen und bei der Bewertung der Cache-Frische ([CACHING]) unnötige Übertragungen erheblich reduzieren und die Dienstverfügbarkeit und Skalierbarkeit erheblich verbessern kann.

Eine Repräsentation ist typischerweise die Summe vieler Teile hinter der Ressourcenschnittstelle. Die Zeit der letzten Änderung wäre normalerweise die jüngste Zeit, zu der einer dieser Teile geändert wurde. Wie dieser Wert für eine gegebene Ressource bestimmt wird, ist ein Implementierungsdetail jenseits des Umfangs dieser Spezifikation. Was für HTTP wichtig ist, ist, wie Empfänger des Last-Modified-Header-Feldes seinen Wert verwenden können, um bedingte Anfragen zu stellen und die Gültigkeit lokal zwischengespeicherter Antworten zu testen.

Ein Ursprungsserver SOLLTE (SHOULD) den Last-Modified-Wert der Repräsentation so nah wie möglich an dem Zeitpunkt erhalten, zu dem er den Date-Feldwert für seine Antwort generiert. Dies ermöglicht es einem Empfänger, eine genaue Bewertung der Änderungszeit der Repräsentation vorzunehmen, insbesondere wenn sich die Repräsentation nahe dem Zeitpunkt ändert, zu dem die Antwort generiert wird.

Ein Ursprungsserver mit einer Uhr (wie in Abschnitt 5.6.7 definiert) DARF NICHT (MUST NOT) ein Last-Modified-Datum senden, das später als die Nachrichtenursprungszeit des Servers (Date) ist. Wenn die Zeit der letzten Änderung von implementierungsspezifischen Metadaten abgeleitet wird, die zu einem Zeitpunkt in der Zukunft gemäß der Uhr des Ursprungsservers ausgewertet werden, MUSS (MUST) der Ursprungsserver diesen Wert durch das Nachrichtenursprungsdatum ersetzen. Dies verhindert, dass ein zukünftiges Änderungsdatum negative Auswirkungen auf die Cache-Validierung hat.

Ein Ursprungsserver ohne Uhr DARF NICHT (MUST NOT) Last-Modified-Werte einer Antwort zuweisen, es sei denn, diese Werte sind der Ressource durch ein anderes System oder einen Benutzer mit einer zuverlässigen Uhr zugeordnet.

8.8.2.2. Vergleich (Comparison)

Eine Last-Modified-Zeit ist, wenn sie als Validator in einer Anfrage verwendet wird, implizit schwach, es sei denn, es kann abgeleitet werden, dass sie stark ist, unter Verwendung der folgenden Regeln:

  • Der Validator wird von einem Ursprungsserver mit dem tatsächlichen aktuellen Validator für die Repräsentation verglichen, und

  • Dieser Ursprungsserver weiß zuverlässig, dass sich die zugehörige Repräsentation nicht zweimal während der Sekunde geändert hat, die vom präsentierten Validator abgedeckt wird.

oder

  • Der Validator wird von einem Client in einem If-Modified-Since-, If-Unmodified-Since- oder If-Range-Header-Feld verwendet, weil der Client einen Cache-Eintrag für die zugehörige Repräsentation hat, und

  • Dieser Cache-Eintrag enthält einen Date-Wert, der die Zeit angibt, zu der der Ursprungsserver die ursprüngliche Antwort gesendet hat, und

  • Die präsentierte Last-Modified-Zeit liegt mindestens 60 Sekunden vor dem Date-Wert.

oder

  • Der Validator wird von einem Zwischen-Cache mit dem im Cache-Eintrag für die Repräsentation gespeicherten Validator verglichen, und

  • Dieser Cache-Eintrag enthält einen Date-Wert, der die Zeit angibt, zu der der Ursprungsserver die ursprüngliche Antwort gesendet hat, und

  • Die präsentierte Last-Modified-Zeit liegt mindestens 60 Sekunden vor dem Date-Wert.

Diese Methode beruht auf der Tatsache, dass wenn zwei verschiedene Antworten vom Ursprungsserver während derselben Sekunde gesendet wurden, aber beide dieselbe Last-Modified-Zeit hatten, dann mindestens eine dieser Antworten einen Date-Wert haben würde, der ihrer Last-Modified-Zeit entspricht. Die willkürliche 60-Sekunden-Grenze schützt vor der Möglichkeit, dass die Date- und Last-Modified-Werte von verschiedenen Uhren generiert werden oder zu etwas unterschiedlichen Zeiten während der Vorbereitung der Antwort. Eine Implementierung KANN (MAY) einen Wert größer als 60 Sekunden verwenden, wenn angenommen wird, dass 60 Sekunden zu kurz sind.

8.8.3. ETag

Das「ETag」-Header-Feld in einer Antwort liefert das aktuelle Entity-Tag für die ausgewählte Repräsentation, wie am Ende der Verarbeitung der Anfrage bestimmt. Ein Entity-Tag ist ein opaquer Validator zur Unterscheidung zwischen mehreren Repräsentationen derselben Ressource, unabhängig davon, ob diese mehrfachen Repräsentationen auf Ressourcenzustandsänderungen im Laufe der Zeit, auf Inhaltsverhandlung, die zu mehreren gleichzeitig gültigen Repräsentationen führt, oder auf beides zurückzuführen sind. Ein Entity-Tag besteht aus einer opaken in Anführungszeichen gesetzten Zeichenfolge, der möglicherweise ein Schwächeindikator vorangestellt ist.

ETag       = entity-tag

entity-tag = [ weak ] opaque-tag
weak = %s"W/"
opaque-tag = DQUOTE *etagc DQUOTE
etagc = %x21 / %x23-7E / obs-text
; VCHAR außer doppelten Anführungszeichen, plus obs-text

Hinweis: Früher wurde opaque-tag als quoted-string definiert ([RFC2616], Abschnitt 3.11); daher können einige Empfänger Backslash-Unescaping durchführen. Server sollten daher Backslash-Zeichen in Entity-Tags vermeiden.

Ein Entity-Tag kann aus mehreren Gründen zuverlässiger sein als ein Änderungsdatum: Es steht möglicherweise keine Uhr für den Server zur Verfügung; die Änderungszeit einer Ressource kann zu Zugriffssteuerungszwecken in die Zukunft gesetzt werden; die Auflösung einer Änderungszeit ist durch die Art der Speicherung begrenzt; verteilte Systeme können Schwierigkeiten haben, Uhren zu synchronisieren; ein Entity-Tag kann zusätzliche Metadaten einbeziehen, wie z. B. den Wert eines Content-Encoding-Header-Feldes, um Repräsentationen besser zu unterscheiden; und so weiter.

Zwei Entity-Tags sind äquivalent, wenn ihre opaque-tags zeichenweise übereinstimmen, unabhängig davon, ob eines oder beide als schwach markiert sind.

Ein Entity-Tag kann entweder ein starker Validator oder ein schwacher Validator sein, wobei stark der Standard ist. Wenn ein Ursprungsserver ein Entity-Tag für eine Repräsentation bereitstellt und die Erzeugung dieses Entity-Tags nicht alle Eigenschaften eines starken Validators erfüllt (Abschnitt 8.8.1), MUSS (MUST) der Ursprungsserver das Entity-Tag als schwach markieren, indem er seinen opaken Wert mit「W/」(groß-/kleinschreibungssensitiv) präfixiert.

ETag: W/"xyzzy"
ETag: ""

8.8.3.1. Erzeugung (Generation)

Das Prinzip hinter Entity-Tags ist, dass nur der Dienstautor die Implementierung einer Ressource gut genug kennt, um den genauesten und effizientesten Validierungsmechanismus für diese Ressource auszuwählen, und dass jeder solche Mechanismus auf eine einfache Sequenz von Oktetten für einfache Vergleiche abgebildet werden kann. Da der Wert opak ist, muss der Client nicht wissen, wie jedes Entity-Tag konstruiert ist.

Beispielsweise kann eine Ressource, auf die implementierungsspezifische Versionierung auf alle Änderungen angewendet wird, eine interne Revisionsnummer verwenden, möglicherweise kombiniert mit einem Varianzidentifikator für die Inhaltsverhandlung, um Repräsentationen genau zu unterscheiden. Andere Implementierungen können einen kollisionsresistenten Hash des Repräsentationsinhalts, eine Kombination verschiedener Dateiattribute oder einen Änderungszeitstempel mit Subsekunden-Auflösung verwenden.

Ein Ursprungsserver SOLLTE (SHOULD) ein ETag für jede ausgewählte Repräsentation senden, für die die Erkennung von Änderungen vernünftig und konsistent bestimmt werden kann, da die Verwendung des Entity-Tags in bedingten Anfragen und bei der Bewertung der Cache-Frische ([CACHING]) zu einer erheblichen Reduzierung des HTTP-Netzwerkverkehrs führen kann und ein bedeutender Beitrag zur Dienst-Skalierbarkeit und -Zuverlässigkeit sein kann.

8.8.3.2. Vergleich (Comparison)

Es gibt zwei Entity-Tag-Vergleichsfunktionen, abhängig davon, ob der Vergleichskontext die Verwendung schwacher Validatoren zulässt oder nicht:

  • Starker Vergleich: Zwei Entity-Tags sind äquivalent, wenn beide nicht schwach sind und ihre opaque-tags zeichenweise übereinstimmen.

  • Schwacher Vergleich: Zwei Entity-Tags sind äquivalent, wenn ihre opaque-tags zeichenweise übereinstimmen, unabhängig davon, ob eines oder beide als schwach markiert sind.

Das folgende Beispiel zeigt die Ergebnisse für eine Reihe von Entity-Tag-Paaren und sowohl die Ergebnisse der schwachen als auch der starken Vergleichsfunktion:

ETag 1ETag 2Starker VergleichSchwacher Vergleich
W/"1"W/"1"keine ÜbereinstimmungÜbereinstimmung
W/"1"W/"2"keine Übereinstimmungkeine Übereinstimmung
W/"1""1"keine ÜbereinstimmungÜbereinstimmung
"1""1"ÜbereinstimmungÜbereinstimmung

8.8.3.3. Beispiel: Entity-Tags, die sich bei inhaltsverhandelten Ressourcen unterscheiden

Betrachten Sie eine Ressource, die einer Inhaltsverhandlung unterliegt (Abschnitt 12.1), und bei der die als Antwort auf eine GET-Anfrage gesendeten Repräsentationen basierend auf dem Accept-Encoding-Anfrage-Header-Feld variieren (Abschnitt 12.5.3):

>> Anfrage:

GET /index HTTP/1.1
Host: www.example.com
Accept-Encoding: gzip

>> Antwort:

HTTP/1.1 200 OK
Date: Fri, 26 Mar 2010 00:05:00 GMT
ETag: "123-a"
Content-Length: 70
Vary: Accept-Encoding
Content-Type: text/plain
Content-Encoding: gzip

[...]

Für einen anderen Satz von Anfrage-Header-Feldern könnte eine andere Repräsentation vom Server gesendet werden:

>> Anfrage:

GET /index HTTP/1.1
Host: www.example.com

>> Antwort:

HTTP/1.1 200 OK
Date: Fri, 26 Mar 2010 00:05:00 GMT
ETag: "123-b"
Content-Length: 400
Vary: Accept-Encoding
Content-Type: text/plain

[...]

Der Unterschied in den Entity-Tags in diesen beiden Antworten zeigt an, dass die gesendeten Repräsentationen unterschiedliche Daten enthalten. Die in diesem Fall verwendeten starken Entity-Tags erlauben die Verwendung bedingter Anfragen sowohl für Cache-Validierung als auch für Bereichsanfragen.

Im Gegensatz dazu könnte ein Ursprungsserver, der eine gzip-kodierte Repräsentation on-the-fly generiert, ohne nach einer früheren Version der Repräsentation zu suchen, die möglicherweise bereits generiert wurde, schwache Entity-Tags verwenden, um äquivalenten Inhalt anzuzeigen:

>> Antwort:

HTTP/1.1 200 OK
Date: Fri, 26 Mar 2010 00:05:00 GMT
ETag: W/"123"
Content-Length: 70
Vary: Accept-Encoding
Content-Type: text/plain
Content-Encoding: gzip

[...]

In diesem Fall nimmt der Server an, dass die komprimierte Version der Repräsentation der unkomprimierten Version äquivalent ist, während er gleichzeitig Versionen nicht gut genug verfolgt, um den starken Validator zu bestimmen.