Zum Hauptinhalt springen

13. Caching in HTTP (HTTP-Zwischenspeicherung)

13 Caching in HTTP

HTTP wird typischerweise für verteilte Informationssysteme verwendet, bei denen die Leistung durch die Verwendung von Antwort-Caches verbessert werden kann. Das HTTP/1.1-Protokoll enthält eine Reihe von Elementen, die das Caching so gut wie möglich funktionieren lassen sollen. Da diese Elemente von anderen Aspekten des Protokolls nicht zu trennen sind und da sie miteinander interagieren, ist es nützlich, das grundlegende Caching-Design von HTTP getrennt von den ausführlichen Beschreibungen von method, header, response code usw. zu beschreiben.

Caching wäre nutzlos, wenn es die Leistung nicht erheblich verbessern würde. Das Ziel des Cachings in HTTP/1.1 ist es, in vielen Fällen die Notwendigkeit zu beseitigen, Anfragen zu senden, und in vielen anderen Fällen die Notwendigkeit zu beseitigen, vollständige Antworten zu senden. Ersteres verringert die Anzahl der für viele Operationen erforderlichen Netzwerkumläufe; zu diesem Zweck verwenden wir einen "expiration"-Mechanismus (siehe Abschnitt 13.2). Letzteres verringert den Bedarf an Netzwerkbandbreite; zu diesem Zweck verwenden wir einen "validation"-Mechanismus (siehe Abschnitt 13.3).

Anforderungen an Leistung, Verfügbarkeit und den Betrieb ohne Verbindung erfordern, dass wir das Ziel der semantischen Transparenz lockern können. Das HTTP/1.1-Protokoll erlaubt es Ursprungsservern, Caches und Clients, die Transparenz bei Bedarf ausdrücklich zu verringern. Da jedoch nicht transparentes Verhalten unerfahrene Benutzer verwirren kann und mit bestimmten Serveranwendungen (etwa solchen zur Bestellung von Waren) unvereinbar sein kann, verlangt das Protokoll, dass die Transparenz nur dann gelockert wird,

  - wenn sie von einem Client oder Ursprungsserver gelockert wird, nur durch eine ausdrückliche Anfrage auf Protokollebene

- wenn sie von einem Cache oder Client gelockert wird, nur mit einer ausdrücklichen Warnung an den Endbenutzer

Daher stellt das HTTP/1.1-Protokoll diese wichtigen Elemente bereit:

  1. Protokollmerkmale, die vollständige semantische Transparenz bieten, wenn dies von allen Beteiligten gefordert wird.

2. Protokollmerkmale, die es einem Ursprungsserver oder Benutzeragenten erlauben, nicht transparenten Betrieb ausdrücklich anzufordern und zu steuern.

3. Protokollmerkmale, die es einem Cache erlauben, Antworten Warnungen beizufügen, die die geforderte Annäherung an semantische Transparenz nicht wahren.

Ein Grundprinzip ist, dass es den Clients möglich sein muss, jede mögliche Lockerung der semantischen Transparenz zu erkennen.

  Note: Wer den Server, den Cache oder den Client implementiert, kann mit Entwurfsentscheidungen konfrontiert werden, die in dieser Spezifikation nicht ausdrücklich erörtert werden. Wenn eine Entscheidung die semantische Transparenz beeinflussen könnte, sollte der Implementierer im Zweifel die Transparenz wahren, es sei denn, eine sorgfältige und vollständige Analyse zeigt erhebliche Vorteile darin, die Transparenz zu durchbrechen.

13.1.1 Cache Correctness (Cache-Korrektheit)​

Ein korrekter Cache muss (MUST) auf eine Anfrage mit der aktuellsten vom Cache gehaltenen Antwort antworten, die für die Anfrage geeignet ist (siehe Abschnitte 13.2.5, 13.2.6 und 13.12) und eine der folgenden Bedingungen erfüllt:

  1. Sie wurde durch Revalidierung der Antwort beim Ursprungsserver auf Gleichwertigkeit mit dem geprüft, was der Ursprungsserver zurückgegeben hätte (Abschnitt 13.3);

2. Sie ist "frisch genug" (siehe Abschnitt 13.2). Im Standardfall bedeutet dies, dass sie die am wenigsten restriktive Frischeanforderung von Client, Ursprungsserver und Cache erfüllt (siehe Abschnitt 14.9); wenn der Ursprungsserver dies so festlegt, ist es allein die Frischeanforderung des Ursprungsservers.

Wenn eine gespeicherte Antwort nach der restriktivsten Frischeanforderung sowohl des Clients als auch des Ursprungsservers nicht "frisch genug" ist, kann (MAY) der Cache die Antwort in sorgfältig abgewogenen Umständen dennoch mit der geeigneten Warning-Headerzeile zurückgeben (siehe Abschnitte 13.1.5 und 14.46), es sei denn, eine solche Antwort ist verboten (z. B. durch eine "no-store" cache-directive oder eine "no-cache" cache-request-directive; siehe Abschnitt 14.9).

3. Es handelt sich um eine geeignete 304 (Not Modified)-, 305 (Proxy Redirect)- oder Fehlerantwort (4xx oder 5xx).

Wenn der Cache nicht mit dem Ursprungsserver kommunizieren kann, sollte (SHOULD) ein korrekter Cache wie oben antworten, wenn die Antwort korrekt aus dem Cache bereitgestellt werden kann; andernfalls muss (MUST) er einen Fehler oder eine Warnung zurückgeben, die anzeigt, dass ein Kommunikationsausfall vorlag.

Wenn ein Cache eine Antwort empfängt (entweder eine vollständige Antwort oder eine 304 (Not Modified)-Antwort), die er normalerweise an den anfragenden Client weiterleiten würde, und die empfangene Antwort nicht mehr frisch ist, sollte (SHOULD) der Cache sie an den anfragenden Client weiterleiten, ohne eine neue Warnung hinzuzufügen (aber ohne vorhandene Warning-Headerzeilen zu entfernen). Ein Cache sollte (SHOULD NOT) nicht versuchen, eine Antwort allein deshalb zu revalidieren, weil diese Antwort auf dem Transportweg veraltet ist; dies könnte zu einer Endlosschleife führen. Ein Benutzeragent, der eine veraltete Antwort ohne Warnung empfängt, kann (MAY) dem Benutzer einen Warnhinweis anzeigen.

13.1.2 Warnings (Warnungen)​

Immer wenn ein Cache eine Antwort zurückgibt, die weder aus erster Hand noch "frisch genug" ist (im Sinne von Bedingung 2 in Abschnitt 13.1.1), muss (MUST) er zu diesem Zweck eine Warnung unter Verwendung einer allgemeinen Warning-Headerzeile beifügen. Die Warning-Headerzeile und die derzeit definierten Warnungen sind in Abschnitt 14.46 beschrieben. Die Warnung ermöglicht es Clients, geeignete Maßnahmen zu ergreifen.

Warnungen können (MAY) auch für andere Zwecke verwendet werden, sowohl cache-bezogene als auch andere. Die Verwendung einer Warnung statt eines Fehler-Statuscodes unterscheidet diese Antworten von echten Fehlern.

Warnungen werden dreistellige Warncodes zugewiesen. Die erste Ziffer gibt an, ob die Warnung nach einer erfolgreichen Revalidierung aus einem gespeicherten Cache-Eintrag gelöscht werden muss (MUST) oder nicht gelöscht werden darf (MUST NOT):

1xx Warnungen, die die Frische oder den Revalidierungsstatus der Antwort beschreiben und daher nach einer erfolgreichen Revalidierung gelöscht werden müssen (MUST). 1xx-Warncodes können (MAY) von einem Cache nur beim Validieren eines zwischengespeicherten Eintrags erzeugt werden. Von Clients dürfen sie nicht erzeugt werden (MUST NOT).

2xx Warnungen, die einen Aspekt des Entitätskörpers oder der Entitäts-Headerzeilen beschreiben, der durch eine Revalidierung nicht behoben wird (zum Beispiel eine verlustbehaftete Kompression der Entitätskörper), und die nach einer erfolgreichen Revalidierung nicht gelöscht werden dürfen (MUST NOT).

Die Definitionen der Codes selbst finden sich in Abschnitt 14.46.

HTTP/1.0-Caches werden alle Warnungen in Antworten zwischenspeichern, ohne diejenigen der ersten Kategorie zu löschen. Warnungen in Antworten, die an HTTP/1.0-Caches weitergegeben werden, tragen ein zusätzliches Feld warning-date, das einen künftigen HTTP/1.1-Empfänger davor bewahrt, einer fälschlich zwischengespeicherten Warnung zu glauben.

Warnungen tragen außerdem einen Warnungstext. Der Text kann (MAY) in jeder geeigneten natürlichen Sprache abgefasst sein (vielleicht basierend auf den Accept-Headerzeilen des Clients) und eine OPTIONAL-Angabe darüber enthalten, welcher Zeichensatz verwendet wird.

Einer Antwort können (MAY) mehrere Warnungen beigefügt werden (entweder vom Ursprungsserver oder von einem Cache), einschließlich mehrerer Warnungen mit derselben Codenummer. Beispielsweise könnte ein Server dieselbe Warnung mit Texten sowohl auf Englisch als auch auf Baskisch bereitstellen.

