Autor Beitrag
fsg4u
Hält's aus hier
Beiträge: 12



BeitragVerfasst: Do 03.11.05 16:42 
Moin. Ich will mir einen einfachen HTTP Server bauen. Finde aber nicht heraus, wo ich beim ID HTTP Server einstelle in welchem Ordner die Daten gespeichert sind, auf die Zugegriffen werden... Habt ihr da nen Plan für mich? Danke FSG
Stefan.Buchholtz
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 612

WIN 2000, WIN XP, Mac OS X
D7 Enterprise, XCode, Eclipse, Ruby On Rails
BeitragVerfasst: Do 03.11.05 16:53 
Die idHttpServer-Komponente implementiert die Server-Seite des http-Protokolls, nichts weiter. Das ist kein vollständiger Web-Server. Den Rest musst schon schon selbst implementieren.

Stefan
fsg4u Threadstarter
Hält's aus hier
Beiträge: 12



BeitragVerfasst: Do 03.11.05 20:40 
achso. ich dachte, weil man auch den port einstellt, dass man dies so einfach tun könnte. Danke FSG
avenger
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 90



BeitragVerfasst: Mi 15.09.10 14:43 
Gibt es hierzu irgendwo ein tutorial ? Moechte eigentlich das gleiche wie fsg4u machen.
Muck
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 98
Erhaltene Danke: 8

Win 8, Win 7, Vista, Win XP
Delphi XE3, Delphi 2009, Delphi 2007, Delphi 5
BeitragVerfasst: Mi 15.09.10 16:05 
Hallo,

habe mal hier was zusammenkopiert. Ungetestet. Nur so als Geruest zur eigenen Verwendung. Natuerlich sollten Domain Names etc aus einer Einstellungsdatei kommen. Beispiel zeigt
- wie man mit einem Server verschiedene Domainnamen verwaltet (setze Verzeichnis, sende bestehende dateien mit ServeFile)
- wie man z.B. eine jpeg datei zurueckgibt die online berechnet wird (counter)
- wie man ein cookie schreibt
- wie man eingabeparameter ( sess ) einliest
- wie man einen XML String zurueckgibt, online berechnet

wie gesagt, ungetestet, einfach als Beispiel aus einem bestehenden Project rauskopiert.
Vielleicht hilft es ja als Start.

ausblenden volle Höhe Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92:
93:
uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, IdBaseComponent, IdComponent, IdCustomHTTPServer,
  IdHTTPServer, StdCtrls, IdContext,inifiles,jpeg, ComCtrls, AppEvnts, ExtCtrls,
  idcookie;

var
BS:Int64;

Procedure Log(W:String);
begin
//Write To LogFile;
end;

Function WriteCounter(W:String):String;
begin
//Move the content of a jpeg stream into the return string
end;

Function MakeTheXML(W:String):String;
begin
//Return XML Data
end;

Function DoTheHTML(W:String):String;
begin
//Return HTML content
end;


