Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/test/jdk/java/net/Authenticator/B4769350.java
41149 views
1
/*
2
* Copyright (c) 2002, 2019, 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 4769350 8017779 8191169
27
* @modules jdk.httpserver
28
* @run main/othervm B4769350 server
29
* @run main/othervm B4769350 proxy
30
* @run main/othervm -Djava.net.preferIPv6Addresses=true B4769350 server
31
* @run main/othervm -Djava.net.preferIPv6Addresses=true B4769350 proxy
32
* @summary proxy authentication username and password caching only works in serial case
33
* Run in othervm since the test sets system properties that are read by the
34
* networking stack and cached when the HTTP handler is invoked, and previous
35
* tests may already have invoked the HTTP handler.
36
*/
37
38
import com.sun.net.httpserver.HttpExchange;
39
import com.sun.net.httpserver.HttpHandler;
40
import com.sun.net.httpserver.HttpServer;
41
import java.io.*;
42
import java.net.*;
43
import java.util.concurrent.BrokenBarrierException;
44
import java.util.concurrent.CountDownLatch;
45
import java.util.concurrent.CyclicBarrier;
46
import java.util.concurrent.Executor;
47
import java.util.concurrent.ExecutorService;
48
import java.util.concurrent.Executors;
49
50
public class B4769350 {
51
52
static int count = 0;
53
static boolean error = false;
54
55
static void read (InputStream is) throws IOException {
56
while (is.read() != -1) {
57
//System.out.write (c);
58
}
59
}
60
61
static class Client extends Thread {
62
String authority, path;
63
boolean allowerror;
64
65
Client (String authority, String path, boolean allowerror) {
66
super("Thread-" + path);
67
this.authority = authority;
68
this.path = path;
69
this.allowerror = allowerror;
70
}
71
72
@Override
73
public void run () {
74
try {
75
URI u = new URI ("http", authority, path, null, null);
76
URL url = u.toURL();
77
URLConnection urlc = url.openConnection();
78
try (InputStream is = urlc.getInputStream()) {
79
read (is);
80
}
81
} catch (URISyntaxException e) {
82
System.out.println (e);
83
error = true;
84
} catch (IOException e) {
85
if (!allowerror) {
86
System.out.println (Thread.currentThread().getName()
87
+ " " + e);
88
e.printStackTrace();
89
error = true;
90
}
91
}
92
}
93
}
94
95
class Server implements AutoCloseable {
96
HttpServer server;
97
Executor executor;
98
99
public String getAddress() {
100
return server.getAddress().getHostName();
101
}
102
103
public void startServer() {
104
InetAddress loopback = InetAddress.getLoopbackAddress();
105
InetSocketAddress addr = new InetSocketAddress(loopback, 0);
106
107
try {
108
server = HttpServer.create(addr, 0);
109
} catch (IOException ioe) {
110
throw new RuntimeException("Server could not be created");
111
}
112
executor = Executors.newFixedThreadPool(10);
113
server.setExecutor(executor);
114
server.createContext("/test/realm1/t1a",
115
new AuthenticationHandlerT1a() );
116
server.createContext("/test/realm2/t1b",
117
new AuthenticationHandlerT1b());
118
server.createContext("/test/realm1/t1c",
119
new AuthenticationHandlerT1c());
120
server.createContext("/test/realm2/t1d",
121
new AuthenticationHandlerT1d());
122
server.createContext("/test/realm3/t2a",
123
new AuthenticationHandlerT2a());
124
server.createContext("/test/realm3/t2b",
125
new AuthenticationHandlerT2b());
126
server.createContext("/test/realm4/t3a",
127
new AuthenticationHandlerT3a());
128
server.createContext("/test/realm4/t3b",
129
new AuthenticationHandlerT3bc());
130
server.createContext("/test/realm4/t3c",
131
new AuthenticationHandlerT3bc());
132
t1Cond1 = new CyclicBarrier(3);
133
server.start();
134
}
135
136
public int getPort() {
137
return server.getAddress().getPort();
138
}
139
140
@Override
141
public void close() {
142
if (executor != null)
143
((ExecutorService)executor).shutdownNow();
144
if (server != null)
145
server.stop(0);
146
}
147
148
/* T1 tests the client by sending 4 requests to 2 different realms
149
* in parallel. The client should recognise two pairs of dependent requests
150
* and execute the first of each pair in parallel. When they both succeed
151
* the second requests should be executed without calling the authenticator.
152
* The test succeeds if the authenticator was only called twice.
153
*/
154
class AuthenticationHandlerT1a implements HttpHandler
155
{
156
volatile int count = -1;
157
158
@Override
159
public void handle(HttpExchange exchange) throws IOException {
160
count++;
161
try {
162
switch(count) {
163
case 0:
164
AuthenticationHandler.errorReply(exchange,
165
"Basic realm=\"realm1\"");
166
break;
167
case 1:
168
t1Cond1.await();
169
AuthenticationHandler.okReply(exchange);
170
break;
171
default:
172
System.out.println ("Unexpected request");
173
}
174
} catch (InterruptedException |
175
BrokenBarrierException e)
176
{
177
throw new RuntimeException(e);
178
}
179
}
180
}
181
182
class AuthenticationHandlerT1b implements HttpHandler
183
{
184
volatile int count = -1;
185
186
@Override
187
public void handle(HttpExchange exchange) throws IOException {
188
count++;
189
try {
190
switch(count) {
191
case 0:
192
AuthenticationHandler.errorReply(exchange,
193
"Basic realm=\"realm2\"");
194
break;
195
case 1:
196
t1Cond1.await();
197
AuthenticationHandler.okReply(exchange);
198
break;
199
default:
200
System.out.println ("Unexpected request");
201
}
202
} catch (InterruptedException | BrokenBarrierException e) {
203
throw new RuntimeException(e);
204
}
205
}
206
}
207
208
class AuthenticationHandlerT1c implements HttpHandler
209
{
210
volatile int count = -1;
211
212
@Override
213
public void handle(HttpExchange exchange) throws IOException {
214
count++;
215
switch(count) {
216
case 0:
217
AuthenticationHandler.errorReply(exchange,
218
"Basic realm=\"realm1\"");
219
break;
220
case 1:
221
AuthenticationHandler.okReply(exchange);
222
break;
223
default:
224
System.out.println ("Unexpected request");
225
}
226
}
227
}
228
229
class AuthenticationHandlerT1d implements HttpHandler
230
{
231
volatile int count = -1;
232
233
@Override
234
public void handle(HttpExchange exchange) throws IOException {
235
count++;
236
switch(count) {
237
case 0:
238
AuthenticationHandler.errorReply(exchange,
239
"Basic realm=\"realm2\"");
240
break;
241
case 1:
242
AuthenticationHandler.okReply(exchange);
243
break;
244
default:
245
System.out.println ("Unexpected request");
246
}
247
}
248
}
249
250
/* T2 tests to check that if initial authentication fails, the second will
251
* succeed, and the authenticator is called twice
252
*/
253
254
class AuthenticationHandlerT2a implements HttpHandler
255
{
256
volatile int count = -1;
257
258
@Override
259
public void handle(HttpExchange exchange) throws IOException {
260
count++;
261
if (count == 1) {
262
t2condlatch.countDown();
263
}
264
AuthenticationHandler.errorReply(exchange,
265
"Basic realm=\"realm3\"");
266
267
}
268
}
269
270
class AuthenticationHandlerT2b implements HttpHandler
271
{
272
volatile int count = -1;
273
274
@Override
275
public void handle(HttpExchange exchange) throws IOException {
276
count++;
277
switch(count) {
278
case 0:
279
AuthenticationHandler.errorReply(exchange,
280
"Basic realm=\"realm3\"");
281
break;
282
case 1:
283
AuthenticationHandler.okReply(exchange);
284
break;
285
default:
286
System.out.println ("Unexpected request");
287
}
288
}
289
}
290
291
/* T3 tests proxy and server authentication. three threads request same
292
* resource at same time. Authenticator should be called once for server
293
* and once for proxy
294
*/
295
296
class AuthenticationHandlerT3a implements HttpHandler
297
{
298
volatile int count = -1;
299
300
@Override
301
public void handle(HttpExchange exchange) throws IOException {
302
count++;
303
switch(count) {
304
case 0:
305
AuthenticationHandler.proxyReply(exchange,
306
"Basic realm=\"proxy\"");
307
break;
308
case 1:
309
t3cond1.countDown();
310
AuthenticationHandler.errorReply(exchange,
311
"Basic realm=\"realm4\"");
312
break;
313
case 2:
314
AuthenticationHandler.okReply(exchange);
315
break;
316
default:
317
System.out.println ("Unexpected request");
318
}
319
}
320
}
321
322
class AuthenticationHandlerT3bc implements HttpHandler
323
{
324
volatile int count = -1;
325
326
@Override
327
public void handle(HttpExchange exchange) throws IOException {
328
count++;
329
switch(count) {
330
case 0:
331
AuthenticationHandler.proxyReply(exchange,
332
"Basic realm=\"proxy\"");
333
break;
334
case 1:
335
AuthenticationHandler.okReply(exchange);
336
break;
337
default:
338
System.out.println ("Unexpected request");
339
}
340
}
341
}
342
}
343
344
static class AuthenticationHandler {
345
static void errorReply(HttpExchange exchange, String reply)
346
throws IOException
347
{
348
exchange.getResponseHeaders().add("Connection", "close");
349
exchange.getResponseHeaders().add("WWW-Authenticate", reply);
350
exchange.sendResponseHeaders(401, 0);
351
exchange.close();
352
}
353
354
static void proxyReply (HttpExchange exchange, String reply)
355
throws IOException
356
{
357
exchange.getResponseHeaders().add("Proxy-Authenticate", reply);
358
exchange.sendResponseHeaders(407, 0);
359
}
360
361
static void okReply (HttpExchange exchange) throws IOException {
362
exchange.getResponseHeaders().add("Connection", "close");
363
String response = "Hello .";
364
exchange.sendResponseHeaders(200, response.getBytes().length);
365
try (OutputStream os = exchange.getResponseBody()) {
366
os.write(response.getBytes());
367
}
368
exchange.close();
369
}
370
}
371
372
static Server server;
373
static MyAuthenticator auth = new MyAuthenticator ();
374
375
static int redirects = 4;
376
377
static Client c1,c2,c3,c4,c5,c6,c7,c8,c9;
378
379
static CountDownLatch t2condlatch;
380
static CountDownLatch t3cond1;
381
static CyclicBarrier t1Cond1;
382
383
static void doServerTests (String authority, Server server) throws Exception
384
{
385
System.out.println ("Doing Server tests");
386
System.out.println ("T1");
387
c1 = new Client (authority, "/test/realm1/t1a", false);
388
c2 = new Client (authority, "/test/realm2/t1b", false);
389
c3 = new Client (authority, "/test/realm1/t1c", false);
390
c4 = new Client (authority, "/test/realm2/t1d", false);
391
c1.start(); c2.start();
392
t1Cond1.await();
393
c3.start(); c4.start();
394
c1.join(); c2.join(); c3.join(); c4.join();
395
396
int f = auth.getCount();
397
if (f != 2) {
398
except ("Authenticator was called "+f+" times. Should be 2",
399
server);
400
}
401
if (error) {
402
except ("error occurred", server);
403
}
404
405
auth.resetCount();
406
System.out.println ("T2");
407
408
c5 = new Client (authority, "/test/realm3/t2a", true);
409
c6 = new Client (authority, "/test/realm3/t2b", false);
410
t2condlatch = new CountDownLatch(1);
411
c5.start ();
412
t2condlatch.await();
413
c6.start ();
414
c5.join(); c6.join();
415
416
f = auth.getCount();
417
if (f != redirects+1) {
418
except ("Authenticator was called "+f+" times. Should be: "
419
+ redirects+1, server);
420
}
421
if (error) {
422
except ("error occurred", server);
423
}
424
}
425
426
static void doProxyTests (String authority, Server server) throws Exception
427
{
428
System.out.println ("Doing Proxy tests");
429
c7 = new Client (authority, "/test/realm4/t3a", false);
430
c8 = new Client (authority, "/test/realm4/t3b", false);
431
c9 = new Client (authority, "/test/realm4/t3c", false);
432
t3cond1 = new CountDownLatch(1);
433
c7.start ();
434
t3cond1.await();
435
c8.start ();
436
c9.start ();
437
c7.join(); c8.join(); c9.join();
438
439
int f = auth.getCount();
440
if (f != 2) {
441
except ("Authenticator was called "+f+" times. Should be: " + 2,
442
server);
443
}
444
if (error) {
445
except ("error occurred", server);
446
}
447
}
448
449
public static void main (String[] args) throws Exception {
450
new B4769350().runTest(args[0].equals ("proxy"));
451
}
452
453
public void runTest(boolean proxy) throws Exception {
454
System.setProperty ("http.maxRedirects", Integer.toString (redirects));
455
System.setProperty ("http.auth.serializeRequests", "true");
456
Authenticator.setDefault (auth);
457
try (Server server = new Server()) {
458
server.startServer();
459
System.out.println ("Server: listening on port: "
460
+ server.getPort());
461
if (proxy) {
462
System.setProperty ("http.proxyHost",
463
InetAddress.getLoopbackAddress().getHostAddress());
464
System.setProperty ("http.proxyPort",
465
Integer.toString(server.getPort()));
466
doProxyTests ("www.foo.com", server);
467
} else {
468
ProxySelector.setDefault(ProxySelector.of(null));
469
doServerTests (authority(server.getPort()), server);
470
}
471
}
472
473
}
474
475
static String authority(int port) {
476
InetAddress loopback = InetAddress.getLoopbackAddress();
477
String hoststr = loopback.getHostAddress();
478
if (hoststr.indexOf(':') > -1) {
479
hoststr = "[" + hoststr + "]";
480
}
481
return hoststr + ":" + port;
482
}
483
484
public static void except (String s, Server server) {
485
server.close();
486
throw new RuntimeException (s);
487
}
488
489
static class MyAuthenticator extends Authenticator {
490
MyAuthenticator () {
491
super ();
492
}
493
494
volatile int count = 0;
495
496
@Override
497
public PasswordAuthentication getPasswordAuthentication () {
498
PasswordAuthentication pw;
499
pw = new PasswordAuthentication ("user", "pass1".toCharArray());
500
count ++;
501
return pw;
502
}
503
504
public void resetCount () {
505
count = 0;
506
}
507
508
public int getCount () {
509
return count;
510
}
511
}
512
}
513
514