这个问题延伸到我之前提到的the question。
目前,我可以让我的TIdHTTPProxyServer代理服务器将请求转发给另一个也使用TIdHTTPProxyServer的代理服务器。但当我试图让它从Web上的免费代理服务器列表转发请求到其他代理服务器时。可以通过IE代理设置使用的大多数服务器向我的代理服务器返回403错误消息。事实上,我已经尝试了大约20个有效的代理服务器,但只有两个可以接受来自我的代理服务器的请求。我无法弄清楚它为什么会发生。
以下是我在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
命令。并且大多数代理服务器在非HTTPS请求时阻止Connect命令(例如,CONNECT www.google.com.tw:80 HTTP / 1.0)。这就是为什么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
命令,我应该直接将GET www.google.com.tw:80 HTTP / 1.0发送到其他代理服务器,而不是首先发送CONNECT 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,并希望有更好的解决方案。
答案 0 :(得分:1)
我相信你不应该使用针孔 - http://www.indyproject.org/docsite/html/TIdConnectThroughHttpProxy.html
CONNECT命令不是WWW的工作方式。没有浏览器使用它。这是非WWW程序试图突破防火墙并开放直接访问WWW以外的所有互联网领域的方式。
不要使用“透明代理”类。 使用常规HTTP代理,例如How to download a file over HTTPS using Indy 10 and OpenSSL?
顺便说一下,没有像你这样命名的“HTTPBeforeCommand”这样的事件处理程序 http://www.indyproject.org/docsite/html/!!MEMBEROVERVIEW_TIdHTTPProxyServer.html