Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/jdk17u
Path: blob/master/test/jdk/sun/net/www/protocol/https/ChunkedOutputStream.java
66646 views
1
/*
2
* Copyright (c) 2004, 2021, 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 5026745
27
* @library /test/lib
28
* @run main/othervm ChunkedOutputStream
29
* @run main/othervm -Djava.net.preferIPv6Addresses=true ChunkedOutputStream
30
*
31
* SunJSSE does not support dynamic system properties, no way to re-use
32
* system properties in samevm/agentvm mode.
33
* @summary Cannot flush output stream when writing to an HttpUrlConnection
34
*/
35
36
import java.io.FileInputStream;
37
import java.io.IOException;
38
import java.io.InputStream;
39
import java.io.OutputStream;
40
import java.net.HttpRetryException;
41
import java.net.HttpURLConnection;
42
import java.net.InetAddress;
43
import java.net.InetSocketAddress;
44
import java.net.Proxy;
45
import java.net.SocketException;
46
import java.net.URL;
47
import java.nio.charset.Charset;
48
import java.security.KeyStore;
49
import java.util.concurrent.Executors;
50
import java.util.concurrent.atomic.AtomicInteger;
51
52
import javax.net.ssl.HostnameVerifier;
53
import javax.net.ssl.HttpsURLConnection;
54
import javax.net.ssl.KeyManagerFactory;
55
import javax.net.ssl.SSLContext;
56
import javax.net.ssl.SSLSession;
57
import javax.net.ssl.TrustManagerFactory;
58
59
import com.sun.net.httpserver.HttpExchange;
60
import com.sun.net.httpserver.HttpHandler;
61
import com.sun.net.httpserver.HttpsConfigurator;
62
import com.sun.net.httpserver.HttpsServer;
63
64
public class ChunkedOutputStream implements HttpHandler {
65
/*
66
* Where do we find the keystores for ssl?
67
*/
68
static String pathToStores = "../../../../../javax/net/ssl/etc";
69
static String keyStoreFile = "keystore";
70
static String trustStoreFile = "truststore";
71
static String passwd = "passphrase";
72
static int count = 0;
73
static final AtomicInteger rogueCount = new AtomicInteger();
74
75
static final String str1 = "Helloworld1234567890abcdefghijklmnopqrstuvwxyz"+
76
"1234567890abcdefkjsdlkjflkjsldkfjlsdkjflkj"+
77
"1434567890abcdefkjsdlkjflkjsldkfjlsdkjflkj";
78
79
static final String str2 = "Helloworld1234567890abcdefghijklmnopqrstuvwxyz"+
80
"1234567890";
81
82
private static String getAuthority() {
83
InetAddress address = server.getAddress().getAddress();
84
String hostaddr = address.getHostAddress();
85
if (address.isAnyLocalAddress()) hostaddr = "localhost";
86
if (hostaddr.indexOf(':') > -1) hostaddr = "[" + hostaddr + "]";
87
return hostaddr + ":" + server.getAddress().getPort();
88
}
89
90
public void handle(HttpExchange req) throws IOException {
91
// this is needed (count++ doesn't work), 'cause we
92
// are doing concurrent tests
93
System.out.println("Request Received");
94
String path = req.getRequestURI().getPath();
95
if (path.equals("/d0")) {
96
count = 0;
97
} else if (path.equals("/d01")) {
98
count = 1;
99
} else if (path.equals("/d3")) {
100
count = 2;
101
} else if (path.equals("/d4") || path.equals("/d5")) {
102
count = 3;
103
} else if (path.equals("/d6")) {
104
count = 3;
105
} else if (path.equals("/d7")) {
106
count = 4;
107
} else if (path.equals("/d8")) {
108
count = 5;
109
}
110
111
switch (count) {
112
case 0: /* test1 -- keeps conn alive */
113
case 1: /* test2 -- closes conn */
114
115
String reqbody = "";
116
try(InputStream inputStream = req.getRequestBody()) {
117
reqbody = new String(inputStream.readAllBytes(), Charset.forName("ISO8859_1"));
118
}
119
if (!reqbody.equals(str1)) {
120
req.sendResponseHeaders(500, -1);
121
break;
122
}
123
String chunk = req.getRequestHeaders().getFirst("Transfer-encoding");
124
if (!"chunked".equals(chunk)) {
125
req.sendResponseHeaders(501, -1);
126
break;
127
}
128
if (count == 1) {
129
req.getResponseHeaders().set("Connection", "close");
130
}
131
req.sendResponseHeaders(200, 0);
132
try (OutputStream os = req.getResponseBody()) {
133
os.write(reqbody.getBytes(Charset.forName("ISO8859_1")));
134
}
135
break;
136
case 2: /* test 3 */
137
reqbody = new String(req.getRequestBody().readAllBytes(), Charset.forName("ISO8859_1"));
138
if (!reqbody.equals(str2)) {
139
req.sendResponseHeaders(500, -1);
140
break;
141
}
142
int clen = Integer.parseInt (req.getRequestHeaders().getFirst("Content-length"));
143
if (clen != str2.length()) {
144
req.sendResponseHeaders(501, -1);
145
break;
146
}
147
req.getResponseHeaders().set("Connection", "close");
148
req.sendResponseHeaders(200, 0);
149
try (OutputStream os = req.getResponseBody()) {
150
os.write(reqbody.getBytes(Charset.forName("ISO8859_1")));
151
}
152
break;
153
case 3: /* test 6 */
154
if (path.equals("/d6")) {
155
reqbody = new String(req.getRequestBody().readAllBytes(), Charset.forName("ISO8859_1"));
156
}
157
req.getResponseHeaders().set("Location", "https://foo.bar/");
158
req.getResponseHeaders().set("Connection", "close");
159
req.sendResponseHeaders(307, -1);
160
break;
161
case 4: /* test 7 */
162
case 5: /* test 8 */
163
reqbody = new String(req.getRequestBody().readAllBytes(), Charset.forName("ISO8859_1"));
164
if (reqbody != null && !"".equals(reqbody)) {
165
req.sendResponseHeaders(501, -1);
166
break;
167
}
168
req.getResponseHeaders().set("Connection", "close");
169
req.sendResponseHeaders(200, -1);
170
break;
171
default:
172
req.sendResponseHeaders(404, -1);
173
break;
174
}
175
req.close();
176
}
177
178
static void readAndCompare(InputStream is, String cmp) throws IOException {
179
int c;
180
byte buf[] = new byte[1024];
181
int off = 0;
182
int len = 1024;
183
while ((c=is.read(buf, off, len)) != -1) {
184
off += c;
185
len -= c;
186
}
187
String s1 = new String(buf, 0, off, "ISO8859_1");
188
if (!cmp.equals(s1)) {
189
throw new IOException("strings not same");
190
}
191
}
192
193
/* basic smoke test: verify that server drops plain connections */
194
static void testPlainText(String authority) throws Exception {
195
URL url = new URL("http://" + authority + "/Donauschiffsgesellschaftskapitaenskajuete");
196
System.out.println("client opening connection to: " + url);
197
HttpURLConnection urlc = (HttpURLConnection)url.openConnection(Proxy.NO_PROXY);
198
int rogue = rogueCount.get();
199
try {
200
int code = urlc.getResponseCode();
201
System.out.println("Unexpected response: " + code);
202
throw new AssertionError("Unexpected response: " + code);
203
} catch (SocketException x) {
204
// we expect that the server will drop the connection and
205
// close the accepted socket, so we should get a SocketException
206
System.out.println("Got expected exception: " + x);
207
}
208
}
209
210
/* basic chunked test (runs twice) */
211
212
static void test1(String u) throws Exception {
213
URL url = new URL(u);
214
System.out.println("client opening connection to: " + u);
215
HttpURLConnection urlc = (HttpURLConnection)url.openConnection(Proxy.NO_PROXY);
216
urlc.setChunkedStreamingMode(20);
217
urlc.setDoOutput(true);
218
urlc.setRequestMethod("POST");
219
OutputStream os = urlc.getOutputStream();
220
os.write(str1.getBytes(Charset.forName("ISO8859_1")));
221
os.close();
222
InputStream is = urlc.getInputStream();
223
readAndCompare(is, str1);
224
is.close();
225
}
226
227
/* basic fixed length test */
228
229
static void test3(String u) throws Exception {
230
URL url = new URL(u);
231
System.out.println("client opening connection to: " + u);
232
HttpURLConnection urlc = (HttpURLConnection)url.openConnection(Proxy.NO_PROXY);
233
urlc.setFixedLengthStreamingMode(str2.length());
234
urlc.setDoOutput(true);
235
urlc.setRequestMethod("POST");
236
OutputStream os = urlc.getOutputStream();
237
os.write (str2.getBytes(Charset.forName("ISO8859_1")));
238
os.close();
239
InputStream is = urlc.getInputStream();
240
readAndCompare(is, str2);
241
is.close();
242
}
243
244
/* write too few bytes */
245
246
static void test4(String u) throws Exception {
247
URL url = new URL(u);
248
System.out.println("client opening connection to: " + u);
249
HttpURLConnection urlc = (HttpURLConnection)url.openConnection(Proxy.NO_PROXY);
250
urlc.setFixedLengthStreamingMode(str2.length()+1);
251
urlc.setDoOutput(true);
252
urlc.setRequestMethod("POST");
253
OutputStream os = urlc.getOutputStream();
254
os.write(str2.getBytes(Charset.forName("ISO8859_1")));
255
try {
256
os.close();
257
throw new Exception("should have thrown IOException");
258
} catch (IOException e) {}
259
}
260
261
/* write too many bytes */
262
263
static void test5(String u) throws Exception {
264
URL url = new URL(u);
265
System.out.println("client opening connection to: " + u);
266
HttpURLConnection urlc = (HttpURLConnection)url.openConnection(Proxy.NO_PROXY);
267
urlc.setFixedLengthStreamingMode(str2.length()-1);
268
urlc.setDoOutput(true);
269
urlc.setRequestMethod("POST");
270
OutputStream os = urlc.getOutputStream();
271
try {
272
os.write(str2.getBytes(Charset.forName("ISO8859_1")));
273
throw new Exception("should have thrown IOException");
274
} catch (IOException e) {}
275
}
276
277
/* check for HttpRetryException on redirection */
278
279
static void test6(String u) throws Exception {
280
URL url = new URL(u);
281
System.out.println("client opening connection to: " + u);
282
HttpURLConnection urlc = (HttpURLConnection)url.openConnection(Proxy.NO_PROXY);
283
urlc.setChunkedStreamingMode(20);
284
urlc.setDoOutput(true);
285
urlc.setRequestMethod("POST");
286
OutputStream os = urlc.getOutputStream();
287
os.write(str1.getBytes(Charset.forName("ISO8859_1")));
288
os.close();
289
try {
290
InputStream is = urlc.getInputStream();
291
throw new Exception("should have gotten HttpRetryException");
292
} catch (HttpRetryException e) {
293
if (e.responseCode() != 307) {
294
throw new Exception("Wrong response code " + e.responseCode());
295
}
296
if (!e.getLocation().equals("https://foo.bar/")) {
297
throw new Exception("Wrong location " + e.getLocation());
298
}
299
}
300
}
301
302
/* next two tests send zero length posts */
303
304
static void test7(String u) throws Exception {
305
URL url = new URL(u);
306
System.out.println("client opening connection to: " + u);
307
HttpURLConnection urlc = (HttpURLConnection)url.openConnection(Proxy.NO_PROXY);
308
urlc.setChunkedStreamingMode(20);
309
urlc.setDoOutput(true);
310
urlc.setRequestMethod("POST");
311
OutputStream os = urlc.getOutputStream();
312
os.close();
313
int ret = urlc.getResponseCode();
314
if (ret != 200) {
315
throw new Exception("Expected 200: got " + ret);
316
}
317
}
318
319
static void test8(String u) throws Exception {
320
URL url = new URL(u);
321
System.out.println("client opening connection to: " + u);
322
HttpURLConnection urlc = (HttpURLConnection)url.openConnection(Proxy.NO_PROXY);
323
urlc.setFixedLengthStreamingMode(0);
324
urlc.setDoOutput(true);
325
urlc.setRequestMethod("POST");
326
OutputStream os = urlc.getOutputStream();
327
os.close();
328
int ret = urlc.getResponseCode();
329
if (ret != 200) {
330
throw new Exception("Expected 200: got " + ret);
331
}
332
}
333
334
static HttpsServer server;
335
336
public static void main(String[] args) throws Exception {
337
ChunkedOutputStream chunkedOutputStream = new ChunkedOutputStream();
338
// setup properties to do ssl
339
String keyFilename =
340
System.getProperty("test.src", "./") + "/" + pathToStores +
341
"/" + keyStoreFile;
342
String trustFilename =
343
System.getProperty("test.src", "./") + "/" + pathToStores +
344
"/" + trustStoreFile;
345
346
InetAddress loopback = InetAddress.getLoopbackAddress();
347
348
HostnameVerifier reservedHV =
349
HttpsURLConnection.getDefaultHostnameVerifier();
350
try {
351
System.setProperty("javax.net.ssl.keyStore", keyFilename);
352
System.setProperty("javax.net.ssl.keyStorePassword", passwd);
353
System.setProperty("javax.net.ssl.trustStore", trustFilename);
354
System.setProperty("javax.net.ssl.trustStorePassword", passwd);
355
HttpsURLConnection.setDefaultHostnameVerifier(new NameVerifier());
356
357
try {
358
// create and initialize a SSLContext
359
KeyStore ks = KeyStore.getInstance("JKS");
360
KeyStore ts = KeyStore.getInstance("JKS");
361
char[] passphrase = "passphrase".toCharArray();
362
363
ks.load(new FileInputStream(System.getProperty("javax.net.ssl.keyStore")), passphrase);
364
ts.load(new FileInputStream(System.getProperty("javax.net.ssl.trustStore")), passphrase);
365
366
KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
367
kmf.init(ks, passphrase);
368
369
TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509");
370
tmf.init(ts);
371
372
SSLContext sslCtx = SSLContext.getInstance("TLS");
373
374
sslCtx.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);
375
376
server = HttpsServer.create(new InetSocketAddress(loopback, 0), 10);
377
server.setHttpsConfigurator(new HttpsConfigurator(sslCtx));
378
server.createContext("/", chunkedOutputStream);
379
server.setExecutor(Executors.newSingleThreadExecutor());
380
server.start();
381
382
System.out.println("Server started: listening on: " + getAuthority());
383
testPlainText(getAuthority());
384
// the test server doesn't support keep-alive yet
385
// test1("http://" + server.getAuthority() + "/d0");
386
test1("https://" + getAuthority() + "/d01");
387
test3("https://" + getAuthority() + "/d3");
388
test4("https://" + getAuthority() + "/d4");
389
test5("https://" + getAuthority() + "/d5");
390
test6("https://" + getAuthority() + "/d6");
391
test7("https://" + getAuthority() + "/d7");
392
test8("https://" + getAuthority() + "/d8");
393
} catch (Exception e) {
394
if (server != null) {
395
server.stop(1);
396
}
397
throw e;
398
}
399
server.stop(1);
400
} finally {
401
HttpsURLConnection.setDefaultHostnameVerifier(reservedHV);
402
}
403
}
404
405
static class NameVerifier implements HostnameVerifier {
406
public boolean verify(String hostname, SSLSession session) {
407
return true;
408
}
409
}
410
411
public static void except(String s) {
412
server.stop(1);
413
throw new RuntimeException(s);
414
}
415
}
416
417