/// <exception cref="System.IO.IOException"></exception> public virtual void Upgrade(ManagedHttpClientConnection conn, HttpHost host, HttpContext context) { HttpClientContext clientContext = ((HttpClientContext)HttpClientContext.Adapt(context )); Lookup <ConnectionSocketFactory> registry = GetSocketFactoryRegistry(clientContext ); ConnectionSocketFactory sf = registry.Lookup(host.GetSchemeName()); if (sf == null) { throw new UnsupportedSchemeException(host.GetSchemeName() + " protocol is not supported" ); } if (!(sf is LayeredConnectionSocketFactory)) { throw new UnsupportedSchemeException(host.GetSchemeName() + " protocol does not support connection upgrade" ); } LayeredConnectionSocketFactory lsf = (LayeredConnectionSocketFactory)sf; System.Net.Sockets.Socket sock = conn.GetSocket(); int port = this.schemePortResolver.Resolve(host); sock = lsf.CreateLayeredSocket(sock, host.GetHostName(), port, context); conn.Bind(sock); }
/// <summary> /// Derives the interpreted (absolute) URI that was used to generate the last /// request. /// </summary> /// <remarks> /// Derives the interpreted (absolute) URI that was used to generate the last /// request. This is done by extracting the request-uri and target origin for /// the last request and scanning all the redirect locations for the last /// fragment identifier, then combining the result into a /// <see cref="Sharpen.URI">Sharpen.URI</see> /// . /// </remarks> /// <param name="originalURI">original request before any redirects</param> /// <param name="target"> /// if the last URI is relative, it is resolved against this target, /// or <code>null</code> if not available. /// </param> /// <param name="redirects"> /// collection of redirect locations since the original request /// or <code>null</code> if not available. /// </param> /// <returns>interpreted (absolute) URI</returns> /// <exception cref="Sharpen.URISyntaxException"></exception> public static URI Resolve(URI originalURI, HttpHost target, IList <URI> redirects) { Args.NotNull(originalURI, "Request URI"); URIBuilder uribuilder; if (redirects == null || redirects.IsEmpty()) { uribuilder = new URIBuilder(originalURI); } else { uribuilder = new URIBuilder(redirects[redirects.Count - 1]); string frag = uribuilder.GetFragment(); // read interpreted fragment identifier from redirect locations for (int i = redirects.Count - 1; frag == null && i >= 0; i--) { frag = redirects[i].GetFragment(); } uribuilder.SetFragment(frag); } // read interpreted fragment identifier from original request if (uribuilder.GetFragment() == null) { uribuilder.SetFragment(originalURI.GetFragment()); } // last target origin if (target != null && !uribuilder.IsAbsolute()) { uribuilder.SetScheme(target.GetSchemeName()); uribuilder.SetHost(target.GetHostName()); uribuilder.SetPort(target.GetPort()); } return(uribuilder.Build()); }
/// <exception cref="Apache.Http.Conn.UnsupportedSchemeException"></exception> public virtual int Resolve(HttpHost host) { Args.NotNull(host, "HTTP host"); int port = host.GetPort(); if (port > 0) { return(port); } else { string name = host.GetSchemeName(); if (Sharpen.Runtime.EqualsIgnoreCase(name, "http")) { return(80); } else { if (Sharpen.Runtime.EqualsIgnoreCase(name, "https")) { return(443); } else { throw new UnsupportedSchemeException(name + " protocol is not supported"); } } } }
/// <summary> /// A convenience method for creating a new /// <see cref="Sharpen.URI">Sharpen.URI</see> /// whose scheme, host /// and port are taken from the target host, but whose path, query and /// fragment are taken from the existing URI. The fragment is only used if /// dropFragment is false. The path is set to "/" if not explicitly specified. /// </summary> /// <param name="uri">Contains the path, query and fragment to use.</param> /// <param name="target">Contains the scheme, host and port to use.</param> /// <param name="dropFragment">True if the fragment should not be copied.</param> /// <exception cref="Sharpen.URISyntaxException">If the resulting URI is invalid.</exception> public static URI RewriteURI(URI uri, HttpHost target, bool dropFragment) { Args.NotNull(uri, "URI"); if (uri.IsOpaque()) { return(uri); } URIBuilder uribuilder = new URIBuilder(uri); if (target != null) { uribuilder.SetScheme(target.GetSchemeName()); uribuilder.SetHost(target.GetHostName()); uribuilder.SetPort(target.GetPort()); } else { uribuilder.SetScheme(null); uribuilder.SetHost(null); uribuilder.SetPort(-1); } if (dropFragment) { uribuilder.SetFragment(null); } if (TextUtils.IsEmpty(uribuilder.GetPath())) { uribuilder.SetPath("/"); } return(uribuilder.Build()); }
/// <exception cref="Apache.Http.HttpException"></exception> public virtual HttpRoute DetermineRoute(HttpHost host, IHttpRequest request, HttpContext context) { Args.NotNull(host, "Target host"); Args.NotNull(request, "Request"); HttpClientContext clientContext = ((HttpClientContext)HttpClientContext.Adapt(context )); RequestConfig config = clientContext.GetRequestConfig(); IPAddress local = config.GetLocalAddress(); HttpHost proxy = config.GetProxy(); if (proxy == null) { proxy = DetermineProxy(host, request, context); } HttpHost target; if (host.GetPort() <= 0) { try { target = new HttpHost(host.GetHostName(), this.schemePortResolver.Resolve(host), host.GetSchemeName()); } catch (UnsupportedSchemeException ex) { throw new HttpException(ex.Message); } } else { target = host; } bool secure = Sharpen.Runtime.EqualsIgnoreCase(target.GetSchemeName(), "https"); if (proxy == null) { return(new HttpRoute(target, local, secure)); } else { return(new HttpRoute(target, local, proxy, secure)); } }
protected internal virtual HttpHost GetKey(HttpHost host) { if (host.GetPort() <= 0) { int port; try { port = schemePortResolver.Resolve(host); } catch (UnsupportedSchemeException) { return(host); } return(new HttpHost(host.GetHostName(), port, host.GetSchemeName())); } else { return(host); } }
/// <exception cref="System.IO.IOException"></exception> public virtual void Connect(ManagedHttpClientConnection conn, HttpHost host, IPEndPoint localAddress, int connectTimeout, SocketConfig socketConfig, HttpContext context ) { Lookup <ConnectionSocketFactory> registry = GetSocketFactoryRegistry(context); ConnectionSocketFactory sf = registry.Lookup(host.GetSchemeName()); if (sf == null) { throw new UnsupportedSchemeException(host.GetSchemeName() + " protocol is not supported" ); } IPAddress[] addresses = this.dnsResolver.Resolve(host.GetHostName()); int port = this.schemePortResolver.Resolve(host); for (int i = 0; i < addresses.Length; i++) { IPAddress address = addresses[i]; bool last = i == addresses.Length - 1; System.Net.Sockets.Socket sock = sf.CreateSocket(context); sock.SetReuseAddress(socketConfig.IsSoReuseAddress()); conn.Bind(sock); IPEndPoint remoteAddress = new IPEndPoint(address, port); if (this.log.IsDebugEnabled()) { this.log.Debug("Connecting to " + remoteAddress); } try { sock.ReceiveTimeout = socketConfig.GetSoTimeout(); sock = sf.ConnectSocket(connectTimeout, sock, host, remoteAddress, localAddress, context); sock.NoDelay = socketConfig.IsTcpNoDelay(); sock.SetKeepAlive(socketConfig.IsSoKeepAlive()); int linger = socketConfig.GetSoLinger(); if (linger >= 0) { sock.SetSoLinger(linger > 0, linger); } conn.Bind(sock); return; } catch (SocketTimeoutException ex) { if (last) { throw new ConnectTimeoutException(ex, host, addresses); } } catch (ConnectException ex) { if (last) { string msg = ex.Message; if ("Connection timed out".Equals(msg)) { throw new ConnectTimeoutException(ex, host, addresses); } else { throw new HttpHostConnectException(ex, host, addresses); } } } if (this.log.IsDebugEnabled()) { this.log.Debug("Connect to " + remoteAddress + " timed out. " + "Connection will be retried using another IP address" ); } } }
/// <exception cref="System.IO.IOException"></exception> /// <exception cref="Apache.Http.HttpException"></exception> public virtual CloseableHttpResponse Execute(HttpRoute route, HttpRequestWrapper request, HttpClientContext context, HttpExecutionAware execAware) { Args.NotNull(route, "HTTP route"); Args.NotNull(request, "HTTP request"); Args.NotNull(context, "HTTP context"); IHttpRequest original = request.GetOriginal(); URI uri = null; if (original is IHttpUriRequest) { uri = ((IHttpUriRequest)original).GetURI(); } else { string uriString = original.GetRequestLine().GetUri(); try { uri = URI.Create(uriString); } catch (ArgumentException ex) { if (this.log.IsDebugEnabled()) { this.log.Debug("Unable to parse '" + uriString + "' as a valid URI; " + "request URI and Host header may be inconsistent" , ex); } } } request.SetURI(uri); // Re-write request URI if needed RewriteRequestURI(request, route); HttpParams @params = request.GetParams(); HttpHost virtualHost = (HttpHost)@params.GetParameter(ClientPNames.VirtualHost); // HTTPCLIENT-1092 - add the port if necessary if (virtualHost != null && virtualHost.GetPort() == -1) { int port = route.GetTargetHost().GetPort(); if (port != -1) { virtualHost = new HttpHost(virtualHost.GetHostName(), port, virtualHost.GetSchemeName ()); } if (this.log.IsDebugEnabled()) { this.log.Debug("Using virtual host" + virtualHost); } } HttpHost target = null; if (virtualHost != null) { target = virtualHost; } else { if (uri != null && uri.IsAbsolute() && uri.GetHost() != null) { target = new HttpHost(uri.GetHost(), uri.GetPort(), uri.GetScheme()); } } if (target == null) { target = route.GetTargetHost(); } // Get user info from the URI if (uri != null) { string userinfo = uri.GetUserInfo(); if (userinfo != null) { CredentialsProvider credsProvider = context.GetCredentialsProvider(); if (credsProvider == null) { credsProvider = new BasicCredentialsProvider(); context.SetCredentialsProvider(credsProvider); } credsProvider.SetCredentials(new AuthScope(target), new UsernamePasswordCredentials (userinfo)); } } // Run request protocol interceptors context.SetAttribute(HttpClientContext.HttpTargetHost, target); context.SetAttribute(HttpClientContext.HttpRoute, route); context.SetAttribute(HttpClientContext.HttpRequest, request); this.httpProcessor.Process(request, context); CloseableHttpResponse response = this.requestExecutor.Execute(route, request, context , execAware); try { // Run response protocol interceptors context.SetAttribute(HttpClientContext.HttpResponse, response); this.httpProcessor.Process(response, context); return(response); } catch (RuntimeException ex) { response.Close(); throw; } catch (IOException ex) { response.Close(); throw; } catch (HttpException ex) { response.Close(); throw; } }
/// <exception cref="Apache.Http.HttpException"></exception> /// <exception cref="System.IO.IOException"></exception> public virtual void Process(IHttpRequest request, HttpContext context) { Args.NotNull(request, "HTTP request"); Args.NotNull(context, "HTTP context"); HttpClientContext clientContext = ((HttpClientContext)HttpClientContext.Adapt(context )); AuthCache authCache = clientContext.GetAuthCache(); if (authCache == null) { this.log.Debug("Auth cache not set in the context"); return; } CredentialsProvider credsProvider = clientContext.GetCredentialsProvider(); if (credsProvider == null) { this.log.Debug("Credentials provider not set in the context"); return; } RouteInfo route = clientContext.GetHttpRoute(); HttpHost target = clientContext.GetTargetHost(); if (target.GetPort() < 0) { target = new HttpHost(target.GetHostName(), route.GetTargetHost().GetPort(), target .GetSchemeName()); } AuthState targetState = clientContext.GetTargetAuthState(); if (targetState != null && targetState.GetState() == AuthProtocolState.Unchallenged) { AuthScheme authScheme = authCache.Get(target); if (authScheme != null) { DoPreemptiveAuth(target, authScheme, targetState, credsProvider); } } HttpHost proxy = route.GetProxyHost(); AuthState proxyState = clientContext.GetProxyAuthState(); if (proxy != null && proxyState != null && proxyState.GetState() == AuthProtocolState .Unchallenged) { AuthScheme authScheme = authCache.Get(proxy); if (authScheme != null) { DoPreemptiveAuth(proxy, authScheme, proxyState, credsProvider); } } }
/// <summary>Obtains the scheme for a host.</summary> /// <remarks> /// Obtains the scheme for a host. /// Convenience method for <code>getScheme(host.getSchemeName())</pre> /// </remarks> /// <param name="host">the host for which to obtain the scheme</param> /// <returns>the scheme for the given host, never <code>null</code></returns> /// <exception cref="System.InvalidOperationException">if a scheme with the respective name is not registered /// </exception> public Apache.Http.Conn.Scheme.Scheme GetScheme(HttpHost host) { Args.NotNull(host, "Host"); return(GetScheme(host.GetSchemeName())); }
/// <exception cref="System.IO.IOException"></exception> /// <exception cref="Apache.Http.HttpException"></exception> public virtual Socket Tunnel(HttpHost proxy, HttpHost target, Credentials credentials ) { Args.NotNull(proxy, "Proxy host"); Args.NotNull(target, "Target host"); Args.NotNull(credentials, "Credentials"); HttpHost host = target; if (host.GetPort() <= 0) { host = new HttpHost(host.GetHostName(), 80, host.GetSchemeName()); } HttpRoute route = new HttpRoute(host, this.requestConfig.GetLocalAddress(), proxy , false, RouteInfo.TunnelType.Tunnelled, RouteInfo.LayerType.Plain); ManagedHttpClientConnection conn = this.connFactory.Create(route, this.connectionConfig ); HttpContext context = new BasicHttpContext(); HttpResponse response; IHttpRequest connect = new BasicHttpRequest("CONNECT", host.ToHostString(), HttpVersion .Http11); BasicCredentialsProvider credsProvider = new BasicCredentialsProvider(); credsProvider.SetCredentials(new AuthScope(proxy), credentials); // Populate the execution context context.SetAttribute(HttpCoreContext.HttpTargetHost, target); context.SetAttribute(HttpCoreContext.HttpConnection, conn); context.SetAttribute(HttpCoreContext.HttpRequest, connect); context.SetAttribute(HttpClientContext.HttpRoute, route); context.SetAttribute(HttpClientContext.ProxyAuthState, this.proxyAuthState); context.SetAttribute(HttpClientContext.CredsProvider, credsProvider); context.SetAttribute(HttpClientContext.AuthschemeRegistry, this.authSchemeRegistry ); context.SetAttribute(HttpClientContext.RequestConfig, this.requestConfig); this.requestExec.PreProcess(connect, this.httpProcessor, context); for (; ;) { if (!conn.IsOpen()) { Socket socket = Sharpen.Extensions.CreateSocket(proxy.GetHostName(), proxy.GetPort ()); conn.Bind(socket); } this.authenticator.GenerateAuthResponse(connect, this.proxyAuthState, context); response = this.requestExec.Execute(connect, conn, context); int status = response.GetStatusLine().GetStatusCode(); if (status < 200) { throw new HttpException("Unexpected response to CONNECT request: " + response.GetStatusLine ()); } if (this.authenticator.IsAuthenticationRequested(proxy, response, this.proxyAuthStrategy , this.proxyAuthState, context)) { if (this.authenticator.HandleAuthChallenge(proxy, response, this.proxyAuthStrategy , this.proxyAuthState, context)) { // Retry request if (this.reuseStrategy.KeepAlive(response, context)) { // Consume response content HttpEntity entity = response.GetEntity(); EntityUtils.Consume(entity); } else { conn.Close(); } // discard previous auth header connect.RemoveHeaders(AUTH.ProxyAuthResp); } else { break; } } else { break; } } int status_1 = response.GetStatusLine().GetStatusCode(); if (status_1 > 299) { // Buffer response content HttpEntity entity = response.GetEntity(); if (entity != null) { response.SetEntity(new BufferedHttpEntity(entity)); } conn.Close(); throw new TunnelRefusedException("CONNECT refused by proxy: " + response.GetStatusLine (), response); } return(conn.GetSocket()); }
private bool NeedAuthentication(AuthState targetAuthState, AuthState proxyAuthState , HttpRoute route, HttpResponse response, HttpClientContext context) { RequestConfig config = context.GetRequestConfig(); if (config.IsAuthenticationEnabled()) { HttpHost target = context.GetTargetHost(); if (target == null) { target = route.GetTargetHost(); } if (target.GetPort() < 0) { target = new HttpHost(target.GetHostName(), route.GetTargetHost().GetPort(), target .GetSchemeName()); } if (this.authenticator.IsAuthenticationRequested(target, response, this.targetAuthStrategy , targetAuthState, context)) { return(this.authenticator.HandleAuthChallenge(target, response, this.targetAuthStrategy , targetAuthState, context)); } HttpHost proxy = route.GetProxyHost(); if (this.authenticator.IsAuthenticationRequested(proxy, response, this.proxyAuthStrategy , proxyAuthState, context)) { // if proxy is not set use target host instead if (proxy == null) { proxy = route.GetTargetHost(); } return(this.authenticator.HandleAuthChallenge(proxy, response, this.proxyAuthStrategy , proxyAuthState, context)); } } return(false); }