Michael Schröpl: Content Negotiation und Caching in HTTP/1.1 ...

Beitrag lesen

Hi Ingo,

Sorry, aber ich bekomme bei teamone immer nur kryptische zeichen
in denen ich nichts erkennen kann, da muss man eben ausweichen

verwendest Du (implizit oder explizit) einen Caching Proxy?

Teamone verwendet eine (die einzige bisher verfügbare) mod_gzip-Version,
welche zwar komprimiert und dabei implizit Content Negotiation betreibt
(nämlich über den HTTP-Header "Accept-Encoding"), aber diese Information
_nicht_ an Proxy-Server ausliefert (in Form eines "Vary:"-Headers).

Der Vary-Header würde den Proxy warnen: "Achtung, diese Daten hier sind
das Ergebnis einer Verhandlung - gib sie nur dann an Browser weiter,
wenn Du sicher sein kannst, daß diese Browser die Daten auch verstehen
werden."
Letzteres herauszufinden ist nicht ganz einfach - der Proxy müßte nämlich
im Wesentlichen die auf dem Server statt gefundene Negotiation selbst
ebenfalls durchführen, und dazu natürlich begriffen haben, wovon der
Server die Auslieferung des entsprechenden Content abhängig gemacht hat.
Genau für letzteres ist der Vary:-Header notwendig.

Meines Wissens kann das _kein_ existierender Proxy-Server. Der verbrei-
tete Proxy-Server Squid (mit dessen Entwicklern ich gerade über genau
dieses Thema diskutiere ...) erkennt aber immerhin am Auftreten eines
"Vary:"- Headers, daß er vorsichtig sein sollte - und schaltet in diesem
Falle unabhängig von anderen HTTP-Headern das Caching für diesen Content
ab (seit Squid 2.0, also schon seeehr lange). Nur müßte mod_gzip ihm
dazu natürlich überhaupt erst mal einen Vary:-Header senden ...

In diesem Vary:-Header müßte dann die Liste derjenigen HTTP-Header auf-
geführt sein, welche der Server für seine Entscheidung ausgewertet hat.
In dem Moment, in dem der Proxy sich für das Speichern eines Inhalt in
seinem Cache entscheidet, weiß er noch, welche HTTP-Header bei derjenigen
Anfrage geliefert wurden, die zu diesem Ergebnis geführt haben; trifft
ein nachfolgender Request mit exakt denselben Werten in allen genannten
HTTP-Headern ein, dann darf er das Ergebnis ausliefern - denn dann würde
die erneute Verhandlung auf dem Server sicher zum selben Ergebnis führen.

Genau diese Denkweise, also das parallele Vorrätighalten verschiedener
Verhandlungsergebnisse (Encodings sind nur _eine_ Art des Problems -
Language Negotiation ist eine weitere), wird gerade in Squid 2.5 ein-
gebaut, der also in absehbarer Zeit das Caching von verhandelten In-
halten unterstützen wird. (Deshalb gehen die Squid-Leute gerade "mit
dem Hut herum" und reden mit ihren potentiellen "Verhandlungspartnern".)

Welche HTTP-Header mod_gzip nun genau mitliefern müßte, das hängt von
der verwendeten mod_gzip-Konfiguration ab.
Im einfachsten Falle würde ein "Vary: Accept-Encoding" ausreichen.
Hat der Server aber von der Konfigurationsregen "mod_gzip_item_**clude
reqheader" Gebrauch gemacht, um Regeln von speziellen HTTP-Headern
abhängig zu machen, dann müßte mod_gzip mitschreiben, welche dieser
Regeln auf dem Weg zu einer Entscheidung geprüft wurden und den Vary:-
Header entsprechend dynamisch erzeugen.
Ganz schlecht sind in diesem Falle natürlich Regeln, welche über den
"User-Agent:" gehen - weil dies den Proxy dazu zwingen würde, viele
tausend Einträge zu speichern, nämlich für jeden User-Agent einen ...

Eine mod_gzip-Version mit einem trivialen Patch, um einfach nur "Vary:
Accept-Encoding" mit jedem komprimiert ausgelieferten Inhalt zu senden,
gibt es auf meiner Homepage
    (http://www.schroepl.net/projekte/mod_gzip/links.htm)
zum Download. Ersatzweise kann man das Problem auch durch den Einsatz
von mod_headers umgehen.

Eine Version, welche den Vary-Header dynamisch baut, kriege ich mit
meinen bescheidenen Kenntnissen über C und vor allem über das Innenleben
des Apache im Moment nicht hin. (Der Trick könnte u. a. darin bestehen,
möglichst schon beim Apache-Start zu berechnen, welche Vary:-Felder
gesendet werden müssen, nicht erst beim jeweiligen Request - denn _was_
geprüft werden muß, hängt nur von der Konfiguration ab, nicht vom der
eigentlichen Anforderung.)
In jedem Falle müßte das Regelauswertungsverfahren in mod_gzip umge-
schrieben werden, weil es nun die "kritischen" Regeln vor den "unkri-
tischen" prüfen muß und nicht einfach abbrechen darf, wenn es zu einem
Entschluß gekommen ist - weil es die Begründung für diesen Beschluß dem
Anrufer mitteilen muß.

Um HTTP/1.1 _vollständig_ zu unterstützen, müßten sowohl mod_gzip als
auch Squid noch eine ganze Menge mehr tun - herauszufinden, was genau
(und ob das algorithmisch überhaupt lösbar ist), findet gerade auf der
mod_gzip-Mailingliste statt ...

Viele Grüße
      Michael