diff --git a/httpclient/src/main/java/org/apache/http/conn/util/PublicSuffixMatcherLoader.java b/httpclient/src/main/java/org/apache/http/conn/util/PublicSuffixMatcherLoader.java index 44edd57b8..173763a87 100644 --- a/httpclient/src/main/java/org/apache/http/conn/util/PublicSuffixMatcherLoader.java +++ b/httpclient/src/main/java/org/apache/http/conn/util/PublicSuffixMatcherLoader.java @@ -26,6 +26,8 @@ */ package org.apache.http.conn.util; +import java.io.File; +import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; @@ -39,18 +41,34 @@ import org.apache.http.annotation.ThreadSafe; import org.apache.http.util.Args; /** + * {@link org.apache.http.conn.util.PublicSuffixMatcher} loader. + * * @since 4.4 */ @ThreadSafe public final class PublicSuffixMatcherLoader { + private static PublicSuffixMatcher load(final InputStream in) throws IOException { + final PublicSuffixList list = new PublicSuffixListParser().parse( + new InputStreamReader(in, Consts.UTF_8)); + return new PublicSuffixMatcher(list.getRules(), list.getExceptions()); + } + public static PublicSuffixMatcher load(final URL url) throws IOException { Args.notNull(url, "URL"); final InputStream in = url.openStream(); try { - final PublicSuffixList list = new PublicSuffixListParser().parse( - new InputStreamReader(in, Consts.UTF_8)); - return new PublicSuffixMatcher(list.getRules(), list.getExceptions()); + return load(in); + } finally { + in.close(); + } + } + + public static PublicSuffixMatcher load(final File file) throws IOException { + Args.notNull(file, "File"); + final InputStream in = new FileInputStream(file); + try { + return load(in); } finally { in.close(); } diff --git a/httpclient/src/main/java/org/apache/http/impl/client/HttpClientBuilder.java b/httpclient/src/main/java/org/apache/http/impl/client/HttpClientBuilder.java index 33b05b95e..2c0d9c0c7 100644 --- a/httpclient/src/main/java/org/apache/http/impl/client/HttpClientBuilder.java +++ b/httpclient/src/main/java/org/apache/http/impl/client/HttpClientBuilder.java @@ -81,9 +81,12 @@ import org.apache.http.conn.routing.HttpRoutePlanner; import org.apache.http.conn.socket.ConnectionSocketFactory; import org.apache.http.conn.socket.LayeredConnectionSocketFactory; import org.apache.http.conn.socket.PlainConnectionSocketFactory; +import org.apache.http.conn.ssl.DefaultHostnameVerifier; 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.conn.util.PublicSuffixMatcher; +import org.apache.http.conn.util.PublicSuffixMatcherLoader; import org.apache.http.cookie.CookieSpecProvider; import org.apache.http.impl.DefaultConnectionReuseStrategy; import org.apache.http.impl.NoConnectionReuseStrategy; @@ -211,6 +214,8 @@ public class HttpClientBuilder { private List closeables; + private PublicSuffixMatcher publicSuffixMatcher; + public static HttpClientBuilder create() { return new HttpClientBuilder(); } @@ -258,6 +263,20 @@ public class HttpClientBuilder { return this; } + /** + * Assigns file containing public suffix matcher. Instances of this class can be created + * with {@link org.apache.http.conn.util.PublicSuffixMatcherLoader}. + * + * @see org.apache.http.conn.util.PublicSuffixMatcher + * @see org.apache.http.conn.util.PublicSuffixMatcherLoader + * + * @since 4.4 + */ + public final HttpClientBuilder setPublicSuffixMatcher(final PublicSuffixMatcher publicSuffixMatcher) { + this.publicSuffixMatcher = publicSuffixMatcher; + return this; + } + /** * Assigns {@link SSLContext} instance. *

@@ -803,6 +822,11 @@ public class HttpClientBuilder { public CloseableHttpClient build() { // Create main request executor // We copy the instance fields to avoid changing them, and rename to avoid accidental use of the wrong version + PublicSuffixMatcher publicSuffixMatcherCopy = this.publicSuffixMatcher; + if (publicSuffixMatcherCopy == null) { + publicSuffixMatcherCopy = PublicSuffixMatcherLoader.getDefault(); + } + HttpRequestExecutor requestExecCopy = this.requestExec; if (requestExecCopy == null) { requestExecCopy = new HttpRequestExecutor(); @@ -817,7 +841,7 @@ public class HttpClientBuilder { System.getProperty("https.cipherSuites")) : null; HostnameVerifier hostnameVerifierCopy = this.hostnameVerifier; if (hostnameVerifierCopy == null) { - hostnameVerifierCopy = SSLConnectionSocketFactory.getDefaultHostnameVerifier(); + hostnameVerifierCopy = new DefaultHostnameVerifier(publicSuffixMatcherCopy); } if (sslcontext != null) { sslSocketFactoryCopy = new SSLConnectionSocketFactory( @@ -1047,8 +1071,8 @@ public class HttpClientBuilder { Lookup cookieSpecRegistryCopy = this.cookieSpecRegistry; if (cookieSpecRegistryCopy == null) { cookieSpecRegistryCopy = RegistryBuilder.create() - .register(CookieSpecs.DEFAULT, new DefaultCookieSpecProvider()) - .register(CookieSpecs.STANDARD, new RFC2965SpecProvider()) + .register(CookieSpecs.DEFAULT, new DefaultCookieSpecProvider(publicSuffixMatcherCopy)) + .register(CookieSpecs.STANDARD, new RFC2965SpecProvider(publicSuffixMatcherCopy)) .register(CookieSpecs.NETSCAPE, new NetscapeDraftSpecProvider()) .register(CookieSpecs.IGNORE_COOKIES, new IgnoreSpecProvider()) .build(); diff --git a/httpclient/src/main/java/org/apache/http/impl/cookie/DefaultCookieSpecProvider.java b/httpclient/src/main/java/org/apache/http/impl/cookie/DefaultCookieSpecProvider.java index 8ed8250ad..e9b894e11 100644 --- a/httpclient/src/main/java/org/apache/http/impl/cookie/DefaultCookieSpecProvider.java +++ b/httpclient/src/main/java/org/apache/http/impl/cookie/DefaultCookieSpecProvider.java @@ -76,6 +76,10 @@ public class DefaultCookieSpecProvider implements CookieSpecProvider { this(compatibilityLevel, publicSuffixMatcher, null, false); } + public DefaultCookieSpecProvider(final PublicSuffixMatcher publicSuffixMatcher) { + this(CompatibilityLevel.DEFAULT, publicSuffixMatcher, null, false); + } + public DefaultCookieSpecProvider() { this(CompatibilityLevel.DEFAULT, null, null, false); }