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