package com.c2kernel.utils.server; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.OutputStream; import java.net.Socket; import java.util.Date; import java.util.HashMap; import java.util.NoSuchElementException; import java.util.StringTokenizer; import com.c2kernel.utils.Logger; public class HTTPRequestHandler implements SocketHandler { protected HashMap headers = new HashMap(); protected String method; protected String resource; protected String version; protected String returnMIME; protected String statusCode; protected String postData; protected final static String CRLF = "\r\n"; protected BufferedReader request; protected Socket currentSocket = null; public HTTPRequestHandler() { } public String getName() { return "HTTP Server"; } public boolean isBusy() { return (currentSocket!=null); } public void setSocket(Socket newSocket) { currentSocket = newSocket; } public void shutdown() { try { if (currentSocket != null) currentSocket.close(); } catch (IOException e) { Logger.error("Error shutting down HTTP connection"); } currentSocket = null; } public void run() { Thread.currentThread().setName("HTTP Request Handler"); try { request = new BufferedReader(new InputStreamReader(currentSocket.getInputStream())); // parse the request boolean firstLine = true; String headerLine; do { headerLine = request.readLine(); if (headerLine == null) throw new IOException("Disconnected"); if (firstLine) { // request line StringTokenizer params = new StringTokenizer(headerLine); try { method = params.nextToken(); resource = params.nextToken(); version = params.nextToken(); } catch (NoSuchElementException ex1) { } // incomplete request line - doesn't matter firstLine = false; } else { // headers int split = headerLine.indexOf(": "); if (split >= 0) headers.put( headerLine.substring(0, split), headerLine.substring(split+2) ); } } while (!headerLine.equals(CRLF) && !headerLine.equals("")); String response = null; try { if (headers.containsKey("Content-length")) { // read POST data StringBuffer postBuffer = new StringBuffer(); int received = 0; int length = Integer.parseInt((String)headers.get("Content-length")); try { while (received < length) { String postLine = request.readLine(); postBuffer.append(postLine); received+=postLine.length(); } } catch (IOException ex) { Logger.error("Error reading post data. "+received+" bytes of "+length+" received. ("+(received*100.0/length)+"%"); Logger.error(ex); throw ex; } } // Got the params, generate response returnMIME = "text/xml"; statusCode = "200 OK"; response = processRequest(); } catch (Exception ex3) { response = error("500 Server Error", ex3.getClass().getName()+"
"+ex3.getMessage()); } System.out.println(new Date().toString()+" "+currentSocket.getInetAddress()+" "+method+" "+resource+" "+statusCode); OutputStream output = currentSocket.getOutputStream(); statusCode = "HTTP/1.0 "+statusCode+CRLF; output.write(statusCode.getBytes()); returnMIME = "Content-type: "+returnMIME+CRLF; output.write(returnMIME.getBytes()); String contentLength = "Content-Length: "+response.length()+CRLF; output.write(contentLength.getBytes()); // Possible: last mod? // end of headers output.write(CRLF.getBytes()); // write the content output.write(response.getBytes()); request.close(); output.close(); currentSocket.close(); } catch (IOException ex2) { Logger.error(ex2); } // aborted connection probably currentSocket = null; } /* This is a dummy method that doesn't support anything. * Override it. */ public String processRequest() { return error("501 Not Implemented", "The method "+method+" you have requested is not supported by this server."); } public String error(String code, String desc) { statusCode = code; returnMIME = "text/html"; return ("" + ""+code+"" + "

"+code+"

" + "

"+desc+ "


Cristal Item HTTP server"); } }