Wenn einer Antwort mehrere Warnungen beigefügt sind, kann es unpraktisch oder unvernünftig sein, sie alle dem Benutzer anzuzeigen. Diese Version von HTTP legt keine strengen Prioritätsregeln dafür fest, welche Warnungen in welcher Reihenfolge anzuzeigen sind, schlägt aber einige Heuristiken vor.

13.1.3 Cache-control Mechanisms (Cache-Kontrollmechanismen)​

Die grundlegenden Cache-Mechanismen in HTTP/1.1 (vom Server festgelegte Ablaufzeiten und Validatoren) sind implizite Direktiven an Caches. In manchen Fällen muss ein Server oder Client den HTTP-Caches ausdrückliche Direktiven bereitstellen. Zu diesem Zweck verwenden wir die Cache-Control-Headerzeile.

Die Cache-Control-Headerzeile erlaubt es einem Client oder Server, in Anfragen oder Antworten eine Vielzahl von Direktiven zu übertragen. Diese Direktiven setzen typischerweise die Standard-Cache-Algorithmen außer Kraft. Als allgemeine Regel gilt: Wenn es einen offensichtlichen Konflikt zwischen Headerwerten gibt, wird die restriktivste Auslegung angewandt (also diejenige, die am ehesten die semantische Transparenz wahrt). In manchen Fällen werden cache-control-Direktiven jedoch ausdrücklich als Abschwächung der Annäherung an die semantische Transparenz angegeben (zum Beispiel "max-stale" oder "public").

Die cache-control-Direktiven sind in Abschnitt 14.9 ausführlich beschrieben.

13.1.4 Explicit User Agent Warnings (Explizite Benutzeragenten-Warnungen)​

Viele Benutzeragenten ermöglichen es Benutzern, die grundlegenden Cache-Mechanismen außer Kraft zu setzen. Beispielsweise könnte der Benutzeragent es dem Benutzer erlauben, festzulegen, dass zwischengespeicherte Entitäten (sogar ausdrücklich veraltete) niemals revalidiert werden. Oder der Benutzeragent könnte gewohnheitsmäßig "Cache-Control: max-stale=3600" an jede Anfrage anhängen. Der Benutzeragent sollte (SHOULD NOT) weder nicht transparentes Verhalten noch Verhalten, das zu einer ungewöhnlich unwirksamen Zwischenspeicherung führt, als Standard wählen, kann (MAY) aber durch eine ausdrückliche Handlung des Benutzers ausdrücklich dazu konfiguriert werden.

Wenn der Benutzer die grundlegenden Cache-Mechanismen außer Kraft gesetzt hat, sollte (SHOULD) der Benutzeragent dem Benutzer ausdrücklich anzeigen, wann immer dies zur Anzeige von Informationen führt, die die Transparenzanforderungen des Servers möglicherweise nicht erfüllen (insbesondere wenn die angezeigte Entität bekanntermaßen veraltet ist). Da das Protokoll es dem Benutzeragenten normalerweise erlaubt festzustellen, ob Antworten veraltet sind oder nicht, muss dieser Hinweis nur angezeigt werden, wenn dies tatsächlich geschieht. Der Hinweis muss kein Dialogfeld sein; er könnte ein Symbol sein (zum Beispiel das Bild eines verrottenden Fisches) oder ein anderer Indikator.

Wenn der Benutzer die Cache-Mechanismen in einer Weise außer Kraft gesetzt hat, die die Wirksamkeit von Caches ungewöhnlich verringert, sollte (SHOULD) der Benutzeragent diesen Zustand dem Benutzer fortlaufend anzeigen (zum Beispiel durch die Anzeige eines Bildes von brennender Währung), damit der Benutzer nicht versehentlich übermäßige Ressourcen verbraucht oder unter übermäßiger Latenz leidet.

13.1.5 Exceptions to the Rules and Warnings (Ausnahmen von den Regeln und Warnungen)​

In manchen Fällen kann (MAY) der Betreiber eines Caches diesen so konfigurieren, dass er veraltete Antworten zurückgibt, auch wenn dies von Clients nicht angefordert wird. Diese Entscheidung sollte nicht leichtfertig getroffen werden, kann aber aus Gründen der Verfügbarkeit oder Leistung notwendig sein, besonders wenn der Cache schlecht mit dem Ursprungsserver verbunden ist. Immer wenn ein Cache eine veraltete Antwort zurückgibt, muss (MUST) er sie als solche kennzeichnen (unter Verwendung einer Warning-Headerzeile), sodass die Client-Software den Benutzer darauf hinweisen kann, dass ein mögliches Problem bestehen könnte.

Dies ermöglicht es dem Benutzeragenten außerdem, Schritte zu unternehmen, um eine Antwort aus erster Hand oder eine frische Antwort zu erhalten. Aus diesem Grund sollte (SHOULD NOT) ein Cache keine veraltete Antwort zurückgeben, wenn der Client ausdrücklich eine Antwort aus erster Hand oder eine frische Antwort anfordert, es sei denn, es ist aus technischen oder politischen Gründen unmöglich, dem nachzukommen.

13.1.6 Client-controlled Behavior (Clientgesteuertes Verhalten)​

Während der Ursprungsserver (und in geringerem Maße Zwischen-Caches, durch ihren Beitrag zum Alter einer Antwort) die primäre Quelle von Ablaufinformationen ist, muss der Client in manchen Fällen die Entscheidung eines Caches darüber steuern, ob eine zwischengespeicherte Antwort ohne Revalidierung zurückgegeben wird. Clients tun dies unter Verwendung mehrerer Direktiven der Cache-Control-Headerzeile.

Die Anfrage eines Clients kann (MAY) das Höchstalter angeben, das er für eine nicht revalidierte Antwort zu akzeptieren bereit ist; die Angabe des Werts null zwingt den oder die Caches, alle Antworten zu revalidieren. Ein Client kann (MAY) auch die Mindestzeit angeben, die verbleibt, bevor eine Antwort abläuft. Beide Optionen erhöhen die Beschränkungen für das Verhalten von Caches und können daher die Annäherung des Caches an die semantische Transparenz nicht weiter lockern.

Ein Client kann (MAY) außerdem angeben, dass er veraltete Antworten akzeptiert, bis zu einem bestimmten Höchstmaß an Veraltung. Dies lockert die Beschränkungen für die Caches und kann daher die vom Ursprungsserver festgelegten Beschränkungen der semantischen Transparenz verletzen, kann aber notwendig sein, um den Betrieb ohne Verbindung oder hohe Verfügbarkeit bei schlechter Konnektivität zu unterstützen.

13.2 Expiration Model (Ablaufmodell)​

13.2.1 Server-Specified Expiration (Vom Server angegebener Ablauf)​

HTTP-Caching funktioniert am besten, wenn Caches gänzlich vermeiden können, Anfragen an den Ursprungsserver zu stellen. Der primäre Mechanismus zur Vermeidung von Anfragen besteht darin, dass ein Ursprungsserver eine ausdrückliche Ablaufzeit in der Zukunft bereitstellt und damit anzeigt, dass eine Antwort verwendet werden kann (MAY), um spätere Anfragen zu erfüllen. Mit anderen Worten: Ein Cache kann eine frische Antwort zurückgeben, ohne zuerst den Server zu kontaktieren.

Unsere Erwartung ist, dass Server Antworten ausdrückliche Ablaufzeiten in der Zukunft zuweisen, in der Annahme, dass sich die Entität vor Erreichen der Ablaufzeit nicht in semantisch bedeutsamer Weise ändern wird. Dies wahrt normalerweise die semantische Transparenz, solange die Ablaufzeiten des Servers sorgfältig gewählt sind.

Der Ablaufmechanismus gilt nur für Antworten, die einem Cache entnommen werden, und nicht für Antworten aus erster Hand, die unmittelbar an den anfragenden Client weitergeleitet werden.

Wenn ein Ursprungsserver einen semantisch transparenten Cache zwingen möchte, jede Anfrage zu revalidieren, kann (MAY) er eine ausdrückliche Ablaufzeit in der Vergangenheit zuweisen. Dies bedeutet, dass die Antwort immer veraltet ist, und daher sollte (SHOULD) der Cache sie revalidieren, bevor er sie für spätere Anfragen verwendet. Für eine restriktivere Möglichkeit, die Revalidierung zu erzwingen, siehe Abschnitt 14.9.4.

Wenn ein Ursprungsserver jeden HTTP/1.1-Cache, wie auch immer er konfiguriert ist, zwingen möchte, jede Anfrage zu revalidieren, sollte (SHOULD) er die cache-control-Direktive "must-revalidate" verwenden (siehe Abschnitt 14.9).

Server legen ausdrückliche Ablaufzeiten entweder mit der Expires-Headerzeile oder mit der max-age-Direktive der Cache-Control-Headerzeile fest.

Eine Ablaufzeit kann nicht dazu verwendet werden, einen Benutzeragenten zu zwingen, seine Anzeige zu aktualisieren oder eine Ressource neu zu laden; ihre Semantik gilt nur für Cache-Mechanismen, und solche Mechanismen müssen den Ablaufstatus einer Ressource nur prüfen, wenn eine neue Anfrage für diese Ressource eingeleitet wird. Eine Erklärung des Unterschieds zwischen Caches und Historienmechanismen findet sich in Abschnitt 13.13.

13.2.2 Heuristic Expiration (Heuristische Ablauf)​

