Delphi-PRAXiS
Seite 1 von 3  1 23      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Netzwerke (https://www.delphipraxis.net/14-netzwerke/)
-   -   Webserveranwendung: EXE ruft ISAPI (https://www.delphipraxis.net/181528-webserveranwendung-exe-ruft-isapi.html)

Delbor 22. Aug 2014 10:34

Webserveranwendung: EXE ruft ISAPI
 
Hi zusammen

Der Titel ist vielleicht etwas...äääh...gewöhnungsbedürftig, aber mir ist nichts besseres eingefallen.
Der Hintergrund:
In einer Projektgroup befinden sich 2 Projekte: Eine mit Webbroker erstellte ISAPI-DLL und eine EXE.
Aufgabe der EXE ist es, die Anfrage entgegenzunehmen und einer existierenden Session zuzuweisen, bzw. eine solche im Falle einner Erstanfrage neu zu erstellen. Anschliessend soll die Anfrage an die DLL, bzw. deren Webmodul weitergeleitet werden.

Anfänglich hab ich das mit IdHttpServer versucht. Das klappt insofern ganz 'gut', als dass ein in der IdHTTPServer1CommandGet-Methode gesetzter Haltepunkt angesprungen wird, wenn im Browser die URL eingegeben wird. Aber jetzt mal erst der Code:

Delphi-Quellcode:
{$R *.dfm}

procedure TDelborMainServer.FormCreate(Sender: TObject);
  var AClass: TComponentClass;
begin
//  FHTMLDir := ExtractFilePath(Application.ExeName) + 'HTML';
  FIdHTTPWebBrokerBridge := TIdHTTPWebBrokerBridge.Create;
  FIdHTTPWebBrokerBridge.AutoStartSession := True;
  FIdHTTPWebBrokerBridge.ServerSoftware := 'DelborMainServer';
  FIdHTTPWebBrokerBridge.OnConnect := OnIdHTTPWebBrokerBridgeConnect;
  FIdHTTPWebBrokerBridge.OnCommandOther := OnIdHTTPWebBrokerBridgeComandother;
  FIdHTTPWebBrokerBridge.DefaultPort := 8000;
  FIdHTTPWebBrokerBridge.Active := True;

end;

procedure TDelborMainServer.IdHTTPServer1CommandGet(AContext: TIdContext;
  ARequestInfo: TIdHTTPRequestInfo; AResponseInfo: TIdHTTPResponseInfo);
  var LFileName, LPathname: String; OK: Boolean; ECB: TEXTENSION_CONTROL_BLOCK;
begin
  OK := DelborFotoGalery(AContext,ARequestInfo, AResponseInfo);
end;

procedure TDelborMainServer.OnIdHTTPWebBrokerBridgeComandother(AThread: TIdContext;  //<===
   ARequestInfo: TIdHTTPRequestInfo; AResponseInfo: TIdHTTPResponseInfo);
begin
  beep;
end;

procedure TDelborMainServer.OnIdHTTPWebBrokerBridgeConnect(AContext: TIdContext);    //<===
begin
  beep;
end;

function DelborFotoGalery(AContext: TIdContext;
  ARequestInfo: TIdHTTPRequestInfo; AResponseInfo: TIdHTTPResponseInfo):Boolean;
  var Handle: THandle; DelborFotoGalery: TDelborFotoGalery;
begin
  Handle:=LoadLibrary(PChar(ExtractFilePath(ParamStr(0))+'DelborProject1.dll'));
  if Handle <> 0 then begin
    @DelborFotoGalery := GetProcAddress(Handle, 'HttpExtensionProc');                     // ): DWORD
    if @DelborFotoGalery <> nil then begin
      result := DelborFotoGalery(AContext,ARequestInfo, AResponseInfo);

    end;
  end;
end;
Nachdem die ersten Versuche sich nur auf die Verwendung des IdHTTPServers beschränkten, diese aber immer AVs lieferten(fehlende Servervariablen) habe ich TIdWebbrokerBridge eingebaut - eigentlich schon vom Klassennamen her einleuchtend.
Der Stand der Dinge ist allerdings: auch hier gibts eine AV. Von zwei gesetzten Haltepunkten (durch Pfeile markiert)wird vor Auslösen der AV gerademal der untere (OnIdHTTPWebBrokerBridgeConnect) ausgelöst.

Was mache ich falsch? Alles, was für mich schon fast sicher ist: Ich brauche die DLL gar nicht so aufzurufen, wie ich das in DelborFotoGalery tue...

Auch die DLL ist im Grunde noch nicht fertig entwickelt; das Webmodul dieser Webbroker-Anwendung wird noch durch ein normales Datenmodul mit Webdispatcher ersetzt. Mein Konzept sieht vor, dass die gesamte Anwendung letzten Endes auf einer(?) Datenbank basiert.


Und zum Schluss vielleicht noch die Info, die wohl an den Anfang gehört hätte: die Anwendung soll auf einem Windows-Server laufen. Vielen Dank für eure - hoffentlich zahlreichen - Antworten! Auch über Sinn und Unsinn einer EXE (die ja nicht zwingend eine CGI-Anwendung sein muss(??), lasse ich gerne mit mir reden.

Gruss
Delbor

mjustin 22. Aug 2014 11:08

AW: Webserveranwendung: EXE ruft ISAPI
 
Delphi-Quellcode:
    @DelborFotoGalery := GetProcAddress(Handle, 'HttpExtensionProc');                     // ): DWORD
    if @DelborFotoGalery <> nil then begin
      result := DelborFotoGalery(AContext,ARequestInfo, AResponseInfo);

    end;
Die Argumente der ISAPI HttpExtensionProc und die Indy Parameter (AContext,ARequestInfo, AResponseInfo) sind völlig inkompatibel. Das wird so nie funktionieren. Indy HTTP Request- und Responseobjekte lassen sich nicht einfach in eine ISAPI DLL "einpflanzen" ;)

Delbor 22. Aug 2014 11:28

AW: Webserveranwendung: EXE ruft ISAPI
 
Hi zusammmen

Die Grundfrage (wieso die verd.. AV's??:evil:) hat sich in Luft aufgelöst, die Seite wird mir im Browser angezeigt:
Delphi-Quellcode:
procedure TDelborMainServer.OnIdHTTPWebBrokerBridgeConnect(AContext: TIdContext);
begin
  FIdHTTPWebBrokerBridge.RegisterWebModuleClass(WebModuleClass);
end;
Laut Kommmentar existiert diese Prozedure nur noch wegen der Abwärtskompatibilität:
Zitat:

// FWebModuleClass, RegisterWebModuleClass supported for backward compatability
// Instead set WebModuleClass using: WebReq.WebRequestHandler.WebModuleClass := TWebModule1;
Ich hab allerdings keine Möglichkeit gefunden, den zuständigen WebRequestHandler anzusprechen. Zugegeben, ich hab auch nicht lange danach gesucht...

Zitat:

Vielen Dank für eure - hoffentlich zahlreichen - Antworten! Auch über Sinn und Unsinn einer EXE (die ja nicht zwingend eine CGI-Anwendung sein muss(??), lasse ich gerne mit mir reden.
Das gilt eigentlich immer noch. So, wie ich die verschiedenen Beispielprogramme verstanden habe, sollte eine Webbroker-Isapi-Anwendung als eigenständige DLL in den Internet InformationServices eingebunden werden können, was ich aber nie geschafft habe.
Das Einbinden als Iapi-Extension in den IIS alleine hätte allerdings nicht viel gebracht - es wären einfach nur die Anfrage bearbeitet worden.
Nach meinem bisherigen Verständnis können in den IIS allerdings auch Isapi-Filter eingebunden werden. Aber genau da hörte bisher mein Verständnis auf, da ich so zwar 2 Isapi-Dlls in den IIS eingebunden hätte - aber eben ohne, dass die eine von der anderen etwas weiss.
Die einzige 'Verbindung' wäre wohl eine gemeinsam genutzte DB gewesen.


Gruss
Delbor

Delbor 22. Aug 2014 11:46

AW: Webserveranwendung: EXE ruft ISAPI
 
Hi mjustin

Vielen Dank für deine Antwort!
Zitat:

Die Argumente der ISAPI HttpExtensionProc und die Indy Parameter (AContext,ARequestInfo, AResponseInfo) sind völlig inkompatibel. Das wird so nie funktionieren. Indy HTTP Request- und Responseobjekte lassen sich nicht einfach in eine ISAPI DLL "einpflanzen"
Das war auch der Grund, weshalb ich mich in den letzten Tagen dumm und dämlich gesucht habe. IdHTTPWebBrokerBridge.OnConnect hat ja nur einen Parameter(AContext). Wie sollte ich da die erwarteten Werte an die DLL weitergeben?

Ich gehe mal davon aus, dass eine Isapi-Dll, in den IIS eingebunden, von diesen die Werte für den ECB erhält. Aber schon das alein wirft chon wieder eine Menge Fragen auf....

Gruss
Delbor

mjustin 22. Aug 2014 12:15

AW: Webserveranwendung: EXE ruft ISAPI
 
Zitat:

Zitat von Delbor (Beitrag 1269552)
Ich gehe mal davon aus, dass eine Isapi-Dll, in den IIS eingebunden, von diesen die Werte für den ECB erhält. Aber schon das alein wirft chon wieder eine Menge Fragen auf....

Soll das Ergebnis ein einfacher HTTP Proxy werden, der in einer Delphi EXE mit Indy läuft und die Anfragen an den IIS durchleitet?

Indy enthält dann mit der Klasse TIdHTTPProxyServer vermutlich schon (fast) alles, was dafür benötigt wird.

Delbor 22. Aug 2014 12:39

AW: Webserveranwendung: EXE ruft ISAPI
 
H mjustin

Nein, das solll kein Proxi-Server werdsen, zumindest, soweit ich diesen Artikel verstanden habe. Das Ding soll von einem Hostserver schlicht meine Webseiten ausgeben. Dazu sollen jeweils Sessions benutzt werden. Abgeschlossene Sessions sollen in einer DB gespeichert werden. In einem weiteren Ausbau soll auch eine Cookieverwaltung dazukommen.

Die IIS habe ich auf meinem Kistchen nur, weil die Anwendung später auf dem Hostserver unter den IIS laufen soll. Die reine, mit dem Delphi-Experten erstellte Webbroker-Isapi (ohne Exe), habe ich auf meinem Computer unter den IIS nie zum laufen gebracht. Da nach meinen Infos unter den IIS aber auch Executables laufen, hab ich diese Variante gewählt wobei mir dies aber auch im Hinblick auf eine Session- und Cookieverwaltung wichtig schien.

Gruss
Delbor

Delbor 22. Aug 2014 18:27

AW: Webserveranwendung: EXE ruft ISAPI
 
Hi zusammen

Gerade eben hab ich mir selbst ein Bein gestellt - ich hab das getan, was Embarcadero hier empfiehlt und das Webmodul durch ein normales Datenmodul ausgetauscht. Seither geht gar nichts mehr...

In der Projekt-Unit habe ich folgendes geändert:
Delphi-Quellcode:
  if WebRequestHandler <> nil then
    WebRequestHandler.WebModuleClass := Webmodul1;
in
Delphi-Quellcode:
  if WebRequestHandler <> nil then
    WebRequestHandler.WebModuleClass := TDelborWebDataModul;
Dadurch startet zwar das Projekt. Aber wenn ich im Browser die URL eingebe, wird eine AV geworfen, wenn der WebRequestHandler das Webmodul aktivieren will, aber keins findet.
So, wie's aussieht, ist die Empfehlung Embarcaderos nur dann gültig, wenn die mit Webbroker erstellt ISAPI-Dll als separate Anwendung im IIS eingebunden wird.
Ich kann jetzt nur hoffen, dass das Webmodul DBExpress-Komponenten akzeptiert...

Oder weiss jemand, wie man ein Datenmodul endgültig zum Webmodul macht?

Gruss
Delbor

Olli73 23. Aug 2014 12:44

AW: Webserveranwendung: EXE ruft ISAPI
 
Zitat:

Zitat von Delbor (Beitrag 1269548)
Aber genau da hörte bisher mein Verständnis auf, da ich so zwar 2 Isapi-Dlls in den IIS eingebunden hätte - aber eben ohne, dass die eine von der anderen etwas weiss.
Die einzige 'Verbindung' wäre wohl eine gemeinsam genutzte DB gewesen.

Ja, in diesem Fall ist die "Verbindung" die Datenbank oder man nutzt HTTP-Requests untereinander.

ABER: Ich habe immer noch nicht verstanden, warum du 2 getrennte ISAPIs/EXEs benötigst und nicht gleich alles in eine ISAPI packst?!

Delbor 23. Aug 2014 18:27

AW: Webserveranwendung: EXE ruft ISAPI
 
Hi Olly73


Zitat:

Zitat von Olli73 (Beitrag 1269647)
Zitat:

Zitat von Delbor (Beitrag 1269548)
Aber genau da hörte bisher mein Verständnis auf, da ich so zwar 2 Isapi-Dlls in den IIS eingebunden hätte - aber eben ohne, dass die eine von der anderen etwas weiss.
Die einzige 'Verbindung' wäre wohl eine gemeinsam genutzte DB gewesen.

Ja, in diesem Fall ist die "Verbindung" die Datenbank oder man nutzt HTTP-Requests untereinander.

Ja, sowas habe ich mir auch gedacht, konnte mir die Sache aber nicht so richtig vorstellen. Vielleicht löst sich der Nebel aber langsam. Zum einen laufen Filter-Dlls ja nicht nur pro Anfrage, sondern permanent (so lange die IIS laufen), zum andern habe ich hier ein Beispiel, wie eine Isapi-Extension eine andere aufruft.
Diese beiden Beispiele hätte ich mir gerne per schrittweisem durchsteppen etwas näher angeschaut, doch wie geschrieben, konnte ich die IIS nie dazu übereden, mir die Seiten aus meinem eigenen Webbroker-Projekt auch anzuzeigen.
Zusammen mit der EXE klappt das aber, und gesetzte Haltepunkte werden auch angesprungen.

Zitat:

Zitat von Olli73 (Beitrag 1269647)
ABER: Ich habe immer noch nicht verstanden, warum du 2 getrennte ISAPIs/EXEs benötigst und nicht gleich alles in eine ISAPI packst?!

Na ja. Auslöser war das Eliza-Beispiel der Indys mit dem HTTP-Server, das mir auch angezeigt wurde, nachdem ich die IIS zwischenzeitlich rausgeworfen habe - wobei ich jetzt ja anstelle des IdHTTPServers die Webbrokerbridge verwende. Wie oben schon gesagt: mit der Exe bin ich unabhängig von den IIS.
Ein weiterer Grund war aber eben auch: Mit einer Filter-Isapi und einer Isapi-Extension hätte ich offensichtlich/scheinbar zwei unabhängige Projekte gehabt und habe mir zumindest vorerst absolut nicht vorstellen können, wie die beiden zusammenarbeiten,
Dazu kommt - eine EXE gibt mir die Möglichkeit, Programmlogik an einem Ort zu verarbeiten (Sessions, Cookies), wie ich das sonst auch mache.

Etwas anderes sollte vielleicht auch nicht ausser acht gelassen werden: Microsoft selbst beschreibt die ISAPI-Filter als veraltet; man solle an ihrer Stelle doch eher Module definieren. Und wenn ich richtig gelesen habe, können die auch executables sein.

Zitat:

...warum du 2 getrennte ISAPIs/EXEs benötigst
Es sind ja nicht zwei gtrennte(also je eine exe und eine Isapi) sondern je eine. Aber was du ansprichst, ist wohl eher die Projektgruppe mit den 2 separaten Projekten. Nun ja, die DL ist für sich ein eigenes Projekt, deshalb meine Überlegung mit der Projektgruppe.
Nachdem ich mir wie oben beschreiben, das ganze durch einfügen des Datemoduls zerschossen habe und eine neue DLL auch nicht viel änderte, werde ich wohl das ganze neu aufsetzen...


Das hier hätte ich beinahe überlesen:
Zitat:

...alles in eine ISAPI packst?!
Eine Webbrokeranwendung (Isapi) wird genau für jeweils einen Request ausgeführt, beantwortet diesen und wird dann beendet. Man kann das Webmodul zwar auch deaktivieren - es ist dann einfach 'geparkt' und kann bei Bedarf wieder aktiviert werden. Aber sie eignet sich nicht für ein Session-oder Cookie-Managment.
Und eine Session in die DB zu schreiben, solange sie nicht beendet wird, denke ich, sollte im Interesse der Performance wohl besser unterbleiben. Ich denke, das ergibt viel zu viele Datenbankzugriffe, vor allem, wenn ich auch anonyme Zugriffe über Sessions ablaufen.

Gruss
Delbor

Olli73 23. Aug 2014 19:35

AW: Webserveranwendung: EXE ruft ISAPI
 
Zitat:

Zitat von Delbor (Beitrag 1269662)
Das hier hätte ich beinahe überlesen:
Zitat:

...alles in eine ISAPI packst?!

Und dabei war das (zumindest für mich) das Wichtigste. ;)

Zitat:

Zitat von Delbor (Beitrag 1269662)
Eine Webbrokeranwendung (Isapi) wird genau für jeweils einen Request ausgeführt, beantwortet diesen und wird dann beendet. Man kann das Webmodul zwar auch deaktivieren - es ist dann einfach 'geparkt' und kann bei Bedarf wieder aktiviert werden. Aber sie eignet sich nicht für ein Session-oder Cookie-Managment.

Nö. Wenn die ISAPI einmal geladen ist, verbleibt sie normalerweise im Speicher; es sei denn du setzt absichtlich den Registryeintrag "CacheExtensions" auf 0:

http://msdn.microsoft.com/de-de/libr...(v=vs.71).aspx

Aber davon wird explizit abgeraten, außer zum Debuggen.

Mit UniGui (unigui.com) kann man auch eine ISAPI-DLL erstellen und die ist "statefull" (hält also Daten für jede aktive Session im Speicher)!

Zitat:

Zitat von Delbor (Beitrag 1269662)
Und eine Session in die DB zu schreiben, solange sie nicht beendet wird, denke ich, sollte im Interesse der Performance wohl besser unterbleiben. Ich denke, das ergibt viel zu viele Datenbankzugriffe, vor allem, wenn ich auch anonyme Zugriffe über Sessions ablaufen.

Du kannst die Daten auch im Speicher behalten, musst aber ein paar Dinge beachten:

Globale Variablen sind grundsätzlich Pfui, da multithreaded, und müssen durch critical sections abgesichert werden. Aber als globale Variable brauchst du eigentlich nur eine SessionList (Liste, Array, Hashmap, ...). Diese ist durch eine CriticalSection abzusichern.

In die einzelnen Sessions (Session-Objekte) kannst du dann deine Daten, (Daten-)Objekte, Datenmodule etc. packen. Dabei muss ein Objekt oder Datenmodul für jede Session neu erstellt werden und es dürfen auch dort keine globalen Variablen, sondern nur Felder/Properties verwendet werden.

Gruß
Olli


Alle Zeitangaben in WEZ +1. Es ist jetzt 01:55 Uhr.
Seite 1 von 3  1 23      

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz