HostDefinition.cs 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  1. using System;
  2. using System.Collections.Generic;
  3. using BestHTTP.Connections;
  4. using BestHTTP.PlatformSupport.Text;
  5. namespace BestHTTP.Core
  6. {
  7. public sealed class HostDefinition
  8. {
  9. public string Host { get; private set; }
  10. // alt-svc support:
  11. // 1. When a request receives an alt-svc header send a plugin msg to the manager with all the details to route to the proper hostDefinition.
  12. // 2. HostDefinition parses the header value
  13. // 3. If there's at least one supported protocol found, start open a connection to that said alternate
  14. // 4. If the new connection is open, route new requests to that connection
  15. public List<HostConnection> Alternates;
  16. /// <summary>
  17. /// Requests to the same host can require different connections: http, https, http + proxy, https + proxy, http2, http2 + proxy
  18. /// </summary>
  19. public Dictionary<string, HostConnection> hostConnectionVariant = new Dictionary<string, HostConnection>();
  20. public HostDefinition(string host)
  21. {
  22. this.Host = host;
  23. }
  24. public HostConnection HasBetterAlternate(HTTPRequest request)
  25. {
  26. return null;
  27. }
  28. public HostConnection GetHostDefinition(HTTPRequest request)
  29. {
  30. string key = GetKeyForRequest(request);
  31. return GetHostDefinition(key);
  32. }
  33. public HostConnection GetHostDefinition(string key)
  34. {
  35. HostConnection host = null;
  36. if (!this.hostConnectionVariant.TryGetValue(key, out host))
  37. this.hostConnectionVariant.Add(key, host = new HostConnection(this, key));
  38. return host;
  39. }
  40. public void Send(HTTPRequest request)
  41. {
  42. GetHostDefinition(request)
  43. .Send(request);
  44. }
  45. public void TryToSendQueuedRequests()
  46. {
  47. foreach (var kvp in hostConnectionVariant)
  48. kvp.Value.TryToSendQueuedRequests();
  49. }
  50. public void HandleAltSvcHeader(HTTPResponse response)
  51. {
  52. var headerValues = response.GetHeaderValues("alt-svc");
  53. if (headerValues == null)
  54. HTTPManager.Logger.Warning(typeof(HostDefinition).Name, "Received HandleAltSvcHeader message, but no Alt-Svc header found!", response.Context);
  55. }
  56. public void HandleConnectProtocol(HTTP2ConnectProtocolInfo info)
  57. {
  58. HTTPManager.Logger.Information(typeof(HostDefinition).Name, string.Format("Received HandleConnectProtocol message. Connect protocol for host {0}. Enabled: {1}", info.Host, info.Enabled));
  59. }
  60. internal void Shutdown()
  61. {
  62. foreach (var kvp in this.hostConnectionVariant)
  63. {
  64. kvp.Value.Shutdown();
  65. }
  66. }
  67. internal void SaveTo(System.IO.BinaryWriter bw)
  68. {
  69. bw.Write(this.hostConnectionVariant.Count);
  70. foreach (var kvp in this.hostConnectionVariant)
  71. {
  72. bw.Write(kvp.Key.ToString());
  73. kvp.Value.SaveTo(bw);
  74. }
  75. }
  76. internal void LoadFrom(int version, System.IO.BinaryReader br)
  77. {
  78. int count = br.ReadInt32();
  79. for (int i = 0; i < count; ++i)
  80. {
  81. GetHostDefinition(br.ReadString())
  82. .LoadFrom(version, br);
  83. }
  84. }
  85. public static string GetKeyForRequest(HTTPRequest request)
  86. {
  87. return GetKeyFor(request.CurrentUri
  88. #if !BESTHTTP_DISABLE_PROXY && (!UNITY_WEBGL || UNITY_EDITOR)
  89. , request.Proxy
  90. #endif
  91. );
  92. }
  93. public static string GetKeyFor(Uri uri
  94. #if !BESTHTTP_DISABLE_PROXY && (!UNITY_WEBGL || UNITY_EDITOR)
  95. , Proxy proxy
  96. #endif
  97. )
  98. {
  99. if (uri.IsFile)
  100. return uri.ToString();
  101. var keyBuilder = StringBuilderPool.Get(11);
  102. #if !BESTHTTP_DISABLE_PROXY && (!UNITY_WEBGL || UNITY_EDITOR)
  103. if (proxy != null && proxy.UseProxyForAddress(uri))
  104. {
  105. keyBuilder.Append(proxy.Address.Scheme);
  106. keyBuilder.Append("://");
  107. keyBuilder.Append(proxy.Address.Host);
  108. keyBuilder.Append(":");
  109. keyBuilder.Append(proxy.Address.Port);
  110. keyBuilder.Append(" @ ");
  111. }
  112. #endif
  113. keyBuilder.Append(uri.Scheme);
  114. keyBuilder.Append("://");
  115. keyBuilder.Append(uri.Host);
  116. keyBuilder.Append(":");
  117. keyBuilder.Append(uri.Port);
  118. return StringBuilderPool.ReleaseAndGrab(keyBuilder);
  119. }
  120. }
  121. }