Da Ursprungsserver nicht immer ausdrückliche Ablaufzeiten bereitstellen, weisen HTTP-Caches typischerweise heuristische Ablaufzeiten zu und verwenden dabei Algorithmen, die andere Headerwerte (wie die Last-Modified-Zeit) nutzen, um eine plausible Ablaufzeit zu schätzen. Die HTTP/1.1-Spezifikation gibt keine bestimmten Algorithmen an, erlegt deren Ergebnissen aber Beschränkungen für den schlimmsten Fall auf. Da heuristische Ablaufzeiten die semantische Transparenz beeinträchtigen können, sollten sie mit Vorsicht verwendet werden, und wir ermutigen Ursprungsserver, so weit wie möglich ausdrückliche Ablaufzeiten bereitzustellen.

13.2.3 Age Calculations (Altersberechnungen)​

Um zu wissen, ob ein zwischengespeicherter Eintrag frisch ist, muss ein Cache wissen, ob sein Alter seine Frischelebensdauer übersteigt. Wie Letztere berechnet wird, erörtern wir in Abschnitt 13.2.4; dieser Abschnitt beschreibt, wie das Alter einer Antwort oder eines Cache-Eintrags berechnet wird.

In dieser Erörterung verwenden wir den Begriff "now" im Sinne von "der aktuelle Wert der Uhr auf dem Host, der die Berechnung durchführt". Hosts, die HTTP verwenden, insbesondere aber Hosts, auf denen Ursprungsserver und Caches laufen, sollten (SHOULD) NTP [28] oder ein ähnliches Protokoll verwenden, um ihre Uhren mit einem global genauen Zeitstandard zu synchronisieren.

HTTP/1.1 verlangt von Ursprungsservern, nach Möglichkeit zu jeder Antwort eine Date-Headerzeile zu senden, die den Zeitpunkt angibt, zu dem die Antwort erzeugt wurde (siehe Abschnitt 14.18). Wir verwenden den Begriff "date_value", um den Wert der Date-Headerzeile in einer für arithmetische Operationen geeigneten Form zu bezeichnen.

HTTP/1.1 verwendet die Age-Antwort-Headerzeile, um das geschätzte Alter der Antwortnachricht zu übermitteln, wenn sie von einem Cache bezogen wird. Der Age-Feldwert ist die Schätzung des Caches für die Zeitspanne, die vergangen ist, seit die Antwort vom Ursprungsserver erzeugt oder revalidiert wurde.

Im Wesentlichen ist der Age-Wert die Summe der Zeit, die die Antwort in jedem der Caches entlang des Pfads vom Ursprungsserver verweilt hat, plus die Zeitspanne, die sie auf Netzwerkpfaden im Transit war.

Wir verwenden den Begriff "age_value", um den Wert der Age-Headerzeile in einer für arithmetische Operationen geeigneten Form zu bezeichnen.

Das Alter einer Antwort kann auf zwei völlig unabhängige Weisen berechnet werden:

  1. now minus date_value, wenn die lokale Uhr hinreichend gut mit der Uhr des Ursprungsservers synchronisiert ist. Ist das Ergebnis negativ, wird es durch null ersetzt.

2. age_value, wenn alle Caches entlang des Antwortpfads HTTP/1.1 implementieren.

Da wir zwei unabhängige Möglichkeiten haben, das Alter einer Antwort bei ihrem Empfang zu berechnen, können wir diese wie folgt kombinieren:

       corrected_received_age = max(now - date_value, age_value)

und solange wir entweder nahezu synchronisierte Uhren oder durchgängige HTTP/1.1-Pfade haben, erhält man ein zuverlässiges (konservatives) Ergebnis.

Aufgrund von netzwerkbedingten Verzögerungen kann zwischen dem Zeitpunkt, zu dem ein Server eine Antwort erzeugt, und dem Zeitpunkt, zu dem sie beim nächsten ausgehenden Cache oder Client empfangen wird, ein erhebliches Intervall vergehen. Ohne Korrektur könnte diese Verzögerung zu unangemessen niedrigen Altern führen.

Da die Anfrage, die den zurückgegebenen Age-Wert zur Folge hatte, vor der Erzeugung dieses Age-Werts eingeleitet worden sein muss, können wir Verzögerungen durch das Netzwerk korrigieren, indem wir den Zeitpunkt aufzeichnen, zu dem die Anfrage eingeleitet wurde. Wenn dann ein Age-Wert empfangen wird, muss (MUST) er relativ zum Zeitpunkt der Einleitung der Anfrage ausgelegt werden, nicht zum Zeitpunkt des Empfangs der Antwort. Dieser Algorithmus führt unabhängig vom Ausmaß der Verzögerung zu konservativem Verhalten. Wir berechnen also:

      corrected_initial_age = corrected_received_age
+ (now - request_time)

wobei "request_time" der Zeitpunkt (nach der lokalen Uhr) ist, zu dem die Anfrage gesendet wurde, die diese Antwort hervorgerufen hat.

Zusammenfassung des Algorithmus zur Altersberechnung, wenn ein Cache eine Antwort empfängt:

      /*
* age_value
* is the value of Age: header received by the cache with
* this response.
* date_value
* is the value of the origin server's Date: header
* request_time
* is the (local) time when the cache made the request
* that resulted in this cached response
* response_time
* is the (local) time when the cache received the
* response
* now
* is the current (local) time
*/

apparent_age = max(0, response_time - date_value);
corrected_received_age = max(apparent_age, age_value);
response_delay = response_time - request_time;
corrected_initial_age = corrected_received_age + response_delay;
resident_time = now - response_time;
current_age = corrected_initial_age + resident_time;

Das current_age eines Cache-Eintrags wird berechnet, indem die Zeitspanne (in Sekunden) seit der letzten Revalidierung des Cache-Eintrags durch den Ursprungsserver zum corrected_initial_age addiert wird. Wenn aus einem Cache-Eintrag eine Antwort erzeugt wird, muss (MUST) der Cache eine einzelne Age-Headerzeile in die Antwort aufnehmen, deren Wert gleich dem current_age des Cache-Eintrags ist.

Das Vorhandensein einer Age-Headerzeile in einer Antwort impliziert, dass die Antwort nicht aus erster Hand ist. Die Umkehrung gilt jedoch nicht, da das Fehlen einer Age-Headerzeile in einer Antwort nicht impliziert, dass die Antwort aus erster Hand ist, es sei denn, alle Caches entlang des Anfragepfads sind mit HTTP/1.1 konform (d. h. ältere HTTP-Caches implementierten die Age-Headerzeile nicht).

13.2.4 Expiration Calculations (Ablaufberechnungen)​

Um zu entscheiden, ob eine Antwort frisch oder veraltet ist, müssen wir ihre Frischelebensdauer mit ihrem Alter vergleichen. Das Alter wird wie in Abschnitt 13.2.3 beschrieben berechnet; dieser Abschnitt beschreibt, wie die Frischelebensdauer berechnet und wie festgestellt wird, ob eine Antwort abgelaufen ist. In der folgenden Erörterung können die Werte in jeder für arithmetische Operationen geeigneten Form dargestellt werden.

Wir verwenden den Begriff "expires_value", um den Wert der Expires-Headerzeile zu bezeichnen. Wir verwenden den Begriff "max_age_value", um einen geeigneten Wert der Anzahl von Sekunden zu bezeichnen, die von der "max-age"-Direktive der Cache-Control-Headerzeile in einer Antwort mitgeführt werden (siehe Abschnitt 14.9.3).

Die max-age-Direktive hat Vorrang vor Expires, wenn also max-age in einer Antwort vorhanden ist, lautet die Berechnung einfach:

      freshness_lifetime = max_age_value

Andernfalls, wenn Expires in der Antwort vorhanden ist, lautet die Berechnung:

      freshness_lifetime = expires_value - date_value

Beachten Sie, dass keine dieser Berechnungen anfällig für Uhrenversatz ist, da alle Informationen vom Ursprungsserver stammen.

Wenn weder Expires noch Cache-Control: max-age noch Cache-Control: s-maxage (siehe Abschnitt 14.9.3) in der Antwort erscheint und die Antwort keine weiteren Einschränkungen der Zwischenspeicherung enthält, kann (MAY) der Cache eine Frischelebensdauer heuristisch berechnen. Der Cache muss (MUST) jeder Antwort, deren Alter mehr als 24 Stunden beträgt, die Warnung 113 beifügen, falls diese Warnung noch nicht hinzugefügt wurde.

Wenn die Antwort außerdem eine Last-Modified-Zeit hat, sollte (SHOULD) der heuristische Ablaufwert nicht größer sein als ein Bruchteil des seit dieser Zeit verstrichenen Intervalls. Eine typische Einstellung dieses Bruchteils könnte 10 % sein.

Die Berechnung, mit der festgestellt wird, ob eine Antwort abgelaufen ist, ist recht einfach:

      response_is_fresh = (freshness_lifetime > current_age)

13.2.5 Disambiguating Expiration Values (Klärung von Ablaufwerten)​

Da Ablaufwerte optimistisch zugewiesen werden, ist es möglich, dass zwei Caches frische Werte für dieselbe Ressource enthalten, die unterschiedlich sind.

Wenn ein Client, der einen Abruf durchführt, eine nicht aus erster Hand stammende Antwort für eine Anfrage empfängt, die in seinem eigenen Cache bereits frisch war, und die Date-Headerzeile in seinem vorhandenen Cache-Eintrag neuer ist als die Date in der neuen Antwort, kann (MAY) der Client die Antwort ignorieren. Ist dies der Fall, kann (MAY) er die Anfrage mit der Direktive "Cache-Control: max-age=0" wiederholen (siehe Abschnitt 14.9), um eine Prüfung beim Ursprungsserver zu erzwingen.

