Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
379 changes: 150 additions & 229 deletions src/xdvrx1_serverProject/ClientRequest.java

Large diffs are not rendered by default.

22 changes: 11 additions & 11 deletions src/xdvrx1_serverProject/FileNotFoundMessage.java
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
package xdvrx1_serverProject;

class FileNotFoundMessage {

String body =
new StringBuilder("<html>\r\n")
.append("<head><title>File Not Found</title>\r\n")
.append("</head>\r\n")
.append("<body>")
.append("<h1>HTTP Error 404: File Not Found [Try again later]</h1>\r\n")
.append("</body></html>\r\n")
.toString();

}
static final String content =
new StringBuilder("<html>\r\n")
.append("<head><title>File Not Found</title>\r\n")
.append("</head>\r\n")
.append("<body>")
.append("<h1>HTTP Error 404: File Not Found [Try again later]</h1>\r\n")
.append("</body></html>\r\n")
.toString();
}
100 changes: 50 additions & 50 deletions src/xdvrx1_serverProject/FileWebServer.java
Original file line number Diff line number Diff line change
@@ -1,64 +1,64 @@
package xdvrx1_serverProject;

/*
/**
* This is the actual server class.
* This will call the overridden
* method `run()` of `Runnable`.
*/

import java.util.concurrent.*;
import java.util.logging.*;

import java.io.*;
import java.net.*;

import java.util.logging.*;

