Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Netzwerke (https://www.delphipraxis.net/14-netzwerke/)
-   -   Delphi Proxy-Server leitet keine https-Seiten weiter (https://www.delphipraxis.net/102169-proxy-server-leitet-keine-https-seiten-weiter.html)

skyobserver 24. Okt 2007 14:54


Proxy-Server leitet keine https-Seiten weiter
 
Hallo zusammen,

ich möchte mit einem selbstgeschrieben Proxy-Server Internet-Seiten filtern.
Den bisher geschriebenen Code habe ich aus vielen Beiträgen aus der DP zusammen-
gesucht (verwende Delphi7 und Indy9):

Delphi-Quellcode:
procedure TfrmMain.IdhttpserverProxyCommandGet(AThread: TIdPeerThread;
  ARequestInfo: TIdHTTPRequestInfo; AResponseInfo: TIdHTTPResponseInfo);
var
  Method: TIdHTTPMethod;
  Source, Dest: TStream;
  Url: AnsiString;
begin
  try
    AResponseInfo.ContentText := '';

    if Pos('ups.com', ARequestInfo.Host) = 0 then Exit; //Nur "ups.com"-Seiten zulassen

    try
      while idhttpProxy.Tag = 1 do Application.ProcessMessages;

      idhttpProxy.Tag := 1;

      if ARequestInfo.Command = 'GET' then Method := hmGet
      else if ARequestInfo.Command = 'POST' then Method := hmPost
      else if ARequestInfo.Command = 'HEAD' then Method := hmHead
      else
      begin
        AResponseInfo.ResponseNo := 501;
        Exit;
      end;

      Source := nil;
      Dest := nil;
      if Method <> hmHead then
      begin
        AResponseInfo.ContentStream := TMemoryStream.Create;
        if Method = hmPost then Source := ARequestInfo.PostStream;
        Dest := AResponseInfo.ContentStream;
      end;

      Url := 'http://'+ARequestInfo.Host+ARequestInfo.Document;
      if Length(ARequestInfo.QueryParams) > 0 then Url := Url+'?'+ARequestInfo.QueryParams;

      idhttpProxy.DoRequest(Method, Url, Source, Dest);
    finally
      AResponseInfo.ResponseNo := idhttpProxy.Response.ResponseCode;
      AResponseInfo.ResponseText := idhttpProxy.Response.ResponseText;
      AResponseInfo.RawHeaders.Assign(idhttpProxy.Response.RawHeaders);

      idhttpProxy.Tag := 0;
    end;
  except
  end;
end;
Die Prozedur gestattet nur das Laden von Internet-Seiten von Hosts mit "ups.com".
Das funktioniert soweit ganz gut...nur wenn man sich über eine https-Seite anmelden
muß klappt's nicht mehr...

Ich habe schon den Indy Http-Client und -Server Komponenten einen SSL-IO-Handler hinzugefügt
(habe ich hier irgendwo gelesen) und die SSL-DLLs für Indy besorgt, aber Zugriffe auf
"https://..." werden völlig ignoriert!?!

Hat jemand eine Idee was fehlt? :gruebel:

Habe von einer Indy HTTP-Proxy Komponente gelesen - finde ich aber bei mir nicht... :(

SubData 24. Okt 2007 14:59

Re: Proxy-Server leitet keine https-Seiten weiter
 
Ist im Browser denn auch eingestellt, dass bei HTTPS dein Proxy verwendet werden soll? :)

mkinzler 24. Okt 2007 15:02

Re: Proxy-Server leitet keine https-Seiten weiter
 
ist der proxy auch dafür eingerichtet (weiterer Port, 443 CONNECT erlaubt, ...)?

skyobserver 24. Okt 2007 15:08

Re: Proxy-Server leitet keine https-Seiten weiter
 
@SubData:

JA!

In meiner Firma surfe ich bereits über einen Proxy.
Der selbstgeschriebene Proxy soll zusätzlich als Filter
dazwischen. Ohne ihn funktioniert es...


@mkinzler:
Zitat:

weiterer Port, 443 CONNECT erlaubt
Ich glaube nicht...wo müßte das denn geschehen?

mkinzler 24. Okt 2007 15:21

Re: Proxy-Server leitet keine https-Seiten weiter
 
Der Proxy muss auch auf Port 443 weiterleiten und muß CONNECT erlauben.

skyobserver 25. Okt 2007 08:14

Re: Proxy-Server leitet keine https-Seiten weiter
 
Ich verwende TIdHTTPServer und TIdHTTP von Indy.

-Wie leite ich da auf den Port 443 Weiter?

-Wie Erlaube ich CONNECT?

mkinzler 25. Okt 2007 08:30

Re: Proxy-Server leitet keine https-Seiten weiter
 
Beides im Proxy.
was für ein Proxyserver wird verwendet?

skyobserver 25. Okt 2007 08:56

Re: Proxy-Server leitet keine https-Seiten weiter
 
...Den Proxy will ich doch selber schreiben (DAS IST DAS PROBLEM)...

Ich verwende TIdHTTPServer (Richtung Browser) und TIdHTTP (Richtung Parent-Proxy).
Bei erlaubten Web-Seiten soll eine Anfrage des Browsers an TidHTTPServer über
TidHTTP an den Parent-Proxy weitergeleitet werden und das Ergebnis wieder über
idHTTPServer an den Browser zurückgegeben werden.

Dafür habe ich das Ereignis OnCommandGet von idHTTPServer implementiert (siehe
Anfang des Threads). Der so entstandene Proxy-Server funktioniert allerdings
nur bei http.

Die Frage ist also: Was muß ich erweitern (Komponenten, Einstellungen...) damit
es auch mit https klappt?

Das reine hinzufügen von SSL-IO-Handlern hat nichts gebracht (ich benutze das
wohl nicht richtig...)

mkinzler 25. Okt 2007 09:00

Re: Proxy-Server leitet keine https-Seiten weiter
 
Warum nicht TIdHTTPProxyServer?

skyobserver 25. Okt 2007 09:04

Re: Proxy-Server leitet keine https-Seiten weiter
 
TIdHTTPProxyServer gibt es bei mir (Indy9) nicht!

Kann es sein, das diese Komponente erst mit Indy10 eingeführt wurde?
Kann in der Firma wegen Kompatibilität zu anderen Projekten nicht
ohne weiteres auf Indy10 upgraden...

hinnack 29. Okt 2007 06:31

Re: Proxy-Server leitet keine https-Seiten weiter
 
stimmt, INDY10 will man nicht

Ich habe mich schon immer bei 9 gefragt, ob das je schon mal jemand benutzt hat - vieles ist einfach nur buggy, angefangen, etc...

du musst eine weiters Verb neben GET, POST, etc. unterstützen: CONNECT

darin mache ich folgendes:
Delphi-Quellcode:
procedure TidHTTPService.CommandConnect(AThread: TIdPeerThread; ARequestInfo: TIdHTTPRequestInfo);
var
   TCP: TidHTTPConnectProxy;
   LCloseConnection: Boolean;
   ConnectStr: String;
   Host: String;
   Port: Integer;
   
begin
   TCP := TidHTTPConnectProxy.Create(AThread.Connection);

   if FConnectForwardingHost <> '' then
   begin
      Host := FConnectForwardingHost;
      Port := FConnectForwardingPort;
   end
   else
   begin
      Host := Copy(ARequestInfo.Document, 1, Pos(':', ARequestInfo.Document) - 1);
      Port := StrToInt( Copy(ARequestInfo.Document, Pos(':', ARequestInfo.Document) + 1, MAXINT));
   end;

   if Assigned(OnBeforeConnect) then
      OnBeforeConnect(ARequestInfo, Host, Port);


   TCP.Server.Host := Host;
   TCP.Server.Port := Port;

   LCloseConnection := false;
   ConnectStr := TCP.Server.Host + ':' + IntToStr(TCP.Server.Port);
   System.Writeln('CONNECT ' + ConnectStr);

   with AThread.Connection do
   try
      try
         TCP.Server.Connect;
         OpenWriteBuffer;
         try
            WriteLn('HTTP/1.1 200 Connection established');
            WriteLn('Proxy-agent: ' + ServerSoftware);
            WriteLn;

         finally
            CloseWriteBuffer;
         end;

      except
         on E: Exception do
         begin
            OpenWriteBuffer;
            try
               WriteLn('HTTP/1.1 502 Bad Gateway');
               WriteLn('Proxy-agent: ' + ServerSoftware);
               WriteLn;
               WriteLn('Server unreachable ' + e.Message);
               TCP.Terminate;
               Exit;
            finally
               CloseWriteBuffer;
            end;
         end;
      end;

      TCP.ConnectionHandle := TObject((AThread.Connection.IOHandler as TIdIOHandlerSocket).Binding.Handle);
      TCP.OutBoundHandle := TObject((TCP.Server.IOHandler as TIdIOHandlerSocket).Binding.Handle);

      TCP.Resume;

      repeat
         {$IFDEF MSWINDOWS}
         SleepEx(10, true);
         {$ELSE}
         Sleep(10);
         {$ENDIF}
      until (LCloseConnection) or (TCP.Terminated) or (not TCP.Server.Connected) or (not AThread.Connection.Connected);
   finally
      TCP.Server.Disconnect;
      while not TCP.Terminated do
{$IFDEF MSWINDOWS}
      SleepEx(5, true);
{$ENDIF}
{$IFDEF LINUX}
      Sleep(5);
{$ENDIF}
      FreeAndNil(TCP);

      AThread.Connection.Disconnect;
      System.Writeln('DISCONNECT ' + ConnectStr);
   end;
end;

dazu braucht man:
Delphi-Quellcode:
   TidHTTPConnectProxy = class(TThread)
      private
         FClient: TidTCPServerConnection;
         FServer: TidTCPClient;
         FReadList: TList;
         FNetData: String;
         FConnectionHandle: TObject;
         FOutBoundHandle: TObject;

      protected
         procedure Execute; override;

      public
         constructor Create(Owner: TidTCPServerConnection);
         destructor Destroy; override;

         property Server: TidTCPClient read FServer write FServer;
         property ReadList: TList read FReadList write FReadList;
         property ConnectionHandle: TObject read FConnectionHandle write FConnectionHandle;
         property OutBoundHandle: TObject read FOutBoundHandle write FOutBoundHandle;
   end;
mit:
Delphi-Quellcode:
{ TidHTTPConnectProxy }

constructor TidHTTPConnectProxy.Create(Owner: TidTCPServerConnection);
begin
   FClient := Owner;
   FReadList := TList.Create;
   FServer := TIdTCPClient.Create(nil);
   inherited Create(true);
end;

destructor TidHTTPConnectProxy.Destroy;
begin
  FreeAndNil(FServer);
  FreeAndNil(FReadList);
  inherited;
end;

procedure TidHTTPConnectProxy.Execute;
begin
   while not Terminated do
   begin
      if (Server.Connected) and (FClient.Connected) then
      begin
         try
            FReadList.Clear;
            FReadList.Add(FConnectionHandle);
            FReadList.Add(FOutBoundHandle);

            if GStack.WSSelect(FReadList, nil, nil, IdTimeoutInfinite) > 0 then
            begin
               if FReadList.IndexOf(FConnectionHandle) > -1 then
               begin
                  // TODO: WSAECONNRESET (Exception [EIdSocketError] Socket Error # 10054 Connection reset by peer)
                  FNetData := FClient.CurrentReadBuffer;
                  if Length(FNetData) > 0 then
                  begin
                     Server.Write(FNetData);
                  end;
               end;
               if FReadList.IndexOf(FOutBoundHandle) > -1 then
               begin
                  FNetData := Server.CurrentReadBuffer;
                 if Length(FNetData)>0 then
                 begin
                     FClient.Write(FNetData);
                 end;
               end;
            end
            else
               System.WriteLn('seems nothing to do...');
         except
            Terminate;
         end;
      end
      else
      begin
         Terminate;
      end;
   end;
end;
die System.Writeln kannst du wegschmeissen, wenn du keine Console hast => ist aber immer gut zum debuggen...

skyobserver 29. Okt 2007 13:28

Re: Proxy-Server leitet keine https-Seiten weiter
 
Dazu habe ich ein paar Fragen:

Delphi-Quellcode:
procedure TidHTTPService.CommandConnect(AThread: TIdPeerThread; ARequestInfo: TIdHTTPRequestInfo);
Wo ist denn die Methode "CommandConnect" implementiert?

In idHTTPServer habe ich als Ereignisse:
-"OnCommandGet" (wird nur bei Kommando "GET" aufgerufen),
-"OnCommandOther" (wird bei Kommando "CONNECT" aufgerufen) - Parameter: "Thread", "asCommand", "asData", "asVersion"
-"OnConnect" - Parameter: "AThread"

Wo kommt "ARequestInfo" und "GStack" her?

hinnack 30. Okt 2007 06:24

Re: Proxy-Server leitet keine https-Seiten weiter
 
die INDY Programmierer haben sich nicht viel Mühe gemacht mit OnCommandGet und OnCommandOther...
Verben gibt es schliesslich viel mehr (GET, POST, PUT, TRACE, OPTIONS, PROPFIND, etc.) ich rufe in OnCommandOther für jedes Verb eine eigene Methode auf (also für Connect: CommandConnect).

GStack ist in UNIT: IdStack.pas und wird immer implizit instanziert.

meine CommandOther aus TIdHTTPServer hat folgende Parameter:

AThread: TIdPeerThread; ARequestInfo: TIdHTTPRequestInfo; AResponseInfo: TIdHTTPResponseInfo; const asCommand, asData, asVersion: string

von dort geben ich AThread und ARequestInfo an CommandConnect weiter


Alle Zeitangaben in WEZ +1. Es ist jetzt 09:49 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz