1 |
|
package org.qedeq.base.test; |
2 |
|
|
3 |
|
|
4 |
|
|
5 |
|
|
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 |
|
|
|
|
| 69.2% |
Uncovered Elements: 64 (208) |
Complexity: 46 |
Complexity Density: 0.31 |
|
19 |
|
public class WebServerWorker implements Runnable { |
20 |
|
|
21 |
|
|
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 |
|
|
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 |
|
|
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 |
|
|
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 |
|
|
76 |
|
byte[] buf; |
77 |
|
|
78 |
|
private Socket s; |
79 |
|
|
80 |
|
private final ServerSocket ss; |
81 |
|
|
|
|
| 100% |
Uncovered Elements: 0 (6) |
Complexity: 1 |
Complexity Density: 0.17 |
|
82 |
1
|
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 |
|
|
|
|
| 88.9% |
Uncovered Elements: 1 (9) |
Complexity: 3 |
Complexity Density: 0.43 |
|
91 |
1
|
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 |
|
|
|
|
| 64.9% |
Uncovered Elements: 27 (77) |
Complexity: 23 |
Complexity Density: 0.47 |
|
104 |
1
|
void handleClient() throws IOException {... |
105 |
1
|
InputStream is = new BufferedInputStream(s.getInputStream()); |
106 |
1
|
PrintStream ps = new PrintStream(s.getOutputStream()); |
107 |
|
|
108 |
|
|
109 |
|
|
110 |
|
|
111 |
1
|
s.setSoTimeout(timeout); |
112 |
1
|
s.setTcpNoDelay(true); |
113 |
|
|
114 |
2049
|
for (int i = 0; i < BUF_SIZE; i++) { |
115 |
2048
|
buf[i] = 0; |
116 |
|
} |
117 |
1
|
try { |
118 |
|
|
119 |
|
|
120 |
|
|
121 |
|
|
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 |
|
|
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 |
|
|
137 |
1
|
break outerloop; |
138 |
|
} |
139 |
|
} |
140 |
|
} |
141 |
|
|
142 |
|
|
143 |
1
|
boolean doingGet; |
144 |
|
|
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 |
|
|
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 |
|
|
172 |
|
|
173 |
|
|
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 |
|
|
|
|
| 72.7% |
Uncovered Elements: 12 (44) |
Complexity: 6 |
Complexity Density: 0.18 |
|
205 |
1
|
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 |
|
|
|
|
| 0% |
Uncovered Elements: 3 (3) |
Complexity: 1 |
Complexity Density: 0.33 |
|
251 |
0
|
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 |
|
|
|
|
| 66.7% |
Uncovered Elements: 5 (15) |
Complexity: 3 |
Complexity Density: 0.27 |
|
258 |
1
|
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 |
|
|
279 |
|
static java.util.Hashtable map = new java.util.Hashtable(); |
280 |
|
|
|
|
| 100% |
Uncovered Elements: 0 (1) |
Complexity: 1 |
Complexity Density: 1 |
|
281 |
2
|
static {... |
282 |
2
|
fillMap(); |
283 |
|
} |
|
|
| 100% |
Uncovered Elements: 0 (1) |
Complexity: 1 |
Complexity Density: 1 |
|
284 |
48
|
static void setSuffix(String k, String v) {... |
285 |
48
|
map.put(k, v); |
286 |
|
} |
287 |
|
|
|
|
| 100% |
Uncovered Elements: 0 (24) |
Complexity: 1 |
Complexity Density: 0.04 |
|
288 |
2
|
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 |
|
|
|
|
| 0% |
Uncovered Elements: 13 (13) |
Complexity: 4 |
Complexity Density: 0.44 |
|
315 |
0
|
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 |
|
|
|
|
| 75% |
Uncovered Elements: 1 (4) |
Complexity: 2 |
Complexity Density: 1 |
|
330 |
3
|
void log(final String msg) {... |
331 |
3
|
if (debug) { |
332 |
3
|
System.out.println(msg); |
333 |
|
} |
334 |
|
} |
335 |
|
} |
336 |
|
|
337 |
|
|