Clover Coverage Report
Coverage timestamp: Fri May 24 2013 13:47:27 UTC
../../../../img/srcFileCovDistChart7.png 74% of files have more coverage
147   337   46   13.36
50   274   0.31   11
11     4.18  
1    
 
  WebServerWorker       Line # 19 147 46 69.2% 0.6923077
 
  (2)
 
1    package org.qedeq.base.test;
2   
3    /*
4    * This web server code was adapted from sun's simple web server tutorial:
5    * http://java.sun.com/developer/technicalArticles/Networking/Webserver/
6    */
7   
8    import java.io.BufferedInputStream;
9    import java.io.File;
10    import java.io.FileInputStream;
11    import java.io.IOException;
12    import java.io.InputStream;
13    import java.io.PrintStream;
14    import java.net.ServerSocket;
15    import java.net.Socket;
16    import java.util.Date;
17   
18   
 
19    public class WebServerWorker implements Runnable {
20   
21    /** 2XX: generally "OK" */
22    public static final int HTTP_OK = 200;
23    public static final int HTTP_CREATED = 201;
24    public static final int HTTP_ACCEPTED = 202;
25    public static final int HTTP_NOT_AUTHORITATIVE = 203;
26    public static final int HTTP_NO_CONTENT = 204;
27    public static final int HTTP_RESET = 205;
28    public static final int HTTP_PARTIAL = 206;
29   
30    /** 3XX: relocation/redirect */
31    public static final int HTTP_MULT_CHOICE = 300;
32    public static final int HTTP_MOVED_PERM = 301;
33    public static final int HTTP_MOVED_TEMP = 302;
34    public static final int HTTP_SEE_OTHER = 303;
35    public static final int HTTP_NOT_MODIFIED = 304;
36    public static final int HTTP_USE_PROXY = 305;
37   
38    /** 4XX: client error */
39    public static final int HTTP_BAD_REQUEST = 400;
40    public static final int HTTP_UNAUTHORIZED = 401;
41    public static final int HTTP_PAYMENT_REQUIRED = 402;
42    public static final int HTTP_FORBIDDEN = 403;
43    public static final int HTTP_NOT_FOUND = 404;
44    public static final int HTTP_BAD_METHOD = 405;
45    public static final int HTTP_NOT_ACCEPTABLE = 406;
46    public static final int HTTP_PROXY_AUTH = 407;
47    public static final int HTTP_CLIENT_TIMEOUT = 408;
48    public static final int HTTP_CONFLICT = 409;
49    public static final int HTTP_GONE = 410;
50    public static final int HTTP_LENGTH_REQUIRED = 411;
51    public static final int HTTP_PRECON_FAILED = 412;
52    public static final int HTTP_ENTITY_TOO_LARGE = 413;
53    public static final int HTTP_REQ_TOO_LONG = 414;
54    public static final int HTTP_UNSUPPORTED_TYPE = 415;
55   
56    /** 5XX: server error */
57    public static final int HTTP_SERVER_ERROR = 500;
58    public static final int HTTP_INTERNAL_ERROR = 501;
59    public static final int HTTP_BAD_GATEWAY = 502;
60    public static final int HTTP_UNAVAILABLE = 503;
61    public static final int HTTP_GATEWAY_TIMEOUT = 504;
62    public static final int HTTP_VERSION = 505;
63   
64    final static int BUF_SIZE = 2048;
65   
66   
67    static final byte[] EOL = {(byte)'\r', (byte)'\n' };
68   
69    final int timeout;
70   
71    final File root;
72   
73    boolean debug = true;
74   
75    /* buffer to use for requests */
76    byte[] buf;
77    /* Socket to client we're handling */
78    private Socket s;
79   
80    private final ServerSocket ss;
81   
 
82  1 toggle WebServerWorker(final int timeout, final File root, final ServerSocket ss, boolean debug) {
83  1 this.ss = ss;
84  1 this.timeout = timeout;
85  1 this.root = root;
86  1 this.debug = debug;
87  1 buf = new byte[BUF_SIZE];
88  1 s = null;
89    }
90   
 
91  1 toggle public synchronized void run() {
92  1 log("starting on port " + ss.getLocalPort());
93  2 while (!Thread.interrupted()) {
94  2 try {
95  2 s = ss.accept();
96  1 handleClient();
97    } catch (Exception e) {
98  1 break;
99    }
100    }
101  1 log("closing");
102    }
103   
 
104  1 toggle void handleClient() throws IOException {
105  1 InputStream is = new BufferedInputStream(s.getInputStream());
106  1 PrintStream ps = new PrintStream(s.getOutputStream());
107    /* we will only block in read for this many milliseconds
108    * before we fail with java.io.InterruptedIOException,
109    * at which point we will abandon the connection.
110    */
111  1 s.setSoTimeout(timeout);
112  1 s.setTcpNoDelay(true);
113    /* zero out the buffer from last time */
114  2049 for (int i = 0; i < BUF_SIZE; i++) {
115  2048 buf[i] = 0;
116    }
117  1 try {
118    /* We only support HTTP GET/HEAD, and don't
119    * support any fancy HTTP options,
120    * so we're only interested really in
121    * the first line.
122    */
123  1 int nread = 0, r = 0;
124   
125  1 outerloop:
126  1 while (nread < BUF_SIZE) {
127  1 r = is.read(buf, nread, BUF_SIZE - nread);
128  1 if (r == -1) {
129    /* EOF */
130  0 return;
131    }
132  1 int i = nread;
133  1 nread += r;
134  37 for (; i < nread; i++) {
135  37 if (buf[i] == (byte)'\n' || buf[i] == (byte)'\r') {
136    /* read one line */
137  1 break outerloop;
138    }
139    }
140    }
141   
142    /* are we doing a GET or just a HEAD */
143  1 boolean doingGet;
144    /* beginning of file name */
145  1 int index;
146  1 if (buf[0] == (byte)'G' &&
147    buf[1] == (byte)'E' &&
148    buf[2] == (byte)'T' &&
149    buf[3] == (byte)' ') {
150  1 doingGet = true;
151  1 index = 4;
152  0 } else if (buf[0] == (byte)'H' &&
153    buf[1] == (byte)'E' &&
154    buf[2] == (byte)'A' &&
155    buf[3] == (byte)'D' &&
156    buf[4] == (byte)' ') {
157  0 doingGet = false;
158  0 index = 5;
159    } else {
160    /* we don't support this method */
161  0 ps.print("HTTP/1.0 " + HTTP_BAD_METHOD +
162    " unsupported method type: ");
163  0 ps.write(buf, 0, 5);
164  0 ps.write(EOL);
165  0 ps.flush();
166  0 s.close();
167  0 return;
168    }
169   
170  1 int i = 0;
171    /* find the file name, from:
172    * GET /foo/bar.html HTTP/1.0
173    * extract "/foo/bar.html"
174    */
175  24 for (i = index; i < nread; i++) {
176  24 if (buf[i] == (byte)' ') {
177  1 break;
178    }
179    }
180  1 String fname = (new String(buf, 0, index,
181    i-index)).replace('/', File.separatorChar);
182  1 if (fname.startsWith(File.separator)) {
183  1 fname = fname.substring(1);
184    }
185  1 File targ = new File(root, fname);
186  1 if (targ.isDirectory()) {
187  0 File ind = new File(targ, "index.html");
188  0 if (ind.exists()) {
189  0 targ = ind;
190    }
191    }
192  1 boolean OK = printHeaders(targ, ps);
193  1 if (doingGet) {
194  1 if (OK) {
195  1 sendFile(targ, ps);
196    } else {
197  0 send404(targ, ps);
198    }
199    }
200    } finally {
201  1 s.close();
202    }
203    }
204   
 
205  1 toggle boolean printHeaders(File targ, PrintStream ps) throws IOException {
206  1 boolean ret = false;
207  1 int rCode = 0;
208  1 if (!targ.exists()) {
209  0 rCode = HTTP_NOT_FOUND;
210  0 ps.print("HTTP/1.0 " + HTTP_NOT_FOUND + " not found");
211  0 ps.write(EOL);
212  0 ret = false;
213    } else {
214  1 rCode = HTTP_OK;
215  1 ps.print("HTTP/1.0 " + HTTP_OK+" OK");
216  1 ps.write(EOL);
217  1 ret = true;
218    }
219  1 log("From " +s.getInetAddress().getHostAddress()+": GET " +
220    targ.getAbsolutePath()+"-->"+rCode);
221  1 ps.print("Server: Simple java");
222  1 ps.write(EOL);
223  1 ps.print("Date: " + (new Date()));
224  1 ps.write(EOL);
225  1 if (ret) {
226  1 if (!targ.isDirectory()) {
227  1 ps.print("Content-length: "+targ.length());
228  1 ps.write(EOL);
229  1 ps.print("Last Modified: " + (new
230    Date(targ.lastModified())));
231  1 ps.write(EOL);
232  1 String name = targ.getName();
233  1 int ind = name.lastIndexOf('.');
234  1 String ct = null;
235  1 if (ind > 0) {
236  1 ct = (String) map.get(name.substring(ind));
237    }
238  1 if (ct == null) {
239  0 ct = "unknown/unknown";
240    }
241  1 ps.print("Content-type: " + ct);
242  1 ps.write(EOL);
243    } else {
244  0 ps.print("Content-type: text/html");
245  0 ps.write(EOL);
246    }
247    }
248  1 return ret;
249    }
250   
 
251  0 toggle void send404(File targ, PrintStream ps) throws IOException {
252  0 ps.write(EOL);
253  0 ps.write(EOL);
254  0 ps.println("Not Found\n\n"+
255    "The requested resource was not found.\n");
256    }
257   
 
258  1 toggle void sendFile(File targ, PrintStream ps) throws IOException {
259  1 InputStream is = null;
260  1 ps.write(EOL);
261  1 if (targ.isDirectory()) {
262  0 listDirectory(targ, ps);
263  0 return;
264    } else {
265  1 is = new FileInputStream(targ.getAbsolutePath());
266    }
267   
268  1 try {
269  1 int n;
270  ? while ((n = is.read(buf)) > 0) {
271  1 ps.write(buf, 0, n);
272    }
273    } finally {
274  1 is.close();
275    }
276    }
277   
278    /* mapping of file extensions to content-types */
279    static java.util.Hashtable map = new java.util.Hashtable();
280   
 
281  2 toggle static {
282  2 fillMap();
283    }
 
284  48 toggle static void setSuffix(String k, String v) {
285  48 map.put(k, v);
286    }
287   
 
288  2 toggle static void fillMap() {
289  2 setSuffix("", "content/unknown");
290  2 setSuffix(".uu", "application/octet-stream");
291  2 setSuffix(".exe", "application/octet-stream");
292  2 setSuffix(".ps", "application/postscript");
293  2 setSuffix(".zip", "application/zip");
294  2 setSuffix(".sh", "application/x-shar");
295  2 setSuffix(".tar", "application/x-tar");
296  2 setSuffix(".snd", "audio/basic");
297  2 setSuffix(".au", "audio/basic");
298  2 setSuffix(".wav", "audio/x-wav");
299  2 setSuffix(".gif", "image/gif");
300  2 setSuffix(".jpg", "image/jpeg");
301  2 setSuffix(".jpeg", "image/jpeg");
302  2 setSuffix(".htm", "text/html");
303  2 setSuffix(".html", "text/html");
304  2 setSuffix(".text", "text/plain");
305  2 setSuffix(".c", "text/plain");
306  2 setSuffix(".cc", "text/plain");
307  2 setSuffix(".c++", "text/plain");
308  2 setSuffix(".h", "text/plain");
309  2 setSuffix(".pl", "text/plain");
310  2 setSuffix(".txt", "text/plain");
311  2 setSuffix(".log", "text/plain");
312  2 setSuffix(".java", "text/plain");
313    }
314   
 
315  0 toggle void listDirectory(File dir, PrintStream ps) {
316  0 ps.println("<TITLE>Directory listing</TITLE><P>\n");
317  0 ps.println("<A HREF=\"..\">Parent Directory</A><BR>\n");
318  0 String[] list = dir.list();
319  0 for (int i = 0; list != null && i < list.length; i++) {
320  0 File f = new File(dir, list[i]);
321  0 if (f.isDirectory()) {
322  0 ps.println("<A HREF=\""+list[i]+"/\">"+list[i]+"/</A><BR>");
323    } else {
324  0 ps.println("<A HREF=\""+list[i]+"\">"+list[i]+"</A><BR>");
325    }
326    }
327  0 ps.println("<P><HR><BR><I>" + (new Date()) + "</I>");
328    }
329   
 
330  3 toggle void log(final String msg) {
331  3 if (debug) {
332  3 System.out.println(msg);
333    }
334    }
335    }
336   
337