| /* |
| * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved. |
| * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
| * |
| * This code is free software; you can redistribute it and/or modify it |
| * under the terms of the GNU General Public License version 2 only, as |
| * published by the Free Software Foundation. |
| * |
| * This code is distributed in the hope that it will be useful, but WITHOUT |
| * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
| * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
| * version 2 for more details (a copy is included in the LICENSE file that |
| * accompanied this code). |
| * |
| * You should have received a copy of the GNU General Public License version |
| * 2 along with this work; if not, write to the Free Software Foundation, |
| * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
| * |
| * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
| * or visit www.oracle.com if you need additional information or have any |
| * questions. |
| */ |
| |
| /** |
| * library /lib/testlibrary/ / |
| * build jdk.testlibrary.SimpleSSLContext ProxyServer EchoHandler |
| * compile ../../../com/sun/net/httpserver/LogFilter.java |
| * compile ../../../com/sun/net/httpserver/FileServerHandler.java |
| */ |
| import com.sun.net.httpserver.Headers; |
| import com.sun.net.httpserver.HttpContext; |
| import com.sun.net.httpserver.HttpExchange; |
| import com.sun.net.httpserver.HttpHandler; |
| import com.sun.net.httpserver.HttpServer; |
| import com.sun.net.httpserver.HttpsConfigurator; |
| import com.sun.net.httpserver.HttpsServer; |
| import java.io.IOException; |
| import java.io.InputStream; |
| import java.io.OutputStream; |
| import java.net.InetSocketAddress; |
| import java.nio.file.Path; |
| import java.util.HashSet; |
| import java.util.concurrent.BrokenBarrierException; |
| import java.util.concurrent.CyclicBarrier; |
| import java.util.concurrent.ExecutorService; |
| import java.util.concurrent.Executors; |
| import java.util.logging.ConsoleHandler; |
| import java.util.logging.Level; |
| import java.util.logging.Logger; |
| import javax.net.ssl.SSLContext; |
| import jdk.testlibrary.SimpleSSLContext; |
| |
| public class LightWeightHttpServer { |
| |
| static SSLContext ctx; |
| static HttpServer httpServer; |
| static HttpsServer httpsServer; |
| static ExecutorService executor; |
| static int port; |
| static int httpsport; |
| static String httproot; |
| static String httpsroot; |
| static ProxyServer proxy; |
| static int proxyPort; |
| static RedirectErrorHandler redirectErrorHandler, redirectErrorHandlerSecure; |
| static RedirectHandler redirectHandler, redirectHandlerSecure; |
| static DelayHandler delayHandler; |
| static final String midSizedFilename = "/files/notsobigfile.txt"; |
| static final String smallFilename = "/files/smallfile.txt"; |
| static Path midSizedFile; |
| static Path smallFile; |
| static String fileroot; |
| |
| public static void initServer() throws IOException { |
| |
| Logger logger = Logger.getLogger("com.sun.net.httpserver"); |
| ConsoleHandler ch = new ConsoleHandler(); |
| logger.setLevel(Level.ALL); |
| ch.setLevel(Level.ALL); |
| logger.addHandler(ch); |
| |
| String root = System.getProperty("test.src") + "/docs"; |
| InetSocketAddress addr = new InetSocketAddress(0); |
| httpServer = HttpServer.create(addr, 0); |
| if (httpServer instanceof HttpsServer) { |
| throw new RuntimeException("should not be httpsserver"); |
| } |
| httpsServer = HttpsServer.create(addr, 0); |
| HttpHandler h = new FileServerHandler(root); |
| |
| HttpContext c1 = httpServer.createContext("/files", h); |
| HttpContext c2 = httpsServer.createContext("/files", h); |
| HttpContext c3 = httpServer.createContext("/echo", new EchoHandler()); |
| redirectHandler = new RedirectHandler("/redirect"); |
| redirectHandlerSecure = new RedirectHandler("/redirect"); |
| HttpContext c4 = httpServer.createContext("/redirect", redirectHandler); |
| HttpContext c41 = httpsServer.createContext("/redirect", redirectHandlerSecure); |
| HttpContext c5 = httpsServer.createContext("/echo", new EchoHandler()); |
| HttpContext c6 = httpServer.createContext("/keepalive", new KeepAliveHandler()); |
| redirectErrorHandler = new RedirectErrorHandler("/redirecterror"); |
| redirectErrorHandlerSecure = new RedirectErrorHandler("/redirecterror"); |
| HttpContext c7 = httpServer.createContext("/redirecterror", redirectErrorHandler); |
| HttpContext c71 = httpsServer.createContext("/redirecterror", redirectErrorHandlerSecure); |
| delayHandler = new DelayHandler(); |
| HttpContext c8 = httpServer.createContext("/delay", delayHandler); |
| HttpContext c81 = httpsServer.createContext("/delay", delayHandler); |
| |
| executor = Executors.newCachedThreadPool(); |
| httpServer.setExecutor(executor); |
| httpsServer.setExecutor(executor); |
| ctx = new SimpleSSLContext().get(); |
| httpsServer.setHttpsConfigurator(new HttpsConfigurator(ctx)); |
| httpServer.start(); |
| httpsServer.start(); |
| |
| port = httpServer.getAddress().getPort(); |
| System.out.println("HTTP server port = " + port); |
| httpsport = httpsServer.getAddress().getPort(); |
| System.out.println("HTTPS server port = " + httpsport); |
| httproot = "http://127.0.0.1:" + port + "/"; |
| httpsroot = "https://127.0.0.1:" + httpsport + "/"; |
| |
| proxy = new ProxyServer(0, false); |
| proxyPort = proxy.getPort(); |
| System.out.println("Proxy port = " + proxyPort); |
| } |
| |
| public static void stop() throws IOException { |
| if (httpServer != null) { |
| httpServer.stop(0); |
| } |
| if (httpsServer != null) { |
| httpsServer.stop(0); |
| } |
| if (proxy != null) { |
| proxy.close(); |
| } |
| if (executor != null) { |
| executor.shutdownNow(); |
| } |
| } |
| |
| static class RedirectErrorHandler implements HttpHandler { |
| |
| String root; |
| volatile int count = 1; |
| |
| RedirectErrorHandler(String root) { |
| this.root = root; |
| } |
| |
| synchronized int count() { |
| return count; |
| } |
| |
| synchronized void increment() { |
| count++; |
| } |
| |
| @Override |
| public synchronized void handle(HttpExchange t) |
| throws IOException { |
| byte[] buf = new byte[2048]; |
| try (InputStream is = t.getRequestBody()) { |
| while (is.read(buf) != -1) ; |
| } |
| |
| Headers map = t.getResponseHeaders(); |
| String redirect = root + "/foo/" + Integer.toString(count); |
| increment(); |
| map.add("Location", redirect); |
| t.sendResponseHeaders(301, -1); |
| t.close(); |
| } |
| } |
| |
| static class RedirectHandler implements HttpHandler { |
| |
| String root; |
| volatile int count = 0; |
| |
| RedirectHandler(String root) { |
| this.root = root; |
| } |
| |
| @Override |
| public synchronized void handle(HttpExchange t) |
| throws IOException { |
| byte[] buf = new byte[2048]; |
| try (InputStream is = t.getRequestBody()) { |
| while (is.read(buf) != -1) ; |
| } |
| |
| Headers map = t.getResponseHeaders(); |
| |
| if (count++ < 1) { |
| map.add("Location", root + "/foo/" + count); |
| } else { |
| map.add("Location", SmokeTest.midSizedFilename); |
| } |
| t.sendResponseHeaders(301, -1); |
| t.close(); |
| } |
| |
| int count() { |
| return count; |
| } |
| |
| void reset() { |
| count = 0; |
| } |
| } |
| |
| static class KeepAliveHandler implements HttpHandler { |
| |
| volatile int counter = 0; |
| HashSet<Integer> portSet = new HashSet<>(); |
| volatile int[] ports = new int[4]; |
| |
| void sleep(int n) { |
| try { |
| Thread.sleep(n); |
| } catch (InterruptedException e) { |
| } |
| } |
| |
| @Override |
| public synchronized void handle(HttpExchange t) |
| throws IOException { |
| int remotePort = t.getRemoteAddress().getPort(); |
| String result = "OK"; |
| |
| int n = counter++; |
| /// First test |
| if (n < 4) { |
| ports[n] = remotePort; |
| } |
| if (n == 3) { |
| // check all values in ports[] are the same |
| if (ports[0] != ports[1] || ports[2] != ports[3] |
| || ports[0] != ports[2]) { |
| result = "Error " + Integer.toString(n); |
| System.out.println(result); |
| } |
| } |
| // Second test |
| if (n >= 4 && n < 8) { |
| // delay to ensure ports are different |
| sleep(500); |
| ports[n - 4] = remotePort; |
| } |
| if (n == 7) { |
| // should be all different |
| if (ports[0] == ports[1] || ports[2] == ports[3] |
| || ports[0] == ports[2]) { |
| result = "Error " + Integer.toString(n); |
| System.out.println(result); |
| System.out.printf("Ports: %d, %d, %d, %d\n", |
| ports[0], ports[1], ports[2], ports[3]); |
| } |
| // setup for third test |
| for (int i = 0; i < 4; i++) { |
| portSet.add(ports[i]); |
| } |
| } |
| // Third test |
| if (n > 7) { |
| // just check that port is one of the ones in portSet |
| if (!portSet.contains(remotePort)) { |
| System.out.println("UNEXPECTED REMOTE PORT " + remotePort); |
| result = "Error " + Integer.toString(n); |
| System.out.println(result); |
| } |
| } |
| byte[] buf = new byte[2048]; |
| |
| try (InputStream is = t.getRequestBody()) { |
| while (is.read(buf) != -1) ; |
| } |
| t.sendResponseHeaders(200, result.length()); |
| OutputStream o = t.getResponseBody(); |
| o.write(result.getBytes("US-ASCII")); |
| t.close(); |
| } |
| } |
| |
| static class DelayHandler implements HttpHandler { |
| |
| CyclicBarrier bar1 = new CyclicBarrier(2); |
| CyclicBarrier bar2 = new CyclicBarrier(2); |
| CyclicBarrier bar3 = new CyclicBarrier(2); |
| |
| CyclicBarrier barrier1() { |
| return bar1; |
| } |
| |
| CyclicBarrier barrier2() { |
| return bar2; |
| } |
| |
| @Override |
| public synchronized void handle(HttpExchange he) throws IOException { |
| byte[] buf = Util.readAll(he.getRequestBody()); |
| try { |
| bar1.await(); |
| bar2.await(); |
| } catch (InterruptedException | BrokenBarrierException e) { |
| } |
| he.sendResponseHeaders(200, -1); // will probably fail |
| he.close(); |
| } |
| } |
| } |