| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271 |
- { $HDR$}
- {**********************************************************************}
- { Unit archived using Team Coherence }
- { Team Coherence is Copyright 2002 by Quality Software Components }
- { }
- { For further information / comments, visit our WEB site at }
- { http://www.TeamCoherence.com }
- {**********************************************************************}
- {}
- { $Log: 13890: IdHTTPProxyServer.pas
- {
- { Rev 1.4 10/14/2004 2:07:40 PM BGooijen
- { changed WriteHeader to WriteStrings
- }
- {
- { Rev 1.3 10/14/2004 1:44:04 PM BGooijen
- { reverted back to 1.1
- }
- {
- { Rev 1.1 10/14/2004 1:42:00 PM BGooijen
- { Ported back from I10
- }
- {
- { Rev 1.0 2002.11.22 8:37:16 PM czhower
- }
- unit IdHTTPProxyServer;
- interface
- {
- Indy HTTP proxy Server
- Original Programmer: Bas Gooijen ([email protected])
- Current Maintainer: Bas Gooijen
- Code is given to the Indy Pit Crew.
- Modifications by Chad Z. Hower (Kudzu)
- Quick Notes:
- Revision History:
- 10-May-2002: Created Unit.
- }
- uses
- Classes,
- IdAssignedNumbers,
- IdGlobal,
- IdTCPConnection,
- IdTCPServer,
- IdHeaderList;
- const
- IdPORT_HTTPProxy = 8080;
- type
- { not needed (yet)
- TIdHTTPProxyServerThread = class( TIdPeerThread )
- protected
- // what needs to be stored...
- fUser: string;
- fPassword: string;
- public
- constructor Create( ACreateSuspended: Boolean = True ) ; override;
- destructor Destroy; override;
- // Any functions for vars
- property Username: string read fUser write fUser;
- property Password: string read fPassword write fPassword;
- end;
- }
- TIdHTTPProxyServer = class;
- TOnHTTPDocument = procedure(ASender: TIdHTTPProxyServer; const ADocument: string;
- var VStream: TStream; const AHeaders: TIdHeaderList) of object;
- TIdHTTPProxyServer = class(TIdTcpServer)
- protected
- FOnHTTPDocument: TOnHTTPDocument;
- // CommandHandlers
- procedure CommandGET(ASender: TIdCommand);
- procedure CommandPOST(ASender: TIdCommand);
- procedure CommandHEAD(ASender: TIdCommand);
- procedure CommandConnect(ASender: TIdCommand); // for ssl
- procedure DoHTTPDocument(const ADocument: string; var VStream: TStream; const AHeaders: TIdHeaderList);
- procedure InitializeCommandHandlers; override;
- procedure TransferData(ASrc: TIdTCPConnection; ADest: TIdTCPConnection; const ADocument: string;
- const ASize: Integer; const AHeaders: TIdHeaderList);
- public
- constructor Create( AOwner: TComponent ) ; override;
- published
- property DefaultPort default IdPORT_HTTPProxy;
- property OnHTTPDocument: TOnHTTPDocument read FOnHTTPDocument write FOnHTTPDocument;
- end;
- // Procs
- procedure Register;
- implementation
- uses
- IdResourceStrings,
- IdRFCReply,
- IdTCPClient,
- IdURI,
- SysUtils;
- procedure Register;
- begin
- RegisterComponents('Indy 10', [TIdHTTPProxyServer]);
- end;
- procedure TIdHTTPProxyServer.InitializeCommandHandlers;
- begin
- inherited;
- with CommandHandlers.Add do begin
- Command := 'GET'; {do not localize}
- OnCommand := CommandGet;
- ParseParams := True;
- Disconnect := true;
- end;
- with CommandHandlers.Add do
- begin
- Command := 'POST'; {do not localize}
- OnCommand := CommandPOST;
- ParseParams := True;
- Disconnect := true;
- end;
- with CommandHandlers.Add do
- begin
- Command := 'HEAD'; {do not localize}
- OnCommand := CommandHEAD;
- ParseParams := True;
- Disconnect := true;
- end;
- with CommandHandlers.Add do
- begin
- Command := 'CONNECT'; {do not localize}
- OnCommand := Commandconnect;
- ParseParams := True;
- Disconnect := true;
- end;
- //HTTP Servers/Proxies do not send a greeting
- Greeting.Clear;
- end;
- procedure TIdHTTPProxyServer.TransferData(
- ASrc: TIdTCPConnection;
- ADest: TIdTCPConnection;
- const ADocument: string;
- const ASize: Integer;
- const AHeaders: TIdHeaderList
- );
- //TODO: This captures then sends. This is great and we need this as an option for proxies that
- // modify data. However we also need another option that writes as it captures.
- // Two modes? Intercept and not?
- var
- LStream: TStream;
- begin
- //TODO: Have an event to let the user perform stream creation
- LStream := TMemoryStream.Create; try
- ASrc.ReadStream(LStream, ASize, ASize = -1);
- LStream.Position := 0;
- DoHTTPDocument(ADocument, LStream, AHeaders);
- // Need to recreate IdStream, DoHTTPDocument passes it as a var and user can change the
- // stream that is returned
- ADest.WriteStream(LStream);
- finally FreeAndNil(LStream); end;
- end;
- procedure TIdHTTPProxyServer.CommandGET( ASender: TIdCommand ) ;
- var
- LClient: TIdTCPClient;
- LDocument: string;
- LHeaders: TIdHeaderList;
- LRemoteHeaders: TIdHeaderList;
- LURI: TIdURI;
- LPageSize: Integer;
- begin
- ASender.PerformReply := false;
- LHeaders := TIdHeaderList.Create; try
- ASender.Thread.Connection.Capture(LHeaders, '');
- LClient := TIdTCPClient.Create(nil); try
- LURI := TIdURI.Create(ASender.Params.Strings[0]); try
- LClient.Port := StrToIntDef(LURI.Port, 80);
- LClient.Host := LURI.Host;
- //We have to remove the host and port from the request
- LDocument := LURI.Path + LURI.Document + LURI.Params;
- finally FreeAndNil(LURI); end;
- LClient.Connect; try
- LClient.WriteLn('GET ' + LDocument + ' HTTP/1.0'); {Do not Localize}
- LClient.WriteStrings(LHeaders);
- LClient.WriteLn('');
- LRemoteHeaders := TIdHeaderList.Create; try
- LClient.Capture(LRemoteHeaders, '');
- ASender.Thread.Connection.WriteStrings(LRemoteHeaders);
- ASender.Thread.Connection.WriteLn('');
- LPageSize := StrToIntDef(LRemoteHeaders.Values['Content-Length'], -1) ; {Do not Localize}
- TransferData(LClient, ASender.Thread.Connection, LDocument, LPageSize, LRemoteHeaders);
- finally FreeAndNil(LRemoteHeaders); end;
- finally LClient.Disconnect; end;
- finally FreeAndNil(LClient); end;
- finally FreeAndNil(LHeaders); end;
- end;
- procedure TIdHTTPProxyServer.CommandPOST( ASender: TIdCommand ) ;
- var
- LClient: TIdTCPClient;
- LDocument: string;
- LHeaders: TIdHeaderList;
- LRemoteHeaders: TIdHeaderList;
- LURI: TIdURI;
- LPageSize: Integer;
- LPostStream: TMemoryStream;
- begin
- ASender.PerformReply := false;
- LHeaders := TIdHeaderList.Create; try
- ASender.Thread.Connection.Capture(LHeaders, '');
- LPostStream:=tmemorystream.Create;
- try
- LPostStream.size:=StrToIntDef( LHeaders.Values['Content-Length'], 0 ); {Do not Localize}
- ASender.Thread.Connection.ReadStream(LPostStream,LPostStream.Size,false);
- LClient := TIdTCPClient.Create(nil); try
- LURI := TIdURI.Create(ASender.Params.Strings[0]); try
- LClient.Port := StrToIntDef(LURI.Port, 80);
- LClient.Host := LURI.Host;
- //We have to remove the host and port from the request
- LDocument := LURI.Path + LURI.Document + LURI.Params;
- finally FreeAndNil(LURI); end;
- LClient.Connect; try
- LClient.WriteLn('POST ' + LDocument + ' HTTP/1.0'); {Do not Localize}
- LClient.WriteStrings(LHeaders);
- LClient.WriteLn('');
- LClient.WriteStream(LPostStream);
- LRemoteHeaders := TIdHeaderList.Create; try
- LClient.Capture(LRemoteHeaders, '');
- ASender.Thread.Connection.WriteStrings(LRemoteHeaders);
- ASender.Thread.Connection.Writeln('');
- LPageSize := StrToIntDef(LRemoteHeaders.Values['Content-Length'], -1) ; {Do not Localize}
- TransferData(LClient, ASender.Thread.Connection, LDocument, LPageSize, LRemoteHeaders);
- finally FreeAndNil(LRemoteHeaders); end;
- finally LClient.Disconnect; end;
- finally FreeAndNil(LClient); end;
- finally FreeAndNil(LPostStream); end;
- finally FreeAndNil(LHeaders); end;
- end;
- procedure TIdHTTPProxyServer.CommandConnect( ASender: TIdCommand ) ;
- begin
- end;
- procedure TIdHTTPProxyServer.CommandHEAD( ASender: TIdCommand ) ;
- begin
- end;
- constructor TIdHTTPProxyServer.Create( AOwner: TComponent ) ;
- begin
- inherited;
- DefaultPort := IdPORT_HTTPProxy;
- Greeting.Text.Text := ''; // RS
- ReplyUnknownCommand.Text.Text := ''; // RS
- end;
- procedure TIdHTTPProxyServer.DoHTTPDocument(const ADocument: string; var VStream: TStream; const AHeaders: TIdHeaderList);
- begin
- if Assigned(OnHTTPDocument) then begin
- OnHTTPDocument(Self, ADocument, VStream, AHeaders);
- end;
- end;
- end.
|