Path: blob/master/test/jdk/java/net/Authenticator/B4933582.java
41149 views
/*1* Copyright (c) 2003, 2021, 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// Note: this test saves a cache.ser file in the scratch directory,24// which the cache implementation will load its configuration25// from. Therefore adding several @run lines does not work.2627/*28* @test29* @bug 493358230* @key intermittent31* @library /test/lib32* @modules java.base/sun.net.www33* java.base/sun.net.www.protocol.http34*35* @run main/othervm B493358236*/3738import java.io.File;39import java.io.FileInputStream;40import java.io.FileOutputStream;41import java.io.IOException;42import java.io.InputStream;43import java.io.ObjectInputStream;44import java.io.ObjectOutputStream;45import java.io.PrintWriter;46import java.net.Authenticator;47import java.net.BindException;48import java.net.InetAddress;49import java.net.InetSocketAddress;50import java.net.PasswordAuthentication;51import java.net.ProxySelector;52import java.net.URL;53import java.net.URLConnection;54import java.util.HashMap;55import java.util.LinkedList;56import java.util.concurrent.Executors;5758import com.sun.net.httpserver.HttpExchange;59import com.sun.net.httpserver.HttpHandler;60import com.sun.net.httpserver.HttpServer;61import jdk.test.lib.net.URIBuilder;62import sun.net.www.protocol.http.AuthCacheImpl;63import sun.net.www.protocol.http.AuthCacheValue;6465public class B4933582 implements HttpHandler {6667static int count = 0;68static String authstring;6970void errorReply (HttpExchange req, String reply) throws IOException {71req.getResponseHeaders().set("Connection", "close");72req.getResponseHeaders().set("WWW-Authenticate", reply);73req.sendResponseHeaders(401, -1);74}7576void okReply (HttpExchange req) throws IOException {77req.sendResponseHeaders(200, 0);78try(PrintWriter pw = new PrintWriter(req.getResponseBody())) {79pw.print("Hello .");80}81}8283static volatile boolean firstTime = true;8485public void handle (HttpExchange req) {86try {87if(req.getRequestHeaders().get("Authorization") != null) {88authstring = req.getRequestHeaders().get("Authorization").get(0);89System.out.println(authstring);90}91if (firstTime) {92switch (count) {93case 0:94errorReply (req, "Basic realm=\"wallyworld\"");95break;96case 1:97/* client stores a username/pw for wallyworld98*/99save (authstring);100okReply (req);101break;102}103} else {104/* check the auth string is premptively set from last time */105String savedauth = retrieve();106if (savedauth.equals (authstring)) {107okReply (req);108} else {109System.out.println ("savedauth = " + savedauth);110System.out.println ("authstring = " + authstring);111errorReply (req, "Basic realm=\"wallyworld\"");112}113}114count ++;115} catch (IOException e) {116e.printStackTrace();117}118}119120void save (String s) {121try {122FileOutputStream f = new FileOutputStream ("auth.save");123ObjectOutputStream os = new ObjectOutputStream (f);124os.writeObject (s);125} catch (IOException e) {126assert false;127}128}129130String retrieve () {131String s = null;132try {133FileInputStream f = new FileInputStream ("auth.save");134ObjectInputStream is = new ObjectInputStream (f);135s = (String) is.readObject();136} catch (Exception e) {137assert false;138}139return s;140}141142static void read (InputStream is) throws IOException {143int c;144System.out.println ("reading");145while ((c=is.read()) != -1) {146System.out.write (c);147}148System.out.println ("");149System.out.println ("finished reading");150}151152static void client (String u) throws Exception {153URL url = new URL (u);154System.out.println ("client opening connection to: " + u);155URLConnection urlc = url.openConnection ();156try(InputStream is = urlc.getInputStream ()) {157read (is);158}159}160161static HttpServer server;162163public static void main (String[] args) throws Exception {164B4933582 b4933582 = new B4933582();165MyAuthenticator auth = new MyAuthenticator ();166Authenticator.setDefault (auth);167ProxySelector.setDefault(ProxySelector.of(null)); // no proxy168InetAddress loopback = InetAddress.getLoopbackAddress();169CacheImpl cache;170try {171server = HttpServer.create(new InetSocketAddress(loopback, 0), 10);172server.createContext("/", b4933582);173server.setExecutor(Executors.newSingleThreadExecutor());174server.start();175cache = new CacheImpl (server.getAddress().getPort());176AuthCacheValue.setAuthCache (cache);177String serverURL = URIBuilder.newBuilder()178.scheme("http")179.loopback()180.port(server.getAddress().getPort())181.path("/")182.build()183.toString();184client(serverURL + "d1/foo.html");185} finally {186if (server != null) {187server.stop(1);188}189}190191int f = auth.getCount();192if (f != 1) {193except("Authenticator was called " + f + " times. Should be 1");194}195196firstTime = false;197198int retries = 0;199cache = new CacheImpl();200while (true) {201try {202server = HttpServer.create(new InetSocketAddress(loopback, cache.getPort()), 10);203server.createContext("/", b4933582);204server.setExecutor(Executors.newSingleThreadExecutor());205server.start();206break;207} catch (BindException e) {208if (retries++ < 5) {209Thread.sleep(200L);210System.out.println("BindException \"" + e.getMessage()211+ "\", retrying...");212continue;213} else {214throw e;215}216}217}218219try {220AuthCacheValue.setAuthCache(cache);221String serverURL = URIBuilder.newBuilder()222.scheme("http")223.loopback()224.port(server.getAddress().getPort())225.path("/")226.build()227.toString();228client(serverURL + "d1/foo.html");229} finally {230if (server != null) {231server.stop(1);232}233}234235f = auth.getCount();236if (f != 1) {237except("Authenticator was called " + f + " times. Should be 1");238}239}240241public static void except (String s) {242server.stop(1);243throw new RuntimeException (s);244}245246static class MyAuthenticator extends Authenticator {247MyAuthenticator () {248super ();249}250251volatile int count = 0;252253public PasswordAuthentication getPasswordAuthentication () {254PasswordAuthentication pw;255pw = new PasswordAuthentication ("user", "pass1".toCharArray());256count ++;257return pw;258}259260public int getCount () {261return (count);262}263}264265static class CacheImpl extends AuthCacheImpl {266HashMap<String,LinkedList<AuthCacheValue>> map;267int port; // need to store the port number the server is using268269CacheImpl () throws IOException {270this (-1);271}272273CacheImpl (int port) throws IOException {274super();275this.port = port;276File src = new File ("cache.ser");277if (src.exists()) {278try (ObjectInputStream is = new ObjectInputStream(279new FileInputStream(src))) {280map = (HashMap<String,LinkedList<AuthCacheValue>>)is281.readObject();282this.port = (Integer)is.readObject ();283System.out.println ("read port from file " + port);284} catch (ClassNotFoundException e) {285assert false;286}287System.out.println ("setMap from cache.ser");288} else {289map = new HashMap<>();290}291setMap (map);292}293294int getPort () {295return port;296}297298private void writeMap () {299File dst = new File("cache.ser");300try {301dst.delete();302if (!dst.createNewFile()) {303return;304}305} catch (IOException e) {306}307308try (ObjectOutputStream os = new ObjectOutputStream(309new FileOutputStream(dst))) {310os.writeObject(map);311os.writeObject(port);312System.out.println("wrote port " + port);313} catch (IOException e) {314}315}316317public void put (String pkey, AuthCacheValue value) {318System.out.println ("put: " + pkey + " " + value);319super.put (pkey, value);320writeMap();321}322323public AuthCacheValue get (String pkey, String skey) {324System.out.println ("get: " + pkey + " " + skey);325AuthCacheValue i = super.get (pkey, skey);326System.out.println ("---> " + i);327return i;328}329330public void remove (String pkey, AuthCacheValue value) {331System.out.println ("remove: " + pkey + " " + value);332super.remove (pkey, value);333writeMap();334}335}336}337338339