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 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 NoBodyTest 34 */ 35 36 import java.io.IOException; 37 import java.io.InputStream; 38 import java.io.OutputStream; 39 import java.net.*; 40 import javax.net.ssl.*; 41 import java.net.http.HttpClient; 42 import java.net.http.HttpHeaders; 43 import java.net.http.HttpRequest; 44 import java.net.http.HttpRequest.BodyPublishers; 45 import java.net.http.HttpResponse; 46 import java.net.http.HttpResponse.BodyHandlers; 47 import java.util.concurrent.*; 48 import jdk.testlibrary.SimpleSSLContext; 49 import org.testng.annotations.Test; 50 import static java.net.http.HttpClient.Version.HTTP_2; 51 52 @Test 53 public class NoBodyTest { 54 static int httpPort, httpsPort; 55 static Http2TestServer httpServer, httpsServer; 56 static HttpClient client = null; 57 static ExecutorService clientExec; 58 static ExecutorService serverExec; 59 static SSLContext sslContext; 60 static String TEST_STRING = "The quick brown fox jumps over the lazy dog "; 61 62 static String httpURIString, httpsURIString; 63 initialize()64 static void initialize() throws Exception { 65 try { 66 SimpleSSLContext sslct = new SimpleSSLContext(); 67 sslContext = sslct.get(); 68 client = getClient(); 69 httpServer = new Http2TestServer(false, 0, serverExec, sslContext); 70 httpServer.addHandler(new Handler(), "/"); 71 httpPort = httpServer.getAddress().getPort(); 72 73 httpsServer = new Http2TestServer(true, 0, serverExec, sslContext); 74 httpsServer.addHandler(new Handler(), "/"); 75 76 httpsPort = httpsServer.getAddress().getPort(); 77 httpURIString = "http://localhost:" + httpPort + "/foo/"; 78 httpsURIString = "https://localhost:" + httpsPort + "/bar/"; 79 80 httpServer.start(); 81 httpsServer.start(); 82 } catch (Throwable e) { 83 System.err.println("Throwing now"); 84 e.printStackTrace(System.err); 85 throw e; 86 } 87 } 88 89 @Test runtest()90 public static void runtest() throws Exception { 91 try { 92 initialize(); 93 warmup(false); 94 warmup(true); 95 test(false); 96 test(true); 97 } catch (Throwable tt) { 98 System.err.println("tt caught"); 99 tt.printStackTrace(System.err); 100 throw tt; 101 } finally { 102 httpServer.stop(); 103 httpsServer.stop(); 104 } 105 } 106 getClient()107 static HttpClient getClient() { 108 if (client == null) { 109 serverExec = Executors.newCachedThreadPool(); 110 clientExec = Executors.newCachedThreadPool(); 111 client = HttpClient.newBuilder() 112 .executor(clientExec) 113 .sslContext(sslContext) 114 .version(HTTP_2) 115 .build(); 116 } 117 return client; 118 } 119 getURI(boolean secure)120 static URI getURI(boolean secure) { 121 if (secure) 122 return URI.create(httpsURIString); 123 else 124 return URI.create(httpURIString); 125 } 126 checkStatus(int expected, int found)127 static void checkStatus(int expected, int found) throws Exception { 128 if (expected != found) { 129 System.err.printf ("Test failed: wrong status code %d/%d\n", 130 expected, found); 131 throw new RuntimeException("Test failed"); 132 } 133 } 134 checkStrings(String expected, String found)135 static void checkStrings(String expected, String found) throws Exception { 136 if (!expected.equals(found)) { 137 System.err.printf ("Test failed: wrong string %s/%s\n", 138 expected, found); 139 throw new RuntimeException("Test failed"); 140 } 141 } 142 143 static final int LOOPS = 13; 144 warmup(boolean secure)145 static void warmup(boolean secure) throws Exception { 146 URI uri = getURI(secure); 147 String type = secure ? "https" : "http"; 148 System.err.println("Request to " + uri); 149 150 // Do a simple warmup request 151 152 HttpClient client = getClient(); 153 HttpRequest req = HttpRequest.newBuilder(uri) 154 .POST(BodyPublishers.ofString("Random text")) 155 .build(); 156 HttpResponse<String> response = client.send(req, BodyHandlers.ofString()); 157 checkStatus(200, response.statusCode()); 158 String responseBody = response.body(); 159 HttpHeaders h = response.headers(); 160 checkStrings(TEST_STRING + type, responseBody); 161 } 162 test(boolean secure)163 static void test(boolean secure) throws Exception { 164 URI uri = getURI(secure); 165 String type = secure ? "https" : "http"; 166 System.err.println("Request to " + uri); 167 168 HttpRequest request = HttpRequest.newBuilder(uri) 169 .POST(BodyPublishers.ofString(TEST_STRING)) 170 .build(); 171 for (int i = 0; i < LOOPS; i++) { 172 System.out.println("Loop " + i); 173 HttpResponse<String> response = client.send(request, BodyHandlers.ofString()); 174 int expectedResponse = (i % 2) == 0 ? 204 : 200; 175 if (response.statusCode() != expectedResponse) 176 throw new RuntimeException("wrong response code " + Integer.toString(response.statusCode())); 177 if (expectedResponse == 200 && !response.body().equals(TEST_STRING + type)) { 178 System.err.printf("response received/expected %s/%s\n", response.body(), TEST_STRING + type); 179 throw new RuntimeException("wrong response body"); 180 } 181 } 182 System.err.println("test: DONE"); 183 } 184 185 static class Handler implements Http2Handler { 186 Handler()187 public Handler() {} 188 189 volatile int invocation = 0; 190 191 @Override handle(Http2TestExchange t)192 public void handle(Http2TestExchange t) 193 throws IOException { 194 try { 195 URI uri = t.getRequestURI(); 196 System.err.printf("Handler received request to %s from %s\n", 197 uri, t.getRemoteAddress()); 198 String type = uri.getScheme().toLowerCase(); 199 InputStream is = t.getRequestBody(); 200 while (is.read() != -1); 201 is.close(); 202 203 // every second response is 204. 204 205 if ((invocation++ % 2) == 1) { 206 System.err.println("Server sending 204"); 207 t.sendResponseHeaders(204, -1); 208 } else { 209 String body = TEST_STRING + type; 210 t.sendResponseHeaders(200, body.length()); 211 OutputStream os = t.getResponseBody(); 212 os.write(body.getBytes()); 213 os.close(); 214 } 215 } catch (Throwable e) { 216 e.printStackTrace(System.err); 217 throw new IOException(e); 218 } 219 } 220 } 221 } 222