1ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel// copied verbatim (except for constructor access) from httpclient-4.0.3 sources 2ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel 3ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel/* 4ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel * ==================================================================== 5ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel * Licensed to the Apache Software Foundation (ASF) under one 6ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel * or more contributor license agreements. See the NOTICE file 7ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel * distributed with this work for additional information 8ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel * regarding copyright ownership. The ASF licenses this file 9ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel * to you under the Apache License, Version 2.0 (the 10ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel * "License"); you may not use this file except in compliance 11ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel * with the License. You may obtain a copy of the License at 12ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel * 13ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel * http://www.apache.org/licenses/LICENSE-2.0 14ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel * 15ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel * Unless required by applicable law or agreed to in writing, 16ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel * software distributed under the License is distributed on an 17ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 18ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel * KIND, either express or implied. See the License for the 19ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel * specific language governing permissions and limitations 20ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel * under the License. 21ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel * ==================================================================== 22ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel * 23ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel * This software consists of voluntary contributions made by many 24ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel * individuals on behalf of the Apache Software Foundation. For more 25ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel * information on the Apache Software Foundation, please see 26ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel * <http://www.apache.org/>. 27ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel * 28ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel */ 29ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkelpackage com.xtremelabs.robolectric.tester.org.apache.http.impl.client; 30ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel 31ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkelimport org.apache.commons.logging.Log; 32ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkelimport org.apache.commons.logging.LogFactory; 334c5da7f8a2e3567f6b8cb2f26a5fc87907dbf208Amrit Thakur & Ryan Richardimport org.apache.http.*; 344c5da7f8a2e3567f6b8cb2f26a5fc87907dbf208Amrit Thakur & Ryan Richardimport org.apache.http.annotation.NotThreadSafe; 354c5da7f8a2e3567f6b8cb2f26a5fc87907dbf208Amrit Thakur & Ryan Richardimport org.apache.http.auth.*; 364c5da7f8a2e3567f6b8cb2f26a5fc87907dbf208Amrit Thakur & Ryan Richardimport org.apache.http.client.*; 37ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkelimport org.apache.http.client.methods.AbortableHttpRequest; 38ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkelimport org.apache.http.client.params.ClientPNames; 39ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkelimport org.apache.http.client.params.HttpClientParams; 40ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkelimport org.apache.http.client.protocol.ClientContext; 41ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkelimport org.apache.http.client.utils.URIUtils; 424c5da7f8a2e3567f6b8cb2f26a5fc87907dbf208Amrit Thakur & Ryan Richardimport org.apache.http.conn.*; 43ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkelimport org.apache.http.conn.params.ConnManagerParams; 44ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkelimport org.apache.http.conn.routing.BasicRouteDirector; 45ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkelimport org.apache.http.conn.routing.HttpRoute; 46ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkelimport org.apache.http.conn.routing.HttpRouteDirector; 47ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkelimport org.apache.http.conn.routing.HttpRoutePlanner; 48ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkelimport org.apache.http.conn.scheme.Scheme; 49ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkelimport org.apache.http.entity.BufferedHttpEntity; 50ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkelimport org.apache.http.impl.client.EntityEnclosingRequestWrapper; 51ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkelimport org.apache.http.impl.client.RequestWrapper; 52ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkelimport org.apache.http.impl.client.RoutedRequest; 53ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkelimport org.apache.http.impl.client.TunnelRefusedException; 54ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkelimport org.apache.http.message.BasicHttpRequest; 55ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkelimport org.apache.http.params.HttpConnectionParams; 56ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkelimport org.apache.http.params.HttpParams; 57ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkelimport org.apache.http.params.HttpProtocolParams; 58ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkelimport org.apache.http.protocol.ExecutionContext; 59ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkelimport org.apache.http.protocol.HttpContext; 60ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkelimport org.apache.http.protocol.HttpProcessor; 61ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkelimport org.apache.http.protocol.HttpRequestExecutor; 62ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel 634c5da7f8a2e3567f6b8cb2f26a5fc87907dbf208Amrit Thakur & Ryan Richardimport java.io.IOException; 644c5da7f8a2e3567f6b8cb2f26a5fc87907dbf208Amrit Thakur & Ryan Richardimport java.io.InterruptedIOException; 654c5da7f8a2e3567f6b8cb2f26a5fc87907dbf208Amrit Thakur & Ryan Richardimport java.net.URI; 664c5da7f8a2e3567f6b8cb2f26a5fc87907dbf208Amrit Thakur & Ryan Richardimport java.net.URISyntaxException; 674c5da7f8a2e3567f6b8cb2f26a5fc87907dbf208Amrit Thakur & Ryan Richardimport java.util.Locale; 684c5da7f8a2e3567f6b8cb2f26a5fc87907dbf208Amrit Thakur & Ryan Richardimport java.util.Map; 694c5da7f8a2e3567f6b8cb2f26a5fc87907dbf208Amrit Thakur & Ryan Richardimport java.util.concurrent.TimeUnit; 704c5da7f8a2e3567f6b8cb2f26a5fc87907dbf208Amrit Thakur & Ryan Richard 71ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel/** 72ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel * Default implementation of {@link RequestDirector}. 73ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel * <p> 74ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel * The following parameters can be used to customize the behavior of this 75ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel * class: 76ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel * <ul> 77ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel * <li>{@link org.apache.http.params.CoreProtocolPNames#PROTOCOL_VERSION}</li> 78ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel * <li>{@link org.apache.http.params.CoreProtocolPNames#STRICT_TRANSFER_ENCODING}</li> 79ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel * <li>{@link org.apache.http.params.CoreProtocolPNames#HTTP_ELEMENT_CHARSET}</li> 80ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel * <li>{@link org.apache.http.params.CoreProtocolPNames#USE_EXPECT_CONTINUE}</li> 81ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel * <li>{@link org.apache.http.params.CoreProtocolPNames#WAIT_FOR_CONTINUE}</li> 82ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel * <li>{@link org.apache.http.params.CoreProtocolPNames#USER_AGENT}</li> 83ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel * <li>{@link org.apache.http.params.CoreConnectionPNames#SOCKET_BUFFER_SIZE}</li> 84ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel * <li>{@link org.apache.http.params.CoreConnectionPNames#MAX_LINE_LENGTH}</li> 85ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel * <li>{@link org.apache.http.params.CoreConnectionPNames#MAX_HEADER_COUNT}</li> 86ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel * <li>{@link org.apache.http.params.CoreConnectionPNames#SO_TIMEOUT}</li> 87ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel * <li>{@link org.apache.http.params.CoreConnectionPNames#SO_LINGER}</li> 88ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel * <li>{@link org.apache.http.params.CoreConnectionPNames#TCP_NODELAY}</li> 89ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel * <li>{@link org.apache.http.params.CoreConnectionPNames#CONNECTION_TIMEOUT}</li> 90ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel * <li>{@link org.apache.http.params.CoreConnectionPNames#STALE_CONNECTION_CHECK}</li> 91ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel * <li>{@link org.apache.http.conn.params.ConnRoutePNames#FORCED_ROUTE}</li> 92ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel * <li>{@link org.apache.http.conn.params.ConnRoutePNames#LOCAL_ADDRESS}</li> 93ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel * <li>{@link org.apache.http.conn.params.ConnRoutePNames#DEFAULT_PROXY}</li> 94ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel * <li>{@link org.apache.http.conn.params.ConnManagerPNames#TIMEOUT}</li> 95ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel * <li>{@link org.apache.http.conn.params.ConnManagerPNames#MAX_CONNECTIONS_PER_ROUTE}</li> 96ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel * <li>{@link org.apache.http.conn.params.ConnManagerPNames#MAX_TOTAL_CONNECTIONS}</li> 97ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel * <li>{@link org.apache.http.cookie.params.CookieSpecPNames#DATE_PATTERNS}</li> 98ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel * <li>{@link org.apache.http.cookie.params.CookieSpecPNames#SINGLE_COOKIE_HEADER}</li> 99ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel * <li>{@link org.apache.http.auth.params.AuthPNames#CREDENTIAL_CHARSET}</li> 100ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel * <li>{@link org.apache.http.client.params.ClientPNames#COOKIE_POLICY}</li> 101ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel * <li>{@link org.apache.http.client.params.ClientPNames#HANDLE_AUTHENTICATION}</li> 102ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel * <li>{@link org.apache.http.client.params.ClientPNames#HANDLE_REDIRECTS}</li> 103ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel * <li>{@link org.apache.http.client.params.ClientPNames#MAX_REDIRECTS}</li> 104ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel * <li>{@link org.apache.http.client.params.ClientPNames#ALLOW_CIRCULAR_REDIRECTS}</li> 105ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel * <li>{@link org.apache.http.client.params.ClientPNames#VIRTUAL_HOST}</li> 106ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel * <li>{@link org.apache.http.client.params.ClientPNames#DEFAULT_HOST}</li> 107ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel * <li>{@link org.apache.http.client.params.ClientPNames#DEFAULT_HEADERS}</li> 108ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel * </ul> 109ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel * 110ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel * @since 4.0 111ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel */ 112ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel@NotThreadSafe // e.g. managedConn 113ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkelpublic class DefaultRequestDirector implements RequestDirector { 114ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel 115ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel private final Log log; 116ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel 117ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel /** The connection manager. */ 118ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel protected final ClientConnectionManager connManager; 119ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel 120ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel /** The route planner. */ 121ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel protected final HttpRoutePlanner routePlanner; 122ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel 123ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel /** The connection re-use strategy. */ 124ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel protected final ConnectionReuseStrategy reuseStrategy; 125ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel 126ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel /** The keep-alive duration strategy. */ 127ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel protected final ConnectionKeepAliveStrategy keepAliveStrategy; 128ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel 129ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel /** The request executor. */ 130ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel protected final HttpRequestExecutor requestExec; 131ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel 132ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel /** The HTTP protocol processor. */ 133ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel protected final HttpProcessor httpProcessor; 134ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel 135ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel /** The request retry handler. */ 136ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel protected final HttpRequestRetryHandler retryHandler; 137ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel 138ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel /** The redirect handler. */ 139ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel protected final RedirectHandler redirectHandler; 140ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel 141ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel /** The target authentication handler. */ 142ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel protected final AuthenticationHandler targetAuthHandler; 143ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel 144ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel /** The proxy authentication handler. */ 145ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel protected final AuthenticationHandler proxyAuthHandler; 146ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel 147ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel /** The user token handler. */ 148ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel protected final UserTokenHandler userTokenHandler; 149ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel 150ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel /** The HTTP parameters. */ 151ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel protected final HttpParams params; 152ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel 153ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel /** The currently allocated connection. */ 154ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel protected ManagedClientConnection managedConn; 155ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel 156ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel protected final AuthState targetAuthState; 157ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel 158ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel protected final AuthState proxyAuthState; 159ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel 160ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel private int redirectCount; 161ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel 162ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel private int maxRedirects; 163ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel 164ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel private HttpHost virtualHost; 165ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel 166ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel public DefaultRequestDirector( 167ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel final Log log, 168ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel final HttpRequestExecutor requestExec, 169ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel final ClientConnectionManager conman, 170ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel final ConnectionReuseStrategy reustrat, 171ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel final ConnectionKeepAliveStrategy kastrat, 172ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel final HttpRoutePlanner rouplan, 173ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel final HttpProcessor httpProcessor, 174ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel final HttpRequestRetryHandler retryHandler, 175ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel final RedirectHandler redirectHandler, 176ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel final AuthenticationHandler targetAuthHandler, 177ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel final AuthenticationHandler proxyAuthHandler, 178ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel final UserTokenHandler userTokenHandler, 179ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel final HttpParams params) { 180ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel 181ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel if (log == null) { 182ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel throw new IllegalArgumentException 183ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel ("Log may not be null."); 184ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel } 185ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel if (requestExec == null) { 186ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel throw new IllegalArgumentException 187ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel ("Request executor may not be null."); 188ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel } 189ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel if (conman == null) { 190ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel throw new IllegalArgumentException 191ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel ("Client connection manager may not be null."); 192ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel } 193ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel if (reustrat == null) { 194ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel throw new IllegalArgumentException 195ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel ("Connection reuse strategy may not be null."); 196ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel } 197ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel if (kastrat == null) { 198ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel throw new IllegalArgumentException 199ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel ("Connection keep alive strategy may not be null."); 200ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel } 201ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel if (rouplan == null) { 202ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel throw new IllegalArgumentException 203ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel ("Route planner may not be null."); 204ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel } 205ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel if (httpProcessor == null) { 206ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel throw new IllegalArgumentException 207ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel ("HTTP protocol processor may not be null."); 208ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel } 209ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel if (retryHandler == null) { 210ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel throw new IllegalArgumentException 211ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel ("HTTP request retry handler may not be null."); 212ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel } 213ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel if (redirectHandler == null) { 214ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel throw new IllegalArgumentException 215ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel ("Redirect handler may not be null."); 216ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel } 217ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel if (targetAuthHandler == null) { 218ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel throw new IllegalArgumentException 219ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel ("Target authentication handler may not be null."); 220ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel } 221ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel if (proxyAuthHandler == null) { 222ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel throw new IllegalArgumentException 223ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel ("Proxy authentication handler may not be null."); 224ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel } 225ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel if (userTokenHandler == null) { 226ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel throw new IllegalArgumentException 227ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel ("User token handler may not be null."); 228ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel } 229ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel if (params == null) { 230ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel throw new IllegalArgumentException 231ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel ("HTTP parameters may not be null"); 232ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel } 233ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel this.log = log; 234ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel this.requestExec = requestExec; 235ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel this.connManager = conman; 236ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel this.reuseStrategy = reustrat; 237ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel this.keepAliveStrategy = kastrat; 238ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel this.routePlanner = rouplan; 239ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel this.httpProcessor = httpProcessor; 240ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel this.retryHandler = retryHandler; 241ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel this.redirectHandler = redirectHandler; 242ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel this.targetAuthHandler = targetAuthHandler; 243ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel this.proxyAuthHandler = proxyAuthHandler; 244ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel this.userTokenHandler = userTokenHandler; 245ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel this.params = params; 246ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel 247ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel this.managedConn = null; 248ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel 249ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel this.redirectCount = 0; 250ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel this.maxRedirects = this.params.getIntParameter(ClientPNames.MAX_REDIRECTS, 100); 251ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel this.targetAuthState = new AuthState(); 252ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel this.proxyAuthState = new AuthState(); 253ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel } // constructor 254ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel 255ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel public DefaultRequestDirector( 256ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel final HttpRequestExecutor requestExec, 257ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel final ClientConnectionManager conman, 258ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel final ConnectionReuseStrategy reustrat, 259ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel final ConnectionKeepAliveStrategy kastrat, 260ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel final HttpRoutePlanner rouplan, 261ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel final HttpProcessor httpProcessor, 262ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel final HttpRequestRetryHandler retryHandler, 263ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel final RedirectHandler redirectHandler, 264ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel final AuthenticationHandler targetAuthHandler, 265ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel final AuthenticationHandler proxyAuthHandler, 266ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel final UserTokenHandler userTokenHandler, 267ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel final HttpParams params) { 268ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel this(LogFactory.getLog(DefaultRequestDirector.class), 269ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel requestExec, 270ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel conman, 271ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel reustrat, 272ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel kastrat, 273ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel rouplan, 274ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel httpProcessor, 275ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel retryHandler, 276ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel redirectHandler, 277ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel targetAuthHandler, 278ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel proxyAuthHandler, 279ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel userTokenHandler, 280ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel params); 281ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel 282ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel } 283ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel 284ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel private RequestWrapper wrapRequest( 285ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel final HttpRequest request) throws ProtocolException { 286ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel if (request instanceof HttpEntityEnclosingRequest) { 287ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel return new EntityEnclosingRequestWrapper( 288ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel (HttpEntityEnclosingRequest) request); 289ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel } else { 290ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel return new RequestWrapper( 291ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel request); 292ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel } 293ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel } 294ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel 295ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel 296ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel protected void rewriteRequestURI( 297ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel final RequestWrapper request, 298ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel final HttpRoute route) throws ProtocolException { 299ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel try { 300ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel 301ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel URI uri = request.getURI(); 302ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel if (route.getProxyHost() != null && !route.isTunnelled()) { 303ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel // Make sure the request URI is absolute 304ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel if (!uri.isAbsolute()) { 305ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel HttpHost target = route.getTargetHost(); 306ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel uri = URIUtils.rewriteURI(uri, target); 307ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel request.setURI(uri); 308ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel } 309ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel } else { 310ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel // Make sure the request URI is relative 311ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel if (uri.isAbsolute()) { 312ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel uri = URIUtils.rewriteURI(uri, null); 313ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel request.setURI(uri); 314ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel } 315ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel } 316ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel 317ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel } catch (URISyntaxException ex) { 318ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel throw new ProtocolException("Invalid URI: " + 319ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel request.getRequestLine().getUri(), ex); 320ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel } 321ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel } 322ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel 323ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel 324ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel // non-javadoc, see interface ClientRequestDirector 325ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel public HttpResponse execute(HttpHost target, HttpRequest request, 326ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel HttpContext context) 327ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel throws HttpException, IOException { 328ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel 329ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel HttpRequest orig = request; 330ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel RequestWrapper origWrapper = wrapRequest(orig); 331ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel origWrapper.setParams(params); 332ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel HttpRoute origRoute = determineRoute(target, origWrapper, context); 333ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel 334ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel virtualHost = (HttpHost) orig.getParams().getParameter( 335ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel ClientPNames.VIRTUAL_HOST); 336ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel 337ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel RoutedRequest roureq = new RoutedRequest(origWrapper, origRoute); 338ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel 339ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel long timeout = ConnManagerParams.getTimeout(params); 340ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel 341ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel int execCount = 0; 342ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel 343ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel boolean reuse = false; 344ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel boolean done = false; 345ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel try { 346ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel HttpResponse response = null; 347ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel while (!done) { 348ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel // In this loop, the RoutedRequest may be replaced by a 349ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel // followup request and route. The request and route passed 350ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel // in the method arguments will be replaced. The original 351ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel // request is still available in 'orig'. 352ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel 353ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel RequestWrapper wrapper = roureq.getRequest(); 354ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel HttpRoute route = roureq.getRoute(); 355ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel response = null; 356ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel 357ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel // See if we have a user token bound to the execution context 358ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel Object userToken = context.getAttribute(ClientContext.USER_TOKEN); 359ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel 360ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel // Allocate connection if needed 361ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel if (managedConn == null) { 362ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel ClientConnectionRequest connRequest = connManager.requestConnection( 363ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel route, userToken); 364ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel if (orig instanceof AbortableHttpRequest) { 365ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel ((AbortableHttpRequest) orig).setConnectionRequest(connRequest); 366ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel } 367ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel 368ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel try { 369ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel managedConn = connRequest.getConnection(timeout, TimeUnit.MILLISECONDS); 370ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel } catch(InterruptedException interrupted) { 371ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel InterruptedIOException iox = new InterruptedIOException(); 372ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel iox.initCause(interrupted); 373ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel throw iox; 374ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel } 375ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel 376ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel if (HttpConnectionParams.isStaleCheckingEnabled(params)) { 377ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel // validate connection 378ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel if (managedConn.isOpen()) { 379ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel this.log.debug("Stale connection check"); 380ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel if (managedConn.isStale()) { 381ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel this.log.debug("Stale connection detected"); 382ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel managedConn.close(); 383ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel } 384ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel } 385ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel } 386ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel } 387ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel 388ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel if (orig instanceof AbortableHttpRequest) { 389ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel ((AbortableHttpRequest) orig).setReleaseTrigger(managedConn); 390ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel } 391ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel 392ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel // Reopen connection if needed 393ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel if (!managedConn.isOpen()) { 394ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel managedConn.open(route, context, params); 395ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel } else { 396ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel managedConn.setSocketTimeout(HttpConnectionParams.getSoTimeout(params)); 397ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel } 398ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel 399ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel try { 400ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel establishRoute(route, context); 401ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel } catch (TunnelRefusedException ex) { 402ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel if (this.log.isDebugEnabled()) { 403ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel this.log.debug(ex.getMessage()); 404ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel } 405ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel response = ex.getResponse(); 406ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel break; 407ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel } 408ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel 409ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel // Reset headers on the request wrapper 410ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel wrapper.resetHeaders(); 411ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel 412ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel // Re-write request URI if needed 413ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel rewriteRequestURI(wrapper, route); 414ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel 415ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel // Use virtual host if set 416ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel target = virtualHost; 417ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel 418ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel if (target == null) { 419ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel target = route.getTargetHost(); 420ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel } 421ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel 422ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel HttpHost proxy = route.getProxyHost(); 423ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel 424ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel // Populate the execution context 425ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel context.setAttribute(ExecutionContext.HTTP_TARGET_HOST, 426ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel target); 427ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel context.setAttribute(ExecutionContext.HTTP_PROXY_HOST, 428ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel proxy); 429ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel context.setAttribute(ExecutionContext.HTTP_CONNECTION, 430ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel managedConn); 431ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel context.setAttribute(ClientContext.TARGET_AUTH_STATE, 432ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel targetAuthState); 433ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel context.setAttribute(ClientContext.PROXY_AUTH_STATE, 434ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel proxyAuthState); 435ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel 436ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel // Run request protocol interceptors 437ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel requestExec.preProcess(wrapper, httpProcessor, context); 438ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel 439ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel boolean retrying = true; 440ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel Exception retryReason = null; 441ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel while (retrying) { 442ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel // Increment total exec count (with redirects) 443ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel execCount++; 444ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel // Increment exec count for this particular request 445ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel wrapper.incrementExecCount(); 446ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel if (!wrapper.isRepeatable()) { 447ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel this.log.debug("Cannot retry non-repeatable request"); 448ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel if (retryReason != null) { 449ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel throw new NonRepeatableRequestException("Cannot retry request " + 450ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel "with a non-repeatable request entity. The cause lists the " + 4514c5da7f8a2e3567f6b8cb2f26a5fc87907dbf208Amrit Thakur & Ryan Richard "reason the original request failed: " + retryReason); 452ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel } else { 453ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel throw new NonRepeatableRequestException("Cannot retry request " + 454ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel "with a non-repeatable request entity."); 455ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel } 456ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel } 457ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel 458ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel try { 459ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel if (this.log.isDebugEnabled()) { 460ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel this.log.debug("Attempt " + execCount + " to execute request"); 461ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel } 462ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel response = requestExec.execute(wrapper, managedConn, context); 463ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel retrying = false; 464ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel 465ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel } catch (IOException ex) { 466ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel this.log.debug("Closing the connection."); 467ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel managedConn.close(); 468ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel if (retryHandler.retryRequest(ex, wrapper.getExecCount(), context)) { 469ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel if (this.log.isInfoEnabled()) { 470ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel this.log.info("I/O exception ("+ ex.getClass().getName() + 471ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel ") caught when processing request: " 472ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel + ex.getMessage()); 473ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel } 474ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel if (this.log.isDebugEnabled()) { 475ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel this.log.debug(ex.getMessage(), ex); 476ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel } 477ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel this.log.info("Retrying request"); 478ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel retryReason = ex; 479ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel } else { 480ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel throw ex; 481ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel } 482ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel 483ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel // If we have a direct route to the target host 484ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel // just re-open connection and re-try the request 485ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel if (!route.isTunnelled()) { 486ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel this.log.debug("Reopening the direct connection."); 487ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel managedConn.open(route, context, params); 488ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel } else { 489ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel // otherwise give up 490ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel this.log.debug("Proxied connection. Need to start over."); 491ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel retrying = false; 492ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel } 493ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel 494ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel } 495ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel 496ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel } 497ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel 498ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel if (response == null) { 499ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel // Need to start over 500ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel continue; 501ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel } 502ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel 503ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel // Run response protocol interceptors 504ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel response.setParams(params); 505ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel requestExec.postProcess(response, httpProcessor, context); 506ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel 507ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel 508ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel // The connection is in or can be brought to a re-usable state. 509ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel reuse = reuseStrategy.keepAlive(response, context); 510ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel if (reuse) { 511ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel // Set the idle duration of this connection 512ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel long duration = keepAliveStrategy.getKeepAliveDuration(response, context); 513ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel managedConn.setIdleDuration(duration, TimeUnit.MILLISECONDS); 514ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel 515ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel if (this.log.isDebugEnabled()) { 516ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel if (duration >= 0) { 517ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel this.log.debug("Connection can be kept alive for " + duration + " ms"); 518ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel } else { 519ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel this.log.debug("Connection can be kept alive indefinitely"); 520ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel } 521ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel } 522ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel } 523ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel 524ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel RoutedRequest followup = handleResponse(roureq, response, context); 525ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel if (followup == null) { 526ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel done = true; 527ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel } else { 528ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel if (reuse) { 529ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel // Make sure the response body is fully consumed, if present 530ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel HttpEntity entity = response.getEntity(); 531ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel if (entity != null) { 532ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel entity.consumeContent(); 533ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel } 534ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel // entity consumed above is not an auto-release entity, 535ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel // need to mark the connection re-usable explicitly 536ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel managedConn.markReusable(); 537ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel } else { 538ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel managedConn.close(); 539ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel } 540ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel // check if we can use the same connection for the followup 541ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel if (!followup.getRoute().equals(roureq.getRoute())) { 542ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel releaseConnection(); 543ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel } 544ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel roureq = followup; 545ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel } 546ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel 547ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel if (managedConn != null && userToken == null) { 548ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel userToken = userTokenHandler.getUserToken(context); 549ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel context.setAttribute(ClientContext.USER_TOKEN, userToken); 550ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel if (userToken != null) { 551ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel managedConn.setState(userToken); 552ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel } 553ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel } 554ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel 555ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel } // while not done 556ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel 557ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel 558ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel // check for entity, release connection if possible 559ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel if ((response == null) || (response.getEntity() == null) || 560ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel !response.getEntity().isStreaming()) { 561ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel // connection not needed and (assumed to be) in re-usable state 562ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel if (reuse) 563ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel managedConn.markReusable(); 564ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel releaseConnection(); 565ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel } else { 566ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel // install an auto-release entity 567ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel HttpEntity entity = response.getEntity(); 568ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel entity = new BasicManagedEntity(entity, managedConn, reuse); 569ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel response.setEntity(entity); 570ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel } 571ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel 572ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel return response; 573ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel 574ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel } catch (HttpException ex) { 575ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel abortConnection(); 576ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel throw ex; 577ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel } catch (IOException ex) { 578ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel abortConnection(); 579ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel throw ex; 580ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel } catch (RuntimeException ex) { 581ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel abortConnection(); 582ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel throw ex; 583ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel } 584ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel } // execute 585ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel 586ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel /** 587ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel * Returns the connection back to the connection manager 588ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel * and prepares for retrieving a new connection during 589ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel * the next request. 590ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel */ 591ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel protected void releaseConnection() { 592ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel // Release the connection through the ManagedConnection instead of the 593ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel // ConnectionManager directly. This lets the connection control how 594ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel // it is released. 595ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel try { 596ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel managedConn.releaseConnection(); 597ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel } catch(IOException ignored) { 598ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel this.log.debug("IOException releasing connection", ignored); 599ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel } 600ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel managedConn = null; 601ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel } 602ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel 603ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel /** 604ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel * Determines the route for a request. 605ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel * Called by {@link #execute} 606ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel * to determine the route for either the original or a followup request. 607ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel * 608ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel * @param target the target host for the request. 609ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel * Implementations may accept <code>null</code> 610ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel * if they can still determine a route, for example 611ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel * to a default target or by inspecting the request. 612ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel * @param request the request to execute 613ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel * @param context the context to use for the execution, 614ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel * never <code>null</code> 615ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel * 616ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel * @return the route the request should take 617ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel * 618ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel * @throws HttpException in case of a problem 619ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel */ 620ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel protected HttpRoute determineRoute(HttpHost target, 621ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel HttpRequest request, 622ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel HttpContext context) 623ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel throws HttpException { 624ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel 625ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel if (target == null) { 626ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel target = (HttpHost) request.getParams().getParameter( 627ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel ClientPNames.DEFAULT_HOST); 628ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel } 629ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel if (target == null) { 630ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel throw new IllegalStateException 631ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel ("Target host must not be null, or set in parameters."); 632ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel } 633ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel 634ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel return this.routePlanner.determineRoute(target, request, context); 635ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel } 636ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel 637ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel 638ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel /** 639ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel * Establishes the target route. 640ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel * 641ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel * @param route the route to establish 642ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel * @param context the context for the request execution 643ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel * 644ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel * @throws HttpException in case of a problem 645ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel * @throws IOException in case of an IO problem 646ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel */ 647ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel protected void establishRoute(HttpRoute route, HttpContext context) 648ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel throws HttpException, IOException { 649ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel 650ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel HttpRouteDirector rowdy = new BasicRouteDirector(); 651ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel int step; 652ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel do { 653ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel HttpRoute fact = managedConn.getRoute(); 654ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel step = rowdy.nextStep(route, fact); 655ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel 656ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel switch (step) { 657ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel 658ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel case HttpRouteDirector.CONNECT_TARGET: 659ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel case HttpRouteDirector.CONNECT_PROXY: 660ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel managedConn.open(route, context, this.params); 661ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel break; 662ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel 663ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel case HttpRouteDirector.TUNNEL_TARGET: { 664ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel boolean secure = createTunnelToTarget(route, context); 665ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel this.log.debug("Tunnel to target created."); 666ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel managedConn.tunnelTarget(secure, this.params); 667ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel } break; 668ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel 669ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel case HttpRouteDirector.TUNNEL_PROXY: { 670ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel // The most simple example for this case is a proxy chain 671ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel // of two proxies, where P1 must be tunnelled to P2. 672ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel // route: Source -> P1 -> P2 -> Target (3 hops) 673ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel // fact: Source -> P1 -> Target (2 hops) 674ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel final int hop = fact.getHopCount()-1; // the hop to establish 675ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel boolean secure = createTunnelToProxy(route, hop, context); 676ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel this.log.debug("Tunnel to proxy created."); 677ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel managedConn.tunnelProxy(route.getHopTarget(hop), 678ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel secure, this.params); 679ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel } break; 680ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel 681ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel 682ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel case HttpRouteDirector.LAYER_PROTOCOL: 683ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel managedConn.layerProtocol(context, this.params); 684ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel break; 685ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel 686ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel case HttpRouteDirector.UNREACHABLE: 687ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel throw new IllegalStateException 688ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel ("Unable to establish route." + 689ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel "\nplanned = " + route + 690ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel "\ncurrent = " + fact); 691ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel 692ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel case HttpRouteDirector.COMPLETE: 693ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel // do nothing 694ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel break; 695ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel 696ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel default: 697ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel throw new IllegalStateException 698ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel ("Unknown step indicator "+step+" from RouteDirector."); 699ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel } // switch 700ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel 701ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel } while (step > HttpRouteDirector.COMPLETE); 702ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel 703ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel } // establishConnection 704ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel 705ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel 706ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel /** 707ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel * Creates a tunnel to the target server. 708ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel * The connection must be established to the (last) proxy. 709ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel * A CONNECT request for tunnelling through the proxy will 710ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel * be created and sent, the response received and checked. 711ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel * This method does <i>not</i> update the connection with 712ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel * information about the tunnel, that is left to the caller. 713ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel * 714ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel * @param route the route to establish 715ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel * @param context the context for request execution 716ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel * 717ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel * @return <code>true</code> if the tunnelled route is secure, 718ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel * <code>false</code> otherwise. 719ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel * The implementation here always returns <code>false</code>, 720ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel * but derived classes may override. 721ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel * 722ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel * @throws HttpException in case of a problem 723ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel * @throws IOException in case of an IO problem 724ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel */ 725ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel protected boolean createTunnelToTarget(HttpRoute route, 726ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel HttpContext context) 727ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel throws HttpException, IOException { 728ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel 729ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel HttpHost proxy = route.getProxyHost(); 730ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel HttpHost target = route.getTargetHost(); 731ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel HttpResponse response = null; 732ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel 733ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel boolean done = false; 734ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel while (!done) { 735ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel 736ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel done = true; 737ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel 738ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel if (!this.managedConn.isOpen()) { 739ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel this.managedConn.open(route, context, this.params); 740ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel } 741ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel 742ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel HttpRequest connect = createConnectRequest(route, context); 743ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel connect.setParams(this.params); 744ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel 745ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel // Populate the execution context 746ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel context.setAttribute(ExecutionContext.HTTP_TARGET_HOST, 747ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel target); 748ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel context.setAttribute(ExecutionContext.HTTP_PROXY_HOST, 749ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel proxy); 750ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel context.setAttribute(ExecutionContext.HTTP_CONNECTION, 751ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel managedConn); 752ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel context.setAttribute(ClientContext.TARGET_AUTH_STATE, 753ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel targetAuthState); 754ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel context.setAttribute(ClientContext.PROXY_AUTH_STATE, 755ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel proxyAuthState); 756ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel context.setAttribute(ExecutionContext.HTTP_REQUEST, 757ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel connect); 758ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel 759ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel this.requestExec.preProcess(connect, this.httpProcessor, context); 760ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel 761ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel response = this.requestExec.execute(connect, this.managedConn, context); 762ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel 763ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel response.setParams(this.params); 764ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel this.requestExec.postProcess(response, this.httpProcessor, context); 765ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel 766ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel int status = response.getStatusLine().getStatusCode(); 767ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel if (status < 200) { 768ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel throw new HttpException("Unexpected response to CONNECT request: " + 769ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel response.getStatusLine()); 770ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel } 771ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel 772ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel CredentialsProvider credsProvider = (CredentialsProvider) 773ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel context.getAttribute(ClientContext.CREDS_PROVIDER); 774ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel 775ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel if (credsProvider != null && HttpClientParams.isAuthenticating(params)) { 776ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel if (this.proxyAuthHandler.isAuthenticationRequested(response, context)) { 777ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel 778ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel this.log.debug("Proxy requested authentication"); 779ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel Map<String, Header> challenges = this.proxyAuthHandler.getChallenges( 780ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel response, context); 781ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel try { 782ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel processChallenges( 783ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel challenges, this.proxyAuthState, this.proxyAuthHandler, 784ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel response, context); 785ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel } catch (AuthenticationException ex) { 786ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel if (this.log.isWarnEnabled()) { 787ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel this.log.warn("Authentication error: " + ex.getMessage()); 788ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel break; 789ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel } 790ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel } 791ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel updateAuthState(this.proxyAuthState, proxy, credsProvider); 792ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel 793ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel if (this.proxyAuthState.getCredentials() != null) { 794ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel done = false; 795ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel 796ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel // Retry request 797ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel if (this.reuseStrategy.keepAlive(response, context)) { 798ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel this.log.debug("Connection kept alive"); 799ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel // Consume response content 800ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel HttpEntity entity = response.getEntity(); 801ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel if (entity != null) { 802ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel entity.consumeContent(); 803ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel } 804ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel } else { 805ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel this.managedConn.close(); 806ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel } 807ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel 808ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel } 809ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel 810ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel } else { 811ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel // Reset proxy auth scope 812ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel this.proxyAuthState.setAuthScope(null); 813ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel } 814ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel } 815ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel } 816ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel 817ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel int status = response.getStatusLine().getStatusCode(); // can't be null 818ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel 819ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel if (status > 299) { 820ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel 821ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel // Buffer response content 822ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel HttpEntity entity = response.getEntity(); 823ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel if (entity != null) { 824ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel response.setEntity(new BufferedHttpEntity(entity)); 825ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel } 826ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel 827ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel this.managedConn.close(); 828ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel throw new TunnelRefusedException("CONNECT refused by proxy: " + 829ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel response.getStatusLine(), response); 830ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel } 831ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel 832ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel this.managedConn.markReusable(); 833ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel 834ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel // How to decide on security of the tunnelled connection? 835ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel // The socket factory knows only about the segment to the proxy. 836ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel // Even if that is secure, the hop to the target may be insecure. 837ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel // Leave it to derived classes, consider insecure by default here. 838ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel return false; 839ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel 840ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel } // createTunnelToTarget 841ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel 842ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel 843ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel 844ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel /** 845ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel * Creates a tunnel to an intermediate proxy. 846ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel * This method is <i>not</i> implemented in this class. 847ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel * It just throws an exception here. 848ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel * 849ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel * @param route the route to establish 850ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel * @param hop the hop in the route to establish now. 851ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel * <code>route.getHopTarget(hop)</code> 852ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel * will return the proxy to tunnel to. 853ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel * @param context the context for request execution 854ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel * 855ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel * @return <code>true</code> if the partially tunnelled connection 856ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel * is secure, <code>false</code> otherwise. 857ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel * 858ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel * @throws HttpException in case of a problem 859ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel * @throws IOException in case of an IO problem 860ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel */ 861ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel protected boolean createTunnelToProxy(HttpRoute route, int hop, 862ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel HttpContext context) 863ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel throws HttpException, IOException { 864ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel 865ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel // Have a look at createTunnelToTarget and replicate the parts 866ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel // you need in a custom derived class. If your proxies don't require 867ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel // authentication, it is not too hard. But for the stock version of 868ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel // HttpClient, we cannot make such simplifying assumptions and would 869ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel // have to include proxy authentication code. The HttpComponents team 870ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel // is currently not in a position to support rarely used code of this 871ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel // complexity. Feel free to submit patches that refactor the code in 872ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel // createTunnelToTarget to facilitate re-use for proxy tunnelling. 873ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel 874ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel throw new UnsupportedOperationException 875ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel ("Proxy chains are not supported."); 876ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel } 877ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel 878ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel 879ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel 880ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel /** 881ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel * Creates the CONNECT request for tunnelling. 882ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel * Called by {@link #createTunnelToTarget createTunnelToTarget}. 883ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel * 884ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel * @param route the route to establish 885ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel * @param context the context for request execution 886ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel * 887ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel * @return the CONNECT request for tunnelling 888ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel */ 889ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel protected HttpRequest createConnectRequest(HttpRoute route, 890ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel HttpContext context) { 891ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel // see RFC 2817, section 5.2 and 892ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel // INTERNET-DRAFT: Tunneling TCP based protocols through 893ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel // Web proxy servers 894ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel 895ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel HttpHost target = route.getTargetHost(); 896ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel 897ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel String host = target.getHostName(); 898ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel int port = target.getPort(); 899ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel if (port < 0) { 900ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel Scheme scheme = connManager.getSchemeRegistry(). 901ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel getScheme(target.getSchemeName()); 902ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel port = scheme.getDefaultPort(); 903ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel } 904ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel 905ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel StringBuilder buffer = new StringBuilder(host.length() + 6); 906ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel buffer.append(host); 907ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel buffer.append(':'); 908ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel buffer.append(Integer.toString(port)); 909ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel 910ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel String authority = buffer.toString(); 911ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel ProtocolVersion ver = HttpProtocolParams.getVersion(params); 912ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel HttpRequest req = new BasicHttpRequest 913ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel ("CONNECT", authority, ver); 914ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel 915ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel return req; 916ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel } 917ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel 918ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel 919ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel /** 920ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel * Analyzes a response to check need for a followup. 921ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel * 922ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel * @param roureq the request and route. 923ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel * @param response the response to analayze 924ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel * @param context the context used for the current request execution 925ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel * 926ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel * @return the followup request and route if there is a followup, or 927ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel * <code>null</code> if the response should be returned as is 928ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel * 929ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel * @throws HttpException in case of a problem 930ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel * @throws IOException in case of an IO problem 931ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel */ 932ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel protected RoutedRequest handleResponse(RoutedRequest roureq, 933ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel HttpResponse response, 934ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel HttpContext context) 935ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel throws HttpException, IOException { 936ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel 937ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel HttpRoute route = roureq.getRoute(); 938ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel RequestWrapper request = roureq.getRequest(); 939ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel 940ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel HttpParams params = request.getParams(); 941ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel if (HttpClientParams.isRedirecting(params) && 942ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel this.redirectHandler.isRedirectRequested(response, context)) { 943ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel 944ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel if (redirectCount >= maxRedirects) { 945ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel throw new RedirectException("Maximum redirects (" 946ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel + maxRedirects + ") exceeded"); 947ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel } 948ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel redirectCount++; 949ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel 950ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel // Virtual host cannot be used any longer 951ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel virtualHost = null; 952ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel 953ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel URI uri = this.redirectHandler.getLocationURI(response, context); 954ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel 955ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel HttpHost newTarget = new HttpHost( 956ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel uri.getHost(), 957ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel uri.getPort(), 958ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel uri.getScheme()); 959ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel 960ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel // Unset auth scope 961ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel targetAuthState.setAuthScope(null); 962ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel proxyAuthState.setAuthScope(null); 963ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel 964ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel // Invalidate auth states if redirecting to another host 965ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel if (!route.getTargetHost().equals(newTarget)) { 966ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel targetAuthState.invalidate(); 967ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel AuthScheme authScheme = proxyAuthState.getAuthScheme(); 968ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel if (authScheme != null && authScheme.isConnectionBased()) { 969ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel proxyAuthState.invalidate(); 970ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel } 971ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel } 972ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel 973ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel HttpRedirect redirect = new HttpRedirect(request.getMethod(), uri); 974ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel HttpRequest orig = request.getOriginal(); 975ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel redirect.setHeaders(orig.getAllHeaders()); 976ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel 977ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel RequestWrapper wrapper = new RequestWrapper(redirect); 978ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel wrapper.setParams(params); 979ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel 980ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel HttpRoute newRoute = determineRoute(newTarget, wrapper, context); 981ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel RoutedRequest newRequest = new RoutedRequest(wrapper, newRoute); 982ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel 983ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel if (this.log.isDebugEnabled()) { 984ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel this.log.debug("Redirecting to '" + uri + "' via " + newRoute); 985ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel } 986ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel 987ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel return newRequest; 988ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel } 989ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel 990ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel CredentialsProvider credsProvider = (CredentialsProvider) 991ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel context.getAttribute(ClientContext.CREDS_PROVIDER); 992ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel 993ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel if (credsProvider != null && HttpClientParams.isAuthenticating(params)) { 994ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel 995ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel if (this.targetAuthHandler.isAuthenticationRequested(response, context)) { 996ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel 997ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel HttpHost target = (HttpHost) 998ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel context.getAttribute(ExecutionContext.HTTP_TARGET_HOST); 999ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel if (target == null) { 1000ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel target = route.getTargetHost(); 1001ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel } 1002ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel 1003ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel this.log.debug("Target requested authentication"); 1004ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel Map<String, Header> challenges = this.targetAuthHandler.getChallenges( 1005ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel response, context); 1006ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel try { 1007ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel processChallenges(challenges, 1008ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel this.targetAuthState, this.targetAuthHandler, 1009ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel response, context); 1010ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel } catch (AuthenticationException ex) { 1011ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel if (this.log.isWarnEnabled()) { 1012ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel this.log.warn("Authentication error: " + ex.getMessage()); 1013ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel return null; 1014ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel } 1015ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel } 1016ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel updateAuthState(this.targetAuthState, target, credsProvider); 1017ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel 1018ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel if (this.targetAuthState.getCredentials() != null) { 1019ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel // Re-try the same request via the same route 1020ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel return roureq; 1021ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel } else { 1022ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel return null; 1023ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel } 1024ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel } else { 1025ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel // Reset target auth scope 1026ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel this.targetAuthState.setAuthScope(null); 1027ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel } 1028ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel 1029ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel if (this.proxyAuthHandler.isAuthenticationRequested(response, context)) { 1030ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel 1031ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel HttpHost proxy = route.getProxyHost(); 1032ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel 1033ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel this.log.debug("Proxy requested authentication"); 1034ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel Map<String, Header> challenges = this.proxyAuthHandler.getChallenges( 1035ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel response, context); 1036ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel try { 1037ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel processChallenges(challenges, 1038ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel this.proxyAuthState, this.proxyAuthHandler, 1039ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel response, context); 1040ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel } catch (AuthenticationException ex) { 1041ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel if (this.log.isWarnEnabled()) { 1042ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel this.log.warn("Authentication error: " + ex.getMessage()); 1043ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel return null; 1044ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel } 1045ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel } 1046ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel updateAuthState(this.proxyAuthState, proxy, credsProvider); 1047ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel 1048ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel if (this.proxyAuthState.getCredentials() != null) { 1049ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel // Re-try the same request via the same route 1050ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel return roureq; 1051ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel } else { 1052ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel return null; 1053ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel } 1054ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel } else { 1055ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel // Reset proxy auth scope 1056ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel this.proxyAuthState.setAuthScope(null); 1057ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel } 1058ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel } 1059ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel return null; 1060ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel } // handleResponse 1061ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel 1062ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel 1063ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel /** 1064ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel * Shuts down the connection. 1065ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel * This method is called from a <code>catch</code> block in 1066ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel * {@link #execute execute} during exception handling. 1067ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel */ 1068ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel private void abortConnection() { 1069ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel ManagedClientConnection mcc = managedConn; 1070ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel if (mcc != null) { 1071ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel // we got here as the result of an exception 1072ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel // no response will be returned, release the connection 1073ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel managedConn = null; 1074ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel try { 1075ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel mcc.abortConnection(); 1076ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel } catch (IOException ex) { 1077ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel if (this.log.isDebugEnabled()) { 1078ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel this.log.debug(ex.getMessage(), ex); 1079ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel } 1080ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel } 1081ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel // ensure the connection manager properly releases this connection 1082ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel try { 1083ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel mcc.releaseConnection(); 1084ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel } catch(IOException ignored) { 1085ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel this.log.debug("Error releasing connection", ignored); 1086ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel } 1087ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel } 1088ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel } // abortConnection 1089ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel 1090ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel 1091ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel private void processChallenges( 1092ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel final Map<String, Header> challenges, 1093ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel final AuthState authState, 1094ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel final AuthenticationHandler authHandler, 1095ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel final HttpResponse response, 1096ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel final HttpContext context) 1097ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel throws MalformedChallengeException, AuthenticationException { 1098ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel 1099ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel AuthScheme authScheme = authState.getAuthScheme(); 1100ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel if (authScheme == null) { 1101ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel // Authentication not attempted before 1102ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel authScheme = authHandler.selectScheme(challenges, response, context); 1103ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel authState.setAuthScheme(authScheme); 1104ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel } 1105ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel String id = authScheme.getSchemeName(); 1106ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel 1107ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel Header challenge = challenges.get(id.toLowerCase(Locale.ENGLISH)); 1108ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel if (challenge == null) { 1109ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel throw new AuthenticationException(id + 1110ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel " authorization challenge expected, but not found"); 1111ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel } 1112ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel authScheme.processChallenge(challenge); 1113ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel this.log.debug("Authorization challenge processed"); 1114ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel } 1115ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel 1116ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel 1117ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel private void updateAuthState( 1118ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel final AuthState authState, 1119ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel final HttpHost host, 1120ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel final CredentialsProvider credsProvider) { 1121ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel 1122ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel if (!authState.isValid()) { 1123ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel return; 1124ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel } 1125ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel 1126ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel String hostname = host.getHostName(); 1127ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel int port = host.getPort(); 1128ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel if (port < 0) { 1129ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel Scheme scheme = connManager.getSchemeRegistry().getScheme(host); 1130ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel port = scheme.getDefaultPort(); 1131ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel } 1132ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel 1133ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel AuthScheme authScheme = authState.getAuthScheme(); 1134ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel AuthScope authScope = new AuthScope( 1135ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel hostname, 1136ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel port, 1137ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel authScheme.getRealm(), 1138ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel authScheme.getSchemeName()); 1139ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel 1140ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel if (this.log.isDebugEnabled()) { 1141ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel this.log.debug("Authentication scope: " + authScope); 1142ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel } 1143ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel Credentials creds = authState.getCredentials(); 1144ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel if (creds == null) { 1145ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel creds = credsProvider.getCredentials(authScope); 1146ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel if (this.log.isDebugEnabled()) { 1147ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel if (creds != null) { 1148ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel this.log.debug("Found credentials"); 1149ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel } else { 1150ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel this.log.debug("Credentials not found"); 1151ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel } 1152ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel } 1153ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel } else { 1154ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel if (authScheme.isComplete()) { 1155ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel this.log.debug("Authentication failed"); 1156ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel creds = null; 1157ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel } 1158ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel } 1159ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel authState.setAuthScope(authScope); 1160ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel authState.setCredentials(creds); 1161ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel } 1162ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel 1163ef24e85f87c30d8d1cbe6f7ca0c29a11bd7e4be4Jan Berkel} // class DefaultClientRequestDirector 1164