[ 
https://issues.apache.org/jira/browse/HTTPCLIENT-2373?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17956305#comment-17956305
 ] 

Oleg Kalnichevski commented on HTTPCLIENT-2373:
-----------------------------------------------

[~beth4soptim] I do not think what you are trying to do here makes sense with 
any version of HttpClient. That same approach most likely does not work with HC 
4, it just was not obvious. The _only_ reliable way to make sure a route is 
valid and fully established it by executing a cheap request such as OPTIONS or 
HEAD.

Oleg

> 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: dev-unsubscr...@hc.apache.org
For additional commands, e-mail: dev-h...@hc.apache.org

Reply via email to