diff options
author | Paul Hawke <paul.hawke@gmail.com> | 2013-09-15 15:20:32 -0500 |
---|---|---|
committer | Paul Hawke <paul.hawke@gmail.com> | 2013-09-15 15:20:32 -0500 |
commit | 6ac6c5a6f11c0eac57c5835e22e7946258131f9d (patch) | |
tree | d3e145a6438238bee42f9c90d4c256d6a447c75c /webserver | |
parent | 220e1a21e7bbb831d06551c72799dfedc1db979f (diff) | |
download | nanohttpd-6ac6c5a6f11c0eac57c5835e22e7946258131f9d.tar.gz |
Created capability for server-side URL rewriting and switched directory index file processing to use the new capability. @psh
Diffstat (limited to 'webserver')
4 files changed, 73 insertions, 17 deletions
diff --git a/webserver/markdown-plugin/src/main/java/fi/iki/elonen/MarkdownWebServerPlugin.java b/webserver/markdown-plugin/src/main/java/fi/iki/elonen/MarkdownWebServerPlugin.java index 6e82c2e..a3b69a3 100644 --- a/webserver/markdown-plugin/src/main/java/fi/iki/elonen/MarkdownWebServerPlugin.java +++ b/webserver/markdown-plugin/src/main/java/fi/iki/elonen/MarkdownWebServerPlugin.java @@ -20,6 +20,9 @@ public class MarkdownWebServerPlugin implements WebServerPlugin { processor = new PegDownProcessor(); } + @Override public void initialize(Map<String, String> commandLineOptions) { + } + @Override public boolean canServeUri(String uri, File rootDir) { File f = new File(rootDir, uri); return f.exists(); diff --git a/webserver/src/main/java/fi/iki/elonen/InternalRewrite.java b/webserver/src/main/java/fi/iki/elonen/InternalRewrite.java new file mode 100644 index 0000000..b84d88e --- /dev/null +++ b/webserver/src/main/java/fi/iki/elonen/InternalRewrite.java @@ -0,0 +1,28 @@ +package fi.iki.elonen; + +import java.util.Map; + +import static fi.iki.elonen.NanoHTTPD.Response; + +/** + * @author Paul S. Hawke (paul.hawke@gmail.com) + * On: 9/15/13 at 2:52 PM + */ +public class InternalRewrite extends Response { + private final String uri; + private final Map<String, String> headers; + + public InternalRewrite(Map<String, String> headers, String uri) { + super(null); + this.headers = headers; + this.uri = uri; + } + + public String getUri() { + return uri; + } + + public Map<String, String> getHeaders() { + return headers; + } +} diff --git a/webserver/src/main/java/fi/iki/elonen/SimpleWebServer.java b/webserver/src/main/java/fi/iki/elonen/SimpleWebServer.java index 90bb2e7..c05b891 100644 --- a/webserver/src/main/java/fi/iki/elonen/SimpleWebServer.java +++ b/webserver/src/main/java/fi/iki/elonen/SimpleWebServer.java @@ -1,12 +1,8 @@ package fi.iki.elonen; import java.io.*; -import java.net.JarURLConnection; -import java.net.URL; import java.net.URLEncoder; import java.util.*; -import java.util.jar.JarEntry; -import java.util.jar.JarFile; public class SimpleWebServer extends NanoHTTPD { /** @@ -106,6 +102,7 @@ public class SimpleWebServer extends NanoHTTPD { String host = "127.0.0.1"; List<File> rootDirs = new ArrayList<File>(); boolean quiet = false; + Map<String, String> options = new HashMap<String, String>(); // Parse command-line, with short and long versions of the options. for (int i = 0; i < args.length; ++i) { @@ -119,7 +116,13 @@ public class SimpleWebServer extends NanoHTTPD { rootDirs.add(new File(args[i + 1]).getAbsoluteFile()); } else if (args[i].equalsIgnoreCase("--licence")) { System.out.println(LICENCE + "\n"); - break; + } else if (args[i].startsWith("-X:")) { + int dot = args[i].indexOf('='); + if (dot > 0) { + String name = args[i].substring(0, dot); + String value = args[i].substring(dot + 1, args[i].length()); + options.put(name, value); + } } } @@ -127,6 +130,20 @@ public class SimpleWebServer extends NanoHTTPD { rootDirs.add(new File(".").getAbsoluteFile()); } + options.put("host", host); + options.put("port", ""+port); + options.put("quiet", String.valueOf(quiet)); + StringBuilder sb = new StringBuilder(); + for (File dir : rootDirs) { + if (sb.length() > 0) { + sb.append(":"); + } + try { + sb.append(dir.getCanonicalPath()); + } catch (IOException ignored) {} + } + options.put("home", sb.toString()); + ServiceLoader<WebServerPluginInfo> serviceLoader = ServiceLoader.load(WebServerPluginInfo.class); for (WebServerPluginInfo info : serviceLoader) { String[] mimeTypes = info.getMimeTypes(); @@ -142,14 +159,14 @@ public class SimpleWebServer extends NanoHTTPD { } System.out.println(")."); } - registerPluginForMimeType(indexFiles, mime, info.getWebServerPlugin(mime)); + registerPluginForMimeType(indexFiles, mime, info.getWebServerPlugin(mime), options); } } ServerRunner.executeInstance(new SimpleWebServer(host, port, rootDirs, quiet)); } - private static void registerPluginForMimeType(String[] indexFiles, String mimeType, WebServerPlugin plugin) { + private static void registerPluginForMimeType(String[] indexFiles, String mimeType, WebServerPlugin plugin, Map<String, String> commandLineOptions) { if (mimeType == null || plugin == null) { return; } @@ -165,6 +182,7 @@ public class SimpleWebServer extends NanoHTTPD { INDEX_FILE_NAMES.addAll(Arrays.asList(indexFiles)); } mimeTypeHandlers.put(mimeType, plugin); + plugin.initialize(commandLineOptions); } private File getRootDir() { @@ -221,16 +239,17 @@ public class SimpleWebServer extends NanoHTTPD { } } - List<File> homeDirs = getRootDirs(); - - for (File homeDir : homeDirs) { + for (File homeDir : getRootDirs()) { // Make sure we won't die of an exception later if (!homeDir.isDirectory()) { return createResponse(Response.Status.INTERNAL_ERROR, NanoHTTPD.MIME_PLAINTEXT, "INTERNAL ERRROR: given path is not a directory (" + homeDir + ")."); } } + return respond(Collections.unmodifiableMap(header), uri); + } + private Response respond(Map<String, String> headers, String uri) { // Remove URL arguments uri = uri.trim().replace(File.separatorChar, '/'); if (uri.indexOf('?') >= 0) { @@ -244,8 +263,9 @@ public class SimpleWebServer extends NanoHTTPD { boolean canServeUri = false; File homeDir = null; - for (int i = 0; !canServeUri && i < homeDirs.size(); i++) { - homeDir = homeDirs.get(i); + List<File> roots = getRootDirs(); + for (int i = 0; !canServeUri && i < roots.size(); i++) { + homeDir = roots.get(i); canServeUri = canServeUri(uri, homeDir); } if (!canServeUri) { @@ -273,9 +293,7 @@ public class SimpleWebServer extends NanoHTTPD { return createResponse(Response.Status.FORBIDDEN, NanoHTTPD.MIME_PLAINTEXT, "FORBIDDEN: No directory listing."); } } else { - // Index file was found, so serve it. - uri += indexFile; - f = new File(f, indexFile); + return respond(headers, uri + indexFile); } } @@ -283,9 +301,13 @@ public class SimpleWebServer extends NanoHTTPD { WebServerPlugin plugin = mimeTypeHandlers.get(mimeTypeForFile); Response response = null; if (plugin != null) { - response = plugin.serveFile(uri, header, f, mimeTypeForFile); + response = plugin.serveFile(uri, headers, f, mimeTypeForFile); + if (response != null && response instanceof InternalRewrite) { + InternalRewrite rewrite = (InternalRewrite) response; + return respond(rewrite.getHeaders(), rewrite.getUri()); + } } else { - response = serveFile(uri, header, f, mimeTypeForFile); + response = serveFile(uri, headers, f, mimeTypeForFile); } return response != null ? response : createResponse(Response.Status.NOT_FOUND, NanoHTTPD.MIME_PLAINTEXT, "Error 404, file not found."); diff --git a/webserver/src/main/java/fi/iki/elonen/WebServerPlugin.java b/webserver/src/main/java/fi/iki/elonen/WebServerPlugin.java index d1292df..96db9a3 100644 --- a/webserver/src/main/java/fi/iki/elonen/WebServerPlugin.java +++ b/webserver/src/main/java/fi/iki/elonen/WebServerPlugin.java @@ -8,6 +8,9 @@ import java.util.Map; * On: 9/14/13 at 8:09 AM */ public interface WebServerPlugin { + + void initialize(Map<String, String> commandLineOptions); + boolean canServeUri(String uri, File rootDir); NanoHTTPD.Response serveFile(String uri, Map<String, String> headers, File file, String mimeType); |