Wenn ein Cache zwei frische Antworten für dieselbe Darstellung mit unterschiedlichen Validatoren hat, muss (MUST) er diejenige mit der neueren Date-Headerzeile verwenden. Diese Situation kann entstehen, weil der Cache Antworten von anderen Caches zusammenführt oder weil ein Client ein Neuladen oder eine Revalidierung eines scheinbar frischen Cache-Eintrags angefordert hat.

13.2.6 Disambiguating Multiple Responses (Klärung mehrerer Antworten)​

Da ein Client Antworten über mehrere Pfade empfangen kann, sodass einige Antworten durch eine Gruppe von Caches und andere Antworten durch eine andere Gruppe von Caches fließen, kann ein Client Antworten in einer anderen Reihenfolge empfangen als der, in der der Ursprungsserver sie gesendet hat. Wir möchten, dass der Client die zuletzt erzeugte Antwort verwendet, auch wenn ältere Antworten noch scheinbar frisch sind.

Weder das Entitäts-Tag noch der Ablaufwert können den Antworten eine Reihenfolge auferlegen, da es möglich ist, dass eine spätere Antwort absichtlich eine frühere Ablaufzeit mitführt. Die Date-Werte sind mit einer Granularität von einer Sekunde geordnet.

Wenn ein Client versucht, einen Cache-Eintrag zu revalidieren, und die empfangene Antwort eine Date-Headerzeile enthält, die älter zu sein scheint als die des vorhandenen Eintrags, sollte (SHOULD) der Client die Anfrage unbedingt wiederholen und

       Cache-Control: max-age=0

einschließen, um alle Zwischen-Caches zu zwingen, ihre Kopien direkt beim Ursprungsserver zu validieren, oder

       Cache-Control: no-cache

einschließen, um alle Zwischen-Caches zu zwingen, eine neue Kopie vom Ursprungsserver zu beziehen.

Wenn die Date-Werte gleich sind, kann (MAY) der Client beide Antworten verwenden (oder kann (MAY), wenn er äußerst umsichtig ist, eine neue Antwort anfordern). Server dürfen (MUST NOT) nicht darauf vertrauen, dass Clients deterministisch zwischen Antworten wählen können, die innerhalb derselben Sekunde erzeugt wurden, wenn sich ihre Ablaufzeiten überschneiden.

13.3 Validation Model (Validierungsmodell)​

Wenn ein Cache einen veralteten Eintrag hat, den er als Antwort auf die Anfrage eines Clients verwenden möchte, muss er zunächst beim Ursprungsserver (oder möglicherweise bei einem Zwischen-Cache mit einer frischen Antwort) prüfen, ob sein zwischengespeicherter Eintrag noch verwendbar ist. Wir nennen dies das "Validieren" des Cache-Eintrags. Da wir nicht den Aufwand für die erneute Übertragung der vollständigen Antwort tragen wollen, wenn der zwischengespeicherte Eintrag gut ist, und nicht den Aufwand für einen zusätzlichen Umlauf tragen wollen, wenn der zwischengespeicherte Eintrag ungültig ist, unterstützt das HTTP/1.1-Protokoll die Verwendung bedingter Methoden.

Die wichtigsten Protokollmerkmale zur Unterstützung bedingter Methoden sind diejenigen, die "cache validator" betreffen. Wenn ein Ursprungsserver eine vollständige Antwort erzeugt, fügt er ihr eine Art Validator bei, der zusammen mit dem Cache-Eintrag aufbewahrt wird. Wenn ein Client (Benutzeragent oder Proxy-Cache) eine bedingte Anfrage für eine Ressource stellt, für die er einen Cache-Eintrag hat, nimmt er den zugehörigen Validator in die Anfrage auf.

Der Server prüft dann diesen Validator gegen den aktuellen Validator für die Entität und, wenn sie übereinstimmen (siehe Abschnitt 13.3.3), antwortet er mit einem besonderen Statuscode (üblicherweise 304 (Not Modified)) und ohne Entitätskörper. Andernfalls gibt er eine vollständige Antwort zurück (einschließlich Entitätskörper). So vermeiden wir die Übertragung der vollständigen Antwort, wenn der Validator übereinstimmt, und wir vermeiden einen zusätzlichen Umlauf, wenn er nicht übereinstimmt.

In HTTP/1.1 sieht eine bedingte Anfrage genau wie eine normale Anfrage für dieselbe Ressource aus, außer dass sie eine besondere Headerzeile mitführt (die den Validator enthält), welche die methode (üblicherweise GET) implizit in eine bedingte verwandelt.

Das Protokoll enthält sowohl die positive als auch die negative Bedeutung von cache-validierenden Bedingungen. Das heißt, es ist möglich, entweder zu verlangen, dass eine methode genau dann ausgeführt wird, wenn ein Validator übereinstimmt, oder genau dann, wenn kein Validator übereinstimmt.

  Note: Eine Antwort, der ein Validator fehlt, kann dennoch zwischengespeichert und bis zu ihrem Ablauf aus dem Cache ausgeliefert werden, sofern dies nicht durch eine cache-control-Direktive ausdrücklich verboten ist. Ein Cache kann jedoch keinen bedingten Abruf durchführen, wenn er keinen Validator für die Entität hat, was bedeutet, dass er nach dem Ablauf nicht aktualisierbar ist.

13.3.1 Last-Modified Dates (Letzte Änderungsdaten)​

Der Wert der Last-Modified-Entitäts-Headerzeile wird häufig als Cache-Validator verwendet. Einfach ausgedrückt gilt ein Cache-Eintrag als gültig, wenn die Entität seit dem Last-Modified-Wert nicht geändert wurde.

13.3.2 Entity Tag Cache Validators (Entitäts-Tag-Cache-Validatoren)​

Der Wert der ETag-Antwort-Headerzeile, ein Entitäts-Tag, bietet einen "undurchsichtigen" Cache-Validator. Dies kann eine zuverlässigere Validierung in Situationen ermöglichen, in denen es unbequem ist, Änderungsdaten zu speichern, in denen die Auflösung von einer Sekunde der HTTP-Datumswerte nicht ausreicht, oder in denen der Ursprungsserver bestimmte Paradoxien vermeiden möchte, die aus der Verwendung von Änderungsdaten entstehen könnten.

Entitäts-Tags sind in Abschnitt 3.11 beschrieben. Die mit Entitäts-Tags verwendeten Headerzeilen sind in den Abschnitten 14.19, 14.24, 14.26 und 14.44 beschrieben.

13.3.3 Weak and Strong Validators (Schwache und starke Validatoren)​

Da sowohl Ursprungsserver als auch Caches zwei Validatoren vergleichen, um zu entscheiden, ob sie dieselbe oder unterschiedliche Entitäten darstellen, würde man normalerweise erwarten, dass sich, wenn sich die Entität (der Entitätskörper oder beliebige Entitäts-Headerzeilen) in irgendeiner Weise ändert, auch der zugehörige Validator ändert. Ist dies der Fall, nennen wir diesen Validator einen "starken Validator".

Es kann jedoch Fälle geben, in denen ein Server es vorzieht, den Validator nur bei semantisch bedeutsamen Änderungen zu ändern und nicht, wenn sich unbedeutende Aspekte der Entität ändern. Ein Validator, der sich nicht immer ändert, wenn sich die Ressource ändert, ist ein "schwacher Validator".

Entitäts-Tags sind normalerweise "starke Validatoren", aber das Protokoll bietet einen Mechanismus, um ein Entitäts-Tag als "schwach" zu kennzeichnen. Man kann sich einen starken Validator als einen vorstellen, der sich ändert, wann immer sich die Bits einer Entität ändern, während sich ein schwacher Wert ändert, wann immer sich die Bedeutung einer Entität ändert. Alternativ kann man sich einen starken Validator als Teil einer Kennung für eine bestimmte Entität vorstellen, während ein schwacher Validator Teil einer Kennung für eine Menge semantisch gleichwertiger Entitäten ist.

  Note: Ein Beispiel für einen starken Validator ist eine ganze Zahl, die bei jeder Änderung einer Entität in stabilem Speicher inkrementiert wird.

Die Änderungszeit einer Entität könnte, wenn sie mit einer Auflösung von einer Sekunde dargestellt wird, ein schwacher Validator sein, da es möglich ist, dass die Ressource zweimal innerhalb einer einzigen Sekunde geändert wird.

Die Unterstützung schwacher Validatoren ist optional. Schwache Validatoren ermöglichen jedoch ein effizienteres Zwischenspeichern gleichwertiger Objekte; beispielsweise ist ein Trefferzähler auf einer Website wahrscheinlich gut genug, wenn er alle paar Tage oder Wochen aktualisiert wird, und jeder Wert in diesem Zeitraum ist wahrscheinlich "gut genug", um als gleichwertig zu gelten.

Eine "Verwendung" eines Validators liegt entweder vor, wenn ein Client eine Anfrage erzeugt und den Validator in eine validierende Headerzeile aufnimmt, oder wenn ein Server zwei Validatoren vergleicht.

Starke Validatoren sind in jedem Kontext verwendbar. Schwache Validatoren sind nur in Kontexten verwendbar, die nicht von der exakten Gleichheit einer Entität abhängen. Beispielsweise ist jede der beiden Arten für ein bedingtes GET einer vollständigen Entität verwendbar. Für einen Teilbereichsabruf ist jedoch nur ein starker Validator verwendbar, da der Client andernfalls mit einer intern inkonsistenten Entität enden könnte.

