Notice

╠ This is my personal blog and my posts here have nothing to do with my employers or any other association I may have. It is my personal blog for my personal experience, ideas and notes. ╣
Showing posts with label How a Http Server works and make a simple web server for yourself. Show all posts
Showing posts with label How a Http Server works and make a simple web server for yourself. Show all posts

Sunday, March 20, 2016

How a Http Server works and develop a simple web server for yourself


I worked with HTTP Servers for a long time but I never tried to explore how an HTTP server works, so let do it together.

What is an HTTP server actually? 

A server which runs in a computer to serve HTTP request from remote browsers.

How it works?

As a user when we type an URL (Unified Resource Locator) in our browser it sends an HTTP request to the internet then it forwarded to the concerned server, the server process the request and send back HTTP response to the client browser.

Okay, it sounds simple to make HTTP server work. 

Let's get into it.
A Server class which creates a server program, do initial setup for web server operation like port number, file directory etc then it run in an infinite loop and wait for requests.

/**
* @Author Anindya Bandopadhyay
*
* SimpleHttpWebServer\andy.blog.web.server.Server.java
*
* @Created on Sep 14, 2014 6:55:31 PM
*/
package andy.blog.web.server;
import java.io.File;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import andy.blog.constant.ServerConstant;
public class Server {
private boolean serverStart = true;
private int port = ServerConstant.PORT;
private String webRootPath = ServerConstant.DEFAULT_WEB_ROOT;
private File webRootDir = new File(ServerConstant.WORKING_DIR, webRootPath);
public static void main(String[] args) {
Server server = new Server();
server.initialSetUp(args);
server.waitForClient();
}
private void initialSetUp(String[] args) {
for (int index = 0; index < args.length; index++) {
switch (index) {
case 0:
break;
case 1:
try {
port = Integer.valueOf(args[1]);
} catch (NumberFormatException e) {
throw new IllegalArgumentException("Port number must be numeric.");
}
break;
case 2:
webRootPath = args[2];
webRootDir = new File(ServerConstant.WORKING_DIR, webRootPath);
if (!(webRootDir.exists() && webRootDir.isDirectory())) {
throw new IllegalArgumentException("Web root '" + webRootPath + "' folder doesn't exist");
}
break;
default:
break;
}
}
}
private void waitForClient() {
ServerSocket serverSocket = null;
try {
serverSocket = new ServerSocket(port, 1, InetAddress.getByName(ServerConstant.HOSTNAME));
} catch (Exception e) {
e.printStackTrace();
System.exit(1);
}
while (serverStart) {
Socket socket = null;
InputStream inputStream = null;
OutputStream outputStream = null;
try {
socket = serverSocket.accept();
inputStream = socket.getInputStream();
outputStream = socket.getOutputStream();
Request httpRequest = new Request();
String resource = httpRequest.getUri(inputStream);
System.out.println("\nRequested resource = " + resource);
Response httpResponse = new Response();
httpResponse.processResponse(outputStream, webRootDir, resource);
inputStream.close();
outputStream.close();
socket.close();
} catch (Exception e) {
e.printStackTrace();
continue; // We want server to keep running...
}
}
}
}
view raw Server.java hosted with ❤ by GitHub

In request object we are going to process the HTTP request coming from client browsers. In Request.java class we are going to process the request and see the URLs browsers are requesting are valid or not.
In request class we are read the request from socket request stream and striping up the requested page name.


/**
* @Author Anindya Bandopadhyay
*
* SimpleHttpWebServer\andy.blog.web.server.Request.java
*
* @Created on Sep 14, 2014 6:55:52 PM
*/
package andy.blog.web.server;
import java.io.IOException;
import java.io.InputStream;
import andy.blog.constant.ServerConstant;
public class Request {
public String getUri(InputStream inputStream) {
byte buffer[] = new byte[ServerConstant.BUFFER_SIZE];
StringBuffer inputBuffer = new StringBuffer(ServerConstant.BUFFER_SIZE);
int byteRequest;
try {
byteRequest = inputStream.read(buffer);
} catch (IOException e) {
e.printStackTrace();
byteRequest = -1;
}
for (int index = 0; index < byteRequest; index++) {
inputBuffer.append((char) buffer[index]);
}
String request = inputBuffer.toString();
System.out.println(request);
return parseUri(request);
}
private String parseUri(String requestString) {
// GET /index.html HTTP/1.1
// strip out '/index.html' from request string
String[] resource = requestString.split(" ");
return resource[1];
}
}
view raw Request.java hosted with ❤ by GitHub

Now let work on HTTP response. In this class we create a response and send it back to requesting browser.
So what we are doing here is we are looking at a specific location where all the web files should be present and if the requested page found then simply write it to socket output stream.
/**
* @Author Anindya Bandopadhyay
*
* SimpleHttpWebServer\andy.blog.web.server.Response.java
*
* @Created on Sep 14, 2014 6:56:11 PM
*/
package andy.blog.web.server;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStream;
public class Response {
private static final int BUFFER_SIZE = 1024;
String success = "HTTP/1.1 200 OK\r\nConnection: close\r\n"+
"Server: Anindya's Server v1\r\nContent-Type: text/html\r\n\r\n";
public void processResponse(OutputStream outputStream, File rootDir, String resource) throws IOException {
byte buffer[] = new byte[BUFFER_SIZE];
FileInputStream fileInputStream = null;
try {
File file = new File(rootDir, resource);
System.out.println(file.getAbsolutePath());
if (file.exists()) {
outputStream.write(success.getBytes());
fileInputStream = new FileInputStream(file);
int character = fileInputStream.read(buffer, 0, BUFFER_SIZE);
while (character != -1) {
outputStream.write(buffer, 0, character);
character = fileInputStream.read(buffer, 0, BUFFER_SIZE);
}
} else {
String notFound = "HTTP/1.1 404 File Not Found\r\n" + "Content-Type: text/html\r\n" + "Content-Length: 23\r\n"
+ "\r\n" + "<h1>Page Not Found</h1>";
outputStream.write(notFound.getBytes());
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if (fileInputStream != null) {
fileInputStream.close();
}
}
}
}
view raw Response.java hosted with ❤ by GitHub



Source Code of SimpleHttpWebServer

Welcome to Anindya's Simple Web Server