| /* |
| * ==================================================================== |
| * 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 |
| * <http://www.apache.org/>. |
| * |
| */ |
| |
| package org.apache.hc.client5.http.examples; |
| |
| import java.net.InetAddress; |
| import java.net.UnknownHostException; |
| import java.nio.charset.CodingErrorAction; |
| import java.nio.charset.StandardCharsets; |
| import java.util.Arrays; |
| import java.util.Collections; |
| |
| import javax.net.ssl.SSLContext; |
| |
| import org.apache.hc.client5.http.DnsResolver; |
| import org.apache.hc.client5.http.HttpRoute; |
| import org.apache.hc.client5.http.SystemDefaultDnsResolver; |
| import org.apache.hc.client5.http.auth.CredentialsProvider; |
| import org.apache.hc.client5.http.auth.StandardAuthScheme; |
| import org.apache.hc.client5.http.classic.methods.HttpGet; |
| import org.apache.hc.client5.http.config.ConnectionConfig; |
| import org.apache.hc.client5.http.config.RequestConfig; |
| import org.apache.hc.client5.http.cookie.BasicCookieStore; |
| import org.apache.hc.client5.http.cookie.CookieStore; |
| import org.apache.hc.client5.http.cookie.StandardCookieSpec; |
| import org.apache.hc.client5.http.impl.auth.CredentialsProviderBuilder; |
| import org.apache.hc.client5.http.impl.classic.CloseableHttpClient; |
| import org.apache.hc.client5.http.impl.classic.CloseableHttpResponse; |
| import org.apache.hc.client5.http.impl.classic.HttpClients; |
| import org.apache.hc.client5.http.impl.io.ManagedHttpClientConnectionFactory; |
| import org.apache.hc.client5.http.impl.io.PoolingHttpClientConnectionManager; |
| import org.apache.hc.client5.http.io.ManagedHttpClientConnection; |
| import org.apache.hc.client5.http.protocol.HttpClientContext; |
| import org.apache.hc.client5.http.socket.ConnectionSocketFactory; |
| import org.apache.hc.client5.http.socket.PlainConnectionSocketFactory; |
| import org.apache.hc.client5.http.ssl.SSLConnectionSocketFactory; |
| import org.apache.hc.core5.http.ClassicHttpRequest; |
| import org.apache.hc.core5.http.ClassicHttpResponse; |
| import org.apache.hc.core5.http.Header; |
| import org.apache.hc.core5.http.HttpHost; |
| import org.apache.hc.core5.http.ParseException; |
| import org.apache.hc.core5.http.config.CharCodingConfig; |
| import org.apache.hc.core5.http.config.Http1Config; |
| import org.apache.hc.core5.http.config.Registry; |
| import org.apache.hc.core5.http.config.RegistryBuilder; |
| import org.apache.hc.core5.http.impl.io.DefaultClassicHttpResponseFactory; |
| import org.apache.hc.core5.http.impl.io.DefaultHttpRequestWriterFactory; |
| import org.apache.hc.core5.http.impl.io.DefaultHttpResponseParser; |
| import org.apache.hc.core5.http.impl.io.DefaultHttpResponseParserFactory; |
| import org.apache.hc.core5.http.io.HttpConnectionFactory; |
| import org.apache.hc.core5.http.io.HttpMessageParser; |
| import org.apache.hc.core5.http.io.HttpMessageParserFactory; |
| import org.apache.hc.core5.http.io.HttpMessageWriterFactory; |
| import org.apache.hc.core5.http.io.SocketConfig; |
| import org.apache.hc.core5.http.io.entity.EntityUtils; |
| import org.apache.hc.core5.http.message.BasicHeader; |
| import org.apache.hc.core5.http.message.BasicLineParser; |
| import org.apache.hc.core5.http.message.LineParser; |
| import org.apache.hc.core5.pool.PoolConcurrencyPolicy; |
| import org.apache.hc.core5.pool.PoolReusePolicy; |
| import org.apache.hc.core5.ssl.SSLContexts; |
| import org.apache.hc.core5.util.CharArrayBuffer; |
| import org.apache.hc.core5.util.TimeValue; |
| import org.apache.hc.core5.util.Timeout; |
| |
| /** |
| * 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(final String[] args) throws Exception { |
| |
| // Use custom message parser / writer to customize the way HTTP |
| // messages are parsed from and written out to the data stream. |
| final HttpMessageParserFactory<ClassicHttpResponse> responseParserFactory = new DefaultHttpResponseParserFactory() { |
| |
| @Override |
| public HttpMessageParser<ClassicHttpResponse> create(final Http1Config h1Config) { |
| final LineParser lineParser = new BasicLineParser() { |
| |
| @Override |
| public Header parseHeader(final CharArrayBuffer buffer) { |
| try { |
| return super.parseHeader(buffer); |
| } catch (final ParseException ex) { |
| return new BasicHeader(buffer.toString(), null); |
| } |
| } |
| |
| }; |
| return new DefaultHttpResponseParser(lineParser, DefaultClassicHttpResponseFactory.INSTANCE, h1Config); |
| } |
| |
| }; |
| final HttpMessageWriterFactory<ClassicHttpRequest> requestWriterFactory = new DefaultHttpRequestWriterFactory(); |
| |
| // Create HTTP/1.1 protocol configuration |
| final Http1Config h1Config = Http1Config.custom() |
| .setMaxHeaderCount(200) |
| .setMaxLineLength(2000) |
| .build(); |
| // Create connection configuration |
| final CharCodingConfig connectionConfig = CharCodingConfig.custom() |
| .setMalformedInputAction(CodingErrorAction.IGNORE) |
| .setUnmappableInputAction(CodingErrorAction.IGNORE) |
| .setCharset(StandardCharsets.UTF_8) |
| .build(); |
| |
| // Use a custom connection factory to customize the process of |
| // initialization of outgoing HTTP connections. Beside standard connection |
| // configuration parameters HTTP connection factory can define message |
| // parser / writer routines to be employed by individual connections. |
| final HttpConnectionFactory<ManagedHttpClientConnection> connFactory = new ManagedHttpClientConnectionFactory( |
| h1Config, connectionConfig, 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. |
| final SSLContext sslcontext = SSLContexts.createSystemDefault(); |
| |
| // Create a registry of custom connection socket factories for supported |
| // protocol schemes. |
| final Registry<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder.<ConnectionSocketFactory>create() |
| .register("http", PlainConnectionSocketFactory.INSTANCE) |
| .register("https", new SSLConnectionSocketFactory(sslcontext)) |
| .build(); |
| |
| // Use custom DNS resolver to override the system DNS resolution. |
| final DnsResolver dnsResolver = new SystemDefaultDnsResolver() { |
| |
| @Override |
| public InetAddress[] resolve(final String host) throws UnknownHostException { |
| if (host.equalsIgnoreCase("myhost")) { |
| return new InetAddress[] { InetAddress.getByAddress(new byte[] {127, 0, 0, 1}) }; |
| } else { |
| return super.resolve(host); |
| } |
| } |
| |
| }; |
| |
| // Create a connection manager with custom configuration. |
| final PoolingHttpClientConnectionManager connManager = new PoolingHttpClientConnectionManager( |
| socketFactoryRegistry, PoolConcurrencyPolicy.STRICT, PoolReusePolicy.LIFO, TimeValue.ofMinutes(5), |
| null, dnsResolver, null); |
| |
| // Configure the connection manager to use socket configuration either |
| // by default or for a specific host. |
| connManager.setDefaultSocketConfig(SocketConfig.custom() |
| .setTcpNoDelay(true) |
| .build()); |
| // Validate connections after 10 sec of inactivity |
| connManager.setDefaultConnectionConfig(ConnectionConfig.custom() |
| .setConnectTimeout(Timeout.ofSeconds(30)) |
| .setSocketTimeout(Timeout.ofSeconds(30)) |
| .setValidateAfterInactivity(TimeValue.ofSeconds(10)) |
| .build()); |
| |
| // 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. |
| final CookieStore cookieStore = new BasicCookieStore(); |
| // Use custom credentials provider if necessary. |
| final CredentialsProvider credentialsProvider = CredentialsProviderBuilder.create() |
| .build(); |
| // Create global request configuration |
| final RequestConfig defaultRequestConfig = RequestConfig.custom() |
| .setCookieSpec(StandardCookieSpec.STRICT) |
| .setExpectContinueEnabled(true) |
| .setTargetPreferredAuthSchemes(Arrays.asList(StandardAuthScheme.NTLM, StandardAuthScheme.DIGEST)) |
| .setProxyPreferredAuthSchemes(Collections.singletonList(StandardAuthScheme.BASIC)) |
| .build(); |
| |
| // Create an HttpClient with the given custom dependencies and configuration. |
| |
| try (final CloseableHttpClient httpclient = HttpClients.custom() |
| .setConnectionManager(connManager) |
| .setDefaultCookieStore(cookieStore) |
| .setDefaultCredentialsProvider(credentialsProvider) |
| .setProxy(new HttpHost("myproxy", 8080)) |
| .setDefaultRequestConfig(defaultRequestConfig) |
| .build()) { |
| final HttpGet httpget = new HttpGet("http://httpbin.org/get"); |
| // Request configuration can be overridden at the request level. |
| // They will take precedence over the one set at the client level. |
| final RequestConfig requestConfig = RequestConfig.copy(defaultRequestConfig) |
| .setConnectionRequestTimeout(Timeout.ofSeconds(5)) |
| .build(); |
| httpget.setConfig(requestConfig); |
| |
| // Execution context can be customized locally. |
| final 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); |
| |
| System.out.println("Executing request " + httpget.getMethod() + " " + httpget.getUri()); |
| try (final CloseableHttpResponse response = httpclient.execute(httpget, context)) { |
| System.out.println("----------------------------------------"); |
| System.out.println(response.getCode() + " " + response.getReasonPhrase()); |
| System.out.println(EntityUtils.toString(response.getEntity())); |
| |
| // 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(); |
| // Auth exchanges |
| context.getAuthExchanges(); |
| // Cookie origin |
| context.getCookieOrigin(); |
| // Cookie spec used |
| context.getCookieSpec(); |
| // User security token |
| context.getUserToken(); |
| |
| } |
| } |
| } |
| |
| } |
| |