/// <summary>
            /// 使用http tunnel检测代理状态
            /// </summary>
            /// <param name="webProxy">web代理</param>
            /// <param name="targetAddress">目标地址,可以是http或https</param>
            /// <param name="timeout">发送或等待数据的超时时间</param>
            /// <exception cref="ArgumentNullException"></exception>
            /// <returns></returns>
            public static HttpStatusCode Validate(IWebProxy webProxy, Uri targetAddress, TimeSpan?timeout = null)
            {
                if (webProxy == null)
                {
                    throw new ArgumentNullException(nameof(webProxy));
                }

                var httpProxy = webProxy as HttpProxy;

                if (httpProxy == null)
                {
                    httpProxy = HttpProxy.FromWebProxy(webProxy, targetAddress);
                }

                Socket socket = null;

                try
                {
                    var ascii = Encoding.GetEncoding("ASCII");
                    var host  = Dns.GetHostEntry(httpProxy.Host);
                    socket = new Socket(host.AddressList[0].AddressFamily, SocketType.Stream, ProtocolType.Tcp);

                    if (timeout.HasValue)
                    {
                        socket.SendTimeout    = (int)timeout.Value.TotalMilliseconds;
                        socket.ReceiveTimeout = (int)timeout.Value.TotalMilliseconds;
                    }

                    socket.Connect(new IPEndPoint(host.AddressList[0], httpProxy.Port));

                    var request    = httpProxy.ToTunnelRequestString(targetAddress);
                    var sendBuffer = ascii.GetBytes(request);
                    socket.Send(sendBuffer);

                    var recvBuffer = new byte[150];
                    var length     = socket.Receive(recvBuffer);

                    var response   = ascii.GetString(recvBuffer, 0, length);
                    var statusCode =
                        int.Parse(Regex.Match(response, "(?<=HTTP/1.1 )\\d+", RegexOptions.IgnoreCase).Value);
                    return((HttpStatusCode)statusCode);
                }
                catch (Exception)
                {
                    return(HttpStatusCode.ServiceUnavailable);
                }
                finally
                {
                    socket?.Dispose();
                }
            }
Exemple #2
0
        public void FromWebProxyTest()
        {
            var target = new Uri("https://www.baidu.com/");
            var p      = new WebProxy("127.0.0.1", 5000)
            {
                Credentials = new NetworkCredential("abc", "123")
            };
            var proxy = HttpProxy.FromWebProxy(p, target);

            Assert.True(proxy.Host == "127.0.0.1" && proxy.Port == 5000);
            Assert.True(proxy.GetProxy(target) == new Uri("http://127.0.0.1:5000"));
            Assert.True(proxy.UserName == "abc");
            Assert.True(proxy.Password == "123");
            Assert.True(((IWebProxy)proxy).Credentials.GetCredential(null, null).UserName == "abc");
            Assert.True(((IWebProxy)proxy).Credentials.GetCredential(null, null).Password == "123");
        }