A web server is an application which delivers web pages using HTTP
protocol
The application explained below is a simple http server application which runs on port 8080
and serves contents from the directory C:/Web
. The server handles each client request in a new worker thread.package com.pankaj.webserver; import java.io.IOException; import java.net.ServerSocket; import java.net.Socket; /** * File: WebServer.java */ public class WebServer { private static final int PORT = 8080; private static ServerSocket listenerSocket = null; private static int requestId = 0; public static void main(String[] args) throws IOException { ConsoleLogger.LogMessage("Starting simple http server"); listenerSocket = new ServerSocket(PORT); ConsoleLogger.LogMessage("Server started on port " + listenerSocket.getLocalPort()); while (true) { Socket socket = listenerSocket.accept(); ConsoleLogger.LogMessage("Client connected on port " + socket.getPort()); new Worker(new RequestHandler(++requestId, socket)); } } }
The
RequestHandler
class is an implementation of Runnable
interface and parses the request from the client, processes it and sends the response back to the client.1.
HTTP/1.1 400 Bad Request
if the request is malformed or null2.
HTTP/1.1 403 Forbidden
if the request is for listing a directory3.
HTTP/1.1 404 Not Found
if the resource requested is not available4.
HTTP/1.1 501 Not Implemented
if the method other than GET
is usedpackage com.pankaj.webserver; import java.io.BufferedOutputStream; import java.io.BufferedReader; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.PrintStream; import java.net.Socket; /** * File: RequestHandler.java */ public class RequestHandler implements Runnable { private static final String WEB_DIR = "C:/Web"; private static final String STR_OK = "Success"; private static final String STR_BAD_REQUEST = "Malformed Request"; private static final String STR_FORBIDDEN = "Directory browsing is forbidden"; private static final String STR_NOT_FOUND = "Requested resource is not found"; private static final String STR_NOT_IMPLEMENTED = "Method is not implemented"; private static final String STR_CRLF = "\r\n"; private Socket socket = null; private String filePath = null; private StatusCode status = null; private int id; private enum StatusCode { OK(200, STR_OK), BAD_REQUEST(400, STR_BAD_REQUEST), FORBIDDEN(403, STR_FORBIDDEN), NOT_FOUND(404, STR_NOT_FOUND), NOT_IMPLEMENTED(501, STR_NOT_IMPLEMENTED); private int val; private String desc; private StatusCode(int sc, String desc) { this.val = sc; this.desc = desc; } public int getValue() { return val; } public String getDescription() { return desc; } } public RequestHandler(int id, Socket socket) { this.id = id; this.socket = socket; } @Override public void run() { BufferedReader in = null; PrintStream out = null; try { // read request from the client in = new BufferedReader(new InputStreamReader(socket.getInputStream())); parseRequest(in); // send the response back to the client out = new PrintStream(new BufferedOutputStream(socket.getOutputStream())); sendResponse(out); } catch (IOException e) { e.printStackTrace(); } finally { close(in); close(out); close(socket); } } // Read filename from the request "GET /filename.html" private void parseRequest(BufferedReader in) throws IOException { String request = in.readLine(); ConsoleLogger.LogMessage(id, request); if (request == null) { status = StatusCode.BAD_REQUEST; return; } if (request.contains("GET")) { String[] tokens = request.split(" "); String fileName = tokens[1]; filePath = getPath(fileName); if (isDirectory(filePath)) { status = StatusCode.FORBIDDEN; } else if (isFile(filePath) == false) { status = StatusCode.NOT_FOUND; } else { status = StatusCode.OK; } } else { status = StatusCode.NOT_IMPLEMENTED; } } private String getPath(String fileName) { return WEB_DIR + fileName; } private boolean isFile(String file) { File f = new File(file); return f.exists() && f.isFile(); } private boolean isDirectory(String file) { return new File(file).isDirectory(); } private void sendResponse(PrintStream out) { StringBuilder respHeader = new StringBuilder(); switch (status) { case BAD_REQUEST: respHeader.append("HTTP/1.1 400 Bad Request"); break; case FORBIDDEN: respHeader.append("HTTP/1.1 403 Forbidden"); break; case NOT_FOUND: respHeader.append("HTTP/1.1 404 Not Found"); break; case NOT_IMPLEMENTED: respHeader.append("HTTP/1.1 501 Not Implemented"); break; default: // OK out.print("HTTP/1.1 200 OK\r\n"); out.print("Content-Type: " + getMimeType(filePath) + "\r\n\r\n"); transferData(out); return; } out.print(respHeader + STR_CRLF); out.print("Content-Type: text/html\r\n\r\n"); out.print("My Simple WebServer (:0)
Error: | " + status.getDescription() + " (" + status.getValue() + ") " + " |
---|
The
Worker
class starts new thread and the ConsoleLogger
is for printing server messages on the console.package com.pankaj.webserver; /** * File: Worker.java */ public class Worker { public Worker(Runnable task) { new Thread(task).start(); } }
package com.pankaj.webserver; import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.Date; /** * File: ConsoleLogger.java */ public class ConsoleLogger { private static final String DATE_FORMAT_NOW = "dd-MM-yyyy HH:mm:ss"; public static void LogMessage(String mesg) { System.out.println("[" + getDateTime() + "]" + mesg); } public static void LogMessage(int id, String mesg) { System.out.println("[" + getDateTime() + "][" + id + "]" + mesg); } private static String getDateTime() { DateFormat dateformat = new SimpleDateFormat(DATE_FORMAT_NOW); Date date = new Date(); return dateformat.format(date); } }
Start the server
The server starts logging requests received from the different clients
Requesting a resource from the client
Make sure you have
C:\Web
directory existing in your machine and you have some html contents in the directory.Sending request from the web browser (firefox)
Trying from
Telnet
clientOpen windows
cmd
prompt and type telnet localhost 8080
. You will be presented an empty window. Type any command and press enter. You will see the response as shown belowIf you enter command in the proper HTTP format as
GET /filename.txt
, you will see a different result in the telnet window as shown below
No comments :
Post a Comment