From: <asa...@us...> - 2014-01-20 14:19:26
|
Revision: 9002 http://sourceforge.net/p/htmlunit/code/9002 Author: asashour Date: 2014-01-20 14:19:21 +0000 (Mon, 20 Jan 2014) Log Message: ----------- Revert testing new HttpWebConnection on the server, as local tests aren't consistent. Modified Paths: -------------- trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/HttpWebConnection.java trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/SocksSocketFactory.java trunk/htmlunit/src/test/java/com/gargoylesoftware/htmlunit/HttpWebConnectionTest.java Removed Paths: ------------- trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/HtmlUnitSSLConnectionSocketFactory.java Deleted: trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/HtmlUnitSSLConnectionSocketFactory.java =================================================================== --- trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/HtmlUnitSSLConnectionSocketFactory.java 2014-01-20 11:55:43 UTC (rev 9001) +++ trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/HtmlUnitSSLConnectionSocketFactory.java 2014-01-20 14:19:21 UTC (rev 9002) @@ -1,239 +0,0 @@ -/* - * Copyright (c) 2002-2014 Gargoyle Software Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.gargoylesoftware.htmlunit; - -import java.io.IOException; -import java.lang.reflect.Field; -import java.net.InetSocketAddress; -import java.net.Socket; -import java.net.SocketAddress; -import java.net.SocketTimeoutException; -import java.security.GeneralSecurityException; -import java.security.KeyManagementException; -import java.security.KeyStore; -import java.security.KeyStoreException; -import java.security.NoSuchAlgorithmException; -import java.security.UnrecoverableKeyException; -import java.security.cert.CertificateException; -import java.security.cert.X509Certificate; -import java.util.Arrays; -import java.util.HashSet; -import java.util.Set; - -import javax.net.ssl.KeyManager; -import javax.net.ssl.KeyManagerFactory; -import javax.net.ssl.SSLContext; -import javax.net.ssl.SSLSocket; -import javax.net.ssl.TrustManager; -import javax.net.ssl.X509TrustManager; - -import org.apache.http.HttpHost; -import org.apache.http.conn.ConnectTimeoutException; -import org.apache.http.conn.ssl.SSLConnectionSocketFactory; -import org.apache.http.conn.ssl.SSLContexts; -import org.apache.http.conn.ssl.X509HostnameVerifier; -import org.apache.http.protocol.HttpContext; - -/** - * Socket factory offering facilities for insecure SSL and for SOCKS proxy support. - * This looks rather like a hack than like clean code but at the time of the writing it seems to - * be the easiest way to provide SOCKS proxy support for HTTPS. - * - * @version $Revision$ - * @author Nicolas Belisle - * @author Ahmed Ashour - * @author Martin Huber - * @author Marc Guillemot - * @author Ronald Brill - */ -final class HtmlUnitSSLConnectionSocketFactory extends SSLConnectionSocketFactory { - private static final String SSL3ONLY = "htmlunit.SSL3Only"; - - static boolean isUseSSL3Only(final HttpContext context) { - return "TRUE".equalsIgnoreCase((String) context.getAttribute(SSL3ONLY)); - } - - public static SSLConnectionSocketFactory buildSSLSocketFactory(final WebClientOptions options) { - try { - if (!options.isUseInsecureSSL()) { - if (options.getSSLClientCertificateUrl() == null) { - return new HtmlUnitSSLConnectionSocketFactory((KeyStore) null, null); // only SOCKS awareness - } - // SOCKS + keystore - return new HtmlUnitSSLConnectionSocketFactory(getKeyStore(options), options.getSSLClientCertificatePassword()); - } - - // we need insecure SSL + SOCKS awareness - final SSLContext sslContext = SSLContext.getInstance("SSL"); - sslContext.init(getKeyManagers(options), new TrustManager[]{new InsecureTrustManager2()}, null); - - final SSLConnectionSocketFactory factory = new HtmlUnitSSLConnectionSocketFactory(sslContext, - SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER); - return factory; - } - catch (final GeneralSecurityException e) { - throw new RuntimeException(e); - } - } - - private HtmlUnitSSLConnectionSocketFactory(final SSLContext sslContext, final X509HostnameVerifier hostnameVerifier) { - super(sslContext, hostnameVerifier); - } - - private HtmlUnitSSLConnectionSocketFactory(final KeyStore keystore, final String keystorePassword) - throws NoSuchAlgorithmException, KeyManagementException, KeyStoreException, UnrecoverableKeyException { - super(SSLContexts.custom() - .loadKeyMaterial(keystore, keystorePassword != null ? keystorePassword.toCharArray() : null) - .build(), - BROWSER_COMPATIBLE_HOSTNAME_VERIFIER); - } - - /** - * {@inheritDoc} - */ - @Override - public Socket createSocket(final HttpContext context) throws IOException { - if (SocksSocketFactory.getSocksProxy(context) != null) { - // we create the socket in connectSocket has we need to know the destination to open the underlying request - return null; - } - final Socket socket = super.createSocket(context); - configureSocket((SSLSocket) socket, context); - return socket; - } - - private void configureSocket(final SSLSocket sslSocket, final HttpContext context) { - if (isUseSSL3Only(context)) { - sslSocket.setEnabledProtocols(new String[]{"SSLv3"}); - } - } - - public Socket connectSocket( - final int connectTimeout, - final Socket socket, - final HttpHost host, - final InetSocketAddress remoteAddress, - final InetSocketAddress localAddress, - final HttpContext context) throws IOException { - final HttpHost socksProxy = SocksSocketFactory.getSocksProxy(context); - if (socksProxy != null) { - final Socket underlying = SocksSocketFactory.createSocketWithSocksProxy(socksProxy); - underlying.setReuseAddress(true); - - // TODO: commented out for HttpClient 4.3 - // final int soTimeout = HttpConnectionParams.getSoTimeout(params); - - final SocketAddress socksProxyAddress = new InetSocketAddress(socksProxy.getHostName(), - socksProxy.getPort()); - try { - //underlying.setSoTimeout(soTimeout); - underlying.connect(remoteAddress, connectTimeout); - } - catch (final SocketTimeoutException ex) { - throw new ConnectTimeoutException("Connect to " + socksProxyAddress + " timed out"); - } - - final Socket sslSocket = getSSLSocketFactory().createSocket(underlying, socksProxy.getHostName(), - socksProxy.getPort(), true); - configureSocket((SSLSocket) sslSocket, context); - return sslSocket; - } - return super.connectSocket(connectTimeout, socket, host, remoteAddress, localAddress, context); - } - - private javax.net.ssl.SSLSocketFactory getSSLSocketFactory() { - try { - final Field field = SSLConnectionSocketFactory.class.getDeclaredField("socketfactory"); - field.setAccessible(true); - return (javax.net.ssl.SSLSocketFactory) field.get(this); - } - catch (final Exception e) { - throw new RuntimeException(e); - } - } - - private static KeyManager[] getKeyManagers(final WebClientOptions options) { - if (options.getSSLClientCertificateUrl() == null) { - return null; - } - try { - final String password = options.getSSLClientCertificatePassword(); - final char[] passwordChars = password != null ? password.toCharArray() : null; - - final KeyStore keyStore = getKeyStore(options); - final KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance("SunX509"); - keyManagerFactory.init(keyStore, passwordChars); - return keyManagerFactory.getKeyManagers(); - } - catch (final Exception e) { - throw new RuntimeException(e); - } - } - - private static KeyStore getKeyStore(final WebClientOptions options) { - try { - final KeyStore keyStore = KeyStore.getInstance(options.getSSLClientCertificateType()); - final String password = options.getSSLClientCertificatePassword(); - final char[] passwordChars = password != null ? password.toCharArray() : null; - keyStore.load(options.getSSLClientCertificateUrl().openStream(), passwordChars); - return keyStore; - } - catch (final Exception e) { - throw new RuntimeException(e); - } - } -} - -/** - * A completely insecure (yet very easy to use) x509 trust manager. This manager trusts all servers - * and all clients, regardless of credentials or lack thereof. - * - * @version $Revision$ - * @author Daniel Gredler - * @author Marc Guillemot - */ -class InsecureTrustManager2 implements X509TrustManager { - private final Set<X509Certificate> acceptedIssuers_ = new HashSet<X509Certificate>(); - - /** - * {@inheritDoc} - */ - public void checkClientTrusted(final X509Certificate[] chain, final String authType) throws CertificateException { - // Everyone is trusted! - acceptedIssuers_.addAll(Arrays.asList(chain)); - } - - /** - * {@inheritDoc} - */ - public void checkServerTrusted(final X509Certificate[] chain, final String authType) throws CertificateException { - // Everyone is trusted! - acceptedIssuers_.addAll(Arrays.asList(chain)); - } - - /** - * {@inheritDoc} - */ - public X509Certificate[] getAcceptedIssuers() { - // it seems to be OK for Java <= 6 to return an empty array but not for Java 7 (at least 1.7.0_04-b20): - // requesting an URL with a valid certificate (working without WebClient.setUseInsecureSSL(true)) throws a - // javax.net.ssl.SSLPeerUnverifiedException: peer not authenticated - // when the array returned here is empty - if (acceptedIssuers_.isEmpty()) { - return new X509Certificate[0]; - } - return acceptedIssuers_.toArray(new X509Certificate[acceptedIssuers_.size()]); - } -} Modified: trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/HttpWebConnection.java =================================================================== --- trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/HttpWebConnection.java 2014-01-20 11:55:43 UTC (rev 9001) +++ trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/HttpWebConnection.java 2014-01-20 14:19:21 UTC (rev 9002) @@ -53,8 +53,6 @@ import org.apache.http.auth.Credentials; import org.apache.http.client.CookieStore; import org.apache.http.client.CredentialsProvider; -import org.apache.http.client.config.CookieSpecs; -import org.apache.http.client.config.RequestConfig; import org.apache.http.client.methods.HttpDelete; import org.apache.http.client.methods.HttpGet; import org.apache.http.client.methods.HttpHead; @@ -64,39 +62,41 @@ import org.apache.http.client.methods.HttpRequestBase; import org.apache.http.client.methods.HttpTrace; import org.apache.http.client.methods.HttpUriRequest; -import org.apache.http.client.protocol.HttpClientContext; +import org.apache.http.client.params.ClientPNames; +import org.apache.http.client.params.HttpClientParams; import org.apache.http.client.utils.DateUtils; import org.apache.http.client.utils.URIUtils; import org.apache.http.client.utils.URLEncodedUtils; -import org.apache.http.config.RegistryBuilder; import org.apache.http.conn.params.ConnRoutePNames; -import org.apache.http.conn.ssl.SSLConnectionSocketFactory; +import org.apache.http.conn.scheme.Scheme; +import org.apache.http.conn.scheme.SchemeRegistry; +import org.apache.http.conn.ssl.SSLSocketFactory; import org.apache.http.cookie.ClientCookie; import org.apache.http.cookie.Cookie; import org.apache.http.cookie.CookieAttributeHandler; import org.apache.http.cookie.CookieOrigin; import org.apache.http.cookie.CookiePathComparator; import org.apache.http.cookie.CookieSpec; -import org.apache.http.cookie.CookieSpecProvider; +import org.apache.http.cookie.CookieSpecFactory; import org.apache.http.cookie.MalformedCookieException; import org.apache.http.cookie.SetCookie; +import org.apache.http.cookie.params.CookieSpecPNames; import org.apache.http.entity.ContentType; import org.apache.http.entity.StringEntity; import org.apache.http.entity.mime.MultipartEntityBuilder; import org.apache.http.entity.mime.content.InputStreamBody; +import org.apache.http.impl.client.AbstractHttpClient; +import org.apache.http.impl.client.DefaultHttpClient; import org.apache.http.impl.client.DefaultRedirectStrategy; -import org.apache.http.impl.client.HttpClientBuilder; +import org.apache.http.impl.conn.PoolingClientConnectionManager; import org.apache.http.impl.cookie.BasicClientCookie; import org.apache.http.impl.cookie.BasicPathHandler; -import org.apache.http.impl.cookie.BestMatchSpecFactory; import org.apache.http.impl.cookie.BrowserCompatSpec; -import org.apache.http.impl.cookie.BrowserCompatSpecFactory; -import org.apache.http.impl.cookie.IgnoreSpecFactory; -import org.apache.http.impl.cookie.NetscapeDraftSpecFactory; -import org.apache.http.impl.cookie.RFC2109SpecFactory; -import org.apache.http.impl.cookie.RFC2965SpecFactory; import org.apache.http.message.BasicHeader; +import org.apache.http.params.BasicHttpParams; +import org.apache.http.params.CoreConnectionPNames; import org.apache.http.params.HttpParams; +import org.apache.http.protocol.BasicHttpContext; import org.apache.http.protocol.HttpContext; import com.gargoylesoftware.htmlunit.util.KeyDataPair; @@ -105,8 +105,6 @@ /** * Default implementation of {@link WebConnection}, using the HttpClient library to perform HTTP requests. - * This is meant to use the new API in HttpClient 4.3, and should be renamed to HttpWebConnection, - * after the old code is removed. * * @version $Revision$ * @author <a href="mailto:mb...@Ga...">Mike Bowler</a> @@ -122,13 +120,13 @@ public class HttpWebConnection implements WebConnection { private static final String HACKED_COOKIE_POLICY = "mine"; - private HttpClientBuilder httpClientBuilder_; + private AbstractHttpClient httpClient_; private final WebClient webClient_; /** Use single HttpContext, so there is no need to re-send authentication for each and every request. */ - private HttpContext httpContext_ = new HttpClientContext(); + private HttpContext httpContext_ = new BasicHttpContext(); private String virtualHost_; - private final CookieSpecProvider htmlUnitCookieSpecProvider_; + private final CookieSpecFactory htmlUnitCookieSpecFactory_; private final WebClientOptions usedOptions_ = new WebClientOptions(); /** @@ -137,10 +135,9 @@ */ public HttpWebConnection(final WebClient webClient) { webClient_ = webClient; - htmlUnitCookieSpecProvider_ = new CookieSpecProvider() { - @Override - public CookieSpec create(final HttpContext context) { - return new HtmlUnitBrowserCompatCookieSpec2(webClient_.getIncorrectnessListener()); + htmlUnitCookieSpecFactory_ = new CookieSpecFactory() { + public CookieSpec newInstance(final HttpParams params) { + return new HtmlUnitBrowserCompatCookieSpec(webClient_.getIncorrectnessListener()); } }; } @@ -150,7 +147,7 @@ */ public WebResponse getResponse(final WebRequest request) throws IOException { final URL url = request.getUrl(); - final HttpClientBuilder builder = reconfigureHttpClientIfNeeded(getHttpClientBuilder()); + final AbstractHttpClient httpClient = getHttpClient(); HttpUriRequest httpMethod = null; try { @@ -162,19 +159,18 @@ + " (reason: " + e.getMessage() + ")", e); } final HttpHost hostConfiguration = getHostConfiguration(request); -// setProxy(httpMethod, request); + setProxy(httpMethod, request); final long startTime = System.currentTimeMillis(); HttpResponse httpResponse = null; try { - httpResponse = builder.build().execute(hostConfiguration, httpMethod, httpContext_); + httpResponse = httpClient.execute(hostConfiguration, httpMethod, httpContext_); } catch (final SSLPeerUnverifiedException s) { // Try to use only SSLv3 instead if (webClient_.getOptions().isUseInsecureSSL()) { - // TODO: asashour - // HtmlUnitSSLSocketFactory.setUseSSL3Only(getHttpClient().getParams(), true); - httpResponse = builder.build().execute(hostConfiguration, httpMethod); + HtmlUnitSSLSocketFactory.setUseSSL3Only(getHttpClient().getParams(), true); + httpResponse = httpClient.execute(hostConfiguration, httpMethod); } else { throw s; @@ -186,7 +182,7 @@ // come out of connections and throw a ConnectionPoolTimeoutException. // => best solution, discard the HttpClient instance. synchronized (this) { - httpClientBuilder_ = null; + httpClient_ = null; } throw e; } @@ -222,39 +218,17 @@ return hostConfiguration; } -// private static void setProxy(final HttpUriRequest httpUriRequest, final WebRequest webRequest) { -// if (webRequest.getProxyHost() != null) { -// final HttpHost proxy = new HttpHost(webRequest.getProxyHost(), webRequest.getProxyPort()); -// final HttpParams httpRequestParams = httpUriRequest.getParams(); -// if (webRequest.isSocksProxy()) { -// SocksSocketFactory.setSocksProxy(httpRequestParams, proxy); -// } -// else { -// httpRequestParams.setParameter(ConnRoutePNames.DEFAULT_PROXY, proxy); -// } -// } -// } - - private void setProxy(final HttpRequestBase httpRequest, final WebRequest webRequest) { - RequestConfig.Builder requestBuilder = createRequestConfig(); - configureTimeout(requestBuilder, webClient_.getOptions().getTimeout()); - + private static void setProxy(final HttpUriRequest httpUriRequest, final WebRequest webRequest) { if (webRequest.getProxyHost() != null) { final HttpHost proxy = new HttpHost(webRequest.getProxyHost(), webRequest.getProxyPort()); - requestBuilder.setProxy(proxy); - httpRequest.setConfig(requestBuilder.build()); - -// if (webRequest.isSocksProxy()) { -// SocksSocketFactory.setSocksProxy(httpRequestParams, proxy); -// } -// else { -// httpRequestParams.setParameter(ConnRoutePNames.DEFAULT_PROXY, proxy); -// } + final HttpParams httpRequestParams = httpUriRequest.getParams(); + if (webRequest.isSocksProxy()) { + SocksSocketFactory.setSocksProxy(httpRequestParams, proxy); + } + else { + httpRequestParams.setParameter(ConnRoutePNames.DEFAULT_PROXY, proxy); + } } - else { - requestBuilder.setProxy(null); - httpRequest.setConfig(requestBuilder.build()); - } } /** @@ -280,7 +254,6 @@ URI uri = URIUtils.createURI(url.getProtocol(), url.getHost(), url.getPort(), url.getPath(), escapeQuery(url.getQuery()), null); final HttpRequestBase httpMethod = buildHttpMethod(webRequest.getHttpMethod(), uri); - setProxy(httpMethod, webRequest); if (!(httpMethod instanceof HttpEntityEnclosingRequest)) { // this is the case for GET as well as TRACE, DELETE, OPTIONS and HEAD if (!webRequest.getRequestParameters().isEmpty()) { @@ -321,8 +294,7 @@ buildFilePart((KeyDataPair) pair, builder); } else { - builder.addTextBody(pair.getName(), pair.getValue(), - ContentType.create(webRequest.getCharset())); + builder.addTextBody(pair.getName(), pair.getValue()); } } method.setEntity(builder.build()); @@ -353,8 +325,10 @@ writeRequestHeadersToHttpMethod(httpMethod, webRequest.getAdditionalHeaders()); // getHttpClient().getParams().setParameter(ClientPNames.HANDLE_REDIRECTS, true); - final HttpClientBuilder httpClient = getHttpClientBuilder(); + final AbstractHttpClient httpClient = getHttpClient(); + reconfigureHttpClientIfNeeded(httpClient); + // Tell the client where to get its credentials from // (it may have changed on the webClient since last call to getHttpClientFor(...)) final CredentialsProvider credentialsProvider = webClient_.getCredentialsProvider(); @@ -367,7 +341,6 @@ final AuthScope authScope = new AuthScope(requestUrl.getHost(), requestUrl.getPort()); // updating our client to keep the credentials for the next request credentialsProvider.setCredentials(authScope, requestUrlCredentials); - httpContext_.removeAttribute(HttpClientContext.TARGET_AUTH_STATE); } // if someone has set credentials to this request, we have to add this @@ -378,20 +351,18 @@ // updating our client to keep the credentials for the next request credentialsProvider.setCredentials(authScope, requestCredentials); } - httpContext_.removeAttribute(HttpClientContext.CREDS_PROVIDER); - httpClient.setDefaultCredentialsProvider(credentialsProvider); + httpClient.setCredentialsProvider(credentialsProvider); - httpContext_.removeAttribute(HttpClientContext.COOKIE_STORE); if (webClient_.getCookieManager().isCookiesEnabled()) { // Cookies are enabled. Note that it's important that we enable single cookie headers, // for compatibility purposes. - // TODO: asashour -// httpClient.getParams().setParameter(CookieSpecPNames.SINGLE_COOKIE_HEADER, Boolean.TRUE); - httpClient.setDefaultCookieStore(new HtmlUnitCookieStore(webClient_.getCookieManager())); + httpClient.getParams().setParameter(CookieSpecPNames.SINGLE_COOKIE_HEADER, Boolean.TRUE); + httpClient.getParams().setParameter(ClientPNames.COOKIE_POLICY, HACKED_COOKIE_POLICY); + httpClient.setCookieStore(new HtmlUnitCookieStore(webClient_.getCookieManager())); } else { // Cookies are disabled. - httpClient.setDefaultCookieStore(new CookieStore() { + httpClient.setCookieStore(new CookieStore() { public void addCookie(final Cookie cookie) { /* empty */ } public void clear() { /* empty */ } public boolean clearExpired(final Date date) { @@ -530,27 +501,16 @@ * * @return the initialized HTTP client */ - protected synchronized HttpClientBuilder getHttpClientBuilder() { - if (httpClientBuilder_ == null) { - httpClientBuilder_ = createHttpClient(); + protected synchronized AbstractHttpClient getHttpClient() { + if (httpClient_ == null) { + httpClient_ = createHttpClient(); // this factory is required later // to be sure this is done, we do it outside the createHttpClient() call - final RegistryBuilder<CookieSpecProvider> registeryBuilder - = RegistryBuilder.<CookieSpecProvider>create() - .register(CookieSpecs.BEST_MATCH, new BestMatchSpecFactory()) - .register(CookieSpecs.STANDARD, new RFC2965SpecFactory()) - .register(CookieSpecs.BROWSER_COMPATIBILITY, new BrowserCompatSpecFactory()) - .register(CookieSpecs.NETSCAPE, new NetscapeDraftSpecFactory()) - .register(CookieSpecs.IGNORE_COOKIES, new IgnoreSpecFactory()) - .register("rfc2109", new RFC2109SpecFactory()) - .register("rfc2965", new RFC2965SpecFactory()); - - registeryBuilder.register(HACKED_COOKIE_POLICY, htmlUnitCookieSpecProvider_); - httpClientBuilder_.setDefaultCookieSpecRegistry(registeryBuilder.build()); + httpClient_.getCookieSpecs().register(HACKED_COOKIE_POLICY, htmlUnitCookieSpecFactory_); } - return httpClientBuilder_; + return httpClient_; } /** @@ -571,40 +531,25 @@ * some tracking; see feature request 1438216). * @return the <tt>HttpClient</tt> that will be used by this WebConnection */ - protected HttpClientBuilder createHttpClient() { - // TODO: asashour -// final HttpParams httpParams = new BasicHttpParams(); -// -// HttpClientParams.setRedirecting(httpParams, false); -// // Set timeouts -// configureTimeout(httpParams, webClient_.getOptions().getTimeout()); -// -// final SchemeRegistry schemeRegistry = new SchemeRegistry(); -// schemeRegistry.register(new Scheme("http", 80, new SocksSocketFactory())); -// configureHttpsScheme(schemeRegistry); -// -// final PoolingClientConnectionManager connectionManager = -// new PoolingClientConnectionManager(schemeRegistry); -// connectionManager.setDefaultMaxPerRoute(6); -// -// final DefaultHttpClient httpClient = new DefaultHttpClient(connectionManager, httpParams); -// httpClient.setCookieStore(new HtmlUnitCookieStore2(webClient_.getCookieManager())); -// -// httpClient.setRedirectStrategy(new DefaultRedirectStrategy() { -// @Override -// public boolean isRedirected(final HttpRequest request, final HttpResponse response, -// final HttpContext context) throws ProtocolException { -// return super.isRedirected(request, response, context) -// && response.getFirstHeader("location") != null; -// } -// }); -// -// if (getVirtualHost() != null) { -// httpClient.getParams().setParameter(ClientPNames.VIRTUAL_HOST, virtualHost_); -// } + protected AbstractHttpClient createHttpClient() { + final HttpParams httpParams = new BasicHttpParams(); - final HttpClientBuilder builder = HttpClientBuilder.create(); - builder.setRedirectStrategy(new DefaultRedirectStrategy() { + HttpClientParams.setRedirecting(httpParams, false); + // Set timeouts + configureTimeout(httpParams, webClient_.getOptions().getTimeout()); + + final SchemeRegistry schemeRegistry = new SchemeRegistry(); + schemeRegistry.register(new Scheme("http", 80, new SocksSocketFactory())); + configureHttpsScheme(schemeRegistry); + + final PoolingClientConnectionManager connectionManager = + new PoolingClientConnectionManager(schemeRegistry); + connectionManager.setDefaultMaxPerRoute(6); + + final DefaultHttpClient httpClient = new DefaultHttpClient(connectionManager, httpParams); + httpClient.setCookieStore(new HtmlUnitCookieStore(webClient_.getCookieManager())); + + httpClient.setRedirectStrategy(new DefaultRedirectStrategy() { @Override public boolean isRedirected(final HttpRequest request, final HttpResponse response, final HttpContext context) throws ProtocolException { @@ -612,57 +557,45 @@ && response.getFirstHeader("location") != null; } }); - configureTimeout(builder, webClient_.getOptions().getTimeout()); - return builder; - } - private void configureTimeout(final HttpClientBuilder builder, final int timeout) { - RequestConfig.Builder requestBuilder = createRequestConfig(); - configureTimeout(requestBuilder, timeout); + if (getVirtualHost() != null) { + httpClient.getParams().setParameter(ClientPNames.VIRTUAL_HOST, virtualHost_); + } - builder.setDefaultRequestConfig(requestBuilder.build()); - httpContext_.removeAttribute(HttpClientContext.REQUEST_CONFIG); - usedOptions_.setTimeout(timeout); + return httpClient; } - private RequestConfig.Builder createRequestConfig() { - RequestConfig.Builder requestBuilder = RequestConfig.custom() - .setCookieSpec(HACKED_COOKIE_POLICY) - .setRedirectsEnabled(false); - return requestBuilder; - } + private void configureTimeout(final HttpParams httpParams, final int timeout) { + httpParams.setParameter(CoreConnectionPNames.SO_TIMEOUT, timeout); + httpParams.setParameter(CoreConnectionPNames.CONNECTION_TIMEOUT, timeout); - private void configureTimeout(final RequestConfig.Builder builder, final int timeout) { - builder.setConnectTimeout(timeout) - .setConnectionRequestTimeout(timeout) - .setSocketTimeout(timeout); + usedOptions_.setTimeout(timeout); } /** * React on changes that may have occurred on the WebClient settings. * Registering as a listener would be probably better. */ - private HttpClientBuilder reconfigureHttpClientIfNeeded(final HttpClientBuilder httpClientBuilder) { + private void reconfigureHttpClientIfNeeded(final AbstractHttpClient httpClient) { final WebClientOptions options = webClient_.getOptions(); // register new SSL factory only if settings have changed if (options.isUseInsecureSSL() != usedOptions_.isUseInsecureSSL() || options.getSSLClientCertificateUrl() != usedOptions_.getSSLClientCertificateUrl()) { - configureHttpsScheme(httpClientBuilder); + configureHttpsScheme(httpClient.getConnectionManager().getSchemeRegistry()); } if (options.getTimeout() != usedOptions_.getTimeout()) { - configureTimeout(httpClientBuilder, options.getTimeout()); + configureTimeout(httpClient.getParams(), options.getTimeout()); } - return httpClientBuilder; } - private void configureHttpsScheme(final HttpClientBuilder builder) { + private void configureHttpsScheme(final SchemeRegistry schemeRegistry) { final WebClientOptions options = webClient_.getOptions(); - final SSLConnectionSocketFactory socketFactory = HtmlUnitSSLConnectionSocketFactory.buildSSLSocketFactory(options); + final SSLSocketFactory socketFactory = HtmlUnitSSLSocketFactory.buildSSLSocketFactory(options); - builder.setSSLSocketFactory(socketFactory); + schemeRegistry.register(new Scheme("https", 443, socketFactory)); usedOptions_.setUseInsecureSSL(options.isUseInsecureSSL()); usedOptions_.setSSLClientCertificate(options.getSSLClientCertificateUrl(), @@ -676,8 +609,7 @@ public void setVirtualHost(final String virtualHost) { virtualHost_ = virtualHost; if (virtualHost_ != null) { - // TODO: asashour - //getHttpClient().getParams().setParameter(ClientPNames.VIRTUAL_HOST, virtualHost_); + getHttpClient().getParams().setParameter(ClientPNames.VIRTUAL_HOST, virtualHost_); } } @@ -693,7 +625,7 @@ * Converts an HttpMethod into a WebResponse. */ private WebResponse makeWebResponse(final HttpResponse httpResponse, - final WebRequest request, final DownloadedContent responseBody, final long loadTime) { + final WebRequest request, final DownloadedContent downloadedContent, final long loadTime) { String statusMessage = httpResponse.getStatusLine().getReasonPhrase(); if (statusMessage == null) { @@ -704,7 +636,7 @@ for (final Header header : httpResponse.getAllHeaders()) { headers.add(new NameValuePair(header.getName(), header.getValue())); } - final WebResponseData responseData = new WebResponseData(responseBody, statusCode, statusMessage, headers); + final WebResponseData responseData = new WebResponseData(downloadedContent, statusCode, statusMessage, headers); return newWebResponseInstance(responseData, loadTime, request); } @@ -789,24 +721,18 @@ * Shutdown the connection manager. */ public synchronized void shutdown() { - if (httpClientBuilder_ != null) { - // TODO: asashour - //httpClientBuilder_.getConnectionManager().shutdown(); - httpClientBuilder_ = null; + if (httpClient_ != null) { + httpClient_.getConnectionManager().shutdown(); + httpClient_ = null; } } - - //TODO: should we really do this? - public void clearCredentials() { - httpContext_.removeAttribute(HttpClientContext.TARGET_AUTH_STATE); - } } /** * Workaround for <a href="https://issues.apache.org/jira/browse/HTTPCLIENT-1006">HttpClient bug 1006</a>: * quotes are wrongly removed in cookie's values. */ -class HtmlUnitBrowserCompatCookieSpec2 extends BrowserCompatSpec { +class HtmlUnitBrowserCompatCookieSpec extends BrowserCompatSpec { /** * Comparator for sending cookies in right order. * See specification: @@ -837,7 +763,7 @@ "d/M/yyyy", }; - HtmlUnitBrowserCompatCookieSpec2(final IncorrectnessListener incorrectnessListener) { + HtmlUnitBrowserCompatCookieSpec(final IncorrectnessListener incorrectnessListener) { super(); final BasicPathHandler pathHandler = new BasicPathHandler() { @Override @@ -950,5 +876,4 @@ public synchronized void clear() { manager_.clearCookies(); } - } Modified: trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/SocksSocketFactory.java =================================================================== --- trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/SocksSocketFactory.java 2014-01-20 11:55:43 UTC (rev 9001) +++ trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/SocksSocketFactory.java 2014-01-20 14:19:21 UTC (rev 9002) @@ -21,7 +21,6 @@ import org.apache.http.HttpHost; import org.apache.http.conn.scheme.PlainSocketFactory; import org.apache.http.params.HttpParams; -import org.apache.http.protocol.HttpContext; /** * SOCKS aware {@link org.apache.http.conn.scheme.SchemeSocketFactory}. @@ -42,10 +41,6 @@ return (HttpHost) parameters.getParameter(SOCKS_PROXY); } - static HttpHost getSocksProxy(final HttpContext context) { - return (HttpHost) context.getAttribute(SOCKS_PROXY); - } - static Socket createSocketWithSocksProxy(final HttpHost socksProxy) { final InetSocketAddress address = new InetSocketAddress(socksProxy.getHostName(), socksProxy.getPort()); final Proxy proxy = new Proxy(Proxy.Type.SOCKS, address); Modified: trunk/htmlunit/src/test/java/com/gargoylesoftware/htmlunit/HttpWebConnectionTest.java =================================================================== --- trunk/htmlunit/src/test/java/com/gargoylesoftware/htmlunit/HttpWebConnectionTest.java 2014-01-20 11:55:43 UTC (rev 9001) +++ trunk/htmlunit/src/test/java/com/gargoylesoftware/htmlunit/HttpWebConnectionTest.java 2014-01-20 14:19:21 UTC (rev 9002) @@ -42,7 +42,8 @@ import org.apache.http.StatusLine; import org.apache.http.entity.StringEntity; import org.apache.http.entity.mime.MultipartEntityBuilder; -import org.apache.http.impl.client.HttpClientBuilder; +import org.apache.http.impl.client.AbstractHttpClient; +import org.apache.http.impl.client.DefaultHttpClient; import org.apache.http.message.BasicHttpResponse; import org.apache.http.message.BasicStatusLine; import org.apache.log4j.Level; @@ -243,9 +244,9 @@ final boolean[] tabCalled = {false}; final WebConnection myWebConnection = new HttpWebConnection(webClient) { @Override - protected HttpClientBuilder createHttpClient() { + protected AbstractHttpClient createHttpClient() { tabCalled[0] = true; - return HttpClientBuilder.create(); + return new DefaultHttpClient(); } }; |