/// <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()); }
/// <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="System.IO.IOException"></exception> public virtual System.Net.Sockets.Socket ConnectSocket(int connectTimeout, System.Net.Sockets.Socket socket, HttpHost host, IPEndPoint remoteAddress, IPEndPoint localAddress, HttpContext context) { Args.NotNull(host, "HTTP host"); Args.NotNull(remoteAddress, "Remote address"); System.Net.Sockets.Socket sock = socket != null ? socket : CreateSocket(context); if (localAddress != null) { sock.Bind2(localAddress); } try { sock.Connect(remoteAddress, connectTimeout); } catch (IOException ex) { try { sock.Close(); } catch (IOException) { } throw; } // Setup SSL layering if necessary if (sock is SSLSocket) { SSLSocket sslsock = (SSLSocket)sock; sslsock.StartHandshake(); VerifyHostname(sslsock, host.GetHostName()); return(sock); } else { return(CreateLayeredSocket(sock, host.GetHostName(), remoteAddress.Port, context)); } }
/// <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); } } }
/// <exception cref="Apache.Http.HttpException"></exception> /// <exception cref="System.IO.IOException"></exception> public void Process(HttpWebRequest request, HttpContext context) { AuthState authState = (AuthState)context.GetAttribute(ClientContext.TargetAuthState ); CredentialsProvider credsProvider = (CredentialsProvider)context.GetAttribute(ClientContext .CredsProvider); HttpHost targetHost = (HttpHost)context.GetAttribute(ExecutionContext.HttpTargetHost ); if (authState.GetAuthScheme() == null) { AuthScope authScope = new AuthScope(targetHost.GetHostName(), targetHost.GetPort( )); authState.SetAuthScheme(new BasicScheme()); authState.SetCredentials(creds); } }
/// <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); } }
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); }
/// <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.Auth.MalformedChallengeException"></exception> public virtual Queue <AuthOption> Select(IDictionary <string, Header> challenges, HttpHost authhost, HttpResponse response, HttpContext context) { Args.NotNull(challenges, "Map of auth challenges"); Args.NotNull(authhost, "Host"); Args.NotNull(response, "HTTP response"); Args.NotNull(context, "HTTP context"); HttpClientContext clientContext = ((HttpClientContext)HttpClientContext.Adapt(context )); Queue <AuthOption> options = new List <AuthOption>(); Lookup <AuthSchemeProvider> registry = clientContext.GetAuthSchemeRegistry(); if (registry == null) { this.log.Debug("Auth scheme registry not set in the context"); return(options); } CredentialsProvider credsProvider = clientContext.GetCredentialsProvider(); if (credsProvider == null) { this.log.Debug("Credentials provider not set in the context"); return(options); } RequestConfig config = clientContext.GetRequestConfig(); ICollection <string> authPrefs = GetPreferredAuthSchemes(config); if (authPrefs == null) { authPrefs = DefaultSchemePriority; } if (this.log.IsDebugEnabled()) { this.log.Debug("Authentication schemes in the order of preference: " + authPrefs); } foreach (string id in authPrefs) { Header challenge = challenges.Get(id.ToLower(CultureInfo.InvariantCulture)); if (challenge != null) { AuthSchemeProvider authSchemeProvider = registry.Lookup(id); if (authSchemeProvider == null) { if (this.log.IsWarnEnabled()) { this.log.Warn("Authentication scheme " + id + " not supported"); } // Try again continue; } AuthScheme authScheme = authSchemeProvider.Create(context); authScheme.ProcessChallenge(challenge); AuthScope authScope = new AuthScope(authhost.GetHostName(), authhost.GetPort(), authScheme .GetRealm(), authScheme.GetSchemeName()); Credentials credentials = credsProvider.GetCredentials(authScope); if (credentials != null) { options.AddItem(new AuthOption(authScheme, credentials)); } } else { if (this.log.IsDebugEnabled()) { this.log.Debug("Challenge for " + id + " authentication scheme not available"); } } } // Try again return(options); }
/// <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"); string method = request.GetRequestLine().GetMethod(); if (Sharpen.Runtime.EqualsIgnoreCase(method, "CONNECT")) { return; } HttpClientContext clientContext = ((HttpClientContext)HttpClientContext.Adapt(context )); // Obtain cookie store CookieStore cookieStore = clientContext.GetCookieStore(); if (cookieStore == null) { this.log.Debug("Cookie store not specified in HTTP context"); return; } // Obtain the registry of cookie specs Lookup <CookieSpecProvider> registry = clientContext.GetCookieSpecRegistry(); if (registry == null) { this.log.Debug("CookieSpec registry not specified in HTTP context"); return; } // Obtain the target host, possibly virtual (required) HttpHost targetHost = clientContext.GetTargetHost(); if (targetHost == null) { this.log.Debug("Target host not set in the context"); return; } // Obtain the route (required) RouteInfo route = clientContext.GetHttpRoute(); if (route == null) { this.log.Debug("Connection route not set in the context"); return; } RequestConfig config = clientContext.GetRequestConfig(); string policy = config.GetCookieSpec(); if (policy == null) { policy = CookieSpecs.BestMatch; } if (this.log.IsDebugEnabled()) { this.log.Debug("CookieSpec selected: " + policy); } URI requestURI = null; if (request is IHttpUriRequest) { requestURI = ((IHttpUriRequest)request).GetURI(); } else { try { requestURI = new URI(request.GetRequestLine().GetUri()); } catch (URISyntaxException) { } } string path = requestURI != null?requestURI.GetPath() : null; string hostName = targetHost.GetHostName(); int port = targetHost.GetPort(); if (port < 0) { port = route.GetTargetHost().GetPort(); } CookieOrigin cookieOrigin = new CookieOrigin(hostName, port >= 0 ? port : 0, !TextUtils .IsEmpty(path) ? path : "/", route.IsSecure()); // Get an instance of the selected cookie policy CookieSpecProvider provider = registry.Lookup(policy); if (provider == null) { throw new HttpException("Unsupported cookie policy: " + policy); } CookieSpec cookieSpec = provider.Create(clientContext); // Get all cookies available in the HTTP state IList <Apache.Http.Cookie.Cookie> cookies = new AList <Apache.Http.Cookie.Cookie>(cookieStore .GetCookies()); // Find cookies matching the given origin IList <Apache.Http.Cookie.Cookie> matchedCookies = new AList <Apache.Http.Cookie.Cookie >(); DateTime now = new DateTime(); foreach (Apache.Http.Cookie.Cookie cookie in cookies) { if (!cookie.IsExpired(now)) { if (cookieSpec.Match(cookie, cookieOrigin)) { if (this.log.IsDebugEnabled()) { this.log.Debug("Cookie " + cookie + " match " + cookieOrigin); } matchedCookies.AddItem(cookie); } } else { if (this.log.IsDebugEnabled()) { this.log.Debug("Cookie " + cookie + " expired"); } } } // Generate Cookie request headers if (!matchedCookies.IsEmpty()) { IList <Header> headers = cookieSpec.FormatCookies(matchedCookies); foreach (Header header in headers) { request.AddHeader(header); } } int ver = cookieSpec.GetVersion(); if (ver > 0) { bool needVersionHeader = false; foreach (Apache.Http.Cookie.Cookie cookie_1 in matchedCookies) { if (ver != cookie_1.GetVersion() || !(cookie_1 is SetCookie2)) { needVersionHeader = true; } } if (needVersionHeader) { Header header = cookieSpec.GetVersionHeader(); if (header != null) { // Advertise cookie version support request.AddHeader(header); } } } // Stick the CookieSpec and CookieOrigin instances to the HTTP context // so they could be obtained by the response interceptor context.SetAttribute(HttpClientContext.CookieSpec, cookieSpec); context.SetAttribute(HttpClientContext.CookieOrigin, cookieOrigin); }
/// <since>4.2</since> public AuthScope(HttpHost host, string realm, string schemeName) : this(host.GetHostName (), host.GetPort(), realm, schemeName) { }
/// <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()); }