www.fabiankeil.de/blog-surrogat/2006/04/13/vorstellung-neuer-privoxy-erweiterungen.html

Vorstellung neuer Privoxy-Header-Aktionen:

crunch-header, hide-accept-language, crunch-if-modified-since, crunch-if-none-match, content-type-overwrite und force-text-mode

Wenn man Privoxys Innereien erstmal oberflächlich verstanden hat, ist das Schreiben eines einfachen Header-Filters nur noch eine Sache von Kopieren und Einfügen.

Beim Lösen meiner Privoxy-DNS-Probleme und beim Schreiben der Privoxy-Ergänzung +hide-referrer{conditional-block} hatte ich mich bereits etwas mit Privoxys Quelltext auseinander gesetzt, für Version 0.4 von uagen.pl fehlte mir eine Funktion um den Accept-Language-Header zu unterdrücken und wo ich schon dabei war, habe ich ein paar zusätzliche Erweiterungen geschrieben, die mir sinnvoll erschienen.

crunch-header

Diese Privoxy-Aktion löscht beliebig viele Header, die noch nicht von anderen Aktionen erfasst wurden und die eine als Parameter übergebene Zeichenkette enthalten. Zusammen mit der bereits vorhandenen Privoxy-Aktion add-header kann damit eine noch nicht vorhandene Header-Ersetzungs-Aktion simuliert werden.

Die nicht veröffentlichte Version 0.3 von uagen.pl stellte die benötigte Accept-Language-Header-Fälschung mit einer Sektion wie

{+crunch-header{Accept-Language:} \
+add-header{Accept-Language: de-ch} \
+hide-user-agent{Mozilla/5.0 (X11; U; NetBSD sparc64; de-CH; rv:1.8.0.1) Gecko/20060218 Firefox/1.5.0.1} \
}
/

nach. Um die schweizerische Firefox-Version glaubhafter zu machen wird damit erst der gesendete Accept-Language-Header gelöscht und anschließend ein neuer Header angelegt, der sprachlich passt.

Da add-header und crunch-header unabhängig voneinander arbeiten, handelt es sich dabei nur um eine Notlösung mit der man sich auch in den Fuß schießen kann.

Wenn man sich bei der crunch-header-Zeichenkette vertippt, hat man nachher zwei Header die sich wiedersprechen. Formuliert man die Zeichenkette zu allgemein, wird die Anfrage ungültig, weil vorgeschriebene Header fehlen. +crunch-header{:} würde zum Beispiel jeden Header entfernen, den sich nicht vorher eine andere Privoxy-Aktion gekrallt hat.

Im Notfall ist crunch-header besser als gar nichts, eine passende Privoxy-Aktion ist jedoch stets vorzuziehen.

Im Gegensatz zu add-header kann crunch-header auch über das Webinterface aktiviert werden, als großer Nachteil kann dadurch pro Anfrage immer nur eine Zeichenkette zur Header-Unterdrückung genutzt werden.

hide-accept-language

Version 0.4 von uagen.pl muss in die user-agent.action nur noch:

{+hide-accept-language{sk-sk}\
+hide-user-agent{Mozilla/5.0 (X11; U; OpenBSD alpha; sk-SK; rv:1.8.0.1) Gecko/20060219 Firefox/1.5.0.1} \
}
/

schreiben. Damit wird sichergestellt, dass der Benutzer die Fälschung des Accept-Language-Headers nicht aus Versehen sabotiert, indem er crunch-header zum Entfernen eines anderen Headers nutzt und damit unbeabsichtigt die in user-agent.action angegebene Zeichenkette Accept-Language: überschreibt.

hide-accept-language kann, wie alle anderen hier beschriebenen Erweiterungen, auch über das Webinterface bedient werden.

crunch-if-modified-since

Beim Testen von neuen regulären Ausdrücken kommt es regelmäßig vor, dass man die zu filternde Seite mit F5 statt mit Strg + F5 anfordert, der Browser die Seite aus dem Cache lädt und man sich über die Wirkungslosigkeit des zu testenden Filters wundert.

Während des Tests kann mit der Aktion crunch-if-modified-since dafür gesorgt werden, dass der Server die komplette Seite neu liefert und Privoxy eine Chance hat, den neuen Filter anzuwenden.

Als Firefox-Nutzer kann man sich damit auch den Affentanz sparen, der nötig ist, um einen Feed wirklich neu zu laden.

Prinzipiell hat der If-Modified-Since-Header einen Sinn, crunch-if-modified-since sollte daher nur bei Bedarf und für bestimmte Seiten aktiviert werden, ansonsten verlangsamt sich der Seitenaufbau.

crunch-if-none-match

