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 33import com.sun.net.httpserver.BasicAuthenticator; 34import com.sun.net.httpserver.HttpContext; 35import com.sun.net.httpserver.HttpExchange; 36import com.sun.net.httpserver.HttpHandler; 37import com.sun.net.httpserver.HttpServer; 38import java.io.IOException; 39import java.io.InputStream; 40import java.io.OutputStream; 41import java.net.InetSocketAddress; 42import java.net.PasswordAuthentication; 43import java.net.URI; 44import jdk.incubator.http.*; 45import java.util.concurrent.ExecutorService; 46import java.util.concurrent.Executors; 47import static java.nio.charset.StandardCharsets.US_ASCII; 48import static jdk.incubator.http.HttpRequest.BodyProcessor.fromString; 49import static jdk.incubator.http.HttpResponse.BodyHandler.asString; 50 51public 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} 162