Title: Anfragebearbeitung durch den Apache 2.0




Dokumentation für Entwickler




    Warnung

Achtung - dies ist ein kurzer Entwurf, der noch überarbeitet werden muss!

Zahlreiche Änderungen des Apache 2.0 betreffen die interne Anfrageverarbeitung. Modulentwickler müssen diese Änderungen kennen, damit sie die Vorteile dieser Optimierungen und Sicherheitserweiterungen nutzen können.

Die erste wichtige Änderung betrifft die Mechanismen für Unteranfragen und Umleitungen. Der Apache 1.3 besaß eine Reihe unterschiedlicher Codepfade für die Optimierung des Verhaltens bei Unteranfragen oder Umleitungen. Mit der Einführung von Patches für die Version 2.0 wurden diese Optimierungen (und das Serververhalten) infolge der Codeduplikation schnell unwirksam. Alle Codeduplikationen wurden wieder in die Funktion ap_process_internal_request() verlagert, um eine mangelnde Synchronisation zu verhindern.

Das bedeutet, dass viel vom vorhandenen Code 'entoptimiert' wurde. Es ist das vorrangige Ziel des Apache HTTP-Projekts, eine robuste und korrekte Implementierung des HTTP-Server-RFC zu realisieren. Zu den weiteren Zielen gehören die Sicherheit, die Skalierbarkeit und die Optimierung. Neue Methoden sollen den Server optimieren (über die Leistungen des Apache 1.3 hinaus), ohne anfälligen oder unsicheren Code.

Der Zyklus der Anfragebearbeitung

Alle Anfragen durchlaufen die Routine ap_process_request_internal() aus der Datei request.c, auch Unteranfragen und Umleitungen. Übergibt ein Modul generierte Anfragen nicht an diesen Code, dann muss sich der Entwickler vergegenwärtigen, dass das Modul durch zukünftige Veränderungen an der Anfragebearbeitung nicht mehr funktionieren kann.

Um Anfragen zu rationalisieren, kann der Entwickler die angebotenen Hooks nutzen, um den Zyklus früher zu verlassen oder um die Apache-Hooks zu umgehen, die irrelevant (und CPU-aufwändig) sind.

Die Phase der Anfrageanalyse
Entschlüsselung der URL

Der parsed_uri-Pfad der Anfrage wird nur einmal zu Beginn der internen Anfragebearbeitung entschlüsselt.

Dieser Schritt wird übergangen, wenn das Flag proxyreq gesetzt oder das Element parsed_uri.path nicht gesetzt ist. Das Modul hat keine weitere Kontrolle über diese einmalige Entschlüsselung, eine fehlgeschlagene oder mehrfache Entschlüsselung der URL wirkt sich auf die Sicherheit aus.

Entfernen von Parent- und This-Elementen aus dem URI

Alle /../- und /./-Elementwerden von ap_getparents() entfernt. Auf diese Weise wird dafür gesorgt, dass der Pfad (nahezu) absolut ist, bevor die Anfragebearbeitung fortgesetzt wird.

Dieser Schritt kann nicht ausgelassen werden.

ap_location_walk() - 1

Jede Anfrage wird von der Funktion ap_location_walk() bearbeitet. Damit wird sichergestellt, dass die Location-Abschnitte konsistent für alle Anfragen wirksam werden. Handelt es sich um eine interne Umleitung oder um eine Unteranfrage, können einige oder alle Resultate von ap_location_walk-Aufrufen vorangegangener oder übergeordneter Anfragen genutzt werden, so dass dieser Schritt nach der Verarbeitung der eigentlichen Anfrage generell sehr effizient ist.

translate_name

In diesem Schritt können Module den Dateinamen ermitteln oder den angegebenen URI ändern. Das Modul mod_vhost_alias wandelt beispielsweise den Pfad des URI in den konfigurierten virtuellen Host um, das Modul mod_alias wandelt den Pfad in einen Alias-Pfad um und wenn die Anfrage an den Kernel zurückgegeben wird, wird die DocumentRoot der Ressource der Anfrage vorangestellt.

Verweigern alle Module diese Phase, wird der Fehlercode 500 an den Browser zurückgegeben und der Fehler "Umwandlung nicht möglich" automatisch protokolliert.

Hook: map_to_storage

Nachdem die Datei oder der korrekte URI ermittelt wurde, werden die entsprechenden Verzeichniskonfigurationen miteinander vermischt. Das Modul mod_proxy vergleicht und vermischt beispielsweise die entsprechenden Proxy-Abschnitte. Ist der URI nichts anderes als eine lokale (nicht Proxy) TRACE-Anfrage, dann behandelt der Kernel die Anfrage und gibt DONE zurück. Antwortet kein Modul auf diesen Hook mit OK oder DONE, führt der Kernel den Dateinamen der Anfrage noch einmal für die Abschnitte Directory und Files aus. Handelt es sich bei dem Dateinamen der Anfrage nicht um einen absoluten, zulässigen Dateinamen, wird eine Note für die spätere Beendigung gesetzt.

ap_location_walk() - 2

