delphi - 为什么当 TIdHTTPProxyServer 尝试将请求转发到大多数代理服务器时返回 403?

标签 delphi proxy c++builder indy

问题来自the question我之前问过。

目前,我可以让我的代理服务器使用 TIdHTTPProxyServer 将请求转发到另一个也使用 TIdHTTPProxyServer 的代理服务器。但是当我尝试让它将请求从网络上的免费代理服务器列表转发到其他代理服务器时。大多数可以通过 IE 代理设置使用的服务器都会向我的代理服务器返回 403 错误消息。事实上我已经尝试了大约20个有效的代理服务器,但只有两个可以接受来 self 的代理服务器的请求。我不明白为什么会发生这种情况。

下面是我在 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年8月7日

嗨,我对那些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中,我应该让 header 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,希望有更好的解决方案。

最佳答案

我相信你不应该使用针孔 - 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

关于delphi - 为什么当 TIdHTTPProxyServer 尝试将请求转发到大多数代理服务器时返回 403?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11822503/

相关文章:

delphi - 在 GLScene 中抓取鼠标位置下的顶点

windows - 如何在 Delphi 中将项目添加到 Windows 资源管理器内容菜单?

c++ - 在 boost 图库中为深度优先搜索提供颜色图时遇到问题

带有用于本地安装的监视器 UI 的 HTTP 代理

database - 将本地 SQLite 数据库与服务器 SQLite 数据库同步

c++ - Borland 字符串::查找错误

C++ Builder - 使用 TIdTCPServer 以编程方式创建 TCP 服务器连接

delphi - 兰德种子不起作用?

delphi - 如何在 TPaintBox(或任何其他控件)上徒手绘制?

java - 通过代理使用 JDBC 驱动程序连接到 MySQL