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
2323
2424/*
2525 * @test
26- * @bug 8303965
26+ * @bug 8303965 8354276
27+ * @summary This test verifies the behaviour of the HttpClient when presented
28+ * with a HEADERS frame followed by CONTINUATION frames, and when presented
29+ * with bad header fields.
2730 * @library /test/lib /test/jdk/java/net/httpclient/lib
2831 * @build jdk.httpclient.test.lib.http2.Http2TestServer jdk.test.lib.net.SimpleSSLContext
2932 * @run testng/othervm -Djdk.internal.httpclient.debug=true BadHeadersTest
4447import java .io .IOException ;
4548import java .io .InputStream ;
4649import java .io .OutputStream ;
50+ import java .net .ProtocolException ;
4751import java .net .URI ;
4852import java .net .http .HttpClient ;
4953import java .net .http .HttpHeaders ;
@@ -76,6 +80,8 @@ public class BadHeadersTest {
7680 of (entry (":status" , "200" ), entry ("hell o" , "value" )), // Space in the name
7781 of (entry (":status" , "200" ), entry ("hello" , "line1\r \n line2\r \n " )), // Multiline value
7882 of (entry (":status" , "200" ), entry ("hello" , "DE" + ((char ) 0x7F ) + "L" )), // Bad byte in value
83+ of (entry (":status" , "200" ), entry ("connection" , "close" )), // Prohibited connection-specific header
84+ of (entry (":status" , "200" ), entry (":scheme" , "https" )), // Request pseudo-header in response
7985 of (entry ("hello" , "world!" ), entry (":status" , "200" )) // Pseudo header is not the first one
8086 );
8187
@@ -86,7 +92,7 @@ public class BadHeadersTest {
8692 String https2URI ;
8793
8894 /**
89- * A function that returns a list of 1) a HEADERS frame ( with an empty
95+ * A function that returns a list of 1) one HEADERS frame ( with an empty
9096 * payload ), and 2) a CONTINUATION frame with the actual headers.
9197 */
9298 static BiFunction <Integer ,List <ByteBuffer >,List <Http2Frame >> oneContinuation =
@@ -100,7 +106,7 @@ public class BadHeadersTest {
100106 };
101107
102108 /**
103- * A function that returns a list of a HEADERS frame followed by a number of
109+ * A function that returns a list of one HEADERS frame followed by a number of
104110 * CONTINUATION frames. Each frame contains just a single byte of payload.
105111 */
106112 static BiFunction <Integer ,List <ByteBuffer >,List <Http2Frame >> byteAtATime =
@@ -189,12 +195,13 @@ void testAsync(String uri,
189195 try {
190196 HttpResponse <String > response = cc .sendAsync (request , BodyHandlers .ofString ()).get ();
191197 fail ("Expected exception, got :" + response + ", " + response .body ());
192- } catch (Throwable t0 ) {
198+ } catch (Exception t0 ) {
193199 System .out .println ("Got EXPECTED: " + t0 );
194200 if (t0 instanceof ExecutionException ) {
195- t0 = t0 .getCause ();
201+ t = t0 .getCause ();
202+ } else {
203+ t = t0 ;
196204 }
197- t = t0 ;
198205 }
199206 assertDetailMessage (t , i );
200207 }
@@ -204,15 +211,21 @@ void testAsync(String uri,
204211 // sync with implementation.
205212 static void assertDetailMessage (Throwable throwable , int iterationIndex ) {
206213 try {
207- assertTrue (throwable instanceof IOException ,
208- "Expected IOException , got, " + throwable );
214+ assertTrue (throwable instanceof ProtocolException ,
215+ "Expected ProtocolException , got " + throwable );
209216 assertTrue (throwable .getMessage ().contains ("malformed response" ),
210217 "Expected \" malformed response\" in: " + throwable .getMessage ());
211218
212219 if (iterationIndex == 0 ) { // unknown
213220 assertTrue (throwable .getMessage ().contains ("Unknown pseudo-header" ),
214221 "Expected \" Unknown pseudo-header\" in: " + throwable .getMessage ());
215- } else if (iterationIndex == 4 ) { // unexpected
222+ } else if (iterationIndex == 4 ) { // prohibited
223+ assertTrue (throwable .getMessage ().contains ("Prohibited header name" ),
224+ "Expected \" Prohibited header name\" in: " + throwable .getMessage ());
225+ } else if (iterationIndex == 5 ) { // unexpected type
226+ assertTrue (throwable .getMessage ().contains ("not valid in context" ),
227+ "Expected \" not valid in context\" in: " + throwable .getMessage ());
228+ } else if (iterationIndex == 6 ) { // unexpected sequence
216229 assertTrue (throwable .getMessage ().contains (" Unexpected pseudo-header" ),
217230 "Expected \" Unexpected pseudo-header\" in: " + throwable .getMessage ());
218231 } else {
0 commit comments