using System; using System.Text; using Best.HTTP.Hosts.Connections; using Best.HTTP.HostSetting; using Best.HTTP.Request.Authentication; using Best.HTTP.Shared; namespace Best.HTTP.Request.Settings { /// /// Represents settings related to using a proxy server for HTTP requests. /// public class ProxySettings { /// /// Checks if there is a proxy configured for the given URI. /// /// The URI to check for proxy usage. /// true if a proxy is configured and should be used for the URI; otherwise, false. public bool HasProxyFor(Uri uri) => Proxy != null && Proxy.UseProxyForAddress(uri); /// /// Gets or sets the proxy object used for the request. /// public Proxies.Proxy Proxy { get; set; } = HTTPManager.Proxy; /// /// Sets up the HTTP request for passing through a proxy server. /// /// The HTTP request to set up. public void SetupRequest(HTTPRequest request) { var currentUri = request.CurrentUri; bool tryToKeepAlive = HTTPManager.PerHostSettings.Get(currentUri.Host) .HTTP1ConnectionSettings .TryToReuseConnections; if (!HTTPProtocolFactory.IsSecureProtocol(currentUri) && this.HasProxyFor(currentUri) && !request.HasHeader("Proxy-Connection")) request.AddHeader("Proxy-Connection", tryToKeepAlive ? "Keep-Alive" : "Close"); // Proxy Authentication if (!HTTPProtocolFactory.IsSecureProtocol(currentUri) && HasProxyFor(currentUri) && this.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 var token = Convert.ToBase64String(Encoding.UTF8.GetBytes(this.Proxy.Credentials.UserName + ":" + this.Proxy.Credentials.Password)); request.SetHeader("Proxy-Authorization", $"Basic {token}"); break; case AuthenticationTypes.Unknown: case AuthenticationTypes.Digest: var digest = DigestStore.Get(this.Proxy.Address); if (digest != null) { string authentication = digest.GenerateResponseHeader(this.Proxy.Credentials, false, request.MethodType, currentUri); if (!string.IsNullOrEmpty(authentication)) request.SetHeader("Proxy-Authorization", authentication); } break; } } } /// /// Handles the proxy's response with status code 407. /// /// The HTTP request that received a 407 response. /// true to resend the request through the proxy; otherwise, false. public bool Handle407(HTTPRequest request) { if (this.Proxy == null) return false; return this.Proxy.SetupRequest(request); } /// /// Adds the proxy address to a hash for the given request URI. /// /// The request URI for which the proxy address is added to the hash. /// The hash to which the proxy address is added. public void AddToHash(Uri requestUri, ref UnityEngine.Hash128 hash) { if (HasProxyFor(requestUri)) HostKey.Append(this.Proxy.Address, ref hash); } public override string ToString() { return this.Proxy?.Address?.ToString(); } } }