Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/test/java/net/Authenticator/B4769350.java
38812 views
/*1* Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*/2223/**24* @test25* @bug 4769350 801777926* @run main/othervm B4769350 server27* @run main/othervm B4769350 proxy28* @summary proxy authentication username and password caching only works in serial case29* Run in othervm since the test sets system properties that are read by the30* networking stack and cached when the HTTP handler is invoked, and previous31* tests may already have invoked the HTTP handler.32*/3334import com.sun.net.httpserver.HttpExchange;35import com.sun.net.httpserver.HttpHandler;36import com.sun.net.httpserver.HttpServer;37import java.io.*;38import java.net.*;39import java.util.concurrent.BrokenBarrierException;40import java.util.concurrent.CountDownLatch;41import java.util.concurrent.CyclicBarrier;42import java.util.concurrent.Executor;43import java.util.concurrent.ExecutorService;44import java.util.concurrent.Executors;4546public class B4769350 {4748static int count = 0;49static boolean error = false;5051static void read (InputStream is) throws IOException {52while (is.read() != -1) {53//System.out.write (c);54}55}5657static class Client extends Thread {58String authority, path;59boolean allowerror;6061Client (String authority, String path, boolean allowerror) {62super("Thread-" + path);63this.authority = authority;64this.path = path;65this.allowerror = allowerror;66}6768@Override69public void run () {70try {71URI u = new URI ("http", authority, path, null, null);72URL url = u.toURL();73URLConnection urlc = url.openConnection();74try (InputStream is = urlc.getInputStream()) {75read (is);76}77} catch (URISyntaxException e) {78System.out.println (e);79error = true;80} catch (IOException e) {81if (!allowerror) {82System.out.println (Thread.currentThread().getName()83+ " " + e);84e.printStackTrace();85error = true;86}87}88}89}9091class Server implements AutoCloseable {92HttpServer server;93Executor executor;9495public String getAddress() {96return server.getAddress().getHostName();97}9899public void startServer() {100InetSocketAddress addr = new InetSocketAddress(0);101102try {103server = HttpServer.create(addr, 0);104} catch (IOException ioe) {105throw new RuntimeException("Server could not be created");106}107executor = Executors.newFixedThreadPool(10);108server.setExecutor(executor);109server.createContext("/test/realm1/t1a",110new AuthenticationHandlerT1a() );111server.createContext("/test/realm2/t1b",112new AuthenticationHandlerT1b());113server.createContext("/test/realm1/t1c",114new AuthenticationHandlerT1c());115server.createContext("/test/realm2/t1d",116new AuthenticationHandlerT1d());117server.createContext("/test/realm3/t2a",118new AuthenticationHandlerT2a());119server.createContext("/test/realm3/t2b",120new AuthenticationHandlerT2b());121server.createContext("/test/realm4/t3a",122new AuthenticationHandlerT3a());123server.createContext("/test/realm4/t3b",124new AuthenticationHandlerT3bc());125server.createContext("/test/realm4/t3c",126new AuthenticationHandlerT3bc());127t1Cond1 = new CyclicBarrier(3);128server.start();129}130131public int getPort() {132return server.getAddress().getPort();133}134135@Override136public void close() {137if (executor != null)138((ExecutorService)executor).shutdownNow();139if (server != null)140server.stop(0);141}142143/* T1 tests the client by sending 4 requests to 2 different realms144* in parallel. The client should recognise two pairs of dependent requests145* and execute the first of each pair in parallel. When they both succeed146* the second requests should be executed without calling the authenticator.147* The test succeeds if the authenticator was only called twice.148*/149class AuthenticationHandlerT1a implements HttpHandler150{151volatile int count = -1;152153@Override154public void handle(HttpExchange exchange) throws IOException {155count++;156try {157switch(count) {158case 0:159AuthenticationHandler.errorReply(exchange,160"Basic realm=\"realm1\"");161break;162case 1:163t1Cond1.await();164AuthenticationHandler.okReply(exchange);165break;166default:167System.out.println ("Unexpected request");168}169} catch (InterruptedException |170BrokenBarrierException e)171{172throw new RuntimeException(e);173}174}175}176177class AuthenticationHandlerT1b implements HttpHandler178{179volatile int count = -1;180181@Override182public void handle(HttpExchange exchange) throws IOException {183count++;184try {185switch(count) {186case 0:187AuthenticationHandler.errorReply(exchange,188"Basic realm=\"realm2\"");189break;190case 1:191t1Cond1.await();192AuthenticationHandler.okReply(exchange);193break;194default:195System.out.println ("Unexpected request");196}197} catch (InterruptedException | BrokenBarrierException e) {198throw new RuntimeException(e);199}200}201}202203class AuthenticationHandlerT1c implements HttpHandler204{205volatile int count = -1;206207@Override208public void handle(HttpExchange exchange) throws IOException {209count++;210switch(count) {211case 0:212AuthenticationHandler.errorReply(exchange,213"Basic realm=\"realm1\"");214break;215case 1:216AuthenticationHandler.okReply(exchange);217break;218default:219System.out.println ("Unexpected request");220}221}222}223224class AuthenticationHandlerT1d implements HttpHandler225{226volatile int count = -1;227228@Override229public void handle(HttpExchange exchange) throws IOException {230count++;231switch(count) {232case 0:233AuthenticationHandler.errorReply(exchange,234"Basic realm=\"realm2\"");235break;236case 1:237AuthenticationHandler.okReply(exchange);238break;239default:240System.out.println ("Unexpected request");241}242}243}244245/* T2 tests to check that if initial authentication fails, the second will246* succeed, and the authenticator is called twice247*/248249class AuthenticationHandlerT2a implements HttpHandler250{251volatile int count = -1;252253@Override254public void handle(HttpExchange exchange) throws IOException {255count++;256if (count == 1) {257t2condlatch.countDown();258}259AuthenticationHandler.errorReply(exchange,260"Basic realm=\"realm3\"");261262}263}264265class AuthenticationHandlerT2b implements HttpHandler266{267volatile int count = -1;268269@Override270public void handle(HttpExchange exchange) throws IOException {271count++;272switch(count) {273case 0:274AuthenticationHandler.errorReply(exchange,275"Basic realm=\"realm3\"");276break;277case 1:278AuthenticationHandler.okReply(exchange);279break;280default:281System.out.println ("Unexpected request");282}283}284}285286/* T3 tests proxy and server authentication. three threads request same287* resource at same time. Authenticator should be called once for server288* and once for proxy289*/290291class AuthenticationHandlerT3a implements HttpHandler292{293volatile int count = -1;294295@Override296public void handle(HttpExchange exchange) throws IOException {297count++;298switch(count) {299case 0:300AuthenticationHandler.proxyReply(exchange,301"Basic realm=\"proxy\"");302break;303case 1:304t3cond1.countDown();305AuthenticationHandler.errorReply(exchange,306"Basic realm=\"realm4\"");307break;308case 2:309AuthenticationHandler.okReply(exchange);310break;311default:312System.out.println ("Unexpected request");313}314}315}316317class AuthenticationHandlerT3bc implements HttpHandler318{319volatile int count = -1;320321@Override322public void handle(HttpExchange exchange) throws IOException {323count++;324switch(count) {325case 0:326AuthenticationHandler.proxyReply(exchange,327"Basic realm=\"proxy\"");328break;329case 1:330AuthenticationHandler.okReply(exchange);331break;332default:333System.out.println ("Unexpected request");334}335}336}337}338339static class AuthenticationHandler {340static void errorReply(HttpExchange exchange, String reply)341throws IOException342{343exchange.getResponseHeaders().add("Connection", "close");344exchange.getResponseHeaders().add("WWW-Authenticate", reply);345exchange.sendResponseHeaders(401, 0);346exchange.close();347}348349static void proxyReply (HttpExchange exchange, String reply)350throws IOException351{352exchange.getResponseHeaders().add("Proxy-Authenticate", reply);353exchange.sendResponseHeaders(407, 0);354}355356static void okReply (HttpExchange exchange) throws IOException {357exchange.getResponseHeaders().add("Connection", "close");358String response = "Hello .";359exchange.sendResponseHeaders(200, response.getBytes().length);360try (OutputStream os = exchange.getResponseBody()) {361os.write(response.getBytes());362}363exchange.close();364}365}366367static Server server;368static MyAuthenticator auth = new MyAuthenticator ();369370static int redirects = 4;371372static Client c1,c2,c3,c4,c5,c6,c7,c8,c9;373374static CountDownLatch t2condlatch;375static CountDownLatch t3cond1;376static CyclicBarrier t1Cond1;377378static void doServerTests (String authority, Server server) throws Exception379{380System.out.println ("Doing Server tests");381System.out.println ("T1");382c1 = new Client (authority, "/test/realm1/t1a", false);383c2 = new Client (authority, "/test/realm2/t1b", false);384c3 = new Client (authority, "/test/realm1/t1c", false);385c4 = new Client (authority, "/test/realm2/t1d", false);386c1.start(); c2.start();387t1Cond1.await();388c3.start(); c4.start();389c1.join(); c2.join(); c3.join(); c4.join();390391int f = auth.getCount();392if (f != 2) {393except ("Authenticator was called "+f+" times. Should be 2",394server);395}396if (error) {397except ("error occurred", server);398}399400auth.resetCount();401System.out.println ("T2");402403c5 = new Client (authority, "/test/realm3/t2a", true);404c6 = new Client (authority, "/test/realm3/t2b", false);405t2condlatch = new CountDownLatch(1);406c5.start ();407t2condlatch.await();408c6.start ();409c5.join(); c6.join();410411f = auth.getCount();412if (f != redirects+1) {413except ("Authenticator was called "+f+" times. Should be: "414+ redirects+1, server);415}416if (error) {417except ("error occurred", server);418}419}420421static void doProxyTests (String authority, Server server) throws Exception422{423System.out.println ("Doing Proxy tests");424c7 = new Client (authority, "/test/realm4/t3a", false);425c8 = new Client (authority, "/test/realm4/t3b", false);426c9 = new Client (authority, "/test/realm4/t3c", false);427t3cond1 = new CountDownLatch(1);428c7.start ();429t3cond1.await();430c8.start ();431c9.start ();432c7.join(); c8.join(); c9.join();433434int f = auth.getCount();435if (f != 2) {436except ("Authenticator was called "+f+" times. Should be: " + 2,437server);438}439if (error) {440except ("error occurred", server);441}442}443444public static void main (String[] args) throws Exception {445new B4769350().runTest(args[0].equals ("proxy"));446}447448public void runTest(boolean proxy) throws Exception {449System.setProperty ("http.maxRedirects", Integer.toString (redirects));450System.setProperty ("http.auth.serializeRequests", "true");451Authenticator.setDefault (auth);452try (Server server = new Server()) {453server.startServer();454System.out.println ("Server: listening on port: "455+ server.getPort());456if (proxy) {457System.setProperty ("http.proxyHost", "localhost");458System.setProperty ("http.proxyPort",459Integer.toString(server.getPort()));460doProxyTests ("www.foo.com", server);461} else {462doServerTests ("localhost:"+server.getPort(), server);463}464}465466}467468public static void except (String s, Server server) {469server.close();470throw new RuntimeException (s);471}472473static class MyAuthenticator extends Authenticator {474MyAuthenticator () {475super ();476}477478volatile int count = 0;479480@Override481public PasswordAuthentication getPasswordAuthentication () {482PasswordAuthentication pw;483pw = new PasswordAuthentication ("user", "pass1".toCharArray());484count ++;485return pw;486}487488public void resetCount () {489count = 0;490}491492public int getCount () {493return count;494}495}496}497498499500