buecher.lingoworld.de
sascha kersken

buecher.lingoworld - Startseite

    buchinfo

    aktuelles

    newsletter

    inhalt

    leseprobe

    rezensionen

    direktiven

    module

    errata

    forum

    buchtipps

    links



    bestellen bei:

    Galileo Press
    amazon.de





Module
 
Galileo Computing 
Energy Brain Comics

mod_daytime

Eine der wichtigsten Neuerungen von Apache 2 ist der Multi-Protokoll-Support: Neben dem "Hauptdienst" HTTP ist die Software prinzipiell in der Lage, auch mit anderen TCP-Netzwerkdiensten umzugehen. Als Beispiel enthält die Apache-Distribution das Modul mod_echo, das das Echo-Protokoll implementiert. Dieser TCP-Standarddienst beantwortet jede Anfrage, indem er deren vollständigen Inhalt zurücksendet. Damit dient er vornehmlich der Überprüfung von Netzwerkverbindungen.

Auf der Grundlage des mod_echo-Codes habe ich das Modul mod_daytime geschrieben. Es implementiert den Daytime-Dienst gemäszlig; RFC 867. Dieser beantwortet jede Anfrage mit Datum und Uhrzeit; das Format ist nicht vorgeschrieben. Die vorliegende Fassung verwendet ctime(3) zur Formatierung.

Das Modul stellt nur eine einzige Konfigurationsdirektive zur Verfügung:

Direktive: ProtocolDaytime
Kontext: Server, <VirtualHost>
Syntax: ProtocolDaytime On | Off

In aller Regel empfiehlt es sich, einen virtuellen Host einzurichten, der ausschließlich den Daytime-Dienst versieht. Dieser könnte beispielsweise für den TCP-Port 13 konfiguriert werden, an dem Daytime-Server standardmäßig lauschen. Die notwendigen Konfigurationsanweisungen sehen so aus:

    # Lauschen an Port 13
    Listen 13

    <VirtualHost *:13>
       ProtocolDaytime On
    </VirtualHost>

Zunächst müssen Sie den hier zur Verfügung gestellten Quellcode allerdings kompilieren. Auf einem UNIX-System, auf dem Apache 2 mit DSO-Unterstützung installiert ist, können Sie einfach (als Root) folgenden Befehl eingeben:

    # [/Pfad/zu/apache/bin/]apxs -cia mod_daytime.c

Dies erstellt die DSO-Datei mod_daytime.so, kopiert sie in das /modules-Verzeichnis der Apache-Installation und fügt automatisch die folgende Direktive zum Laden des Moduls in die httpd.conf ein:

    LoadModule daytime_module modules/mod_daytime.c

Erläuterung des Modul-Quellcodes

Wie jedes Apache-Modul ist auch mod_daytime in ANSI-C geschrieben und macht Gebrauch von der Apache-API. Daher beginnt es mit einigen Präprozessor-Direktiven zum Einfügen der API-Header-Dateien sowie der Standardbibliotheksdatei time.h:

    #include "ap_config.h"
    #include "ap_mmn.h"
    #include "httpd.h"
    #include "http_config.h"
    #include "http_connection.h"

    #include "apr_buckets.h"
    #include "util_filter.h"
    #include <time.h>

Als Nächstes erfolgt die Forward-Deklaration der Modulstruktur, da im Verlauf der diversen Modulfunktionen manchmal darauf Bezug genommen wird:

    module AP_MODULE_DECLARE_DATA daytime_module;

Die Definition der Modulstruktur selbst steht dagegen in aller Regel am Ende der Datei (genauer gesagt: am Ende der Hauptdatei mod_xxx.c, falls ein Modul aus mehreren Quellcode-Dateien besteht):

    /* Modulstruktur */
    module AP_MODULE_DECLARE_DATA daytime_module = {
        STANDARD20_MODULE_STUFF,
        NULL,                       /* Konfiguration pro Verzeichnis */
        NULL,                       /* Verknüpfung (Merger) der Verzeichnis-Konfigurationen */
        create_daytime_server_config,  /* Konfiguration pro Server */
        NULL,                       /* Verknüpfung (Merger) der Server-Konfigurationen */
        daytime_cmds,                  /* Befehlstabelle (Direktiven) */
        register_hooks              /* Registrierung der Hooks */
    };

Jedes Modul kann also Funktionen zur Verzeichniskonfiguration, zur Verknüpfung verschachtelter Verzeichniskonfigurationen, zur Server-Konfiguration und zur Verknüpfung von Server-Konfigurationen definieren, die hier referenziert werden. Zum Schluss folgen die Befehlstabelle, die die Konfigurationsdirektiven des Moduls festlegt, sowie die Hook-Registrierungsfunktion, die bestimmt, zu welchem Zeitpunkt der HTTP-Transaktion die Dienste des Moduls in Anspruch genommen werden. Nicht benötigte Funktionsreferenzen werden einfach auf NULL gesetzt. Die symbolische Konstante STANDARD20_MODULE_STUFF wird dagegen von jedem Apache-2-Modul benötigt.

