Added a "directory multiplexer" responder.
authorFredrik Tolf <fredrik@dolda2000.com>
Tue, 13 Oct 2009 00:11:58 +0000 (02:11 +0200)
committerFredrik Tolf <fredrik@dolda2000.com>
Tue, 13 Oct 2009 00:11:58 +0000 (02:11 +0200)
src/dolda/jsvc/RequestWrap.java [new file with mode: 0644]
src/dolda/jsvc/util/Multiplexer.java [new file with mode: 0644]
src/dolda/jsvc/util/SimpleWriter.java [new file with mode: 0644]

diff --git a/src/dolda/jsvc/RequestWrap.java b/src/dolda/jsvc/RequestWrap.java
new file mode 100644 (file)
index 0000000..1314c5d
--- /dev/null
@@ -0,0 +1,51 @@
+package dolda.jsvc;
+
+import java.io.*;
+import java.net.URL;
+import java.net.SocketAddress;
+import java.util.Map;
+
+public class RequestWrap implements Request {
+    private final Request bk;
+    
+    public RequestWrap(Request req) {
+       this.bk = req;
+    }
+    
+    public URL url() {return(bk.url());}
+    public String method() {return(bk.method());}
+    public String path() {return(bk.path());}
+    public InputStream input() {return(bk.input());}
+    public MultiMap<String, String> inheaders() {return(bk.inheaders());}
+    public MultiMap<String, String> params() {return(bk.params());}
+    public OutputStream output() {return(bk.output());}
+    public void status(int code) {bk.status(code);}
+    public void status(int code, String message) {bk.status(code, message);}
+    public MultiMap<String, String> outheaders() {return(bk.outheaders());}
+    public Map<Object, Object> props() {return(bk.props());}
+    public ServerContext ctx() {return(bk.ctx());}
+    public SocketAddress remoteaddr() {return(bk.remoteaddr());}
+    public SocketAddress localaddr() {return(bk.localaddr());}
+
+    public Request orig() {
+       return(bk);
+    }
+    
+    public static Request chpath(Request req, String path) {
+       class PathWrap extends RequestWrap {
+           private final String path;
+           
+           public PathWrap(Request req, String path) {
+               super(req);
+               this.path = path;
+           }
+           
+           public String path() {
+               return(path);
+           }
+       }
+       if(req instanceof PathWrap)
+           return(new PathWrap(((PathWrap)req).orig(), path));
+       return(new PathWrap(req, path));
+    }
+}
diff --git a/src/dolda/jsvc/util/Multiplexer.java b/src/dolda/jsvc/util/Multiplexer.java
new file mode 100644 (file)
index 0000000..dabcb34
--- /dev/null
@@ -0,0 +1,69 @@
+package dolda.jsvc.util;
+
+import dolda.jsvc.*;
+import java.util.*;
+
+public class Multiplexer implements Responder {
+    private Responder def;
+    private Collection<Sub> subs = new LinkedList<Sub>();
+
+    private static interface Sub {
+       boolean match(Request req);
+    }
+    
+    public Multiplexer(Responder def) {
+       this.def = def;
+    }
+    
+    public Multiplexer() {
+       this(new SimpleWriter("html") {
+               public void respond(Request req, java.io.PrintWriter out) {
+                   req.status(404);
+                   out.println("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
+                   out.println("<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.1//EN\" \"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd\">");
+                   out.println("<html xmlns=\"http://www.w3.org/1999/xhtml\" xml:lang=\"en-US\">");
+                   out.println("<head><title>Resource not found</title></head>");
+                   out.println("<body>");
+                   out.println("<h1>Resource not found</h1>");
+                   out.println("The resource you requested could not be found on this server.");
+                   out.println("</body>");
+                   out.println("</html>");
+               }
+           });
+    }
+    
+    public void file(final String path, final Responder responder) {
+       subs.add(new Sub() {
+               public boolean match(Request req) {
+                   if(req.path().equals(path)) {
+                       responder.respond(req);
+                       return(true);
+                   }
+                   return(false);
+               }
+           });
+    }
+
+    public void dir(String path, final Responder responder) {
+       final String fp = Misc.stripslashes(path, true, true);
+       subs.add(new Sub() {
+               public boolean match(Request req) {
+                   if(req.path().equals(fp)) {
+                       throw(Restarts.redirect(fp + "/"));
+                   } else if(req.path().startsWith(fp + "/")) {
+                       responder.respond(RequestWrap.chpath(req, req.path().substring(fp.length() + 1)));
+                       return(true);
+                   }
+                   return(false);
+               }
+           });
+    }
+    
+    public void respond(Request req) {
+       for(Sub s : subs) {
+           if(s.match(req))
+               return;
+       }
+       def.respond(req);
+    }
+}
diff --git a/src/dolda/jsvc/util/SimpleWriter.java b/src/dolda/jsvc/util/SimpleWriter.java
new file mode 100644 (file)
index 0000000..60f17d2
--- /dev/null
@@ -0,0 +1,26 @@
+package dolda.jsvc.util;
+
+import dolda.jsvc.*;
+import java.io.*;
+
+public abstract class SimpleWriter implements Responder {
+    private String ctype;
+    
+    public SimpleWriter(String ctype) {
+       this.ctype = ctype;
+    }
+    
+    public abstract void respond(Request req, PrintWriter out);
+    
+    public void respond(Request req) {
+       req.outheaders().put("Content-Type", "text/" + ctype + "; charset=utf-8");
+       PrintWriter out;
+       try {
+           out = new PrintWriter(new OutputStreamWriter(req.output(), "UTF-8"));
+       } catch(UnsupportedEncodingException e) {
+           throw(new Error(e));
+       }
+       respond(req, out);
+       out.flush();
+    }
+}