import java.net.*; import java.io.*; import java.util.*; /* * EasyWebServer is a simple web server that can provide limited * service. Specifically, it can return one of the three pages:
*
* * @param fileIn a pointer to the buffered reader where the client * sends in the information. * @author Xiannong Meng */ public static String readAll(BufferedReader fileIn) { String inBuffer = ""; try { String line; do { line = fileIn.readLine(); inBuffer += line + "\r\n"; // System.out.print("in readAll -> " + line + "<-"); if (line.length() == 2 && line.compareTo("\r\n") == 0) { System.out.println("we hit the break in readAll"); break; } } while (line.length() > 0); } catch (IOException ignored) {}; System.out.println("\n end of readAll -> " + inBuffer + "<-"); return inBuffer; } /* * Process the request (cmd) by a client. Determine what to * do based on the parsing result.
* * The results are directly written to the output stream back * to the client.
* * @param cmd the client request * @param sockIn socket input stream * @param sockOut socket output stream * * @author Xiannong Meng * */ public static void processHTTPCmd(String cmd, BufferedReader sockIn, DataOutputStream sockOut) { String operation; // the operation requested String path; // the path to the HTML doc String version; // version of http int returnStatus = 200; // status of operation long returnLength = 0; // length of the doc to return boolean isForm = false; // by default it is not a form input /* take the input command and split it into tokens */ /* here is an example of the command */ /* get /path http/1.0 \r\n */ StringTokenizer tokens = new StringTokenizer(cmd, " \r\n"); operation = (tokens.nextToken()).toUpperCase(); path = tokens.nextToken(); version = (tokens.nextToken()).toUpperCase(); /* for debugging purpose */ System.out.println("operation: " + operation); System.out.println("path: " + path); System.out.println("version: " + version); /* check for a request that we dont' understand */ if ((operation.compareTo("GET") != 0 && operation.compareTo("POST") != 0) || ((version.compareTo("HTTP/1.0") != 0) && (version.compareTo("HTTP/1.1") != 0))) { returnStatus = 400; returnLength = ERROR_400.length(); } else /* the request is trying to get some HTML page */ if (path.compareTo("/") == 0) { returnStatus = 200; returnLength = HOME_PAGE.length(); } else if (path.compareTo("/sample.html") == 0) { returnStatus = 200; File f = new File("sample.html"); returnLength = f.length(); } else if (path.compareTo("/search") == 0) { returnStatus = 200; File f = new File("form.html"); returnLength = f.length(); } else if (path.compareTo("/cross.gif") == 0) { returnStatus = 200; File f = new File("cross.gif"); returnLength = f.length(); } else if (path.compareTo("/form") == 0) isForm = true; else /* the page is unknown */ { returnStatus = 404; returnLength = ERROR_404.length(); } /* now that we know what to do, send the result back */ if (isForm == true) // this is a form request { processForm(sockIn, sockOut); } else try { if (path.compareTo("/cross.gif") == 0) sendHeader(sockOut, returnStatus, returnLength, "image/gif"); else sendHeader(sockOut, returnStatus, returnLength, "text/html"); switch (returnStatus) { case 200: // send the page requested if (path.compareTo("/") == 0) sockOut.writeBytes(HOME_PAGE); // short page else if (path.compareTo("/sample.html") == 0) openAndSendFile(sockOut, "sample.html"); // long page else if (path.compareTo("/cross.gif") == 0) openAndSendFile(sockOut, "cross.gif"); // image page else openAndSendFile(sockOut, "form.html"); // a test form break; case 400: sockOut.writeBytes(ERROR_400); break; case 404: sockOut.writeBytes(ERROR_404); break; } } catch (IOException ignored) {} } /* * Send the returning header to the client, based on the return * status. The response must follow the HTTP protocol.
* * @param out output stream of the socket * @param returnStatus the numerical code for the returning status * @param contentLength the length of the content (not the header) * @param contentType the type of the return content * * @author Xiannong Meng * */ static void sendHeader(DataOutputStream out, int returnStatus, long contentLength, String contentType) { String statusStr; String returnContent; switch (returnStatus) { case 200: statusStr = "OK"; break; case 400: statusStr = "Bad Request"; break; case 404: statusStr = "Not Found"; break; default: statusStr = "Unknown"; break; } /* * send an HTTP/1.0 response with Server, Content-Length, * and Content-Type headers. */ try { returnContent = "HTTP/1.0 " + returnStatus + " " + statusStr + "\r\n"; out.writeBytes(returnContent); returnContent = "Server: " + SERVER_NAME + "\r\n"; out.writeBytes(returnContent); returnContent = "Content-Length: " + contentLength + "\r\n"; out.writeBytes(returnContent); returnContent = "Content-Type: " + contentType + "\r\n"; out.writeBytes(returnContent); returnContent = "\r\n"; out.writeBytes(returnContent); } catch (IOException ignored){} } /* * Send the file requested to the output stream (client).
* * @param out output stream to the client. * @param fileToSend string name of the file to be sent. * * @author Xiannong Meng * */ static void openAndSendFile(DataOutputStream out, String fileToSend) { try { DataInputStream fileIn = new DataInputStream (new FileInputStream (new File(fileToSend))); File f = new File(fileToSend); long length = f.length(); byte[] content = new byte[(int)length]; fileIn.readFully(content); out.write(content); } catch (IOException ignored) {}; } /* * Process the form sent from the client. The content of the form * has been stored in http_data, a member of the class.
*
* @param sockIn input stream from the client.
* @param sockOut output stream to the client
*
*/
public static void processForm(BufferedReader sockIn,
DataOutputStream sockOut)
{
try
{
String inBuffer;
String returnString = "";
int returnStatus;
int returnLength;
int dataLength = Integer.parseInt
((http_data.get("content-length")).trim());
System.out.println("data length " + dataLength);
char[] inChars = new char[dataLength];
sockIn.read(inChars, 0, dataLength);
inBuffer = new String(inChars);
// for debugging only
System.out.print(inBuffer);
//
// Parse the CGI input string
//
Hashtable The server couldn't understand your request.\n";
// error message 404
static String ERROR_404 = " Document not found.\n";
// a simple, short home page
static String HOME_PAGE = " Why not visit:
";
//
// Create the Bottom of the returned HTML page - which closes it cleanly.
//
returnString += Html.HtmlBot();
//
// Print the required CGI header.
//
returnStatus = 200;
returnLength = returnString.length();
sendHeader(sockOut, returnStatus, returnLength, "text/html");
//
// Send back the contents
//
sockOut.writeBytes(returnString);
}
catch (IOException ignored) {};
}
/* this is the class data segments */
static int PORT; // the port used for communication
static HashtableError 400
Error 404
Welcome to the Web IR Demo Server