1 package dolda.jsvc.scgi;
3 import java.util.logging.*;
8 public abstract class Server implements Runnable {
9 private final ServerSocket sk;
10 private final Logger logger = Logger.getLogger("dolda.jsvc.scgi");
11 public String headcs = "UTF-8";
13 public Server(ServerSocket sk) {
17 private static int readnslen(InputStream in) throws IOException {
23 else if((c >= '0') && (c <= '9'))
24 ret = (ret * 10) + (c - '0');
26 throw(new InvalidRequestException("Malformed netstring length"));
30 private static byte[] readns(InputStream in) throws IOException {
31 byte[] buf = new byte[readnslen(in)];
33 while(off < buf.length) {
34 int ret = in.read(buf, off, buf.length - off);
36 throw(new InvalidRequestException("Unexpected EOS in netstring"));
40 throw(new InvalidRequestException("Unterminated netstring"));
44 private Map<String, String> readhead(InputStream in) throws IOException {
45 byte[] rawhead = readns(in);
46 String head = new String(rawhead, headcs);
47 Map<String, String> ret = new HashMap<String, String>();
50 int p2 = head.indexOf(0, p);
52 if(p == head.length())
54 throw(new InvalidRequestException("Malformed headers"));
56 String key = head.substring(p, p2);
57 int p3 = head.indexOf(0, p2 + 1);
59 throw(new InvalidRequestException("Malformed headers"));
60 String val = head.substring(p2 + 1, p3);
66 private boolean checkhead(Map<String, String> head) {
67 if(!head.containsKey("SCGI") || !head.get("SCGI").equals("1"))
72 protected abstract void handle(Map<String, String> head, Socket sk) throws Exception;
74 private void serve(Socket sk) {
77 InputStream in = sk.getInputStream();
78 Map<String, String> head = readhead(in);
83 } catch(Exception e) {
84 logger.log(Level.WARNING, "Could not handle request", e);
92 } catch(IOException e) {
93 logger.log(Level.WARNING, "I/O error encountered while serving SCGI request", e);
101 Socket nsk = sk.accept();
107 } catch(IOException e) {
108 logger.log(Level.SEVERE, "SCGI server encountered I/O error", e);