3

質問は、私が以前に尋ねた質問から拡張されています。

現在、TIdHTTPProxyServer を使用するプロキシ サーバーに、TIdHTTPProxyServer を使用する別のプロキシ サーバーにリクエストを転送させることができます。しかし、Web上の無料のプロキシサーバーリストから他のプロキシサーバーにリクエストを転送させようとしたとき。IE プロキシ設定で使用できるほとんどのサーバーが、私のプロキシ サーバーに 403 エラー メッセージを返します。実際、約 20 の有効なプロキシ サーバーを試しましたが、プロキシ サーバーからの要求を受け入れることができるのは 2 つだけです。なぜそれが起こるのか分かりません。

以下は、TIdHTTPProxyServer の HTTPBeforeCommand で使用するコードです。

    TIdIOHandlerStack* tempIO = new TIdIOHandlerStack(AContext->OutboundClient);

    TIdConnectThroughHttpProxy* tempProxy = new TIdConnectThroughHttpProxy(AContext->OutboundClient);
    tempProxy->Enabled = true;
    tempProxy->Host = ProxyServerAddress;
    tempProxy->Port = ProxyServerPort ;
    tempIO->TransparentProxy  =  tempProxy;
    AContext->OutboundClient->IOHandler =  tempIO;

Wireshark を使用して TIdHTTPProxyServer の動作を監視した後、TIdHTTPProxyServer は常に、実際の要求の前に最初に他のプロキシ サーバーに CONNECT 要求を送信することがわかりました (ブラウザーはそれを行いません)。そして、ほとんどのプロキシ サーバーで 403 応答を受け取ります。しかし、それを機能させる方法はまだわかりません。


2012/08/07 更新

こんにちは、私はこれらの HTTP に詳しくないので、wireshark で見たものをここに記録します。IE はリクエストにコマンドGET/POSTを使用し、HTTPリクエストにコマンドを使用しているようです。また、ほとんどのプロキシ サーバーは、Connect コマンドが HTTPS 要求でない場合にブロックします (たとえば、CONNECT www.google.com.tw:80 HTTP/1.0)。そのため、常に機能しません。 CONNECTHTTPSTIdConnectThroughHttpProxy

以下は私の回避策です。IdHTTPProxyServer.pas に少し変更を加えました。同じ問題を抱えている他の誰かに役立つことを願っています。

CONNECT コマンドの場合は、引き続き使用しますTIdConnectThroughHttpProxy

内部TIdHTTPProxyServer.CommandCONNECT

if UseProxy = True then
begin
     tempIO := TIdIOHandlerStack.Create(LContext.FOutboundClient);
     tempProxy := TIdConnectThroughHttpProxy.Create(LContext.FOutboundClient);
     tempProxy.Enabled := True;
       tempProxy.Host := UseProxyAddr;
       tempProxy.Port := UseProxyPort ;
       tempIO.TransparentProxy  :=  tempProxy;
       LContext.FOutboundClient.IOHandler :=  tempIO;
end;

コマンドについてGET/POSTは、最初に CONNECT www.google.com.tw:80 HTTP/1.0 を送信する代わりに、GET www.google.com.tw:80 HTTP/1.0 を他のプロキシ サーバーに直接送信する必要があります。

内部TIdHTTPProxyServer.CommandPassThrough

  if UseProxy = True then
  begin
     TIdTCPClient(LContext.FOutboundClient).Host := UseProxyAddr;
     TIdTCPClient(LContext.FOutboundClient).Port := UseProxyPort;
  end else
  begin
     TIdTCPClient(LContext.FOutboundClient).Host := LURI.Host;
     TIdTCPClient(LContext.FOutboundClient).Port := IndyStrToInt(LURI.Port, 80);
  end;

またTIdHTTPProxyServer.CommandPassThrough、ヘッダーを許可する必要がありますProxy-Connection = close

LContext.Connection.IOHandler.Capture(LContext.Headers, '', False);      
LContext.Headers.Values['Proxy-Connection'] := 'close';

最終的に以内にTIdHTTPProxyServer.TransferData

if AContext.TransferSource = tsClient then 
begin

  if UseProxy = True then
  begin
     ADest.IOHandler.WriteLn(AContext.Command + ' ' + AContext.Target + ' HTTP/1.0'); 
  end else
  begin
      ADest.IOHandler.WriteLn(AContext.Command + ' ' + AContext.Document + ' HTTP/1.0'); 
  end;
end;

Delphi を実装するのは初めてで、より良い解決策があることを願っています。

4

1 に答える 1

1

ピンホールを使用するべきではないと思います-http ://www.indyproject.org/docsite/html/TIdConnectThroughHttpProxy.html

CONNECTコマンドは、WWWの動作方法ではありません。ブラウザはそれを使用しません。これは、非WWWプログラムがファイアウォールを突破し、WWWを超えたインターネットのすべての領域への直接アクセスを開こうとする方法です。

「透過プロキシ」クラスは使用しないでください。Indy 10とOpenSSLを使用してHTTPS経由でファイルをダウンロードする方法のように、通常のHTTPプロキシを使用しますか?

ところで、u name"HTTPBeforeCommand" http://www.indyproject.org/docsite/html/!!MEMBEROVERVIEW_TIdHTTPProxyServer.htmlのようなイベントハンドラーはありません。

于 2012-08-06T09:07:21.723 に答える