import java.io.*;
import java.net.*;
import java.util.*;
public class JWebServer {
private int portNumber;
private static final String SERVER_ID = "Jose Sandoval HTTP Server/1.0";
private ServerSocket listenSocket;
static public void main( String[] args ) throws Exception {
if (args.length != 1) {
System.out.println("Usage: java -jar web.jar <portNumber>");
System.exit(1);
}
int portNumber = Integer.parseInt(args[0]);
System.out.println("Starting " + SERVER_ID);
new JWebServer(portNumber).runServer();
}
public JWebServer() {
super();
}
public JWebServer(int port) {
super();
portNumber = port;
init();
}
private void init() {
try {
listenSocket = new ServerSocket(portNumber);
} catch (Exception e) {
e.printStackTrace();
}
}
private void runServer() throws Exception {
while (true) {
new HandleRequest(listenSocket.accept()).start();
}
}
class HandleRequest extends Thread {
Socket connectionSocket;
private static final String EOL = "\r\n";
public HandleRequest(Socket aSocket) {
super();
connectionSocket = aSocket;
}
public HandleRequest() {
super();
}
public void run() {
String requestMessageLine = null;
String fileName = null;
String requestMethod = null;
BufferedReader inFromClient = null;
DataOutputStream outToClient = null;
StringTokenizer tokenizedLine = null;
try {
inFromClient = new BufferedReader( new InputStreamReader(connectionSocket.getInputStream()) );
outToClient = new DataOutputStream( connectionSocket.getOutputStream() );
requestMessageLine = inFromClient.readLine();
tokenizedLine = new StringTokenizer(requestMessageLine);
consoleMessage(requestMessageLine);
if (tokenizedLine.countTokens() >= 2) {
requestMethod = tokenizedLine.nextToken();
fileName = tokenizedLine.nextToken();
if (requestMethod.equals("GET")) {
doGetRequest(fileName, outToClient);
} else {
doBadRequest(outToClient);
}
} else {
doBadRequest(outToClient);
}
inFromClient.close();
outToClient.close();
connectionSocket.close();
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException(e.getMessage());
}
}
public String myReplace(String str, String pattern, String replace) {
int s = 0;
int e = 0;
StringBuffer result = new StringBuffer();
while ((e = str.indexOf(pattern, s)) >= 0) {
result.append(str.substring(s, e));
result.append(replace);
s = e + pattern.length();
}
result.append(str.substring(s));
return result.toString();
}
private void doGetRequest(String fileName, DataOutputStream out) throws Exception {
if (fileName.endsWith("/")) {
fileName = fileName + "index.html";
}
if (fileName.startsWith("/")) {
fileName = fileName.substring(1);
}
File file = new File(fileName);
if ( file.isDirectory()) {
doDirectoryListing(out, fileName, file.list());
} else if (file.exists() && !file.isDirectory()) {
doFileExist(out, fileName);
} else {
doFileNotFound(out);
}
}
private String doGetContentType(String fileName) throws Exception {
String contentType = null;
if (fileName.toLowerCase().endsWith(".html") || fileName.toLowerCase().endsWith(".htm")) {
contentType = "text/html";
} else if (fileName.toLowerCase().endsWith(".gif")) {
contentType = "image/gif";
} else if (fileName.toLowerCase().endsWith(".jpg")) {
contentType = "image/jpeg";
} else {
contentType = "unknown/unknown";
}
return contentType;
}
private void doFileExist(DataOutputStream out, String fileName) {
try {
int numOfBytes = (int) new File(fileName).length();
FileInputStream inFile = new FileInputStream(fileName);
byte[] fileInBytes = new byte[numOfBytes];
inFile.read(fileInBytes);
out.writeBytes("HTTP/1.0 200 OK" + EOL);
out.writeBytes("Date: " + new Date() + EOL);
out.writeBytes("Server: " + SERVER_ID + EOL);
out.writeBytes("Content-Length: " + numOfBytes + EOL);
out.writeBytes("Content-Type: " + doGetContentType(fileName) + EOL);
out.writeBytes(EOL);
out.write(fileInBytes, 0, numOfBytes);
inFile.close();
} catch (Exception e) {
throw new RuntimeException(e.getMessage());
}
consoleMessage("HTTP/1.0 200 OK");
}
private void doDirectoryListing(DataOutputStream out, String fileName, String[] fileList) {
try {
StringBuffer listing = new StringBuffer();
listing.append("<html><head><title>Directory listing for ").append(fileName);
listing.append("</title></head>");
listing.append("<body>");
listing.append("<h1>Directory listing for: ").append(fileName).append("</h1>");
listing.append("<table border=0 width=80% cellpadding=8 cellspacing=0>");
listing.append("<tr><td width=40%><b>Name</b></td> <td width=40%><b>Last modified</b></td> <td width=20%><b>Size in bytes</b></td></tr>");
listing.append("<tr><td colspan=3><hr size=1 noshadow></td></tr>");
boolean isDirectory = false;
File fileInfo = null;
String thisFileName = null;
for (int i = 0; i<fileList.length; i++) {
listing.append("<tr>");
listing.append("<td>");
thisFileName = fileList[i];
fileInfo = new File(thisFileName);
isDirectory = fileInfo.isDirectory();
listing.append("<a href='/").append(fileName).append("/").append(thisFileName).append("'>").append(thisFileName);
if (isDirectory) {
listing.append("/");
}
listing.append("</a>");
listing.append("</td>");
listing.append("<td>");
listing.append(new Date(fileInfo.lastModified()));
listing.append("</td>");
listing.append("<td>");
if (isDirectory) {
listing.append("-");
} else {
listing.append(fileInfo.length());
}
listing.append("</td>");
listing.append("</tr>");
}
listing.append("<tr><td colspan=3><hr size=1 noshadow></td></tr>");
listing.append("<tr><td colspan=3><font size=1><i>Server by <a href='mailto:jose@josesandoval'>jose@josesandoval.com</a></i></font></td></tr>");
listing.append("</table>");
listing.append("</body>");
listing.append("</html>");
out.writeBytes("HTTP/1.0 404 Not Found" + EOL);
out.writeBytes("Date: " + new Date() + EOL);
out.writeBytes("Server: " + SERVER_ID + EOL);
out.writeBytes("Content-Type: text/html" + EOL);
out.writeBytes(EOL);
out.writeBytes(listing.toString());
} catch (Exception e) {
throw new RuntimeException(e.getMessage());
}
consoleMessage("HTTP/1.0 200 OK");
}
private void doFileNotFound(DataOutputStream out) throws Exception {
out.writeBytes("HTTP/1.0 404 Not Found" + EOL);
out.writeBytes("Date: " + new Date() + EOL);
out.writeBytes("Server: " + SERVER_ID + EOL);
out.writeBytes("Content-Type: text/html" + EOL);
out.writeBytes(EOL);
out.writeBytes("<HTML>\n <HEAD>\n <TITLE>\n 404 Not Found\n </TITLE>\n </HEAD>\n <BODY>\n 404 File Not Found\n </BODY>\n</HTML>" + EOL);
consoleMessage("HTTP/1.0 404 Not Found");
}
private void doBadRequest(DataOutputStream out) throws Exception {
out.writeBytes("HTTP/1.0 400 Illegal Request" + EOL);
out.writeBytes("Date: " + new Date() + EOL);
out.writeBytes("Server: " + SERVER_ID + EOL);
out.writeBytes("Content-Type: text/html" + EOL);
out.writeBytes(EOL);
out.writeBytes("<HTML>\n <HEAD>\n <TITLE>\n 400 Illegal Request\n </TITLE>\n </HEAD>\n <BODY>\n 400 Illegal Request\n </BODY>\n</HTML>" + EOL);
consoleMessage("HTTP/1.0 400 Illegal Request");
}
private void consoleMessage(String message) {
System.out.println(message);
}
}
}