21 * questions. |
21 * questions. |
22 */ |
22 */ |
23 |
23 |
24 /* |
24 /* |
25 * @test |
25 * @test |
26 * @bug 8087112 |
26 * @bug 8087112 8180044 |
27 * @modules jdk.incubator.httpclient |
27 * @modules jdk.incubator.httpclient |
28 * java.logging |
28 * java.logging |
29 * jdk.httpserver |
29 * jdk.httpserver |
30 * @library /lib/testlibrary/ / |
30 * @library /lib/testlibrary/ / |
31 * @build jdk.testlibrary.SimpleSSLContext EchoHandler |
31 * @build jdk.testlibrary.SimpleSSLContext EchoHandler |
32 * @compile ../../../com/sun/net/httpserver/LogFilter.java |
32 * @compile ../../../com/sun/net/httpserver/LogFilter.java |
33 * @compile ../../../com/sun/net/httpserver/FileServerHandler.java |
33 * @compile ../../../com/sun/net/httpserver/FileServerHandler.java |
34 * @run main/othervm/timeout=40 -Djdk.httpclient.HttpClient.log=ssl ManyRequests |
34 * @run main/othervm/timeout=40 -Djdk.httpclient.HttpClient.log=ssl ManyRequests |
|
35 * @run main/othervm/timeout=40 -Dtest.insertDelay=true ManyRequests |
|
36 * @run main/othervm/timeout=40 -Dtest.chunkSize=64 ManyRequests |
|
37 * @run main/othervm/timeout=40 -Dtest.insertDelay=true -Dtest.chunkSize=64 ManyRequests |
35 * @summary Send a large number of requests asynchronously |
38 * @summary Send a large number of requests asynchronously |
36 */ |
39 */ |
|
40 // * @run main/othervm/timeout=40 -Djdk.httpclient.HttpClient.log=ssl ManyRequests |
37 |
41 |
38 import com.sun.net.httpserver.HttpsConfigurator; |
42 import com.sun.net.httpserver.HttpsConfigurator; |
39 import com.sun.net.httpserver.HttpsParameters; |
43 import com.sun.net.httpserver.HttpsParameters; |
40 import com.sun.net.httpserver.HttpsServer; |
44 import com.sun.net.httpserver.HttpsServer; |
|
45 import com.sun.net.httpserver.HttpExchange; |
41 import java.io.IOException; |
46 import java.io.IOException; |
|
47 import java.io.InputStream; |
|
48 import java.io.OutputStream; |
42 import jdk.incubator.http.HttpClient; |
49 import jdk.incubator.http.HttpClient; |
43 import jdk.incubator.http.HttpRequest; |
50 import jdk.incubator.http.HttpRequest; |
44 import java.net.InetSocketAddress; |
51 import java.net.InetSocketAddress; |
45 import java.net.URI; |
52 import java.net.URI; |
46 import java.util.Arrays; |
53 import java.util.Arrays; |
63 |
70 |
64 public static void main(String[] args) throws Exception { |
71 public static void main(String[] args) throws Exception { |
65 Logger logger = Logger.getLogger("com.sun.net.httpserver"); |
72 Logger logger = Logger.getLogger("com.sun.net.httpserver"); |
66 logger.setLevel(Level.ALL); |
73 logger.setLevel(Level.ALL); |
67 logger.info("TEST"); |
74 logger.info("TEST"); |
68 |
75 System.out.println("Sending " + REQUESTS |
|
76 + " requests; delay=" + INSERT_DELAY |
|
77 + ", chunks=" + CHUNK_SIZE |
|
78 + ", XFixed=" + XFIXED); |
69 SSLContext ctx = new SimpleSSLContext().get(); |
79 SSLContext ctx = new SimpleSSLContext().get(); |
70 |
80 |
71 InetSocketAddress addr = new InetSocketAddress(0); |
81 InetSocketAddress addr = new InetSocketAddress(0); |
72 HttpsServer server = HttpsServer.create(addr, 0); |
82 HttpsServer server = HttpsServer.create(addr, 0); |
73 server.setHttpsConfigurator(new Configurator(ctx)); |
83 server.setHttpsConfigurator(new Configurator(ctx)); |
84 } |
94 } |
85 } |
95 } |
86 |
96 |
87 //static final int REQUESTS = 1000; |
97 //static final int REQUESTS = 1000; |
88 static final int REQUESTS = 20; |
98 static final int REQUESTS = 20; |
|
99 static final boolean INSERT_DELAY = Boolean.getBoolean("test.insertDelay"); |
|
100 static final int CHUNK_SIZE = Math.max(0, |
|
101 Integer.parseInt(System.getProperty("test.chunkSize", "0"))); |
|
102 static final boolean XFIXED = Boolean.getBoolean("test.XFixed"); |
|
103 |
|
104 static class TestEchoHandler extends EchoHandler { |
|
105 final Random rand = new Random(); |
|
106 @Override |
|
107 public void handle(HttpExchange e) throws IOException { |
|
108 System.out.println("Server: received " + e.getRequestURI()); |
|
109 super.handle(e); |
|
110 } |
|
111 protected void close(OutputStream os) throws IOException { |
|
112 if (INSERT_DELAY) { |
|
113 try { Thread.sleep(rand.nextInt(200)); } catch (InterruptedException e) {} |
|
114 } |
|
115 super.close(os); |
|
116 } |
|
117 protected void close(InputStream is) throws IOException { |
|
118 if (INSERT_DELAY) { |
|
119 try { Thread.sleep(rand.nextInt(200)); } catch (InterruptedException e) {} |
|
120 } |
|
121 super.close(is); |
|
122 } |
|
123 } |
89 |
124 |
90 static void test(HttpsServer server, HttpClient client) throws Exception { |
125 static void test(HttpsServer server, HttpClient client) throws Exception { |
91 int port = server.getAddress().getPort(); |
126 int port = server.getAddress().getPort(); |
92 URI uri = new URI("https://127.0.0.1:" + port + "/foo/x"); |
127 URI baseURI = new URI("https://127.0.0.1:" + port + "/foo/x"); |
93 server.createContext("/foo", new EchoHandler()); |
128 server.createContext("/foo", new TestEchoHandler()); |
94 server.start(); |
129 server.start(); |
95 |
130 |
96 RequestLimiter limiter = new RequestLimiter(40); |
131 RequestLimiter limiter = new RequestLimiter(40); |
97 Random rand = new Random(); |
132 Random rand = new Random(); |
98 CompletableFuture<?>[] results = new CompletableFuture<?>[REQUESTS]; |
133 CompletableFuture<?>[] results = new CompletableFuture<?>[REQUESTS]; |
99 HashMap<HttpRequest,byte[]> bodies = new HashMap<>(); |
134 HashMap<HttpRequest,byte[]> bodies = new HashMap<>(); |
100 |
135 |
101 for (int i=0; i<REQUESTS; i++) { |
136 for (int i=0; i<REQUESTS; i++) { |
102 byte[] buf = new byte[i+1]; // different size bodies |
137 byte[] buf = new byte[(i+1)*CHUNK_SIZE+i+1]; // different size bodies |
103 rand.nextBytes(buf); |
138 rand.nextBytes(buf); |
|
139 URI uri = new URI(baseURI.toString() + String.valueOf(i+1)); |
104 HttpRequest r = HttpRequest.newBuilder(uri) |
140 HttpRequest r = HttpRequest.newBuilder(uri) |
|
141 .header("XFixed", "true") |
105 .POST(fromByteArray(buf)) |
142 .POST(fromByteArray(buf)) |
106 .build(); |
143 .build(); |
107 bodies.put(r, buf); |
144 bodies.put(r, buf); |
108 |
145 |
109 results[i] = |
146 results[i] = |
110 limiter.whenOkToSend() |
147 limiter.whenOkToSend() |
111 .thenCompose((v) -> client.sendAsync(r, asByteArray())) |
148 .thenCompose((v) -> { |
|
149 System.out.println("Client: sendAsync: " + r.uri()); |
|
150 return client.sendAsync(r, asByteArray()); |
|
151 }) |
112 .thenCompose((resp) -> { |
152 .thenCompose((resp) -> { |
113 limiter.requestComplete(); |
153 limiter.requestComplete(); |
114 if (resp.statusCode() != 200) { |
154 if (resp.statusCode() != 200) { |
115 String s = "Expected 200, got: " + resp.statusCode(); |
155 String s = "Expected 200, got: " + resp.statusCode(); |
|
156 System.out.println(s + " from " |
|
157 + resp.request().uri().getPath()); |
116 return completedWithIOException(s); |
158 return completedWithIOException(s); |
117 } else { |
159 } else { |
118 counter++; |
160 counter++; |
119 System.out.println("Result from " + counter); |
161 System.out.println("Result (" + counter + ") from " |
|
162 + resp.request().uri().getPath()); |
120 } |
163 } |
121 return CompletableFuture.completedStage(resp.body()) |
164 return CompletableFuture.completedStage(resp.body()) |
122 .thenApply((b) -> new Pair<>(resp, b)); |
165 .thenApply((b) -> new Pair<>(resp, b)); |
123 }) |
166 }) |
124 .thenAccept((pair) -> { |
167 .thenAccept((pair) -> { |