Nun wird eine Datenstruktur definiert, die die Konfigurationsdaten der Direktive aufnehmen kann. mod_daytime benötigt nur einen einzigen int-Wert, der auf 0 für ProtocolDaytime Off (Standard) und auf 1 für ProtocolDaytime On gesetzt werden kann. Folgerichtig heißt das entsprechende struct-Feld dt_enabled:

    /* Konfigurations-Datenstruktur */
    typedef struct {
        int dt_enabled;
    } daytime_config;

Beachten Sie, dass manche Module zwei verschiedene Konfigurations-Datenstrukturen deklarieren, wenn die Einstellungsmöglichkeiten pro Server und pro Verzeichnis sich voneinander unterscheiden. mod_daytime enthält dagegen nur eine Server-Konfiguration, was bereits die Modulstruktur zeigt.

Die Funktion create_daytime_server_config() reserviert den nötigen Speicher für die Konfigurationseinstellungen und belegt sie mit einem Standardwert - hier 0 für »ausgeschaltet«. Ihr Aufruf wird durch den weiter oben erwähnten Zeiger in der Modulstruktur gesteuert:

    /* Erstellen der Konfiguration pro Server */
    static void *create_daytime_server_config(apr_pool_t *p, server_rec *s)
    {
        daytime_config *conf = apr_pcalloc(p, sizeof *conf);

        conf->dt_enabled = 0;

        return conf;
    }

Diese Vorkonfiguration wird durch den Wert der Direktive ProtocolEcho überschrieben, bei deren Auftreten die folgende Funktion aufgerufen wird:

    /* Verarbeiten der Konfigurationsdirektive ProtocolDaytime */
    static const char *daytime_on(cmd_parms *cmd, void *dummy, int arg)
    {
        daytime_config *conf = ap_get_module_config(cmd->server->module_config,
                                                    &daytime_module);
        conf->dt_enabled = arg;

        return NULL;
    }

Die Kernfunktionalität des Moduls wird durch die nachfolgende Funktion bereitgestellt. Diese liest zunächst die Konfiguration des aktuellen Verzeichnisses und gibt DECLIEND (»nicht zuständig«) zurück, falls dt_enabled false ist. Andernfalls erstellt sie mit Hilfe einer Apache-API-Funktion eine so genannte Bucket Brigade, die die Ausgabedaten für den Client enthält, und schreibt die mittels ctime() formatierte Uhrzeit hinein. Hier der vollständige Code:

    /* Verarbeiten der daytime-Verbindung */
    static int process_daytime_connection(conn_rec *c)
    {
        apr_bucket_brigade *bb;
        apr_bucket *b;
        apr_status_t rv;
        time_t now;
        daytime_config *conf = ap_get_module_config(c->base_server->module_config,
                                                   &daytime_module);

        if (!conf->dt_enabled) {
            return DECLINED;
        }

        bb = apr_brigade_create(c->pool, c->bucket_alloc);

        now = time (NULL);
        
        ap_fprintf(c->output_filters, bb, "%s\r\n", ctime(&now));
        ap_fflush(c->output_filters, bb);

        return OK;
    }

Die bereits genannte Befehlstabelle definiert die Direktive und legt fest, welche Funktion bei deren Auftreten aufgerufen wird:

    /* Direktive */
    static const command_rec daytime_cmds[] =
    {
        AP_INIT_FLAG("ProtocolDaytime", daytime_on, NULL, RSRC_CONF,
                     "Run a daytime server on this host"),
        { NULL }
    };

Die Datentypkonstante AP_INIT_FLAG besagt, dass die Direktive die Werte On und Off versteht, die automatisch in 1 beziehungsweise 0 umgewandelt werden. Für andere Direktivenarten gibt es weitere Typkonstanten, etwa AP_INIT_TAKE1 für genau einen beliebigen Wert.

Das letzte Element ist die Funktion register_hooks(). Hooks legen fest, an welchen Stellen Module in den Arbeitsablauf des Apache-Webservers eingreifen können. Es gibt zahlreiche Hooks, die Zeitpunkte vom Serverstart über das Einlesen der Konfiguration, das Lesen der Client-Anfrage und die Erzeugung der Antwort bis hin zur Verarbeitung durch Ausgabefilter definieren. Da mod_daytime ein anderes Anwendungsprotokoll als HTTP definiert, ist der passende Hook process_connection - denn die Feststellung, dass überhaupt eine Anfrage (mit beliebigem Inhalt) stattgefunden hat, genügt bereits für die Erzeugung der Antwort. Mit Details wie speziellen Protokollbefehlen gibt sich Daytime nämlich nicht ab, und der standardmäßig zuständige HTTP-Parser braucht hier erst recht nicht aktiv zu werden. Hier nur noch der Code von register_hooks():

    /* Hooks registrieren */
    static void register_hooks(apr_pool_t *p)
    {
        ap_hook_process_connection(process_daytime_connection, NULL, NULL,
                                   APR_HOOK_MIDDLE);
    }

Hier können Sie mod_daytime herunterladen.



nach oben
Zur Übersicht
No Software Patents!

Ihre Werbung hier?
    
    www.lingoworld.de
    webmaster@lingoworld.de
    © Copyright 2004-2007 by Lingoworld IT Services, Köln
    designed by Tülay Kersken
    Impressum