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();
}
}
}