예제 #1
0
        private static void SetManagedHandlerProperty(HttpClientHandler handler, string name, object value)
        {
            // TODO #23166: Use the managed API for ConnectionIdleTimeout when it's exposed
            object managedHandler = handler.GetType().GetField("_managedHandler", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(handler);

            managedHandler.GetType().GetProperty(name).SetValue(managedHandler, value);
        }
예제 #2
0
        /// <summary>
        /// sets the ip endpoint to use for the connections estabilished by this HttpClientHandler
        /// </summary>
        /// <param name="handler"></param>
        /// <param name="biep"></param>
        public static void SetServicePointOptions(this HttpClientHandler handler, BindIPEndPoint biep)
        {
            if (handler == null)
            {
                throw new ArgumentNullException("handler cannot be null");
            }
            var field = handler.GetType().GetField("_startRequest", BindingFlags.NonPublic | BindingFlags.Instance);             // Fieldname has a _ due to being private

            if (field == null)
            {
                throw new ArgumentNullException($"Field _startRequest not found in handler type {handler.GetType()}");
            }
            var startRequest = field.GetValue(handler) as Action <object>;

            if (startRequest == null)
            {
                throw new ArgumentNullException("startRequest value is null");
            }

            Action <object> newStartRequest = obj =>
            {
                var webReqField = obj.GetType().GetField("webRequest", BindingFlags.NonPublic | BindingFlags.Instance);
                if (webReqField == null)
                {
                    throw new ArgumentNullException($"webRequest is not set on type {obj.GetType()}");
                }
                var webRequest = webReqField.GetValue(obj) as HttpWebRequest;
                if (webRequest == null)
                {
                    throw new ArgumentNullException($"webRequest is null");
                }
                webRequest.ServicePoint.BindIPEndPointDelegate = new BindIPEndPoint(biep);
                startRequest(obj);                 //call original action
            };

            field.SetValue(handler, newStartRequest);             //replace original 'startRequest' with the one above
        }
예제 #3
0
 public HandlerWrapper(HttpClientHandler handler)
 {
     this.handlerType = handler.GetType().Name;
     this.handler     = handler;
 }
예제 #4
0
        // NOTE: this method replicates the logic that the base ServiceClient uses except that it doesn't insert the RetryDelegatingHandler
        // and it does insert the WatcherDelegatingHandler. we don't want the RetryDelegatingHandler because it has a very broad definition
        // of what requests have failed. it considers everything outside 2xx to be failed, including 1xx (e.g. 101 Switching Protocols) and
        // 3xx. in particular, this prevents upgraded connections and certain generic/custom requests from working.
        private void CreateHttpClient(DelegatingHandler[] handlers, KubernetesClientConfiguration config)
        {
            FirstMessageHandler = HttpClientHandler = CreateRootHandler();


#if NET5_0
            // https://github.com/kubernetes-client/csharp/issues/587
            // let user control if tcp keep alive until better fix
            if (config.TcpKeepAlive)
            {
                // https://github.com/kubernetes-client/csharp/issues/533
                // net5 only
                // this is a temp fix to attach SocketsHttpHandler to HttpClient in order to set SO_KEEPALIVE
                // https://tldp.org/HOWTO/html_single/TCP-Keepalive-HOWTO/
                //
                // _underlyingHandler is not a public accessible field
                // src of net5 HttpClientHandler and _underlyingHandler field defined here
                // https://github.com/dotnet/runtime/blob/79ae74f5ca5c8a6fe3a48935e85bd7374959c570/src/libraries/System.Net.Http/src/System/Net/Http/HttpClientHandler.cs#L22
                //
                // Should remove after better solution

                var sh = new SocketsHttpHandler();
                sh.ConnectCallback = async(context, token) =>
                {
                    var socket = new Socket(SocketType.Stream, ProtocolType.Tcp)
                    {
                        NoDelay = true,
                    };

                    socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.KeepAlive, true);

                    var host = context.DnsEndPoint.Host;

                    if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
                    {
                        // https://github.com/dotnet/runtime/issues/24917
                        // GetHostAddresses will return {host} if host is an ip
                        var ips = Dns.GetHostAddresses(host);
                        if (ips.Length == 0)
                        {
                            throw new Exception($"{host} DNS lookup failed");
                        }

                        host = ips[new Random().Next(ips.Length)].ToString();
                    }

                    await socket.ConnectAsync(host, context.DnsEndPoint.Port, token).ConfigureAwait(false);

                    return(new NetworkStream(socket, ownsSocket: true));
                };


                // set HttpClientHandler's cert callback before replace _underlyingHandler
                // force HttpClientHandler use our callback
                InitializeFromConfig(config);

                var p = HttpClientHandler.GetType().GetField("_underlyingHandler", BindingFlags.NonPublic | BindingFlags.Instance);
                p.SetValue(HttpClientHandler, (sh));
            }
#endif

            if (handlers == null || handlers.Length == 0)
            {
                // ensure we have at least one DelegatingHandler so AppendDelegatingHandler will work
                FirstMessageHandler = new ForwardingHandler(HttpClientHandler);
            }
            else
            {
                for (int i = handlers.Length - 1; i >= 0; i--)
                {
                    DelegatingHandler handler = handlers[i];
                    while (handler.InnerHandler is DelegatingHandler d)
                    {
                        handler = d;
                    }

                    handler.InnerHandler = FirstMessageHandler;
                    FirstMessageHandler  = handlers[i];
                }
            }

            AppendDelegatingHandler <WatcherDelegatingHandler>();
            HttpClient = new HttpClient(FirstMessageHandler, false);
        }