Created
November 20, 2018 17:26
-
-
Save weburnit/8a147a9e2e6baa2dfeee792b857e7a55 to your computer and use it in GitHub Desktop.
WebServer.java
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.ArrayList; | |
class WebServer { | |
// this is the port the web server listens on | |
private static final int PORT_NUMBER = 8080; | |
// main entry point for the application | |
public static void main(String args[]) { | |
try { | |
// open socket | |
ServerSocket serverSocket = new ServerSocket(PORT_NUMBER); | |
// start listener thread | |
Thread listener = new Thread(new SocketListener(serverSocket)); | |
listener.start(); | |
// message explaining how to connect | |
System.out.println("To connect to this server via a web browser, try \"http://127.0.0.1:8080/{url to retrieve}\""); | |
// wait until finished | |
System.out.println("Press enter to shutdown the web server..."); | |
// kill listener thread | |
listener.interrupt(); | |
} catch (Exception e) { | |
System.err.println("WebServer::main - " + e.toString()); | |
} | |
} | |
} | |
class SocketListener implements Runnable { | |
private ServerSocket serverSocket; | |
public SocketListener(ServerSocket serverSocket) { | |
this.serverSocket = serverSocket; | |
} | |
// this thread listens for connections, launches a seperate socket connection | |
// thread to interact with them | |
public void run() { | |
while (true) { | |
try { | |
Socket clientSocket = serverSocket.accept(); | |
Thread connection = new Thread(new SocketConnection(clientSocket)); | |
connection.start(); | |
Thread.yield(); | |
} catch (IOException e) { | |
if (!this.serverSocket.isClosed()) { | |
System.err.println("SocketListener::run - " + e.toString()); | |
} | |
} | |
} | |
} | |
} | |
class HttpRequest { | |
private String method; | |
private String path; | |
public HttpRequest() { | |
} | |
public String getMethod() { | |
return method; | |
} | |
public void setMethod(String method) { | |
this.method = method; | |
} | |
public String getPath() { | |
return path; | |
} | |
public void setPath(String path) { | |
this.path = path; | |
} | |
} | |
class SocketConnection implements Runnable { | |
private final String HTTP_LINE_BREAK = "\r\n"; | |
private Socket clientSocket; | |
public SocketConnection(Socket clientSocket) { | |
this.clientSocket = clientSocket; | |
} | |
// one of these threads is spawned and used to talk to each connection | |
public void run() { | |
try { | |
BufferedReader request = new BufferedReader(new InputStreamReader(this.clientSocket.getInputStream())); | |
PrintWriter response = new PrintWriter(this.clientSocket.getOutputStream(), true); | |
this.handleConnection(request, response); | |
} catch (Exception e) { | |
System.err.println("SocketConnection::run - " + e.toString()); | |
} | |
} | |
// TODO: implement your HTTP protocol for this server within this method | |
private void handleConnection(BufferedReader reader, PrintWriter response) throws IOException { | |
try { | |
/* | |
* | |
* TODO: implement your web server here | |
* | |
* Tasks: | |
* ------ | |
* 1.) Figure out how to parse the HTTP reader header | |
* 2.) Figure out how to open files | |
* 3.) Figure out how to create an HTTP responseHtml header | |
* 4.) Figure out how to return resources (i.e. files) | |
* | |
*/ | |
// EXAMPLE: code prints the web reader | |
HttpRequest request = this.readHTTPHeader(reader, new HttpRequest()); | |
ArrayList<String> folders = new ArrayList<>(); | |
folders.add("add"); | |
folders.add("helloworld"); | |
folders.add("subdirectory"); | |
// Start sending our reply, using the HTTP 1.1 protocol | |
response.print("HTTP/1.1 200 \r\n"); // Version & status code | |
response.print("Content-Type: text/html; charset=utf-8\r\n"); // The type of data | |
response.print("Connection: close\r\n"); // Will close stream | |
response.print("\r\n"); // End of headers | |
if (folders.contains(request.getPath().replaceFirst("/", ""))) { | |
if (request.getPath().replace("/", "").equals("subdirectory")) { | |
response.print(responseDirectory(null)); | |
} else response.println(this.responseHtmlFile(request.getPath())); | |
} else if (request.getPath().contains("subdirectory")) { | |
response.print(responseDirectory(request.getPath().replace("/subdirectory/", ""))); | |
} else { | |
StringBuilder builder = new StringBuilder(); | |
builder.append("<a href=\"/add\">add</a><br>"); | |
builder.append("<a href=\"/helloworld\">helloworld</a><br>"); | |
builder.append("<a href=\"/subdirectory\">subdirectory</a><br>"); | |
response.print(builder.toString()); | |
} | |
response.close(); | |
reader.close(); | |
} finally { | |
// close the socket, no keep alives | |
this.clientSocket.close(); | |
} | |
} | |
private String responseDirectory(String sub) throws IOException { | |
if (sub == null) { | |
StringBuilder builder = new StringBuilder(); | |
String dir = System.getProperty("user.dir") + "/" + "webroot" + "/subdirectory"; | |
File directory = new File(dir); | |
//get all the files from a directory | |
File[] fList = directory.listFiles(); | |
for (File file : fList) { | |
if (file.isFile()) { | |
builder.append("<a href=\"/subdirectory/" + file.getName() + "\">" + file.getName() + "</a><br>"); | |
} | |
} | |
return builder.toString(); | |
} | |
return responseHtml(System.getProperty("user.dir") + "/" + "webroot" + "/subdirectory/" + sub); | |
} | |
private String responseHtmlFile(String path) throws IOException { | |
String dir = System.getProperty("user.dir") + "/" + "webroot" + "/" + path + "/" + "index.html"; | |
return responseHtml(dir); | |
} | |
private String responseHtml(String dir) throws IOException { | |
FileReader fr = new FileReader(dir); | |
BufferedReader br = new BufferedReader(fr); | |
String sCurrentLine; | |
StringBuilder content = new StringBuilder(); | |
try { | |
while ((sCurrentLine = br.readLine()) != null) { | |
content.append(sCurrentLine); | |
} | |
} catch (IOException e) { | |
e.printStackTrace(); | |
} finally { | |
br.close(); | |
fr.close(); | |
} | |
return content.toString(); | |
} | |
private HttpRequest readHTTPHeader(BufferedReader reader, HttpRequest request) { | |
String message = ""; | |
String line = ""; | |
int read = 0; | |
while ((line != null) && (!line.equals(this.HTTP_LINE_BREAK))) { | |
line = this.readHTTPHeaderLine(reader); | |
if (read == 0) { | |
String[] data = line.split(" "); | |
request.setMethod(data[0]); | |
request.setPath(data[1]); | |
} | |
message += line; | |
read++; | |
} | |
return request; | |
} | |
private String readHTTPHeaderLine(BufferedReader reader) { | |
String line = ""; | |
try { | |
line = reader.readLine() + this.HTTP_LINE_BREAK; | |
} catch (IOException e) { | |
System.err.println("SocketConnection::readHTTPHeaderLine: " + e.toString()); | |
line = ""; | |
} | |
return line; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment