HostSettings.cs 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Net.Security;
  4. using System.Security.Cryptography.X509Certificates;
  5. using Best.HTTP.Hosts.Connections;
  6. using Best.HTTP.HostSetting;
  7. using Best.HTTP.Shared.Extensions;
  8. using Best.HTTP.Shared.Logger;
  9. using Best.HTTP.Shared.PlatformSupport.Network.Tcp;
  10. namespace Best.HTTP.Hosts.Settings
  11. {
  12. #if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
  13. /// <summary>
  14. /// Delegate for creating a TLS 1.3 client instance.
  15. /// </summary>
  16. /// <param name="uri">The URI of the request.</param>
  17. /// <param name="protocols">A list of supported TLS ALPN protocols.</param>
  18. /// <param name="context">The logging context for the operation.</param>
  19. /// <returns>A TLS 1.3 client instance.</returns>
  20. public delegate Best.HTTP.Shared.TLS.AbstractTls13Client TlsClientFactoryDelegate(Uri uri, List<SecureProtocol.Org.BouncyCastle.Tls.ProtocolName> protocols, LoggingContext context);
  21. #endif
  22. /// <summary>
  23. /// Settings for HTTP requests.
  24. /// </summary>
  25. public class HTTRequestSettings
  26. {
  27. /// <summary>
  28. /// The timeout for establishing a connection.
  29. /// </summary>
  30. public TimeSpan ConnectTimeout = TimeSpan.FromSeconds(20);
  31. /// <summary>
  32. /// The maximum time allowed for the request to complete.
  33. /// </summary>
  34. public TimeSpan RequestTimeout = TimeSpan.MaxValue;
  35. }
  36. /// <summary>
  37. /// Settings for HTTP/1 connections.
  38. /// </summary>
  39. public class HTTP1ConnectionSettings
  40. {
  41. /// <summary>
  42. /// Indicates whether the connection should be open after receiving the response.
  43. /// </summary>
  44. /// <remarks>
  45. /// If set to <c>true</c>, internal TCP connections will be reused whenever possible.
  46. /// If making rare requests to the server, it's recommended to change this to <c>false</c>.
  47. /// </remarks>
  48. public bool TryToReuseConnections = true;
  49. /// <summary>
  50. /// The maximum time a connection can remain idle before being closed.
  51. /// </summary>
  52. public TimeSpan MaxConnectionIdleTime = TimeSpan.FromSeconds(20);
  53. /// <summary>
  54. /// Indicates whether the upload thread should use a <see href="https://learn.microsoft.com/en-us/dotnet/api/system.threading.threadpool">ThreadPool</see> thread instead of creating and using a <see href="https://learn.microsoft.com/en-us/dotnet/api/system.threading.thread">Thread</see>.
  55. /// </summary>
  56. /// <remarks>The plugin tries to use ThreadPool threads for known short-living uploads like requests without upload body. With <c>ForceUseThreadPool</c> all HTTP/1 requests, including long uploads or downloads can be forced to use ThreadPool threads.</remarks>
  57. public bool ForceUseThreadPool;
  58. }
  59. #if !UNITY_WEBGL || UNITY_EDITOR
  60. /// <summary>
  61. /// Delegate for selecting a client certificate.
  62. /// </summary>
  63. /// <param name="targetHost">The target host.</param>
  64. /// <param name="localCertificates">A collection of local certificates.</param>
  65. /// <param name="remoteCertificate">The remote certificate.</param>
  66. /// <param name="acceptableIssuers">An array of acceptable certificate issuers.</param>
  67. /// <returns>The selected X.509 certificate.</returns>
  68. public delegate X509Certificate ClientCertificateSelector(string targetHost, X509CertificateCollection localCertificates, X509Certificate remoteCertificate, string[] acceptableIssuers);
  69. /// <summary>
  70. /// Available TLS handlers.
  71. /// </summary>
  72. public enum TLSHandlers
  73. {
  74. #if !BESTHTTP_DISABLE_ALTERNATE_SSL
  75. /// <summary>
  76. /// To use the 3rd party BouncyCastle implementation.
  77. /// </summary>
  78. BouncyCastle = 0x00,
  79. #endif
  80. /// <summary>
  81. /// To use .net's SslStream.
  82. /// </summary>
  83. Framework = 0x01
  84. }
  85. /// <summary>
  86. /// Settings for Bouncy Castle TLS.
  87. /// </summary>
  88. public class BouncyCastleSettings
  89. {
  90. #if !BESTHTTP_DISABLE_ALTERNATE_SSL
  91. /// <summary>
  92. /// Delegate for creating a TLS 1.3 client instance using Bouncy Castle.
  93. /// </summary>
  94. public TlsClientFactoryDelegate TlsClientFactory;
  95. /// <summary>
  96. /// The default TLS 1.3 client factory.
  97. /// </summary>
  98. /// <param name="uri">The URI of the request.</param>
  99. /// <param name="protocols">A list of supported TLS ALPN protocols.</param>
  100. /// <param name="context">The logging context for the operation.</param>
  101. /// <returns>A TLS 1.3 client instance.</returns>
  102. public static Best.HTTP.Shared.TLS.AbstractTls13Client DefaultTlsClientFactory(Uri uri, List<Best.HTTP.SecureProtocol.Org.BouncyCastle.Tls.ProtocolName> protocols, LoggingContext context)
  103. {
  104. // http://tools.ietf.org/html/rfc3546#section-3.1
  105. // -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.
  106. // -Literal IPv4 and IPv6 addresses are not permitted in "HostName".
  107. // User-defined list has a higher priority
  108. List<Best.HTTP.SecureProtocol.Org.BouncyCastle.Tls.ServerName> hostNames = null;
  109. // If there's no user defined one and the host isn't an IP address, add the default one
  110. if (!uri.IsHostIsAnIPAddress())
  111. {
  112. hostNames = new List<Best.HTTP.SecureProtocol.Org.BouncyCastle.Tls.ServerName>(1);
  113. hostNames.Add(new Best.HTTP.SecureProtocol.Org.BouncyCastle.Tls.ServerName(0, System.Text.Encoding.UTF8.GetBytes(uri.Host)));
  114. }
  115. return new Best.HTTP.Shared.TLS.DefaultTls13Client(hostNames, protocols, context);
  116. }
  117. #endif
  118. }
  119. /// <summary>
  120. /// Settings for .NET's SslStream based handler.
  121. /// </summary>
  122. public class FrameworkTLSSettings
  123. {
  124. /// <summary>
  125. /// The supported TLS versions.
  126. /// </summary>
  127. public System.Security.Authentication.SslProtocols TlsVersions = System.Security.Authentication.SslProtocols.Tls12;
  128. /// <summary>
  129. /// Indicates whether to check certificate revocation.
  130. /// </summary>
  131. public bool CheckCertificateRevocation = true;
  132. /// <summary>
  133. /// The default certification validator.
  134. /// </summary>
  135. public static Func<string, X509Certificate, X509Chain, SslPolicyErrors, bool> DefaultCertificationValidator = (host, certificate, chain, sslPolicyErrors) => true;
  136. public Func<string, X509Certificate, X509Chain, SslPolicyErrors, bool> CertificationValidator = DefaultCertificationValidator;
  137. /// <summary>
  138. /// Delegate for providing a client certificate.
  139. /// </summary>
  140. public ClientCertificateSelector ClientCertificationProvider;
  141. }
  142. /// <summary>
  143. /// Settings for TLS.
  144. /// </summary>
  145. public class TLSSettings
  146. {
  147. /// <summary>
  148. /// The selected TLS handler.
  149. /// </summary>
  150. public TLSHandlers TLSHandler
  151. #if !BESTHTTP_DISABLE_ALTERNATE_SSL
  152. = TLSHandlers.BouncyCastle;
  153. #else
  154. = TLSHandlers.Framework;
  155. #endif
  156. /// <summary>
  157. /// Settings for Bouncy Castle.
  158. /// </summary>
  159. public BouncyCastleSettings BouncyCastleSettings = new BouncyCastleSettings();
  160. /// <summary>
  161. /// .NET's SslStream settings.
  162. /// </summary>
  163. public FrameworkTLSSettings FrameworkTLSSettings = new FrameworkTLSSettings();
  164. }
  165. #endif
  166. /// <summary>
  167. /// Settings for <see cref="HostSetting.HostVariant"/>s.
  168. /// </summary>
  169. public class HostVariantSettings
  170. {
  171. /// <summary>
  172. /// The maximum number of connections allowed per host variant.
  173. /// </summary>
  174. public int MaxConnectionPerVariant = 6;
  175. /// <summary>
  176. /// Factor used when calculations are made whether to open a new connection to the server or not.
  177. /// </summary>
  178. /// <remarks>
  179. /// It has an effect on HTTP/2 connections only.
  180. /// <para>Higher values (gte <c>1.0f</c>) delay, lower values (lte <c>1.0f</c>) bring forward creation of new connections.</para>
  181. /// </remarks>
  182. public float MaxAssignedRequestsFactor = 1.2f;
  183. /// <summary>
  184. /// Factory function to generate HostVariant or descendent instances.
  185. /// </summary>
  186. public Func<HostVariantSettings, HostKey, HostVariant> VariantFactory = (settings, key) => new HostVariant(key);
  187. /// <summary>
  188. /// Factory function to generate custom connection implementations.
  189. /// </summary>
  190. public Func<HostVariantSettings, HostVariant, ConnectionBase> ConnectionFactory;
  191. }
  192. /// <summary>
  193. /// Represents the low-level TCP buffer settings for connections.
  194. /// </summary>
  195. public class LowLevelConnectionSettings
  196. {
  197. /// <summary>
  198. /// Gets or sets the size of the TCP write buffer in bytes.
  199. /// </summary>
  200. /// <remarks>
  201. /// <para>Default value is 1 MiB.</para>
  202. /// <para>This determines the maximum amount of data that that the <see cref="TCPStreamer"/> class can buffer up if it's already in a write operation.
  203. /// Increasing this value can potentially improve write performance, especially for large messages or data streams.
  204. /// However, setting it too high might consume a significant amount of memory, especially if there are many active connections.
  205. /// </para>
  206. /// </remarks>
  207. /// <value>The size of the TCP write buffer in bytes.</value>
  208. public uint TCPWriteBufferSize = 1024 * 1024;
  209. /// <summary>
  210. /// Gets or sets the size of the read buffer in bytes.
  211. /// </summary>
  212. /// <value>The size of the read buffer in bytes.</value>
  213. /// <remarks>
  214. /// <para>Default value is 1 MiB.</para>
  215. /// <para>This determines the maximum amount of data that low level streams and the <see cref="TCPStreamer"/> can buffer up for consuming by higher level layers.
  216. /// Adjusting this value can affect the read performance of the application.
  217. /// Like the write buffer, setting this too high might be memory-intensive, especially with many connections.
  218. /// It's advised to find a balance that suits the application's needs and resources.
  219. /// </para>
  220. /// </remarks>
  221. public uint ReadBufferSize = 1024 * 1024;
  222. }
  223. /// <summary>
  224. /// Contains settings that can be associated with a specific host or host variant.
  225. /// </summary>
  226. public class HostSettings
  227. {
  228. /// <summary>
  229. /// Gets or sets the low-level TCP buffer settings for connections associated with the host or host variant.
  230. /// </summary>
  231. /// <value>The low-level TCP buffer settings.</value>
  232. /// <remarks>
  233. /// These settings determine the buffer sizes for reading from and writing to TCP connections,
  234. /// which can impact performance and memory usage.
  235. /// </remarks>
  236. public LowLevelConnectionSettings LowLevelConnectionSettings = new LowLevelConnectionSettings();
  237. /// <summary>
  238. /// Settings related to HTTP requests made to this host or host variant.
  239. /// </summary>
  240. public HTTRequestSettings RequestSettings = new HTTRequestSettings();
  241. /// <summary>
  242. /// Settings related to HTTP/1.x connection behavior.
  243. /// </summary>
  244. public HTTP1ConnectionSettings HTTP1ConnectionSettings = new HTTP1ConnectionSettings();
  245. #if !UNITY_WEBGL || UNITY_EDITOR
  246. /// <summary>
  247. /// Settings related to TCP Ringmaster used in non-webgl platforms.
  248. /// </summary>
  249. public TCPRingmasterSettings TCPRingmasterSettings = new TCPRingmasterSettings();
  250. #if !BESTHTTP_DISABLE_ALTERNATE_SSL
  251. /// <summary>
  252. /// Settings related to HTTP/2 connection behavior.
  253. /// </summary>
  254. public Best.HTTP.Hosts.Connections.HTTP2.HTTP2ConnectionSettings HTTP2ConnectionSettings = new Connections.HTTP2.HTTP2ConnectionSettings();
  255. #endif
  256. /// <summary>
  257. /// Settings related to TLS (Transport Layer Security) behavior.
  258. /// </summary>
  259. public TLSSettings TLSSettings = new TLSSettings();
  260. #endif
  261. /// <summary>
  262. /// Settings related to <see cref="HostSetting.HostVariant"/> behavior.
  263. /// </summary>
  264. public HostVariantSettings HostVariantSettings = new HostVariantSettings();
  265. }
  266. }