1 /* 2 * Copyright (c) 2015, 2016, 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 8161157 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,frames,errors NoBody 33 */ 34 35 import java.io.IOException; 36 import java.net.URI; 37 import jdk.incubator.http.HttpClient; 38 import jdk.incubator.http.HttpRequest; 39 import jdk.incubator.http.HttpResponse; 40 import javax.net.ssl.SSLContext; 41 import javax.net.ssl.SSLParameters; 42 import java.util.concurrent.Executors; 43 import java.util.concurrent.ExecutorService; 44 import jdk.testlibrary.SimpleSSLContext; 45 import static jdk.incubator.http.HttpClient.Version.HTTP_2; 46 import static jdk.incubator.http.HttpRequest.BodyProcessor.fromString; 47 import static jdk.incubator.http.HttpResponse.BodyHandler.asString; 48 49 import org.testng.annotations.Test; 50 51 public class NoBody { 52 53 static final String SIMPLE_STRING = "Hello world. Goodbye world"; 54 55 @Test(timeOut=60000) 56 public void test() throws Exception { 57 SSLContext sslContext = (new SimpleSSLContext()).get(); 58 ExecutorService exec = Executors.newCachedThreadPool(); 59 HttpClient client = HttpClient.newBuilder() 60 .executor(exec) 61 .sslContext(sslContext) 62 .version(HTTP_2) 63 .build(); 64 65 Http2TestServer httpsServer = null; 66 try { 67 httpsServer = new Http2TestServer(true, 68 0, 69 exec, 70 sslContext); 71 httpsServer.addHandler(new NoBodyHandler(), "/"); 72 73 int httpsPort = httpsServer.getAddress().getPort(); 74 String httpsURIString = "https://127.0.0.1:" + httpsPort + "/bar/"; 75 76 httpsServer.start(); 77 URI uri = URI.create(httpsURIString); 78 System.err.println("Request to " + uri); 79 80 HttpRequest req = HttpRequest.newBuilder(uri) 81 .PUT(fromString(SIMPLE_STRING)) 82 .build(); 83 HttpResponse<String> response = client.send(req, asString()); 84 String body = response.body(); 85 if (!body.equals("")) 86 throw new RuntimeException("expected empty body"); 87 System.err.println("DONE"); 88 } finally { 89 if (httpsServer != null ) { httpsServer.stop(); } 90 exec.shutdownNow(); 91 } 92 } 93 } | 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 8161157 27 * @summary Test response body handlers/subscribers when there is no body 28 * @library /lib/testlibrary http2/server 29 * @build jdk.testlibrary.SimpleSSLContext 30 * @modules java.base/sun.net.www.http 31 * jdk.incubator.httpclient/jdk.incubator.http.internal.common 32 * jdk.incubator.httpclient/jdk.incubator.http.internal.frame 33 * jdk.incubator.httpclient/jdk.incubator.http.internal.hpack 34 * @run testng/othervm NoBody 35 */ 36 37 import java.io.IOException; 38 import java.io.InputStream; 39 import java.net.InetSocketAddress; 40 import java.net.URI; 41 import java.nio.file.Files; 42 import java.nio.file.Path; 43 import java.nio.file.Paths; 44 import java.util.Optional; 45 import java.util.concurrent.Executor; 46 import java.util.concurrent.Executors; 47 import java.util.function.Consumer; 48 import com.sun.net.httpserver.HttpExchange; 49 import com.sun.net.httpserver.HttpHandler; 50 import com.sun.net.httpserver.HttpServer; 51 import com.sun.net.httpserver.HttpsConfigurator; 52 import com.sun.net.httpserver.HttpsServer; 53 import jdk.incubator.http.HttpClient; 54 import jdk.incubator.http.HttpRequest; 55 import jdk.incubator.http.HttpResponse; 56 import jdk.incubator.http.HttpResponse.BodyHandler; 57 import javax.net.ssl.SSLContext; 58 import jdk.testlibrary.SimpleSSLContext; 59 import org.testng.annotations.AfterTest; 60 import org.testng.annotations.BeforeTest; 61 import org.testng.annotations.DataProvider; 62 import org.testng.annotations.Test; 63 import static java.lang.System.out; 64 import static java.nio.charset.StandardCharsets.UTF_8; 65 import static jdk.incubator.http.HttpRequest.BodyPublisher.fromString; 66 import static jdk.incubator.http.HttpResponse.BodyHandler.asByteArray; 67 import static jdk.incubator.http.HttpResponse.BodyHandler.asByteArrayConsumer; 68 import static jdk.incubator.http.HttpResponse.BodyHandler.asFile; 69 import static jdk.incubator.http.HttpResponse.BodyHandler.asInputStream; 70 import static jdk.incubator.http.HttpResponse.BodyHandler.asString; 71 import static jdk.incubator.http.HttpResponse.BodyHandler.buffering; 72 import static jdk.incubator.http.HttpResponse.BodyHandler.discard; 73 import static org.testng.Assert.assertEquals; 74 import static org.testng.Assert.assertTrue; 75 import static org.testng.Assert.fail; 76 77 public class NoBody { 78 79 SSLContext sslContext; 80 HttpServer httpTestServer; // HTTP/1.1 [ 4 servers ] 81 HttpsServer httpsTestServer; // HTTPS/1.1 82 Http2TestServer http2TestServer; // HTTP/2 ( h2c ) 83 Http2TestServer https2TestServer; // HTTP/2 ( h2 ) 84 String httpURI_fixed; 85 String httpURI_chunk; 86 String httpsURI_fixed; 87 String httpsURI_chunk; 88 String http2URI_fixed; 89 String http2URI_chunk; 90 String https2URI_fixed; 91 String https2URI_chunk; 92 93 static final String SIMPLE_STRING = "Hello world. Goodbye world"; 94 static final int ITERATION_COUNT = 10; 95 // a shared executor helps reduce the amount of threads created by the test 96 static final Executor executor = Executors.newCachedThreadPool(); 97 98 @DataProvider(name = "variants") 99 public Object[][] variants() { 100 return new Object[][]{ 101 { httpURI_fixed, false }, 102 { httpURI_chunk, false }, 103 { httpsURI_fixed, false }, 104 { httpsURI_chunk, false }, 105 { http2URI_fixed, false }, 106 { http2URI_chunk, false }, 107 { https2URI_fixed, false,}, 108 { https2URI_chunk, false }, 109 110 { httpURI_fixed, true }, 111 { httpURI_chunk, true }, 112 { httpsURI_fixed, true }, 113 { httpsURI_chunk, true }, 114 { http2URI_fixed, true }, 115 { http2URI_chunk, true }, 116 { https2URI_fixed, true,}, 117 { https2URI_chunk, true }, 118 }; 119 } 120 121 HttpClient newHttpClient() { 122 return HttpClient.newBuilder() 123 .executor(executor) 124 .sslContext(sslContext) 125 .build(); 126 } 127 128 @Test(dataProvider = "variants") 129 public void testAsString(String uri, boolean sameClient) throws Exception { 130 HttpClient client = null; 131 for (int i=0; i< ITERATION_COUNT; i++) { 132 if (!sameClient || client == null) 133 client = newHttpClient(); 134 135 HttpRequest req = HttpRequest.newBuilder(URI.create(uri)) 136 .PUT(fromString(SIMPLE_STRING)) 137 .build(); 138 BodyHandler<String> handler = i % 2 == 0 ? asString() : asString(UTF_8); 139 HttpResponse<String> response = client.send(req, handler); 140 String body = response.body(); 141 assertEquals(body, ""); 142 } 143 } 144 145 @Test(dataProvider = "variants") 146 public void testAsFile(String uri, boolean sameClient) throws Exception { 147 HttpClient client = null; 148 for (int i=0; i< ITERATION_COUNT; i++) { 149 if (!sameClient || client == null) 150 client = newHttpClient(); 151 152 HttpRequest req = HttpRequest.newBuilder(URI.create(uri)) 153 .PUT(fromString(SIMPLE_STRING)) 154 .build(); 155 Path p = Paths.get("NoBody_testAsFile.txt"); 156 HttpResponse<Path> response = client.send(req, asFile(p)); 157 Path bodyPath = response.body(); 158 assertTrue(Files.exists(bodyPath)); 159 assertEquals(Files.size(bodyPath), 0); 160 } 161 } 162 163 @Test(dataProvider = "variants") 164 public void testAsByteArray(String uri, boolean sameClient) throws Exception { 165 HttpClient client = null; 166 for (int i=0; i< ITERATION_COUNT; i++) { 167 if (!sameClient || client == null) 168 client = newHttpClient(); 169 170 HttpRequest req = HttpRequest.newBuilder(URI.create(uri)) 171 .PUT(fromString(SIMPLE_STRING)) 172 .build(); 173 HttpResponse<byte[]> response = client.send(req, asByteArray()); 174 byte[] body = response.body(); 175 assertEquals(body.length, 0); 176 } 177 } 178 179 volatile boolean consumerHasBeenCalled; 180 @Test(dataProvider = "variants") 181 public void testAsByteArrayConsumer(String uri, boolean sameClient) throws Exception { 182 HttpClient client = null; 183 for (int i=0; i< ITERATION_COUNT; i++) { 184 if (!sameClient || client == null) 185 client = newHttpClient(); 186 187 HttpRequest req = HttpRequest.newBuilder(URI.create(uri)) 188 .PUT(fromString(SIMPLE_STRING)) 189 .build(); 190 Consumer<Optional<byte[]>> consumer = oba -> { 191 consumerHasBeenCalled = true; 192 oba.ifPresent(ba -> fail("Unexpected non-empty optional:" + ba)); 193 }; 194 consumerHasBeenCalled = false; 195 client.send(req, asByteArrayConsumer(consumer)); 196 assertTrue(consumerHasBeenCalled); 197 } 198 } 199 200 @Test(dataProvider = "variants") 201 public void testAsInputStream(String uri, boolean sameClient) throws Exception { 202 HttpClient client = null; 203 for (int i=0; i< ITERATION_COUNT; i++) { 204 if (!sameClient || client == null) 205 client = newHttpClient(); 206 207 HttpRequest req = HttpRequest.newBuilder(URI.create(uri)) 208 .PUT(fromString(SIMPLE_STRING)) 209 .build(); 210 HttpResponse<InputStream> response = client.send(req, asInputStream()); 211 byte[] body = response.body().readAllBytes(); 212 assertEquals(body.length, 0); 213 } 214 } 215 216 @Test(dataProvider = "variants") 217 public void testBuffering(String uri, boolean sameClient) throws Exception { 218 HttpClient client = null; 219 for (int i=0; i< ITERATION_COUNT; i++) { 220 if (!sameClient || client == null) 221 client = newHttpClient(); 222 223 HttpRequest req = HttpRequest.newBuilder(URI.create(uri)) 224 .PUT(fromString(SIMPLE_STRING)) 225 .build(); 226 HttpResponse<byte[]> response = client.send(req, buffering(asByteArray(), 1024)); 227 byte[] body = response.body(); 228 assertEquals(body.length, 0); 229 } 230 } 231 232 @Test(dataProvider = "variants") 233 public void testDiscard(String uri, boolean sameClient) throws Exception { 234 HttpClient client = null; 235 for (int i=0; i< ITERATION_COUNT; i++) { 236 if (!sameClient || client == null) 237 client = newHttpClient(); 238 239 HttpRequest req = HttpRequest.newBuilder(URI.create(uri)) 240 .PUT(fromString(SIMPLE_STRING)) 241 .build(); 242 Object obj = new Object(); 243 HttpResponse<Object> response = client.send(req, discard(obj)); 244 assertEquals(response.body(), obj); 245 } 246 } 247 248 249 @BeforeTest 250 public void setup() throws Exception { 251 sslContext = new SimpleSSLContext().get(); 252 if (sslContext == null) 253 throw new AssertionError("Unexpected null sslContext"); 254 255 // HTTP/1.1 256 HttpHandler h1_fixedLengthNoBodyHandler = new HTTP1_FixedLengthNoBodyHandler(); 257 HttpHandler h1_chunkNoBodyHandler = new HTTP1_ChunkedNoBodyHandler(); 258 InetSocketAddress sa = new InetSocketAddress("localhost", 0); 259 httpTestServer = HttpServer.create(sa, 0); 260 httpTestServer.createContext("/http1/noBodyFixed", h1_fixedLengthNoBodyHandler); 261 httpTestServer.createContext("/http1/noBodyChunk", h1_chunkNoBodyHandler); 262 httpURI_fixed = "http://127.0.0.1:" + httpTestServer.getAddress().getPort() + "/http1/noBodyFixed"; 263 httpURI_chunk = "http://127.0.0.1:" + httpTestServer.getAddress().getPort() + "/http1/noBodyChunk"; 264 265 httpsTestServer = HttpsServer.create(sa, 0); 266 httpsTestServer.setHttpsConfigurator(new HttpsConfigurator(sslContext)); 267 httpsTestServer.createContext("/https1/noBodyFixed", h1_fixedLengthNoBodyHandler); 268 httpsTestServer.createContext("/https1/noBodyChunk", h1_chunkNoBodyHandler); 269 httpsURI_fixed = "https://127.0.0.1:" + httpsTestServer.getAddress().getPort() + "/https1/noBodyFixed"; 270 httpsURI_chunk = "https://127.0.0.1:" + httpsTestServer.getAddress().getPort() + "/https1/noBodyChunk"; 271 272 // HTTP/2 273 Http2Handler h2_fixedLengthNoBodyHandler = new HTTP2_FixedLengthNoBodyHandler(); 274 Http2Handler h2_chunkedNoBodyHandler = new HTTP2_ChunkedNoBodyHandler(); 275 276 http2TestServer = new Http2TestServer("127.0.0.1", false, 0); 277 http2TestServer.addHandler(h2_fixedLengthNoBodyHandler, "/http2/noBodyFixed"); 278 http2TestServer.addHandler(h2_chunkedNoBodyHandler, "/http2/noBodyChunk"); 279 int port = http2TestServer.getAddress().getPort(); 280 http2URI_fixed = "http://127.0.0.1:" + port + "/http2/noBodyFixed"; 281 http2URI_chunk = "http://127.0.0.1:" + port + "/http2/noBodyChunk"; 282 283 https2TestServer = new Http2TestServer("127.0.0.1", true, 0); 284 https2TestServer.addHandler(h2_fixedLengthNoBodyHandler, "/https2/noBodyFixed"); 285 https2TestServer.addHandler(h2_chunkedNoBodyHandler, "/https2/noBodyChunk"); 286 port = https2TestServer.getAddress().getPort(); 287 https2URI_fixed = "https://127.0.0.1:" + port + "/https2/noBodyFixed"; 288 https2URI_chunk = "https://127.0.0.1:" + port + "/https2/noBodyChunk"; 289 290 httpTestServer.start(); 291 httpsTestServer.start(); 292 http2TestServer.start(); 293 https2TestServer.start(); 294 } 295 296 @AfterTest 297 public void teardown() throws Exception { 298 httpTestServer.stop(0); 299 httpsTestServer.stop(0); 300 http2TestServer.stop(); 301 https2TestServer.stop(); 302 } 303 304 static class HTTP1_FixedLengthNoBodyHandler implements HttpHandler { 305 @Override 306 public void handle(HttpExchange t) throws IOException { 307 //out.println("NoBodyHandler received request to " + t.getRequestURI()); 308 try (InputStream is = t.getRequestBody()) { 309 is.readAllBytes(); 310 } 311 t.sendResponseHeaders(200, -1); // no body 312 } 313 } 314 315 static class HTTP1_ChunkedNoBodyHandler implements HttpHandler { 316 @Override 317 public void handle(HttpExchange t) throws IOException { 318 //out.println("NoBodyHandler received request to " + t.getRequestURI()); 319 try (InputStream is = t.getRequestBody()) { 320 is.readAllBytes(); 321 } 322 t.sendResponseHeaders(200, 0); // chunked 323 t.getResponseBody().close(); // write nothing 324 } 325 } 326 327 static class HTTP2_FixedLengthNoBodyHandler implements Http2Handler { 328 @Override 329 public void handle(Http2TestExchange t) throws IOException { 330 //out.println("NoBodyHandler received request to " + t.getRequestURI()); 331 try (InputStream is = t.getRequestBody()) { 332 is.readAllBytes(); 333 } 334 t.sendResponseHeaders(200, 0); 335 } 336 } 337 338 static class HTTP2_ChunkedNoBodyHandler implements Http2Handler { 339 @Override 340 public void handle(Http2TestExchange t) throws IOException { 341 //out.println("NoBodyHandler received request to " + t.getRequestURI()); 342 try (InputStream is = t.getRequestBody()) { 343 is.readAllBytes(); 344 } 345 t.sendResponseHeaders(200, -1); 346 t.getResponseBody().close(); // write nothing 347 } 348 } 349 } |