Clients können (MAY) einfache GET-Anfragen (ohne Teilbereich) mit schwachen Validatoren oder mit starken Validatoren stellen. Clients dürfen (MUST NOT) schwache Validatoren in anderen Formen von Anfragen verwenden.

Die einzige Funktion, die das HTTP/1.1-Protokoll für Validatoren definiert, ist der Vergleich. Es gibt zwei Validator-Vergleichsfunktionen, je nachdem, ob der Vergleichskontext die Verwendung schwacher Validatoren zulässt oder nicht:

  - Die starke Vergleichsfunktion: Um als gleich zu gelten, müssen (MUST) beide Validatoren in jeder Hinsicht identisch sein, und beide dürfen nicht schwach sein (MUST NOT).

- Die schwache Vergleichsfunktion: Um als gleich zu gelten, müssen (MUST) beide Validatoren in jeder Hinsicht identisch sein, aber einer oder beide können (MAY) als "schwach" gekennzeichnet sein, ohne das Ergebnis zu beeinflussen.

Ein Entitäts-Tag ist stark, sofern es nicht ausdrücklich als schwach gekennzeichnet ist. Abschnitt 3.11 gibt die Syntax für Entitäts-Tags an.

Eine Last-Modified-Zeit ist, wenn sie als Validator in einer Anfrage verwendet wird, implizit schwach, es sei denn, es lässt sich anhand der folgenden Regeln ableiten, dass sie stark ist:

  - Der Validator wird von einem Ursprungsserver mit dem tatsächlichen aktuellen Validator für die Entität verglichen, und

- dieser Ursprungsserver weiß zuverlässig, dass sich die zugehörige Entität nicht zweimal während der Sekunde geändert hat, die vom vorgelegten Validator abgedeckt wird.

oder

  - Der Validator soll von einem Client in einer If-Modified-Since- oder If-Unmodified-Since-Headerzeile verwendet werden, weil der Client einen Cache-Eintrag für die zugehörige Entität hat, und

- dieser Cache-Eintrag enthält einen Date-Wert, der den Zeitpunkt angibt, zu dem der Ursprungsserver die ursprüngliche Antwort gesendet hat, und

- die vorgelegte Last-Modified-Zeit liegt mindestens 60 Sekunden vor dem Date-Wert.

oder

  - Der Validator wird von einem Zwischen-Cache mit dem in seinem Cache-Eintrag für die Entität gespeicherten Validator verglichen, und

- dieser Cache-Eintrag enthält einen Date-Wert, der den Zeitpunkt angibt, zu dem der Ursprungsserver die ursprüngliche Antwort gesendet hat, und

- die vorgelegte Last-Modified-Zeit liegt mindestens 60 Sekunden vor dem Date-Wert.

Diese Methode beruht auf der Tatsache, dass, wenn zwei unterschiedliche Antworten vom Ursprungsserver innerhalb derselben Sekunde gesendet wurden, beide aber dieselbe Last-Modified-Zeit hatten, mindestens eine dieser Antworten einen Date-Wert gleich ihrer Last-Modified-Zeit gehabt hätte. Das willkürliche Limit von 60 Sekunden schützt gegen die Möglichkeit, dass die Date- und Last-Modified-Werte von unterschiedlichen Uhren oder zu etwas unterschiedlichen Zeitpunkten während der Vorbereitung der Antwort erzeugt werden. Eine Implementierung kann (MAY) einen Wert größer als 60 Sekunden verwenden, wenn angenommen wird, dass 60 Sekunden zu kurz sind.

Wenn ein Client einen Teilbereichsabruf für einen Wert durchführen möchte, für den er nur eine Last-Modified-Zeit und keinen undurchsichtigen Validator hat, kann (MAY) er dies nur tun, wenn die Last-Modified-Zeit im hier beschriebenen Sinne stark ist.

Ein Cache oder Ursprungsserver, der eine bedingte Anfrage empfängt, die keine GET-Anfrage mit vollständigem Körper ist, muss (MUST) die starke Vergleichsfunktion verwenden, um die Bedingung zu bewerten.

Diese Regeln erlauben es HTTP/1.1-Caches und -Clients, Teilbereichsabrufe für Werte sicher durchzuführen, die von HTTP/1.0-Servern bezogen wurden.

13.3.4 Rules for When to Use Entity Tags and Last-Modified Dates (Regeln für die Verwendung von Entitäts-Tags und Last-Modified-Daten)​

Wir übernehmen eine Reihe von Regeln und Empfehlungen für Ursprungsserver, Clients und Caches dazu, wann die verschiedenen Validatortypen verwendet werden sollten und zu welchen Zwecken.

HTTP/1.1-Ursprungsserver:

  - Sollten (SHOULD) einen Entitäts-Tag-Validator senden, es sei denn, es ist nicht machbar, einen zu erzeugen.

- Können (MAY) ein schwaches Entitäts-Tag anstelle eines starken Entitäts-Tags senden, wenn Leistungserwägungen die Verwendung schwacher Entitäts-Tags unterstützen oder wenn es nicht machbar ist, ein starkes Entitäts-Tag zu senden.

- Sollten (SHOULD) einen Last-Modified-Wert senden, wenn es machbar ist, einen zu senden, es sei denn, das Risiko eines Bruchs der semantischen Transparenz, das aus der Verwendung dieses Datums in einer If-Modified-Since-Headerzeile entstehen könnte, würde zu ernsten Problemen führen.

Mit anderen Worten: Das bevorzugte Verhalten für einen HTTP/1.1-Ursprungsserver ist, sowohl ein starkes Entitäts-Tag als auch einen Last-Modified-Wert zu senden.

Um zulässig zu sein, muss (MUST) sich ein starkes Entitäts-Tag ändern, wann immer sich der zugehörige Entitätswert in irgendeiner Weise ändert. Ein schwaches Entitäts-Tag sollte (SHOULD) sich ändern, wann immer sich die zugehörige Entität in semantisch bedeutsamer Weise ändert.

  Note: Um semantisch transparentes Zwischenspeichern zu bieten, muss ein Ursprungsserver vermeiden, einen bestimmten starken Entitäts-Tag-Wert für zwei verschiedene Entitäten wiederzuverwenden oder einen bestimmten schwachen Entitäts-Tag-Wert für zwei semantisch verschiedene Entitäten wiederzuverwenden. Cache-Einträge können unbegrenzt lange bestehen bleiben, unabhängig von Ablaufzeiten, daher könnte es unangemessen sein zu erwarten, dass ein Cache niemals wieder versucht, einen Eintrag mit einem Validator zu validieren, den er irgendwann in der Vergangenheit bezogen hat.

HTTP/1.1-Clients:

  - Wenn ein Entitäts-Tag vom Ursprungsserver bereitgestellt wurde, müssen (MUST) sie dieses Entitäts-Tag in jeder cache-bedingten Anfrage verwenden (unter Verwendung von If-Match oder If-None-Match).

- Wenn vom Ursprungsserver nur ein Last-Modified-Wert bereitgestellt wurde, sollten (SHOULD) sie diesen Wert in cache-bedingten Anfragen ohne Teilbereich verwenden (unter Verwendung von If-Modified-Since).

- Wenn von einem HTTP/1.0-Ursprungsserver nur ein Last-Modified-Wert bereitgestellt wurde, können (MAY) sie diesen Wert in cache-bedingten Teilbereichsanfragen verwenden (unter Verwendung von If-Unmodified-Since). Der Benutzeragent sollte (SHOULD) eine Möglichkeit bieten, dies bei Schwierigkeiten zu deaktivieren.

- Wenn sowohl ein Entitäts-Tag als auch ein Last-Modified-Wert vom Ursprungsserver bereitgestellt wurden, sollten (SHOULD) sie beide Validatoren in cache-bedingten Anfragen verwenden. Dies erlaubt es sowohl HTTP/1.0- als auch HTTP/1.1-Caches, angemessen zu antworten.

Ein HTTP/1.1-Ursprungsserver darf (MUST NOT), wenn er eine bedingte Anfrage empfängt, die sowohl ein Last-Modified-Datum (z. B. in einer If-Modified-Since- oder If-Unmodified-Since-Headerzeile) als auch ein oder mehrere Entitäts-Tags (z. B. in einer If-Match-, If-None-Match- oder If-Range-Headerzeile) als Cache-Validatoren enthält, keinen Antwortstatus 304 (Not Modified) zurückgeben, es sei denn, dies ist mit allen bedingten Headerzeilen der Anfrage vereinbar.

Ein HTTP/1.1-Caching-Proxy darf (MUST NOT), wenn er eine bedingte Anfrage empfängt, die sowohl ein Last-Modified-Datum als auch ein oder mehrere Entitäts-Tags als Cache-Validatoren enthält, keine lokal zwischengespeicherte Antwort an den Client zurückgeben, es sei denn, diese zwischengespeicherte Antwort ist mit allen bedingten Headerzeilen der Anfrage vereinbar.

  Note: Das allgemeine Prinzip hinter diesen Regeln ist, dass HTTP/1.1-Server und -Clients so viele nicht redundante Informationen übertragen sollten, wie in ihren Antworten und Anfragen verfügbar sind. HTTP/1.1-Systeme, die diese Informationen empfangen, werden die konservativsten Annahmen über die Validatoren treffen, die sie empfangen.

