/* * 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(); } } }