2011-08-04 16 views
4

ソケットを使用してプロキシ経由でHTTPSサーバーに接続しようとしています。私が知っている限り、HTTPプロキシを使用するときはソケットをソケットに接続し、それが実際のサーバーであるために相互作用する必要があります。 HTTPではこのアプローチが有効ですが、HTTPSではそうではありません。どうして?HTTPSプロキシに接続する方法は?

はここ

using System; 
using System.Text; 
using System.Net.Sockets; 
using System.Net.Security; 

namespace SslTcpClient 
{ 
    public class SslTcpClient 
    { 
     public static void Main(string[] args) 
     { 
      string host = "encrypted.google.com"; 
      string proxy = "127.0.0.1";//host; 
      int proxyPort = 8888;//443; 

      // Connect socket 
      TcpClient client = new TcpClient(proxy, proxyPort); 

      // Wrap in SSL stream 
      SslStream sslStream = new SslStream(client.GetStream()); 
      sslStream.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)); 
      sslStream.Write(request); 
      sslStream.Flush(); 

      // Read response 
      byte[] buffer = new byte[2048]; 
      int bytes; 
      do 
      { 
       bytes = sslStream.Read(buffer, 0, buffer.Length); 
       Console.Write(Encoding.UTF8.GetString(buffer, 0, bytes)); 
      } while (bytes != 0); 

      client.Close(); 
      Console.ReadKey(); 
     } 
    } 
} 

それが正常時に接続しているHTTPSサーバに接続する簡単なプログラムですproxy = hostproxyPort = 443。しかし、私が127.0.0.1:8888(localhost上のfiddlerプロキシ)に設定しても動作しません。プログラムはsslStream.AuthenticateAsClient(host);でハングしますなぜですか? FiddlerはHTTPSをサポートしています(ブラウザはそれを介して接続できます)。

P.S.いいえ、私の場合はHttpWebRequestを使用できません。

+1

私は最初にプロキシ経由でTCPトンネルを確立しなければならないようです。 CONNECTメソッドを使用して実行できます。しかし、私はまだそれを動作させることはできませんでした。 – Poma

答えて

7

自分で解決するために管理しました。ここに解決策があります:

using System; 
using System.Text; 
using System.Net.Sockets; 
using System.Net.Security; 

namespace SslTcpClient 
{ 
    public class SslTcpClient 
    { 
     public static void Main(string[] args) 
     { 
      string host = "encrypted.google.com"; 
      string proxy = "127.0.0.1";//host; 
      int proxyPort = 8888;//443; 

      byte[] buffer = new byte[2048]; 
      int bytes; 

      // Connect socket 
      TcpClient client = new TcpClient(proxy, proxyPort); 
      NetworkStream stream = client.GetStream(); 

      // Establish Tcp tunnel 
      byte[] 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 in SSL stream 
      SslStream sslStream = new SslStream(stream); 
      sslStream.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)); 
      sslStream.Write(request, 0, request.Length); 
      sslStream.Flush(); 

      // Read response 
      do 
      { 
       bytes = sslStream.Read(buffer, 0, buffer.Length); 
       Console.Write(Encoding.UTF8.GetString(buffer, 0, bytes)); 
      } while (bytes != 0); 

      client.Close(); 
      Console.ReadKey(); 
     } 
    } 
} 
+0

こんにちはPoma、このコードをサーバーとして使用するにはどうすればいいですか?私は、encrypted.google.comページをダウンロードしてクライアントブラウザに送信したいと思います。 –

関連する問題