HTTP/1.0-Clients und -Caches werden Entitäts-Tags ignorieren. Im Allgemeinen werden last-modified-Werte, die von diesen Systemen empfangen oder verwendet werden, transparentes und effizientes Zwischenspeichern unterstützen, und daher sollten HTTP/1.1-Ursprungsserver Last-Modified-Werte bereitstellen. In den seltenen Fällen, in denen die Verwendung eines Last-Modified-Werts als Validator durch ein HTTP/1.0-System zu einem ernsten Problem führen könnte, sollten HTTP/1.1-Ursprungsserver keinen bereitstellen.

13.3.5 Non-validating Conditionals (Nicht-validierende Bedingungen)​

Das Prinzip hinter Entitäts-Tags ist, dass nur der Autor des Dienstes die Semantik einer Ressource gut genug kennt, um einen geeigneten Cache-Validierungsmechanismus auszuwählen, und dass die Spezifikation einer Validator-Vergleichsfunktion, die komplexer als Byte-Gleichheit ist, eine Büchse der Pandora öffnen würde. Daher werden Vergleiche beliebiger anderer Headerzeilen (außer Last-Modified, aus Kompatibilität mit HTTP/1.0) niemals zum Zweck der Validierung eines Cache-Eintrags verwendet.

13.4 Response Cacheability (Antwort-Cachbarkeit)​

Sofern nicht ausdrücklich durch eine cache-control-Direktive (Abschnitt 14.9) eingeschränkt, kann (MAY) ein Caching-System immer eine erfolgreiche Antwort (siehe Abschnitt 13.8) als Cache-Eintrag speichern, kann (MAY) sie ohne Validierung zurückgeben, wenn sie frisch ist, und kann (MAY) sie nach erfolgreicher Validierung zurückgeben. Wenn einer Antwort weder ein Cache-Validator noch eine ausdrückliche Ablaufzeit zugeordnet ist, erwarten wir nicht, dass sie zwischengespeichert wird, aber bestimmte Caches können (MAY) diese Erwartung verletzen (zum Beispiel wenn wenig oder keine Netzwerkkonnektivität verfügbar ist). Ein Client kann üblicherweise erkennen, dass eine solche Antwort einem Cache entnommen wurde, indem er die Date-Headerzeile mit der aktuellen Zeit vergleicht.

  Note: Es ist bekannt, dass einige HTTP/1.0-Caches diese Erwartung verletzen, ohne eine Warnung bereitzustellen.

In manchen Fällen kann es jedoch unangemessen sein, dass ein Cache eine Entität aufbewahrt oder sie als Antwort auf eine spätere Anfrage zurückgibt. Dies kann daran liegen, dass der Autor des Dienstes absolute semantische Transparenz für notwendig hält, oder an Sicherheits- oder Datenschutzerwägungen. Daher sind bestimmte cache-control-Direktiven vorgesehen, damit der Server anzeigen kann, dass bestimmte Ressourcenentitäten oder Teile davon ungeachtet anderer Erwägungen nicht zwischengespeichert werden sollen.

Beachten Sie, dass Abschnitt 14.8 normalerweise verhindert, dass ein gemeinsam genutzter Cache eine Antwort auf eine frühere Anfrage speichert und zurückgibt, wenn diese Anfrage eine Authorization-Headerzeile enthielt.

Eine Antwort, die mit dem Statuscode 200, 203, 206, 300, 301 oder 410 empfangen wurde, kann (MAY) von einem Cache gespeichert und in Erwiderung auf eine spätere Anfrage verwendet werden, vorbehaltlich des Ablaufmechanismus, sofern eine cache-control-Direktive das Zwischenspeichern nicht verbietet. Ein Cache, der die Range- und Content-Range-Headerzeilen nicht unterstützt, darf (MUST NOT) jedoch keine 206 (Partial Content)-Antworten zwischenspeichern.

Eine Antwort, die mit einem beliebigen anderen Statuscode empfangen wurde (z. B. die Statuscodes 302 und 307), darf (MUST NOT) in Erwiderung auf eine spätere Anfrage zurückgegeben werden, sofern es keine cache-control-Direktiven oder andere Headerzeilen gibt, die dies ausdrücklich erlauben. Beispielsweise gehören dazu: eine Expires-Headerzeile (Abschnitt 14.21); eine cache-control-Direktive "max-age", "s-maxage", "must-revalidate", "proxy-revalidate", "public" oder "private" (Abschnitt 14.9).

13.5 Constructing Responses From Caches (Konstruktion von Antworten aus Caches)​

Der Zweck eines HTTP-Caches ist es, Informationen zu speichern, die als Antwort auf Anfragen empfangen wurden, um sie beim Beantworten künftiger Anfragen zu verwenden. In vielen Fällen gibt ein Cache einfach die geeigneten Teile einer Antwort an den Anforderer zurück. Wenn der Cache jedoch einen auf einer früheren Antwort beruhenden Cache-Eintrag hält, muss er möglicherweise Teile einer neuen Antwort mit dem kombinieren, was im Cache-Eintrag gehalten wird.

13.5.1 End-to-end and Hop-by-hop Headers (End-to-End- und Hop-by-Hop-Header)​

Zum Zweck der Definition des Verhaltens von Caches und nicht zwischenspeichernden Proxies teilen wir HTTP-Headerzeilen in zwei Kategorien ein:

  - End-to-End-Headerzeilen, die an den endgültigen Empfänger einer Anfrage oder Antwort übertragen werden. End-to-End-Headerzeilen in Antworten müssen (MUST) als Teil eines Cache-Eintrags gespeichert und in jeder aus einem Cache-Eintrag gebildeten Antwort übertragen werden (MUST).

- Hop-by-Hop-Headerzeilen, die nur für eine einzelne Verbindung auf Transportebene bedeutsam sind und nicht von Caches gespeichert oder von Proxies weitergeleitet werden.

Die folgenden HTTP/1.1-Headerzeilen sind Hop-by-Hop-Headerzeilen:

  - Connection
- Keep-Alive
- Proxy-Authenticate
- Proxy-Authorization
- TE
- Trailers
- Transfer-Encoding
- Upgrade

Alle anderen von HTTP/1.1 definierten Headerzeilen sind End-to-End-Headerzeilen.

Andere Hop-by-Hop-Headerzeilen müssen (MUST) in einer Connection-Headerzeile aufgeführt werden (Abschnitt 14.10), um in HTTP/1.1 (oder später) eingeführt zu werden.

13.5.2 Non-modifiable Headers (Nicht modifizierbare Header)​

Einige Merkmale des HTTP/1.1-Protokolls, wie die Digest Authentication, hängen vom Wert bestimmter End-to-End-Headerzeilen ab. Ein transparenter Proxy sollte (SHOULD NOT) keine End-to-End-Headerzeile ändern, es sei denn, die Definition dieser Headerzeile verlangt oder erlaubt dies ausdrücklich.

Ein transparenter Proxy darf (MUST NOT) keines der folgenden Felder in einer Anfrage oder Antwort ändern und darf keines dieser Felder hinzufügen, wenn sie nicht bereits vorhanden sind (MUST NOT):

  - Content-Location

- Content-MD5

- ETag

- Last-Modified

Ein transparenter Proxy darf (MUST NOT) keines der folgenden Felder in einer Antwort ändern:

  - Expires

Er kann (MAY) jedoch eines dieser Felder hinzufügen, wenn es nicht bereits vorhanden ist. Wenn eine Expires-Headerzeile hinzugefügt wird, muss (MUST) ihr ein field-value gegeben werden, das mit dem der Date-Headerzeile in dieser Antwort identisch ist.

Ein Proxy darf (MUST NOT) keines der folgenden Felder in einer Nachricht ändern oder hinzufügen, die die cache-control-Direktive no-transform enthält, oder in irgendeiner Anfrage:

  - Content-Encoding

- Content-Range

- Content-Type

Ein nicht transparenter Proxy kann (MAY) diese Felder zu einer Nachricht hinzufügen oder sie darin ändern, die no-transform nicht enthält, aber wenn er dies tut, muss (MUST) er eine Warnung 214 (Transformation applied) hinzufügen, falls nicht bereits eine in der Nachricht erscheint (siehe Abschnitt 14.46).

      Warning: unnecessary modification of end-to-end headers might
cause authentication failures if stronger authentication
mechanisms are introduced in later versions of HTTP. Such
authentication mechanisms MAY rely on the values of header fields
not listed here.

Das Feld Content-Length einer Anfrage oder Antwort wird nach den Regeln in Abschnitt 4.4 hinzugefügt oder gelöscht. Ein transparenter Proxy muss (MUST) die entity-length (Abschnitt 7.2.2) des Entitätskörpers bewahren, obwohl er die transfer-length (Abschnitt 4.4) ändern kann (MAY).

13.5.3 Combining Headers (Kombinieren von Headern)​

Wenn ein Cache eine validierende Anfrage an einen Server stellt und der Server eine 304 (Not Modified)-Antwort oder eine 206 (Partial Content)-Antwort bereitstellt, konstruiert der Cache anschließend eine Antwort, die an den anfragenden Client gesendet wird.

