1 9 package com.roblisa.classfinder; 10 11 import java.io.*; 12 import java.net.*; 13 import java.util.*; 14 import java.text.*; 15 16 public abstract class WebHandler implements Runnable 17 { 18 19 public static final int HTTP_OK = 200; 20 public static final int HTTP_CREATED = 201; 21 public static final int HTTP_ACCEPTED = 202; 22 public static final int HTTP_NOT_AUTHORITATIVE = 203; 23 public static final int HTTP_NO_CONTENT = 204; 24 public static final int HTTP_RESET = 205; 25 public static final int HTTP_PARTIAL = 206; 26 27 28 public static final int HTTP_MULT_CHOICE = 300; 29 public static final int HTTP_MOVED_PERM = 301; 30 public static final int HTTP_MOVED_TEMP = 302; 31 public static final int HTTP_SEE_OTHER = 303; 32 public static final int HTTP_NOT_MODIFIED = 304; 33 public static final int HTTP_USE_PROXY = 305; 34 35 36 public static final int HTTP_BAD_REQUEST = 400; 37 public static final int HTTP_UNAUTHORIZED = 401; 38 public static final int HTTP_PAYMENT_REQUIRED = 402; 39 public static final int HTTP_FORBIDDEN = 403; 40 public static final int HTTP_NOT_FOUND = 404; 41 public static final int HTTP_BAD_METHOD = 405; 42 public static final int HTTP_NOT_ACCEPTABLE = 406; 43 public static final int HTTP_PROXY_AUTH = 407; 44 public static final int HTTP_CLIENT_TIMEOUT = 408; 45 public static final int HTTP_CONFLICT = 409; 46 public static final int HTTP_GONE = 410; 47 public static final int HTTP_LENGTH_REQUIRED = 411; 48 public static final int HTTP_PRECON_FAILED = 412; 49 public static final int HTTP_ENTITY_TOO_LARGE = 413; 50 public static final int HTTP_REQ_TOO_LONG = 414; 51 public static final int HTTP_UNSUPPORTED_TYPE = 415; 52 53 54 public static final int HTTP_SERVER_ERROR = 500; 55 public static final int HTTP_INTERNAL_ERROR = 501; 56 public static final int HTTP_BAD_GATEWAY = 502; 57 public static final int HTTP_UNAVAILABLE = 503; 58 public static final int HTTP_GATEWAY_TIMEOUT = 504; 59 public static final int HTTP_VERSION = 505; 60 61 private static final int MAX_HANDLERS=5; 62 63 private static final String IF_MODIFIED_SINCE="If-Modified-Since: "; 64 65 66 private static final Map mimeTypes = new HashMap(); 67 68 static 69 { 70 mimeTypes.put("", "content/unknown"); 71 mimeTypes.put(".uu", "application/octet-stream"); 72 mimeTypes.put(".exe", "application/octet-stream"); 73 mimeTypes.put(".ps", "application/postscript"); 74 mimeTypes.put(".zip", "application/zip"); 75 mimeTypes.put(".sh", "application/x-shar"); 76 mimeTypes.put(".tar", "application/x-tar"); 77 mimeTypes.put(".snd", "audio/basic"); 78 mimeTypes.put(".au", "audio/basic"); 79 mimeTypes.put(".wav", "audio/x-wav"); 80 mimeTypes.put(".gif", "image/gif"); 81 mimeTypes.put(".jpg", "image/jpeg"); 82 mimeTypes.put(".jpeg", "image/jpeg"); 83 mimeTypes.put(".htm", "text/html"); 84 mimeTypes.put(".html", "text/html"); 85 mimeTypes.put(".text", "text/plain"); 86 mimeTypes.put(".c", "text/plain"); 87 mimeTypes.put(".cc", "text/plain"); 88 mimeTypes.put(".c++", "text/plain"); 89 mimeTypes.put(".h", "text/plain"); 90 mimeTypes.put(".pl", "text/plain"); 91 mimeTypes.put(".txt", "text/plain"); 92 mimeTypes.put(".java", "text/x-java-source"); 93 mimeTypes.put(".lnk", "text/plain"); 94 mimeTypes.put(".css", "text/css"); 95 } 96 97 private static DateFormat df=new SimpleDateFormat("EEE, dd MMM yyyy hh:mm:ss zzz"); 98 static 99 { 100 df.setTimeZone(TimeZone.getTimeZone("GMT")); 101 } 102 103 static final byte[] EOL = {(byte)'\r', (byte)'\n' }; 104 static List handlers=new ArrayList(); 105 static PrintStream log = System.out; 106 107 private Socket s; 108 private PrintStream ps; 109 private ByteArrayOutputStream content; 110 long ifModifiedSince=-1; 111 long lastModified=-1; 112 String path; 113 boolean responseSent=false; 114 boolean doingGet=false; 115 116 public boolean isLocalHost() 117 { 118 return s!=null&&s.getInetAddress().getHostAddress().equals("127.0.0.1"); 119 } 120 121 public static void setLog(PrintStream ps) 122 { 123 log=ps; 124 } 125 126 protected static void log(String s) { 127 synchronized (log) { 128 log.println(s); 129 log.flush(); 130 } 131 } 132 133 134 public long parseDate(String date) 135 { 136 try 137 { 138 return df.parse(date).getTime(); 139 } 140 catch(ParseException e) 141 { 142 log("Can't parse date: "+date); 143 return -1; 144 } 145 } 146 147 public String formatDate(long date) 148 { 149 return df.format(new Date(date)); 150 } 151 152 public String getServerName() 153 { 154 return "WebHandler"; 155 } 156 157 synchronized void setSocket(Socket s) 158 { 159 this.s = s; 160 notify(); 161 } 162 163 public void getStream(InputStream is,OutputStream os) throws IOException 164 { 165 byte[] buf=new byte[4096]; 166 try { 167 int n; 168 while ((n = is.read(buf)) > 0) { 169 os.write(buf, 0, n); 170 } 171 } finally { 172 is.close(); 173 } 174 } 175 176 public boolean responseHasBeenSent() 177 { 178 return responseSent; 179 } 180 181 public void sendResponse(int rCode,String comment) throws IOException 182 { 183 responseSent=true; 184 ps.print("HTTP/1.1 "); 185 ps.print(rCode); 186 ps.print(' '); 187 ps.print(comment); 188 ps.write(EOL); 189 190 log("From " +s.getInetAddress().getHostAddress()+": GET " + 191 path+"-->"+rCode); 192 ps.print("Server: "+getServerName()); 193 ps.write(EOL); 194 ps.print("Date: " + formatDate(System.currentTimeMillis())); 195 ps.write(EOL); 196 ps.print("Connection: keep-alive"); 197 ps.write(EOL); 198 if (lastModified!=-1) 199 { 200 ps.print("Last-modified: "+formatDate(lastModified)); 201 ps.write(EOL); 202 } 203 if (rCode==HTTP_MOVED_TEMP||rCode==HTTP_MOVED_PERM) 204 { 205 ps.print("Location: "); 206 ps.print(comment); 207 ps.write(EOL); 208 } 209 210 String contentType="text/html"; 211 if (rCode==HTTP_OK) 212 { 213 int q=path.lastIndexOf('?'); 214 if (q==-1) 215 q=path.length(); 216 int slash=path.lastIndexOf('/',q-1); 217 int dot=path.lastIndexOf('.',q-1); 218 219 if (dot==-1||dot<slash) 220 { 221 ps.print("text/html"); 222 } 223 else 224 { 225 String s=(String)mimeTypes.get(path.substring(dot,q)); 226 if (s!=null) 227 contentType=s; 228 } 229 } 230 byte[] bytes=null; 231 if (rCode==HTTP_OK||rCode==HTTP_NOT_FOUND) 232 { 233 bytes=content.toByteArray(); 234 235 ps.print("Content-type: "); 236 ps.print(contentType); 237 ps.write(EOL); 238 239 ps.print("Content-length: "); 240 ps.print(bytes.length); 241 ps.write(EOL); 242 } 243 ps.write(EOL); 244 if (bytes!=null&&doingGet) 245 { 246 ps.write(bytes); 247 } 248 ps.flush(); 249 } 250 251 public boolean setLastModified(long lastModified) 252 { 253 this.lastModified=lastModified; 254 return !(lastModified<=ifModifiedSince); 255 } 256 257 public void handleClient(InputStream is,OutputStream os) throws IOException 258 { 259 BufferedReader br = new BufferedReader(new InputStreamReader(is)); 260 ps = new PrintStream(new BufferedOutputStream(os)); 261 content=new ByteArrayOutputStream(); 262 PrintStream cps=new PrintStream(content); 263 264 log("************* NEW CONNECTION ***********"); 265 266 try 267 { 268 while(true) 269 { 270 responseSent=false; 271 content.reset(); 272 String line=br.readLine(); 273 if (line==null) 274 { 275 log("Client returned null. Closing."); 276 s.close(); 277 return; 278 } 279 String x=null; 280 ifModifiedSince=-1; 281 while((x=br.readLine())!=null&&x.length()>0) 282 { 283 if (x.startsWith(IF_MODIFIED_SINCE)) 284 { 285 ifModifiedSince=parseDate(x.substring(IF_MODIFIED_SINCE.length())); 286 } 287 } 288 289 StringTokenizer st=new StringTokenizer(line); 290 String method=st.nextToken(); 291 path=st.nextToken(); 292 boolean valid=true; 293 doingGet=false; 294 LibClass cla=null; 295 File tempFile=null; 296 297 if (method!=null&&path!=null) 298 { 299 if (method.equals("GET")) 300 doingGet=true; 301 else 302 if (method.equals("HEAD")) 303 doingGet=false; 304 else 305 valid=false; 306 } 307 else 308 valid=false; 309 310 if (!valid) 311 { 312 313 sendResponse(HTTP_BAD_METHOD,"Unsupported method type: "+method); 314 continue; 315 } 316 317 try 318 { 319 lastModified=-1; 320 handleGet(path,cps); 321 if (responseHasBeenSent()) 322 continue; 323 } 324 catch(IOException e) 325 { 326 System.out.println("Error handling: "+path+":"+e); 327 } 328 send404(path,cps); 329 continue; 330 } 331 } 332 catch(IOException e) 333 { 334 System.out.println(e); 335 } 336 finally 337 { 338 s.close(); 339 } 340 System.out.println("*** SOCKET CLOSED ***"); 341 } 342 343 public void handleGet(String path,PrintStream ps) throws IOException 344 { 345 } 346 347 void send404(String path,PrintStream ps) throws IOException 348 { 349 ps.println("<html><head><title>File Not Found</title></head>"); 350 ps.println("<body><center><h1>File Not Found</h1>"); 351 ps.print("The file you were looking for:<br><b>"); 352 ps.print(path); 353 ps.println("</b><br>was not found. Tough luck!"); 354 ps.println("</center></body></html>"); 355 sendResponse(HTTP_NOT_FOUND,"File not found"); 356 } 357 358 public synchronized void run() 359 { 360 while(true) 361 { 362 if (s == null) 363 { 364 365 try 366 { 367 wait(); 368 } 369 catch (InterruptedException e) 370 { 371 372 continue; 373 } 374 } 375 try 376 { 377 handleClient(s.getInputStream(),s.getOutputStream()); 378 } 379 catch (Exception e) 380 { 381 e.printStackTrace(); 382 } 383 386 s = null; 387 synchronized (handlers) 388 { 389 if (handlers.size() >= MAX_HANDLERS) 390 { 391 392 return; 393 } 394 else 395 { 396 handlers.add(this); 397 } 398 } 399 } 400 } 401 } 402 | Popular Tags |