Jede Anfrage muss einen zweiten ap_location_walk()-Aufruf durchlaufen. Damit wird sichergestellt, dass eine umgewandelte Anfrage immer noch Gegenstand der konfigurierten Location-Abschnitte ist. Die Anfrage übernimmt wieder einige oder alle Resultate des oben angeführten location_walk-Aufrufs, so dass dieser Schritt fast immer sehr effizient ist, es sei denn, der umgewandelte URI ist einem grundsätzlich anderen Pfad oder virtuellem Host zugeordnet.

Hook: header_parser

Die Hauptanfrage bearbeitet dann die Client-Header. Damit werden die verbleibenden Schritte der Anfragebearbeitung vorbereitet, um die Client-Anfrage besser bedienen zu können.

Die Sicherheitsphase

Muss noch dokumentiert werden. Der Code ist:

switch (ap_satisfies(r)) {
case SATISFY_ALL:
case SATISFY_NOSPEC:
    if ((access_status = ap_run_access_checker(r)) != 0) {
        return decl_die(access_status, "check access", r);
    }

    if (ap_some_auth_required(r)) {
        if (((access_status = ap_run_check_user_id(r)) != 0)
            || !ap_auth_type(r)) {
            return decl_die(access_status, ap_auth_type(r)
                          ? "check user.  No user file?"
                          : "perform authentication. AuthType not set!",
                          r);
        }

        if (((access_status = ap_run_auth_checker(r)) != 0)
            || !ap_auth_type(r)) {
            return decl_die(access_status, ap_auth_type(r)
                          ? "check access.  No groups file?"
                          : "perform authentication. AuthType not set!",
                          r);
        }
    }
    break;

case SATISFY_ANY:
    if (((access_status = ap_run_access_checker(r)) != 0)) {
        if (!ap_some_auth_required(r)) {
            return decl_die(access_status, "check access", r);
        }

        if (((access_status = ap_run_check_user_id(r)) != 0)
            || !ap_auth_type(r)) {
            return decl_die(access_status, ap_auth_type(r)
                          ? "check user.  No user file?"
                          : "perform authentication. AuthType not set!",
                          r);
        }

        if (((access_status = ap_run_auth_checker(r)) != 0)
            || !ap_auth_type(r)) {
            return decl_die(access_status, ap_auth_type(r)
                          ? "check access.  No groups file?"
                          : "perform authentication. AuthType not set!",
                          r);
        }
    }
    break;
}
Die Vorbereitungsphase
Hook: type_checker

Die Module haben eine Gelegenheit, den URI oder Dateinamen im Vergleich zur Zielressource zu testen und MIME-Informationen für die Anfrage zu setzen. Sowohl mod_mime als auch mod_mime_magic benutzen diese Phase für einen Vergleich des Dateinamens oder Inhalts mit der vom Administrator vorgenommenen Konfiguration und setzen den Inhaltstyp, die Sprache, den Zeichensatz und den Anfrage-Handler. Einige Module können zu diesem Zeitpunkt ihre Filter oder andere Parameter für die Anfragebearbeitung setzen.

Verweigern alle Module diese Phase, wird der Fehlercode 500 an den Browser zurückgegeben und der Fehler "Typen nicht gefunden" automatisch ins Fehlerprotokoll geschrieben.

Hook: Fixup-Phase

Viele Module werden in einigen der oben aufgeführten Phasen 'beschnitten'. In Fixup-Phase stellen die Module ihre Eigentümerschaft wieder her oder sorgen für die entsprechenden Werte in den Header-Feldern der Anfrage. Dies ist nicht unbedingt das sauberste Verfahren, ist aber oft die einzige Option.

Die Handler-Phase

Diese Phase ist nicht Betsandteil der Verarbeitung durch ap_process_request_internal(). Viele Module bereiten eine oder mehrere Unteranfragen vor dem Erzeugen von Inhalten vor. Nachdem der Kernel oder ein anderes Modul ap_process_request_internal() aufgerufen hat, wird ap_invoke_handler() aufgerufen, um die Anfrage zu erzeugen.

Hook: insert_filter

Module, die den Inhalt in irgendeiner Form umwandeln, können ihre Werte einfügen und vorhandene Filter überschreiben. Hat der Benutzer außerhalb der Reihenfolge einen etwas erweiterten Filter konfiguriert, dann kann das Modul daher die Reihenfolge nach Bedarf ändern. Es gibt keinen Ergebniscode, deshalb sollte den Aktionen in diesem Hook besser unterstellt werden, dass er immer erfolgreich ist.

Hook: Handler

Abschließend hat das Modul die Möglichkeit, die Anfrage über den Handler-Hook zu bedienen. Beachten Sie, dass nicht jede vorbereitete Anfrage an den Handler-Hook gesendet wird. Viele Module wie zum Beispiel mod_autoindex erzeugen für einen angegebenen URI Unteranfragen, die niemals bedient werden, sondern sie nur für den Benutzer aufführen. Denken Sie daran, den erforderlichen Abbau der oben angeführten Hooks nicht in dieses Modul einzubinden, sondern Poolbereinigungen für den Anfragepool zu registrieren, um Ressourcen wie erforderlich freizugeben.

---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to