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.
   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 8087112
  27  * @modules jdk.incubator.httpclient
  28  *          jdk.httpserver
  29  * @run main/othervm BasicAuthTest
  30  * @summary Basic Authentication Test
  31  */
  32 
  33 import com.sun.net.httpserver.BasicAuthenticator;
  34 import com.sun.net.httpserver.HttpContext;
  35 import com.sun.net.httpserver.HttpExchange;
  36 import com.sun.net.httpserver.HttpHandler;
  37 import com.sun.net.httpserver.HttpServer;
  38 import java.io.IOException;
  39 import java.io.InputStream;
  40 import java.io.OutputStream;
  41 import java.net.InetSocketAddress;
  42 import java.net.PasswordAuthentication;
  43 import java.net.URI;
  44 import jdk.incubator.http.*;
  45 import java.util.concurrent.ExecutorService;
  46 import java.util.concurrent.Executors;
  47 import static java.nio.charset.StandardCharsets.US_ASCII;
  48 import static jdk.incubator.http.HttpRequest.BodyProcessor.fromString;
  49 import static jdk.incubator.http.HttpResponse.BodyHandler.asString;
  50 
  51 public class BasicAuthTest {
  52 
  53     static volatile boolean ok;
  54     static final String RESPONSE = "Hello world";
  55     static final String POST_BODY = "This is the POST body 123909090909090";
  56 
  57     public static void main(String[] args) throws Exception {
  58         HttpServer server = HttpServer.create(new InetSocketAddress(0), 10);
  59         ExecutorService e = Executors.newCachedThreadPool();
  60         Handler h = new Handler();
  61         HttpContext serverContext = server.createContext("/test", h);
  62         int port = server.getAddress().getPort();
  63         System.out.println("Server port = " + port);
  64 
  65         ClientAuth ca = new ClientAuth();
  66         ServerAuth sa = new ServerAuth("foo realm");
  67         serverContext.setAuthenticator(sa);
  68         server.setExecutor(e);
  69         server.start();
  70         HttpClient client = HttpClient.newBuilder()
  71                                       .authenticator(ca)
  72                                       .build();
  73 
  74         try {
  75             URI uri = new URI("http://127.0.0.1:" + Integer.toString(port) + "/test/foo");
  76             HttpRequest req = HttpRequest.newBuilder(uri).GET().build();
  77 
  78             HttpResponse resp = client.send(req, asString());
  79             ok = resp.statusCode() == 200 && resp.body().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             resp = client.send(req, asString());
  87             ok = resp.statusCode() == 200 && resp.body().equals(RESPONSE);
  88 
  89             if (!ok || ca.count != 1)
  90                 throw new RuntimeException("Test failed");
  91 
  92             // try a POST
  93 
  94             req = HttpRequest.newBuilder(uri)
  95                              .POST(fromString(POST_BODY))
  96                              .build();
  97             resp = client.send(req, asString());
  98             ok = resp.statusCode() == 200;
  99 
 100             if (!ok || ca.count != 1)
 101                 throw new RuntimeException("Test failed");
 102         } finally {
 103             server.stop(0);
 104             e.shutdownNow();
 105         }
 106         System.out.println("OK");
 107     }
 108 
 109     static class ServerAuth extends BasicAuthenticator {
 110 
 111         ServerAuth(String realm) {
 112             super(realm);
 113         }
 114 
 115         @Override
 116         public boolean checkCredentials(String username, String password) {
 117             if (!"user".equals(username) || !"passwd".equals(password)) {
 118                 return false;
 119             }
 120             return true;
 121         }
 122 
 123     }
 124 
 125     static class ClientAuth extends java.net.Authenticator {
 126         volatile int count = 0;
 127 
 128         @Override
 129         protected PasswordAuthentication getPasswordAuthentication() {
 130             count++;
 131             return new PasswordAuthentication("user", "passwd".toCharArray());
 132         }
 133     }
 134 
 135    static class Handler implements HttpHandler {
 136         static volatile boolean ok;
 137 
 138         @Override
 139         public void handle(HttpExchange he) throws IOException {
 140             String method = he.getRequestMethod();
 141             InputStream is = he.getRequestBody();
 142             if (method.equalsIgnoreCase("POST")) {
 143                 String requestBody = new String(is.readAllBytes(), US_ASCII);
 144                 if (!requestBody.equals(POST_BODY)) {
 145                     he.sendResponseHeaders(500, -1);
 146                     ok = false;
 147                 } else {
 148                     he.sendResponseHeaders(200, -1);
 149                     ok = true;
 150                 }
 151             } else { // GET
 152                 he.sendResponseHeaders(200, RESPONSE.length());
 153                 OutputStream os = he.getResponseBody();
 154                 os.write(RESPONSE.getBytes(US_ASCII));
 155                 os.close();
 156                 ok = true;
 157             }
 158         }
 159 
 160    }
 161 }