diff --git a/httpclient/src/examples/org/apache/http/examples/client/ClientConfiguration.java b/httpclient/src/examples/org/apache/http/examples/client/ClientConfiguration.java
new file mode 100644
index 000000000..65ce15f68
--- /dev/null
+++ b/httpclient/src/examples/org/apache/http/examples/client/ClientConfiguration.java
@@ -0,0 +1,240 @@
+/*
+ * ====================================================================
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * .
+ *
+ */
+
+package org.apache.http.examples.client;
+
+import java.nio.charset.CodingErrorAction;
+import java.util.Arrays;
+
+import javax.net.ssl.SSLContext;
+
+import org.apache.http.Consts;
+import org.apache.http.HttpEntity;
+import org.apache.http.HttpHost;
+import org.apache.http.HttpRequest;
+import org.apache.http.HttpResponse;
+import org.apache.http.HttpResponseFactory;
+import org.apache.http.client.CookieStore;
+import org.apache.http.client.CredentialsProvider;
+import org.apache.http.client.config.AuthSchemes;
+import org.apache.http.client.config.CookieSpecs;
+import org.apache.http.client.config.RequestConfig;
+import org.apache.http.client.methods.CloseableHttpResponse;
+import org.apache.http.client.methods.HttpGet;
+import org.apache.http.client.protocol.HttpClientContext;
+import org.apache.http.config.ConnectionConfig;
+import org.apache.http.config.MessageConstraints;
+import org.apache.http.config.Registry;
+import org.apache.http.config.RegistryBuilder;
+import org.apache.http.config.SocketConfig;
+import org.apache.http.conn.DnsResolver;
+import org.apache.http.conn.HttpConnectionFactory;
+import org.apache.http.conn.SocketClientConnection;
+import org.apache.http.conn.routing.HttpRoute;
+import org.apache.http.conn.socket.ConnectionSocketFactory;
+import org.apache.http.conn.socket.PlainSocketFactory;
+import org.apache.http.conn.ssl.BrowserCompatHostnameVerifier;
+import org.apache.http.conn.ssl.SSLSocketFactory;
+import org.apache.http.conn.ssl.X509HostnameVerifier;
+import org.apache.http.impl.DefaultHttpResponseFactory;
+import org.apache.http.impl.client.BasicCookieStore;
+import org.apache.http.impl.client.BasicCredentialsProvider;
+import org.apache.http.impl.client.CloseableHttpClient;
+import org.apache.http.impl.client.HttpClients;
+import org.apache.http.impl.conn.DefaultClientConnectionFactory;
+import org.apache.http.impl.conn.DefaultHttpResponseParserFactory;
+import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
+import org.apache.http.impl.conn.SystemDefaultDnsResolver;
+import org.apache.http.impl.io.DefaultHttpRequestWriterFactory;
+import org.apache.http.io.HttpMessageParserFactory;
+import org.apache.http.io.HttpMessageWriterFactory;
+
+/**
+ * This example demonstrates how to customize and configure the most common aspects
+ * of HTTP request execution and connection management.
+ */
+public class ClientConfiguration {
+
+ public final static void main(String[] args) throws Exception {
+
+ // Use a custom response factory to customize the way HTTP response
+ // objects are generated.
+ HttpResponseFactory responseFactory = new DefaultHttpResponseFactory();
+
+ // Use custom message parser / writer to customize the way HTTP
+ // messages are parsed from and written out to the data stream.
+ HttpMessageParserFactory responseParserFactory = new DefaultHttpResponseParserFactory(
+ responseFactory);
+ HttpMessageWriterFactory requestWriterFactory = new DefaultHttpRequestWriterFactory();
+
+ // Use a custom connection factory to customize the process of
+ // initialization of outgoing HTTP connections. Beside standard connection
+ // configuration parameters HTTP connection factory can control the size of
+ // input / output buffers as well as determine message parser / writer routines
+ // to be employed by individual connections.
+ HttpConnectionFactory connFactory = new DefaultClientConnectionFactory(
+ 8 * 1024, requestWriterFactory, responseParserFactory);
+
+ // Client HTTP connection objects when fully initialized can be bound to
+ // an arbitrary network socket. The process of network socket initialization,
+ // its connection to a remote address and binding to a local one is controlled
+ // by a connection socket factory.
+
+ // SSL context for secure connections can be created either based on
+ // system or application specific properties.
+ SSLContext sslcontext = SSLSocketFactory.createSystemSSLContext();
+ // Use custom hostname verifier to customize SSL hostname verification.
+ X509HostnameVerifier hostnameVerifier = new BrowserCompatHostnameVerifier();
+
+ // Create a registry of custom connection socket factories for supported
+ // protocol schemes.
+ Registry socketFactoryRegistry = RegistryBuilder.create()
+ .register("http", PlainSocketFactory.INSTANCE)
+ .register("https", new SSLSocketFactory(sslcontext, hostnameVerifier))
+ .build();
+
+ // Use custom DNS resolver to override the system DNS resolution.
+ DnsResolver dnsResolver = new SystemDefaultDnsResolver();
+
+ // Create a connection manager with custom configuration.
+ PoolingHttpClientConnectionManager connManager = new PoolingHttpClientConnectionManager(
+ socketFactoryRegistry, connFactory, dnsResolver);
+
+ // Create socket configuration
+ SocketConfig socketConfig = SocketConfig.custom()
+ .setTcpNoDelay(true)
+ .build();
+ // Configure the connection manager to use socket configuration either
+ // by default or for a specific host.
+ connManager.setDefaultSocketConfig(socketConfig);
+ connManager.setSocketConfig(new HttpHost("somehost", 80), socketConfig);
+
+ // Create message constraints
+ MessageConstraints messageConstraints = MessageConstraints.custom()
+ .setMaxHeaderCount(200)
+ .setMaxLineLength(2000)
+ .build();
+ // Create connection configuration
+ ConnectionConfig connectionConfig = ConnectionConfig.custom()
+ .setMalformedInputAction(CodingErrorAction.IGNORE)
+ .setUnmappableInputAction(CodingErrorAction.IGNORE)
+ .setCharset(Consts.UTF_8)
+ .setMessageConstraints(messageConstraints)
+ .build();
+ // Configure the connection manager to use connection configuration either
+ // by default or for a specific host.
+ connManager.setDefaultConnectionConfig(connectionConfig);
+ connManager.setConnectionConfig(new HttpHost("somehost", 80), ConnectionConfig.DEFAULT);
+
+ // Configure total max or per route limits for persistent connections
+ // that can be kept in the pool or leased by the connection manager.
+ connManager.setMaxTotal(100);
+ connManager.setDefaultMaxPerRoute(10);
+ connManager.setMaxPerRoute(new HttpRoute(new HttpHost("somehost", 80)), 20);
+
+ // Use custom cookie store if necessary.
+ CookieStore cookieStore = new BasicCookieStore();
+ // Use custom credentials provider if necessary.
+ CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
+ // Create global request configuration
+ RequestConfig defaultRequestConfig = RequestConfig.custom()
+ .setCookieSpec(CookieSpecs.BEST_MATCH)
+ .setExpectContinueEnabled(true)
+ .setStaleConnectionCheckEnabled(true)
+ .setTargetPreferredAuthSchemes(Arrays.asList(AuthSchemes.NTLM, AuthSchemes.DIGEST))
+ .setProxyPreferredAuthSchemes(Arrays.asList(AuthSchemes.BASIC))
+ .setDefaultProxy(new HttpHost("myproxy", 8080))
+ .build();
+
+ // Create an HttpClient with the given custom dependencies and configuration.
+ CloseableHttpClient httpclient = HttpClients.custom()
+ .setConnectionManager(connManager)
+ .setCookieStore(cookieStore)
+ .setCredentialsProvider(credentialsProvider)
+ .setDefaultRequestConfig(defaultRequestConfig)
+ .build();
+
+ try {
+ HttpGet httpget = new HttpGet("http://www.apache.org/");
+ // Request configuration can be overridden at the request level.
+ // They will take precedence over the one set at the client level.
+ RequestConfig requestConfig = RequestConfig.copy(defaultRequestConfig)
+ .setSocketTimeout(5000)
+ .setConnectTimeout(5000)
+ .setConnectionRequestTimeout(5000)
+ .build();
+ httpget.setConfig(requestConfig);
+
+ // Execution context can be customized locally.
+ HttpClientContext context = HttpClientContext.create();
+ // Contextual attributes set the local context level will take
+ // precedence over those set at the client level.
+ context.setCookieStore(cookieStore);
+ context.setCredentialsProvider(credentialsProvider);
+ context.setSocketFactoryRegistry(socketFactoryRegistry);
+
+ System.out.println("executing request " + httpget.getURI());
+ CloseableHttpResponse response = httpclient.execute(httpget, context);
+ try {
+ HttpEntity entity = response.getEntity();
+
+ System.out.println("----------------------------------------");
+ System.out.println(response.getStatusLine());
+ if (entity != null) {
+ System.out.println("Response content length: " + entity.getContentLength());
+ }
+ System.out.println("----------------------------------------");
+
+ // Once the request has been executed the local context can
+ // be used to examine updated state and various objects affected
+ // by the request execution.
+
+ // Last executed request
+ context.getRequest();
+ // Execution route
+ context.getHttpRoute();
+ // Target auth state
+ context.getTargetAuthState();
+ // Proxy auth state
+ context.getTargetAuthState();
+ // Cookie origin
+ context.getCookieOrigin();
+ // Cookie spec used
+ context.getCookieSpec();
+ // User security token
+ context.getUserToken();
+
+ } finally {
+ response.close();
+ }
+ } finally {
+ httpclient.close();
+ }
+ }
+
+}
+
diff --git a/httpclient/src/examples/org/apache/http/examples/client/ClientExecuteDirect.java b/httpclient/src/examples/org/apache/http/examples/client/ClientExecuteDirect.java
deleted file mode 100644
index dde3ffd9b..000000000
--- a/httpclient/src/examples/org/apache/http/examples/client/ClientExecuteDirect.java
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * ====================================================================
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation. For more
- * information on the Apache Software Foundation, please see
- * .
- *
- */
-
-package org.apache.http.examples.client;
-
-import org.apache.http.Header;
-import org.apache.http.HttpEntity;
-import org.apache.http.HttpHost;
-import org.apache.http.client.HttpClient;
-import org.apache.http.client.methods.CloseableHttpResponse;
-import org.apache.http.client.methods.HttpGet;
-import org.apache.http.impl.client.CloseableHttpClient;
-import org.apache.http.impl.client.HttpClients;
-import org.apache.http.util.EntityUtils;
-
-/**
- * How to send a request directly using {@link HttpClient}.
- *
- * @since 4.0
- */
-public class ClientExecuteDirect {
-
- public static void main(String[] args) throws Exception {
- CloseableHttpClient httpclient = HttpClients.createDefault();
- try {
- HttpHost target = new HttpHost("www.apache.org", 80, "http");
- HttpGet request = new HttpGet("/");
-
- System.out.println("executing request to " + target);
-
- CloseableHttpResponse response = httpclient.execute(target, request);
- try {
- HttpEntity entity = response.getEntity();
-
- System.out.println("----------------------------------------");
- System.out.println(response.getStatusLine());
- Header[] headers = response.getAllHeaders();
- for (int i = 0; i < headers.length; i++) {
- System.out.println(headers[i]);
- }
- System.out.println("----------------------------------------");
-
- if (entity != null) {
- System.out.println(EntityUtils.toString(entity));
- }
- } finally {
- response.close();
- }
- } finally {
- httpclient.close();
- }
- }
-
-}
diff --git a/httpclient/src/examples/org/apache/http/examples/client/ClientWithResponseHandler.java b/httpclient/src/examples/org/apache/http/examples/client/ClientWithResponseHandler.java
index e069cdc17..6f6ae2fae 100644
--- a/httpclient/src/examples/org/apache/http/examples/client/ClientWithResponseHandler.java
+++ b/httpclient/src/examples/org/apache/http/examples/client/ClientWithResponseHandler.java
@@ -27,11 +27,16 @@
package org.apache.http.examples.client;
+import java.io.IOException;
+
+import org.apache.http.HttpEntity;
+import org.apache.http.HttpResponse;
+import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.ResponseHandler;
import org.apache.http.client.methods.HttpGet;
-import org.apache.http.impl.client.BasicResponseHandler;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
+import org.apache.http.util.EntityUtils;
/**
* This example demonstrates the use of the {@link ResponseHandler} to simplify
@@ -46,8 +51,21 @@ public class ClientWithResponseHandler {
System.out.println("executing request " + httpget.getURI());
- // Create a response handler
- ResponseHandler responseHandler = new BasicResponseHandler();
+ // Create a custom response handler
+ ResponseHandler responseHandler = new ResponseHandler() {
+
+ public String handleResponse(
+ final HttpResponse response) throws ClientProtocolException, IOException {
+ int status = response.getStatusLine().getStatusCode();
+ if (status >= 200 && status < 300) {
+ HttpEntity entity = response.getEntity();
+ return entity != null ? EntityUtils.toString(entity) : null;
+ } else {
+ throw new ClientProtocolException("Unexpected response status: " + status);
+ }
+ }
+
+ };
String responseBody = httpclient.execute(httpget, responseHandler);
System.out.println("----------------------------------------");
System.out.println(responseBody);
diff --git a/httpclient/src/main/java/org/apache/http/conn/ssl/SSLSocketFactory.java b/httpclient/src/main/java/org/apache/http/conn/ssl/SSLSocketFactory.java
index 79be403ca..0d7743e28 100644
--- a/httpclient/src/main/java/org/apache/http/conn/ssl/SSLSocketFactory.java
+++ b/httpclient/src/main/java/org/apache/http/conn/ssl/SSLSocketFactory.java
@@ -349,7 +349,10 @@ public class SSLSocketFactory implements LayeredConnectionSocketFactory, SchemeL
return sslcontext;
}
- private static SSLContext createDefaultSSLContext() throws SSLInitializationException {
+ /**
+ * @since 4.3
+ */
+ public static SSLContext createDefaultSSLContext() throws SSLInitializationException {
try {
return createSSLContext(TLS, null, null, null, null, null);
} catch (Exception ex) {
@@ -357,7 +360,10 @@ public class SSLSocketFactory implements LayeredConnectionSocketFactory, SchemeL
}
}
- private static SSLContext createSystemSSLContext() throws SSLInitializationException {
+ /**
+ * @since 4.3
+ */
+ public static SSLContext createSystemSSLContext() throws SSLInitializationException {
try {
return createSystemSSLContext(TLS, null);
} catch (Exception ex) {
diff --git a/httpclient/src/main/java/org/apache/http/impl/conn/DefaultClientConnectionFactory.java b/httpclient/src/main/java/org/apache/http/impl/conn/DefaultClientConnectionFactory.java
index cb7877c30..3dd8ce555 100644
--- a/httpclient/src/main/java/org/apache/http/impl/conn/DefaultClientConnectionFactory.java
+++ b/httpclient/src/main/java/org/apache/http/impl/conn/DefaultClientConnectionFactory.java
@@ -32,10 +32,16 @@ import java.nio.charset.CharsetDecoder;
import java.nio.charset.CharsetEncoder;
import java.nio.charset.CodingErrorAction;
+import org.apache.http.HttpRequest;
+import org.apache.http.HttpResponse;
import org.apache.http.annotation.Immutable;
import org.apache.http.config.ConnectionConfig;
import org.apache.http.conn.HttpConnectionFactory;
import org.apache.http.conn.SocketClientConnection;
+import org.apache.http.impl.io.DefaultHttpRequestWriterFactory;
+import org.apache.http.io.HttpMessageParserFactory;
+import org.apache.http.io.HttpMessageWriterFactory;
+import org.apache.http.util.Args;
/**
* @since 4.3
@@ -45,6 +51,36 @@ public class DefaultClientConnectionFactory implements HttpConnectionFactory requestWriterFactory;
+ private final HttpMessageParserFactory responseParserFactory;
+
+ public DefaultClientConnectionFactory(
+ int bufferSize,
+ final HttpMessageWriterFactory requestWriterFactory,
+ final HttpMessageParserFactory responseParserFactory) {
+ super();
+ this.bufferSize = Args.notNegative(bufferSize, "Buffer size");
+ this.requestWriterFactory = requestWriterFactory != null ? requestWriterFactory :
+ DefaultHttpRequestWriterFactory.INSTANCE;
+ this.responseParserFactory = responseParserFactory != null ? responseParserFactory :
+ DefaultHttpResponseParserFactory.INSTANCE;
+ }
+
+ public DefaultClientConnectionFactory(
+ final HttpMessageParserFactory responseParserFactory) {
+ this(8 * 1024, null, responseParserFactory);
+ }
+
+ public DefaultClientConnectionFactory(
+ int bufferSize) {
+ this(bufferSize, null, null);
+ }
+
+ public DefaultClientConnectionFactory() {
+ this(8 * 1024, null, null);
+ }
+
public SocketClientConnection create(final ConnectionConfig config) {
ConnectionConfig cconfig = config != null ? config : ConnectionConfig.DEFAULT;
CharsetDecoder chardecoder = null;
@@ -62,11 +98,12 @@ public class DefaultClientConnectionFactory implements HttpConnectionFactory socketFactoryRegistry,
+ final HttpConnectionFactory connFactory,
+ final DnsResolver dnsResolver) {
+ this(socketFactoryRegistry, connFactory, null, dnsResolver, -1, TimeUnit.MILLISECONDS);
+ }
+
public PoolingHttpClientConnectionManager(
final Registry socketFactoryRegistry,
final HttpConnectionFactory connFactory,