Wenn der Statuscode 304 (Not Modified) lautet, verwendet der Cache den im Cache-Eintrag gespeicherten Entitätskörper als Entitätskörper dieser ausgehenden Antwort. Wenn der Statuscode 206 (Partial Content) lautet und die ETag- oder Last-Modified-Headerzeilen genau übereinstimmen, kann (MAY) der Cache die im Cache-Eintrag gespeicherten Inhalte mit den in der Antwort neu empfangenen Inhalten kombinieren und das Ergebnis als Entitätskörper dieser ausgehenden Antwort verwenden (siehe 13.5.4).

Die im Cache-Eintrag gespeicherten End-to-End-Headerzeilen werden für die konstruierte Antwort verwendet, mit der Ausnahme, dass

  - alle gespeicherten Warning-Headerzeilen mit warn-code 1xx (siehe Abschnitt 14.46) aus dem Cache-Eintrag und der weitergeleiteten Antwort gelöscht werden müssen (MUST).

- alle gespeicherten Warning-Headerzeilen mit warn-code 2xx im Cache-Eintrag und der weitergeleiteten Antwort erhalten bleiben müssen (MUST).

- alle in der 304- oder 206-Antwort bereitgestellten End-to-End-Headerzeilen die entsprechenden Headerzeilen aus dem Cache-Eintrag ersetzen müssen (MUST).

Sofern der Cache nicht beschließt, den Cache-Eintrag zu entfernen, muss (MUST) er außerdem die mit dem Cache-Eintrag gespeicherten End-to-End-Headerzeilen durch die entsprechenden in der eingehenden Antwort empfangenen Headerzeilen ersetzen, mit Ausnahme der Warning-Headerzeilen wie unmittelbar oben beschrieben. Wenn ein header field-name in der eingehenden Antwort mit mehr als einer Headerzeile im Cache-Eintrag übereinstimmt, müssen (MUST) alle derartigen alten Headerzeilen ersetzt werden.

Mit anderen Worten: Die Menge der in der eingehenden Antwort empfangenen End-to-End-Headerzeilen überschreibt alle entsprechenden mit dem Cache-Eintrag gespeicherten End-to-End-Headerzeilen (mit Ausnahme der gespeicherten Warning-Headerzeilen mit warn-code 1xx, die gelöscht werden, auch wenn sie nicht überschrieben werden).

  Note: Diese Regel erlaubt es einem Ursprungsserver, mit einer 304 (Not Modified)- oder 206 (Partial Content)-Antwort jede Headerzeile zu aktualisieren, die einer früheren Antwort für dieselbe Entität oder deren Teilbereiche zugeordnet ist, obwohl dies nicht immer sinnvoll oder korrekt sein mag. Diese Regel erlaubt es einem Ursprungsserver nicht, mit einer 304 (Not Modified)- oder 206 (Partial Content)-Antwort eine Headerzeile vollständig zu löschen, die er mit einer früheren Antwort bereitgestellt hatte.

13.5.4 Combining Byte Ranges (Kombinieren von Byte-Bereichen)​

Eine Antwort überträgt möglicherweise nur einen Teilbereich der Bytes eines Entitätskörpers, entweder weil die Anfrage eine oder mehrere Range-Spezifikationen enthielt oder weil eine Verbindung vorzeitig unterbrochen wurde. Nach mehreren solchen Übertragungen hat ein Cache möglicherweise mehrere Bereiche desselben Entitätskörpers empfangen.

Wenn ein Cache eine gespeicherte nicht leere Menge von Teilbereichen für eine Entität hat und eine eingehende Antwort einen weiteren Teilbereich überträgt, kann (MAY) der Cache den neuen Teilbereich mit der vorhandenen Menge kombinieren, wenn beide der folgenden Bedingungen erfüllt sind:

  - Sowohl die eingehende Antwort als auch der Cache-Eintrag haben einen Cache-Validator.

- Die beiden Cache-Validatoren stimmen unter Verwendung der starken Vergleichsfunktion überein (siehe Abschnitt 13.3.3).

Wenn eine der beiden Anforderungen nicht erfüllt ist, muss (MUST) der Cache nur die jüngste Teilantwort verwenden (auf Grundlage der mit jeder Antwort übertragenen Date-Werte, wobei die eingehende Antwort verwendet wird, wenn diese Werte gleich sind oder fehlen) und muss (MUST) die anderen Teilinformationen verwerfen.

13.6 Caching Negotiated Responses (Caching von verhandelten Antworten)​

Die Verwendung der servergesteuerten Inhaltsaushandlung (Abschnitt 12.1), wie sie durch das Vorhandensein einer Vary-Headerzeile in einer Antwort angezeigt wird, verändert die Bedingungen und das Verfahren, nach denen ein Cache die Antwort für spätere Anfragen verwenden kann. Zur Verwendung der Vary-Headerzeile durch Server siehe Abschnitt 14.44.

Ein Server sollte (SHOULD) die Vary-Headerzeile verwenden, um einen Cache darüber zu informieren, welche Anfrage-Headerzeilen verwendet wurden, um unter mehreren Darstellungen einer cachefähigen Antwort auszuwählen, die der servergesteuerten Aushandlung unterliegt. Die Menge der durch den Vary-Feldwert benannten Headerzeilen ist als "auswählende" request-header bekannt.

Wenn der Cache eine spätere Anfrage empfängt, deren Request-URI einen oder mehrere Cache-Einträge angibt, die eine Vary-Headerzeile enthalten, darf (MUST NOT) der Cache einen solchen Cache-Eintrag nicht verwenden, um eine Antwort auf die neue Anfrage zu konstruieren, sofern nicht alle in der neuen Anfrage vorhandenen auswählenden request-header mit den entsprechenden gespeicherten request-header in der ursprünglichen Anfrage übereinstimmen.

Die auswählenden request-header zweier Anfragen stimmen per Definition genau dann überein, wenn die auswählenden request-header in der ersten Anfrage in die auswählenden request-header in der zweiten Anfrage überführt werden können, indem an Stellen, an denen dies nach dem entsprechenden BNF zulässig ist, linear white space (LWS) hinzugefügt oder entfernt wird und/oder mehrere message-header-Felder mit demselben field name nach den Regeln über message header in Abschnitt 4.2 kombiniert werden.

Ein Vary-Feldwert von "*" stimmt niemals überein, und spätere Anfragen zu dieser Ressource können nur vom Ursprungsserver richtig interpretiert werden.

Wenn die auswählenden Anfrage-Headerzeilen für den zwischengespeicherten Eintrag nicht mit den auswählenden Anfrage-Headerzeilen der neuen Anfrage übereinstimmen, darf (MUST NOT) der Cache einen zwischengespeicherten Eintrag nicht verwenden, um die Anfrage zu erfüllen, es sei denn, er leitet die neue Anfrage zuerst als bedingte Anfrage an den Ursprungsserver weiter und der Server antwortet mit 304 (Not Modified), einschließlich eines Entitäts-Tags oder Content-Location, das die zu verwendende Entität angibt.

Wenn einer zwischengespeicherten Darstellung ein Entitäts-Tag zugewiesen wurde, sollte (SHOULD) die weitergeleitete Anfrage bedingt sein und die Entitäts-Tags aus allen ihren Cache-Einträgen für die Ressource in einer If-None-Match-Headerzeile enthalten. Dies übermittelt dem Server die Menge der derzeit vom Cache gehaltenen Entitäten, sodass der Server, wenn eine dieser Entitäten mit der angeforderten Entität übereinstimmt, die ETag-Headerzeile in seiner 304 (Not Modified)-Antwort verwenden kann, um dem Cache mitzuteilen, welcher Eintrag geeignet ist. Wenn das Entitäts-Tag der neuen Antwort mit dem eines vorhandenen Eintrags übereinstimmt, sollte (SHOULD) die neue Antwort verwendet werden, um die Headerzeilen des vorhandenen Eintrags zu aktualisieren, und das Ergebnis muss (MUST) an den Client zurückgegeben werden.

Wenn einer der vorhandenen Cache-Einträge nur teilweisen Inhalt für die zugehörige Entität enthält, sollte (SHOULD NOT) sein Entitäts-Tag nicht in die If-None-Match-Headerzeile aufgenommen werden, es sei denn, die Anfrage gilt einem Bereich, der durch diesen Eintrag vollständig erfüllt würde.

Wenn ein Cache eine erfolgreiche Antwort empfängt, deren Content-Location-Feld mit dem eines vorhandenen Cache-Eintrags für denselben Request-URI übereinstimmt, deren Entitäts-Tag sich von dem des vorhandenen Eintrags unterscheidet und deren Date neuer ist als die des vorhandenen Eintrags, sollte (SHOULD NOT) der vorhandene Eintrag nicht als Antwort auf künftige Anfragen zurückgegeben werden und sollte (SHOULD) aus dem Cache gelöscht werden.

13.7 Shared and Non-Shared Caches (Gemeinsam genutzte und nicht gemeinsam genutzte Caches)​

Aus Gründen der Sicherheit und des Datenschutzes ist es notwendig, zwischen "gemeinsam genutzten" und "nicht gemeinsam genutzten" Caches zu unterscheiden. Ein nicht gemeinsam genutzter Cache ist ein Cache, auf den nur ein einzelner Benutzer zugreifen kann. Die Zugänglichkeit sollte (SHOULD) in diesem Fall durch geeignete Sicherheitsmechanismen erzwungen werden. Alle anderen Caches gelten als "gemeinsam genutzt". Andere Abschnitte dieser Spezifikation erlegen dem Betrieb gemeinsam genutzter Caches bestimmte Beschränkungen auf, um den Verlust der Privatsphäre oder das Versagen von Zugriffskontrollen zu verhindern.

