//Oppgavetekst: Lag en webserver med foelgende funksjoner: // * Server filer // * List opp mapper og filer i en mappe - saakalt directory index // * Sender en 404-side naar noen spoer om en fil som ikke finnes // * Kjoer Python-scripts, filer som ender i .py, og send resultatet til nettlesere import java.util.Scanner; import java.util.HashMap; import java.io.*; import java.nio.file.Paths; import com.sun.net.httpserver.HttpExchange; import com.sun.net.httpserver.HttpServer; import com.sun.net.httpserver.HttpHandler; import java.net.InetSocketAddress; import java.net.URLDecoder; class Templates { public static String sysInfo = "
"+ "

"+ "Web Server running on "+ System.getProperty("os.name")+" "+ System.getProperty("os.version")+" "+ System.getProperty("os.arch")+ "

"; public static String err404 = ""+ ""+ ""+ "Error 404"+ ""+ ""+ "

404 Not Found

"+ "

The file {{$1}} was not found.

"+ sysInfo+ ""+ ""; public static String index = ""+ ""+ ""+ "Index"+ ""+ ""+ ""+ sysInfo+ ""+ ""; public static String indexEntry = "
  • "+ "{{$1}}"+ "
  • "; //Convenience function; many templates have only one argument, //pointless to have to build up a String[] just for that public static String templatify(String str, String arg) { String[] args = {arg}; return templatify(str, args); } //Build a template, replacing things within {{ and }} with //the arguments provided public static String templatify(String str, String[] args) { for (int i = 0; i < args.length; ++i) { str = str.replace("{{$"+(i+1)+"}}", args[i]); } return str; } } class RequestHandler implements HttpHandler { private File root; @Override public void handle(HttpExchange t) throws IOException { OutputStream out = t.getResponseBody(); String url = t.getRequestURI().toString().split("\\?")[0]; int lmul = 1; //HEAD requests want to only receive headers, but that's //somewhat hard to implement with this structure. //We'll just kill the connection if that happens. if (t.getRequestMethod().equalsIgnoreCase("HEAD")) { out.close(); return; } File f = new File(root, url); if (!f.exists()) { send404(f, url, out, t); } else if (f.isDirectory()) sendIndex(f, url, out, t); else { if (url.endsWith(".py")) sendPython(f, url, out, t); else sendFile(f, url, out, t); } out.close(); } RequestHandler(File r) { root = r; } //404 when a file which doesn't exist is requested private static void send404(File f, String url, OutputStream out, HttpExchange t) throws IOException { byte[] res = Templates.templatify(Templates.err404, url).getBytes(); t.sendResponseHeaders(404, res.length); out.write(res); } //Directory index when a directory is requested private static void sendIndex(File dir, String url, OutputStream out, HttpExchange t) throws IOException { File[] files = dir.listFiles(); String entries = ""; //Loop through files in the requested directory, //building up the list of entries for (int i = 0; i < files.length; ++i) { File f = files[i]; String name = f.toPath().getFileName().toString(); if (f.isDirectory()) name += "/"; entries += Templates.templatify(Templates.indexEntry, name); } //Combine the entries with the rest of the index' HTML, //and send to the client byte[] res = Templates.templatify(Templates.index, entries).getBytes(); t.sendResponseHeaders(200, res.length); out.write(res); } //Send file when a file is requested private static void sendFile(File f, String url, OutputStream out, HttpExchange t) throws IOException { Scanner s = new Scanner(f); t.sendResponseHeaders(200, f.length()); while (s.hasNextLine()) { out.write((s.nextLine()+"\n").getBytes()); } } //Execute python script and send the output to the browser private static void sendPython(File f, String url, OutputStream out, HttpExchange t) throws IOException { String[] command = {"python", f.toPath().toString()}; Process proc = Runtime.getRuntime().exec(command); BufferedReader stdin = new BufferedReader(new InputStreamReader(proc.getInputStream())); BufferedReader stderr = new BufferedReader(new InputStreamReader(proc.getErrorStream())); String res = ""; String s = null; //Print the output from the python script while ((s = stdin.readLine()) != null) { res += s+"\n"; } //Print the errors from the python script while ((s = stderr.readLine()) != null) { res += s+"\n"; } t.getResponseHeaders().add("Content-Type", "text/plain"); t.sendResponseHeaders(200, res.length()); out.write(res.getBytes()); } } class MinOppgave4 { private static HttpServer server; private static File root = new File("www"); private static int port = 8000; //Simple command line interface public static String onCommand(String str) { String[] tokens = str.split("\\s+"); switch (tokens[0]) { case "help": return "help: Display this help text\n"+ "stop: Stop the web server"; case "stop": System.exit(0); return ""; default: return "Unknown command: "+tokens[0]+"\n"+ "Type 'help' for help."; } } public static void main(String[] args) throws IOException { Scanner s = new Scanner(System.in); //Create an HTTP server server = HttpServer.create(new InetSocketAddress(port), 0); //Add request handler server.createContext("/", new RequestHandler(root)); //Start the server server.start(); System.out.println("Server started. Visit http://localhost:"+port+" in a web browser."); System.out.println("Try modifying the contents of the directory "+root.toPath().getFileName()+"."); //Simple command line interface System.out.print("> "); while (s.hasNextLine()) { System.out.println(onCommand(s.nextLine())); System.out.print("> "); } } }