2323
2424/*
2525 * @test
26- * @bug 8342075
26+ * @bug 8342075 8343855
2727 * @library /test/lib /test/jdk/java/net/httpclient/lib
2828 * @build jdk.httpclient.test.lib.http2.Http2TestServer jdk.test.lib.net.SimpleSSLContext
2929 * jdk.httpclient.test.lib.common.TestServerConfigurator
5656import javax .net .ssl .SSLContext ;
5757import javax .net .ssl .SSLSession ;
5858
59+ import jdk .httpclient .test .lib .common .HttpServerAdapters .HttpHeadOrGetHandler ;
5960import jdk .httpclient .test .lib .common .HttpServerAdapters .HttpTestServer ;
6061import jdk .httpclient .test .lib .http2 .BodyOutputStream ;
6162import jdk .httpclient .test .lib .http2 .Http2Handler ;
7273import org .testng .annotations .DataProvider ;
7374import org .testng .annotations .Test ;
7475
76+ import static java .util .concurrent .TimeUnit .NANOSECONDS ;
7577import static org .testng .Assert .assertEquals ;
7678import static org .testng .Assert .fail ;
7779
@@ -95,6 +97,19 @@ public Object[][] variants() {
9597 };
9698 }
9799
100+ static void sleep (long wait ) throws InterruptedException {
101+ if (wait <= 0 ) return ;
102+ long remaining = Utils .adjustTimeout (wait );
103+ long start = System .nanoTime ();
104+ while (remaining > 0 ) {
105+ Thread .sleep (remaining );
106+ long end = System .nanoTime ();
107+ remaining = remaining - NANOSECONDS .toMillis (end - start );
108+ }
109+ System .out .printf ("Waited %s ms%n" ,
110+ NANOSECONDS .toMillis (System .nanoTime () - start ));
111+ }
112+
98113
99114 @ Test (dataProvider = "variants" )
100115 void test (String uri ,
@@ -121,7 +136,7 @@ void test(String uri,
121136 CompletableFuture <String > sent = new CompletableFuture <>();
122137 responseSent .put (query , sent );
123138 HttpRequest request = HttpRequest .newBuilder (uriWithQuery )
124- .POST ( BodyPublishers . ofString ( "Hello there!" ) )
139+ .GET ( )
125140 .build ();
126141 System .out .println ("\n Sending request:" + uriWithQuery );
127142 final HttpClient cc = client ;
@@ -136,9 +151,9 @@ void test(String uri,
136151 // we have to pull to get the exception, but slow enough
137152 // so that DataFrames are buffered up to the point that
138153 // the window is exceeded...
139- int wait = uri .startsWith ("https://" ) ? 500 : 350 ;
154+ long wait = uri .startsWith ("https://" ) ? 800 : 350 ;
140155 try (InputStream is = response .body ()) {
141- Thread . sleep (Utils . adjustTimeout ( wait ) );
156+ sleep (wait );
142157 is .readAllBytes ();
143158 }
144159 // we could fail here if we haven't waited long enough
@@ -187,7 +202,7 @@ void testAsync(String uri,
187202 CompletableFuture <String > sent = new CompletableFuture <>();
188203 responseSent .put (query , sent );
189204 HttpRequest request = HttpRequest .newBuilder (uriWithQuery )
190- .POST ( BodyPublishers . ofString ( "Hello there!" ) )
205+ .GET ( )
191206 .build ();
192207 System .out .println ("\n Sending request:" + uriWithQuery );
193208 final HttpClient cc = client ;
@@ -201,9 +216,9 @@ void testAsync(String uri,
201216 assertEquals (key , label , "Unexpected key for " + query );
202217 }
203218 sent .join ();
204- int wait = uri .startsWith ("https://" ) ? 600 : 300 ;
219+ long wait = uri .startsWith ("https://" ) ? 800 : 350 ;
205220 try (InputStream is = response .body ()) {
206- Thread . sleep (Utils . adjustTimeout ( wait ) );
221+ sleep (wait );
207222 is .readAllBytes ();
208223 }
209224 // we could fail here if we haven't waited long enough
@@ -269,7 +284,9 @@ public void setup() throws Exception {
269284 var https2TestServer = new Http2TestServer ("localhost" , true , sslContext );
270285 https2TestServer .addHandler (new Http2TestHandler (), "/https2/" );
271286 this .https2TestServer = HttpTestServer .of (https2TestServer );
287+ this .https2TestServer .addHandler (new HttpHeadOrGetHandler (), "/https2/head/" );
272288 https2URI = "https://" + this .https2TestServer .serverAuthority () + "/https2/x" ;
289+ String h2Head = "https://" + this .https2TestServer .serverAuthority () + "/https2/head/z" ;
273290
274291 // Override the default exchange supplier with a custom one to enable
275292 // particular test scenarios
@@ -278,6 +295,17 @@ public void setup() throws Exception {
278295
279296 this .http2TestServer .start ();
280297 this .https2TestServer .start ();
298+
299+ // warmup to eliminate delay due to SSL class loading and initialization.
300+ HttpClient client = HttpClient .newBuilder ().executor (Executors .newCachedThreadPool ()).sslContext (sslContext ).build ();
301+ try {
302+ var request = HttpRequest .newBuilder (URI .create (h2Head )).method ("HEAD" , BodyPublishers .noBody ()).build ();
303+ var resp = client .send (request , BodyHandlers .discarding ());
304+ assertEquals (resp .statusCode (), 200 );
305+ } finally {
306+ ExecutorService exec = (ExecutorService )client .executor ().get ();
307+ exec .shutdownNow ();
308+ }
281309 }
282310
283311 @ AfterTest
@@ -296,11 +324,19 @@ public void handle(Http2TestExchange t) throws IOException {
296324 OutputStream os = t .getResponseBody ()) {
297325
298326 byte [] bytes = is .readAllBytes ();
299- System .out .println ("Server " + t .getLocalAddress () + " received:\n "
300- + t .getRequestURI () + ": " + new String (bytes , StandardCharsets .UTF_8 ));
327+ if (bytes .length != 0 ) {
328+ System .out .println ("Server " + t .getLocalAddress () + " received:\n "
329+ + t .getRequestURI () + ": " + new String (bytes , StandardCharsets .UTF_8 ));
330+ } else {
331+ System .out .println ("No request body for " + t .getRequestMethod ());
332+ }
333+
301334 t .getResponseHeaders ().setHeader ("X-Connection-Key" , t .getConnectionKey ());
302335
303- if (bytes .length == 0 ) bytes = "no request body!" .getBytes (StandardCharsets .UTF_8 );
336+ if (bytes .length == 0 ) {
337+ bytes = "no request body!"
338+ .repeat (100 ).getBytes (StandardCharsets .UTF_8 );
339+ }
304340 int window = Integer .getInteger ("jdk.httpclient.windowsize" , 2 * 16 * 1024 );
305341 final int maxChunkSize ;
306342 if (t instanceof FCHttp2TestExchange fct ) {
@@ -324,13 +360,22 @@ public void handle(Http2TestExchange t) throws IOException {
324360 // ignore and continue...
325361 }
326362 }
327- ((BodyOutputStream ) os ).writeUncontrolled (resp , 0 , resp .length );
363+ try {
364+ ((BodyOutputStream ) os ).writeUncontrolled (resp , 0 , resp .length );
365+ } catch (IOException x ) {
366+ if (t instanceof FCHttp2TestExchange fct ) {
367+ fct .conn .updateConnectionWindow (resp .length );
368+ }
369+ }
370+ }
371+ } finally {
372+ if (t instanceof FCHttp2TestExchange fct ) {
373+ fct .responseSent (query );
374+ } else {
375+ fail ("Exchange is not %s but %s"
376+ .formatted (FCHttp2TestExchange .class .getName (), t .getClass ().getName ()));
328377 }
329378 }
330- if (t instanceof FCHttp2TestExchange fct ) {
331- fct .responseSent (query );
332- } else fail ("Exchange is not %s but %s"
333- .formatted (FCHttp2TestExchange .class .getName (), t .getClass ().getName ()));
334379 }
335380 }
336381
0 commit comments