2012-07-20 40 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