1 /*
   2  * Copyright (c) 2015, 2016, 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.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  */
  24 
  25 /**
  26  * @test
  27  * @bug 8087112
  28  * @modules java.httpclient
  29  *          jdk.httpserver
  30  * @run main/othervm BasicAuthTest
  31  * @summary Basic Authentication Test
  32  */
  33 
  34 import com.sun.net.httpserver.BasicAuthenticator;
  35 import com.sun.net.httpserver.HttpContext;
  36 import com.sun.net.httpserver.HttpExchange;
  37 import com.sun.net.httpserver.HttpHandler;
  38 import com.sun.net.httpserver.HttpServer;
  39 import java.io.IOException;
  40 import java.io.InputStream;
  41 import java.io.OutputStream;
  42 import java.net.InetSocketAddress;
  43 import java.net.PasswordAuthentication;
  44 import java.net.URI;
  45 import java.net.http.*;
  46 import java.util.concurrent.ExecutorService;
  47 import java.util.concurrent.Executors;
  48 import static java.nio.charset.StandardCharsets.US_ASCII;
  49 
  50 public class BasicAuthTest {
  51 
  52     static volatile boolean ok;
  53     static final String RESPONSE = "Hello world";
  54     static final String POST_BODY = "This is the POST body 123909090909090";
  55 
  56     public static void main(String[] args) throws Exception {
  57         HttpServer server = HttpServer.create(new InetSocketAddress(0), 10);
  58         ExecutorService e = Executors.newCachedThreadPool();
  59         Handler h = new Handler();
  60         HttpContext serverContext = server.createContext("/test", h);
  61         int port = server.getAddress().getPort();
  62         System.out.println("Server port = " + port);
  63 
  64         ClientAuth ca = new ClientAuth();
  65         ServerAuth sa = new ServerAuth("foo realm");
  66         serverContext.setAuthenticator(sa);
  67         server.setExecutor(e);
  68         server.start();
  69         HttpClient client = HttpClient.create()
  70                                       .authenticator(ca)
  71                                       .build();
  72 
  73         try {
  74             URI uri = new URI("http://127.0.0.1:" + Integer.toString(port) + "/test/foo");
  75             HttpRequest req = client.request(uri).GET();
  76 
  77             HttpResponse resp = req.response();
  78             ok = resp.statusCode() == 200 &&
  79                     resp.body(HttpResponse.asString()).equals(RESPONSE);
  80 
  81             if (!ok || ca.count != 1)
  82                 throw new RuntimeException("Test failed");
  83 
  84             // repeat same request, should succeed but no additional authenticator calls
  85 
  86             req = client.request(uri).GET();
  87             resp = req.response();
  88             ok = resp.statusCode() == 200 &&
  89                     resp.body(HttpResponse.asString()).equals(RESPONSE);
  90 
  91             if (!ok || ca.count != 1)
  92                 throw new RuntimeException("Test failed");
  93 
  94             // try a POST
  95 
  96             req = client.request(uri)
  97                     .body(HttpRequest.fromString(POST_BODY))
  98                     .POST();
  99             resp = req.response();
 100             ok = resp.statusCode() == 200;
 101 
 102             if (!ok || ca.count != 1)
 103                 throw new RuntimeException("Test failed");
 104         } finally {
 105             client.executorService().shutdownNow();
 106             server.stop(0);
 107             e.shutdownNow();
 108         }
 109         System.out.println("OK");
 110     }
 111 
 112     static class ServerAuth extends BasicAuthenticator {
 113 
 114         ServerAuth(String realm) {
 115             super(realm);
 116         }
 117 
 118         @Override
 119         public boolean checkCredentials(String username, String password) {
 120             if (!"user".equals(username) || !"passwd".equals(password)) {
 121                 return false;
 122             }
 123             return true;
 124         }
 125 
 126     }
 127 
 128     static class ClientAuth extends java.net.Authenticator {
 129         volatile int count = 0;
 130 
 131         @Override
 132         protected PasswordAuthentication getPasswordAuthentication() {
 133             count++;
 134             return new PasswordAuthentication("user", "passwd".toCharArray());
 135         }
 136     }
 137 
 138    static class Handler implements HttpHandler {
 139         static volatile boolean ok;
 140 
 141         @Override
 142         public void handle(HttpExchange he) throws IOException {
 143             String method = he.getRequestMethod();
 144             InputStream is = he.getRequestBody();
 145             if (method.equalsIgnoreCase("POST")) {
 146                 String requestBody = new String(is.readAllBytes(), US_ASCII);
 147                 if (!requestBody.equals(POST_BODY)) {
 148                     he.sendResponseHeaders(500, -1);
 149                     ok = false;
 150                 } else {
 151                     he.sendResponseHeaders(200, -1);
 152                     ok = true;
 153                 }
 154             } else { // GET
 155                 he.sendResponseHeaders(200, RESPONSE.length());
 156                 OutputStream os = he.getResponseBody();
 157                 os.write(RESPONSE.getBytes(US_ASCII));
 158                 os.close();
 159                 ok = true;
 160             }
 161         }
 162 
 163    }
 164 }