Лучший подход для подключения TCP через Http Proxy Server - PullRequest
0 голосов
/ 18 января 2019

Нам нужно подключить наш tcp-сервер и установить tcp-соединение за прокси-сервером (большинство брандмауэров блокируют наше прямое tcp-соединение с определенным портом).

Итак, мы внедрили прокси-сервер Apache http и подключили tcp, используя HTTP CONNECT METHOD через наш прокси-сервер http.

Итак, нам нужно сделать следующие шаги:

  • Подключение к прокси.
  • Отправить CONNECT Host:Port HTTP/1.1<CR><LF>
  • Отправить <CR><LF>
  • Ждите ответной строки. Если он содержит HTTP/1.X 200, соединение установлено

  • Читайте дальнейшие строки ответа, пока не получите пустую строку.

  • Это связано с внешним миром через прокси

Ниже я нашел два кода, написанных кем-то для этого.

Мой вопрос : Каков наилучший подход для создания TCP-соединения за прокси-сервером. И каким способом я должен использовать Webrequest или через TCP-сокет?

public static class HttpProxy
{
    public static TcpClient connectViaHTTPProxyMethod1(
    string targetHost,
    int targetPort,
    string httpProxyHost, 
    int httpProxyPort,
    string proxyUserName,
    string proxyPassword)
    {
        UriBuilder uriBuilder = null;
        Uri proxyUri = null;
        if (httpProxyHost != "")
        {
            uriBuilder = new UriBuilder
            {
                Scheme = Uri.UriSchemeHttp,
                Host = httpProxyHost,
                Port = httpProxyPort
            };

            proxyUri = uriBuilder.Uri;
        }
        HttpWebRequest request = (HttpWebRequest)WebRequest.Create(
            "http://" + targetHost + ":" + targetPort);
        //request.Timeout = 1000 * 60 * 60;
        request.KeepAlive = false;
        var webProxy = new WebProxy(proxyUri);
        if (httpProxyHost != "")
            request.Proxy = webProxy;
        request.Method = "CONNECT";

        var credentials = new NetworkCredential(
            proxyUserName, proxyPassword);

        if (proxyUserName != "")
            webProxy.Credentials = credentials;

        var response = request.GetResponse();

        var responseStream = response.GetResponseStream();
        Debug.Assert(responseStream != null);

        const BindingFlags Flags = BindingFlags.NonPublic | BindingFlags.Instance;

        var rsType = responseStream.GetType();
        var connectionProperty = rsType.GetProperty("Connection", Flags);

        var connection = connectionProperty.GetValue(responseStream, null);
        var connectionType = connection.GetType();
        var networkStreamProperty = connectionType.GetProperty("NetworkStream", Flags);

        var networkStream = networkStreamProperty.GetValue(connection, null);
        var nsType = networkStream.GetType();
        var socketProperty = nsType.GetProperty("Socket", Flags);
        var socket = (Socket)socketProperty.GetValue(networkStream, null);

        return new TcpClient { Client = socket };
    }

    public static TcpClient connectViaHTTPProxyMethod2(string targetHost, int targetPort, string httpProxyHost, int httpProxyPort, string proxyUserName, string proxyPassword)
    {
        byte[] buffer = new byte[2048];
        int bytes;

        // Connect socket
        // Dnt know how to implement proxyUserName proxyPassword
        TcpClient client = new TcpClient(httpProxyHost, httpProxyPort);
        NetworkStream stream = client.GetStream();

        // Establish Tcp tunnel
        byte[] tunnelRequest = Encoding.UTF8.GetBytes(String.Format("CONNECT {0}:{1} HTTP/1.1\r\nHost:{0}\r\n\r\n", targetHost, targetPort));
        stream.Write(tunnelRequest, 0, tunnelRequest.Length);
        stream.Flush();

        // Read response to CONNECT request
        bytes = stream.Read(buffer, 0, buffer.Length);

        return client;

    }      
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...