Commit | Line | Data |
---|---|---|
13e578b1 FT |
1 | package dolda.jsvc.scgi; |
2 | ||
3 | import java.io.*; | |
4 | import java.net.*; | |
5 | import java.util.*; | |
6 | import dolda.jsvc.*; | |
7 | import dolda.jsvc.util.*; | |
8 | import dolda.jsvc.j2ee.PosixArgs; | |
9 | ||
10 | public class DirServer extends Server { | |
11 | private final Map<File, DSContext> contexts = new HashMap<File, DSContext>(); | |
12 | private final File datroot; | |
13 | ||
14 | public DirServer(ServerSocket sk, File datroot) { | |
15 | super(sk); | |
16 | this.datroot = datroot; | |
17 | } | |
18 | ||
19 | private DSContext context(File file) throws ThreadContext.CreateException { | |
20 | synchronized(contexts) { | |
21 | DSContext ctx = contexts.get(file); | |
22 | if(ctx != null) { | |
23 | if(ctx.mtime < file.lastModified()) { | |
24 | ctx.tg.destroy(); | |
25 | contexts.remove(file); | |
26 | ctx = null; | |
27 | } | |
28 | } | |
29 | if(ctx == null) { | |
30 | ctx = new DSContext(file, datroot); | |
31 | contexts.put(file, ctx); | |
32 | } | |
33 | return(ctx); | |
34 | } | |
35 | } | |
36 | ||
37 | public void handle(Map<String, String> head, Socket sk) throws Exception { | |
38 | String filename = head.get("SCRIPT_FILENAME"); | |
39 | if(filename == null) | |
40 | throw(new Exception("Request for DirServer must contain SCRIPT_FILENAME")); | |
41 | File file = new File(filename); | |
42 | if(!file.exists() || !file.canRead()) | |
43 | throw(new Exception("Cannot access the requested JSvc file " + file.toString())); | |
44 | DSContext ctx = context(file); | |
45 | Request req = new ScgiRequest(sk, head); | |
46 | RequestThread w = ctx.tg.respond(req); | |
47 | w.start(); | |
48 | } | |
49 | ||
50 | private static void usage(PrintStream out) { | |
51 | out.println("usage: dolda.jsvc.scgi.DirServer [-h] [-e CHARSET] [-d DATADIR] PORT"); | |
52 | } | |
53 | ||
54 | public static void main(String[] args) { | |
55 | PosixArgs opt = PosixArgs.getopt(args, "h"); | |
56 | if(opt == null) { | |
57 | usage(System.err); | |
58 | System.exit(1); | |
59 | } | |
60 | String charset = null; | |
61 | File datroot = null; | |
62 | for(char c : opt.parsed()) { | |
63 | switch(c) { | |
64 | case 'e': | |
65 | charset = opt.arg; | |
66 | break; | |
67 | case 'd': | |
68 | datroot = new File(opt.arg); | |
69 | if(!datroot.exists() || !datroot.isDirectory()) { | |
70 | System.err.println(opt.arg + ": no such directory"); | |
71 | System.exit(1); | |
72 | } | |
73 | break; | |
74 | case 'h': | |
75 | usage(System.out); | |
76 | return; | |
77 | } | |
78 | } | |
79 | if(opt.rest.length < 1) { | |
80 | usage(System.err); | |
81 | System.exit(1); | |
82 | } | |
83 | if(datroot == null) { | |
84 | datroot = new File(System.getProperty("user.home"), ".jsvc"); | |
85 | if(!datroot.exists() || !datroot.isDirectory()) | |
86 | datroot = null; | |
87 | } | |
88 | int port = Integer.parseInt(opt.rest[0]); | |
89 | ServerSocket sk; | |
90 | try { | |
91 | sk = new ServerSocket(port); | |
92 | } catch(IOException e) { | |
93 | System.err.println("could not bind to port " + port + ": " + e.getMessage()); | |
94 | System.exit(1); | |
95 | return; /* Because javac is stupid. :-/ */ | |
96 | } | |
97 | DirServer s = new DirServer(sk, datroot); | |
98 | if(charset != null) | |
99 | s.headcs = charset; | |
100 | ||
101 | new Thread(s, "SCGI server thread").start(); | |
102 | } | |
103 | } |