|
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228 |
- //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 =
- "<hr>"+
- "<p>"+
- "Web Server running on "+
- System.getProperty("os.name")+" "+
- System.getProperty("os.version")+" "+
- System.getProperty("os.arch")+
- "</p>";
-
- public static String err404 =
- "<!DOCTYPE html>"+
- "<html>"+
- "<head>"+
- "<title>Error 404</title>"+
- "</head>"+
- "<body>"+
- "<h1>404 Not Found</h1>"+
- "<p>The file {{$1}} was not found.</p>"+
- sysInfo+
- "</body>"+
- "</html>";
-
- public static String index =
- "<!DOCTYPE html>"+
- "<html>"+
- "<head>"+
- "<title>Index</title>"+
- "</head>"+
- "<body>"+
- "<ul>"+
- "<li><a href='..'>..</a></li>"+
- "{{$1}}"+
- "</ul>"+
- sysInfo+
- "</body>"+
- "</html>";
-
- public static String indexEntry =
- "<li>"+
- "<a href='{{$1}}'>{{$1}}</a>"+
- "</li>";
-
- //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("> ");
- }
- }
- }
|