public class FileWebServer {

private final File rootDirectory;
private final int port;
private static final int pool_count = 10000;
private static final String defaultPage = "index.html";

private static final Logger
serverLogger = Logger.getLogger(FileWebServer
.class.getCanonicalName());

//the constructor
public FileWebServer(File rootDirectory, int port)
throws IOException {

if (!rootDirectory.isDirectory()) {
throw new IOException(rootDirectory
+ " is not a directory");
}

this.rootDirectory = rootDirectory;
this.port = port;

}

//void start
public void start()
throws IOException {

ExecutorService pool =
Executors.newFixedThreadPool(pool_count);

try (ServerSocket server = new ServerSocket(port)) {

serverLogger.info("Listening on port " + server.getLocalPort());
serverLogger.info("@DocumentRoot");

while (true) {
try {
Socket request = server.accept();
Runnable r =
new ClientRequest(rootDirectory, defaultPage, request);
pool.submit(r);
} catch (IOException ex) {
serverLogger.log(Level.WARNING, "Error accepting connection", ex);

private final File rootDirectory;
private final int port;
private static final int pool_count = 1000;
private static final String defaultPage = "index.html";

private static final Logger
serverLogger = Logger.getLogger(FileWebServer
.class.getCanonicalName());

//the constructor
public FileWebServer(File rootDirectory, int port)
throws IOException {

if (!rootDirectory.isDirectory()) {
throw new IOException(rootDirectory
+ " is not a directory");
}

this.rootDirectory = rootDirectory;
this.port = port;

}

//void start
public void start()
throws IOException {

ExecutorService pool =
Executors.newFixedThreadPool(pool_count);

try (ServerSocket server = new ServerSocket(port)) {

serverLogger.info("Listening on port " + server.getLocalPort());
serverLogger.info("@DocumentRoot");

while (true) {
try {
Socket request = server.accept();
Runnable r =
new ClientRequest(rootDirectory, defaultPage, request);
pool.submit(r);
} catch (IOException ex) {
serverLogger.log(Level.WARNING, "Error accepting connection", ex);
}
}
}
}
}
}
}
}
79 changes: 79 additions & 0 deletions src/xdvrx1_serverProject/GETMethod.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
package xdvrx1_serverProject;

import java.nio.file.Files;
import java.io.*;
import java.net.*;

class GETMethod {

byte[] processGET(File rootDirectory,
String[] token,
String defaultPage,
String http_version,
Writer out) {

try {
String fileName = token[1];

//add manually the default page
if (fileName.endsWith("/")) {
fileName = fileName + defaultPage;
}

//get the content type for proper encoding of data
String contentType =
URLConnection.getFileNameMap().getContentTypeFor(fileName);

if (token.length > 2) {
http_version = token[2];
}

File actualFile =
new File(rootDirectory,
fileName.substring(1, fileName.length()));

String root = rootDirectory.getPath();

// restrict clients inside the document root
if (actualFile.canRead()
&& actualFile.getCanonicalPath().startsWith(root)) {

byte[] _data = Files.readAllBytes(actualFile.toPath());

if (http_version.startsWith("HTTP/")) {
// send a MIME header
ServerHeader
.serverHeader(out,
"HTTP/1.0 200 OK",
contentType,
_data.length);
}

return _data;

} else {

// file not found
if (http_version.startsWith("HTTP/")) {

// send a MIME header
ServerHeader
.serverHeader(out,
"HTTP/1.0 404 File Not Found",
"text/html; charset=utf-8",
FileNotFoundMessage.content.length());
}

out.write(FileNotFoundMessage.content);
out.flush();
return null;
}

} catch (IOException ioe) {
System.out.println(ioe.getMessage());
return null;
}

}

}
30 changes: 4 additions & 26 deletions src/xdvrx1_serverProject/MainMethod.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,30 +3,8 @@
import java.io.*;

class MainMethod {
public static void main(String[] args) {

try {

//the relative root directory
//it's up to you if you want to change this
File currentDir = new File(".");

//create an instance of `FileWebServer`
//at the current directory and using port 80
//again, it is up to you when you want to change
//the port
FileWebServer filewebserver = new FileWebServer(currentDir, 80);

//call `start` method that
//contains the call for the Runnable `run`
//of `ClientRequest` class
filewebserver.start();

} catch (IOException ex) {
//throws an exception if `currentDir`
//is not recognized as such
System.out.println(ex);
}
}

public static void main(String[] args) {
ServerApp serverApp = new ServerApp();
serverApp.build();
}
}
16 changes: 8 additions & 8 deletions src/xdvrx1_serverProject/NotSupportedMessage.java
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
package xdvrx1_serverProject;

class NotSupportedMessage {

String body = new StringBuilder("<html>\r\n")
.append("<head><title>Not Implemented</title>\r\n")
.append("</head>\r\n")
.append("<body>")
.append("<h1>HTTP Error 501: Not Yet Supported Method</h1>\r\n")
.append("</body></html>\r\n")
.toString();
static final String content = new StringBuilder("<html>\r\n")
.append("<head><title>Not Implemented</title>\r\n")
.append("</head>\r\n")
.append("<body>")
.append("<h1>HTTP Error 501: Not Yet Supported Method</h1>\r\n")
.append("</body></html>\r\n")
.toString();
}
21 changes: 21 additions & 0 deletions src/xdvrx1_serverProject/POSTMethod.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package xdvrx1_serverProject;

class POSTMethod {

String returnPOSTData(String userRequestToString) {

//get the request body for POST method
//add 4, because the index that
//will be returned is relative to the
//very first occurence of the string
String requestBody =
userRequestToString
.substring(userRequestToString.lastIndexOf("\r\n\r\n") + 4);

//just showing the input data back to the client
//a lot of things can be done for the request body
//it can go directly to a file or a database,
//or be loaded into an XML file for further processing
return requestBody;
}
}
44 changes: 44 additions & 0 deletions src/xdvrx1_serverProject/ReadInputStream.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package xdvrx1_serverProject;

import java.io.*;
import java.net.*;

class ReadInputStream {

StringBuffer readUserRequest(BufferedInputStream bis,
Reader in,
Socket connection) {

StringBuffer userRequest = new StringBuffer();

try {
//this will be the basis to get
//all the bytes from the stream
int bufferSize = bis.available();

while (true) {
if (userRequest.length() > bufferSize-1) {
//for performance, always shutdown
//after breaking from this loop
connection.shutdownInput();
break;
}

//read() of Reader is actually a blocking
//method, and without proper algorithm
//this will hang the entire program
int c = in.read();
userRequest.append((char) c);

//ignore the line endings,
//the Reader will interpret this as end of buffer
//we need to read the entire content of the buffer
if (c == '\n' || c == '\r' || c == 1) continue;
}
return userRequest;
} catch (IOException ioe) {
System.out.println(ioe.getMessage());
return null;
}
}
}
31 changes: 31 additions & 0 deletions src/xdvrx1_serverProject/ServerApp.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package xdvrx1_serverProject;

import java.io.*;

class ServerApp {
public void build() {

try {
//the relative root directory
//it's up to you if you want to change this
File currentDir = new File(".");

//create an instance of `FileWebServer`
//at the current directory and using port 80
//again, it is up to you when you want to change
//the port
FileWebServer filewebserver = new FileWebServer(currentDir, 80);

//call `start` method that
//contains the call for the Runnable `run`
//of `ClientRequest` class
filewebserver.start();

} catch (IOException ex) {
//throws an exception if `currentDir`
//is not recognized as such
System.out.println(ex.getMessage());
}
}

}
Loading