9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 24 /* 25 * @test 26 * @library /lib/testlibrary server 27 * @build jdk.testlibrary.SimpleSSLContext 28 * @modules java.base/sun.net.www.http 29 * jdk.incubator.httpclient/jdk.incubator.http.internal.common 30 * jdk.incubator.httpclient/jdk.incubator.http.internal.frame 31 * jdk.incubator.httpclient/jdk.incubator.http.internal.hpack 32 * @run testng/othervm -Djdk.internal.httpclient.debug=true -Djdk.httpclient.HttpClient.log=errors,requests,responses,trace ImplicitPushCancel 33 */ 34 35 import java.io.ByteArrayInputStream; 36 import java.io.IOException; 37 import java.io.InputStream; 38 import java.io.OutputStream; 39 import java.net.URI; 40 import java.util.Map; 41 import java.util.Objects; 42 import java.util.Optional; 43 import jdk.incubator.http.HttpClient; 44 import jdk.incubator.http.HttpRequest; 45 import jdk.incubator.http.HttpResponse; 46 import jdk.incubator.http.HttpResponse.BodyHandler; 47 import jdk.incubator.http.MultiMapResult; 48 import jdk.incubator.http.internal.common.HttpHeadersImpl; 49 import org.testng.annotations.AfterTest; 50 import org.testng.annotations.BeforeTest; 51 import org.testng.annotations.Test; 52 import static java.nio.charset.StandardCharsets.UTF_8; 53 import static org.testng.Assert.assertEquals; 54 55 public class ImplicitPushCancel { 56 57 static Map<String,String> PUSH_PROMISES = Map.of( 58 "/x/y/z/1", "the first push promise body", 59 "/x/y/z/2", "the second push promise body", 60 "/x/y/z/3", "the third push promise body", 61 "/x/y/z/4", "the fourth push promise body", 62 "/x/y/z/5", "the fifth push promise body", 63 "/x/y/z/6", "the sixth push promise body", 64 "/x/y/z/7", "the seventh push promise body", 65 "/x/y/z/8", "the eight push promise body", 66 "/x/y/z/9", "the ninth push promise body" 67 ); 68 static final String MAIN_RESPONSE_BODY = "the main response body"; 90 static final <T> HttpResponse<T> assert200ResponseCode(HttpResponse<T> response) { 91 assertEquals(response.statusCode(), 200); 92 return response; 93 } 94 95 /* 96 * With a handler not capable of accepting push promises, then all push 97 * promises should be rejected / cancelled, without interfering with the 98 * main response. 99 */ 100 @Test 101 public void test() throws Exception { 102 HttpClient client = HttpClient.newHttpClient(); 103 104 client.sendAsync(HttpRequest.newBuilder(uri).build(), BodyHandler.asString()) 105 .thenApply(ImplicitPushCancel::assert200ResponseCode) 106 .thenApply(HttpResponse::body) 107 .thenAccept(body -> body.equals(MAIN_RESPONSE_BODY)) 108 .join(); 109 110 MultiMapResult<String> map = client.sendAsync( 111 HttpRequest.newBuilder(uri).build(), 112 HttpResponse.MultiSubscriber.asMap( 113 (req) -> Optional.of(HttpResponse.BodyHandler.asString())) 114 ).join(); 115 116 map.entrySet().stream().forEach(e -> System.out.println(e.getKey() + ":" + e.getValue().join().body())); 117 118 map.entrySet().stream().forEach(entry -> { 119 HttpRequest request = entry.getKey(); 120 HttpResponse<String> response = entry.getValue().join(); 121 assertEquals(response.statusCode(), 200); 122 if (PUSH_PROMISES.containsKey(request.uri().getPath())) { 123 assertEquals(response.body(), PUSH_PROMISES.get(request.uri().getPath())); 124 } else { 125 assertEquals(response.body(), MAIN_RESPONSE_BODY); 126 } 127 128 } ); 129 } 130 131 // --- server push handler --- 132 static class ServerPushHandler implements Http2Handler { 133 134 private final String mainResponseBody; 135 private final Map<String,String> promises; 136 137 public ServerPushHandler(String mainResponseBody, 138 Map<String,String> promises) | 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 24 /* 25 * @test 26 * @library /lib/testlibrary server 27 * @build jdk.testlibrary.SimpleSSLContext 28 * @modules java.base/sun.net.www.http 29 * java.net.http/jdk.internal.net.http.common 30 * java.net.http/jdk.internal.net.http.frame 31 * java.net.http/jdk.internal.net.http.hpack 32 * @run testng/othervm 33 * -Djdk.internal.httpclient.debug=true 34 * -Djdk.httpclient.HttpClient.log=errors,requests,responses,trace 35 * ImplicitPushCancel 36 */ 37 38 import java.io.ByteArrayInputStream; 39 import java.io.IOException; 40 import java.io.InputStream; 41 import java.io.OutputStream; 42 import java.net.URI; 43 import java.util.Map; 44 import java.util.Objects; 45 import java.util.concurrent.CompletableFuture; 46 import java.util.concurrent.ConcurrentHashMap; 47 import java.util.concurrent.ConcurrentMap; 48 49 import java.net.http.HttpClient; 50 import java.net.http.HttpRequest; 51 import java.net.http.HttpResponse; 52 import java.net.http.HttpResponse.BodyHandler; 53 import java.net.http.HttpResponse.PushPromiseHandler; 54 import jdk.internal.net.http.common.HttpHeadersImpl; 55 import org.testng.annotations.AfterTest; 56 import org.testng.annotations.BeforeTest; 57 import org.testng.annotations.Test; 58 import static java.nio.charset.StandardCharsets.UTF_8; 59 import static org.testng.Assert.assertEquals; 60 61 public class ImplicitPushCancel { 62 63 static Map<String,String> PUSH_PROMISES = Map.of( 64 "/x/y/z/1", "the first push promise body", 65 "/x/y/z/2", "the second push promise body", 66 "/x/y/z/3", "the third push promise body", 67 "/x/y/z/4", "the fourth push promise body", 68 "/x/y/z/5", "the fifth push promise body", 69 "/x/y/z/6", "the sixth push promise body", 70 "/x/y/z/7", "the seventh push promise body", 71 "/x/y/z/8", "the eight push promise body", 72 "/x/y/z/9", "the ninth push promise body" 73 ); 74 static final String MAIN_RESPONSE_BODY = "the main response body"; 96 static final <T> HttpResponse<T> assert200ResponseCode(HttpResponse<T> response) { 97 assertEquals(response.statusCode(), 200); 98 return response; 99 } 100 101 /* 102 * With a handler not capable of accepting push promises, then all push 103 * promises should be rejected / cancelled, without interfering with the 104 * main response. 105 */ 106 @Test 107 public void test() throws Exception { 108 HttpClient client = HttpClient.newHttpClient(); 109 110 client.sendAsync(HttpRequest.newBuilder(uri).build(), BodyHandler.asString()) 111 .thenApply(ImplicitPushCancel::assert200ResponseCode) 112 .thenApply(HttpResponse::body) 113 .thenAccept(body -> body.equals(MAIN_RESPONSE_BODY)) 114 .join(); 115 116 ConcurrentMap<HttpRequest, CompletableFuture<HttpResponse<String>>> promises 117 = new ConcurrentHashMap<>(); 118 PushPromiseHandler<String> pph = PushPromiseHandler 119 .of((r) -> BodyHandler.asString(), promises); 120 HttpResponse<String> main = client.sendAsync( 121 HttpRequest.newBuilder(uri).build(), 122 BodyHandler.asString(), 123 pph) 124 .join(); 125 126 promises.entrySet().stream().forEach(e -> System.out.println(e.getKey() + ":" + e.getValue().join().body())); 127 128 promises.putIfAbsent(main.request(), CompletableFuture.completedFuture(main)); 129 promises.entrySet().stream().forEach(entry -> { 130 HttpRequest request = entry.getKey(); 131 HttpResponse<String> response = entry.getValue().join(); 132 assertEquals(response.statusCode(), 200); 133 if (PUSH_PROMISES.containsKey(request.uri().getPath())) { 134 assertEquals(response.body(), PUSH_PROMISES.get(request.uri().getPath())); 135 } else { 136 assertEquals(response.body(), MAIN_RESPONSE_BODY); 137 } 138 139 } ); 140 } 141 142 // --- server push handler --- 143 static class ServerPushHandler implements Http2Handler { 144 145 private final String mainResponseBody; 146 private final Map<String,String> promises; 147 148 public ServerPushHandler(String mainResponseBody, 149 Map<String,String> promises) |