Добрый вечер. В общем интересует вопрос. Есть такая программа HandyCache. Пытаюсь написать ее аналог для себя. Т.к. многие настройки которые там есть мне не нужны. Программа работает как прокси. А именно анализирует трафик и записывает некоторые файлы к примеру jpg или swf на диск. В следующий раз когда пользователь опять заходит на этот же сайт и программа видит что используются эти же файлы она их берет из папки. Как такое реализовать? Анализатор траффика это по сути обычный http сниффер. Если есть примеры их чтобы анализатор не брал данные об ответе от сервера и т.д. а просто url тока. Но самый главный вопрос как организовать подмену файла из папки? Это меня интересует больше всего!
Я хз, мб туплю но это похоже на кеширование, самый очевидный вариант хукать recv посмотри сорцы зевса чемто напоминает его инжекты.
Ругается что нету IdCmdTCPServer.... И на панели Indy нету компонента IdHTTPProxyServer так должно быть? Я правда его через uses прописала и он начал ругаться что не найден файл IdCmdTCPServer
Он и стоит. В нем нету компонента HttpProxyServer точнее он есть в файлах. А вот почему то на панели нигде его нету. Переустановка Indy помогла решить вопрос.
Читал очень внимательно? PHP: unit IdHTTPProxyServer; interface { Indy HTTP proxy Server Original Programmer: Bas Gooijen (bas_gooijen@yahoo.com) 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, IdHeaderList, IdTCPConnection, IdCmdTCPServer, IdCommandHandlers; 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(TIdCmdTCPServer) protected FOnHTTPDocument: TOnHTTPDocument; // CommandHandlers procedure CommandGET(ASender: TIdCommand); procedure CommandPOST(ASender: TIdCommand); procedure CommandHEAD(ASender: TIdCommand); procedure CommandFILE(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); procedure InitComponent; override; published property DefaultPort default IdPORT_HTTPProxy; property OnHTTPDocument: TOnHTTPDocument read FOnHTTPDocument write FOnHTTPDocument; end; implementation uses IdResourceStrings, IdStreamVCL, IdReplyRFC, IdTCPClient, IdURI, IdGlobalProtocols, SysUtils; function HexToInt(HexStr: String): Int64; // Taken from http://www.delphi3000.com/article.asp?id=1412 var RetVar : Int64; i : byte; begin HexStr := UpperCase(HexStr); if HexStr[length(HexStr)] = 'H' then Delete(HexStr,length(HexStr),1); RetVar := 0; for i := 1 to length(HexStr) do begin RetVar := RetVar shl 4; if HexStr[i] in ['0'..'9'] then RetVar := RetVar + (byte(HexStr[i]) - 48) else if HexStr[i] in ['A'..'F'] then RetVar := RetVar + (byte(HexStr[i]) - 55) else begin Retvar := 0; break; end; end; Result := RetVar; end; { By Alexander Dzyubenko alexander@dzsoft.com http://www.dzsoft.com } function UrlDecode(const EncodedStr: String): String; // Decodes URL data into a readable string. // Example: http%3A%2F%2Fwww.dzsoft.com%2F -> http://www.dzsoft.com var I: Integer; begin Result := ''; if Length(EncodedStr) > 0 then begin I := 1; while I <= Length(EncodedStr) do begin if EncodedStr[I] = '%' then begin Result := Result + Chr(HexToInt(EncodedStr[I+1] + EncodedStr[I+2])); I := Succ(Succ(I)); end else if EncodedStr[I] = '+' then Result := Result + ' ' else Result := Result + EncodedStr[I]; I := Succ(I); end; end; 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 := 'FILE'; {do not localize} OnCommand := CommandFILE; 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; LS : TIdStreamVCL; begin //TODO: Have an event to let the user perform stream creation LStream := TMemoryStream.Create; try LS := TIdStreamVCL.Create(LStream); try ASrc.IOHandler.ReadStream(LS, ASize, ASize = -1); finally FreeAndNil(LS); end; 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 LS := TIdStreamVCL.Create(LStream); try ADest.IOHandler.Write(LS); finally FreeAndNil(LS); end; 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.Context.Connection.IOHandler.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.IOHandler.WriteLn('GET ' + LDocument + ' HTTP/1.0'); {Do not Localize} LClient.IOHandler.Write(LHeaders); LClient.IOHandler.WriteLn(''); LRemoteHeaders := TIdHeaderList.Create; try LClient.IOHandler.Capture(LRemoteHeaders, ''); ASender.Context.Connection.IOHandler.Write(LRemoteHeaders); ASender.Context.Connection.IOHandler.WriteLn(''); LPageSize := StrToIntDef(LRemoteHeaders.Values['Content-Length'], -1) ; {Do not Localize} TransferData(LClient, ASender.Context.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; LS : TIdStreamVCL; begin ASender.PerformReply := false; LHeaders := TIdHeaderList.Create; try ASender.Context.Connection.IOHandler.Capture(LHeaders, ''); LPostStream:=tmemorystream.Create; LS:= TIdStreamVCL.Create(LPostStream,False); try LPostStream.size:=StrToIntDef( LHeaders.Values['Content-Length'], 0 ); {Do not Localize} ASender.Context.Connection.IOHandler.ReadStream(LS,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.IOHandler.WriteLn('POST ' + LDocument + ' HTTP/1.0'); {Do not Localize} LClient.IOHandler.Write(LHeaders); LClient.IOHandler.WriteLn(''); LClient.IOHandler.Write(LS,0,false); LRemoteHeaders := TIdHeaderList.Create; try LClient.IOHandler.Capture(LRemoteHeaders, ''); ASender.Context.Connection.IOHandler.Write(LRemoteHeaders); ASender.Context.Connection.IOHandler.Writeln(''); LPageSize := StrToIntDef(LRemoteHeaders.Values['Content-Length'], -1) ; {Do not Localize} TransferData(LClient, ASender.Context.Connection, LDocument, LPageSize, LRemoteHeaders); finally FreeAndNil(LRemoteHeaders); end; finally LClient.Disconnect; end; finally FreeAndNil(LClient); end; finally FreeAndNil(LPostStream); FreeAndNil(LS); end; finally FreeAndNil(LHeaders); end; end; procedure TIdHTTPProxyServer.CommandConnect( ASender: TIdCommand ) ; var LHeaders: tidheaderlist; LClient: TIdTCPClient; LRemoteHost: string; LBuffer:TIdBytes; begin ASender.PerformReply := false; LHeaders := TIdHeaderList.Create; try ASender.Context.Connection.IOHandler.Capture(LHeaders, ''); LRemoteHost := ASender.Params.Strings[0]; LClient := TIdTCPClient.Create(nil); try LClient.Host := Fetch(LRemoteHost,':',True); LClient.Port := StrToIntDef(LRemoteHost, 443); LClient.Connect; try ASender.Context.Connection.IOHandler.WriteLn(''); ASender.Context.Connection.IOHandler.WriteLn('HTTP/1.0 200 Connection established'); {do not localize} ASender.Context.Connection.IOHandler.WriteLn('Proxy-agent: Indy-Proxy/1.1'); {do not localize} ASender.Context.Connection.IOHandler.WriteLn(''); ASender.Context.Connection.IOHandler.ReadTimeout:=100; LClient.IOHandler.ReadTimeout:=100; while ASender.Context.Connection.Connected and LClient.Connected do begin ASender.Context.Connection.IOHandler.ReadBytes(LBuffer,-1,true); LClient.IOHandler.Write(LBuffer); SetLength(LBuffer,0); LClient.IOHandler.ReadBytes(LBuffer,-1,true); ASender.Context.Connection.IOHandler.Write(LBuffer); SetLength(LBuffer,0); end; finally LClient.Disconnect; end; finally FreeAndNil(LClient); end; finally FreeAndNil(LHeaders); end; end; procedure TIdHTTPProxyServer.CommandFILE( ASender: TIdCommand ); begin ASender.Context.Connection.IOHandler.WriteFile(URLDecode(ASender.Params.Strings[0])); end; procedure TIdHTTPProxyServer.CommandHEAD( ASender: TIdCommand ) ; begin end; procedure TIdHTTPProxyServer.InitComponent; 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.