这个问题是从我之前提出的问题延伸而来的。
目前我可以让我的代理服务器使用 TIdHTTPProxyServer 将请求转发到另一个也使用 TIdHTTPProxyServer 的代理服务器。但是当我试图让它从网络上的免费代理服务器列表中将请求转发到其他代理服务器时。大多数可以通过 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
使用命令。并且大多数代理服务器在它们不是 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
命令,我应该直接将 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,希望有更好的解决方案。