Files
ichni_Official/Packages/com.tivadar.best.http/Runtime/HTTP/Hosts/Manager/HostKey.cs
2026-06-15 18:18:16 +08:00

135 lines
5.3 KiB
C#

using System;
using System.Collections.Generic;
using Best.HTTP.Request.Settings;
using UnityEngine;
namespace Best.HTTP.HostSetting
{
/// <summary>
/// The <see cref="HostKey"/> struct represents a unique key for identifying hosts based on their <see cref="System.Uri"/> and <see cref="ProxySettings"/>.
/// </summary>
/// <remarks>
/// <para>
/// The <see cref="HostKey"/> struct is designed to uniquely identify a host based on its URI (Uniform Resource Identifier) and optional proxy settings.
/// It provides a way to create, compare, and hash host keys, enabling efficient host variant management in the <see cref="HostManager"/>.
/// </para>
/// <para>
/// Key features of the <see cref="HostKey"/> struct include:
/// </para>
/// <list type="bullet">
/// <item>
/// <term>Uniqueness</term>
/// <description>
/// Each <see cref="HostKey"/> is guaranteed to be unique for a specific host, considering both the URI and proxy settings.
/// </description>
/// </item>
/// <item>
/// <term>Hashing</term>
/// <description>
/// The struct provides a method to calculate a hash code for a <see cref="HostKey"/>, making it suitable for use as a dictionary key.
/// </description>
/// </item>
/// <item>
/// <term>Creation</term>
/// <description>
/// You can create a <see cref="HostKey"/> instance from a <see cref="System.Uri"/> and optional <see cref="ProxySettings"/>.
/// </description>
/// </item>
/// </list>
/// <para>
/// Usage of the <see cref="HostKey"/> struct is typically handled internally by the BestHTTP library to manage unique hosts and optimize resource usage.
/// Developers can use it when dealing with host-specific operations or customization of the library's behavior.
/// </para>
/// </remarks>
public readonly struct HostKey
{
/// <summary>
/// Gets the URI (Uniform Resource Identifier) associated with the host.
/// </summary>
public readonly Uri Uri;
/// <summary>
/// Gets the proxy settings associated with the host.
/// </summary>
public readonly ProxySettings Proxy;
/// <summary>
/// Gets the unique hash key for the host.
/// </summary>
public readonly Hash128 Key;
/// <summary>
/// Gets the host name from the URI or "file" if the URI is a file URI.
/// </summary>
public string Host { get => !this.Uri.IsFile ? this.Uri.Host : "file"; }
/// <summary>
/// Initializes a new instance of the <see cref="HostKey"/> struct with the specified URI and proxy settings.
/// </summary>
/// <param name="uri">The URI of the host.</param>
/// <param name="proxy">The proxy settings associated with the host, or <c>null</c> if no proxy is used.</param>
public HostKey(Uri uri, ProxySettings proxy)
{
this.Uri = uri;
this.Proxy = proxy;
this.Key = CalculateHash(uri, proxy);
}
public override bool Equals(object obj) => obj switch
{
HostKey hostKey => hostKey.Equals(this),
_ => false
};
public bool Equals(HostKey hostKey) => this.Key.Equals(hostKey.Key);
public override int GetHashCode() => this.Key.GetHashCode();
public override string ToString() => $"{{\"Uri\":\"{this.Uri.GetComponents(UriComponents.SchemeAndServer, UriFormat.Unescaped)}\", \"Proxy\": {this.Proxy.ToString()}, \"Key\": {this.Key.ToString()}}}";
private static Hash128 CalculateHash(Uri uri, ProxySettings proxy)
{
Hash128 hash = new Hash128();
Append(uri, ref hash);
proxy?.AddToHash(uri, ref hash);
return hash;
}
internal static void Append(Uri uri, ref Hash128 hash)
{
if (uri != null)
{
hash.Append(uri.Scheme);
hash.Append(uri.Host);
hash.Append(uri.Port);
}
}
/// <summary>
/// Creates a <see cref="HostKey"/> instance from an HTTP request.
/// </summary>
/// <param name="request">The HTTP request from which to extract the current URI and proxy settings.</param>
/// <returns>A <see cref="HostKey"/> representing the host of the HTTP request.</returns>
public static HostKey From(HTTPRequest request) => new HostKey(request.CurrentUri, request.ProxySettings);
/// <summary>
/// Creates a <see cref="HostKey"/> instance from a URI and proxy settings.
/// </summary>
/// <param name="uri">The URI of the host.</param>
/// <param name="proxy">The proxy settings associated with the host, or <c>null</c> if no proxy is used.</param>
/// <returns>A <see cref="HostKey"/> representing the host with the given URI and proxy settings.</returns>
public static HostKey From(Uri uri, ProxySettings proxy) => new HostKey(uri, proxy);
}
internal sealed class HostKeyEqualityComparer : IEqualityComparer<HostKey>
{
public bool Equals(HostKey x, HostKey y) => x.Equals(y);
public int GetHashCode(HostKey obj) => obj.GetHashCode();
}
}