jetty.project icon indicating copy to clipboard operation
jetty.project copied to clipboard

HttpClient fails to connect https target through http proxy with authentication when client's `strictEventOrdering` is set to true

Open vimukthiD opened this issue 3 years ago • 2 comments

Jetty version(s) 9.4.40.v20210413 (also 11.0.12)

Java version/vendor (use: java -version) openjdk 17.0.4 2022-07-19

OS type/version macOS 12.6

Description I tried to access a https target trough HTTP squid proxy but it keeps failing with Pipelined requests not supported exception (jetty-client-stacktrace.log). However if the strictEventOrdering is set to false connection is successful and target is loaded. Also if I'm connecting to http target (http://www.google.com) this will not happen.

With a small investigation it seems like when the HttpReceiver.terminateResponse notifies complete and by the time HttpChannel.associate getting called disassociate hasn't been executed resulting ProxyConnection which is used (which is getting configured to request attribute in HttpProxy.tunnel and used in AuthenticationListener.onComplete) will still have previous non null _exchange.

How to reproduce?

@Test
    public void testProxyWithAuth() throws Exception {
        String user = "test";
        String password = "test";
        String serverHost = "https://www.google.com";
        String realm = "Squid proxy-realm";
        String proxyHost = "127.0.0.1";
        int proxyPort = 8080;

        SslContextFactory.Client sslContextFactory = new SslContextFactory.Client();
        sslContextFactory.setTrustAll(true);

        HttpClient client = new HttpClient(sslContextFactory);

        ProxyConfiguration proxyConfig = client.getProxyConfiguration();
        HttpProxy proxy = new HttpProxy(new Origin.Address(proxyHost, proxyPort), false);
        proxy.getIncludedAddresses().add("www.google.com:80");
        proxy.getIncludedAddresses().add("www.google.com:443");

        client.getAuthenticationStore().addAuthentication(
                new BasicAuthentication(new URI("http://" + proxyHost + ":" + proxyPort)
                        , realm, user, password)
        );

        proxyConfig.getProxies().add(proxy);

        client.setExecutor(new QueuedThreadPool(64, 0, 60000));
        client.setMaxConnectionsPerDestination(10);
        client.setIdleTimeout(6000);
        client.setStrictEventOrdering(true);
        client.setFollowRedirects(true);

        client.start();

        try {
            Request request = client.newRequest(serverHost);
            ContentResponse response = request
                    .timeout(600, TimeUnit.SECONDS)
                    .send();

            System.out.println("Status: " + response.getStatus());
        } finally {
            client.stop();
        }
    }

vimukthiD avatar Oct 17 '22 10:10 vimukthiD