HttpClientHandler.cs 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200
  1. // Licensed to the .NET Foundation under one or more agreements.
  2. // The .NET Foundation licenses this file to you under the MIT license.
  3. // See the LICENSE file in the project root for more information.
  4. using System.Collections.Generic;
  5. using System.Net.Security;
  6. using System.Security.Authentication;
  7. using System.Security.Cryptography.X509Certificates;
  8. using System.Threading;
  9. using System.Threading.Tasks;
  10. namespace System.Net.Http
  11. {
  12. public partial class HttpClientHandler : HttpMessageHandler
  13. {
  14. readonly IMonoHttpClientHandler _delegatingHandler;
  15. ClientCertificateOption _clientCertificateOptions;
  16. public HttpClientHandler () : this (CreateDefaultHandler ()) { }
  17. internal HttpClientHandler (IMonoHttpClientHandler handler)
  18. {
  19. _delegatingHandler = handler;
  20. ClientCertificateOptions = ClientCertificateOption.Manual;
  21. }
  22. protected override void Dispose (bool disposing)
  23. {
  24. if (disposing) {
  25. _delegatingHandler.Dispose ();
  26. }
  27. base.Dispose (disposing);
  28. }
  29. public virtual bool SupportsAutomaticDecompression => _delegatingHandler.SupportsAutomaticDecompression;
  30. public virtual bool SupportsProxy => true;
  31. public virtual bool SupportsRedirectConfiguration => true;
  32. public bool UseCookies {
  33. get => _delegatingHandler.UseCookies;
  34. set => _delegatingHandler.UseCookies = value;
  35. }
  36. public CookieContainer CookieContainer {
  37. get => _delegatingHandler.CookieContainer;
  38. set => _delegatingHandler.CookieContainer = value;
  39. }
  40. void ThrowForModifiedManagedSslOptionsIfStarted ()
  41. {
  42. // Hack to trigger an InvalidOperationException if a property that's stored on
  43. // SslOptions is changed, since SslOptions itself does not do any such checks.
  44. _delegatingHandler.SslOptions = _delegatingHandler.SslOptions;
  45. }
  46. public ClientCertificateOption ClientCertificateOptions {
  47. get {
  48. return _clientCertificateOptions;
  49. }
  50. set {
  51. switch (value) {
  52. case ClientCertificateOption.Manual:
  53. ThrowForModifiedManagedSslOptionsIfStarted ();
  54. _clientCertificateOptions = value;
  55. _delegatingHandler.SslOptions.LocalCertificateSelectionCallback = (sender, targetHost, localCertificates, remoteCertificate, acceptableIssuers) => CertificateHelper.GetEligibleClientCertificate (ClientCertificates);
  56. break;
  57. case ClientCertificateOption.Automatic:
  58. ThrowForModifiedManagedSslOptionsIfStarted ();
  59. _clientCertificateOptions = value;
  60. _delegatingHandler.SslOptions.LocalCertificateSelectionCallback = (sender, targetHost, localCertificates, remoteCertificate, acceptableIssuers) => CertificateHelper.GetEligibleClientCertificate ();
  61. break;
  62. default:
  63. throw new ArgumentOutOfRangeException (nameof (value));
  64. }
  65. }
  66. }
  67. public X509CertificateCollection ClientCertificates {
  68. get {
  69. if (ClientCertificateOptions != ClientCertificateOption.Manual) {
  70. throw new InvalidOperationException (SR.Format (SR.net_http_invalid_enable_first, nameof (ClientCertificateOptions), nameof (ClientCertificateOption.Manual)));
  71. }
  72. return _delegatingHandler.SslOptions.ClientCertificates ??
  73. (_delegatingHandler.SslOptions.ClientCertificates = new X509CertificateCollection ());
  74. }
  75. }
  76. public Func<HttpRequestMessage, X509Certificate2, X509Chain, SslPolicyErrors, bool> ServerCertificateCustomValidationCallback {
  77. get => (_delegatingHandler.SslOptions.RemoteCertificateValidationCallback?.Target as ConnectHelper.CertificateCallbackMapper)?.FromHttpClientHandler;
  78. set {
  79. ThrowForModifiedManagedSslOptionsIfStarted ();
  80. _delegatingHandler.SslOptions.RemoteCertificateValidationCallback = value != null ?
  81. new ConnectHelper.CertificateCallbackMapper (value).ForSocketsHttpHandler :
  82. null;
  83. }
  84. }
  85. public bool CheckCertificateRevocationList {
  86. get => _delegatingHandler.SslOptions.CertificateRevocationCheckMode == X509RevocationMode.Online;
  87. set {
  88. ThrowForModifiedManagedSslOptionsIfStarted ();
  89. _delegatingHandler.SslOptions.CertificateRevocationCheckMode = value ? X509RevocationMode.Online : X509RevocationMode.NoCheck;
  90. }
  91. }
  92. public SslProtocols SslProtocols {
  93. get => _delegatingHandler.SslOptions.EnabledSslProtocols;
  94. set {
  95. ThrowForModifiedManagedSslOptionsIfStarted ();
  96. _delegatingHandler.SslOptions.EnabledSslProtocols = value;
  97. }
  98. }
  99. public DecompressionMethods AutomaticDecompression {
  100. get => _delegatingHandler.AutomaticDecompression;
  101. set => _delegatingHandler.AutomaticDecompression = value;
  102. }
  103. public bool UseProxy {
  104. get => _delegatingHandler.UseProxy;
  105. set => _delegatingHandler.UseProxy = value;
  106. }
  107. public IWebProxy Proxy {
  108. get => _delegatingHandler.Proxy;
  109. set => _delegatingHandler.Proxy = value;
  110. }
  111. public ICredentials DefaultProxyCredentials {
  112. get => _delegatingHandler.DefaultProxyCredentials;
  113. set => _delegatingHandler.DefaultProxyCredentials = value;
  114. }
  115. public bool PreAuthenticate {
  116. get => _delegatingHandler.PreAuthenticate;
  117. set => _delegatingHandler.PreAuthenticate = value;
  118. }
  119. public bool UseDefaultCredentials {
  120. // Either read variable from curlHandler or compare .Credentials as socketsHttpHandler does not have separate prop.
  121. get => _delegatingHandler.Credentials == CredentialCache.DefaultCredentials;
  122. set {
  123. if (value) {
  124. _delegatingHandler.Credentials = CredentialCache.DefaultCredentials;
  125. } else {
  126. if (_delegatingHandler.Credentials == CredentialCache.DefaultCredentials) {
  127. // Only clear out the Credentials property if it was a DefaultCredentials.
  128. _delegatingHandler.Credentials = null;
  129. }
  130. }
  131. }
  132. }
  133. public ICredentials Credentials {
  134. get => _delegatingHandler.Credentials;
  135. set => _delegatingHandler.Credentials = value;
  136. }
  137. public bool AllowAutoRedirect {
  138. get => _delegatingHandler.AllowAutoRedirect;
  139. set => _delegatingHandler.AllowAutoRedirect = value;
  140. }
  141. public int MaxAutomaticRedirections {
  142. get => _delegatingHandler.MaxAutomaticRedirections;
  143. set => _delegatingHandler.MaxAutomaticRedirections = value;
  144. }
  145. public int MaxConnectionsPerServer {
  146. get => _delegatingHandler.MaxConnectionsPerServer;
  147. set => _delegatingHandler.MaxConnectionsPerServer = value;
  148. }
  149. public int MaxResponseHeadersLength {
  150. get => _delegatingHandler.MaxResponseHeadersLength;
  151. set => _delegatingHandler.MaxResponseHeadersLength = value;
  152. }
  153. public long MaxRequestContentBufferSize {
  154. get => _delegatingHandler.MaxRequestContentBufferSize;
  155. set => _delegatingHandler.MaxRequestContentBufferSize = value;
  156. }
  157. public IDictionary<string, object> Properties => _delegatingHandler.Properties;
  158. // Only used in MonoWebRequestHandler and ignored by the other handlers.
  159. internal void SetWebRequestTimeout (TimeSpan timeout)
  160. {
  161. _delegatingHandler.SetWebRequestTimeout (timeout);
  162. }
  163. protected internal override Task<HttpResponseMessage> SendAsync (HttpRequestMessage request, CancellationToken cancellationToken) =>
  164. _delegatingHandler.SendAsync (request, cancellationToken);
  165. }
  166. }