Der If-None-Match-Header kann wie der If-Modified-Since-Header dafür genutzt werden, um das Dokument nur bei Änderungen neu übertragen zu müssen.

Wenn auch der If-None-Match-Header gesetzt ist, reicht das Unterdrücken des If-Modified-Since-Headers nicht aus, mit dieser Aktion kann man zusätzlich den If-None-Match-Header unterdrücken.

Ich überlege noch, ob ich die beiden Aktionen zusammenfassen sollte, mir fällt jedenfalls kein Grund ein, warum man nur die eine verwenden wollte.

content-type-overwrite

Ich begründetet bereits, warum ich 99% der XHTML-Benutzer für inkompetente Nasenbären halte, unter den restlichen Spezialisten gibt es aber noch die Clowns, die ihre Seiten zwar als application/xhtml+xml ausgeben, sich aber nicht an die Regeln halten.

Bei XHTML führt das dazu, dass der Browser die Seite nicht darstellt, egal wie geringfügig die Fehler sind. Der glückliche Besucher darf dann den Quelltext selber parsen, oder den Fehler mit Privoxy (und viel Zeit) selber beseitigen.

Mit content-type-overwrite kann man auch mal Schnarchnase spielen und den Content-Type auf text/html setzen, auf das der Browser die Seite als defektes HTML betrachtet und versucht, das Beste aus ihr zu machen.

Diese Aktion nimmt keine Rücksicht darauf, mit welchem Content-Type das Dokument geliefert wird. Sie greift sobald Privoxy das Dokument anhand des Content-Types als Text eingestuft hat.

Damit wird zwar sichergestellt, dass man nicht ungewollt Bilder und andere Binär-Dokumente umdeklariert, der Benutzer muss aber selbst dafür sorgen, dass keine Style-Sheets umdeklariert werden. Es sei denn es wäre erwünscht oder zumindest egal.

Wenn die Aktion zuerst für alle Dokumente der gewünschten Domain aktiviert und anschließend für alle Adressen, die die Zeichenkette CSS oder Style enthalten wieder deaktiviert, stehen die Chancen gut:

{+content-type-overwrite{text/html} \
}
.example.com/
{-content-type-overwrite \
}
/.*(CSS|Style)

Wie Marius Müller-Westernhagen schon wusste: Garantie gibt es keine.

force-text-mode

Wenn man sicher ist, eine von Privoxy nicht als Text erkanntes Dokument über reguläre Ausdrücke verändern oder mit content-type-overwrite umdeklarieren zu wollen, kann man mit force-text-mode den Text-Modus erzwingen.

Diese Privoxy-Aktion hat das Potential defekte Dateien zu verursachen, den Einsatz sollte man sich gut überlegen und um den Schaden gering zu halten dabei alle nicht benötigten Aktionen, die Einfluss auf den Textinhalt haben können, ausdrücklich deaktivieren.

Nochmal zum mitschreiben:

force-text-mode, Schere, Feuer, Licht, ist für Kinderhände nicht!

Richtungsangabe

crunch-header greift nur auf dem Weg vom Browser zum Server, wenn man die Kommentar-Zeichen in Zeile 515 (+-X, bin gerade zu faul die Angabe zu aktualisieren) von parsers.c entfernt auch auf dem Rückweg. Da add-header jedoch nur auf dem Hinweg tätig wird, kann crunch-header auf dem Rückweg nur zum Header-Löschen genutzt werden.

hide-accept-language, crunch-if-none-match und crunch-if-modified-since sind ebenfalls nur auf dem Hinweg aktiv, content-type-overwrite und force-text-mode nur auf dem Rückweg.

Privoxy-Sammel-Patch

Da es mir zu umständlich geworden ist, für jede geänderte Datei einen eigenen Patch zu erzeugen und hochzuladen, habe ich einen Sammel-Patch angelegt.

Momentan umfasst er alle im Blog-Surrogat erwähnten Erweiterungen mit Ausnahme der Umdeklaration von DNS-Fehlermeldungen nach 503, die nicht mehr benötigt werden sollte.

Den Patch werde ich noch gelegentlich verändern, Teile der neuen Erweiterungen müssen gesäubert werden, möglicherweise finden sich auch noch Fehler. Beim Einsatz des Patches ist es empfehlenswert, in Privoxys Konfigurationsdatei debug 8 aktivieren und Privoxy beim Parsen der Header über die Schultern zu schauen.

Der Patch basiert auf Privoxys Entwickler-Version, kann aber auch mit Privoxy 3.0.3 ohne Anpassungen genutzt werden. Die Offset-Meldungen sind kein Grund zur Panik. Weitere Informationen zum Patch gibt es auf der Seite Minor Privoxy improvements.