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 8087112 8159814 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=errors,requests,responses ServerPush 33 */ 34 35import java.io.*; 36import java.net.*; 37import java.nio.file.*; 38import java.nio.file.attribute.*; 39import jdk.incubator.http.*; 40import jdk.incubator.http.HttpResponse.MultiProcessor; 41import jdk.incubator.http.HttpResponse.BodyHandler; 42import java.util.*; 43import java.util.concurrent.*; 44import org.testng.annotations.Test; 45 46public class ServerPush { 47 48 static ExecutorService e = Executors.newCachedThreadPool(); 49 50 static final int LOOPS = 13; 51 static final int FILE_SIZE = 512 * 1024 + 343; 52 53 static Path tempFile; 54 55 @Test(timeOut=30000) 56 public static void test() throws Exception { 57 Http2TestServer server = null; 58 final Path dir = Files.createTempDirectory("serverPush"); 59 try { 60 server = new Http2TestServer(false, 0); 61 server.addHandler(new PushHandler(FILE_SIZE, LOOPS), "/"); 62 tempFile = TestUtil.getAFile(FILE_SIZE); 63 64 System.err.println("Server listening on port " + server.getAddress().getPort()); 65 server.start(); 66 int port = server.getAddress().getPort(); 67 68 // use multi-level path 69 URI uri = new URI("http://127.0.0.1:" + port + "/foo/a/b/c"); 70 HttpRequest request = HttpRequest.newBuilder(uri).GET().build(); 71 72 CompletableFuture<MultiMapResult<Path>> cf = 73 HttpClient.newBuilder().version(HttpClient.Version.HTTP_2) 74 .executor(e).build().sendAsync( 75 request, MultiProcessor.asMap((req) -> { 76 URI u = req.uri(); 77 Path path = Paths.get(dir.toString(), u.getPath()); 78 try { 79 Files.createDirectories(path.getParent()); 80 } catch (IOException ee) { 81 throw new UncheckedIOException(ee); 82 } 83 return Optional.of(BodyHandler.asFile(path)); 84 } 85 )); 86 MultiMapResult<Path> results = cf.get(); 87 88 //HttpResponse resp = request.response(); 89 System.err.println(results.size()); 90 Set<HttpRequest> requests = results.keySet(); 91 92 for (HttpRequest r : requests) { 93 URI u = r.uri(); 94 Path result = results.get(r).get().body(); 95 System.err.printf("%s -> %s\n", u.toString(), result.toString()); 96 TestUtil.compareFiles(result, tempFile); 97 } 98 if (requests.size() != LOOPS + 1) 99 throw new RuntimeException("some results missing"); 100 System.out.println("TEST OK: sleeping for 5 sec"); 101 Thread.sleep (5 * 1000); 102 } finally { 103 e.shutdownNow(); 104 server.stop(); 105 Files.walkFileTree(dir, new SimpleFileVisitor<Path>() { 106 public FileVisitResult postVisitDirectory(Path dir, IOException exc) { 107 dir.toFile().delete(); 108 return FileVisitResult.CONTINUE; 109 } 110 public FileVisitResult visitFile(Path path, BasicFileAttributes attrs) { 111 path.toFile().delete(); 112 return FileVisitResult.CONTINUE; 113 } 114 }); 115 } 116 } 117} 118