Autor |
Beitrag |
fsg4u
Hält's aus hier
Beiträge: 12
|
Verfasst: 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
      
Beiträge: 612
WIN 2000, WIN XP, Mac OS X
D7 Enterprise, XCode, Eclipse, Ruby On Rails
|
Verfasst: 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 
Hält's aus hier
Beiträge: 12
|
Verfasst: 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
      
Beiträge: 90
|
Verfasst: Mi 15.09.10 14:43
Gibt es hierzu irgendwo ein tutorial ? Moechte eigentlich das gleiche wie fsg4u machen.
|
|
Muck
      
Beiträge: 98
Erhaltene Danke: 8
Win 8, Win 7, Vista, Win XP
Delphi XE3, Delphi 2009, Delphi 2007, Delphi 5
|
Verfasst: 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.
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 end;
Function WriteCounter(W:String):String; begin end;
Function MakeTheXML(W:String):String; begin end;
Function DoTheHTML(W:String):String; begin 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))>0) then 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))>0) then 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); end else begin if fileexists(LocalDoc) or (length(RequestInfo.Params.Values['sess'])>0) then begin if AnsiSameText(RequestInfo.Command, 'HEAD') then begin Log('HEAD HEAD HEAD ------------------ '+LocalDoc); 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'])>0) then begin 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; end else begin ResponseInfo.ContentType:='text/HTML'; ResponseInfo.ResponseNo := 404; ResponseInfo.ContentText := '<html><head><title>Error</title></head><body><h1>' + ResponseInfo.ResponseText + '</h1></body></html>'; end; end; end; |
|
|
avenger
      
Beiträge: 90
|
Verfasst: 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
      
Beiträge: 98
Erhaltene Danke: 8
Win 8, Win 7, Vista, Win XP
Delphi XE3, Delphi 2009, Delphi 2007, Delphi 5
|
Verfasst: 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
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); if fileexists(LocalDoc) then begin if AnsiSameText(RequestInfo.Command, 'HEAD') then begin Log('HEAD HEAD HEAD ------------------ '+LocalDoc); 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); end else begin ResponseInfo.ContentType:='text/HTML'; ResponseInfo.ResponseNo := 404; ResponseInfo.ContentText := '<html><head><title>Error</title></head><body><h1>' + ResponseInfo.ResponseText + '</h1></body></html>'; end; end; |
|
|
avenger
      
Beiträge: 90
|
Verfasst: 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
      
Beiträge: 98
Erhaltene Danke: 8
Win 8, Win 7, Vista, Win XP
Delphi XE3, Delphi 2009, Delphi 2007, Delphi 5
|
Verfasst: 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:
Delphi-Quelltext 1:
| ResponseInfo.ContentType:= GetMIMEType(LocalDoc); |
Ausserdem addiere zum Testprogramm:
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
      
Beiträge: 90
|
Verfasst: 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
      
Beiträge: 98
Erhaltene Danke: 8
Win 8, Win 7, Vista, Win XP
Delphi XE3, Delphi 2009, Delphi 2007, Delphi 5
|
Verfasst: 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
Delphi-Quelltext 1:
| ResponseInfo.ContentType:=IdHTTPServer1.MimeTable.GetFileMIMEType(LocalDoc); |
funktionieren.
Brauchst also nicht selbst im Form Create anzulegen.
Markus
|
|
avenger
      
Beiträge: 90
|
Verfasst: 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 !!
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); if fileexists(LocalDoc) then begin if AnsiSameText(ARequestInfo.Command, 'HEAD') then begin 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); end else begin AResponseInfo.ContentType:='text/HTML'; AResponseInfo.ResponseNo := 404; AResponseInfo.ContentText := '<html><head><title>Error</title></head><body><h1>' + AResponseInfo.ResponseText + '</h1></body></html>'; end; end; |
|
|
Muck
      
Beiträge: 98
Erhaltene Danke: 8
Win 8, Win 7, Vista, Win XP
Delphi XE3, Delphi 2009, Delphi 2007, Delphi 5
|
Verfasst: 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 Narses: Beiträge zusammengefasst---
Hi,
Delphi-Quelltext 1: 2: 3: 4: 5:
| ResultFile:=TFileStream.create(LocalDoc, fmOpenRead or fmShareDenyWrite); ResponseInfo.ResponseNo := 200; ResponseInfo.ContentLength := ResultFile.Size; ResponseInfo.ContentStream:=ResultFile; |
Stream statt ServeFile funktioniert unter Delphi 2010.
Markus
|
|
avenger
      
Beiträge: 90
|
Verfasst: Mi 15.09.10 22:06
Soo ?? Also bei mir kommt immer noch der download Dialog.
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); if fileexists(LocalDoc) then begin if AnsiSameText(ARequestInfo.Command, 'HEAD') then begin ResultFile := TFileStream.create(LocalDoc, fmOpenRead or fmShareDenyWrite); try AResponseInfo.ResponseNo := 200; AResponseInfo.ContentLength := ResultFile.Size; finally ResultFile.Free; end; end else AResponseInfo.ContentStream:=ResultFile; end else begin AResponseInfo.ContentType:='text/HTML'; AResponseInfo.ResponseNo := 404; AResponseInfo.ContentText := '<html><head><title>Error</title></head><body><h1>' + AResponseInfo.ResponseText + '</h1></body></html>';
end; end; |
|
|
Muck
      
Beiträge: 98
Erhaltene Danke: 8
Win 8, Win 7, Vista, Win XP
Delphi XE3, Delphi 2009, Delphi 2007, Delphi 5
|
Verfasst: 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.
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
|
|
|