Friday, November 21, 2003

simplest ever web server (from Rahul)

adapted from http://www.oreillynet.com/pub/a/onjava/2003/04/23/java_webserver.html

a very simple web server has been implemented in this example using java. HttpServer is the main class in which a ServerSocket is created the constructor of which is
public ServerSocket(int port, int backLog, InetAddress bindingAddress);

here backlog is the maximum number of simultaneous clients. the port used is 8080 on localhost, 127.0.0.1 . the files in WEB_ROOT directory which points to user.dir can be served. this is the user directory, ~ in linux or My Documents in windows. i have so far tested the code only in linux and am not sure if the space in My Documents will cause problems.

the serverSocket is server socket as in it just opens a port and listens. when a connection is made to this port by a socket opened by a browser or any client it accepts, and the input stream is used to create a Request instance. the request object parses the request for http protocol messages like GET /index.html HTTP/1.1 . it simply seperates /index.html based on the indexof spaces. the request instance uri is used by the response instance. it simply opens the file and pases it to the outputstream. if the file does not exist it simply pases the http file not found message. voila!! as easy as that.


1.

import java.net.Socket;
import java.net.ServerSocket;
import java.net.InetAddress;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.IOException;
import java.io.File;

public class HttpServer {

//set the directory containig files here
public static final String WEB_ROOT =
System.getProperty("user.dir");

public static void main(String[] args) {
System.out.println(System.getProperty("user.dir").toString());
HttpServer server = new HttpServer();
server.await();
}

public void await() {
ServerSocket serverSocket = null;
//set the port number
int port = 8080;
try {
serverSocket = new ServerSocket(port, 10, InetAddress.getByName("127.0.0.1"));
}
catch (IOException e) {
e.printStackTrace();
System.exit(1);
}

//loop waiting for a request
while (true) {
Socket socket = null;
//create streams for input and output
InputStream input = null;
OutputStream output = null;
try {
socket = serverSocket.accept();
input = socket.getInputStream();
output = socket.getOutputStream();

//create Request object and parse
Request request = new Request(input);
request.parse();

//create Response object
Response response = new Response(output);
response.setRequest(request);
response.sendStaticResource();

//close the socket
socket.close();
}
catch (Exception e) {
e.printStackTrace();
continue;
}
}
}
}

2.
import java.io.InputStream;
import java.io.IOException;

public class Request {

private InputStream input;
private String uri;

public Request(InputStream input) {
this.input = input;
}

public void parse() {
//read a set of characters from the socket
StringBuffer request = new StringBuffer(2048);
int i;
byte[] buffer = new byte[2048];
try {
i = input.read(buffer);
}
catch (IOException e) {
e.printStackTrace();
i = -1;
}
for (int j=0; j<i; j++) {
request.append((char) buffer[j]);
}
System.out.print("complete request: \n" + request.toString());
uri = parseUri(request.toString());
System.out.println("after parsing for file: \n" + uri);
}

//parse the http
private String parseUri(String requestString) {
int index1, index2;
index1 = requestString.indexOf(' ');
if (index1 != -1) {
index2 = requestString.indexOf(' ', index1 + 1);
if (index2 > index1)
return requestString.substring(index1 + 1, index2);
}
return null;
}

public String getUri() {
return uri;
}

}

3.
import java.io.OutputStream;
import java.io.IOException;
import java.io.FileInputStream;
import java.io.File;

public class Response {

private static final int BUFFER_SIZE = 1024;
Request request;
OutputStream output;

public Response(OutputStream output) {
this.output = output;
}

public void setRequest(Request request) {
this.request = request;
}

public void sendStaticResource() throws IOException {
byte[] bytes = new byte[BUFFER_SIZE];
FileInputStream fis = null;
try {
//open file
File file = new File(HttpServer.WEB_ROOT, request.getUri());
System.out.println("request file path: \n" + HttpServer.WEB_ROOT+request.getUri() + "\n\n");
if (file.exists()) {
fis = new FileInputStream(file);
int ch = fis.read(bytes, 0, BUFFER_SIZE);
while (ch!=-1) {
output.write(bytes, 0, ch);
ch = fis.read(bytes, 0, BUFFER_SIZE);
}
}
else {
//file not found
String errorMessage = "HTTP/1.1 404 File Not Found\r\n" +
"Content-Type: text/html\r\n" +
"Content-Length: 23\r\n" +
"\r\n" +
"File Not Found";
output.write(errorMessage.getBytes());
}
}
catch (Exception e) {
System.out.println(e.toString() );
}
finally {
if (fis!=null)
fis.close();
}
}
}


how would such code be written in c++?
also does anyone know some other protocol like ftp. correct me if i am wrong http is an application layer protocol. so if i can parse for ftp the above code should also work.

No comments: