[prev in list] [next in list] [prev in thread] [next in thread] 

List:       apache-docs
Subject:    German translation filters.xml.de
From:       JGiesecke () t-online ! de (Jobst Giesecke)
Date:       2004-02-20 14:29:10
Message-ID: 403619B6.3050504 () t-online ! de
[Download RAW message or body]

["filters.xml.de" (text/html)]

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE manualpage SYSTEM "../style/manualpage.dtd">
<?xml-stylesheet type="text/xsl" href="../style/manual.de.xsl"?>

<manualpage metafile="filters.xml.meta">
<parentdocument href="./">Dokumentation für Entwickler</parentdocument>

<title>Wie Filter unter Apache 2.0 funktionieren</title>

<summary>
    <note type="warning"><title>Achtung</title>
<p>Dieses Dokument wurde mit "Ausschneiden und Einfügen" aus einer E-Mail
(&lt;022501c1c529$f63a9550$7f00000a@KOJ&gt;) erstellt und damit es besser
lesbar ist, neu formatiert. Es ist nicht auf aktuellem Stand, kann aber
als Ausgangspunkt für weitere Untersuchungen dienen.</p>
    </note>
</summary>

<section id="types"><title>Filtertypen</title>
<p>Es gibt drei Grundtypen von Filtern (die sich jeweils in zwei Kategorien
  unterteilen lassen, worauf später noch eingegangen wird).</p>

    <dl>
    <dt><code>CONNECTION</code></dt>
    <dd>Filter diesen Typs sind für die Dauer dieser Verbindung gültig.
    (<code>AP_FTYPE_CONNECTION</code>,
    <code>AP_FTYPE_NETWORK</code>)</dd>

    <dt><code>PROTOCOL</code></dt>
    <dd>Filter diesen Typs sind für die Dauer dieser Anfrage aus der Sicht des
    Client gültig, was bedeutet, dass die Anfrage vom Versenden bis zum Eingang
    der Antwort gültig ist. (<code>AP_FTYPE_PROTOCOL</code>,
    <code>AP_FTYPE_TRANSCODE</code>)</dd>

    <dt><code>RESOURCE</code></dt>
    <dd>Filter diesen Typs sind für die Zeit gültig, in der dieser Inhalt für eine
    Anfrage verwendet wird. Bei einfachen Anfragen ist dies identisch mit dem Filter
    <code>PROTOCOL</code>, aber interne Umleitungen und Unteranfragen
    können den Inhalt verändern, ohne dass die Anfrage damit beendet ist.
    (<code>AP_FTYPE_RESOURCE</code>,
    <code>AP_FTYPE_CONTENT_SET</code>)</dd>
    </dl>

<p>Die Unterscheidung zwischen einem Protokoll und einem
  Ressourcenfilter ist von Bedeutung.  Ein Ressourcenfilter ist an eine
  bestimmte Ressource gebunden, er kann auch an Header-Informationen
  gebunden sein, die wichtige Bindung ist jedoch die an die Ressource. Wenn Sie
  einen Filter erstellen und wissen wollen, ob es sich um eine Ressource oder
  um ein Protokoll handelt, dann lautet die richtige Frage: "Kann dieser Filter
  verschoben werden, wenn die Anfrage zu einer anderen Ressource umgeleitet
  wird?" Lautet die Antwort "Ja", dann handelt es sich um einen Ressourcenfilter.
  Lautet sie "Nein", handelt es sich wahrscheinlich um ein Protokoll oder um einen
  Verbindungsfilter. Auf Verbindungsfilter wird hier nicht eingegangen, weil
  sie hinreichend verständlich sind. Die Definitionen können mit einigen Beispielen
  verdeutlicht werden:</p>

    <dl>
    <dt>byterange</dt>
    <dd>Dieser Filter wurde so kodiert, dass er für alle Anfragen eingefügt und
    entfernt werden kann, wenn er nicht verwendet wird. Da dieser Filter
    zu Beginn aller Anfragen aktiv ist, kann er bei einer Umleitung nicht entfernt
    werden, dementsprechend handelt es sich um einen Protokollfilter.</dd>

    <dt>http_header</dt>
    <dd>Dieser Filter schreibt eigentlich die Header für das Netzwerk. Er wird
    offensichtlich benötigt (außer im Sonderfall von
    <module>mod_asis</module>, worauf weiter unten noch eingegangen wird)
    und er ist somit ein Protokollfilter.</dd>

    <dt>deflate</dt>
    <dd>Der Administrator konfiguriert diesen Filter entsprechend der angeforderten
    Datei. Bei einer internen Umleitung von einer Autoindex-Seite zu einer
    <code>index.html</code>- Seite kann der <code>deflate</code>-Filter
    entsprechend der Konfiguration hinzugefügt oder entfernt werden, daher
    handelt es sich um einen Ressourcenfilter.</dd>
    </dl>

<p>Die weitere Unterteilung der einzelnen Kategorien in zwei weitere Filtertypen
  dient ausschließlich der Anordnung. Wir könnten sie aufheben und nur einen
  Filtertyp zulassen, dann würde aber die Anordnung durcheinander geraten und
  es wären Eingriffe notwendig, um die Funktion zu gewährleisten. Zur Zeit
  besitzen die <code>RESOURCE</code>-Filter nur einen Filtertyp, aber das
  sollte geändert werden.</p>
</section>

<section id="howinserted"><title>Wie werden Filter eingefügt?</title>
<p>In der Theorie ist das eigentlich ganz einfach, der Code ist jedoch
  kompliziert. Zuerst einmal ist es wichtig, dass jeder sich klar macht, dass
  es drei Filterlisten für jede Anfrage gibt, die aber alle miteinander verkettet
  sind. Die erste Liste sind <code>r->output_filters</code>, dann folgen
  <code>r->proto_output_filters</code> und anschließend
  <code>r->connection->output_filters</code>. Sie entsprechen den
  <code>RESOURCE</code>-, <code>PROTOCOL</code>- und
  <code>CONNECTION</code>-Filtern. Vorher bestand das Problem darin,
  dass eine einfach verknüpfte Liste benutzt wurde, um einen Filter-Stack zu 
  erzeugen. Begonnen wurde dabei mit der "korrekten" Position.
  War eine <code>RESOURCE</code>-Filter im Stack und ein
 <code>CONNECTION</code>-Filter wurde hinzugefügt, dann bedeutete das,
dass der <code>CONNECTION</code>-Filter ignoriert wird. Das erscheint
sinnvoll, weil der Verbindungsfilter am Anfang der
<code>c->output_filters</code>-Liste eingefügt wird, während das Ende von
<code>r->output_filters</code> auf den Filter zeigt, der normalerweise
am Beginn von <code>c->output_filters</code> stand. Das ist offensichtlich
falsch. Der neue Code für das Einfügen benutzt eine doppelt verknüpfte Liste.
Das hat den Vorteil, dass ein eingefügter Filter niemals verloren geht. Leider
gibt es noch anderes Problem.</p>

<p>Es besteht darin, dass es zwei unterschiedliche Fälle
gibt, in den wir Unteranfragen verwenden. Im ersten Fall werden weitere Daten in
eine Antwort eingefügt. Im zweiten wird die vorhandene Antwort durch eine
interne Umleitung ersetzt. Dies sind zwei unterschiedliche Situationen, die
entsprechend behandelt werden müssen.</p>

<p>Im ersten Fall erzeugen wir die Unteranfrage aus einem Handler oder Filter
heraus. Das bedeutet, dass der nächste Filter an die Funktion
<code>make_sub_request</code> weitergereicht werden sollte und dass der
letzte Ressourcenfilter der Unteranfrage auf den nächsten Filter der Hauptanfrage
verweist. Das ist sinnvoll, wenn die Daten der Unteranfrage durch die gleichen Filter
laufen müssen wie die Hauptanfrage. Eine grafische Darstellung kann das
verdeutlichen:</p>

<example>
<pre>
Default_handler --> includes_filter --> byterange --> ...
</pre>
</example>

<p>Erzeugt der <code>include_filter</code> eine Unteranfrage, dann sollen
die Daten dieser Unteranfrage durch diesen Filter laufen, weil es sich nicht um
SSI-Daten handeln kann. Daher nimmt die Unteranfrage folgende Ergänzung vor:</p>

<example>
<pre>    
Default_handler --> includes_filter -/-> byterange --> ...
                                    /
Default_handler --> sub_request_core
</pre>
</example>

<p>Was geschieht, wenn die Unteranfrage SSI-Daten enthält? Das ist
ganz einfach, der <code>includes_filter</code> ist ein Ressourcenfilter, daher
wird er der Unteranfrage zwischen dem <code>Default_handler</code> und dem
<code>sub_request_core</code>-Filter hinzugefügt.</p>

<p>Der zweite Fall für Unteranfragen liegt vor, wenn eine Unteranfrage zu einer
richtigen Anfrage wird. Das geschieht immer dann, wenn eine Unteranfrage
außerhalb eines Handler oder Filters erzeugt wird und NULL als nächster
Filter an die Funktion <code>make_sub_request</code> weitergegeben wird.</p>

<p>In diesem Fall sind die Ressourcenfilter nicht mehr sinnvoll, weil sich die
Ressource geändert hat. Anstatt ganz von vorne zu beginnen, wird einfach
auf den Anfang der Ressourcenfilter für die Unteranfrage am Anfang der
Protokollfilter für die alte Anfrage verwiesen. Das bedeutet, dass keine
Protokollfilter verloren gehen und die Daten auch nicht durch einen Filter
geleitet werden, der nicht für sie vorgesehen ist.</p>

<p>Das Problem ist, dass jetzt eine doppelt verknüpfte Liste für die
Filter-Stacks benutzt wird. Sie sollten aber beachten, dass es möglich ist,
bei zwei Listen dieses Modell zu durchkreuzen. Wie wird mit dem vorherigen
Filter umgegangen? Diese Frage ist schwer zu beantworten, weil es keine
"richtige" Antwort noch eine gleichermaßen gültige Methode gibt. Ich habe
untersucht, warum der Pointer verwendet wird. Der einzige Grund ist, dass
Hinzufügen neuer Server zu vereinfachen. Vor diesem Hintergrund habe ich die
Lösung gewählt, den vorherigen Pointer immer auf die ursprüngliche Anfrage
verweisen zu lassen.</p>

<p>Das führt zu einer etwas komplexeren Logik, funktioniert aber in allen
Fällen. Meine Bedenken hinsichtlich der Verschiebung auf die Unteranfrage
rühren daher, dass in den allgemeineren Fällen (wo einer Antwort mit der
Unteranfrage Daten hinzugefügt werden), die Hauptfilterkette falsch wäre.
Das scheint mir keine gute Idee zu sein.</p>
</section>

<section id="asis"><title>Asis</title>
<p>Der letzte Punkt.  :-)  <code>mod_asis</code> hat etwas von einem Hack,
aber der Handler muss alle Filter mit Ausnahme des Verbindungsfilters entfernen
und die Daten senden. Wenn Sie <module>mod_asis</module> benutzen,
sind alle anderen außer Kraft gesetzt.</p>
</section>

<section id="conclusion"><title>Erläuterungen</title>
<p>Zum Abschluss sei erwähnt, dass der Grund, warum dieser Code so schwer
zu formulieren war, die Tatsache war, dass er so stark manipuliert werden musste,
damit er funktioniert. Die meisten der Manipulationen habe ich selbst vorgenommen,
so dass die Schuld bei mir liegt. Aber jetzt, wo der Code richtig ist, habe ich damit
begonnen, einige Hacks zu entfernen. Den meisten sollte aufgefallen seien, dass
die Funktionen <code>reset_filters</code> und
<code>add_required_filters</code> verschwunden sind. Diese haben auf
Protokollebene Filter für Fehlerbedingungen eingefügt und seltsamer Weise
haben beide Funktionen nacheinander das Gleiche getan. Da jetzt keine
Protokollfilter für Fehlersituationen mehr verloren gehen, sind diese Hacks entfernt
worden.
Die Filter <code>HTTP_HEADER</code>, <code>content-length</code> und
<code>byterange</code> wurden in die <code>insert_filters</code>-Phase
eingefügt, denn würden sie vorher eingefügt, dann käme es zu interessanten
Interaktionen. Sie konnten jetzt alle so verschoben werden, dass sie mit den
Filtern <code>HTTP_IN</code>, <code>CORE</code> und
<code>CORE_IN</code> eingefügt werden. Auf diese Weise ist der Code
leichter nachzuvollziehen.</p>
</section>
</manualpage>




---------------------------------------------------------------------
To unsubscribe, e-mail: docs-unsubscribe@httpd.apache.org
For additional commands, e-mail: docs-help@httpd.apache.org

[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic