/// <summary> /// Creates an instance of an <see cref="HttpMessageHandler"/> using the <see cref="DelegatingHandler"/> instances /// provided by <paramref name="handlers"/>. The resulting pipeline can be used to manually create <see cref="HttpClient"/> /// or <see cref="HttpMessageInvoker"/> instances with customized message handlers. /// </summary> /// <param name="finalHandler">The inner handler represents the destination of the HTTP message channel.</param> /// <param name="handlers">An ordered list of <see cref="DelegatingHandler"/> instances to be invoked as part /// of sending an <see cref="HttpRequestMessage"/> and receiving an <see cref="HttpResponseMessage"/>. /// The handlers are invoked in a top-down fashion. That is, the first entry is invoked first for /// an outbound request message but last for an inbound response message.</param> /// <returns>A tuple with The HTTP message channel and FeatureFlag for the handlers.</returns> internal static (HttpMessageHandler Pipeline, FeatureFlag FeatureFlags) CreatePipelineWithFeatureFlags(IEnumerable <DelegatingHandler> handlers, HttpMessageHandler finalHandler = null) { FeatureFlag handlerFlags = FeatureFlag.None; if (finalHandler == null) { finalHandler = GetNativePlatformHttpHandler(); } if (handlers == null) { return(Pipeline : finalHandler, FeatureFlags : handlerFlags); } HttpMessageHandler httpPipeline = finalHandler; IEnumerable <DelegatingHandler> reversedHandlers = handlers.Reverse(); HashSet <Type> existingHandlerTypes = new HashSet <Type>(); foreach (DelegatingHandler handler in reversedHandlers) { if (handler == null) { throw new ArgumentNullException(nameof(handlers), "DelegatingHandler array contains null item."); } #if iOS || macOS #if iOS // Skip CompressionHandler since NSUrlSessionHandler automatically handles decompression on iOS and macOS and it can't be turned off. // See issue https://github.com/microsoftgraph/msgraph-sdk-dotnet/issues/481 for more details. if (finalHandler.GetType().Equals(typeof(NSUrlSessionHandler)) && handler.GetType().Equals(typeof(CompressionHandler))) #elif macOS if (finalHandler.GetType().Equals(typeof(Foundation.NSUrlSessionHandler)) && handler.GetType().Equals(typeof(CompressionHandler))) #endif { // Skip chaining of CompressionHandler. continue; } #endif // Check for duplicate handler by type. if (!existingHandlerTypes.Add(handler.GetType())) { throw new ArgumentException($"DelegatingHandler array has a duplicate handler. {handler} has a duplicate handler.", "handlers"); } // Existing InnerHandlers on handlers will be overwritten handler.InnerHandler = httpPipeline; httpPipeline = handler; // Register feature flag for the handler. handlerFlags |= GetHandlerFeatureFlag(handler); } return(Pipeline : httpPipeline, FeatureFlags : handlerFlags); }
public void CreateClient_NoPrimaryHandlerNet5OrLater_SocketsHttpHandlerConfigured() { // Arrange var services = new ServiceCollection(); services .AddGrpcClient <TestGreeterClient>(o => o.Address = new Uri("https://localhost")); var serviceProvider = services.BuildServiceProvider(validateScopes: true); var clientFactory = CreateGrpcClientFactory(serviceProvider); // Act var handlerFactory = serviceProvider.GetRequiredService <IHttpMessageHandlerFactory>(); var handler = handlerFactory.CreateHandler(nameof(TestGreeterClient)); // Assert var hasSocketsHttpHandler = false; HttpMessageHandler?currentHandler = handler; while (currentHandler is DelegatingHandler delegatingHandler) { currentHandler = delegatingHandler.InnerHandler; if (currentHandler?.GetType() == typeof(SocketsHttpHandler)) { hasSocketsHttpHandler = true; break; } } Assert.IsTrue(hasSocketsHttpHandler); }
public static Task <HttpResponseMessage> SendAsync(this HttpMessageHandler handler, HttpRequestMessage request, CancellationToken cancellationToken) { return((Task <HttpResponseMessage>)handler.GetType() .GetMethod("SendAsync", BindingFlags.Instance | BindingFlags.NonPublic).Invoke(handler, new object[] { request, cancellationToken })); }
public OidcDelegationHandler(IAccessTokenProvider accessTokenProvider, HttpMessageHandler innerHanler) { _accessTokenProvider = accessTokenProvider ?? throw new ArgumentNullException(nameof(accessTokenProvider)); _innerHanler = innerHanler ?? throw new ArgumentNullException(nameof(innerHanler)); var type = innerHanler.GetType(); _method = type.GetMethod("SendAsync", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.InvokeMethod) ?? throw new InvalidOperationException("Cannot get SendAsync method"); }
private static async Task <HttpResponseMessage> SendAsyncInternal( HttpMessageHandler handler, HttpRequestMessage request, CancellationToken cancellationToken) { var executeAsync = DynamicMethodBuilder <Func <HttpMessageHandler, HttpRequestMessage, CancellationToken, Task <HttpResponseMessage> > > .GetOrCreateMethodCallDelegate( handler.GetType(), nameof(SendAsync)); var handlerTypeName = handler.GetType().FullName; if (handlerTypeName != "System.Net.Http.HttpClientHandler" || !IsTracingEnabled(request)) { // skip instrumentation return(await executeAsync(handler, request, cancellationToken).ConfigureAwait(false)); } string httpMethod = request.Method.ToString().ToUpperInvariant(); string integrationName = typeof(HttpMessageHandlerIntegration).Name.TrimEnd("Integration", StringComparison.OrdinalIgnoreCase); using (var scope = ScopeFactory.CreateOutboundHttpScope(httpMethod, request.RequestUri, integrationName)) { try { if (scope != null) { // add distributed tracing headers to the HTTP request SpanContextPropagator.Instance.Inject(scope.Span.Context, request.Headers.Wrap()); } HttpResponseMessage response = await executeAsync(handler, request, cancellationToken).ConfigureAwait(false); // this tag can only be set after the response is returned scope?.Span.SetTag(Tags.HttpStatusCode, ((int)response.StatusCode).ToString()); return(response); } catch (Exception ex) when(scope?.Span.SetExceptionForFilter(ex) ?? false) { // unreachable code throw; } } }
public TestAuthenticator(HttpMessageHandler innerTestHandler) { _innerTestHandler = innerTestHandler; if (innerTestHandler == null) { throw new ArgumentNullException(nameof(innerTestHandler)); } _sender = BuildSender(innerTestHandler.GetType()); }
public ApproovHttpClient(HttpMessageHandler handler) : base(handler) { // a handler must be provided if (handler == null) { throw new ApproovSDKException(TAG + "ApproovHttpClient constructor: HttpMessageHandler must be provided"); } // traverse the chain of handlers to find the inner HttpClientHandler HttpMessageHandler chainedHandler = handler; while (chainedHandler != null) { if (chainedHandler.GetType().IsSubclassOf(typeof(DelegatingHandler))) { // traverse through DelegatingHandlers DelegatingHandler delegatingHandler = (DelegatingHandler)chainedHandler; chainedHandler = delegatingHandler.InnerHandler; if (chainedHandler == null) { throw new ApproovSDKException(TAG + "ApproovHttpClient constructor: No inner handler found"); } } else if (chainedHandler.GetType().IsSubclassOf(typeof(HttpClientHandler)) || (chainedHandler.GetType() == typeof(HttpClientHandler))) { // we've found the inner handler test if the callback has been set, then bail out HttpClientHandler httpClientHandler = (HttpClientHandler)chainedHandler; if ((httpClientHandler.ServerCertificateCustomValidationCallback != null) && (httpClientHandler.ServerCertificateCustomValidationCallback != ServerCallback)) { throw new ApproovSDKException(TAG + "Unable to override InnerHandler custom vallidation callback"); } // set the callback handler httpClientHandler.ServerCertificateCustomValidationCallback = ServerCallback; // We are done chainedHandler = null; } else { // there must be an inner HttpClientHandler that we can setup pinning for throw new ApproovSDKException(TAG + "No HttpClientHandler found"); } } }
public void AddNetworkCredentials(NetworkCredential cred) { if (handler != null) { var prop = handler.GetType().GetProperty("Credentials"); if (prop != null) { prop.SetValue(handler, cred, null); } } }
/// <summary> /// Initializes a new instance of the <see cref="MockedHttpClientHandler"/> class. /// </summary> /// <param name="httpMessageHandler">Handler to use.</param> public MockedHttpClientHandler(HttpMessageHandler httpMessageHandler) { _httpMessageHandler = httpMessageHandler; // Call directly to avoid wrapping with HttpClient. httpMessageHandlerMethod = httpMessageHandler.GetType().GetMethod( nameof(SendAsync), BindingFlags.Instance | BindingFlags.NonPublic, Type.DefaultBinder, new[] { typeof(HttpRequestMessage), typeof(CancellationToken) }, null); }
public RecordingHttpMessageHandler(HttpMessageHandler innerHandler, Cassette cassette) : base(innerHandler) { var cookieContainerProperty = innerHandler.GetType().GetRuntimeProperty(nameof(HttpClientHandler.CookieContainer)); if (cookieContainerProperty?.PropertyType == typeof(CookieContainer) && cookieContainerProperty.CanRead) { // Create Open Delegate from property getter method var cookieContainerGetter = cookieContainerProperty.GetMethod.CreateDelegate(typeof(Func <,>).MakeGenericType(innerHandler.GetType(), typeof(CookieContainer))); _innerHandlerCookieContainerGetter = () => (CookieContainer)cookieContainerGetter.DynamicInvoke(innerHandler); } _cassette = cassette; }
public static HttpMessageHandler?GetHttpHandlerType(HttpMessageHandler handler, string handlerTypeName) { if (handler?.GetType().FullName == handlerTypeName) { return(handler); } HttpMessageHandler?currentHandler = handler; while (currentHandler is DelegatingHandler delegatingHandler) { currentHandler = delegatingHandler.InnerHandler; if (currentHandler?.GetType().FullName == handlerTypeName) { return(currentHandler); } } return(null); }
public static bool HasHttpHandlerType(HttpMessageHandler handler, string handlerTypeName) { if (handler?.GetType().FullName == handlerTypeName) { return(true); } HttpMessageHandler?currentHandler = handler; DelegatingHandler? delegatingHandler; while ((delegatingHandler = currentHandler as DelegatingHandler) != null) { currentHandler = delegatingHandler.InnerHandler; if (currentHandler?.GetType().FullName == handlerTypeName) { return(true); } } return(false); }
private void InitHttps(string securityRole) { if (HttpMessageHandler == null) { HttpMessageHandler = new HttpClientHandler(); } var wrh = HttpMessageHandler as HttpClientHandler; if (wrh == null) { throw new ProgrammaticException("When using HTTPS in ServiceProxy, only WebRequestHandler is supported.", unencrypted: new Tags { { "HandlerType", HttpMessageHandler.GetType().FullName } }); } var clientCert = CertificateLocator.GetCertificate("Client"); var clientRootCertHash = clientCert.GetHashOfRootCertificate(); wrh.ClientCertificates.Add(clientCert); wrh.ServerCertificateCustomValidationCallback = (sender, serverCertificate, serverChain, errors) => { switch (errors) { case SslPolicyErrors.RemoteCertificateNotAvailable: Log.Error("Remote certificate not available."); return(false); case SslPolicyErrors.RemoteCertificateChainErrors: Log.Error(log => { var sb = new StringBuilder("Certificate error/s."); foreach (var chainStatus in serverChain.ChainStatus) { sb.AppendFormat("Status {0}, status information {1}\n", chainStatus.Status, chainStatus.StatusInformation); } log(sb.ToString()); }); return(false); case SslPolicyErrors.RemoteCertificateNameMismatch: // by design domain name do not match name of certificate, so RemoteCertificateNameMismatch is not an error. case SslPolicyErrors.None: //Check if security role of a server is as expected if (securityRole != null) { var name = ((X509Certificate2)serverCertificate).GetNameInfo(X509NameType.SimpleName, false); if (name == null || !name.Contains(securityRole)) { return(false); } } bool hasSameRootCertificateHash = serverChain.HasSameRootCertificateHash(clientRootCertHash); if (!hasSameRootCertificateHash) { Log.Error(_ => _("Server root certificate do not match client root certificate")); } return(hasSameRootCertificateHash); default: throw new ArgumentOutOfRangeException(nameof(errors), errors, "The supplied value of SslPolicyErrors is invalid."); } }; }