Hello, Primoz! I think the modified code can not solve the problem on its own, without further modifications. The reason for this is that ProcessHeader procedure is called from ReceivedFromClient if and only if Client.GotHeader is false, but it is set to true after the very first invocation of the ProcessHeader, so it will not be called for all subsequent requests in a given connection.
Best wishes, Stanislav Korotky. ----- Original Message ----- From: "Primož Gabrijelčič" <[EMAIL PROTECTED]> To: "'ICS support mailing'" <twsocket@elists.org> Sent: Monday, September 22, 2008 10:06 AM Subject: Re: [twsocket] GpHTTPProxy doesn't work correctly Oh, it is that bug :(( Sorry for not including in the debate sooner, but I lost contact with GpHttpProxy years ago when I started to work on a custom version for one of my customers. Now I had no idea which of the problems I fixed years ago this was (yes, I was not using source control at the time :( ). The trick was to destroy remote socket and recreate it if host or port changed. I think this are the two most important parts: procedure TGpHttpProxy.ProcessHeader(Client: TGpHttpProxyClient); var ahost : string; aport : string; header : string; returnContent: string; resetSocket : boolean; begin resetSocket := false; returnContent := ''; header := Client.Received; if SameText(FirstEl(header,' ',-1),'CONNECT') then begin // TCP Tunnel proxy request HttpData(Client).ProxyType := ptTCPTunnel; if not IPSec.IsAllowed(Client.PeerAddr) then returnContent := Response.sTCPTunnelIPForbidden.Text else if not (ptTCPTunnel in EnabledTypes) then returnContent := Response.sTCPTunnelClosed.Text else if not ProcessTCPTunnelHeader(Client,header,ahost,aport,returnContent) then returnContent := Response.sTCPTunnelBadRequest.Text; end else begin // HTTP proxy request HttpData(Client).ProxyType := ptHTTP; if not IPSec.IsAllowed(Client.PeerAddr) then returnContent := Response.sHTTPIPForbidden.Text else if not (ptHTTP in EnabledTypes) then returnContent := Response.sHTTPClosed.Text else if not ProcessHTTPHeader(Client,header,ahost,aport,returnContent,resetSocket) then returnContent := Response.sHTTPBadRequest.Text; end; //else SameText() // Header parsed, create remote socket. if returnContent = '' then begin if resetSocket then begin {$IFDEF LogHttpFlow} LogFlow(Client, 'Destroyed connection to %s:%s due to host/port change', [Client.RemoteHost, Client.RemoteSocket.Port]); {$ENDIF LogHttpFlow} Client.DestroyRemoteSocket; Client.NumRequests := 1; end; if not assigned(Client.RemoteSocket) then with Client do begin {$IFDEF LogHttpFlow} LogFlow(Client, 'Opening connection to %s:%s', [ahost, aport]); {$ENDIF LogHttpFlow} CreateRemoteSocket; RemoteHost := ahost; RemoteSocket.Port := aport; RemoteSocket.LineMode := false; HookRemoteEvents(RemoteSocket); RemoteSocket.DnsLookup(ahost); DoRemoteSocketPrepared(Client); end //with/if else begin {$IFDEF LogHttpFlow} LogFlow(Client, 'Reusing connection to %s:%s', [Client.RemoteHost, Client.RemoteSocket.Port]); {$ENDIF LogHttpFlow} end; {$IFDEF LogHttpFlow} LogFlow(Client, 'Request: %s', [FirstEl(header, #13, -1)]); {$ENDIF LogHttpFlow} Client.Received := header; end else begin Client.DestroyRemoteSocket; Client.RemoteContent := returnContent; end; Client.GotHeader := true; end; { TGpHttpProxy.ProcessHeader } function TGpHttpProxy.ProcessHTTPHeader(Client: TGpHttpProxyClient; var header, ahost, aport, returnContent: string; var socketResetRequired: boolean): boolean; function MakeUrl(aproto, auser, apass, ahost, aport, apath: string): string; begin Result := aproto; if Last(Result,1) = ':' then Result := Result + '//' else if Last(Result,1) <> '/' then Result := Result + '://'; if auser <> '' then begin Result := Result + auser; if apass <> '' then Result := Result + ':' + apass; Result := Result + '@'; end; Result := Result + ahost; if (aport <> '') and (aport <> '80') then Result := Result + ':' + aport; Result := Result + apath; end; { MakeUrl } var apass : string; apath : string; aproto : string; auser : string; command : string; hdrHost : string; ignoreNextHopProxy: boolean; p1 : integer; p2 : integer; s : string; url : string; begin { TGpHttpProxy.ProcessHTTPHeader } Result := false; socketResetRequired := false; // extract url from GET/POST header s := header; p1 := Pos(' ',s); if p1 > 0 then begin command := First(s,p1-1); Delete(s,1,p1); s := TrimLeft(s); p2 := Pos(' ',s); if p2 > 0 then begin url := Copy(s,1,p2-1); ParseURL(url,aproto,auser,apass,ahost,aport,apath); if aport = '' then aport := '80'; hdrHost := ExtractHeader(header,'Host'); returnContent := ''; ignoreNextHopProxy := false; DoClientHeaderAvailable(Client,url,header,aproto,auser,apass,ahost,aport, apath,hdrHost,ignoreNextHopProxy,returnContent); if (NextHopHTTP.Address <> '') and (not ignoreNextHopProxy) and (returnContent = '') then //replace host information with proxy begin Delete(header,p1+1,p2-1); Insert(MakeUrl(aproto,auser,apass,ahost,aport,apath),header,p1+1); if NextHopHTTP.Username <> '' then begin // Insert 'Proxy-Authorization' header p1 := Pos(CRLF+CRLF,header); Insert(CRLF+'Proxy-Authorization: Basic '+ EncodeStr(encBase64, NextHopHTTP.Username+':'+NextHopHTTP.Password), header,p1); end; ReplaceHeader(header,'Host',hdrHost); aport := IntToStr(FNextHopProxy[ptHTTP].Port); ahost := FNextHopProxy[ptHTTP].Address; Client.UsingNextHop := true; end else if SameText(command,'OPTIONS') and (ahost = '*') then Exit else begin socketResetRequired := assigned(Client.RemoteSocket) and ((not SameText(Client.RemoteHost, ahost)) or (Client.RemoteSocket.Port <> aport)); // Any of the URL parts may have changed in the event handler - modify the header. Delete(header,p1+1,p2-1); if SameText(command,'OPTIONS') then Insert('*', header, p1+1) else if ((Client.NumRequests <= 1) and (Pos('HTTP/1.0', FirstEl(header, #13, -1)) > 0)) or socketResetRequired then Insert(apath, header, p1+1) else Insert(aproto+'://'+ahost+IFF(aport<>'80',':'+aport,'')+apath, header, p1+1); ReplaceHeader(header, 'Host', hdrHost); if auser <> '' then begin // Insert 'Authorization' header p1 := Pos(CRLF+CRLF,header); Insert(CRLF+'Authorization: Basic '+EncodeStr(encBase64, auser+ ':'+apass), header,p1); end; Client.ProxyConnection := ExtractHeader(header, 'Proxy-connection'); Client.UsingNextHop := false; end; Result := true; end; //else p2 > 0 end; //else p1 > 0 end; { TGpHttpProxy.ProcessHTTPHeader } Hope that helps. Primoz -----Original Message----- From: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED] On Behalf Of S.Korotky Sent: Sunday, September 21, 2008 9:56 PM To: ICS support mailing Subject: Re: [twsocket] GpHTTPProxy doesn't work correctly Hello Stephane, Yes, I've managed to locate the place where the problems are "initiated", this is ProcessHeader procedure. It processes only the very first http-header in an established connection and bypasses all the others. So, if a browser keeps the connections and uses them to request pages from different sites, 404 errors are produced or incorrect content is shown. I don't think it will be easy to write a quick patch without proper processing of http 1.1 data on per-document basis. Perhaps, if it'll be possible to make a browser believe, that it is _not_ connected to a proxy, it will not re-use the same connection for different sites, but will establish new ones. I don't remember if a http-header exists which allows for doing so, if included in http response header to the browser (this is not the thing the Proxy-Connection does). Best wishes Stanislav Korotky ----- Original Message ----- From: "Stéphane CHADEYRON" <[EMAIL PROTECTED]> To: "ICS support mailing" <twsocket@elists.org> Sent: Saturday, September 20, 2008 10:03 PM Subject: Re: [twsocket] GpHTTPProxy doesn't work correctly > Hello Stanislav, > > I have a user case: with the web-site :www.youtube.com > Impossible display this web site correct. > > Other case but not systematic: > 1. write in the address bar in your navigator (with the proxy) the url: > www.google.com > 2. write in the address bar in your navigator (with the proxy) the url: > www.clubic.com > 3. write again in the address bar in your navigator (with the proxy) the > url: www.clubic.com > > result: there is a other page... google or smartserver or error... > > Thank you for your help. > > Best regards, > > Stephan > > -- > To unsubscribe or change your settings for TWSocket mailing list > please goto http://lists.elists.org/cgi-bin/mailman/listinfo/twsocket > Visit our website at http://www.overbyte.be > -- To unsubscribe or change your settings for TWSocket mailing list please goto http://lists.elists.org/cgi-bin/mailman/listinfo/twsocket Visit our website at http://www.overbyte.be -- To unsubscribe or change your settings for TWSocket mailing list please goto http://lists.elists.org/cgi-bin/mailman/listinfo/twsocket Visit our website at http://www.overbyte.be -- To unsubscribe or change your settings for TWSocket mailing list please goto http://lists.elists.org/cgi-bin/mailman/listinfo/twsocket Visit our website at http://www.overbyte.be