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 bool Receive() { SupportedProtocols protocol = CurrentRequest.ProtocolHandler == SupportedProtocols.Unknown ? HTTPProtocolFactory.GetProtocolFromUri(CurrentRequest.CurrentUri) : CurrentRequest.ProtocolHandler; if (HTTPManager.Logger.Level == Logger.Loglevels.All) { HTTPManager.Logger.Verbose("HTTPConnection", string.Format("{0} - Receive - protocol: {1}", this.CurrentRequest.CurrentUri.ToString(), protocol.ToString())); } CurrentRequest.Response = HTTPProtocolFactory.Get(protocol, CurrentRequest, Stream, CurrentRequest.UseStreaming, false); if (!CurrentRequest.Response.Receive()) { if (HTTPManager.Logger.Level == Logger.Loglevels.All) { HTTPManager.Logger.Verbose("HTTPConnection", string.Format("{0} - Receive - Failed! Response will be null, returning with false.", this.CurrentRequest.CurrentUri.ToString())); } CurrentRequest.Response = null; return(false); } if (CurrentRequest.Response.StatusCode == 304 #if !BESTHTTP_DISABLE_CACHING && !CurrentRequest.DisableCache #endif ) { #if !BESTHTTP_DISABLE_CACHING if (CurrentRequest.IsRedirected) { if (!LoadFromCache(CurrentRequest.RedirectUri)) { LoadFromCache(CurrentRequest.Uri); } } else { LoadFromCache(CurrentRequest.Uri); } #else return(false); #endif } if (HTTPManager.Logger.Level == Logger.Loglevels.All) { HTTPManager.Logger.Verbose("HTTPConnection", string.Format("{0} - Receive - Finished Successfully!", this.CurrentRequest.CurrentUri.ToString())); } return(true); }
void OnResponse(int httpStatus, byte[] buffer) { try { using (MemoryStream ms = new MemoryStream()) { Stream = ms; XHR_GetStatusLine(NativeId, OnBufferCallback); XHR_GetResponseHeaders(NativeId, OnBufferCallback); if (buffer != null && buffer.Length > 0) { ms.Write(buffer, 0, buffer.Length); } ms.Seek(0L, SeekOrigin.Begin); SupportedProtocols protocol = CurrentRequest.ProtocolHandler == SupportedProtocols.Unknown ? HTTPProtocolFactory.GetProtocolFromUri(CurrentRequest.CurrentUri) : CurrentRequest.ProtocolHandler; CurrentRequest.Response = HTTPProtocolFactory.Get(protocol, CurrentRequest, ms, CurrentRequest.UseStreaming, false); CurrentRequest.Response.Receive(buffer != null && buffer.Length > 0 ? (int)buffer.Length : -1, true); if (CurrentRequest.IsCookiesEnabled) { BestHTTP.Cookies.CookieJar.Set(CurrentRequest.Response); } } } catch (Exception e) { HTTPManager.Logger.Exception(this.NativeId + " WebGLConnection", "OnResponse", e); if (CurrentRequest != null) { // Something gone bad, Response must be null! CurrentRequest.Response = null; switch (State) { case HTTPConnectionStates.AbortRequested: CurrentRequest.State = HTTPRequestStates.Aborted; break; case HTTPConnectionStates.TimedOut: CurrentRequest.State = HTTPRequestStates.TimedOut; break; default: CurrentRequest.Exception = e; CurrentRequest.State = HTTPRequestStates.Error; break; } } } finally { Connections.Remove(NativeId); Stream = null; if (CurrentRequest != null) { lock (HTTPManager.Locker) { State = HTTPConnectionStates.Closed; if (CurrentRequest.State == HTTPRequestStates.Processing) { if (CurrentRequest.Response != null) { CurrentRequest.State = HTTPRequestStates.Finished; } else { CurrentRequest.State = HTTPRequestStates.Error; } } } } LastProcessTime = DateTime.UtcNow; if (OnConnectionRecycled != null) { RecycleNow(); } XHR_Release(NativeId); } }
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 } } }
/// <summary> /// Writes out the Headers to the stream. /// </summary> /// <param name="stream"></param> private void SendHeaders(BinaryWriter stream) { if (!HasHeader("Host")) { SetHeader("Host", CurrentUri.Host); } if (IsRedirected && !HasHeader("Referer")) { AddHeader("Referer", Uri.ToString()); } if (!HasHeader("Accept-Encoding")) { AddHeader("Accept-Encoding", "gzip, identity"); } if (HasProxy && !HasHeader("Proxy-Connection")) { AddHeader("Proxy-Connection", IsKeepAlive ? "Keep-Alive" : "Close"); } if (!HasHeader("Connection")) { AddHeader("Connection", IsKeepAlive ? "Keep-Alive, TE" : "Close, TE"); } if (!HasHeader("TE")) { AddHeader("TE", "identity"); } if (!HasHeader("User-Agent")) { AddHeader("User-Agent", "BestHTTP"); } byte[] entityBody = GetEntityBody(); int contentLength = entityBody != null ? entityBody.Length : 0; if (RawData == null && (FormImpl != null || (FieldCollector != null && !FieldCollector.IsEmpty))) { SelectFormImplementation(); if (FormImpl != null) { FormImpl.PrepareRequest(this); } } if (!HasHeader("Content-Length") && contentLength != 0) { AddHeader("Content-Length", contentLength.ToString()); } // 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 SetHeader("Proxy-Authorization", string.Concat("Basic ", Convert.ToBase64String(Encoding.UTF8.GetBytes(Credentials.UserName + ":" + Credentials.Password)))); break; case AuthenticationTypes.Unknown: case AuthenticationTypes.Digest: var digest = DigestStore.Get(Proxy.Address); if (digest != null) { string authentication = digest.GenerateResponseHeader(this, Proxy.Credentials); if (!string.IsNullOrEmpty(authentication)) { SetHeader("Proxy-Authorization", authentication); } } break; } } // Server authentication if (Credentials != null) { switch (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 SetHeader("Authorization", string.Concat("Basic ", Convert.ToBase64String(Encoding.UTF8.GetBytes(Credentials.UserName + ":" + Credentials.Password)))); break; case AuthenticationTypes.Unknown: case AuthenticationTypes.Digest: var digest = DigestStore.Get(this.CurrentUri); if (digest != null) { string authentication = digest.GenerateResponseHeader(this, Credentials); if (!string.IsNullOrEmpty(authentication)) { SetHeader("Authorization", authentication); } } break; } } // Cookies if (IsCookiesEnabled) { var cookies = CookieJar.Get(CurrentUri); // http://tools.ietf.org/html/rfc6265#section-5.4 // -When the user agent generates an HTTP request, the user agent MUST NOT attach more than one Cookie header field. if (cookies != null && cookies.Count > 0) { // TODO: // 2. The user agent SHOULD sort the cookie-list in the following order: // * Cookies with longer paths are listed before cookies with shorter paths. // * Among cookies that have equal-length path fields, cookies with earlier creation-times are listed before cookies with later creation-times. bool first = true; string cookieStr = string.Empty; foreach (var cookie in cookies) { if ((!cookie.IsSecure || (cookie.IsSecure && HTTPProtocolFactory.IsSecureProtocol(CurrentUri))) && (!cookie.IsHttpOnly || (cookie.IsHttpOnly && HTTPProtocolFactory.GetProtocolFromUri(CurrentUri) == SupportedProtocols.HTTP))) { if (!first) { cookieStr += "; "; } else { first = false; } cookieStr += cookie.ToString(); // 3. Update the last-access-time of each cookie in the cookie-list to the current date and time. cookie.LastAccess = DateTime.UtcNow; } } SetHeader("Cookie", cookieStr); } } // Write out the headers to the stream foreach (var kvp in Headers) { byte[] headerName = string.Concat(kvp.Key, ": ").GetASCIIBytes(); for (int i = 0; i < kvp.Value.Count; ++i) { stream.Write(headerName); stream.Write(kvp.Value[i].GetASCIIBytes()); stream.Write(EOL); } } }
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 string address = HTTPManager.GetHostCache(uri.Host); if (!string.IsNullOrEmpty(address)) { Client.Connect(address, uri.Port); } else { Client.Connect(uri.Host, uri.Port); if (Client.IsConnected()) { System.Net.IPEndPoint end_point = Client.Client.RemoteEndPoint as System.Net.IPEndPoint; address = end_point.Address.ToString(); HTTPManager.AddHostCache(uri.Host, address); } } } else { // NGUIDebug.print("Client.Connected ========>" + Client.Connected); } 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 = !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 bool Receive() { SupportedProtocols protocol = (base.CurrentRequest.ProtocolHandler != SupportedProtocols.Unknown) ? base.CurrentRequest.ProtocolHandler : HTTPProtocolFactory.GetProtocolFromUri(base.CurrentRequest.CurrentUri); if (HTTPManager.Logger.Level == Loglevels.All) { HTTPManager.Logger.Verbose("HTTPConnection", $"{base.CurrentRequest.CurrentUri.ToString()} - Receive - protocol: {protocol.ToString()}"); } base.CurrentRequest.Response = HTTPProtocolFactory.Get(protocol, base.CurrentRequest, this.Stream, base.CurrentRequest.UseStreaming, false); if (!base.CurrentRequest.Response.Receive(-1, true)) { if (HTTPManager.Logger.Level == Loglevels.All) { HTTPManager.Logger.Verbose("HTTPConnection", $"{base.CurrentRequest.CurrentUri.ToString()} - Receive - Failed! Response will be null, returning with false."); } base.CurrentRequest.Response = null; return(false); } if ((base.CurrentRequest.Response.StatusCode == 0x130) && !base.CurrentRequest.DisableCache) { if (base.CurrentRequest.IsRedirected) { if (!this.LoadFromCache(base.CurrentRequest.RedirectUri)) { this.LoadFromCache(base.CurrentRequest.Uri); } } else { this.LoadFromCache(base.CurrentRequest.Uri); } } if (HTTPManager.Logger.Level == Loglevels.All) { HTTPManager.Logger.Verbose("HTTPConnection", $"{base.CurrentRequest.CurrentUri.ToString()} - Receive - Finished Successfully!"); } return(true); }
private bool Receive() { SupportedProtocols protocol = CurrentRequest.ProtocolHandler == SupportedProtocols.Unknown ? HTTPProtocolFactory.GetProtocolFromUri(CurrentRequest.CurrentUri) : CurrentRequest.ProtocolHandler; if (HTTPManager.Logger.Level == Logger.Loglevels.All) { HTTPManager.Logger.Verbose("HTTPConnection", string.Format("{0} - Receive - protocol: {1}", this.CurrentRequest.CurrentUri.ToString(), protocol.ToString())); } CurrentRequest.Response = HTTPProtocolFactory.Get(protocol, CurrentRequest, Stream, CurrentRequest.UseStreaming, false); if (!CurrentRequest.Response.Receive()) { if (HTTPManager.Logger.Level == Logger.Loglevels.All) { HTTPManager.Logger.Verbose("HTTPConnection", string.Format("{0} - Receive - Failed! Response will be null, returning with false.", this.CurrentRequest.CurrentUri.ToString())); } CurrentRequest.Response = null; return(false); } // We didn't check HTTPManager.IsCachingDisabled's value on purpose. (sending out a request with conditional get then change IsCachingDisabled to true may produce undefined behavior) if (CurrentRequest.Response.StatusCode == 304) { #if !BESTHTTP_DISABLE_CACHING && (!UNITY_WEBGL || UNITY_EDITOR) if (CurrentRequest.IsRedirected) { if (!LoadFromCache(CurrentRequest.RedirectUri)) { LoadFromCache(CurrentRequest.Uri); } } else { LoadFromCache(CurrentRequest.Uri); } #else return(false); #endif } if (HTTPManager.Logger.Level == Logger.Loglevels.All) { HTTPManager.Logger.Verbose("HTTPConnection", string.Format("{0} - Receive - Finished Successfully!", this.CurrentRequest.CurrentUri.ToString())); } return(true); }
internal override void Connect(Stream stream, HTTPRequest request) { bool isSecure = HTTPProtocolFactory.IsSecureProtocol(request.CurrentUri); if (!this.IsTransparent || (isSecure && this.NonTransparentForHTTPS)) { using (var bufferedStream = new WriteOnlyBufferedStream(stream, HTTPRequest.UploadChunkSize)) using (var outStream = new BinaryWriter(bufferedStream, Encoding.UTF8)) { 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", request.CurrentUri.Host, request.CurrentUri.Port.ToString()); HTTPManager.Logger.Information("HTTPProxy", "Sending " + connectStr, request.Context); 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}", request.CurrentUri.Host, request.CurrentUri.Port.ToString())); outStream.Write(HTTPRequest.EOL); // Proxy Authentication if (this.Credentials != null) { switch (this.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(this.Credentials.UserName + ":" + this.Credentials.Password)))).GetASCIIBytes()); outStream.Write(HTTPRequest.EOL); break; case AuthenticationTypes.Unknown: case AuthenticationTypes.Digest: var digest = DigestStore.Get(this.Address); if (digest != null) { string authentication = digest.GenerateResponseHeader(request, this.Credentials, true); if (!string.IsNullOrEmpty(authentication)) { string auth = string.Format("Proxy-Authorization: {0}", authentication); if (HTTPManager.Logger.Level <= Logger.Loglevels.Information) { HTTPManager.Logger.Information("HTTPProxy", "Sending proxy authorization header: " + auth, request.Context); } var bytes = auth.GetASCIIBytes(); outStream.Write(bytes); outStream.Write(HTTPRequest.EOL); BufferPool.Release(bytes); } } break; } } outStream.Write(HTTPRequest.EOL); // Make sure to send all the wrote data to the wire outStream.Flush(); request.ProxyResponse = new HTTPResponse(request, stream, false, false); // Read back the response of the proxy if (!request.ProxyResponse.Receive(-1, true)) { throw new Exception("Connection to the Proxy Server failed!"); } if (HTTPManager.Logger.Level <= Logger.Loglevels.Information) { HTTPManager.Logger.Information("HTTPProxy", "Proxy returned - status code: " + request.ProxyResponse.StatusCode + " message: " + request.ProxyResponse.Message + " Body: " + request.ProxyResponse.DataAsText, request.Context); } switch (request.ProxyResponse.StatusCode) { // Proxy authentication required // http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.8 case 407: { string authHeader = DigestStore.FindBest(request.ProxyResponse.GetHeaderValues("proxy-authenticate")); if (!string.IsNullOrEmpty(authHeader)) { var digest = DigestStore.GetOrCreate(this.Address); digest.ParseChallange(authHeader); if (this.Credentials != null && digest.IsUriProtected(this.Address) && (!request.HasHeader("Proxy-Authorization") || digest.Stale)) { retry = true; } } if (!retry) { throw new Exception(string.Format("Can't authenticate Proxy! Status Code: \"{0}\", Message: \"{1}\" and Response: {2}", request.ProxyResponse.StatusCode, request.ProxyResponse.Message, request.ProxyResponse.DataAsText)); } break; } default: if (!request.ProxyResponse.IsSuccess) { throw new Exception(string.Format("Proxy returned Status Code: \"{0}\", Message: \"{1}\" and Response: {2}", request.ProxyResponse.StatusCode, request.ProxyResponse.Message, request.ProxyResponse.DataAsText)); } break; } } while (retry); }// using outstream } }
private bool Receive() { SupportedProtocols protocol = CurrentRequest.ProtocolHandler == SupportedProtocols.Unknown ? HTTPProtocolFactory.GetProtocolFromUri(CurrentRequest.CurrentUri) : CurrentRequest.ProtocolHandler; CurrentRequest.Response = HTTPProtocolFactory.Get(protocol, CurrentRequest, Stream, CurrentRequest.UseStreaming, false); if (!CurrentRequest.Response.Receive()) { CurrentRequest.Response = null; return(false); } // We didn't check HTTPManager.IsCachingDisabled's value on purpose. (sending out a request with conditional get then change IsCachingDisabled to true may produce undefined behavior) if (CurrentRequest.Response.StatusCode == 304) { #if !BESTHTTP_DISABLE_CACHING && (!UNITY_WEBGL || UNITY_EDITOR) if (CurrentRequest.IsRedirected) { if (!LoadFromCache(CurrentRequest.RedirectUri)) { LoadFromCache(CurrentRequest.Uri); } } else { LoadFromCache(CurrentRequest.Uri); } #else return(false); #endif } return(true); }