/* WebServerTestHelper.java v0.3 (1/18/2018) Tiny standalone Java web server to aid with JUnit tests. Creates randomly-generated sub-directories, and indicates once they have been accessed by a remote host (and what the IP address of the remote host is). */ package bort.millipede.wlt3.tests; import com.sun.net.httpserver.HttpServer; import com.sun.net.httpserver.HttpHandler; import com.sun.net.httpserver.HttpExchange; import com.sun.net.httpserver.Headers; import java.net.InetSocketAddress; import java.io.OutputStream; import java.io.IOException; import java.util.Hashtable; import java.security.SecureRandom; public class WebServerTestHelper { private HttpServer hs; private int port; private SecureRandom sr; private Hashtable<String,String> accessList; private static final int DEFAULT_PORT = 8080; public WebServerTestHelper() throws IOException, IllegalArgumentException { port = DEFAULT_PORT; String inPort = System.getProperty("wlt3.test.server.port"); if(inPort!=null && !inPort.isEmpty()) { try { inPort = inPort.trim(); port = Integer.parseInt(inPort); if((port<1) || (port>65535)) { throw new IllegalArgumentException("\""+inPort+"\" is not a valid TCP port for standalone web server listener! Valid TCP ports: 0-65535"); } } catch(Exception e) { throw new IllegalArgumentException("\""+inPort+"\" is not a valid TCP port for standalone web server listener!"); } } hs = HttpServer.create(new InetSocketAddress(port),0); sr = new SecureRandom(); accessList = new Hashtable<String,String>(); hs.start(); } //dynamically create new context when requested public String createContext() { String guid = generateGUID(); hs.createContext("/"+guid,new TestHttpHandler(guid)); return guid; } public String isSourceAccessed(String path) { if(accessList==null) return null; return accessList.get(path); } public void stop() { hs.stop(0); accessList = null; } public int getPort() { return port; } private String generateGUID() { byte[] buffer = new byte[16]; sr.nextBytes(buffer); String retVal = bytesToHex(buffer); return retVal.substring(0,8)+"-"+retVal.substring(8,12)+"-"+retVal.substring(12,16)+"-"+retVal.substring(16,20)+"-"+retVal.substring(20); } private String bytesToHex(byte[] bytes) { final char[] hexArray = "0123456789ABCDEF".toCharArray(); char[] hexChars = new char[bytes.length*2]; for(int j=0;j<bytes.length;j++){ int v =bytes[j] & 0xFF; hexChars[j*2]=hexArray[v>>>4]; hexChars[j*2+1]=hexArray[v&0x0F]; } return new String(hexChars); } private class TestHttpHandler implements HttpHandler { private String path; private boolean accessed; private String source; TestHttpHandler(String p) { path = p; accessed = false; source = null; } public void handle(HttpExchange exchange) { try { exchange.getRequestMethod(); exchange.getRequestBody().close(); Headers respHeaders = null; if(!accessed && (source == null)) { //context hasn't been accessed before source = exchange.getRemoteAddress().getHostString(); accessed = true; respHeaders = exchange.getResponseHeaders(); respHeaders.add("Content-Type","text/plain"); exchange.sendResponseHeaders(200,path.length()); OutputStream os = exchange.getResponseBody(); os.write(path.getBytes()); os.flush(); os.close(); accessList.put(path,source); } else { respHeaders = exchange.getResponseHeaders(); exchange.sendResponseHeaders(404,0); exchange.getResponseBody().close(); } } catch(Exception e) { System.err.println("Unforeseen error occurred!"); e.printStackTrace(); } } } }