28
28
* @summary Tests that when the httpclient sends a 100 Expect Continue header and receives
29
29
* a response code of 417 Expectation Failed, that the client does not hang
30
30
* indefinitely and closes the connection.
31
- * @bug 8286171
31
+ * @bug 8286171 8307648
32
32
* @library /test/lib /test/jdk/java/net/httpclient/lib
33
33
* @build jdk.httpclient.test.lib.common.HttpServerAdapters
34
34
* @run testng/othervm -Djdk.internal.httpclient.debug=err ExpectContinueTest
56
56
import java .net .Socket ;
57
57
import java .net .URI ;
58
58
import java .net .http .HttpClient ;
59
+ import java .net .http .HttpClient .Builder ;
59
60
import java .net .http .HttpRequest ;
60
61
import java .net .http .HttpResponse ;
61
62
import java .util .StringTokenizer ;
@@ -106,6 +107,10 @@ public void setup() throws Exception {
106
107
h2postUri = URI .create ("http://" + http2TestServer .serverAuthority () + "/http2/post" );
107
108
h2hangUri = URI .create ("http://" + http2TestServer .serverAuthority () + "/http2/hang" );
108
109
110
+ System .out .println ("HTTP/1.1 server listening at: " + http1TestServer .serverAuthority ());
111
+ System .out .println ("HTTP/1.1 hang server listening at: " + hangUri .getRawAuthority ());
112
+ System .out .println ("HTTP/2 clear server listening at: " + http2TestServer .serverAuthority ());
113
+
109
114
http1TestServer .start ();
110
115
http1HangServer .start ();
111
116
http2TestServer .start ();
@@ -124,8 +129,10 @@ static class GetHandler implements HttpTestHandler {
124
129
public void handle (HttpTestExchange exchange ) throws IOException {
125
130
try (InputStream is = exchange .getRequestBody ();
126
131
OutputStream os = exchange .getResponseBody ()) {
132
+ System .err .println ("Server reading body" );
127
133
is .readAllBytes ();
128
134
byte [] bytes = "RESPONSE_BODY" .getBytes (UTF_8 );
135
+ System .err .println ("Server sending 200 (length=" +bytes .length +")" );
129
136
exchange .sendResponseHeaders (200 , bytes .length );
130
137
os .write (bytes );
131
138
}
@@ -139,13 +146,16 @@ public void handle(HttpTestExchange exchange) throws IOException {
139
146
// Http1 server has already sent 100 response at this point but not Http2 server
140
147
if (exchange .getExchangeVersion ().equals (HttpClient .Version .HTTP_2 )) {
141
148
// Send 100 Headers, tell client that we're ready for body
149
+ System .err .println ("Server sending 100 (length = 0)" );
142
150
exchange .sendResponseHeaders (100 , 0 );
143
151
}
144
152
145
153
// Read body from client and acknowledge with 200
146
154
try (InputStream is = exchange .getRequestBody ();
147
155
OutputStream os = exchange .getResponseBody ()) {
156
+ System .err .println ("Server reading body" );
148
157
is .readAllBytes ();
158
+ System .err .println ("Server send 200 (length=0)" );
149
159
exchange .sendResponseHeaders (200 , 0 );
150
160
}
151
161
}
@@ -159,6 +169,7 @@ public void handle(HttpTestExchange exchange) throws IOException {
159
169
try (InputStream is = exchange .getRequestBody ();
160
170
OutputStream os = exchange .getResponseBody ()) {
161
171
byte [] bytes = EXPECTATION_FAILED_417 .getBytes ();
172
+ System .err .println ("Server send 417 (length=" +bytes .length +")" );
162
173
exchange .sendResponseHeaders (417 , bytes .length );
163
174
os .write (bytes );
164
175
}
@@ -184,11 +195,14 @@ static class Http1HangServer extends Thread implements Closeable {
184
195
public void run () {
185
196
byte [] bytes = EXPECTATION_FAILED_417 .getBytes ();
186
197
198
+ boolean closed = this .closed ;
187
199
while (!closed ) {
188
200
try {
189
201
// Not using try with resources here as we expect the client to close resources when
190
202
// 417 is received
191
- client = ss .accept ();
203
+ System .err .println ("Http1HangServer accepting connections" );
204
+ var client = this .client = ss .accept ();
205
+ System .err .println ("Http1HangServer accepted connection: " + client );
192
206
InputStream is = client .getInputStream ();
193
207
OutputStream os = client .getOutputStream ();
194
208
@@ -213,7 +227,8 @@ public void run() {
213
227
&& version .equals ("HTTP/1.1" );
214
228
// If correct request, send 417 reply. Otherwise, wait for correct one
215
229
if (validRequest ) {
216
- closed = true ;
230
+ System .err .println ("Http1HangServer sending 417" );
231
+ closed = this .closed = true ;
217
232
response .append ("HTTP/1.1 417 Expectation Failed\r \n " )
218
233
.append ("Content-Length: " )
219
234
.append (0 )
@@ -224,17 +239,25 @@ public void run() {
224
239
os .write (bytes );
225
240
os .flush ();
226
241
} else {
242
+ System .err .println ("Http1HangServer received invalid request: closing" );
227
243
client .close ();
228
244
}
229
245
} catch (IOException e ) {
230
- closed = true ;
246
+ closed = this . closed = true ;
231
247
e .printStackTrace ();
248
+ } finally {
249
+ if (closed = this .closed ) {
250
+ System .err .println ("Http1HangServer: finished" );
251
+ } else {
252
+ System .err .println ("Http1HangServer: looping for accepting next connection" );
253
+ }
232
254
}
233
255
}
234
256
}
235
257
236
258
@ Override
237
259
public void close () throws IOException {
260
+ var client = this .client ;
238
261
if (client != null ) client .close ();
239
262
if (ss != null ) ss .close ();
240
263
}
@@ -244,13 +267,15 @@ public void close() throws IOException {
244
267
public Object [][] urisData () {
245
268
return new Object [][]{
246
269
{ getUri , postUri , hangUri , HTTP_1_1 },
247
- { h2getUri , h2postUri , h2hangUri , HttpClient . Version . HTTP_2 }
270
+ { h2getUri , h2postUri , h2hangUri , HTTP_2 }
248
271
};
249
272
}
250
273
251
274
@ Test (dataProvider = "uris" )
252
275
public void test (URI getUri , URI postUri , URI hangUri , HttpClient .Version version ) throws IOException , InterruptedException {
276
+ System .out .println ("Testing with version: " + version );
253
277
HttpClient client = HttpClient .newBuilder ()
278
+ .proxy (Builder .NO_PROXY )
254
279
.version (version )
255
280
.build ();
256
281
@@ -268,18 +293,24 @@ public void test(URI getUri, URI postUri, URI hangUri, HttpClient.Version versio
268
293
.expectContinue (true )
269
294
.build ();
270
295
296
+ System .out .printf ("Sending request (%s): %s%n" , version , getRequest );
297
+ System .err .println ("Sending request: " + getRequest );
271
298
CompletableFuture <HttpResponse <String >> cf = client .sendAsync (getRequest , HttpResponse .BodyHandlers .ofString ());
272
299
HttpResponse <String > resp = cf .join ();
273
300
System .err .println ("Response Headers: " + resp .headers ());
274
301
System .err .println ("Response Status Code: " + resp .statusCode ());
275
302
assertEquals (resp .statusCode (), 200 );
276
303
304
+ System .out .printf ("Sending request (%s): %s%n" , version , postRequest );
305
+ System .err .println ("Sending request: " + postRequest );
277
306
cf = client .sendAsync (postRequest , HttpResponse .BodyHandlers .ofString ());
278
307
resp = cf .join ();
279
308
System .err .println ("Response Headers: " + resp .headers ());
280
309
System .err .println ("Response Status Code: " + resp .statusCode ());
281
310
assertEquals (resp .statusCode (), 200 );
282
311
312
+ System .out .printf ("Sending request (%s): %s%n" , version , hangRequest );
313
+ System .err .println ("Sending request: " + hangRequest );
283
314
cf = client .sendAsync (hangRequest , HttpResponse .BodyHandlers .ofString ());
284
315
resp = cf .join ();
285
316
System .err .println ("Response Headers: " + resp .headers ());
0 commit comments