Default implementation of WebConnection, using the HttpClient library to perform HTTP requests. @author Mike Bowler @author Noboru Sinohara @author David D. Kilzer @author Marc Guillemot @author Brad Clarke @author Ahmed Ashour @author Nicolas Belisle @author Ronald Brill @author John J Mur
| 131 | * @author Lai Quang Duong |
| 132 | */ |
| 133 | public class HttpWebConnection implements WebConnection { |
| 134 | |
| 135 | private static final Log LOG = LogFactory.getLog(HttpWebConnection.class); |
| 136 | |
| 137 | private static final String HACKED_COOKIE_POLICY = "mine"; |
| 138 | |
| 139 | // have one per thread because this is (re)configured for every call (see configureHttpProcessorBuilder) |
| 140 | // do not use a ThreadLocal because this in only accessed form this class, but we still need it synchronized |
| 141 | private final Map<Thread, HttpClientBuilder> httpClientBuilder_ = new WeakHashMap<>(); |
| 142 | private final WebClient webClient_; |
| 143 | |
| 144 | private String virtualHost_; |
| 145 | private final HtmlUnitCookieSpecProvider htmlUnitCookieSpecProvider_; |
| 146 | private final WebClientOptions usedOptions_; |
| 147 | private PoolingHttpClientConnectionManager connectionManager_; |
| 148 | |
| 149 | /** Authentication cache shared among all threads of a web client. */ |
| 150 | private final AuthCache sharedAuthCache_ = new SynchronizedAuthCache(); |
| 151 | |
| 152 | /** Maintains a separate {@link HttpClientContext} object per HttpWebConnection and thread. */ |
| 153 | private final Map<Thread, HttpClientContext> httpClientContextByThread_ = new WeakHashMap<>(); |
| 154 | |
| 155 | /** |
| 156 | * Creates a new HTTP web connection instance. |
| 157 | * @param webClient the WebClient that is using this connection |
| 158 | */ |
| 159 | public HttpWebConnection(final WebClient webClient) { |
| 160 | super(); |
| 161 | webClient_ = webClient; |
| 162 | htmlUnitCookieSpecProvider_ = new HtmlUnitCookieSpecProvider(webClient.getBrowserVersion()); |
| 163 | usedOptions_ = new WebClientOptions(); |
| 164 | } |
| 165 | |
| 166 | /** |
| 167 | * {@inheritDoc} |
| 168 | */ |
| 169 | @Override |
| 170 | public WebResponse getResponse(final WebRequest webRequest) throws IOException { |
| 171 | final HttpClientBuilder builder = reconfigureHttpClientIfNeeded(getHttpClientBuilder(), webRequest); |
| 172 | |
| 173 | HttpUriRequest httpMethod = null; |
| 174 | try { |
| 175 | try { |
| 176 | httpMethod = makeHttpMethod(webRequest, builder); |
| 177 | } |
| 178 | catch (final URISyntaxException e) { |
| 179 | throw new IOException("Unable to create URI from URL: " + webRequest.getUrl().toExternalForm() |
| 180 | + " (reason: " + e.getMessage() + ")", e); |
| 181 | } |
| 182 | |
| 183 | final URL url = webRequest.getUrl(); |
| 184 | final HttpHost httpHost = new HttpHost(url.getHost(), url.getPort(), url.getProtocol()); |
| 185 | final long startTime = System.currentTimeMillis(); |
| 186 | |
| 187 | final HttpContext httpContext = getHttpContext(); |
| 188 | try { |
| 189 | try (CloseableHttpClient closeableHttpClient = builder.build()) { |
| 190 | try (CloseableHttpResponse httpResponse = |
nothing calls this directly
no outgoing calls
no test coverage detected
searching dependent graphs…