13.8 Errors or Incomplete Response Cache Behavior (Fehler- oder unvollständiges Antwort-Cache-Verhalten)​

Ein Cache, der eine unvollständige Antwort empfängt (zum Beispiel mit weniger Datenbytes, als in einer Content-Length-Headerzeile angegeben), kann (MAY) die Antwort speichern. Der Cache muss (MUST) sie jedoch als Teilantwort behandeln. Teilantworten können (MAY) wie in Abschnitt 13.5.4 beschrieben kombiniert werden; das Ergebnis kann eine vollständige Antwort sein oder noch teilweise sein. Ein Cache darf (MUST NOT) eine Teilantwort nicht an einen Client zurückgeben, ohne sie ausdrücklich als solche zu kennzeichnen, und zwar unter Verwendung des Statuscodes 206 (Partial Content). Ein Cache darf (MUST NOT) eine Teilantwort nicht unter Verwendung eines Statuscodes 200 (OK) zurückgeben.

Wenn ein Cache beim Versuch, einen Eintrag zu revalidieren, eine 5xx-Antwort empfängt, kann (MAY) er diese Antwort entweder an den anfragenden Client weiterleiten oder sich verhalten, als hätte der Server nicht geantwortet. Im letzteren Fall kann (MAY) er eine zuvor empfangene Antwort zurückgeben, es sei denn, der zwischengespeicherte Eintrag enthält die cache-control-Direktive "must-revalidate" (siehe Abschnitt 14.9).

13.9 Side Effects of GET and HEAD (Nebenwirkungen von GET und HEAD)​

Sofern der Ursprungsserver das Zwischenspeichern ihrer Antworten nicht ausdrücklich verbietet, sollte (SHOULD NOT) die Anwendung der Methoden GET und HEAD auf beliebige Ressourcen keine Nebenwirkungen haben, die zu fehlerhaftem Verhalten führen würden, wenn diese Antworten einem Cache entnommen werden. Sie können (MAY) dennoch Nebenwirkungen haben, aber ein Cache ist nicht verpflichtet, solche Nebenwirkungen bei seinen Zwischenspeicherungsentscheidungen zu berücksichtigen. Von Caches wird stets erwartet, dass sie die ausdrücklichen Beschränkungen eines Ursprungsservers für die Zwischenspeicherung beachten.

Wir bemerken eine Ausnahme von dieser Regel: Da einige Anwendungen traditionell GET und HEAD mit Query-URLs (solchen, die ein "?" im Teil rel_path enthalten) verwendet haben, um Operationen mit erheblichen Nebenwirkungen durchzuführen, dürfen (MUST NOT) Caches Antworten auf solche URIs nicht als frisch behandeln, es sei denn, der Server stellt eine ausdrückliche Ablaufzeit bereit. Dies bedeutet insbesondere, dass Antworten von HTTP/1.0-Servern für solche URIs nicht einem Cache entnommen werden sollten (SHOULD NOT). Verwandte Informationen finden sich in Abschnitt 9.1.1.

13.10 Invalidation After Updates or Deletions (Ungültigmachung nach Aktualisierungen oder Löschungen)​

Die Wirkung bestimmter Methoden, die an einer Ressource beim Ursprungsserver ausgeführt werden, kann dazu führen, dass ein oder mehrere vorhandene Cache-Einträge nicht transparent ungültig werden. Das heißt: Obwohl sie weiterhin "frisch" sein mögen, geben sie nicht genau das wieder, was der Ursprungsserver für eine neue Anfrage zu dieser Ressource zurückgeben würde.

Es gibt für das HTTP-Protokoll keine Möglichkeit zu gewährleisten, dass alle derartigen Cache-Einträge als ungültig gekennzeichnet werden. Beispielsweise hat die Anfrage, die die Änderung beim Ursprungsserver bewirkt hat, möglicherweise nicht den Proxy durchlaufen, in dem ein Cache-Eintrag gespeichert ist. Mehrere Regeln tragen jedoch dazu bei, die Wahrscheinlichkeit fehlerhaften Verhaltens zu verringern.

In diesem Abschnitt bedeutet die Wendung "eine Entität ungültig machen", dass der Cache entweder alle Instanzen dieser Entität aus seinem Speicher entfernt oder diese als "ungültig" kennzeichnet und als einer zwingenden Revalidierung bedürftig, bevor sie als Antwort auf eine spätere Anfrage zurückgegeben werden können.

Bestimmte HTTP-Methoden müssen (MUST) bewirken, dass ein Cache eine Entität ungültig macht. Dies ist entweder die durch den Request-URI bezeichnete Entität oder die durch die Location- oder Content-Location-Headerzeilen bezeichnete Entität (falls vorhanden). Diese Methoden sind:

  - PUT

- DELETE

- POST

Um Denial-of-Service-Angriffe zu verhindern, muss (MUST) eine Ungültigmachung auf Grundlage des URI in einer Location- oder Content-Location-Headerzeile nur dann durchgeführt werden, wenn der Host-Teil derselbe ist wie im Request-URI.

Ein Cache, der Anfragen für Methoden durchlässt, die er nicht versteht, sollte (SHOULD) alle durch den Request-URI bezeichneten Entitäten ungültig machen.

13.11 Write-Through Mandatory (Durchschreiben obligatorisch)​

Alle Methoden, von denen erwartet werden kann, dass sie Änderungen an den Ressourcen des Ursprungsservers bewirken, müssen (MUST) zum Ursprungsserver durchgeschrieben (write-through) werden. Dies umfasst derzeit alle Methoden außer GET und HEAD. Ein Cache darf (MUST NOT) nicht auf eine solche Anfrage eines Clients antworten, bevor er die Anfrage an den eingehenden Server übertragen und eine entsprechende Antwort vom eingehenden Server empfangen hat. Dies hindert einen Proxy-Cache nicht daran, eine 100 (Continue)-Antwort zu senden, bevor der eingehende Server seine endgültige Antwort gesendet hat.

Die Alternative (bekannt als "write-back"- oder "copy-back"-Caching) ist in HTTP/1.1 nicht zulässig, aufgrund der Schwierigkeit, konsistente Aktualisierungen bereitzustellen, und der Probleme, die sich aus Server-, Cache- oder Netzwerkausfällen vor dem Write-back ergeben.

13.12 Cache Replacement (Cache-Ersetzung)​

Wenn eine neue cachefähige Antwort (siehe Abschnitte 14.9.2, 13.2.5, 13.2.6 und 13.8) von einer Ressource empfangen wird, während vorhandene Antworten für dieselbe Ressource zwischengespeichert sind, sollte (SHOULD) der Cache die neue Antwort verwenden, um auf die aktuelle Anfrage zu antworten. Er kann (MAY) sie in den Cache-Speicher einfügen und kann (MAY), wenn sie alle anderen Anforderungen erfüllt, sie verwenden, um auf künftige Anfragen zu antworten, die zuvor die Rückgabe der alten Antwort bewirkt hätten. Wenn er die neue Antwort in den Cache-Speicher einfügt, gelten die Regeln in Abschnitt 13.5.3.

  Note: Eine neue Antwort, die einen älteren Date-Headerwert hat als vorhandene zwischengespeicherte Antworten, ist nicht cachefähig.

13.13 History Lists (Historienlisten)​

Benutzeragenten haben oft Historienmechanismen, wie "Zurück"-Schaltflächen und Historienlisten, mit denen eine früher in einer Sitzung abgerufene Entität erneut angezeigt werden kann.

Historienmechanismen und Caches sind unterschiedlich. Insbesondere sollten (SHOULD NOT) Historienmechanismen nicht versuchen, eine semantisch transparente Sicht auf den aktuellen Zustand einer Ressource zu zeigen. Vielmehr soll ein Historienmechanismus genau das zeigen, was der Benutzer zum Zeitpunkt des Abrufs der Ressource gesehen hat.

Standardmäßig gilt eine Ablaufzeit nicht für Historienmechanismen. Wenn die Entität noch im Speicher ist, sollte (SHOULD) ein Historienmechanismus sie anzeigen, auch wenn die Entität abgelaufen ist, es sei denn, der Benutzer hat den Agenten ausdrücklich so konfiguriert, dass abgelaufene Historien-Dokumente aktualisiert werden.

Dies ist nicht so auszulegen, dass es dem Historienmechanismus verboten wäre, dem Benutzer mitzuteilen, dass eine Ansicht veraltet sein könnte.

  Note: Wenn Historienlistenmechanismen Benutzer unnötig daran hindern, veraltete Ressourcen anzusehen, wird dies dazu tendieren, Autoren von Diensten zu zwingen, HTTP-Ablaufsteuerungen und Cache-Steuerungen zu vermeiden, wenn sie sie sonst gerne verwenden würden. Autoren von Diensten mögen es für wichtig halten, dass Benutzern keine Fehler- oder Warnmeldungen angezeigt werden, wenn sie Navigationssteuerungen (wie BACK) verwenden, um früher abgerufene Ressourcen anzusehen. Auch wenn solche Ressourcen manchmal nicht zwischengespeichert werden sollten oder schnell ablaufen sollten, können Erwägungen der Benutzeroberfläche Autoren von Diensten zwingen, auf andere Mittel zur Verhinderung der Zwischenspeicherung zurückzugreifen (z. B. "once-only"-URLs), um nicht unter den Auswirkungen von Historienmechanismen zu leiden, die nicht ordnungsgemäß funktionieren.