Einzelnen Beitrag anzeigen

Thom

Registriert seit: 19. Mai 2006
570 Beiträge
 
Delphi XE3 Professional
 
#11

AW: TEmbeddedWB + MultiProxy

  Alt 24. Feb 2011, 22:49
Auch wenn's etwas länger gedauert hat: Hier kommt der versprochene Beispielcode, um aus TIdHTTPServer einen voll steuerbaren Proxy zu basteln:
Delphi-Quellcode:
procedure TForm1.IdHTTPServer1CommandGet(AContext: TIdContext; ARequestInfo: TIdHTTPRequestInfo; AResponseInfo: TIdHTTPResponseInfo);
var
  URL: String;
  HTTP: TIdHTTP;
begin
  HTTP:=TIdHTTP.Create;
  try
    HTTP.Request.Assign(ARequestInfo);
    //Dinge, die bei Assign nicht mit übertragen werden:
    HTTP.Request.Authentication:=ARequestInfo.Authentication;
    HTTP.Request.BasicAuthentication:=ARequestInfo.BasicAuthentication;
    HTTP.Request.From:=ARequestInfo.From;
    HTTP.Request.Host:=ARequestInfo.Host;
    HTTP.Request.Range:=ARequestInfo.Range;
    //Kekse übergeben:
    //Die Übertragung erfolgt mit einen Trick, da der "offizielle" Weg über den Cookie-Manager
    //fehlerhaft ist (IdCookie.ExtractNextCookie() parst Client-Cookies falsch!!!).
    HTTP.Request.CustomHeaders.Add('Cookie: '+ARequestInfo.RawHeaders.Values['Cookie']);
    //Stream für Daten erstellen:
    AResponseInfo.ContentStream:=TMemoryStream.Create;
    //Anfrage zusammenstellen:
    {$IFDEF 10_5_7}
    URL:=ARequestInfo.URI;
    {$ELSE}
    URL:=ARequestInfo.RawHTTPCommand;
    Fetch(URL,' '); //Kommando entfernen (z.B. 'GET'
    URL:=Fetch(URL,' '); //komplette Anfrage ermitteln und HTTP-Typ entfernen (z.B. 'HTTP/1.0')
    URL:=Fetch(URL,'?'); //Anfrage-Parameter entfernen
    {$ENDIF}
    if ARequestInfo.QueryParams<>''
      then URL:=URL+'?'+ARequestInfo.QueryParams;
    //Anfrage an Server:
    try
      HTTP.Get(URL,AResponseInfo.ContentStream,[301,302]);
    except
    end;
    //Antwort übergeben:
    AResponseInfo.RawHeaders.Assign(HTTP.Response.RawHeaders);
    //Reaktion auf bestimmte Antworten:
    case HTTP.Response.ResponseCode of
      301, 302: AResponseInfo.Redirect(HTTP.Response.RawHeaders.Values['Location']);
    end;
  finally
    HTTP.Free;
  end;
end;
Dabei handelt es sich nur um einen prinzipiellen Entwurf, der viele Speziallfälle noch nicht berücksichtigt! Desweiteren beherrschen weder das Beispiel noch die Indy-Komponenten das Streaming von Daten. Diese werden in der aktuellen Indy Version 10 in einem Stück übertragen. Das Anschauen eines YouTube-Videos endet also mit großer Wahrscheinlichkeit im Task-Manager...

Getestet habe ich den Proxy in einem kleinen Programm, das den Datenverkehr zwischen Client (TWebBrowser) und Server protokolliert:
delphipraxis.jpg

In der oben beschriebenen Methode kann jetzt nach Lust und Laune an den einzelnen Werten herumgeschraubt werden.
Zum Beispiel wäre die Zwischenschaltung eines weiteren Proxys möglich:
Delphi-Quellcode:
    //nächsten Proxy einstellen:
    HTTP.UseProxy:=true;
    HTTP.ProxyParams.ProxyServer:=naechster_Proxy;
    HTTP.ProxyParams.ProxyPort:=80;
    HTTP.ProxyParams.ProxyUsername:=Username;
    HTTP.ProxyParams.ProxyPassword:=Password;
Möchte ich Google Maps auf hebräisch, muß ich nur die Sprache ändern:
Delphi-Quellcode:
    HTTP.Request.AcceptLanguage:='he';
    //...
Soll eine Anfrage blockiert werden, reicht folgender Code:
Delphi-Quellcode:
    if SameStr(ARequestInfo.URI,'unbeliebt') then
    begin
      AResponseInfo.ResponseNo:=204; //'HTTP/1.1 204 No Content'
      Exit;
    end;
Ist man der Meinung, daß es niemanden etwas angeht, mit welchem Browser man unterwegs ist, kann das so verhindert werden:
Delphi-Quellcode:
    HTTP.Request.UserAgent:='Mozilla/3.0 (compatible)';
    //...
Baut man das Ganze noch etwas aus, ließe sich mit einer Black-List gezielt Werbung unterdrücken. Und da gibt es sicherlich noch etliche weitere Dinge, die man mit einem solchen Proxy anstellen könnte...

Quelltext für eine einfache Demo mit TEmbeddedWB und TIdHTTPServer:
Angehängte Dateien
Dateityp: zip ProxyTest.zip (86,6 KB, 28x aufgerufen)
Thomas Nitzschke
Google Maps mit Delphi

Geändert von Thom (25. Feb 2011 um 21:38 Uhr) Grund: Demo
  Mit Zitat antworten Zitat