2012-07-20 39 views
2

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

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

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

我需要做的是通过办公室代理发送请求,然后通过远程国家的代理并最终发送到网站。

让我知道如果这不够清楚!

回答

3

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

  • 请求CONNECT隧道

    1. 连接到第一代理到第二代理
    2. 一旦隧道被创建,请求隧道目标主机
    3. 发送请求。请求将通过代理#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(); 
      
  • +0

    。它在我的箱子上工作。代理支持CONNECT方法是必要的。 – 2012-07-20 21:29:49