University stuff.
Du kannst nicht mehr als 25 Themen auswählen Themen müssen mit entweder einem Buchstaben oder einer Ziffer beginnen. Sie können Bindestriche („-“) enthalten und bis zu 35 Zeichen lang sein.

MinOppgave4.java 6.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228
  1. //Oppgavetekst: Lag en webserver med foelgende funksjoner:
  2. // * Server filer
  3. // * List opp mapper og filer i en mappe - saakalt directory index
  4. // * Sender en 404-side naar noen spoer om en fil som ikke finnes
  5. // * Kjoer Python-scripts, filer som ender i .py, og send resultatet til nettlesere
  6. import java.util.Scanner;
  7. import java.util.HashMap;
  8. import java.io.*;
  9. import java.nio.file.Paths;
  10. import com.sun.net.httpserver.HttpExchange;
  11. import com.sun.net.httpserver.HttpServer;
  12. import com.sun.net.httpserver.HttpHandler;
  13. import java.net.InetSocketAddress;
  14. import java.net.URLDecoder;
  15. class Templates {
  16. public static String sysInfo =
  17. "<hr>"+
  18. "<p>"+
  19. "Web Server running on "+
  20. System.getProperty("os.name")+" "+
  21. System.getProperty("os.version")+" "+
  22. System.getProperty("os.arch")+
  23. "</p>";
  24. public static String err404 =
  25. "<!DOCTYPE html>"+
  26. "<html>"+
  27. "<head>"+
  28. "<title>Error 404</title>"+
  29. "</head>"+
  30. "<body>"+
  31. "<h1>404 Not Found</h1>"+
  32. "<p>The file {{$1}} was not found.</p>"+
  33. sysInfo+
  34. "</body>"+
  35. "</html>";
  36. public static String index =
  37. "<!DOCTYPE html>"+
  38. "<html>"+
  39. "<head>"+
  40. "<title>Index</title>"+
  41. "</head>"+
  42. "<body>"+
  43. "<ul>"+
  44. "<li><a href='..'>..</a></li>"+
  45. "{{$1}}"+
  46. "</ul>"+
  47. sysInfo+
  48. "</body>"+
  49. "</html>";
  50. public static String indexEntry =
  51. "<li>"+
  52. "<a href='{{$1}}'>{{$1}}</a>"+
  53. "</li>";
  54. //Convenience function; many templates have only one argument,
  55. //pointless to have to build up a String[] just for that
  56. public static String templatify(String str, String arg) {
  57. String[] args = {arg};
  58. return templatify(str, args);
  59. }
  60. //Build a template, replacing things within {{ and }} with
  61. //the arguments provided
  62. public static String templatify(String str, String[] args) {
  63. for (int i = 0; i < args.length; ++i) {
  64. str = str.replace("{{$"+(i+1)+"}}", args[i]);
  65. }
  66. return str;
  67. }
  68. }
  69. class RequestHandler implements HttpHandler {
  70. private File root;
  71. @Override public void handle(HttpExchange t) throws IOException {
  72. OutputStream out = t.getResponseBody();
  73. String url = t.getRequestURI().toString().split("\\?")[0];
  74. int lmul = 1;
  75. //HEAD requests want to only receive headers, but that's
  76. //somewhat hard to implement with this structure.
  77. //We'll just kill the connection if that happens.
  78. if (t.getRequestMethod().equalsIgnoreCase("HEAD")) {
  79. out.close();
  80. return;
  81. }
  82. File f = new File(root, url);
  83. if (!f.exists()) {
  84. send404(f, url, out, t);
  85. } else if (f.isDirectory())
  86. sendIndex(f, url, out, t);
  87. else {
  88. if (url.endsWith(".py"))
  89. sendPython(f, url, out, t);
  90. else
  91. sendFile(f, url, out, t);
  92. }
  93. out.close();
  94. }
  95. RequestHandler(File r) {
  96. root = r;
  97. }
  98. //404 when a file which doesn't exist is requested
  99. private static void send404(File f, String url, OutputStream out, HttpExchange t) throws IOException {
  100. byte[] res = Templates.templatify(Templates.err404, url).getBytes();
  101. t.sendResponseHeaders(404, res.length);
  102. out.write(res);
  103. }
  104. //Directory index when a directory is requested
  105. private static void sendIndex(File dir, String url, OutputStream out, HttpExchange t) throws IOException {
  106. File[] files = dir.listFiles();
  107. String entries = "";
  108. //Loop through files in the requested directory,
  109. //building up the list of entries
  110. for (int i = 0; i < files.length; ++i) {
  111. File f = files[i];
  112. String name = f.toPath().getFileName().toString();
  113. if (f.isDirectory())
  114. name += "/";
  115. entries += Templates.templatify(Templates.indexEntry, name);
  116. }
  117. //Combine the entries with the rest of the index' HTML,
  118. //and send to the client
  119. byte[] res = Templates.templatify(Templates.index, entries).getBytes();
  120. t.sendResponseHeaders(200, res.length);
  121. out.write(res);
  122. }
  123. //Send file when a file is requested
  124. private static void sendFile(File f, String url, OutputStream out, HttpExchange t) throws IOException {
  125. Scanner s = new Scanner(f);
  126. t.sendResponseHeaders(200, f.length());
  127. while (s.hasNextLine()) {
  128. out.write((s.nextLine()+"\n").getBytes());
  129. }
  130. }
  131. //Execute python script and send the output to the browser
  132. private static void sendPython(File f, String url, OutputStream out, HttpExchange t) throws IOException {
  133. String[] command = {"python", f.toPath().toString()};
  134. Process proc = Runtime.getRuntime().exec(command);
  135. BufferedReader stdin = new BufferedReader(new InputStreamReader(proc.getInputStream()));
  136. BufferedReader stderr = new BufferedReader(new InputStreamReader(proc.getErrorStream()));
  137. String res = "";
  138. String s = null;
  139. //Print the output from the python script
  140. while ((s = stdin.readLine()) != null) {
  141. res += s+"\n";
  142. }
  143. //Print the errors from the python script
  144. while ((s = stderr.readLine()) != null) {
  145. res += s+"\n";
  146. }
  147. t.getResponseHeaders().add("Content-Type", "text/plain");
  148. t.sendResponseHeaders(200, res.length());
  149. out.write(res.getBytes());
  150. }
  151. }
  152. class MinOppgave4 {
  153. private static HttpServer server;
  154. private static File root = new File("www");
  155. private static int port = 8000;
  156. //Simple command line interface
  157. public static String onCommand(String str) {
  158. String[] tokens = str.split("\\s+");
  159. switch (tokens[0]) {
  160. case "help":
  161. return
  162. "help: Display this help text\n"+
  163. "stop: Stop the web server";
  164. case "stop":
  165. System.exit(0);
  166. return "";
  167. default:
  168. return
  169. "Unknown command: "+tokens[0]+"\n"+
  170. "Type 'help' for help.";
  171. }
  172. }
  173. public static void main(String[] args) throws IOException {
  174. Scanner s = new Scanner(System.in);
  175. //Create an HTTP server
  176. server = HttpServer.create(new InetSocketAddress(port), 0);
  177. //Add request handler
  178. server.createContext("/", new RequestHandler(root));
  179. //Start the server
  180. server.start();
  181. System.out.println("Server started. Visit http://localhost:"+port+" in a web browser.");
  182. System.out.println("Try modifying the contents of the directory "+root.toPath().getFileName()+".");
  183. //Simple command line interface
  184. System.out.print("> ");
  185. while (s.hasNextLine()) {
  186. System.out.println(onCommand(s.nextLine()));
  187. System.out.print("> ");
  188. }
  189. }
  190. }