Created
October 10, 2012 17:25
-
-
Save feltnerm/3867073 to your computer and use it in GitHub Desktop.
Webserver for CS3830
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import java.io.*; | |
import java.net.*; | |
import java.util.*; | |
/** | |
* Primitive HTTP Web Server | |
* @author Mark Feltner | |
* | |
*/ | |
class HttpRequest extends Thread { | |
private Socket sock; | |
private PrintWriter server_thread_log; | |
private static final String LOG_FILE = "P3.LOG"; | |
private final static String CRLF = "\r\n"; | |
/** | |
* Processes an HTTP request and returns a response. | |
* @param inSock The incoming client request socket. | |
*/ | |
public HttpRequest(Socket inSock) { | |
this.sock = inSock; | |
try { | |
this.server_thread_log = new PrintWriter( | |
new FileWriter(LOG_FILE, true), true); | |
} catch (IOException e) { | |
System.err.println("Error reading logfile. Using stdout instead"); | |
this.server_thread_log = new PrintWriter(System.out); | |
} | |
} | |
/** | |
* Runs the Thread. | |
*/ | |
public void run() { | |
try { | |
this.processRequest(); | |
} catch (Exception e) { | |
this.log("Error processing request."); | |
e.printStackTrace(); | |
} | |
this.server_thread_log.close(); | |
} | |
/** | |
* Process an HTTP Request and return a response. | |
* @throws Exception | |
*/ | |
private void processRequest() throws Exception { | |
InputStream socketInput = this.sock.getInputStream(); | |
DataOutputStream clientWriter = new DataOutputStream( | |
this.sock.getOutputStream()); | |
BufferedReader clientReader = new BufferedReader( | |
new InputStreamReader(this.sock.getInputStream())); | |
String requestLine = clientReader.readLine(); | |
String headerLine = clientReader.readLine(); | |
while (!headerLine.equals("")) | |
{ | |
System.out.println(headerLine); | |
headerLine = clientReader.readLine(); | |
} | |
String fileName = parseRequestLine(requestLine); | |
File responseFile = new File(fileName); | |
String responseStatus = null; | |
String responseContentType = null; | |
String responseBody = null; | |
if (responseFile.exists()) | |
{ | |
responseStatus = "HTTP/1.1 200 OK"; | |
responseContentType = "Content-type: " + contentType(fileName) + CRLF; | |
} else | |
{ | |
responseStatus = "HTTP/1.1 404 Not Found"; | |
responseContentType = "Content-type: text/html" + CRLF; | |
responseBody = "<HTML>"+ | |
"<HEAD><TITLE>Not Found</TITLE></HEAD>"+ | |
"<BODY>Not Found</BODY></HTML>"; | |
} | |
clientWriter.writeBytes(responseStatus + CRLF); | |
clientWriter.writeBytes(responseContentType + CRLF); | |
clientWriter.writeBytes(CRLF); | |
if (responseFile.exists() && responseFile.isFile()) | |
{ | |
FileInputStream istream = new FileInputStream(responseFile); | |
sendBytes(istream, clientWriter); | |
} | |
else | |
{ | |
clientWriter.writeBytes(responseBody); | |
} | |
clientWriter.writeBytes(CRLF); | |
clientWriter.close(); | |
clientReader.close(); | |
socketInput.close(); | |
this.log("Request: " + requestLine); | |
this.log("Response: " + responseStatus); | |
} | |
/** | |
* Parse the filename requested from the request header. | |
* @param requestLine The request line header | |
* @return A file. | |
*/ | |
private String parseRequestLine(String requestLine) { | |
return "." + requestLine.split(" ")[1]; | |
} | |
/** | |
* Returns a MIMETYPE for a filename | |
* @param filename Filename with extension | |
* @return That filename's mimetype. | |
*/ | |
private String contentType(String filename) { | |
if (filename.endsWith(".html") || filename.endsWith(".htm")) | |
{ | |
return "text/html"; | |
} | |
else if (filename.endsWith(".gif")) | |
{ | |
return "image/gif"; | |
} | |
else if (filename.endsWith(".jpg") || filename.endsWith(".jpeg")) { | |
return "image/jpeg"; | |
} | |
else | |
{ | |
return "application/octet-stream"; | |
} | |
} | |
/** | |
* Writes a file to an outputstream | |
* @param istream The file input stream to read | |
* @param ostream The outputstream to write to | |
* @throws Exception | |
*/ | |
private void sendBytes(FileInputStream istream, OutputStream ostream) | |
throws Exception | |
{ | |
byte[] buffer = new byte[1024]; | |
int bytes = 0; | |
bytes = istream.read(buffer); | |
while (bytes != -1) | |
{ | |
ostream.write(buffer); | |
bytes = istream.read(buffer); | |
} | |
this.log("Bytes transferred: " + bytes); | |
} | |
/** | |
* Log a message to the log. | |
* @param message the message to write. | |
*/ | |
private void log(String message) { | |
String client_ip = this.sock.getInetAddress().toString(); | |
int client_port = this.sock.getPort(); | |
String time_now = new Date().toString(); | |
this.server_thread_log.println(time_now + " [" + client_ip + ":" | |
+ client_port + "] " + "-- " + message); | |
} | |
} | |
class WebServer { | |
public static final int LISTEN_PORT = 3333; | |
ServerSocket serv_sock = null; | |
PrintWriter server_log; | |
/** | |
* A multithreaded WebServer | |
*/ | |
/** | |
* Runs the webserver and it begins listening for requests. | |
*/ | |
public void run() { | |
try { | |
this.serv_sock = new ServerSocket(LISTEN_PORT); | |
} catch (IOException e) { | |
System.err.println("Unable to start server on port: " | |
+ LISTEN_PORT + '\n' | |
+ "(maybe someone's already using it?)"); | |
e.printStackTrace(); | |
} | |
boolean error = false; | |
while (!error) { | |
Socket sock = null; | |
try { | |
sock = serv_sock.accept(); | |
HttpRequest request = new HttpRequest(sock); | |
request.start(); | |
} catch (IOException e) { | |
System.err.println("Error binding to request with client"); | |
e.printStackTrace(); | |
} | |
} | |
try { | |
this.serv_sock.close(); | |
} catch (IOException e) { | |
} | |
} | |
/** | |
* Main | |
*/ | |
public static void main(String[] args) { | |
System.out.println("Web Server...go!"); | |
WebServer app = new WebServer(); | |
app.run(); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment