1 /*
   2  * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   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  * @bug 8087112 8177935
  27  * @library /lib/testlibrary server
  28  * @build jdk.testlibrary.SimpleSSLContext
  29  * @modules java.base/sun.net.www.http
  30  *          jdk.incubator.httpclient/jdk.incubator.http.internal.common
  31  *          jdk.incubator.httpclient/jdk.incubator.http.internal.frame
  32  *          jdk.incubator.httpclient/jdk.incubator.http.internal.hpack
  33  * @run testng/othervm -Djdk.httpclient.HttpClient.log=ssl,requests,responses,errors FixedThreadPoolTest
  34  */
  35 
  36 import java.net.*;
  37 import jdk.incubator.http.*;
  38 import static jdk.incubator.http.HttpClient.Version.HTTP_2;
  39 import javax.net.ssl.*;
  40 import java.nio.file.*;
  41 import java.util.concurrent.*;
  42 import jdk.testlibrary.SimpleSSLContext;
  43 import static jdk.incubator.http.HttpRequest.BodyPublisher.fromFile;
  44 import static jdk.incubator.http.HttpRequest.BodyPublisher.fromString;
  45 import static jdk.incubator.http.HttpResponse.BodyHandler.asFile;
  46 import static jdk.incubator.http.HttpResponse.BodyHandler.asString;
  47 
  48 import org.testng.annotations.Test;
  49 
  50 @Test
  51 public class FixedThreadPoolTest {
  52     static int httpPort, httpsPort;
  53     static Http2TestServer httpServer, httpsServer;
  54     static HttpClient client = null;
  55     static ExecutorService exec;
  56     static SSLContext sslContext;
  57 
  58     static String httpURIString, httpsURIString;
  59 
  60     static void initialize() throws Exception {
  61         try {
  62             SimpleSSLContext sslct = new SimpleSSLContext();
  63             sslContext = sslct.get();
  64             client = getClient();
  65             httpServer = new Http2TestServer(false, 0, exec, sslContext);
  66             httpServer.addHandler(new Http2EchoHandler(), "/");
  67             httpPort = httpServer.getAddress().getPort();
  68 
  69             httpsServer = new Http2TestServer(true, 0, exec, sslContext);
  70             httpsServer.addHandler(new Http2EchoHandler(), "/");
  71 
  72             httpsPort = httpsServer.getAddress().getPort();
  73             httpURIString = "http://127.0.0.1:" + httpPort + "/foo/";
  74             httpsURIString = "https://127.0.0.1:" + httpsPort + "/bar/";
  75 
  76             httpServer.start();
  77             httpsServer.start();
  78         } catch (Throwable e) {
  79             System.err.println("Throwing now");
  80             e.printStackTrace();
  81             throw e;
  82         }
  83     }
  84 
  85     @Test
  86     public static void test() throws Exception {
  87         try {
  88             initialize();
  89             simpleTest(false);
  90             simpleTest(true);
  91             streamTest(false);
  92             streamTest(true);
  93             paramsTest();
  94             Thread.sleep(1000 * 4);
  95         } catch (Exception | Error tt) {
  96             tt.printStackTrace();
  97             throw tt;
  98         } finally {
  99             httpServer.stop();
 100             httpsServer.stop();
 101             exec.shutdownNow();
 102         }
 103     }
 104 
 105     static HttpClient getClient() {
 106         if (client == null) {
 107             exec = Executors.newCachedThreadPool();
 108             // Executor e1 = Executors.newFixedThreadPool(1);
 109             // Executor e = (Runnable r) -> e1.execute(() -> {
 110             //    System.out.println("[" + Thread.currentThread().getName()
 111             //                       + "] Executing: "
 112             //                       + r.getClass().getName());
 113             //    r.run();
 114             // });
 115             client = HttpClient.newBuilder()
 116                                .executor(Executors.newFixedThreadPool(2))
 117                                .sslContext(sslContext)
 118                                .version(HTTP_2)
 119                                .build();
 120         }
 121         return client;
 122     }
 123 
 124     static URI getURI(boolean secure) {
 125         if (secure)
 126             return URI.create(httpsURIString);
 127         else
 128             return URI.create(httpURIString);
 129     }
 130 
 131     static void checkStatus(int expected, int found) throws Exception {
 132         if (expected != found) {
 133             System.err.printf ("Test failed: wrong status code %d/%d\n",
 134                 expected, found);
 135             throw new RuntimeException("Test failed");
 136         }
 137     }
 138 
 139     static void checkStrings(String expected, String found) throws Exception {
 140         if (!expected.equals(found)) {
 141             System.err.printf ("Test failed: wrong string %s/%s\n",
 142                 expected, found);
 143             throw new RuntimeException("Test failed");
 144         }
 145     }
 146 
 147     static Void compareFiles(Path path1, Path path2) {
 148         return TestUtil.compareFiles(path1, path2);
 149     }
 150 
 151     static Path tempFile() {
 152         return TestUtil.tempFile();
 153     }
 154 
 155     static final String SIMPLE_STRING = "Hello world Goodbye world";
 156 
 157     static final int LOOPS = 32;
 158     static final int FILESIZE = 64 * 1024 + 200;
 159 
 160     static void streamTest(boolean secure) throws Exception {
 161         URI uri = getURI(secure);
 162         System.err.printf("streamTest %b to %s\n" , secure, uri);
 163 
 164         HttpClient client = getClient();
 165         Path src = TestUtil.getAFile(FILESIZE * 4);
 166         HttpRequest req = HttpRequest.newBuilder(uri)
 167                                      .POST(fromFile(src))
 168                                      .build();
 169 
 170         Path dest = Paths.get("streamtest.txt");
 171         dest.toFile().delete();
 172         CompletableFuture<Path> response = client.sendAsync(req, asFile(dest))
 173                 .thenApply(resp -> {
 174                     if (resp.statusCode() != 200)
 175                         throw new RuntimeException();
 176                     return resp.body();
 177                 });
 178         response.join();
 179         compareFiles(src, dest);
 180         System.err.println("DONE");
 181     }
 182 
 183     static void paramsTest() throws Exception {
 184         System.err.println("paramsTest");
 185         Http2TestServer server = new Http2TestServer(true, 0, exec, sslContext);
 186         server.addHandler((t -> {
 187             SSLSession s = t.getSSLSession();
 188             String prot = s.getProtocol();
 189             if (prot.equals("TLSv1.2")) {
 190                 t.sendResponseHeaders(200, -1);
 191             } else {
 192                 System.err.printf("Protocols =%s\n", prot);
 193                 t.sendResponseHeaders(500, -1);
 194             }
 195         }), "/");
 196         server.start();
 197         int port = server.getAddress().getPort();
 198         URI u = new URI("https://127.0.0.1:"+port+"/foo");
 199         HttpClient client = getClient();
 200         HttpRequest req = HttpRequest.newBuilder(u).build();
 201         HttpResponse<String> resp = client.sendAsync(req, asString()).get();
 202         int stat = resp.statusCode();
 203         if (stat != 200) {
 204             throw new RuntimeException("paramsTest failed "
 205                 + Integer.toString(stat));
 206         }
 207     }
 208 
 209     static void simpleTest(boolean secure) throws Exception {
 210         URI uri = getURI(secure);
 211         System.err.println("Request to " + uri);
 212 
 213         // Do a simple warmup request
 214 
 215         HttpClient client = getClient();
 216         HttpRequest req = HttpRequest.newBuilder(uri)
 217                                      .POST(fromString(SIMPLE_STRING))
 218                                      .build();
 219         HttpResponse<String> response = client.sendAsync(req, asString()).get();
 220         HttpHeaders h = response.headers();
 221 
 222         checkStatus(200, response.statusCode());
 223 
 224         String responseBody = response.body();
 225         checkStrings(SIMPLE_STRING, responseBody);
 226 
 227         checkStrings(h.firstValue("x-hello").get(), "world");
 228         checkStrings(h.firstValue("x-bye").get(), "universe");
 229 
 230         // Do loops asynchronously
 231 
 232         CompletableFuture[] responses = new CompletableFuture[LOOPS];
 233         final Path source = TestUtil.getAFile(FILESIZE);
 234         HttpRequest request = HttpRequest.newBuilder(uri)
 235                                          .POST(fromFile(source))
 236                                          .build();
 237         for (int i = 0; i < LOOPS; i++) {
 238             responses[i] = client.sendAsync(request, asFile(tempFile()))
 239                 //.thenApply(resp -> compareFiles(resp.body(), source));
 240                 .thenApply(resp -> {
 241                     System.out.printf("Resp status %d body size %d\n",
 242                                       resp.statusCode(), resp.body().toFile().length());
 243                     return compareFiles(resp.body(), source);
 244                 });
 245         }
 246         CompletableFuture.allOf(responses).join();
 247         System.err.println("DONE");
 248     }
 249 }