Added initial SCGI server and a handler for serving JARs from the filesystem.
[jsvc.git] / src / dolda / jsvc / scgi / DirServer.java
CommitLineData
13e578b1
FT
1package dolda.jsvc.scgi;
2
3import java.io.*;
4import java.net.*;
5import java.util.*;
6import dolda.jsvc.*;
7import dolda.jsvc.util.*;
8import dolda.jsvc.j2ee.PosixArgs;
9
10public 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}