質問は、私が以前に尋ねた質問から拡張されています。
現在、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)。そのため、常に機能しません。 CONNECT
HTTPS
TIdConnectThroughHttpProxy
以下は私の回避策です。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 を実装するのは初めてで、より良い解決策があることを願っています。