1
2 import java.io.IOException;
3 import java.io.InputStream;
4 import java.nio.ByteBuffer;
5 import java.nio.charset.Charset;
6 import java.util.HashMap;
7
8 /**
9 * SCGI connector.<br>
10 * Version: 1.0<br>
11 * Home page: http://snippets.dzone.com/posts/show/4304
12 */
13 public class SCGI {
14 public static class SCGIException extends IOException {
15 private static final long serialVersionUID = 1L;
16
17 public SCGIException(String message) {
18 super(message);
19 }
20 }
21
22 /** Used to decode the headers. */
23 public static final Charset ISO_8859_1 = Charset.forName("ISO-8859-1");
24
25 /**
26 * Read the <a href="http://python.ca/scgi/protocol.txt">SCGI</a> request headers.<br>
27 * After the headers had been loaded,
28 * you can read the body of the request manually from the same {@code input} stream:<pre>
29 * // Load the SCGI headers.
30 * Socket clientSocket = socket.accept();
31 * BufferedInputStream bis = new BufferedInputStream(clientSocket.getInputStream(), 4096);
32 * HashMap<String, String> env = SCGI.parse(bis);
33 * // Read the body of the request.
34 * bis.read(new byte[Integer.parseInt(env.get("CONTENT_LENGTH"))]);
35 * </pre>
36 * @param input an efficient (buffered) input stream.
37 * @return strings passed via the SCGI request.
38 */
39 public static HashMap parse(InputStream input) throws IOException {
40 StringBuilder lengthString = new StringBuilder(12);
41 String headers = "";
42 for (;;) {
43 char ch = (char) input.read();
44 if (ch >= '0' && ch <= '9') {
45 lengthString.append(ch);
46 } else if (ch == ':') {
47 int length = Integer.parseInt(lengthString.toString());
48 byte[] headersBuf = new byte[length];
49 int read = input.read(headersBuf);
50 if (read != headersBuf.length)
51 throw new SCGIException("Couldn't read all the headers (" + length + ").");
52 headers = ISO_8859_1.decode(ByteBuffer.wrap(headersBuf)).toString();
53 if (input.read() != ',') throw new SCGIException("Wrong SCGI header length: " + lengthString);
54 break;
55 } else {
56 lengthString.append(ch);
57 throw new SCGIException("Wrong SCGI header length: " + lengthString);
58 }
59 }
60 HashMap env = new HashMap();
61 while (headers.length() != 0) {
62 int sep1 = headers.indexOf(0);
63 int sep2 = headers.indexOf(0, sep1 + 1);
64 env.put(headers.substring(0, sep1), headers.substring(sep1 + 1, sep2));
65 headers = headers.substring(sep2 + 1);
66 }
67 return env;
68 }
69 }