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 ("" +
"
"+desc+ "
Cristal Item HTTP server"); } }