private async Task DoConnectAsync(NetworkStream localStream, HttpRequest httpRequest) { string host; int port; { string[] parts = httpRequest.RequestPath.Split(':'); host = parts[0]; if (parts.Length > 1) { port = int.Parse(parts[1]); } else { port = 80; } } //connect to remote server _remoteSocket = await _connectionManager.ConnectAsync(EndPointExtension.GetEndPoint(host, port)); //signal client 200 OK await localStream.WriteAsync(Encoding.ASCII.GetBytes(httpRequest.Protocol + " 200 OK\r\nConnection: close\r\n\r\n")); //pipe sockets _ = _localSocket.CopyToAsync(_remoteSocket).ContinueWith(delegate(Task prevTask) { Dispose(); }); _ = _remoteSocket.CopyToAsync(_localSocket).ContinueWith(delegate(Task prevTask) { Dispose(); }); }
public static NetProxy CreateProxy(NetProxyType type, string address, int port, NetworkCredential credential = null) { switch (type) { case NetProxyType.Http: return(new HttpProxy(EndPointExtension.GetEndPoint(address, port), credential)); case NetProxyType.Socks5: return(new SocksProxy(EndPointExtension.GetEndPoint(address, port), credential)); default: throw new NotSupportedException("Proxy type not supported."); } }
public static NetProxy CreateSystemHttpProxy() { IWebProxy proxy = WebRequest.DefaultWebProxy; if (proxy == null) { return(null); //no proxy configured } Uri testUri = new Uri("https://www.google.com/"); if (proxy.IsBypassed(testUri)) { return(null); //no proxy configured } Uri proxyAddress = proxy.GetProxy(testUri); if (proxyAddress.Equals(testUri)) { return(null); //no proxy configured } return(new HttpProxy(EndPointExtension.GetEndPoint(proxyAddress.Host, proxyAddress.Port), proxy.Credentials.GetCredential(proxyAddress, "BASIC"))); }
public async Task StartAsync() { bool dontDispose = false; try { NetworkStream localStream = new NetworkStream(_localSocket); Stream remoteStream = null; string lastHost = null; int lastPort = 0; while (true) { HttpRequest httpRequest; { Task <HttpRequest> task = HttpRequest.ReadRequestAsync(localStream); using (CancellationTokenSource timeoutCancellationTokenSource = new CancellationTokenSource()) { if (await Task.WhenAny(task, Task.Delay(CLIENT_REQUEST_TIMEOUT, timeoutCancellationTokenSource.Token)) != task) { return; //request timed out } timeoutCancellationTokenSource.Cancel(); //cancel delay task } httpRequest = await task; } if (httpRequest == null) { return; //connection closed gracefully by client } if (_authenticationManager != null) { string proxyAuth = httpRequest.Headers[HttpRequestHeader.ProxyAuthorization]; if (string.IsNullOrEmpty(proxyAuth)) { await SendResponseAsync(407, "<h1>Proxy Authentication Required</h1>"); return; } string username; string password; { string[] parts = proxyAuth.Split(new char[] { ' ' }, 2); if (!parts[0].Equals("BASIC", StringComparison.OrdinalIgnoreCase) || (parts.Length < 2)) { await SendResponseAsync(407, "<h1>Proxy Authentication Required</h1><p>Proxy authentication method is not supported.</p>"); return; } string[] credParts = Encoding.ASCII.GetString(Convert.FromBase64String(parts[1])).Split(new char[] { ':' }, 2); if (credParts.Length != 2) { await SendResponseAsync(407, "<h1>Proxy Authentication Required</h1><p>Proxy authentication method is not supported.</p>"); return; } username = credParts[0]; password = credParts[1]; } if (!_authenticationManager.Authenticate(username, password)) { await SendResponseAsync(407, "<h1>Proxy Authentication Required</h1><p>Invalid username or password.</p>"); return; } } if (httpRequest.HttpMethod.Equals("CONNECT", StringComparison.OrdinalIgnoreCase)) { await DoConnectAsync(localStream, httpRequest); dontDispose = true; break; } else { #region connect to remote server string host; int port; string requestPathAndQuery; if (Uri.TryCreate(httpRequest.RequestPathAndQuery, UriKind.Absolute, out Uri requestUri)) { host = requestUri.Host; port = requestUri.Port; requestPathAndQuery = requestUri.PathAndQuery; } else { string hostHeader = httpRequest.Headers[HttpRequestHeader.Host]; if (string.IsNullOrEmpty(hostHeader)) { throw new HttpProxyServerException("Invalid proxy request."); } string[] parts = hostHeader.Split(':'); host = parts[0]; if (parts.Length > 1) { port = int.Parse(parts[1]); } else { port = 80; } requestPathAndQuery = httpRequest.RequestPathAndQuery; } if (!host.Equals(lastHost) || port != lastPort || !_remoteSocket.Connected) { if (_remoteSocket != null) { if (_remoteSocket.Connected) { try { _remoteSocket.Shutdown(SocketShutdown.Both); } catch { } } _remoteSocket.Dispose(); } _remoteSocket = await _connectionManager.ConnectAsync(EndPointExtension.GetEndPoint(host, port)); remoteStream = new WriteBufferedStream(new NetworkStream(_remoteSocket), 512); lastHost = host; lastPort = port; //pipe response stream _ = _remoteSocket.CopyToAsync(_localSocket).ContinueWith(delegate(Task prevTask) { Dispose(); }); } #endregion #region relay client request to server foreach (string header in httpRequest.Headers.AllKeys) { if (header.StartsWith("Proxy-", StringComparison.OrdinalIgnoreCase)) { httpRequest.Headers.Remove(header); } } await remoteStream.WriteAsync(Encoding.ASCII.GetBytes(httpRequest.HttpMethod + " " + requestPathAndQuery + " " + httpRequest.Protocol + "\r\n")); await remoteStream.WriteAsync(httpRequest.Headers.ToByteArray()); if (httpRequest.InputStream != null) { await httpRequest.InputStream.CopyToAsync(remoteStream); } await remoteStream.FlushAsync(); #endregion } } } catch (Exception ex) { await SendResponseAsync(ex); } finally { if (!dontDispose) { Dispose(); } } }
public static NetProxy CreateHttpProxy(string address, int port = 8080, NetworkCredential credential = null) { return(new HttpProxy(EndPointExtension.GetEndPoint(address, port), credential)); }
public Task <TunnelProxy> CreateTunnelProxyAsync(string address, int port, bool enableSsl = false, bool ignoreCertificateErrors = false) { return(CreateTunnelProxyAsync(EndPointExtension.GetEndPoint(address, port), enableSsl, ignoreCertificateErrors)); }
public async Task <Socket> ConnectAsync(string address, int port) { return(await ConnectAsync(EndPointExtension.GetEndPoint(address, port))); }
public bool IsBypassed(Uri host) { return(IsBypassed(EndPointExtension.GetEndPoint(host.Host, host.Port))); }
public new async Task SendMailAsync(MailMessage message) { if (_disposed) { throw new ObjectDisposedException("SmtpClientEx"); } if (message.To.Count == 0) { throw new ArgumentException("Message does not contain receipent email address."); } if (DeliveryMethod == SmtpDeliveryMethod.Network) { string host = _host; if (string.IsNullOrEmpty(host)) { //resolve MX for the receipent domain using IDnsClient if (_dnsClient == null) { _dnsClient = new DnsClient() { Proxy = _proxy } } ; IReadOnlyList <string> mxDomains = await Dns.DnsClient.ResolveMXAsync(_dnsClient, message.To[0].Host); if (mxDomains.Count > 0) { host = mxDomains[0]; } else { host = message.To[0].Host; } _port = 25; Credentials = null; } if (_proxy == null) { if (_smtpOverTls) { EndPoint remoteEP = EndPointExtension.GetEndPoint(host, _port); if ((_tunnelProxy != null) && !_tunnelProxy.RemoteEndPoint.Equals(remoteEP)) { _tunnelProxy.Dispose(); _tunnelProxy = null; } if ((_tunnelProxy == null) || _tunnelProxy.IsBroken) { _tunnelProxy = await TunnelProxy.CreateTunnelProxyAsync(remoteEP, true, _ignoreCertificateErrors); } base.Host = _tunnelProxy.TunnelEndPoint.Address.ToString(); base.Port = _tunnelProxy.TunnelEndPoint.Port; } else { base.Host = host; base.Port = _port; } await base.SendMailAsync(message); } else { EndPoint remoteEP = EndPointExtension.GetEndPoint(host, _port); if ((_tunnelProxy != null) && !_tunnelProxy.RemoteEndPoint.Equals(remoteEP)) { _tunnelProxy.Dispose(); _tunnelProxy = null; } if ((_tunnelProxy == null) || _tunnelProxy.IsBroken) { _tunnelProxy = await _proxy.CreateTunnelProxyAsync(remoteEP, _smtpOverTls, _ignoreCertificateErrors); } base.Host = _tunnelProxy.TunnelEndPoint.Address.ToString(); base.Port = _tunnelProxy.TunnelEndPoint.Port; await base.SendMailAsync(message); } } else { await base.SendMailAsync(message); } }
public new async Task SendMailAsync(MailMessage message) { if (_disposed) { throw new ObjectDisposedException("SmtpClientEx"); } if (DeliveryMethod == SmtpDeliveryMethod.Network) { if (string.IsNullOrEmpty(_host)) { if (_dnsClient == null) { _dnsClient = new DnsClient(); } IReadOnlyList <string> mxServers = await _dnsClient.ResolveMXAsync(message.To[0].Host); if (mxServers.Count > 0) { _host = mxServers[0]; } else { _host = message.To[0].Host; } _port = 25; Credentials = null; } if (_proxy == null) { if (_enableSslWrapper) { EndPoint remoteEP = EndPointExtension.GetEndPoint(_host, _port); if ((_tunnelProxy != null) && !_tunnelProxy.RemoteEndPoint.Equals(remoteEP)) { _tunnelProxy.Dispose(); _tunnelProxy = null; } if ((_tunnelProxy == null) || _tunnelProxy.IsBroken) { IPEndPoint ep = await remoteEP.GetIPEndPointAsync(); Socket socket = new Socket(ep.AddressFamily, SocketType.Stream, ProtocolType.Tcp); await socket.ConnectAsync(ep); _tunnelProxy = new TunnelProxy(socket, remoteEP, _enableSslWrapper, _ignoreCertificateErrors); } base.Host = _tunnelProxy.TunnelEndPoint.Address.ToString(); base.Port = _tunnelProxy.TunnelEndPoint.Port; } else { base.Host = _host; base.Port = _port; } await base.SendMailAsync(message); } else { EndPoint remoteEP = EndPointExtension.GetEndPoint(_host, _port); if ((_tunnelProxy != null) && !_tunnelProxy.RemoteEndPoint.Equals(remoteEP)) { _tunnelProxy.Dispose(); _tunnelProxy = null; } if ((_tunnelProxy == null) || _tunnelProxy.IsBroken) { _tunnelProxy = await _proxy.CreateTunnelProxyAsync(remoteEP, _enableSslWrapper, _ignoreCertificateErrors); } base.Host = _tunnelProxy.TunnelEndPoint.Address.ToString(); base.Port = _tunnelProxy.TunnelEndPoint.Port; await base.SendMailAsync(message); } } else { await base.SendMailAsync(message); } }