private static void DoTestClientServer(bool fragment) { SecureRandom secureRandom = new SecureRandom(); TlsClientProtocol clientProtocol = new TlsClientProtocol(secureRandom); TlsServerProtocol serverProtocol = new TlsServerProtocol(secureRandom); clientProtocol.Connect(new MockTlsClient(null)); serverProtocol.Accept(new MockTlsServer()); // pump handshake bool hadDataFromServer = true; bool hadDataFromClient = true; while (hadDataFromServer || hadDataFromClient) { hadDataFromServer = PumpData(serverProtocol, clientProtocol, fragment); hadDataFromClient = PumpData(clientProtocol, serverProtocol, fragment); } // send data in both directions byte[] data = new byte[1024]; secureRandom.NextBytes(data); WriteAndRead(clientProtocol, serverProtocol, data, fragment); WriteAndRead(serverProtocol, clientProtocol, data, fragment); // close the connection clientProtocol.Close(); PumpData(clientProtocol, serverProtocol, fragment); CheckClosed(serverProtocol); CheckClosed(clientProtocol); }
internal static TlsClientProtocol OpenTlsConnection(string hostname, int port, TlsClient client) { TcpClient tcp = new TcpClient(hostname, port); TlsClientProtocol protocol = new TlsClientProtocol(tcp.GetStream(), secureRandom); protocol.Connect(client); return protocol; }
public void TestClientServer() { SecureRandom secureRandom = new SecureRandom(); PipedStream clientPipe = new PipedStream(); PipedStream serverPipe = new PipedStream(clientPipe); TlsClientProtocol clientProtocol = new TlsClientProtocol(clientPipe, secureRandom); TlsServerProtocol serverProtocol = new TlsServerProtocol(serverPipe, secureRandom); Server server = new Server(serverProtocol); Thread serverThread = new Thread(new ThreadStart(server.Run)); serverThread.Start(); MockSrpTlsClient client = new MockSrpTlsClient(null, MockSrpTlsServer.TEST_IDENTITY, MockSrpTlsServer.TEST_PASSWORD); clientProtocol.Connect(client); // NOTE: Because we write-all before we read-any, this length can't be more than the pipe capacity int length = 1000; byte[] data = new byte[length]; secureRandom.NextBytes(data); Stream output = clientProtocol.Stream; output.Write(data, 0, data.Length); byte[] echo = new byte[data.Length]; int count = Streams.ReadFully(clientProtocol.Stream, echo); Assert.AreEqual(count, data.Length); Assert.IsTrue(Arrays.AreEqual(data, echo)); output.Close(); serverThread.Join(); }
public void Connect(HTTPRequest request) { string negotiatedProtocol = HTTPProtocolFactory.W3C_HTTP1; Uri uri = #if !BESTHTTP_DISABLE_PROXY request.HasProxy ? request.Proxy.Address : #endif request.CurrentUri; #region TCP Connection if (Client == null) { Client = new TcpClient(); } if (!Client.Connected) { Client.ConnectTimeout = request.ConnectTimeout; #if NETFX_CORE Client.UseHTTPSProtocol = #if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) !Request.UseAlternateSSL && #endif HTTPProtocolFactory.IsSecureProtocol(uri); #endif if (HTTPManager.Logger.Level == Logger.Loglevels.All) { HTTPManager.Logger.Verbose("TCPConnector", string.Format("'{0}' - Connecting to {1}:{2}", request.CurrentUri.ToString(), uri.Host, uri.Port.ToString()), request.Context); } #if !NETFX_CORE && (!UNITY_WEBGL || UNITY_EDITOR) Client.SendBufferSize = HTTPManager.SendBufferSize; Client.ReceiveBufferSize = HTTPManager.ReceiveBufferSize; if (HTTPManager.Logger.Level == Logger.Loglevels.All) { HTTPManager.Logger.Verbose("TCPConnector", string.Format("'{0}' - Buffer sizes - Send: {1} Receive: {2} Blocking: {3}", request.CurrentUri.ToString(), Client.SendBufferSize.ToString(), Client.ReceiveBufferSize.ToString(), Client.Client.Blocking.ToString()), request.Context); } #endif #if NETFX_CORE && !UNITY_EDITOR && !ENABLE_IL2CPP try { Client.Connect(uri.Host, uri.Port); } finally { request.Timing.Add(TimingEventNames.TCP_Connection); } #else System.Net.IPAddress[] addresses = null; try { if (Client.ConnectTimeout > TimeSpan.Zero) { // https://forum.unity3d.com/threads/best-http-released.200006/page-37#post-3150972 using (System.Threading.ManualResetEvent mre = new System.Threading.ManualResetEvent(false)) { IAsyncResult result = System.Net.Dns.BeginGetHostAddresses(uri.Host, (res) => { try { mre.Set(); } catch { } }, null); bool success = mre.WaitOne(Client.ConnectTimeout); if (success) { addresses = System.Net.Dns.EndGetHostAddresses(result); } else { throw new TimeoutException("DNS resolve timed out!"); } } } else { addresses = System.Net.Dns.GetHostAddresses(uri.Host); } } finally { request.Timing.Add(TimingEventNames.DNS_Lookup); } if (request.IsCancellationRequested) { throw new Exception("IsCancellationRequested"); } try { Client.Connect(addresses, uri.Port, request); } finally { request.Timing.Add(TimingEventNames.TCP_Connection); } if (request.IsCancellationRequested) { throw new Exception("IsCancellationRequested"); } #endif if (HTTPManager.Logger.Level <= Logger.Loglevels.Information) { HTTPManager.Logger.Information("TCPConnector", "Connected to " + uri.Host + ":" + uri.Port.ToString(), request.Context); } } else if (HTTPManager.Logger.Level <= Logger.Loglevels.Information) { HTTPManager.Logger.Information("TCPConnector", "Already connected to " + uri.Host + ":" + uri.Port.ToString(), request.Context); } #endregion if (Stream == null) { bool isSecure = HTTPProtocolFactory.IsSecureProtocol(request.CurrentUri); // set the stream to Client.GetStream() so the proxy, if there's any can use it directly. this.Stream = this.TopmostStream = Client.GetStream(); /*if (Stream.CanTimeout) * Stream.ReadTimeout = Stream.WriteTimeout = (int)Request.Timeout.TotalMilliseconds;*/ #if !BESTHTTP_DISABLE_PROXY if (request.HasProxy) { try { request.Proxy.Connect(this.Stream, request); } finally { request.Timing.Add(TimingEventNames.Proxy_Negotiation); } } if (request.IsCancellationRequested) { throw new Exception("IsCancellationRequested"); } #endif // proxy connect is done, we can set the stream to a buffered one. HTTPProxy requires the raw NetworkStream for HTTPResponse's ReadUnknownSize! this.Stream = this.TopmostStream = new BufferedReadNetworkStream(Client.GetStream(), Math.Max(8 * 1024, HTTPManager.ReceiveBufferSize)); // We have to use Request.CurrentUri here, because uri can be a proxy uri with a different protocol if (isSecure) { DateTime tlsNegotiationStartedAt = DateTime.Now; #region SSL Upgrade #if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) if (request.UseAlternateSSL) { var handler = new TlsClientProtocol(this.Stream, new BestHTTP.SecureProtocol.Org.BouncyCastle.Security.SecureRandom()); List <string> protocols = new List <string>(); #if !BESTHTTP_DISABLE_HTTP2 SupportedProtocols protocol = request.ProtocolHandler == SupportedProtocols.Unknown ? HTTPProtocolFactory.GetProtocolFromUri(request.CurrentUri) : request.ProtocolHandler; if (protocol == SupportedProtocols.HTTP) { // http/2 over tls (https://www.iana.org/assignments/tls-extensiontype-values/tls-extensiontype-values.xhtml#alpn-protocol-ids) protocols.Add(HTTPProtocolFactory.W3C_HTTP2); } #endif protocols.Add(HTTPProtocolFactory.W3C_HTTP1); AbstractTlsClient tlsClient = null; if (HTTPManager.TlsClientFactory == null) { tlsClient = HTTPManager.DefaultTlsClientFactory(request, protocols); } else { try { tlsClient = HTTPManager.TlsClientFactory(request, protocols); } catch { } if (tlsClient == null) { tlsClient = HTTPManager.DefaultTlsClientFactory(request, protocols); } } tlsClient.LoggingContext = request.Context; handler.Connect(tlsClient); if (!string.IsNullOrEmpty(tlsClient.ServerSupportedProtocol)) { negotiatedProtocol = tlsClient.ServerSupportedProtocol; } Stream = handler.Stream; } else #endif { #if !NETFX_CORE SslStream sslStream = new SslStream(Client.GetStream(), false, (sender, cert, chain, errors) => { return(request.CallCustomCertificationValidator(cert, chain)); }); if (!sslStream.IsAuthenticated) { sslStream.AuthenticateAsClient(request.CurrentUri.Host); } Stream = sslStream; #else Stream = Client.GetStream(); #endif } #endregion request.Timing.Add(TimingEventNames.TLS_Negotiation, DateTime.Now - tlsNegotiationStartedAt); } } this.NegotiatedProtocol = negotiatedProtocol; }
public void Connect(HTTPRequest request) { string negotiatedProtocol = HTTPProtocolFactory.W3C_HTTP1; Uri uri = #if !BESTHTTP_DISABLE_PROXY request.HasProxy ? request.Proxy.Address : #endif request.CurrentUri; #region TCP Connection if (Client == null) { Client = new TcpClient(); } if (!Client.Connected) { Client.ConnectTimeout = request.ConnectTimeout; #if NETFX_CORE Client.UseHTTPSProtocol = #if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) !Request.UseAlternateSSL && #endif HTTPProtocolFactory.IsSecureProtocol(uri); #endif if (HTTPManager.Logger.Level == Logger.Loglevels.All) { HTTPManager.Logger.Verbose("TCPConnector", string.Format("'{0}' - Connecting to {1}:{2}", request.CurrentUri.ToString(), uri.Host, uri.Port.ToString())); } #if !NETFX_CORE && (!UNITY_WEBGL || UNITY_EDITOR) Client.SendBufferSize = HTTPManager.SendBufferSize; Client.ReceiveBufferSize = HTTPManager.ReceiveBufferSize; if (HTTPManager.Logger.Level == Logger.Loglevels.All) { HTTPManager.Logger.Verbose("TCPConnector", string.Format("'{0}' - Buffer sizes - Send: {1} Receive: {2} Blocking: {3}", request.CurrentUri.ToString(), Client.SendBufferSize.ToString(), Client.ReceiveBufferSize.ToString(), Client.Client.Blocking.ToString())); } #endif Client.Connect(uri.Host, uri.Port); if (HTTPManager.Logger.Level <= Logger.Loglevels.Information) { HTTPManager.Logger.Information("TCPConnector", "Connected to " + uri.Host + ":" + uri.Port.ToString()); } } else if (HTTPManager.Logger.Level <= Logger.Loglevels.Information) { HTTPManager.Logger.Information("TCPConnector", "Already connected to " + uri.Host + ":" + uri.Port.ToString()); } #endregion if (Stream == null) { bool isSecure = HTTPProtocolFactory.IsSecureProtocol(request.CurrentUri); this.Stream = this.TopmostStream = Client.GetStream(); /*if (Stream.CanTimeout) * Stream.ReadTimeout = Stream.WriteTimeout = (int)Request.Timeout.TotalMilliseconds;*/ #if !BESTHTTP_DISABLE_PROXY if (request.Proxy != null) { request.Proxy.Connect(this.Stream, request); } #endif // We have to use Request.CurrentUri here, because uri can be a proxy uri with a different protocol if (isSecure) { #region SSL Upgrade #if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) if (request.UseAlternateSSL) { var handler = new TlsClientProtocol(Client.GetStream(), new BestHTTP.SecureProtocol.Org.BouncyCastle.Security.SecureRandom()); // http://tools.ietf.org/html/rfc3546#section-3.1 // -It is RECOMMENDED that clients include an extension of type "server_name" in the client hello whenever they locate a server by a supported name type. // -Literal IPv4 and IPv6 addresses are not permitted in "HostName". // User-defined list has a higher priority List <string> hostNames = request.CustomTLSServerNameList; // If there's no user defined one and the host isn't an IP address, add the default one if ((hostNames == null || hostNames.Count == 0) && !request.CurrentUri.IsHostIsAnIPAddress()) { hostNames = new List <string>(1); hostNames.Add(request.CurrentUri.Host); } List <string> protocols = new List <string>(); #if !BESTHTTP_DISABLE_HTTP2 SupportedProtocols protocol = request.ProtocolHandler == SupportedProtocols.Unknown ? HTTPProtocolFactory.GetProtocolFromUri(request.CurrentUri) : request.ProtocolHandler; if (protocol == SupportedProtocols.HTTP) { // http/2 over tls (https://www.iana.org/assignments/tls-extensiontype-values/tls-extensiontype-values.xhtml#alpn-protocol-ids) protocols.Add(HTTPProtocolFactory.W3C_HTTP2); } #endif protocols.Add(HTTPProtocolFactory.W3C_HTTP1); var tlsClient = new LegacyTlsClient(request.CurrentUri, request.CustomCertificateVerifyer == null ? new AlwaysValidVerifyer() : request.CustomCertificateVerifyer, request.CustomClientCredentialsProvider, hostNames, protocols); handler.Connect(tlsClient); if (!string.IsNullOrEmpty(tlsClient.ServerSupportedProtocol)) { negotiatedProtocol = tlsClient.ServerSupportedProtocol; } Stream = handler.Stream; } else #endif { #if !NETFX_CORE SslStream sslStream = new SslStream(Client.GetStream(), false, (sender, cert, chain, errors) => { return(request.CallCustomCertificationValidator(cert, chain)); }); if (!sslStream.IsAuthenticated) { sslStream.AuthenticateAsClient(request.CurrentUri.Host); } Stream = sslStream; #else Stream = Client.GetStream(); #endif } #endregion } } this.NegotiatedProtocol = negotiatedProtocol; }
public void Connect() { BasicTlsPskIdentity pskIdentity = null; if (_userKey != null) { if (_userKey.HasKeyType((int)COSE.GeneralValuesInt.KeyType_Octet)) { CBORObject kid = _userKey[COSE.CoseKeyKeys.KeyIdentifier]; if (kid != null) { pskIdentity = new BasicTlsPskIdentity(kid.GetByteString(), _userKey[CoseKeyParameterKeys.Octet_k].GetByteString()); } else { pskIdentity = new BasicTlsPskIdentity(new byte[0], _userKey[CoseKeyParameterKeys.Octet_k].GetByteString()); } } } _tlsSession = new TLSClient(null, pskIdentity); _authKey = _userKey; TlsClientProtocol clientProtocol = new TlsClientProtocol(new SecureRandom()); _client = new TcpClient(_ipEndPoint.AddressFamily); _client.Connect(_ipEndPoint); _stm = _client.GetStream(); clientProtocol.Connect(_tlsSession); while (_tlsSession.InHandshake) { bool sleep = true; int cbToRead = clientProtocol.GetAvailableOutputBytes(); if (cbToRead != 0) { byte[] data = new byte[cbToRead]; int cbRead = clientProtocol.ReadOutput(data, 0, cbToRead); _stm.Write(data, 0, cbRead); sleep = false; } if (_stm.DataAvailable) { byte[] data = new byte[1024]; int cbRead = _stm.Read(data, 0, data.Length); Array.Resize(ref data, cbRead); clientProtocol.OfferInput(data); sleep = false; } if (sleep) { Thread.Sleep(100); } } _tlsClient = clientProtocol; // Send over the capability block SendCSMSignal(); // if (_toSend != null) { _queue.Enqueue(_toSend); _toSend = null; } _stm.BeginRead(_buffer, 0, _buffer.Length, ReadCallback, this); WriteData(); }
public override async Task OnConnectedAsync(ConnectionContext connection) { Logger.Debug($"Connecting to {_proxySettings.RemoteHost}:{_proxySettings.RemotePort}"); var proxyClient = new TcpClient(); await proxyClient.ConnectAsync(_proxySettings.RemoteHost, _proxySettings.RemotePort); var ogStream = proxyClient.GetStream(); Stream proxyStream = ogStream; if (_proxySettings.Secure) { var protocol = new TlsClientProtocol(proxyStream, new Org.BouncyCastle.Security.SecureRandom()); protocol.Connect(new BlazeTlsClient()); proxyStream = protocol.Stream; } var blazeProtocol = new BlazeProxyProtocol(); var localReader = connection.CreateReader(); var localWriter = connection.CreateWriter(); var remoteReader = new ProtocolReader(proxyStream); var remoteWriter = new ProtocolWriter(proxyStream); while (true) { try { var result = await localReader.ReadAsync(blazeProtocol); var message = result.Message; if (message != null) { var header = message.Header; Logger.Debug( $"Client -> Proxy; Length:{header.Length} Component:{header.Component} Command:0x{header.Command:X2} ErrorCode:{header.ErrorCode} MessageType:{header.MessageType} MessageId:{header.MessageId}"); var requestPayload = message.Payload; if (!requestPayload.IsEmpty) { if (!_parser.TryParseBody(requestPayload)) { Logger.Error("Failed to parse request message"); } } await remoteWriter.WriteAsync(blazeProtocol, message); } if (result.IsCompleted) { break; } } finally { localReader.Advance(); } do { try { var result = await remoteReader.ReadAsync(blazeProtocol); var message = result.Message; if (message != null) { var header = message.Header; Logger.Debug( $"Proxy <- Server; Length:{header.Length} Component:{header.Component} Command:0x{header.Command:X2} ErrorCode:{header.ErrorCode} MessageType:{header.MessageType} MessageId:{header.MessageId}"); var responsePayload = message.Payload; if (!responsePayload.IsEmpty) { if (!_parser.TryParseBody(responsePayload)) { Logger.Error("Failed to parse response message"); } } await localWriter.WriteAsync(blazeProtocol, message); } if (result.IsCompleted) { break; } } finally { remoteReader.Advance(); } } while (ogStream.DataAvailable); } }
private void Connect() { Uri uri = (!this.CurrentRequest.HasProxy) ? this.CurrentRequest.CurrentUri : this.CurrentRequest.Proxy.Address; if (this.Client == null) { this.Client = new TcpClient(); } if (!this.Client.Connected) { this.Client.ConnectTimeout = this.CurrentRequest.ConnectTimeout; this.Client.Connect(uri.Host, uri.Port); HTTPManager.Logger.Information("HTTPConnection", "Connected to " + uri.Host); } else { HTTPManager.Logger.Information("HTTPConnection", "Already connected to " + uri.Host); } object locker = HTTPManager.Locker; lock (locker) { this.StartTime = DateTime.UtcNow; } if (this.Stream == null) { if (this.HasProxy && !this.Proxy.IsTransparent) { this.Stream = this.Client.GetStream(); BinaryWriter binaryWriter = new BinaryWriter(this.Stream); binaryWriter.Write(string.Format("CONNECT {0}:{1} HTTP/1.1", this.CurrentRequest.CurrentUri.Host, this.CurrentRequest.CurrentUri.Port).GetASCIIBytes()); binaryWriter.Write(HTTPRequest.EOL); binaryWriter.Write(string.Format("Proxy-Connection: Keep-Alive", new object[0])); binaryWriter.Write(HTTPRequest.EOL); binaryWriter.Write(string.Format("Connection: Keep-Alive", new object[0])); binaryWriter.Write(HTTPRequest.EOL); binaryWriter.Write(string.Format("Host: {0}:{1}", this.CurrentRequest.CurrentUri.Host, this.CurrentRequest.CurrentUri.Port).GetASCIIBytes()); binaryWriter.Write(HTTPRequest.EOL); binaryWriter.Write(HTTPRequest.EOL); binaryWriter.Flush(); this.CurrentRequest.ProxyResponse = new HTTPProxyResponse(this.CurrentRequest, this.Stream, false, false); if (!this.CurrentRequest.ProxyResponse.Receive(-1, true)) { throw new Exception("Connection to the Proxy Server failed!"); } HTTPManager.Logger.Information("HTTPConnection", string.Concat(new object[] { "Proxy returned - status code: ", this.CurrentRequest.ProxyResponse.StatusCode, " message: ", this.CurrentRequest.ProxyResponse.Message })); } if (HTTPProtocolFactory.IsSecureProtocol(this.CurrentRequest.CurrentUri)) { if (this.CurrentRequest.UseAlternateSSL) { TlsClientProtocol tlsClientProtocol = new TlsClientProtocol(this.Client.GetStream(), new SecureRandom()); List <string> list = new List <string>(1); list.Add(this.CurrentRequest.CurrentUri.Host); TlsClientProtocol arg_32B_0 = tlsClientProtocol; ICertificateVerifyer arg_326_0; if (this.CurrentRequest.CustomCertificateVerifyer == null) { ICertificateVerifyer certificateVerifyer = new AlwaysValidVerifyer(); arg_326_0 = certificateVerifyer; } else { arg_326_0 = this.CurrentRequest.CustomCertificateVerifyer; } arg_32B_0.Connect(new LegacyTlsClient(arg_326_0, null, list)); this.Stream = tlsClientProtocol.Stream; } else { SslStream sslStream = new SslStream(this.Client.GetStream(), false, (object sender, X509Certificate cert, X509Chain chain, SslPolicyErrors errors) => this.CurrentRequest.CallCustomCertificationValidator(cert, chain)); if (!sslStream.IsAuthenticated) { sslStream.AuthenticateAsClient(uri.Host); } this.Stream = sslStream; } } else { this.Stream = this.Client.GetStream(); } } }
public static string DownloadFile(string url, int timeout) { string response = ""; Uri uri = null; // try to pasre url try { uri = new Uri(url); } catch (Exception ex) { return(ex.Message); } // create new TCP-Client using (var client = new TcpClient(uri.Host, uri.Port)) { var sr = new SecureRandom(); var cl = new OSNTlsClient(uri.Host); var protocol = new TlsClientProtocol(client.GetStream(), sr); protocol.Connect(cl); using (var stream = protocol.Stream) { var hdr = new StringBuilder(); hdr.AppendLine("GET " + uri.PathAndQuery + " HTTP/1.1"); hdr.AppendLine("Host: " + uri.Host); hdr.AppendLine("Content-Type: text/json; charset=utf-8"); hdr.AppendLine("Connection: close"); hdr.AppendLine(); var dataToSend = Encoding.ASCII.GetBytes(hdr.ToString()); stream.Write(dataToSend, 0, dataToSend.Length); // set stop watch as timout Stopwatch st = new Stopwatch(); st.Start(); //read header bytewise string header = ""; int totalRead = 0; byte[] buff = new byte[1]; do { totalRead = stream.Read(buff, 0, buff.Length); header += Encoding.ASCII.GetString(buff); if (st.ElapsedMilliseconds > timeout) { throw new TimeoutException("Connection to " + url + " timed out."); } }while (!header.Contains("\r\n\r\n")); int contentlength = 0; if (header.Contains("Transfer-Encoding: chunked")) { // chunked transfer, first line should contain content length string strcontentlength = ""; do { totalRead = stream.Read(buff, 0, buff.Length); strcontentlength += Encoding.ASCII.GetString(buff, 0, buff.Length); if (st.ElapsedMilliseconds > timeout) { throw new TimeoutException("Connection to " + url + " timed out."); } }while (!strcontentlength.Contains("\r\n")); strcontentlength = strcontentlength.Replace("\r\n", ""); contentlength = int.Parse(strcontentlength, System.Globalization.NumberStyles.HexNumber); } else { // get content length from header Regex strcontentlength = new Regex("(?<=Content-Length:\\s)\\d+", RegexOptions.IgnoreCase); contentlength = int.Parse(strcontentlength.Match(header).Value); } // re-assign buffer // read response buff = new byte[1000]; totalRead = 0; do { int bytesRead = stream.Read(buff, 0, buff.Length); string part = Encoding.UTF8.GetString(buff, 0, bytesRead); Console.WriteLine(part); response += part; totalRead += bytesRead; if (st.ElapsedMilliseconds > timeout) { throw new TimeoutException("Connection to " + url + " timed out."); } }while (totalRead < contentlength); // cut response at the end if (response.Contains("\r\n")) { response = response.Substring(0, response.IndexOf("\r\n")); } st.Stop(); } } return(response); }
private void Connect() { Uri uri = (!base.CurrentRequest.HasProxy) ? base.CurrentRequest.CurrentUri : base.CurrentRequest.Proxy.Address; if (Client == null) { Client = new TcpClient(); } if (!Client.Connected) { Client.ConnectTimeout = base.CurrentRequest.ConnectTimeout; Client.Connect(uri.Host, uri.Port); if (HTTPManager.Logger.Level <= Loglevels.Information) { HTTPManager.Logger.Information("HTTPConnection", "Connected to " + uri.Host + ":" + uri.Port.ToString()); } } else if (HTTPManager.Logger.Level <= Loglevels.Information) { HTTPManager.Logger.Information("HTTPConnection", "Already connected to " + uri.Host + ":" + uri.Port.ToString()); } lock (HTTPManager.Locker) { base.StartTime = DateTime.UtcNow; } if (Stream == null) { bool flag = HTTPProtocolFactory.IsSecureProtocol(base.CurrentRequest.CurrentUri); if (base.HasProxy && (!base.Proxy.IsTransparent || (flag && base.Proxy.NonTransparentForHTTPS))) { Stream = Client.GetStream(); BinaryWriter binaryWriter = new BinaryWriter(Stream); bool flag2; do { flag2 = false; binaryWriter.SendAsASCII($"CONNECT {base.CurrentRequest.CurrentUri.Host}:{base.CurrentRequest.CurrentUri.Port} HTTP/1.1"); binaryWriter.Write(HTTPRequest.EOL); binaryWriter.SendAsASCII("Proxy-Connection: Keep-Alive"); binaryWriter.Write(HTTPRequest.EOL); binaryWriter.SendAsASCII("Connection: Keep-Alive"); binaryWriter.Write(HTTPRequest.EOL); binaryWriter.SendAsASCII($"Host: {base.CurrentRequest.CurrentUri.Host}:{base.CurrentRequest.CurrentUri.Port}"); binaryWriter.Write(HTTPRequest.EOL); if (base.HasProxy && base.Proxy.Credentials != null) { switch (base.Proxy.Credentials.Type) { case AuthenticationTypes.Basic: binaryWriter.Write(string.Format("Proxy-Authorization: {0}", "Basic " + Convert.ToBase64String(Encoding.UTF8.GetBytes(base.Proxy.Credentials.UserName + ":" + base.Proxy.Credentials.Password))).GetASCIIBytes()); binaryWriter.Write(HTTPRequest.EOL); break; case AuthenticationTypes.Unknown: case AuthenticationTypes.Digest: { Digest digest = DigestStore.Get(base.Proxy.Address); if (digest != null) { string text = digest.GenerateResponseHeader(base.CurrentRequest, base.Proxy.Credentials); if (!string.IsNullOrEmpty(text)) { binaryWriter.Write($"Proxy-Authorization: {text}".GetASCIIBytes()); binaryWriter.Write(HTTPRequest.EOL); } } break; } } } binaryWriter.Write(HTTPRequest.EOL); binaryWriter.Flush(); base.CurrentRequest.ProxyResponse = new HTTPResponse(base.CurrentRequest, Stream, isStreamed: false, isFromCache: false); if (!base.CurrentRequest.ProxyResponse.Receive()) { throw new Exception("Connection to the Proxy Server failed!"); } if (HTTPManager.Logger.Level <= Loglevels.Information) { HTTPManager.Logger.Information("HTTPConnection", "Proxy returned - status code: " + base.CurrentRequest.ProxyResponse.StatusCode + " message: " + base.CurrentRequest.ProxyResponse.Message); } int statusCode = base.CurrentRequest.ProxyResponse.StatusCode; if (statusCode == 407) { string text2 = DigestStore.FindBest(base.CurrentRequest.ProxyResponse.GetHeaderValues("proxy-authenticate")); if (!string.IsNullOrEmpty(text2)) { Digest orCreate = DigestStore.GetOrCreate(base.Proxy.Address); orCreate.ParseChallange(text2); if (base.Proxy.Credentials != null && orCreate.IsUriProtected(base.Proxy.Address) && (!base.CurrentRequest.HasHeader("Proxy-Authorization") || orCreate.Stale)) { flag2 = true; } } } else if (!base.CurrentRequest.ProxyResponse.IsSuccess) { throw new Exception($"Proxy returned Status Code: \"{base.CurrentRequest.ProxyResponse.StatusCode}\", Message: \"{base.CurrentRequest.ProxyResponse.Message}\" and Response: {base.CurrentRequest.ProxyResponse.DataAsText}"); } }while (flag2); } if (flag) { if (base.CurrentRequest.UseAlternateSSL) { TlsClientProtocol tlsClientProtocol = new TlsClientProtocol(Client.GetStream(), new SecureRandom()); List <string> list = new List <string>(1); list.Add(base.CurrentRequest.CurrentUri.Host); TlsClientProtocol tlsClientProtocol2 = tlsClientProtocol; Uri currentUri = base.CurrentRequest.CurrentUri; object verifyer; if (base.CurrentRequest.CustomCertificateVerifyer == null) { ICertificateVerifyer certificateVerifyer = new AlwaysValidVerifyer(); verifyer = certificateVerifyer; } else { verifyer = base.CurrentRequest.CustomCertificateVerifyer; } tlsClientProtocol2.Connect(new LegacyTlsClient(currentUri, (ICertificateVerifyer)verifyer, base.CurrentRequest.CustomClientCredentialsProvider, list)); Stream = tlsClientProtocol.Stream; } else { SslStream sslStream = new SslStream(Client.GetStream(), leaveInnerStreamOpen: false, (object sender, X509Certificate cert, X509Chain chain, SslPolicyErrors errors) => base.CurrentRequest.CallCustomCertificationValidator(cert, chain)); if (!sslStream.IsAuthenticated) { sslStream.AuthenticateAsClient(base.CurrentRequest.CurrentUri.Host); } Stream = sslStream; } } else { Stream = Client.GetStream(); } } }
private void Connect() { Uri uri = #if !BESTHTTP_DISABLE_PROXY CurrentRequest.HasProxy ? CurrentRequest.Proxy.Address : #endif CurrentRequest.CurrentUri; #region TCP Connection if (Client == null) { Client = new TcpClient(); } if (!Client.Connected) { Client.ConnectTimeout = CurrentRequest.ConnectTimeout; #if NETFX_CORE || (UNITY_WP8 && !UNITY_EDITOR) Client.UseHTTPSProtocol = #if !BESTHTTP_DISABLE_ALTERNATE_SSL !CurrentRequest.UseAlternateSSL && #endif HTTPProtocolFactory.IsSecureProtocol(uri); #endif Client.Connect(uri.Host, uri.Port); if (HTTPManager.Logger.Level <= Logger.Loglevels.Information) { HTTPManager.Logger.Information("HTTPConnection", "Connected to " + uri.Host + ":" + uri.Port.ToString()); } } else if (HTTPManager.Logger.Level <= Logger.Loglevels.Information) { HTTPManager.Logger.Information("HTTPConnection", "Already connected to " + uri.Host + ":" + uri.Port.ToString()); } #endregion lock (HTTPManager.Locker) StartTime = DateTime.UtcNow; if (Stream == null) { bool isSecure = HTTPProtocolFactory.IsSecureProtocol(CurrentRequest.CurrentUri); #if !BESTHTTP_DISABLE_PROXY #region Proxy Handling if (HasProxy && (!Proxy.IsTransparent || (isSecure && Proxy.NonTransparentForHTTPS))) { Stream = Client.GetStream(); var outStream = new BinaryWriter(Stream); bool retry; do { // If we have to becouse of a authentication request, we will switch it to true retry = false; outStream.SendAsASCII(string.Format("CONNECT {0}:{1} HTTP/1.1", CurrentRequest.CurrentUri.Host, CurrentRequest.CurrentUri.Port)); outStream.Write(HTTPRequest.EOL); outStream.SendAsASCII("Proxy-Connection: Keep-Alive"); outStream.Write(HTTPRequest.EOL); outStream.SendAsASCII("Connection: Keep-Alive"); outStream.Write(HTTPRequest.EOL); outStream.SendAsASCII(string.Format("Host: {0}:{1}", CurrentRequest.CurrentUri.Host, CurrentRequest.CurrentUri.Port)); outStream.Write(HTTPRequest.EOL); // Proxy Authentication if (HasProxy && Proxy.Credentials != null) { switch (Proxy.Credentials.Type) { case AuthenticationTypes.Basic: // With Basic authentication we don't want to wait for a challange, we will send the hash with the first request outStream.Write(string.Format("Proxy-Authorization: {0}", string.Concat("Basic ", Convert.ToBase64String(Encoding.UTF8.GetBytes(Proxy.Credentials.UserName + ":" + Proxy.Credentials.Password)))).GetASCIIBytes()); outStream.Write(HTTPRequest.EOL); break; case AuthenticationTypes.Unknown: case AuthenticationTypes.Digest: var digest = DigestStore.Get(Proxy.Address); if (digest != null) { string authentication = digest.GenerateResponseHeader(CurrentRequest, Proxy.Credentials); if (!string.IsNullOrEmpty(authentication)) { outStream.Write(string.Format("Proxy-Authorization: {0}", authentication).GetASCIIBytes()); outStream.Write(HTTPRequest.EOL); } } break; } } outStream.Write(HTTPRequest.EOL); // Make sure to send all the wrote data to the wire outStream.Flush(); CurrentRequest.ProxyResponse = new HTTPResponse(CurrentRequest, Stream, false, false); // Read back the response of the proxy if (!CurrentRequest.ProxyResponse.Receive(-1, true)) { throw new Exception("Connection to the Proxy Server failed!"); } if (HTTPManager.Logger.Level <= Logger.Loglevels.Information) { HTTPManager.Logger.Information("HTTPConnection", "Proxy returned - status code: " + CurrentRequest.ProxyResponse.StatusCode + " message: " + CurrentRequest.ProxyResponse.Message); } switch (CurrentRequest.ProxyResponse.StatusCode) { // Proxy authentication required // http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.8 case 407: { string authHeader = DigestStore.FindBest(CurrentRequest.ProxyResponse.GetHeaderValues("proxy-authenticate")); if (!string.IsNullOrEmpty(authHeader)) { var digest = DigestStore.GetOrCreate(Proxy.Address); digest.ParseChallange(authHeader); if (Proxy.Credentials != null && digest.IsUriProtected(Proxy.Address) && (!CurrentRequest.HasHeader("Proxy-Authorization") || digest.Stale)) { retry = true; } } break; } default: if (!CurrentRequest.ProxyResponse.IsSuccess) { throw new Exception(string.Format("Proxy returned Status Code: \"{0}\", Message: \"{1}\" and Response: {2}", CurrentRequest.ProxyResponse.StatusCode, CurrentRequest.ProxyResponse.Message, CurrentRequest.ProxyResponse.DataAsText)); } break; } } while (retry); } #endregion #endif // #if !BESTHTTP_DISABLE_PROXY // We have to use CurrentRequest.CurrentUri here, becouse uri can be a proxy uri with a different protocol if (isSecure) { #region SSL Upgrade #if !BESTHTTP_DISABLE_ALTERNATE_SSL if (CurrentRequest.UseAlternateSSL) { var handler = new TlsClientProtocol(Client.GetStream(), new Org.BouncyCastle.Security.SecureRandom()); // http://tools.ietf.org/html/rfc3546#section-3.1 // It is RECOMMENDED that clients include an extension of type "server_name" in the client hello whenever they locate a server by a supported name type. List <string> hostNames = new List <string>(1); hostNames.Add(CurrentRequest.CurrentUri.Host); handler.Connect(new LegacyTlsClient(CurrentRequest.CurrentUri, CurrentRequest.CustomCertificateVerifyer == null ? new AlwaysValidVerifyer() : CurrentRequest.CustomCertificateVerifyer, null, hostNames)); Stream = handler.Stream; } else #endif { #if !NETFX_CORE && !UNITY_WP8 SslStream sslStream = new SslStream(Client.GetStream(), false, (sender, cert, chain, errors) => { return(CurrentRequest.CallCustomCertificationValidator(cert, chain)); }); if (!sslStream.IsAuthenticated) { sslStream.AuthenticateAsClient(CurrentRequest.CurrentUri.Host); } Stream = sslStream; #else Stream = Client.GetStream(); #endif } #endregion } else { Stream = Client.GetStream(); } } }
Connect() { Uri uri = CurrentRequest.HasProxy ? CurrentRequest.Proxy.Address : CurrentRequest.CurrentUri; if (Client == null) { Client = new TcpClient(); } if (!Client.Connected) { Client.ConnectTimeout = CurrentRequest.ConnectTimeout; //#if NETFX_CORE //await //#endif Client.Connect(uri.Host, uri.Port); } if (Stream == null) { if (HasProxy && !Proxy.IsTransparent) { Stream = Client.GetStream(); var outStream = new BinaryWriter(Stream); outStream.Write(string.Format("CONNECT {0}:{1} HTTP/1.1", CurrentRequest.CurrentUri.Host, CurrentRequest.CurrentUri.Port).GetASCIIBytes()); outStream.Write(HTTPRequest.EOL); outStream.Write(string.Format("Host: {0}:{1}", CurrentRequest.CurrentUri.Host, CurrentRequest.CurrentUri.Port).GetASCIIBytes()); outStream.Write(HTTPRequest.EOL); outStream.Write(string.Format("Proxy-Connection: Keep-Alive")); outStream.Write(HTTPRequest.EOL); outStream.Write(HTTPRequest.EOL); outStream.Flush(); ReadTo(Stream, HTTPResponse.LF); ReadTo(Stream, HTTPResponse.LF); } if (HTTPProtocolFactory.IsSecureProtocol(uri)) { // On WP8 there are no Mono, so we must use the 'alternate' TlsHandlers #if !UNITY_WP8 && !NETFX_CORE if (CurrentRequest.UseAlternateSSL) { #endif var handler = new TlsClientProtocol(Client.GetStream(), new Org.BouncyCastle.Security.SecureRandom()); handler.Connect(new LegacyTlsClient(new AlwaysValidVerifyer())); Stream = handler.Stream; #if !UNITY_WP8 && !NETFX_CORE } else { SslStream sslStream = new SslStream(Client.GetStream(), false, (sender, cert, chain, errors) => { return(CurrentRequest.CallCustomCertificationValidator(cert, chain)); }); if (!sslStream.IsAuthenticated) { sslStream.AuthenticateAsClient(uri.Host); } Stream = sslStream; } #endif } else { Stream = Client.GetStream(); } } }
private void Connect() { Uri uri = #if !BESTHTTP_DISABLE_PROXY CurrentRequest.HasProxy ? CurrentRequest.Proxy.Address : #endif CurrentRequest.CurrentUri; #region TCP Connection if (Client == null) { Client = new TcpClient(); } if (!Client.Connected) { Client.ConnectTimeout = CurrentRequest.ConnectTimeout; #if NETFX_CORE Client.UseHTTPSProtocol = #if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) !CurrentRequest.UseAlternateSSL && #endif HTTPProtocolFactory.IsSecureProtocol(uri); #endif if (HTTPManager.Logger.Level == Logger.Loglevels.All) { HTTPManager.Logger.Verbose("HTTPConnection", string.Format("'{0}' - Connecting to {1}:{2}", this.CurrentRequest.CurrentUri.ToString(), uri.Host, uri.Port.ToString())); } #if !NETFX_CORE && (!UNITY_WEBGL || UNITY_EDITOR) Client.SendBufferSize = HTTPManager.SendBufferSize; Client.ReceiveBufferSize = HTTPManager.ReceiveBufferSize; if (HTTPManager.Logger.Level == Logger.Loglevels.All) { HTTPManager.Logger.Verbose("HTTPConnection", string.Format("'{0}' - Buffer sizes - Send: {1} Receive: {2} Blocking: {3}", this.CurrentRequest.CurrentUri.ToString(), Client.SendBufferSize.ToString(), Client.ReceiveBufferSize.ToString(), Client.Client.Blocking.ToString())); } #endif Client.Connect(uri.Host, uri.Port); if (HTTPManager.Logger.Level <= Logger.Loglevels.Information) { HTTPManager.Logger.Information("HTTPConnection", "Connected to " + uri.Host + ":" + uri.Port.ToString()); } } else if (HTTPManager.Logger.Level <= Logger.Loglevels.Information) { HTTPManager.Logger.Information("HTTPConnection", "Already connected to " + uri.Host + ":" + uri.Port.ToString()); } #endregion StartTime = DateTime.UtcNow; if (Stream == null) { bool isSecure = HTTPProtocolFactory.IsSecureProtocol(CurrentRequest.CurrentUri); Stream = Client.GetStream(); /*if (Stream.CanTimeout) * Stream.ReadTimeout = Stream.WriteTimeout = (int)CurrentRequest.Timeout.TotalMilliseconds;*/ #if !BESTHTTP_DISABLE_PROXY if (CurrentRequest.Proxy != null) { CurrentRequest.Proxy.Connect(this.Stream, this.CurrentRequest); } #endif // We have to use CurrentRequest.CurrentUri here, because uri can be a proxy uri with a different protocol if (isSecure) { // Under the new experimental runtime there's a bug in the Socket.Send implementation that can cause a // connection when the TLS protocol is used. #if !NETFX_CORE && (!UNITY_WEBGL || UNITY_EDITOR) && NET_4_6 //Client.SendBufferSize = 0; #endif #region SSL Upgrade #if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) if (CurrentRequest.UseAlternateSSL) { var handler = new TlsClientProtocol(Client.GetStream(), new BestHTTP.SecureProtocol.Org.BouncyCastle.Security.SecureRandom()); // http://tools.ietf.org/html/rfc3546#section-3.1 // -It is RECOMMENDED that clients include an extension of type "server_name" in the client hello whenever they locate a server by a supported name type. // -Literal IPv4 and IPv6 addresses are not permitted in "HostName". // User-defined list has a higher priority List <string> hostNames = CurrentRequest.CustomTLSServerNameList; // If there's no user defined one and the host isn't an IP address, add the default one if ((hostNames == null || hostNames.Count == 0) && !CurrentRequest.CurrentUri.IsHostIsAnIPAddress()) { hostNames = new List <string>(1); hostNames.Add(CurrentRequest.CurrentUri.Host); } handler.Connect(new LegacyTlsClient(CurrentRequest.CurrentUri, CurrentRequest.CustomCertificateVerifyer == null ? new AlwaysValidVerifyer() : CurrentRequest.CustomCertificateVerifyer, CurrentRequest.CustomClientCredentialsProvider, hostNames)); Stream = handler.Stream; } else #endif { #if !NETFX_CORE SslStream sslStream = new SslStream(Client.GetStream(), false, (sender, cert, chain, errors) => { return(CurrentRequest.CallCustomCertificationValidator(cert, chain)); }); if (!sslStream.IsAuthenticated) { sslStream.AuthenticateAsClient(CurrentRequest.CurrentUri.Host); } Stream = sslStream; #else Stream = Client.GetStream(); #endif } #endregion } } }
private void Connect() { Uri uri = !base.CurrentRequest.HasProxy ? base.CurrentRequest.CurrentUri : base.CurrentRequest.Proxy.Address; if (this.Client == null) { this.Client = new TcpClient(); } if (!this.Client.Connected) { this.Client.ConnectTimeout = base.CurrentRequest.ConnectTimeout; if (HTTPManager.Logger.Level == Loglevels.All) { HTTPManager.Logger.Verbose("HTTPConnection", $"'{base.CurrentRequest.CurrentUri.ToString()}' - Connecting to {uri.Host}:{uri.Port.ToString()}"); } this.Client.Connect(uri.Host, uri.Port); if (HTTPManager.Logger.Level <= Loglevels.Information) { HTTPManager.Logger.Information("HTTPConnection", "Connected to " + uri.Host + ":" + uri.Port.ToString()); } } else if (HTTPManager.Logger.Level <= Loglevels.Information) { HTTPManager.Logger.Information("HTTPConnection", "Already connected to " + uri.Host + ":" + uri.Port.ToString()); } base.StartTime = DateTime.UtcNow; if (this.Stream == null) { bool flag = HTTPProtocolFactory.IsSecureProtocol(base.CurrentRequest.CurrentUri); this.Stream = this.Client.GetStream(); if (base.HasProxy && (!base.Proxy.IsTransparent || (flag && base.Proxy.NonTransparentForHTTPS))) { bool flag2; BinaryWriter stream = new BinaryWriter(this.Stream); do { flag2 = false; string str = $"CONNECT {base.CurrentRequest.CurrentUri.Host}:{base.CurrentRequest.CurrentUri.Port} HTTP/1.1"; HTTPManager.Logger.Information("HTTPConnection", "Sending " + str); stream.SendAsASCII(str); stream.Write(HTTPRequest.EOL); stream.SendAsASCII("Proxy-Connection: Keep-Alive"); stream.Write(HTTPRequest.EOL); stream.SendAsASCII("Connection: Keep-Alive"); stream.Write(HTTPRequest.EOL); stream.SendAsASCII($"Host: {base.CurrentRequest.CurrentUri.Host}:{base.CurrentRequest.CurrentUri.Port}"); stream.Write(HTTPRequest.EOL); if (base.HasProxy && (base.Proxy.Credentials != null)) { switch (base.Proxy.Credentials.Type) { case AuthenticationTypes.Basic: stream.Write($"Proxy-Authorization: {("Basic " + Convert.ToBase64String(Encoding.UTF8.GetBytes(base.Proxy.Credentials.UserName + ":" + base.Proxy.Credentials.Password)))}".GetASCIIBytes()); stream.Write(HTTPRequest.EOL); break; case AuthenticationTypes.Unknown: case AuthenticationTypes.Digest: { Digest digest = DigestStore.Get(base.Proxy.Address); if (digest != null) { string str2 = digest.GenerateResponseHeader(base.CurrentRequest, base.Proxy.Credentials); if (!string.IsNullOrEmpty(str2)) { stream.Write($"Proxy-Authorization: {str2}".GetASCIIBytes()); stream.Write(HTTPRequest.EOL); } } break; } } } stream.Write(HTTPRequest.EOL); stream.Flush(); base.CurrentRequest.ProxyResponse = new HTTPResponse(base.CurrentRequest, this.Stream, false, false); if (!base.CurrentRequest.ProxyResponse.Receive(-1, true)) { throw new Exception("Connection to the Proxy Server failed!"); } if (HTTPManager.Logger.Level <= Loglevels.Information) { object[] objArray1 = new object[] { "Proxy returned - status code: ", base.CurrentRequest.ProxyResponse.StatusCode, " message: ", base.CurrentRequest.ProxyResponse.Message }; HTTPManager.Logger.Information("HTTPConnection", string.Concat(objArray1)); } if (base.CurrentRequest.ProxyResponse.StatusCode == 0x197) { string str3 = DigestStore.FindBest(base.CurrentRequest.ProxyResponse.GetHeaderValues("proxy-authenticate")); if (!string.IsNullOrEmpty(str3)) { Digest orCreate = DigestStore.GetOrCreate(base.Proxy.Address); orCreate.ParseChallange(str3); if (((base.Proxy.Credentials != null) && orCreate.IsUriProtected(base.Proxy.Address)) && (!base.CurrentRequest.HasHeader("Proxy-Authorization") || orCreate.Stale)) { flag2 = true; } } } else if (!base.CurrentRequest.ProxyResponse.IsSuccess) { throw new Exception($"Proxy returned Status Code: " { base.CurrentRequest.ProxyResponse.StatusCode } ", Message: " { base.CurrentRequest.ProxyResponse.Message } " and Response: {base.CurrentRequest.ProxyResponse.DataAsText}"); } }while (flag2); } if (flag) { if (base.CurrentRequest.UseAlternateSSL) { TlsClientProtocol protocol = new TlsClientProtocol(this.Client.GetStream(), new SecureRandom()); List <string> hostNames = new List <string>(1) { base.CurrentRequest.CurrentUri.Host }; protocol.Connect(new LegacyTlsClient(base.CurrentRequest.CurrentUri, (base.CurrentRequest.CustomCertificateVerifyer != null) ? base.CurrentRequest.CustomCertificateVerifyer : new AlwaysValidVerifyer(), base.CurrentRequest.CustomClientCredentialsProvider, hostNames)); this.Stream = protocol.Stream; } else { SslStream stream = new SslStream(this.Client.GetStream(), false, (sender, cert, chain, errors) => base.CurrentRequest.CallCustomCertificationValidator(cert, chain)); if (!stream.IsAuthenticated) { stream.AuthenticateAsClient(base.CurrentRequest.CurrentUri.Host); } this.Stream = stream; } } } }
private void Connect() { Uri uri = #if !BESTHTTP_DISABLE_PROXY CurrentRequest.HasProxy ? CurrentRequest.Proxy.Address : #endif CurrentRequest.CurrentUri; #region TCP Connection if (Client == null) { Client = new TcpClient(); } if (!Client.Connected) { Client.ConnectTimeout = CurrentRequest.ConnectTimeout; #if NETFX_CORE || (UNITY_WP8 && !UNITY_EDITOR) Client.UseHTTPSProtocol = #if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) !CurrentRequest.UseAlternateSSL && #endif HTTPProtocolFactory.IsSecureProtocol(uri); #endif if (HTTPManager.Logger.Level == Logger.Loglevels.All) { HTTPManager.Logger.Verbose("HTTPConnection", string.Format("'{0}' - Connecting to {1}:{2}", this.CurrentRequest.CurrentUri.ToString(), uri.Host, uri.Port.ToString())); } #if !NETFX_CORE && (!UNITY_WEBGL || UNITY_EDITOR) Client.SendBufferSize = HTTPManager.SendBufferSize; Client.ReceiveBufferSize = HTTPManager.ReceiveBufferSize; if (HTTPManager.Logger.Level == Logger.Loglevels.All) { HTTPManager.Logger.Verbose("HTTPConnection", string.Format("'{0}' - Buffer sizes - Send: {1} Receive: {2} Blocking: {3}", this.CurrentRequest.CurrentUri.ToString(), Client.SendBufferSize.ToString(), Client.ReceiveBufferSize.ToString(), Client.Client.Blocking.ToString())); } #endif Client.Connect(uri.Host, uri.Port); if (HTTPManager.Logger.Level <= Logger.Loglevels.Information) { HTTPManager.Logger.Information("HTTPConnection", "Connected to " + uri.Host + ":" + uri.Port.ToString()); } } else if (HTTPManager.Logger.Level <= Logger.Loglevels.Information) { HTTPManager.Logger.Information("HTTPConnection", "Already connected to " + uri.Host + ":" + uri.Port.ToString()); } #endregion StartTime = DateTime.UtcNow; if (Stream == null) { bool isSecure = HTTPProtocolFactory.IsSecureProtocol(CurrentRequest.CurrentUri); Stream = Client.GetStream(); /*if (Stream.CanTimeout) * Stream.ReadTimeout = Stream.WriteTimeout = (int)CurrentRequest.Timeout.TotalMilliseconds;*/ #if !BESTHTTP_DISABLE_PROXY #region Proxy Handling if (HasProxy && (!Proxy.IsTransparent || (isSecure && Proxy.NonTransparentForHTTPS))) { var outStream = new BinaryWriter(Stream); bool retry; do { // If we have to because of a authentication request, we will switch it to true retry = false; string connectStr = string.Format("CONNECT {0}:{1} HTTP/1.1", CurrentRequest.CurrentUri.Host, CurrentRequest.CurrentUri.Port); HTTPManager.Logger.Information("HTTPConnection", "Sending " + connectStr); outStream.SendAsASCII(connectStr); outStream.Write(HTTPRequest.EOL); outStream.SendAsASCII("Proxy-Connection: Keep-Alive"); outStream.Write(HTTPRequest.EOL); outStream.SendAsASCII("Connection: Keep-Alive"); outStream.Write(HTTPRequest.EOL); outStream.SendAsASCII(string.Format("Host: {0}:{1}", CurrentRequest.CurrentUri.Host, CurrentRequest.CurrentUri.Port)); outStream.Write(HTTPRequest.EOL); // Proxy Authentication if (HasProxy && Proxy.Credentials != null) { switch (Proxy.Credentials.Type) { case AuthenticationTypes.Basic: // With Basic authentication we don't want to wait for a challenge, we will send the hash with the first request outStream.Write(string.Format("Proxy-Authorization: {0}", string.Concat("Basic ", Convert.ToBase64String(Encoding.UTF8.GetBytes(Proxy.Credentials.UserName + ":" + Proxy.Credentials.Password)))).GetASCIIBytes()); outStream.Write(HTTPRequest.EOL); break; case AuthenticationTypes.Unknown: case AuthenticationTypes.Digest: var digest = DigestStore.Get(Proxy.Address); if (digest != null) { string authentication = digest.GenerateResponseHeader(CurrentRequest, Proxy.Credentials, true); if (!string.IsNullOrEmpty(authentication)) { string auth = string.Format("Proxy-Authorization: {0}", authentication); if (HTTPManager.Logger.Level <= Logger.Loglevels.Information) { HTTPManager.Logger.Information("HTTPConnection", "Sending proxy authorization header: " + auth); } outStream.Write(auth.GetASCIIBytes()); outStream.Write(HTTPRequest.EOL); } } break; } } outStream.Write(HTTPRequest.EOL); // Make sure to send all the wrote data to the wire outStream.Flush(); CurrentRequest.ProxyResponse = new HTTPResponse(CurrentRequest, Stream, false, false); // Read back the response of the proxy if (!CurrentRequest.ProxyResponse.Receive(-1, true)) { throw new Exception("Connection to the Proxy Server failed!"); } if (HTTPManager.Logger.Level <= Logger.Loglevels.Information) { HTTPManager.Logger.Information("HTTPConnection", "Proxy returned - status code: " + CurrentRequest.ProxyResponse.StatusCode + " message: " + CurrentRequest.ProxyResponse.Message + " Body: " + CurrentRequest.ProxyResponse.DataAsText); } switch (CurrentRequest.ProxyResponse.StatusCode) { // Proxy authentication required // http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.8 case 407: { string authHeader = DigestStore.FindBest(CurrentRequest.ProxyResponse.GetHeaderValues("proxy-authenticate")); if (!string.IsNullOrEmpty(authHeader)) { var digest = DigestStore.GetOrCreate(Proxy.Address); digest.ParseChallange(authHeader); if (Proxy.Credentials != null && digest.IsUriProtected(Proxy.Address) && (!CurrentRequest.HasHeader("Proxy-Authorization") || digest.Stale)) { retry = true; } } break; } default: if (!CurrentRequest.ProxyResponse.IsSuccess) { throw new Exception(string.Format("Proxy returned Status Code: \"{0}\", Message: \"{1}\" and Response: {2}", CurrentRequest.ProxyResponse.StatusCode, CurrentRequest.ProxyResponse.Message, CurrentRequest.ProxyResponse.DataAsText)); } break; } } while (retry); } #endregion #endif // #if !BESTHTTP_DISABLE_PROXY // We have to use CurrentRequest.CurrentUri here, because uri can be a proxy uri with a different protocol if (isSecure) { // Under the new experimental runtime there's a bug in the Socket.Send implementation that can cause a // connection when the TLS protocol is used. #if !NETFX_CORE && (!UNITY_WEBGL || UNITY_EDITOR) && NET_4_6 //Client.SendBufferSize = 0; #endif #region SSL Upgrade #if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) if (CurrentRequest.UseAlternateSSL) { var handler = new TlsClientProtocol(Client.GetStream(), new Org.BouncyCastle.Security.SecureRandom()); // http://tools.ietf.org/html/rfc3546#section-3.1 // -It is RECOMMENDED that clients include an extension of type "server_name" in the client hello whenever they locate a server by a supported name type. // -Literal IPv4 and IPv6 addresses are not permitted in "HostName". // User-defined list has a higher priority List <string> hostNames = CurrentRequest.CustomTLSServerNameList; // If there's no user defined one and the host isn't an IP address, add the default one if ((hostNames == null || hostNames.Count == 0) && !CurrentRequest.CurrentUri.IsHostIsAnIPAddress()) { hostNames = new List <string>(1); hostNames.Add(CurrentRequest.CurrentUri.Host); } handler.Connect(new LegacyTlsClient(CurrentRequest.CurrentUri, CurrentRequest.CustomCertificateVerifyer == null ? new AlwaysValidVerifyer() : CurrentRequest.CustomCertificateVerifyer, CurrentRequest.CustomClientCredentialsProvider, hostNames)); Stream = handler.Stream; } else #endif { #if !NETFX_CORE && !UNITY_WP8 SslStream sslStream = new SslStream(Client.GetStream(), false, (sender, cert, chain, errors) => { return(CurrentRequest.CallCustomCertificationValidator(cert, chain)); }); if (!sslStream.IsAuthenticated) { sslStream.AuthenticateAsClient(CurrentRequest.CurrentUri.Host); } Stream = sslStream; #else Stream = Client.GetStream(); #endif } #endregion } } }
public void RunTest(TlsTestConfig config) { CheckTlsVersion(config.clientMinimumVersion); CheckTlsVersion(config.clientOfferVersion); CheckTlsVersion(config.serverMaximumVersion); CheckTlsVersion(config.serverMinimumVersion); SecureRandom secureRandom = new SecureRandom(); PipedStream clientPipe = new PipedStream(); PipedStream serverPipe = new PipedStream(clientPipe); NetworkStream clientNet = new NetworkStream(clientPipe); NetworkStream serverNet = new NetworkStream(serverPipe); TlsClientProtocol clientProtocol = new TlsClientProtocol(clientNet, secureRandom); TlsServerProtocol serverProtocol = new TlsServerProtocol(serverNet, secureRandom); TlsTestClientImpl clientImpl = new TlsTestClientImpl(config); TlsTestServerImpl serverImpl = new TlsTestServerImpl(config); Server server = new Server(this, serverProtocol, serverImpl); Thread serverThread = new Thread(new ThreadStart(server.Run)); serverThread.Start(); Exception caught = null; try { clientProtocol.Connect(clientImpl); // NOTE: Because we write-all before we read-any, this length can't be more than the pipe capacity int length = 1000; byte[] data = new byte[length]; secureRandom.NextBytes(data); Stream output = clientProtocol.Stream; output.Write(data, 0, data.Length); byte[] echo = new byte[data.Length]; int count = Streams.ReadFully(clientProtocol.Stream, echo); Assert.AreEqual(count, data.Length); Assert.IsTrue(Arrays.AreEqual(data, echo)); output.Close(); } catch (Exception e) { caught = e; LogException(caught); } server.AllowExit(); serverThread.Join(); Assert.IsTrue(clientNet.IsClosed, "Client Stream not closed"); Assert.IsTrue(serverNet.IsClosed, "Server Stream not closed"); Assert.AreEqual(config.expectFatalAlertConnectionEnd, clientImpl.FirstFatalAlertConnectionEnd, "Client fatal alert connection end"); Assert.AreEqual(config.expectFatalAlertConnectionEnd, serverImpl.FirstFatalAlertConnectionEnd, "Server fatal alert connection end"); Assert.AreEqual(config.expectFatalAlertDescription, clientImpl.FirstFatalAlertDescription, "Client fatal alert description"); Assert.AreEqual(config.expectFatalAlertDescription, serverImpl.FirstFatalAlertDescription, "Server fatal alert description"); if (config.expectFatalAlertConnectionEnd == -1) { Assert.IsNull(caught, "Unexpected client exception"); Assert.IsNull(server.mCaught, "Unexpected server exception"); } }