Added a responder to serve static content from the classloader.
[jsvc.git] / src / dolda / jsvc / util / StaticContent.java
1 package dolda.jsvc.util;
2
3 import dolda.jsvc.*;
4 import java.io.*;
5 import java.util.*;
6
7 public class StaticContent implements Responder {
8     private final Class<?> base;
9     private final String resname;
10     private final boolean dir;
11     private final String mimetype;
12     
13     public StaticContent(Class<?> base, String resname, boolean dir, String mimetype) {
14         this.base = base;
15         this.resname = resname;
16         this.dir = dir;
17         this.mimetype = mimetype;
18     }
19     
20     public StaticContent(String resname, boolean dir, String mimetype) {
21         this(null, resname, dir, mimetype);
22     }
23     
24     public void respond(Request req) {
25         String nm;
26         if(dir) {
27             nm = resname + "/" + req.path();
28         } else {
29             nm = resname;
30         }
31         InputStream in;
32         if(base == null) {
33             in = StaticContent.class.getClassLoader().getResourceAsStream(nm);
34         } else {
35             in = base.getResourceAsStream(nm);
36         }
37         if(in == null)
38             throw(Restarts.stdresponse(404));
39         String ims = req.inheaders().get("If-Modified-Since");
40         Date mtime = new Date((req.ctx().starttime() / 1000) * 1000);
41         if(ims != null) {
42             Date d;
43             try {
44                 d = Http.parsedate(ims);
45             } catch(java.text.ParseException e) {
46                 throw(Restarts.stdresponse(400));
47             }
48             if(mtime.compareTo(d) <= 0) {
49                 req.status(304);
50                 req.outheaders().put("Content-Length", "0");
51                 return;
52             }
53         }
54         try {
55             try {
56                 req.outheaders().put("Content-Type", mimetype);
57                 req.outheaders().put("Last-Modified", Http.fmtdate(mtime));
58                 Misc.cpstream(in, req.output());
59             } finally {
60                 in.close();
61             }
62         } catch(IOException e) {
63             throw(new Error(e));
64         }
65     }
66 }