[ zurück ]

"Hallo ISAPI!" - simples Demoprojekt zum Einstieg


Ein erstes bescheidenes Projekt soll Ihnen den Einstieg in die Materie vermitteln. Sie werden mittels eines ISAPI-Programmes eine dynamische HTML-Seite erzeugen, die beim Abruf die aktuelle Uhrzeit enthält. Delphi stellt Ihnen das Grundgerüst der zukünftigen DLL über "Datei" - "Neu" - "DLL" bereit.

In jeder Ihrer ISAPI-DLLs benötigen Sie zuerst den Eintrittspunkt für den HTTP-Server beim Laden der Servererweiterung.

function GetExtensionVersion(var Ver: THSE_VERSION_INFO): BOOL; stdcall;
begin
 Ver.dwExtensionVersion:= MAKELONG(HSE_VERSION_MINOR, HSE_VERSION_MAJOR);
 Ver.lpszExtensionDesc:= 'Meine-ISAPI-DLL';
 GetExtensionVersion:=true;
end;

Ver ist dabei ein Mini-Record mit den beiden Elementen dwExtensionVersion und lpszExtensionDesc, der in der Unit Isapi.PAS deklariert ist. Vergessen Sie deren Aufnahme in den uses-Abschnitt Ihres Programmes nicht! Als dwExtensionVersion wird die Versionsnummer des verwendeten ISAPI-Standards erwartet. Momentan unterstützen alle ISAPI-fähigen Server Version 1, die aktuellen Microsoft-Server auch Version 2 und 3. Die Delphi-Unit Isapi.PAS deklariert HSE_VERSION_MAJOR derzeit auf den Versionswert 1. Es gibt aber von Inprise auch die Unit Isapi2.PAS für Version 2.

Für lpszExtensionDesc haben Sie freie Hand. Jede von Ihnen programmierte Servererweiterung sollte sich mit einem eindeutigen Namen beim Server registrieren. Auf diesen Name wird aber im Weiteren nicht mehr zurückgegriffen.

Damit ist die erste Prozedur bereits fertig. Der zweite Eintrittspunkt Ihrer ISAPI-DLL namens HttpExtensionProc ist im Grundgerüst nicht wesentlich komplizierter. Allerdings implementieren Sie hier frei die beabsichtigte Ausgabeaktion Ihres Programmes.

function HttpExtensionProc(var ECB:TEXTENSION_CONTROL_BLOCK):DWORD;stdcall;
var ResStr: string;
    StrLen: DWORD;
begin
 ECB.lpszLogData:='Delphi-DLL';
 ResStr:='<HTML><HEAD><TITLE>ISAPI-Hallo</TITLE></HEAD>'+
         '<BODY><H1>ISAPI-Hallo!!</H1>'+
          FormatDateTime('d. mmmm yyyy, hh:nn:ss',Now())+
         '</BODY></HTML>';
 ResStr:=Format(
   'HTTP/1.0 200 OK'#13#10'Content-Type: text/html'#13#10+
   'Content-Length: %d'#13#10'Content:'#13#10#13#10'%s',
   [Length(ResStr), ResStr]);
 StrLen:=Length(ResStr);
 ECB.dwHTTPStatusCode:=200;
 ECB.WriteClient(ECB.ConnID, Pointer(ResStr), StrLen, 0);
 HttpExtensionProc:=HSE_STATUS_SUCCESS;
end;

Charakteristisch für diese Prozedur ist der Variablenparameter ECB. Dieser Datenblock ECB, dessen Record-Elemente ebenfalls in der Unit Isapi.PAS definiert sind, dient zur Vermittlung sowohl der Ein- als auch der Ausgabeparameter.

Ausgegeben werden eine Log-Information und ein Statuscode für den Webserver. lpszLogData ist ein Zeichenfeld, das je nach Server im Logbuch zur Aufzeichnung von Zugriffen verwendet wird. Der Statuscode dwHTTPStatusCode dient ebenfalls der Rückmeldung. In den einschlägigen RFCs (request for comment - Diskussionspapier zu technischen Standards) sind die Werte erklärt. Die folgende Tabelle liefert einen groben Ausschnitt der Werte. Details lesen Sie bitte im Papier RFC 2068 nach.

StatuscodeBedeutung
1xx Information (Die Anforderung wurde empfangen, aber nicht vollständig verarbeitet).
2xx Erfolg (Die Anforderung wurde empfangen, verstanden und akzeptiert).
3xx Umleitung (Der Client muß weitere Aktionen ausführen, damit die Anforderung fertiggestellt werden kann).
4xx Client-Fehler (Die Anforderung wurde nicht verstanden und kann deshalb nicht bearbeitet werden).
5xx Server-Fehler (Die Anforderung war gültig, konnte aber vom Server nicht verarbeitet werden).

Im eigentlichen Kern erzeugen Sie in der Funktion HttpExtensionProc die Rückantwort Ihrer Servererweiterung. Im einführenden Beispiel wird im Resultat ResStr zunächst eine HTML-Antwort mit dem aktuellen Datum und der Uhrzeit erzeugt. Vor Ausgabe an den Server verpacken Sie diese Antwort noch mit dem Ausgabe-Header. Das ist bei ISAPI im Gegensatz zu CGI dringend geboten, da der Web-Server die Antwort gleich an den Browser des Client durchreicht. Die verpackte Antwort leiten Sie mit WriteClient aus der DLL über den Server zum Client.

Der Antwort-Header besteht aus mehreren simplen Textzeilen. Zuerst geben Sie den verwendeten HTTP-Standard an. Diese Angabe ergänzen Sie wiederum mit dem Statuscode der Abfrage laut obiger Tabelle. In der zweiten Zeile geben Sie den Datentyp der Antwort an. Zeile 3 verrät dem Browser die Länge des folgenden Datenstromes. Die Angabe Content:  in der vierten Zeile ist nicht zwingend vorgeschrieben. Einige Server sind hier erfahrungsgemäß leider doch empfindlich. Es schadet also nichts. Das Ende des Headers bilden genau zwei Zeilenvorschübe.

Zum Abschluß dieser ersten ISAPI-Extension vergessen Sie bitte nicht, beide Funktionen zu exportieren:

Exports GetExtensionVersion, HttpExtensionProc;

Die fertige DLL legen Sie in ein Verzeichnis Ihres Webs, für das Sie Ausführungs-Rechte vereinbart haben. Bei jedem Aufruf, egal ob über die Methode GET oder POST wird nun die aktuelle Zeit mit ausgegeben. Somit erzeugen Sie eine dynamische HTML-Seite. Das Ergebnis sieht ungefähr so aus:

Screen Hallo

Download kompletter Programmquelltext:
Disk IsapiHlo.zip (1 kByte)
[ Seitenanfang ] [ ISAPI ]

J. Hummel,   2000