AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Netzwerke Webserveranwendung: EXE ruft ISAPI

Webserveranwendung: EXE ruft ISAPI

Ein Thema von Delbor · begonnen am 22. Aug 2014 · letzter Beitrag vom 25. Aug 2014
Antwort Antwort
Seite 1 von 3  1 23   
Delbor

Registriert seit: 8. Okt 2006
Ort: St.Gallen/Schweiz
1.186 Beiträge
 
Delphi 11 Alexandria
 
#1

Webserveranwendung: EXE ruft ISAPI

  Alt 22. Aug 2014, 11:34
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
Roger
Man muss und kann nicht alles wissen - man muss nur wissen, wo es steht.
Frei nach Albert Einstein
http://roase.ch
  Mit Zitat antworten Zitat
mjustin

Registriert seit: 14. Apr 2008
3.006 Beiträge
 
Delphi 2009 Professional
 
#2

AW: Webserveranwendung: EXE ruft ISAPI

  Alt 22. Aug 2014, 12:08
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"
Michael Justin
habarisoft.com
  Mit Zitat antworten Zitat
Delbor

Registriert seit: 8. Okt 2006
Ort: St.Gallen/Schweiz
1.186 Beiträge
 
Delphi 11 Alexandria
 
#3

AW: Webserveranwendung: EXE ruft ISAPI

  Alt 22. Aug 2014, 12:28
Hi zusammmen

Die Grundfrage (wieso die verd.. AV's??) 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
Roger
Man muss und kann nicht alles wissen - man muss nur wissen, wo es steht.
Frei nach Albert Einstein
http://roase.ch
  Mit Zitat antworten Zitat
Delbor

Registriert seit: 8. Okt 2006
Ort: St.Gallen/Schweiz
1.186 Beiträge
 
Delphi 11 Alexandria
 
#4

AW: Webserveranwendung: EXE ruft ISAPI

  Alt 22. Aug 2014, 12:46
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
Roger
Man muss und kann nicht alles wissen - man muss nur wissen, wo es steht.
Frei nach Albert Einstein
http://roase.ch
  Mit Zitat antworten Zitat
mjustin

Registriert seit: 14. Apr 2008
3.006 Beiträge
 
Delphi 2009 Professional
 
#5

AW: Webserveranwendung: EXE ruft ISAPI

  Alt 22. Aug 2014, 13:15
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.
Michael Justin
  Mit Zitat antworten Zitat
Delbor

Registriert seit: 8. Okt 2006
Ort: St.Gallen/Schweiz
1.186 Beiträge
 
Delphi 11 Alexandria
 
#6

AW: Webserveranwendung: EXE ruft ISAPI

  Alt 22. Aug 2014, 13:39
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
Roger
Man muss und kann nicht alles wissen - man muss nur wissen, wo es steht.
Frei nach Albert Einstein
http://roase.ch
  Mit Zitat antworten Zitat
Delbor

Registriert seit: 8. Okt 2006
Ort: St.Gallen/Schweiz
1.186 Beiträge
 
Delphi 11 Alexandria
 
#7

AW: Webserveranwendung: EXE ruft ISAPI

  Alt 22. Aug 2014, 19:27
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
Roger
Man muss und kann nicht alles wissen - man muss nur wissen, wo es steht.
Frei nach Albert Einstein
http://roase.ch
  Mit Zitat antworten Zitat
Benutzerbild von Olli73
Olli73

Registriert seit: 25. Apr 2008
Ort: Neunkirchen
740 Beiträge
 
#8

AW: Webserveranwendung: EXE ruft ISAPI

  Alt 23. Aug 2014, 13:44
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?!
  Mit Zitat antworten Zitat
Delbor

Registriert seit: 8. Okt 2006
Ort: St.Gallen/Schweiz
1.186 Beiträge
 
Delphi 11 Alexandria
 
#9

AW: Webserveranwendung: EXE ruft ISAPI

  Alt 23. Aug 2014, 19:27
Hi Olly73


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.

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
Roger
Man muss und kann nicht alles wissen - man muss nur wissen, wo es steht.
Frei nach Albert Einstein
http://roase.ch
  Mit Zitat antworten Zitat
Benutzerbild von Olli73
Olli73

Registriert seit: 25. Apr 2008
Ort: Neunkirchen
740 Beiträge
 
#10

AW: Webserveranwendung: EXE ruft ISAPI

  Alt 23. Aug 2014, 20:35
Das hier hätte ich beinahe überlesen:
Zitat:
...alles in eine ISAPI packst?!
Und dabei war das (zumindest für mich) das Wichtigste.

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)!

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
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 3  1 23   

Themen-Optionen Thema durchsuchen
Thema durchsuchen:

Erweiterte Suche
Ansicht

Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 11:38 Uhr.
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