jdk/test/java/net/HttpURLConnection/SetAuthenticator/HTTPTestServer.java
changeset 43508 6b8bca7f0cee
parent 42351 85ed90be0ae1
equal deleted inserted replaced
43507:71265fdc85d1 43508:6b8bca7f0cee
    48 import java.net.Socket;
    48 import java.net.Socket;
    49 import java.net.URL;
    49 import java.net.URL;
    50 import java.security.MessageDigest;
    50 import java.security.MessageDigest;
    51 import java.security.NoSuchAlgorithmException;
    51 import java.security.NoSuchAlgorithmException;
    52 import java.time.Instant;
    52 import java.time.Instant;
       
    53 import java.util.ArrayList;
    53 import java.util.Arrays;
    54 import java.util.Arrays;
    54 import java.util.Base64;
    55 import java.util.Base64;
    55 import java.util.List;
    56 import java.util.List;
    56 import java.util.Objects;
    57 import java.util.Objects;
    57 import java.util.Random;
    58 import java.util.Random;
       
    59 import java.util.concurrent.CopyOnWriteArrayList;
    58 import java.util.stream.Collectors;
    60 import java.util.stream.Collectors;
    59 import javax.net.ssl.SSLContext;
    61 import javax.net.ssl.SSLContext;
    60 import sun.net.www.HeaderParser;
    62 import sun.net.www.HeaderParser;
    61 
    63 
    62 /**
    64 /**
   143             default:
   145             default:
   144                 throw new InternalError("Unknown server type: " + authType);
   146                 throw new InternalError("Unknown server type: " + authType);
   145         }
   147         }
   146     }
   148     }
   147 
   149 
       
   150     /**
       
   151      * The HttpServerFactory ensures that the local port used by an HttpServer
       
   152      * previously created by the current test/VM will not get reused by
       
   153      * a subsequent test in the same VM. This is to avoid having the
       
   154      * AuthCache reuse credentials from previous tests - which would
       
   155      * invalidate the assumptions made by the current test on when
       
   156      * the default authenticator should be called.
       
   157      */
       
   158     private static final class HttpServerFactory {
       
   159         private static final int MAX = 10;
       
   160         private static final CopyOnWriteArrayList<String> addresses =
       
   161             new CopyOnWriteArrayList<>();
       
   162         private static HttpServer newHttpServer(HttpProtocolType protocol)
       
   163                 throws IOException {
       
   164             switch (protocol) {
       
   165                case HTTP:  return HttpServer.create();
       
   166                case HTTPS: return HttpsServer.create();
       
   167                default: throw new InternalError("Unsupported protocol " + protocol);
       
   168             }
       
   169         }
       
   170         static <T extends HttpServer> T create(HttpProtocolType protocol)
       
   171                 throws IOException {
       
   172             final int max = addresses.size() + MAX;
       
   173             final List<HttpServer> toClose = new ArrayList<>();
       
   174             try {
       
   175                 for (int i = 1; i <= max; i++) {
       
   176                     HttpServer server = newHttpServer(protocol);
       
   177                     server.bind(new InetSocketAddress("127.0.0.1", 0), 0);
       
   178                     InetSocketAddress address = server.getAddress();
       
   179                     String key = address.toString();
       
   180                     if (addresses.addIfAbsent(key)) {
       
   181                        System.out.println("Server bound to: " + key
       
   182                                           + " after " + i + " attempt(s)");
       
   183                        return (T) server;
       
   184                     }
       
   185                     System.out.println("warning: address " + key
       
   186                                        + " already used. Retrying bind.");
       
   187                     // keep the port bound until we get a port that we haven't
       
   188                     // used already
       
   189                     toClose.add(server);
       
   190                 }
       
   191             } finally {
       
   192                 // if we had to retry, then close the servers we're not
       
   193                 // going to use.
       
   194                 for (HttpServer s : toClose) {
       
   195                   try { s.stop(1); } catch (Exception x) { /* ignore */ }
       
   196                 }
       
   197             }
       
   198             throw new IOException("Couldn't bind servers after " + max + " attempts: "
       
   199                                   + "addresses used before: " + addresses);
       
   200         }
       
   201     }
       
   202 
   148     static HttpServer createHttpServer(HttpProtocolType protocol) throws IOException {
   203     static HttpServer createHttpServer(HttpProtocolType protocol) throws IOException {
   149         switch (protocol) {
   204         switch (protocol) {
   150             case HTTP:  return HttpServer.create();
   205             case HTTP:  return HttpServerFactory.create(protocol);
   151             case HTTPS: return configure(HttpsServer.create());
   206             case HTTPS: return configure(HttpServerFactory.create(protocol));
   152             default: throw new InternalError("Unsupported protocol " + protocol);
   207             default: throw new InternalError("Unsupported protocol " + protocol);
   153         }
   208         }
   154     }
   209     }
   155 
   210 
   156     static HttpsServer configure(HttpsServer server) throws IOException {
   211     static HttpsServer configure(HttpsServer server) throws IOException {
   191         HttpServer impl = createHttpServer(protocol);
   246         HttpServer impl = createHttpServer(protocol);
   192         final HTTPTestServer server = new HTTPTestServer(impl, null, delegate);
   247         final HTTPTestServer server = new HTTPTestServer(impl, null, delegate);
   193         final HttpHandler hh = server.createHandler(schemeType, auth, authType);
   248         final HttpHandler hh = server.createHandler(schemeType, auth, authType);
   194         HttpContext ctxt = impl.createContext(path, hh);
   249         HttpContext ctxt = impl.createContext(path, hh);
   195         server.configureAuthentication(ctxt, schemeType, auth, authType);
   250         server.configureAuthentication(ctxt, schemeType, auth, authType);
   196         impl.bind(new InetSocketAddress("127.0.0.1", 0), 0);
       
   197         impl.start();
   251         impl.start();
   198         return server;
   252         return server;
   199     }
   253     }
   200 
   254 
   201     public static HTTPTestServer createProxy(HttpProtocolType protocol,
   255     public static HTTPTestServer createProxy(HttpProtocolType protocol,
   213                 ? new HttpsProxyTunnel(impl, null, delegate)
   267                 ? new HttpsProxyTunnel(impl, null, delegate)
   214                 : new HTTPTestServer(impl, null, delegate);
   268                 : new HTTPTestServer(impl, null, delegate);
   215         final HttpHandler hh = server.createHandler(schemeType, auth, authType);
   269         final HttpHandler hh = server.createHandler(schemeType, auth, authType);
   216         HttpContext ctxt = impl.createContext(path, hh);
   270         HttpContext ctxt = impl.createContext(path, hh);
   217         server.configureAuthentication(ctxt, schemeType, auth, authType);
   271         server.configureAuthentication(ctxt, schemeType, auth, authType);
   218 
       
   219         impl.bind(new InetSocketAddress("127.0.0.1", 0), 0);
       
   220         impl.start();
   272         impl.start();
   221 
   273 
   222         return server;
   274         return server;
   223     }
   275     }
   224 
   276 
   251         InetSocketAddress redirectAddr = redirectTarget.getAddress();
   303         InetSocketAddress redirectAddr = redirectTarget.getAddress();
   252         URL locationURL = url(targetProtocol, redirectAddr, "/");
   304         URL locationURL = url(targetProtocol, redirectAddr, "/");
   253         final HttpHandler hh = redirectingServer.create300Handler(locationURL,
   305         final HttpHandler hh = redirectingServer.create300Handler(locationURL,
   254                                              HttpAuthType.SERVER, code300);
   306                                              HttpAuthType.SERVER, code300);
   255         impl.createContext("/", hh);
   307         impl.createContext("/", hh);
   256         impl.bind(new InetSocketAddress("127.0.0.1", 0), 0);
       
   257         impl.start();
   308         impl.start();
   258         return redirectingServer;
   309         return redirectingServer;
   259     }
   310     }
   260 
   311 
   261     public InetSocketAddress getAddress() {
   312     public InetSocketAddress getAddress() {