/**
* $Id: HttpServer.java,v 1.1 2005/10/20 06:07:00 johnr Exp $
*
* (c) John Reekie 2004
* (c) The University of Technology, Sydney, 2004
*
* This software is written for teaching purposes. As such, you can do
* anything you want with it, as long as you don't remove this
* copyright notice, or blame us if it doesn't do what you think
* it should do.
*/
import java.net.*;
import java.io.*;
import java.util.Map;
import java.util.HashMap;
/** An extremely simple HTTP Server. The goal of this class is to provide
* the simplest possible implementation of a functioning web server.
* It gets upset with the slightest provocation, but serves to illustrate
* how basic HTTP works. It creates a thread for each request, in the
* same manner as ThreadedServer.
*/
public class HttpServer {
/** Run the server.
*/
public void run (int p)
throws IOException {
ServerSocket serversocket = new ServerSocket(p);
System.out.println("Listening on port " + p);
// Block waiting for input, handle connection, repeat forever
while (true) {
Socket clientsocket = serversocket.accept();
ConnectionHandler h = new ConnectionHandler(clientsocket);
h.start(); // start a new thread for this connection
}
}
/** The ConnectionHandler class is a subclass of Thread, so that
* we can run many of them at the same time.
*/
public class ConnectionHandler extends Thread {
private Socket _socket;
/** Construct the ConnectionHandler object with the given
* client socket.
*/
public ConnectionHandler (Socket s) {
_socket = s;
}
/** Run this thread to handle a connection from a client.
*/
public void run () {
try {
InputStream in = _socket.getInputStream();
OutputStream out = _socket.getOutputStream();
handleConnection(in, out);
_socket.close();
}
catch (Exception e) {
e.printStackTrace();
}
}
/** Handle the connection. Get the HTTP headers and figure
* out what to do.
*/
public void handleConnection (InputStream in, OutputStream out)
throws IOException {
// Read the HTTP request header
BufferedReader reader = new BufferedReader(new InputStreamReader(in));
String line = reader.readLine();
// System.out.println(line); // display received request
String[] elements = line.split(" ");
String resource = elements[1];
// Read the rest of the headers, print, and discard them
HashMap headers = new HashMap();
while (true) {
line = reader.readLine();
if (line.length() == 0) {
break; // Blank line, so all headers are read
}
if (line == null) {
return; // whoops...
}
// System.out.println(line); // display received header
}
// System.out.println("");
// Try and find the file... what about directory redirects?
String filename = resource.substring(1); // Strip initial '/'
if (filename.equals("")) {
filename = ".";
}
File file = new File(filename);
if (!file.exists()) {
out.write("HTTP/1.0 404\r\n\r\n".getBytes());
out.write(("You requested a file that I don't know about: "
+ resource + "\r\n").getBytes());
} else if (file.isDirectory()) {
if (resource.charAt(resource.length()-1) != '/') {
// Redirect with trailing slash
out.write("HTTP/1.0 302\r\n".getBytes());
out.write(("Location: " + resource + "/\r\n\r\n").getBytes());
} else {
// Generate directory listing
out.write("HTTP/1.0 200\r\n\r\n".getBytes());
StringBuffer listing = new StringBuffer();
listing.append("(Parent directory)
");
String[] files = file.list();
for (int j = 0; j < files.length; j++) {
listing.append("" + files[j] + "
");
}
out.write(listing.toString().getBytes());
}
} else if (false) {
// Here is where you could check to see if the URL
// represents something that you would want to do in
// custom code.
} else {
// Serve a file
out.write("HTTP/1.0 200\r\n\r\n".getBytes());
FileInputStream fis = new FileInputStream(file);
byte[] buffer = new byte[1024];
while (true) {
int readcount = fis.read(buffer);
out.write(buffer, 0, readcount);
if (readcount < 1024) {
break;
}
}
}
}
}
/** This is the main function to start the server running
*/
public static void main (String[] argv) {
if (argv.length != 1) {
throw new IllegalArgumentException("Expecting one argument");
}
int portnr = Integer.parseInt(argv[0]);
HttpServer server = new HttpServer();
try {
server.run(portnr);
}
catch (Exception e) {
System.out.println(e.getStackTrace());
}
}
}