[
https://issues.apache.org/jira/browse/HTTPCLIENT-2373?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
]
Oleg Kalnichevski resolved HTTPCLIENT-2373.
-------------------------------------------
Resolution: Invalid
> HTTP proxy returns 400 when connection was established before
> -------------------------------------------------------------
>
> Key: HTTPCLIENT-2373
> URL: https://issues.apache.org/jira/browse/HTTPCLIENT-2373
> Project: HttpComponents HttpClient
> Issue Type: Bug
> Components: HttpClient (classic)
> Affects Versions: 5.4.4
> Reporter: Thomas Beckers
> Priority: Major
>
> The following code makes a HTTP request that returns 400 from the proxy
> (Squid).
> There is no issue when no connection is established before
> (DO_SOCKET_CONNECT_BEFORE = false). The socket connection is done to perform
> some sort of connection test before making the actual HTTP request.
> Equivalent code is working in Http Client 4.
> {code:java}
> import org.apache.hc.client5.http.HttpRoute;
> 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.impl.classic.CloseableHttpClient;
> import org.apache.hc.client5.http.impl.classic.HttpClientBuilder;
> import org.apache.hc.client5.http.impl.classic.HttpClients;
> import org.apache.hc.client5.http.impl.io.BasicHttpClientConnectionManager;
> import org.apache.hc.client5.http.impl.io.ManagedHttpClientConnectionFactory;
> import org.apache.hc.client5.http.impl.routing.DefaultProxyRoutePlanner;
> import org.apache.hc.client5.http.io.ConnectionEndpoint;
> import org.apache.hc.client5.http.io.HttpClientConnectionManager;
> import org.apache.hc.client5.http.io.LeaseRequest;
> import org.apache.hc.client5.http.protocol.HttpClientContext;
> import org.apache.hc.client5.http.routing.HttpRoutePlanner;
> import org.apache.hc.client5.http.ssl.DefaultClientTlsStrategy;
> import org.apache.hc.client5.http.ssl.TlsSocketStrategy;
> import org.apache.hc.core5.http.HttpException;
> import org.apache.hc.core5.http.HttpHost;
> import org.apache.hc.core5.http.HttpVersion;
> 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.io.SocketConfig;
> import org.apache.hc.core5.http.protocol.HttpContext;
> import org.apache.hc.core5.util.TimeValue;
> import org.apache.hc.core5.util.Timeout;
> import java.io.IOException;
> import java.net.URI;
> import java.util.concurrent.ExecutionException;
> import java.util.concurrent.TimeUnit;
> import java.util.concurrent.TimeoutException;
> public class HttpClientIssue {
> private static final String PROXY_HOST = "<SQUID_HOST>";
> private static final int PROXY_PORT = 3128;
> private static final URI TARGET_URI =
> URI.create("https://workspace.google.com:443/intl/de/gmail/");
> private static boolean DO_SOCKET_CONNECT_BEFORE = true;
> public static void main(String[] args) throws IOException,
> ExecutionException, InterruptedException, TimeoutException {
> Client client = createHttpClient();
> if (DO_SOCKET_CONNECT_BEFORE) {
> ConnectionEndpoint connectionEndpoint = null;
> try {
> HttpHost targetHost = new HttpHost(TARGET_URI.getScheme(),
> TARGET_URI.getHost(), TARGET_URI.getPort());
> HttpRoute route = determineRouteViaHttpProxy(targetHost);
> LeaseRequest connectionRequest =
> client.connectionManager().lease(null, route, Timeout.ofMilliseconds(15_000),
> null);
> connectionEndpoint =
> connectionRequest.get(Timeout.ofMilliseconds(15_000));
> HttpClientContext context = HttpClientContext.create();
> context.setRoute(route);
> client.connectionManager().connect(connectionEndpoint,
> Timeout.ofMilliseconds(15_000), context);
> if (!connectionEndpoint.isConnected()) {
> throw new RuntimeException();
> }
> } finally {
> client.connectionManager().release(connectionEndpoint, null,
> TimeValue.of(0, TimeUnit.SECONDS));
> }
> }
> HttpGet request = new HttpGet(TARGET_URI);
> String result = client.client()
> .execute(request, response -> new
> String(response.getEntity().getContent().readAllBytes()));
> System.out.println(result);
> }
> private record Client(CloseableHttpClient client,
> HttpClientConnectionManager connectionManager) {
> }
> private static class HttpProxyRoutePlanner implements HttpRoutePlanner {
> @Override
> public HttpRoute determineRoute(HttpHost targetHost, HttpContext
> context) {
> HttpHost proxyHost = new HttpHost(PROXY_HOST, PROXY_PORT);
> boolean isSecure =
> "https".equalsIgnoreCase(targetHost.getSchemeName());
> return new HttpRoute(targetHost, null, proxyHost, isSecure);
> }
> }
> private static HttpRoute determineRouteViaHttpProxy(HttpHost targetHost) {
> HttpRoutePlanner routePlanner = new HttpProxyRoutePlanner();
> HttpRoute httpRoute;
> try {
> httpRoute = routePlanner.determineRoute(targetHost, null, null);
> } catch (HttpException e) {
> throw new RuntimeException(e.getMessage(), e);
> }
> return httpRoute;
> }
> private static Client createHttpClient() {
> Http1Config http1Config = Http1Config.custom()
> .setVersion(HttpVersion.HTTP_1_1)
> .build();
> ManagedHttpClientConnectionFactory managedHttpClientConnectionFactory
> = ManagedHttpClientConnectionFactory.builder()
>
> .http1Config(http1Config)
>
> .build();
> ConnectionConfig connectionConfig = ConnectionConfig.custom()
>
> .setConnectTimeout(15_000, TimeUnit.MILLISECONDS)
>
> .setSocketTimeout(15_000, TimeUnit.MILLISECONDS)
> .build();
> RequestConfig requestConfig = RequestConfig.custom()
>
> .setExpectContinueEnabled(false)
> .build();
> BasicHttpClientConnectionManager connectionManager =
> BasicHttpClientConnectionManager.create(createSchemeRegistry(),
>
> managedHttpClientConnectionFactory);
> connectionManager.setConnectionConfig(connectionConfig);
>
> connectionManager.setSocketConfig(SocketConfig.custom().setSoTimeout(15_000,
> TimeUnit.MILLISECONDS).build());
> HttpClientBuilder clientBuilder = HttpClients.custom()
>
> .setConnectionManager(connectionManager)
>
> .setDefaultRequestConfig(requestConfig)
> .setRoutePlanner(
> new
> DefaultProxyRoutePlanner(new HttpHost(PROXY_HOST, PROXY_PORT)));
> return new Client(clientBuilder.build(), connectionManager);
> }
> private static Registry<TlsSocketStrategy> createSchemeRegistry() {
> RegistryBuilder<TlsSocketStrategy> registryBuilder =
> RegistryBuilder.create();
> registryBuilder.register("https",
> DefaultClientTlsStrategy.createSystemDefault());
> return registryBuilder.build();
> }
> }
> {code}
> (This code is a boiled down version of the real code in our application)
> Is this a bug or are we misusing Http Client?
--
This message was sent by Atlassian Jira
(v8.20.10#820010)
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]