Skip to content

Commit eef6aef

Browse files
committed
8352623: MultiExchange should cancel exchange impl if responseFilters throws
Reviewed-by: djelinski
1 parent e2a461b commit eef6aef

File tree

2 files changed

+56
-43
lines changed

2 files changed

+56
-43
lines changed

src/java.net.http/share/classes/jdk/internal/net/http/MultiExchange.java

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2015, 2024, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -25,6 +25,7 @@
2525

2626
package jdk.internal.net.http;
2727

28+
import java.io.IOError;
2829
import java.io.IOException;
2930
import java.lang.ref.WeakReference;
3031
import java.net.ConnectException;
@@ -440,7 +441,9 @@ private CompletableFuture<Response> responseAsyncImpl() {
440441
try {
441442
// 3. apply response filters
442443
newrequest = responseFilters(response);
443-
} catch (IOException e) {
444+
} catch (Throwable t) {
445+
IOException e = t instanceof IOException io ? io : new IOException(t);
446+
exch.exchImpl.cancel(e);
444447
return failedFuture(e);
445448
}
446449
// 4. check filter result and repeat or continue

test/jdk/java/net/httpclient/UnauthorizedTest.java

Lines changed: 51 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -23,7 +23,7 @@
2323

2424
/*
2525
* @test
26-
* @bug 8203882
26+
* @bug 8203882 8352623
2727
* @summary (httpclient) Check that HttpClient throws IOException when
2828
* receiving 401/407 with no WWW-Authenticate/Proxy-Authenticate
2929
* header only in the case where an authenticator is configured
@@ -36,9 +36,6 @@
3636
* UnauthorizedTest
3737
*/
3838

39-
import com.sun.net.httpserver.HttpServer;
40-
import com.sun.net.httpserver.HttpsConfigurator;
41-
import com.sun.net.httpserver.HttpsServer;
4239
import jdk.test.lib.net.SimpleSSLContext;
4340
import org.testng.annotations.AfterTest;
4441
import org.testng.annotations.BeforeTest;
@@ -49,9 +46,8 @@
4946
import java.io.IOException;
5047
import java.io.InputStream;
5148
import java.io.OutputStream;
49+
import java.lang.ref.WeakReference;
5250
import java.net.Authenticator;
53-
import java.net.InetAddress;
54-
import java.net.InetSocketAddress;
5551
import java.net.URI;
5652
import java.net.http.HttpClient;
5753
import java.net.http.HttpRequest;
@@ -60,7 +56,6 @@
6056
import java.util.concurrent.ExecutionException;
6157
import java.util.concurrent.atomic.AtomicLong;
6258
import jdk.httpclient.test.lib.common.HttpServerAdapters;
63-
import jdk.httpclient.test.lib.http2.Http2TestServer;
6459

6560
import static java.lang.System.out;
6661
import static java.net.http.HttpClient.Version.HTTP_1_1;
@@ -95,41 +90,45 @@ public class UnauthorizedTest implements HttpServerAdapters {
9590
static final int HTTP_OK = 200;
9691
static final String MESSAGE = "Unauthorized";
9792

93+
static WeakReference<HttpClient> ref(HttpClient client) {
94+
return new WeakReference<>(client);
95+
}
96+
9897
@DataProvider(name = "all")
9998
public Object[][] positive() {
10099
return new Object[][] {
101-
{ httpURI + "/server", UNAUTHORIZED, true, authClient},
102-
{ httpsURI + "/server", UNAUTHORIZED, true, authClient},
103-
{ http2URI + "/server", UNAUTHORIZED, true, authClient},
104-
{ https2URI + "/server", UNAUTHORIZED, true, authClient},
105-
{ httpURI + "/proxy", PROXY_UNAUTHORIZED, true, authClient},
106-
{ httpsURI + "/proxy", PROXY_UNAUTHORIZED, true, authClient},
107-
{ http2URI + "/proxy", PROXY_UNAUTHORIZED, true, authClient},
108-
{ https2URI + "/proxy", PROXY_UNAUTHORIZED, true, authClient},
109-
{ httpURI + "/server", UNAUTHORIZED, false, authClient},
110-
{ httpsURI + "/server", UNAUTHORIZED, false, authClient},
111-
{ http2URI + "/server", UNAUTHORIZED, false, authClient},
112-
{ https2URI + "/server", UNAUTHORIZED, false, authClient},
113-
{ httpURI + "/proxy", PROXY_UNAUTHORIZED, false, authClient},
114-
{ httpsURI + "/proxy", PROXY_UNAUTHORIZED, false, authClient},
115-
{ http2URI + "/proxy", PROXY_UNAUTHORIZED, false, authClient},
116-
{ https2URI + "/proxy", PROXY_UNAUTHORIZED, false, authClient},
117-
{ httpURI + "/server", UNAUTHORIZED, true, noAuthClient},
118-
{ httpsURI + "/server", UNAUTHORIZED, true, noAuthClient},
119-
{ http2URI + "/server", UNAUTHORIZED, true, noAuthClient},
120-
{ https2URI + "/server", UNAUTHORIZED, true, noAuthClient},
121-
{ httpURI + "/proxy", PROXY_UNAUTHORIZED, true, noAuthClient},
122-
{ httpsURI + "/proxy", PROXY_UNAUTHORIZED, true, noAuthClient},
123-
{ http2URI + "/proxy", PROXY_UNAUTHORIZED, true, noAuthClient},
124-
{ https2URI + "/proxy", PROXY_UNAUTHORIZED, true, noAuthClient},
125-
{ httpURI + "/server", UNAUTHORIZED, false, noAuthClient},
126-
{ httpsURI + "/server", UNAUTHORIZED, false, noAuthClient},
127-
{ http2URI + "/server", UNAUTHORIZED, false, noAuthClient},
128-
{ https2URI + "/server", UNAUTHORIZED, false, noAuthClient},
129-
{ httpURI + "/proxy", PROXY_UNAUTHORIZED, false, noAuthClient},
130-
{ httpsURI + "/proxy", PROXY_UNAUTHORIZED, false, noAuthClient},
131-
{ http2URI + "/proxy", PROXY_UNAUTHORIZED, false, noAuthClient},
132-
{ https2URI + "/proxy", PROXY_UNAUTHORIZED, false, noAuthClient},
100+
{ httpURI + "/server", UNAUTHORIZED, true, ref(authClient)},
101+
{ httpsURI + "/server", UNAUTHORIZED, true, ref(authClient)},
102+
{ http2URI + "/server", UNAUTHORIZED, true, ref(authClient)},
103+
{ https2URI + "/server", UNAUTHORIZED, true, ref(authClient)},
104+
{ httpURI + "/proxy", PROXY_UNAUTHORIZED, true, ref(authClient)},
105+
{ httpsURI + "/proxy", PROXY_UNAUTHORIZED, true, ref(authClient)},
106+
{ http2URI + "/proxy", PROXY_UNAUTHORIZED, true, ref(authClient)},
107+
{ https2URI + "/proxy", PROXY_UNAUTHORIZED, true, ref(authClient)},
108+
{ httpURI + "/server", UNAUTHORIZED, false, ref(authClient)},
109+
{ httpsURI + "/server", UNAUTHORIZED, false, ref(authClient)},
110+
{ http2URI + "/server", UNAUTHORIZED, false, ref(authClient)},
111+
{ https2URI + "/server", UNAUTHORIZED, false, ref(authClient)},
112+
{ httpURI + "/proxy", PROXY_UNAUTHORIZED, false, ref(authClient)},
113+
{ httpsURI + "/proxy", PROXY_UNAUTHORIZED, false, ref(authClient)},
114+
{ http2URI + "/proxy", PROXY_UNAUTHORIZED, false, ref(authClient)},
115+
{ https2URI + "/proxy", PROXY_UNAUTHORIZED, false, ref(authClient)},
116+
{ httpURI + "/server", UNAUTHORIZED, true, ref(noAuthClient)},
117+
{ httpsURI + "/server", UNAUTHORIZED, true, ref(noAuthClient)},
118+
{ http2URI + "/server", UNAUTHORIZED, true, ref(noAuthClient)},
119+
{ https2URI + "/server", UNAUTHORIZED, true, ref(noAuthClient)},
120+
{ httpURI + "/proxy", PROXY_UNAUTHORIZED, true, ref(noAuthClient)},
121+
{ httpsURI + "/proxy", PROXY_UNAUTHORIZED, true, ref(noAuthClient)},
122+
{ http2URI + "/proxy", PROXY_UNAUTHORIZED, true, ref(noAuthClient)},
123+
{ https2URI + "/proxy", PROXY_UNAUTHORIZED, true, ref(noAuthClient)},
124+
{ httpURI + "/server", UNAUTHORIZED, false, ref(noAuthClient)},
125+
{ httpsURI + "/server", UNAUTHORIZED, false, ref(noAuthClient)},
126+
{ http2URI + "/server", UNAUTHORIZED, false, ref(noAuthClient)},
127+
{ https2URI + "/server", UNAUTHORIZED, false, ref(noAuthClient)},
128+
{ httpURI + "/proxy", PROXY_UNAUTHORIZED, false, ref(noAuthClient)},
129+
{ httpsURI + "/proxy", PROXY_UNAUTHORIZED, false, ref(noAuthClient)},
130+
{ http2URI + "/proxy", PROXY_UNAUTHORIZED, false, ref(noAuthClient)},
131+
{ https2URI + "/proxy", PROXY_UNAUTHORIZED, false, ref(noAuthClient)},
133132
};
134133
}
135134

@@ -139,7 +138,8 @@ public Object[][] positive() {
139138
};
140139

141140
@Test(dataProvider = "all")
142-
void test(String uriString, int code, boolean async, HttpClient client) throws Throwable {
141+
void test(String uriString, int code, boolean async, WeakReference<HttpClient> clientRef) throws Throwable {
142+
HttpClient client = clientRef.get();
143143
out.printf("%n---- starting (%s, %d, %s, %s) ----%n",
144144
uriString, code, async ? "async" : "sync",
145145
client.authenticator().isPresent() ? "authClient" : "noAuthClient");
@@ -223,10 +223,20 @@ public void setup() throws Exception {
223223

224224
@AfterTest
225225
public void teardown() throws Exception {
226+
// authClient.close();
227+
// noAuthClient.close();
228+
var TRACKER = ReferenceTracker.INSTANCE;
229+
TRACKER.track(authClient);
230+
TRACKER.track(noAuthClient);
231+
authClient = noAuthClient = null;
232+
System.gc();
233+
var error = TRACKER.check(1000);
234+
226235
httpTestServer.stop();
227236
httpsTestServer.stop();
228237
http2TestServer.stop();
229238
https2TestServer.stop();
239+
if (error != null) throw error;
230240
}
231241

232242
static class UnauthorizedHandler implements HttpTestHandler {

0 commit comments

Comments
 (0)