Path: blob/master/test/jdk/java/net/httpclient/CustomResponseSubscriber.java
41152 views
/*1* Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*/2223/*24* @test25* @summary Tests response body subscribers's onComplete is not invoked before onSubscribe26* @library /test/lib http2/server27* @build jdk.test.lib.net.SimpleSSLContext28* @modules java.base/sun.net.www.http29* java.net.http/jdk.internal.net.http.common30* java.net.http/jdk.internal.net.http.frame31* java.net.http/jdk.internal.net.http.hpack32* @run testng/othervm CustomResponseSubscriber33*/3435import java.io.IOException;36import java.io.InputStream;37import java.net.InetAddress;38import java.net.InetSocketAddress;39import java.net.URI;40import java.nio.ByteBuffer;41import java.util.List;42import java.util.concurrent.CompletionStage;43import java.util.concurrent.Executor;44import java.util.concurrent.Executors;45import java.util.concurrent.Flow;46import com.sun.net.httpserver.HttpExchange;47import com.sun.net.httpserver.HttpHandler;48import com.sun.net.httpserver.HttpServer;49import com.sun.net.httpserver.HttpsConfigurator;50import com.sun.net.httpserver.HttpsServer;51import java.net.http.HttpClient;52import java.net.http.HttpHeaders;53import java.net.http.HttpRequest;54import java.net.http.HttpResponse;55import java.net.http.HttpResponse.BodyHandler;56import java.net.http.HttpResponse.BodySubscriber;57import java.net.http.HttpResponse.BodySubscribers;58import javax.net.ssl.SSLContext;59import jdk.test.lib.net.SimpleSSLContext;60import org.testng.annotations.AfterTest;61import org.testng.annotations.BeforeTest;62import org.testng.annotations.DataProvider;63import org.testng.annotations.Test;64import static java.lang.System.out;65import static java.nio.charset.StandardCharsets.UTF_8;66import static org.testng.Assert.assertEquals;67import static org.testng.Assert.assertTrue;6869public class CustomResponseSubscriber {7071SSLContext sslContext;72HttpServer httpTestServer; // HTTP/1.1 [ 4 servers ]73HttpsServer httpsTestServer; // HTTPS/1.174Http2TestServer http2TestServer; // HTTP/2 ( h2c )75Http2TestServer https2TestServer; // HTTP/2 ( h2 )76String httpURI_fixed;77String httpURI_chunk;78String httpsURI_fixed;79String httpsURI_chunk;80String http2URI_fixed;81String http2URI_chunk;82String https2URI_fixed;83String https2URI_chunk;8485static final int ITERATION_COUNT = 10;86// a shared executor helps reduce the amount of threads created by the test87static final Executor executor = Executors.newCachedThreadPool();8889@DataProvider(name = "variants")90public Object[][] variants() {91return new Object[][]{92{ httpURI_fixed, false },93{ httpURI_chunk, false },94{ httpsURI_fixed, false },95{ httpsURI_chunk, false },96{ http2URI_fixed, false },97{ http2URI_chunk, false },98{ https2URI_fixed, false,},99{ https2URI_chunk, false },100101{ httpURI_fixed, true },102{ httpURI_chunk, true },103{ httpsURI_fixed, true },104{ httpsURI_chunk, true },105{ http2URI_fixed, true },106{ http2URI_chunk, true },107{ https2URI_fixed, true,},108{ https2URI_chunk, true },109};110}111112HttpClient newHttpClient() {113return HttpClient.newBuilder()114.executor(executor)115.sslContext(sslContext)116.build();117}118119@Test(dataProvider = "variants")120public void testAsString(String uri, boolean sameClient) throws Exception {121HttpClient client = null;122for (int i=0; i< ITERATION_COUNT; i++) {123if (!sameClient || client == null)124client = newHttpClient();125126HttpRequest req = HttpRequest.newBuilder(URI.create(uri))127.build();128BodyHandler<String> handler = new CRSBodyHandler();129HttpResponse<String> response = client.send(req, handler);130String body = response.body();131assertEquals(body, "");132}133}134135static class CRSBodyHandler implements BodyHandler<String> {136@Override137public BodySubscriber<String> apply(HttpResponse.ResponseInfo rinfo) {138assertEquals(rinfo.statusCode(), 200);139return new CRSBodySubscriber();140}141}142143static class CRSBodySubscriber implements BodySubscriber<String> {144private final BodySubscriber<String> ofString = BodySubscribers.ofString(UTF_8);145volatile boolean onSubscribeCalled;146147@Override148public void onSubscribe(Flow.Subscription subscription) {149//out.println("onSubscribe ");150onSubscribeCalled = true;151ofString.onSubscribe(subscription);152}153154@Override155public void onNext(List<ByteBuffer> item) {156// out.println("onNext " + item);157assertTrue(onSubscribeCalled);158ofString.onNext(item);159}160161@Override162public void onError(Throwable throwable) {163//out.println("onError");164assertTrue(onSubscribeCalled);165ofString.onError(throwable);166}167168@Override169public void onComplete() {170//out.println("onComplete");171assertTrue(onSubscribeCalled, "onComplete called before onSubscribe");172ofString.onComplete();173}174175@Override176public CompletionStage<String> getBody() {177return ofString.getBody();178}179}180181static String serverAuthority(HttpServer server) {182return InetAddress.getLoopbackAddress().getHostName() + ":"183+ server.getAddress().getPort();184}185186@BeforeTest187public void setup() throws Exception {188sslContext = new SimpleSSLContext().get();189if (sslContext == null)190throw new AssertionError("Unexpected null sslContext");191192// HTTP/1.1193HttpHandler h1_fixedLengthHandler = new HTTP1_FixedLengthHandler();194HttpHandler h1_chunkHandler = new HTTP1_ChunkedHandler();195InetSocketAddress sa = new InetSocketAddress(InetAddress.getLoopbackAddress(), 0);196httpTestServer = HttpServer.create(sa, 0);197httpTestServer.createContext("/http1/fixed", h1_fixedLengthHandler);198httpTestServer.createContext("/http1/chunk", h1_chunkHandler);199httpURI_fixed = "http://" + serverAuthority(httpTestServer) + "/http1/fixed";200httpURI_chunk = "http://" + serverAuthority(httpTestServer) + "/http1/chunk";201202httpsTestServer = HttpsServer.create(sa, 0);203httpsTestServer.setHttpsConfigurator(new HttpsConfigurator(sslContext));204httpsTestServer.createContext("/https1/fixed", h1_fixedLengthHandler);205httpsTestServer.createContext("/https1/chunk", h1_chunkHandler);206httpsURI_fixed = "https://" + serverAuthority(httpsTestServer) + "/https1/fixed";207httpsURI_chunk = "https://" + serverAuthority(httpsTestServer) + "/https1/chunk";208209// HTTP/2210Http2Handler h2_fixedLengthHandler = new HTTP2_FixedLengthHandler();211Http2Handler h2_chunkedHandler = new HTTP2_VariableHandler();212213http2TestServer = new Http2TestServer("localhost", false, 0);214http2TestServer.addHandler(h2_fixedLengthHandler, "/http2/fixed");215http2TestServer.addHandler(h2_chunkedHandler, "/http2/chunk");216http2URI_fixed = "http://" + http2TestServer.serverAuthority() + "/http2/fixed";217http2URI_chunk = "http://" + http2TestServer.serverAuthority() + "/http2/chunk";218219https2TestServer = new Http2TestServer("localhost", true, sslContext);220https2TestServer.addHandler(h2_fixedLengthHandler, "/https2/fixed");221https2TestServer.addHandler(h2_chunkedHandler, "/https2/chunk");222https2URI_fixed = "https://" + https2TestServer.serverAuthority() + "/https2/fixed";223https2URI_chunk = "https://" + https2TestServer.serverAuthority() + "/https2/chunk";224225httpTestServer.start();226httpsTestServer.start();227http2TestServer.start();228https2TestServer.start();229}230231@AfterTest232public void teardown() throws Exception {233httpTestServer.stop(0);234httpsTestServer.stop(0);235http2TestServer.stop();236https2TestServer.stop();237}238239static class HTTP1_FixedLengthHandler implements HttpHandler {240@Override241public void handle(HttpExchange t) throws IOException {242out.println("HTTP1_FixedLengthHandler received request to " + t.getRequestURI());243try (InputStream is = t.getRequestBody()) {244is.readAllBytes();245}246t.sendResponseHeaders(200, -1); //no body247}248}249250static class HTTP1_ChunkedHandler implements HttpHandler {251@Override252public void handle(HttpExchange t) throws IOException {253out.println("HTTP1_ChunkedHandler received request to " + t.getRequestURI());254try (InputStream is = t.getRequestBody()) {255is.readAllBytes();256}257t.sendResponseHeaders(200, 0); // chunked258t.getResponseBody().close(); // no body259}260}261262static class HTTP2_FixedLengthHandler implements Http2Handler {263@Override264public void handle(Http2TestExchange t) throws IOException {265out.println("HTTP2_FixedLengthHandler received request to " + t.getRequestURI());266try (InputStream is = t.getRequestBody()) {267is.readAllBytes();268}269t.sendResponseHeaders(200, 0);270t.getResponseBody().close();271}272}273274static class HTTP2_VariableHandler implements Http2Handler {275@Override276public void handle(Http2TestExchange t) throws IOException {277out.println("HTTP2_VariableHandler received request to " + t.getRequestURI());278try (InputStream is = t.getRequestBody()) {279is.readAllBytes();280}281t.sendResponseHeaders(200, -1); // variable282t.getResponseBody().close(); //no body283}284}285}286287288