8352623: MultiExchange should cancel exchange impl if responseFilters throws

Reviewed-by: djelinski
This commit is contained in:
Daniel Fuchs 2025-03-26 13:01:44 +00:00
parent e2a461bdde
commit eef6aefc21
2 changed files with 56 additions and 43 deletions

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2015, 2024, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -25,6 +25,7 @@
package jdk.internal.net.http;
import java.io.IOError;
import java.io.IOException;
import java.lang.ref.WeakReference;
import java.net.ConnectException;
@ -440,7 +441,9 @@ class MultiExchange<T> implements Cancelable {
try {
// 3. apply response filters
newrequest = responseFilters(response);
} catch (IOException e) {
} catch (Throwable t) {
IOException e = t instanceof IOException io ? io : new IOException(t);
exch.exchImpl.cancel(e);
return failedFuture(e);
}
// 4. check filter result and repeat or continue

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -23,7 +23,7 @@
/*
* @test
* @bug 8203882
* @bug 8203882 8352623
* @summary (httpclient) Check that HttpClient throws IOException when
* receiving 401/407 with no WWW-Authenticate/Proxy-Authenticate
* header only in the case where an authenticator is configured
@ -36,9 +36,6 @@
* UnauthorizedTest
*/
import com.sun.net.httpserver.HttpServer;
import com.sun.net.httpserver.HttpsConfigurator;
import com.sun.net.httpserver.HttpsServer;
import jdk.test.lib.net.SimpleSSLContext;
import org.testng.annotations.AfterTest;
import org.testng.annotations.BeforeTest;
@ -49,9 +46,8 @@ import javax.net.ssl.SSLContext;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.lang.ref.WeakReference;
import java.net.Authenticator;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
@ -60,7 +56,6 @@ import java.net.http.HttpResponse.BodyHandlers;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.atomic.AtomicLong;
import jdk.httpclient.test.lib.common.HttpServerAdapters;
import jdk.httpclient.test.lib.http2.Http2TestServer;
import static java.lang.System.out;
import static java.net.http.HttpClient.Version.HTTP_1_1;
@ -95,41 +90,45 @@ public class UnauthorizedTest implements HttpServerAdapters {
static final int HTTP_OK = 200;
static final String MESSAGE = "Unauthorized";
static WeakReference<HttpClient> ref(HttpClient client) {
return new WeakReference<>(client);
}
@DataProvider(name = "all")
public Object[][] positive() {
return new Object[][] {
{ httpURI + "/server", UNAUTHORIZED, true, authClient},
{ httpsURI + "/server", UNAUTHORIZED, true, authClient},
{ http2URI + "/server", UNAUTHORIZED, true, authClient},
{ https2URI + "/server", UNAUTHORIZED, true, authClient},
{ httpURI + "/proxy", PROXY_UNAUTHORIZED, true, authClient},
{ httpsURI + "/proxy", PROXY_UNAUTHORIZED, true, authClient},
{ http2URI + "/proxy", PROXY_UNAUTHORIZED, true, authClient},
{ https2URI + "/proxy", PROXY_UNAUTHORIZED, true, authClient},
{ httpURI + "/server", UNAUTHORIZED, false, authClient},
{ httpsURI + "/server", UNAUTHORIZED, false, authClient},
{ http2URI + "/server", UNAUTHORIZED, false, authClient},
{ https2URI + "/server", UNAUTHORIZED, false, authClient},
{ httpURI + "/proxy", PROXY_UNAUTHORIZED, false, authClient},
{ httpsURI + "/proxy", PROXY_UNAUTHORIZED, false, authClient},
{ http2URI + "/proxy", PROXY_UNAUTHORIZED, false, authClient},
{ https2URI + "/proxy", PROXY_UNAUTHORIZED, false, authClient},
{ httpURI + "/server", UNAUTHORIZED, true, noAuthClient},
{ httpsURI + "/server", UNAUTHORIZED, true, noAuthClient},
{ http2URI + "/server", UNAUTHORIZED, true, noAuthClient},
{ https2URI + "/server", UNAUTHORIZED, true, noAuthClient},
{ httpURI + "/proxy", PROXY_UNAUTHORIZED, true, noAuthClient},
{ httpsURI + "/proxy", PROXY_UNAUTHORIZED, true, noAuthClient},
{ http2URI + "/proxy", PROXY_UNAUTHORIZED, true, noAuthClient},
{ https2URI + "/proxy", PROXY_UNAUTHORIZED, true, noAuthClient},
{ httpURI + "/server", UNAUTHORIZED, false, noAuthClient},
{ httpsURI + "/server", UNAUTHORIZED, false, noAuthClient},
{ http2URI + "/server", UNAUTHORIZED, false, noAuthClient},
{ https2URI + "/server", UNAUTHORIZED, false, noAuthClient},
{ httpURI + "/proxy", PROXY_UNAUTHORIZED, false, noAuthClient},
{ httpsURI + "/proxy", PROXY_UNAUTHORIZED, false, noAuthClient},
{ http2URI + "/proxy", PROXY_UNAUTHORIZED, false, noAuthClient},
{ https2URI + "/proxy", PROXY_UNAUTHORIZED, false, noAuthClient},
{ httpURI + "/server", UNAUTHORIZED, true, ref(authClient)},
{ httpsURI + "/server", UNAUTHORIZED, true, ref(authClient)},
{ http2URI + "/server", UNAUTHORIZED, true, ref(authClient)},
{ https2URI + "/server", UNAUTHORIZED, true, ref(authClient)},
{ httpURI + "/proxy", PROXY_UNAUTHORIZED, true, ref(authClient)},
{ httpsURI + "/proxy", PROXY_UNAUTHORIZED, true, ref(authClient)},
{ http2URI + "/proxy", PROXY_UNAUTHORIZED, true, ref(authClient)},
{ https2URI + "/proxy", PROXY_UNAUTHORIZED, true, ref(authClient)},
{ httpURI + "/server", UNAUTHORIZED, false, ref(authClient)},
{ httpsURI + "/server", UNAUTHORIZED, false, ref(authClient)},
{ http2URI + "/server", UNAUTHORIZED, false, ref(authClient)},
{ https2URI + "/server", UNAUTHORIZED, false, ref(authClient)},
{ httpURI + "/proxy", PROXY_UNAUTHORIZED, false, ref(authClient)},
{ httpsURI + "/proxy", PROXY_UNAUTHORIZED, false, ref(authClient)},
{ http2URI + "/proxy", PROXY_UNAUTHORIZED, false, ref(authClient)},
{ https2URI + "/proxy", PROXY_UNAUTHORIZED, false, ref(authClient)},
{ httpURI + "/server", UNAUTHORIZED, true, ref(noAuthClient)},
{ httpsURI + "/server", UNAUTHORIZED, true, ref(noAuthClient)},
{ http2URI + "/server", UNAUTHORIZED, true, ref(noAuthClient)},
{ https2URI + "/server", UNAUTHORIZED, true, ref(noAuthClient)},
{ httpURI + "/proxy", PROXY_UNAUTHORIZED, true, ref(noAuthClient)},
{ httpsURI + "/proxy", PROXY_UNAUTHORIZED, true, ref(noAuthClient)},
{ http2URI + "/proxy", PROXY_UNAUTHORIZED, true, ref(noAuthClient)},
{ https2URI + "/proxy", PROXY_UNAUTHORIZED, true, ref(noAuthClient)},
{ httpURI + "/server", UNAUTHORIZED, false, ref(noAuthClient)},
{ httpsURI + "/server", UNAUTHORIZED, false, ref(noAuthClient)},
{ http2URI + "/server", UNAUTHORIZED, false, ref(noAuthClient)},
{ https2URI + "/server", UNAUTHORIZED, false, ref(noAuthClient)},
{ httpURI + "/proxy", PROXY_UNAUTHORIZED, false, ref(noAuthClient)},
{ httpsURI + "/proxy", PROXY_UNAUTHORIZED, false, ref(noAuthClient)},
{ http2URI + "/proxy", PROXY_UNAUTHORIZED, false, ref(noAuthClient)},
{ https2URI + "/proxy", PROXY_UNAUTHORIZED, false, ref(noAuthClient)},
};
}
@ -139,7 +138,8 @@ public class UnauthorizedTest implements HttpServerAdapters {
};
@Test(dataProvider = "all")
void test(String uriString, int code, boolean async, HttpClient client) throws Throwable {
void test(String uriString, int code, boolean async, WeakReference<HttpClient> clientRef) throws Throwable {
HttpClient client = clientRef.get();
out.printf("%n---- starting (%s, %d, %s, %s) ----%n",
uriString, code, async ? "async" : "sync",
client.authenticator().isPresent() ? "authClient" : "noAuthClient");
@ -223,10 +223,20 @@ public class UnauthorizedTest implements HttpServerAdapters {
@AfterTest
public void teardown() throws Exception {
// authClient.close();
// noAuthClient.close();
var TRACKER = ReferenceTracker.INSTANCE;
TRACKER.track(authClient);
TRACKER.track(noAuthClient);
authClient = noAuthClient = null;
System.gc();
var error = TRACKER.check(1000);
httpTestServer.stop();
httpsTestServer.stop();
http2TestServer.stop();
https2TestServer.stop();
if (error != null) throw error;
}
static class UnauthorizedHandler implements HttpTestHandler {