C# HttpWebRequest通过两个代理

C# HttpWebRequest通过两个代理,c#,.net,proxy,C#,.net,Proxy,我最近建立了一个网站,它使用地理DNS将DNS解析为两个不同的IP,具体取决于您的位置 然而,这意味着要监控网站,我需要确保该网站在两个地理位置都可用。为此,我在.net中编写了一个小程序,不断尝试和HttpWebRequest在网站上获取一个小html文件,一次使用本地internet设置,一次使用基于区域的代理,该代理将名称解析为第二个IP地址 这在我家的笔记本电脑上运行良好,但在办公室,要在几乎所有的机器上连接到互联网,你都需要通过代理,这意味着我之前设置的代理不再工作 我需要能够做的是通

我最近建立了一个网站,它使用地理DNS将DNS解析为两个不同的IP,具体取决于您的位置

然而,这意味着要监控网站,我需要确保该网站在两个地理位置都可用。为此,我在.net中编写了一个小程序,不断尝试和HttpWebRequest在网站上获取一个小html文件,一次使用本地internet设置,一次使用基于区域的代理,该代理将名称解析为第二个IP地址

这在我家的笔记本电脑上运行良好,但在办公室,要在几乎所有的机器上连接到互联网,你都需要通过代理,这意味着我之前设置的代理不再工作

我需要能够做的是通过office代理发送请求,然后通过远程国家的代理发送,最后发送到网站


如果这不够清楚,请告诉我

首先,您需要确保两个代理都是HTTPS,并且都支持连接方法,即“代理链接”。通常HTTP协议的设计不支持“代理链接”。 这个想法是建立两个连接隧道,一个在另一个里面。 算法如下所示:

  • 通过TCP连接到第一个代理
  • 请求将隧道连接到第二个代理
  • 创建隧道后,向目标主机请求隧道
  • 发送请求。请求将通过代理1和代理2发送到目标主机。 下面是我在我的机器上测试的示例代码:

    string host = "encrypted.google.com";
    string proxy2 = "213.240.237.149";//host;
    int proxyPort2 = 3128;//443;
    string proxy = "180.183.236.63";//host;
    int proxyPort = 3128;//443;
    
    byte[] buffer = new byte[2048];
    int bytes;
    
    // Connect to the 1st proxy
    TcpClient client = new TcpClient(proxy, proxyPort);
    NetworkStream stream = client.GetStream();
    
    // Establish tunnel to 2nd proxy
    byte[] tunnelRequest = Encoding.UTF8.GetBytes(String.Format("CONNECT {0}:{1}  HTTP/1.1\r\nHost:{0}\r\n\r\n", proxy2, proxyPort2));
    stream.Write(tunnelRequest, 0, tunnelRequest.Length);
    stream.Flush();
    
    // Read response to CONNECT request
    // There should be loop that reads multiple packets
    bytes = stream.Read(buffer, 0, buffer.Length);
    Console.Write(Encoding.UTF8.GetString(buffer, 0, bytes));
    
    // Establish tunnel to target host
    tunnelRequest = Encoding.UTF8.GetBytes(String.Format("CONNECT {0}:443  HTTP/1.1\r\nHost:{0}\r\n\r\n", host));
    stream.Write(tunnelRequest, 0, tunnelRequest.Length);
    stream.Flush();
    
    // Read response to CONNECT request
    // There should be loop that reads multiple packets
    bytes = stream.Read(buffer, 0, buffer.Length);
    Console.Write(Encoding.UTF8.GetString(buffer, 0, bytes));
    
    // Wrap into SSL stream
    SslStream sslStream2 = new SslStream(stream);
    sslStream2.AuthenticateAsClient(host);
    
    // Send request
    byte[] request = Encoding.UTF8.GetBytes(String.Format("GET https://{0}/  HTTP/1.1\r\nHost: {0}\r\n\r\n", host));
    sslStream2.Write(request, 0, request.Length);
    sslStream2.Flush();
    
    // Read response
    do
    {
        bytes = sslStream2.Read(buffer, 0, buffer.Length);
        Console.Write(Encoding.UTF8.GetString(buffer, 0, bytes));
    } while (bytes != 0);
    
    client.Close();
    Console.ReadKey();
    

  • 我已经测试了代码。它在我的盒子上起作用了。代理支持CONNECT方法是必要的。