procedure TForm1.HTTPServerCommandGet(Context: TIdContext;  RequestInfo: TIdHTTPRequestInfo; ResponseInfo: TIdHTTPResponseInfo);
var LocalRoot,LocalDoc,Cook:String;ResultFile:TFileStream;WriteCookie:TIdCookieRFC2109;HostNo:Byte;I:Integer;TS:TStringList;
begin
LocalRoot:=Root;HostNo:=0;
if (Pos('henry.com',lowercase(RequestInfo.Host))>0then begin
  LocalRoot:='C:\henry web files';HostNo:=3;
end else if Pos('asianmart.com',lowercase(RequestInfo.Host))>0 then begin
  LocalRoot:='C:\JMart';HostNo:=1;
end else if (Pos('piano.com',lowercase(RequestInfo.Host))>0then begin
  LocalRoot:='C:\piano files';HostNo:=2;
end;
LocalDoc:=LowerCase(StringReplace(ExpandFileName(LocalRoot+RequestInfo.Document),'%20',' ',[rfReplaceAll]));
if not FileExists(LocalDoc) and DirectoryExists(LocalDoc) and FileExists(ExpandFileName(LocalDoc + '/index.htm')) then begin
  LocalDoc := ExpandFileName(LocalDoc + '/index.htm');
end;
Log(LocalDoc+' to '+Context.Connection.Socket.Binding.PeerIP);
ResponseInfo.ContentType:=HTTPServer.MimeTable.GetFileMIMEType(LocalDoc);
if Pos('counter.jpg',LocalDoc)>0 then begin
  ResponseInfo.ContentType:='image/JPEG';
  ResponseInfo.ContentText:=WriteCounter(localDoc); // return content of an jpeg file
end else begin
  // Default is index.htm
  if fileexists(LocalDoc) or (length(RequestInfo.Params.Values['sess'])>0then begin
    if AnsiSameText(RequestInfo.Command, 'HEAD'then begin
      Log('HEAD HEAD HEAD ------------------ '+LocalDoc);
      // HEAD request, don't send the document but still send back it's size
      ResultFile := TFileStream.create(LocalDoc, fmOpenRead or fmShareDenyWrite);
      try
        ResponseInfo.ResponseNo := 200;
        ResponseInfo.ContentLength := ResultFile.Size;
      finally
        ResultFile.Free;
      end;
    end else begin
      case HostNo of
      0:begin
      if (length(RequestInfo.Params.Values['sess'])>0then begin // session parameter found, create html on the fly
        ResponseInfo.ContentText:=DoTheHTML(RequestInfo,LocalDoc,Context.Connection.Socket.Binding.PeerIp);
        WriteCookie := responseinfo.Cookies.Add;
        WriteCookie.CookieName := 'rememberme';
        WriteCookie.Value := 'Its me';
        WriteCookie.Domain := 'henry.com';
        WriteCookie.Expires := 'Wed, 30-SEP-2020 01:00:01 GMT';
      end else begin
        if Pos('xml.htm',LowerCase(localDoc))>0 then begin
          ResponseInfo.ContentType:='text/xml';
          ResponseInfo.ContentText:=MakeTheXML(RequestInfo);
          Inc(BS,length(ResponseInfo.ContentText));
        end else Inc(BS,ResponseInfo.ServeFile(Context,LocalDoc));
      end;
      end;
      1,2:begin
        Inc(BS,ResponseInfo.ServeFile(Context,LocalDoc));
        end;
      end// end of case HostNo
    end;
  end else begin
    ResponseInfo.ContentType:='text/HTML';
    ResponseInfo.ResponseNo := 404// Not found
    ResponseInfo.ContentText := '<html><head><title>Error</title></head><body><h1>' + ResponseInfo.ResponseText + '</h1></body></html>';
  end;
end;
end;
avenger
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 90



BeitragVerfasst: Mi 15.09.10 19:25 
danke fuer die info aber ich komme damit ueberhaupt nicht klar. Wie schaff ich es das der server mit der einer index.html oder index.php antwortet ?

Muss ich dazu auch einen Filestream erzeugen ? Hast du veilleicht ein ganz einfaches Grundbeispiel ?
Muck
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 98
Erhaltene Danke: 8

Win 8, Win 7, Vista, Win XP
Delphi XE3, Delphi 2009, Delphi 2007, Delphi 5
BeitragVerfasst: Mi 15.09.10 19:41 
Hi,
das war eigentlich schon in dem letzten Code enthalten. Also hier nochmal verkuerzt.
Um ein file zurueckzugeben wird ServeFile in ResponseInfo benutzt.

Lege einen Ordner C:\WebFiles an und kopiere eine komplette Website in den Ordner.
Starte Testprogramm und dann Deinen browser und teste mit 127.0.0.1
Die Hauptdatei muss in diesem Beispiel index.htm heissen.

Markus

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
procedure TForm1.HTTPServerCommandGet(Context: TIdContext;  RequestInfo: TIdHTTPRequestInfo; ResponseInfo: TIdHTTPResponseInfo);
var LocalRoot,LocalDoc:String;ResultFile:TFileStream;
begin
LocalRoot:='C:\WebFiles';
LocalDoc:=LowerCase(StringReplace(ExpandFileName(LocalRoot+RequestInfo.Document),'%20',' ',[rfReplaceAll]));
if not FileExists(LocalDoc) and DirectoryExists(LocalDoc) and FileExists(ExpandFileName(LocalDoc + '/index.htm')) then begin
  LocalDoc := ExpandFileName(LocalDoc + '/index.htm');
end;
ResponseInfo.ContentType:=HTTPServer.MimeTable.GetFileMIMEType(LocalDoc);
// Default is index.htm
if fileexists(LocalDoc) then begin
  if AnsiSameText(RequestInfo.Command, 'HEAD'then begin
    Log('HEAD HEAD HEAD ------------------ '+LocalDoc);
    // HEAD request, don't send the document but still send back it's size
    ResultFile := TFileStream.create(LocalDoc, fmOpenRead or fmShareDenyWrite);
    try
      ResponseInfo.ResponseNo := 200;
      ResponseInfo.ContentLength := ResultFile.Size;
    finally
      ResultFile.Free;
    end;
  end else ResponseInfo.ServeFile(Context,LocalDoc); // <----- Datei zurueckgeben
end else begin
  ResponseInfo.ContentType:='text/HTML';
  ResponseInfo.ResponseNo := 404// Not found
  ResponseInfo.ContentText := '<html><head><title>Error</title></head><body><h1>' + ResponseInfo.ResponseText + '</h1></body></html>';
end;
end;
avenger
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 90



BeitragVerfasst: Mi 15.09.10 19:50 
AResponseInfo.ContentType:=tIdHTTPServer.MimeTable.GetFileMIMEType(LocalDoc);

bekomme in der Zeile die Fehlermeldung das mimetable inaccessible here ist ! Was bedeutet MimeTable ?
Muck
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 98
Erhaltene Danke: 8

Win 8, Win 7, Vista, Win XP
Delphi XE3, Delphi 2009, Delphi 2007, Delphi 5
BeitragVerfasst: Mi 15.09.10 20:14 
Nun, damit wird der ContentType fuer die Responseinfo gesetzt.
Falls Du den ContentType nicht setzt werden mp3 Dateien aufeinmal im Browser angezeigt.
Meine Procedur laueft auf Delphi 2007.
Du kannst die Zeile auch weglassen und konstant mit 'text/html' setzen, falls Du eh nur htm Dateien zurueckgibts.
Ansonsten, in aelteren Indy Versionen sollte es so gehen.

Ersetze die fehlerhafte Zeile in CommandGet mit:
ausblenden Delphi-Quelltext
1:
ResponseInfo.ContentType:= GetMIMEType(LocalDoc);					


Ausserdem addiere zum Testprogramm:

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
var
MIME1: TIdMIMETable;

procedure TForm1.FormCreate(Sender: TObject);
begin
MIME1:= TIdMIMETable.Create(true);
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
MIME1.Free;
end;

function GetMIMEType(sFile: TFileName): string;
begin
result:= MIME1.GetFileMIMEType(sFile);
end;
avenger
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 90



BeitragVerfasst: Mi 15.09.10 20:29 
Hallo,

var
MIME1: TIdMIMETable;

die variable laesst sich so nicht deklarieren. Muss da noch etwa in die USES ?


Ich nutze D2010 aber eigentlich sollte das mit den Indys doch auch funkionieren. Habe leider mit dem tidhttpserver noch nie zu tun gehabt. hab schon oefers mit den Smtp und dem TCP Server gearbeitet und das leiss sich relativ leicht nach D2010 portieren ?
Muck
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 98
Erhaltene Danke: 8

Win 8, Win 7, Vista, Win XP
Delphi XE3, Delphi 2009, Delphi 2007, Delphi 5
BeitragVerfasst: Mi 15.09.10 20:53 
Hallo,

Du hast Delphi 2010, nun hier ist MimeTable bereits in IdHTTPServer enthalten.
Addieren im ersten Beispiel IDGlobalProtocols zum uses, das ist neu in Delphi2010.
Dann sollte
ausblenden Delphi-Quelltext
1:
ResponseInfo.ContentType:=IdHTTPServer1.MimeTable.GetFileMIMEType(LocalDoc);					

funktionieren.
Brauchst also nicht selbst im Form Create anzulegen.

Markus
avenger
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 90



BeitragVerfasst: Mi 15.09.10 21:24 
Hallo,

Ich habs jetzt zumindest mal so das es kompiliert. Beim aufrufen im Browser wird oeffnet sichjedoch der download dialog und man kann die index.htm laden und dann zeigt ers ie erst im Browser an. Also es wird nicht direkt im Browser angezeigt !
Danke fuer deine Hilfe !!



ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
procedure TForm2.IdHTTPServer1CommandGet(AContext: TIdContext;
  ARequestInfo: TIdHTTPRequestInfo; AResponseInfo: TIdHTTPResponseInfo);
var LocalRoot,LocalDoc:String;ResultFile:TFileStream;
begin
LocalRoot:='C:\WebFiles';
LocalDoc:=LowerCase(StringReplace(ExpandFileName(LocalRoot+ARequestInfo.Document),'%20',' ',[rfReplaceAll]));
if not FileExists(LocalDoc) and DirectoryExists(LocalDoc) and FileExists(ExpandFileName(LocalDoc + '/index.htm')) then begin
  LocalDoc := ExpandFileName(LocalDoc + '/index.htm');
end;
AResponseInfo.ContentType:=IdHTTPServer1.MimeTable.GetFileMIMEType(LocalDoc);
// Default is index.htm
if fileexists(LocalDoc) then begin
  if AnsiSameText(ARequestInfo.Command, 'HEAD'then begin
    //Log('HEAD HEAD HEAD ------------------ '+LocalDoc);
    // HEAD request, don't send the document but still send back it's size
    ResultFile := TFileStream.create(LocalDoc, fmOpenRead or fmShareDenyWrite);
    try
      AResponseInfo.ResponseNo := 200;
      AResponseInfo.ContentLength := ResultFile.Size;
    finally
      ResultFile.Free;
    end;
  end else AResponseInfo.ServeFile(aContext,LocalDoc); // <----- Datei zurueckgeben
end else begin
  AResponseInfo.ContentType:='text/HTML';
  AResponseInfo.ResponseNo := 404// Not found
  AResponseInfo.ContentText := '<html><head><title>Error</title></head><body><h1>' + AResponseInfo.ResponseText + '</h1></body></html>';
end;
end;
Muck
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 98
Erhaltene Danke: 8

Win 8, Win 7, Vista, Win XP
Delphi XE3, Delphi 2009, Delphi 2007, Delphi 5
BeitragVerfasst: Mi 15.09.10 21:39 
Hallo,

nun da hat sich was in Delphi2010 geaendert. Der Code laeuft problemlos in Delphi 2007 und Delphi 2009. Compiliere ich mit 2010 wird zunaechst gefragt ob ich 127_0_0_1.txt downloaden will.

Leider gibt es noch keine Indy 10 Demos. Veilleicht findet sich was in der Hilfe. Es hat mit dem MimeTable zu tun, index.htm sollte nicht als txt Datei zum download angeboten werden.

Markus

---Moderiert von user profile iconNarses: Beiträge zusammengefasst---

Hi,

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
    ResultFile:=TFileStream.create(LocalDoc, fmOpenRead or fmShareDenyWrite);
    ResponseInfo.ResponseNo := 200;
    ResponseInfo.ContentLength := ResultFile.Size;
    ResponseInfo.ContentStream:=ResultFile;
//    ResponseInfo.ServeFile(AContext,LocalDoc); // <----- Datei zurueckgeben


Stream statt ServeFile funktioniert unter Delphi 2010.

Markus
avenger
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 90



BeitragVerfasst: Mi 15.09.10 22:06 
Soo ?? Also bei mir kommt immer noch der download Dialog.

ausblenden volle Höhe Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
procedure TForm2.IdHTTPServer1CommandGet(AContext: TIdContext;
  ARequestInfo: TIdHTTPRequestInfo; AResponseInfo: TIdHTTPResponseInfo);
var LocalRoot,LocalDoc:String;ResultFile:TFileStream;
begin
LocalRoot:='C:\WebFiles';
LocalDoc:=LowerCase(StringReplace(ExpandFileName(LocalRoot+ARequestInfo.Document),'%20',' ',[rfReplaceAll]));
if not FileExists(LocalDoc) and DirectoryExists(LocalDoc) and FileExists(ExpandFileName(LocalDoc + '/index.htm')) then begin
  LocalDoc := ExpandFileName(LocalDoc + '/index.htm');
end;
AResponseInfo.ContentType:=IdHTTPServer1.MimeTable.GetFileMIMEType(LocalDoc);
// Default is index.htm
if fileexists(LocalDoc) then begin
  if AnsiSameText(ARequestInfo.Command, 'HEAD'then begin
    //Log('HEAD HEAD HEAD ------------------ '+LocalDoc);
    // HEAD request, don't send the document but still send back it's size
    ResultFile := TFileStream.create(LocalDoc, fmOpenRead or fmShareDenyWrite);
    try
      AResponseInfo.ResponseNo := 200;
      AResponseInfo.ContentLength := ResultFile.Size;
    finally
      ResultFile.Free;
    end;
  end else AResponseInfo.ContentStream:=ResultFile;///AResponseInfo.ServeFile(aContext,LocalDoc); // <----- Datei zurueckgeben

end else begin
  AResponseInfo.ContentType:='text/HTML';
  AResponseInfo.ResponseNo := 404// Not found
  AResponseInfo.ContentText := '<html><head><title>Error</title></head><body><h1>' + AResponseInfo.ResponseText + '</h1></body></html>';

end;
end;
Muck
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 98
Erhaltene Danke: 8

Win 8, Win 7, Vista, Win XP
Delphi XE3, Delphi 2009, Delphi 2007, Delphi 5
BeitragVerfasst: Mi 15.09.10 22:15 
Hallo,

nun, am besten mal den Internet cache leeren. Der browser liest immer noch 127_0_0_1.txt vom cache.
Zu Deinem Code:
Den Stream auch oeffnen.
Wie im letzten Post die kompletten 4 Zeilen in den else Zweig statt der ServeFile Zeile.

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
if AnsiSameText(ARequestInfo.Command, 'HEAD'then begin
.
.
.
.
.
.
end else begin
  ResultFile:=TFileStream.create(LocalDoc, fmOpenRead or fmShareDenyWrite);
  ResponseInfo.ResponseNo := 200;
  ResponseInfo.ContentLength := ResultFile.Size;
  ResponseInfo.ContentStream:=ResultFile;
end;


Markus