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