import java.io.* ; import java.net.* ; import java.util.* ; public final class WebServer { public static void main(String argv[]) throws Exception { int port = 6897; // Establish the listen socket. ServerSocket listenSocket = new ServerSocket(port); while (true) { // Listen for a TCP connection request. Socket connectionSocket = listenSocket.accept(); // Construct an object to process the HTTP request message HttpRequest request = new HttpRequest(connectionSocket); // Create a new thread to process the request. Thread thread = new Thread(request); // Start the thread. thread.start(); } } } final class HttpRequest implements Runnable { final static String CRLF = "\r\n"; Socket socket; // Constructor public HttpRequest(Socket socket) throws Exception { this.socket = socket; } // Implement the run() method of the Runnable interface. public void run() { try { processRequest(); } catch (Exception e) { System.out.println(e); } } private void processRequest() throws Exception { // Get a reference to the socket's input and output streams. InputStream is = socket.getInputStream(); DataOutputStream os = new DataOutputStream(socket.getOutputStream()); // Set up input stream filters. BufferedReader br = new BufferedReader(new InputStreamReader(is)); //Get the request line of the HTTP request message. String requestLine = br.readLine(); //Extract the filename from the request line. StringTokenizer tokens = new StringTokenizer(requestLine); boolean badRequest = false; boolean methodNotImplemented = false; String fileName = null; String version = null; String command = tokens.nextToken(); if (tokens.hasMoreTokens()) { fileName = tokens.nextToken(); // Prepend a "." so that file request is within the current directory. fileName = "." + fileName; } else { badRequest = true; } if (tokens.hasMoreTokens()) { version = tokens.nextToken(); } else { badRequest = true; } if (tokens.hasMoreTokens()) { badRequest = true; } boolean fileExists = true; boolean fileOpen = true; FileOutputStream fos = null; FileInputStream fis = null; if (!((command.equals("GET")) || (command.equals("HEAD")) || (command.equals("PUT")))) { methodNotImplemented = true; } if (!version.matches("HTTP/.[.].")) { System.out.println("Version pattern mismatch"); badRequest = true; } // Construct the response message. String statusLine = null; String contentTypeLine = null; String entityBody = null; if (badRequest) { statusLine = "HTTP/1.0 400 Bad Request" + CRLF; contentTypeLine = "Content-type: " + "text/html" + CRLF; entityBody = "" + "Bad Request" + "" + requestLine + " is a bad request" + CRLF; } if (methodNotImplemented) { statusLine = "HTTP/1.0 501 Method Not Implemented" + CRLF; contentTypeLine = "Content-type: " + "text/html" + CRLF; entityBody = "" + "Method Not Implemented" + " Method " + command + " Not Implemented" + CRLF; } if (!(badRequest || methodNotImplemented)) { if (command.equals("PUT")) { try { fos = new FileOutputStream(fileName); } catch (Exception e) { fileOpen = false; } } else { // Open the requested file. try { fis = new FileInputStream(fileName); } catch (FileNotFoundException e) { System.out.println("File not found"); fileExists = false; } } if (fileExists && fileOpen) { statusLine = "HTTP/1.0 200 OK" + CRLF; contentTypeLine = "Content-type: " + contentType(fileName) + CRLF; } else { if (!(fileExists)) { statusLine = "HTTP/1.0 404 Not Found" + CRLF; contentTypeLine = "Content-type: " + "text/html" + CRLF; entityBody = "" + "Not Found" + "File " + fileName + " Not Found" + CRLF; } else { statusLine = "HTTP/1.0 404 Not Found" + CRLF; contentTypeLine = "Content-type: " + "text/html" + CRLF; entityBody = "" + "Not Found" + "File " + fileName + " could not be written" + CRLF; } } } // Send the status line. os.writeBytes(statusLine); // Send the content-type line. os.writeBytes(contentTypeLine); // Send a blank line to indicate the end of the header lines. os.writeBytes(CRLF); // Send the entity body. if (!(badRequest || methodNotImplemented) && (fileExists && fileOpen)) { if (command.equals("PUT")) { try { int character; // Read the input data one character at a time until end // of stream reached character = br.read(); while (character != -1) { fos.write(character); character = br.read(); } fos.close(); } catch (Exception e) { fos.close(); } } else { if (command.equals("GET")) { try { sendBytes(fis, os); } catch (Exception e) { System.out.println("Exception raised"); } } fis.close(); } } else { System.out.println(entityBody); os.writeBytes(entityBody); } //Display the request line. System.out.println(); System.out.println(requestLine); os.close(); br.close(); socket.close(); } private static void sendBytes(FileInputStream fis, OutputStream os) throws Exception { // Construct a 1K buffer to hold bytes on their way to the socket. byte[] buffer = new byte[1024]; int bytes = 0; // Copy requested file into the socket's output stream. while ((bytes = fis.read(buffer)) != -1) { os.write(buffer, 0, bytes); } } private static String contentType(String fileName) { if (fileName.endsWith(".htm") || fileName.endsWith(".html")) { return "text/html"; } if (fileName.endsWith(".jpg") || fileName.endsWith(".jpeg")) { return "image/jpeg"; } if (fileName.endsWith(".gif")) { return "image/gif"; } if (fileName.endsWith(".txt")) { return "text/plain"; } if (fileName.endsWith(".pdf")) { return "application/pdf"; } return "application/octet-stream"; } }