Moin
hm ... das ist nicht so einfach.
Hmm, bei PHP scheint das aber durchaus einfach zu sein :) (s.u.)
Diese gehen schon mal damit los, daß man herausfinden muß, ob der Client
überhaupt komprimierte Daten empfangen will. Dazu muß man in seinem
HTTP-Header nachsehen - das könnte ein Modul durchaus tun.
Die Request-Header sollten in einem Skript doch wohl zu bekommen sein?
Als nächstes sollte man sich Gedanken darüber machen, ob man dem Client
glauben will. Es ist nämlich mitnichten so, daß der Client in jedem Fall,
in dem er behauptet, komprimierte Daten zu verstehen, das auch tatsächlich
tut. Neben HTML gibt es noch eine Menge anderer Dinge, die man mit HTTP
über die Leitung jagen kann ... mod_gzip muß sich da mit eine Menge Zeug
herumschlagen, die an dieser Stelle wohl zu weit führen würden. Reduzie-
ren wir Deinen Fall mal auf HTML, das vereinfacht die Sache schon sehr.
Das verstehe ich jetzt nicht ganz?
Wenn da ein Header
Accept-Encoding: gzip
gesendet wird, dann versichert mir der Client das er diese Kodierung versteht und bereit ist sie zu aktzeptieren. Wenn er das nicht ist, dann ist es so, dass er entweder a) lügt oder b) kein HTTP kann.
Bei a) hat er es nicht anders gewollt, und bei b) halte ich einen Programmierfehler der einfach mal so einen zusätzlichen Header in den Request einschleust, für relativ unwahrscheinlich.
Was HTML oder nicht-HTML angeht: Spielt das denn überhaupt eine Rolle? Diese Kodierung ist doch nur für die Übertragung da, und wird nach dem Empfang sofort wieder entfernt. Was auch immer hinter dem HTTP-Teil des Clients liegt, sollte davon nichts mehr mitkriegen. Allenfalls die Nutzlosigkeit des gzippens von JPEG-Daten erscheint mir problematisch, aber das sollte bei Perl-Skripten eher selten vorkommen, und wenn, dann weiss ich als Programmierer dass ich jetzt nur schwer komprimierbare Daten senden werde.
[Header und Inhaltslänge]
Auch da sehe ich ein Problem nicht. Lass den Server tun, was er normalerweise tut. Er kennt doch auch sonst einen Weg die Daten irgendwie zum Client zu schaffen, auch wenn das Skript nicht komprimiert. Der einzige Unterschied ist a) die Daten sind anders (das geht den Server aber nichts an, da er sich die Daten normalerweise auch nicht anschaut) und b) es muß _ein_ zusätzlicher Header gesendet werden:
Content-Encoding: gzip
und auch da mischt sich der Server doch normalerweise nicht ein?
Das mit der Länge muss der Server so halten, wie immer:
a) HTTP/1.1, dann geht in jeden Fall Tranfer-Encoding: chunked
b) HTTP/1.0, dann macht der Server entweder Connection: Close oder er speichert sich bei Keep-Alive alle Daten zwischen und kann dann einen Content-Length Header senden. Das alles geht das Skript aber nichts an, da es ja einfach bloß Daten liefern muß.
[ob_gzhandler]
Der ist ja auch bloß dafür gedacht, es möglichst einfach zu machen.
Richtige Männer ( :-) ) oder solche die kein PHP >= 4.0.4 haben, bauen das zu Fuß. In etwa so:
ob_start(); // Outputbuffering starten
..der rest des skripts...
$content = ob_get_contents(); // Skriptausgaben holen
ob_end_clean(); // Outputbuffering beenden
if(preg_match("/gzip/", $HTTP_SERVER_VARS["HTTP_ACCEPT_ENCODING"])) {
// Herausfinden, ob der Client komprimierte Daten will
header("Content-Encoding: gzip");
echo gzencode($content); // Komprimieren und senden
} else echo $content;
Und du willst mir doch wohl nicht erzählen dass ein fest kompiliertes Modul, dass sich nur über die Serverkonfigurationsdatei konfigurieren lässt, flexibler ist, als etwas dass du selbst in den Scriptcode schreibst?
In Perl müsste das alles ähnlich oder äquivalent gehen, auch wenn ich keinen blassen Schimmer hätte, wie ich etwas ähnliches wie die Outputbufferingfunktionen implementieren sollte. (Ist PHP am Ende gar doch besser als Perl? :)
--
Henryk Plötz
Grüße aus Berlin