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