diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..efff418
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,2 @@
+.idea/
+httpserver/target
\ No newline at end of file
diff --git a/README.md b/README.md
deleted file mode 100644
index 7530104..0000000
--- a/README.md
+++ /dev/null
@@ -1,2 +0,0 @@
-# simple-java-http-server
-Create a Simple HTTP Server in Java Tutorial Series - https://www.youtube.com/playlist?list=PLAuGQNR28pW56GigraPdiI0oKwcs8gglW
diff --git a/Request.txt b/Request.txt
deleted file mode 100644
index bdd8dbc..0000000
--- a/Request.txt
+++ /dev/null
@@ -1,11 +0,0 @@
-GET / HTTP/1.1
-Host: localhost:8080
-Connection: keep-alive
-Upgrade-Insecure-Requests: 1
-User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.97 Safari/537.36
-Sec-Fetch-User: ?1
-Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3
-Sec-Fetch-Site: none
-Sec-Fetch-Mode: navigate
-Accept-Encoding: gzip, deflate, br
-Accept-Language: en-US,en;q=0.9,es;q=0.8,pt;q=0.7,de-DE;q=0.6,de;q=0.5,la;q=0.4
diff --git a/WebRoot/favicon.ico b/WebRoot/favicon.ico
deleted file mode 100644
index dad8daf..0000000
Binary files a/WebRoot/favicon.ico and /dev/null differ
diff --git a/WebRoot/index.html b/WebRoot/index.html
deleted file mode 100644
index 13265de..0000000
--- a/WebRoot/index.html
+++ /dev/null
@@ -1,17 +0,0 @@
-
-
- Simple Java HTTP Server
-
-
-
-Welcome to our first rendered page!
-
-This page was delivered using our own made Https Server made in Java.
-
-
-
-
\ No newline at end of file
diff --git a/WebRoot/logo.png b/WebRoot/logo.png
deleted file mode 100644
index 430c02b..0000000
Binary files a/WebRoot/logo.png and /dev/null differ
diff --git a/httpserver/WebRoot/Index.html b/httpserver/WebRoot/Index.html
new file mode 100644
index 0000000..eb7d87b
--- /dev/null
+++ b/httpserver/WebRoot/Index.html
@@ -0,0 +1,17 @@
+
+
+ Simple Java HTTP Server
+
+
+
+Welcome to my rendered page!
+
+This page was delivered using my custom-built HTTP Server made in Java.
+
+
+
+
\ No newline at end of file
diff --git a/httpserver/WebRoot/favicon.ico b/httpserver/WebRoot/favicon.ico
new file mode 100644
index 0000000..a243e62
Binary files /dev/null and b/httpserver/WebRoot/favicon.ico differ
diff --git a/httpserver/WebRoot/randomlogo.png b/httpserver/WebRoot/randomlogo.png
new file mode 100644
index 0000000..9bfcf64
Binary files /dev/null and b/httpserver/WebRoot/randomlogo.png differ
diff --git a/httpserver/pom.xml b/httpserver/pom.xml
new file mode 100644
index 0000000..8faf82f
--- /dev/null
+++ b/httpserver/pom.xml
@@ -0,0 +1,64 @@
+
+
+ 4.0.0
+
+ com.johan.httpserver
+ httpserver
+ 1.0-SNAPSHOT
+
+
+ 17
+ 17
+
+
+
+
+
+ org.codehaus.mojo
+ exec-maven-plugin
+ 3.6.3
+
+ com.johan.httpserver.httpserver
+
+
+
+
+
+
+
+
+ com.fasterxml.jackson.core
+ jackson-core
+ 2.21.1
+
+
+ com.fasterxml.jackson.core
+ jackson-databind
+ 2.21.1
+
+
+ org.slf4j
+ slf4j-api
+ 2.0.13
+
+
+ ch.qos.logback
+ logback-classic
+ 1.5.13
+
+
+ org.jetbrains
+ annotations
+ 24.0.1
+
+
+ org.junit.jupiter
+ junit-jupiter
+ RELEASE
+ test
+
+
+
+
\ No newline at end of file
diff --git a/httpserver/src/main/java/com/johan/http/BadHttpVersionException.java b/httpserver/src/main/java/com/johan/http/BadHttpVersionException.java
new file mode 100644
index 0000000..f127ce0
--- /dev/null
+++ b/httpserver/src/main/java/com/johan/http/BadHttpVersionException.java
@@ -0,0 +1,11 @@
+package com.johan.http;
+
+public class BadHttpVersionException extends Exception {
+ public BadHttpVersionException() {
+ super("Unsupported or malformed HTTP version");
+ }
+
+ public BadHttpVersionException(String message) {
+ super(message);
+ }
+}
diff --git a/httpserver/src/main/java/com/johan/http/HttpMethod.java b/httpserver/src/main/java/com/johan/http/HttpMethod.java
new file mode 100644
index 0000000..1101c71
--- /dev/null
+++ b/httpserver/src/main/java/com/johan/http/HttpMethod.java
@@ -0,0 +1,17 @@
+package com.johan.http;
+
+public enum HttpMethod {
+ GET, HEAD;
+ public static final int MAX_LENGTH;
+
+ //this checks all the valid METHODS declared in the server and sets max_length as the biggest header
+ static{
+ int tempMaxLength = -1;
+ for (HttpMethod method : HttpMethod.values()){
+ if(method.name().length()>tempMaxLength){
+ tempMaxLength = method.name().length();
+ }
+ }
+ MAX_LENGTH = tempMaxLength;
+ }
+}
diff --git a/httpserver/src/main/java/com/johan/http/HttpParser.java b/httpserver/src/main/java/com/johan/http/HttpParser.java
new file mode 100644
index 0000000..f7b0616
--- /dev/null
+++ b/httpserver/src/main/java/com/johan/http/HttpParser.java
@@ -0,0 +1,135 @@
+package com.johan.http;
+
+import org.slf4j.LoggerFactory;
+import org.slf4j.Logger;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.nio.charset.StandardCharsets;
+
+public class HttpParser {
+
+ private final static Logger LOGGER = LoggerFactory.getLogger(HttpParser.class);
+
+ private static final int SP = 0x20; //32
+ private static final int CR = 0x0D; //13
+ private static final int LF = 0x0A; //10
+
+ public static HttpRequest parseHttpReq(InputStream iptStream) throws HttpParsingException {
+ InputStreamReader isr = new InputStreamReader(iptStream, StandardCharsets.US_ASCII);
+
+ HttpRequest request = new HttpRequest();
+ try {
+ parseRequestLine(isr, request);
+ parseHeader(isr, request);
+ }catch(IOException e){
+ throw new HttpParsingException(HttpStatusCode.CLIENT_ERROR_400_BAD_REQ);
+ }
+ parseBody(isr, request);
+
+ return request;
+ }
+ private static void parseRequestLine(InputStreamReader isr, HttpRequest req) throws IOException, HttpParsingException {
+ boolean methodParsed = false;
+ boolean reqTargetParsed = false;
+ StringBuilder processDataBuffer = new StringBuilder();
+ int _byte;
+ while ((_byte=isr.read()) >=0){
+ if(_byte==CR){
+ _byte=isr.read();
+ if(_byte==LF){
+ LOGGER.debug("Request Line VERSION to process : {}", processDataBuffer.toString());
+ if (!methodParsed || !reqTargetParsed) {
+ throw new HttpParsingException(HttpStatusCode.CLIENT_ERROR_400_BAD_REQ);
+ }
+ try {
+ req.setHttpVersion(processDataBuffer.toString());
+ }catch (BadHttpVersionException e) {
+ LOGGER.error("Bad HTTP Version received : {}", e.getMessage());
+ throw new HttpParsingException(HttpStatusCode.SERVER_ERROR_505_HTTP_VERSION_NOT_SUPPORTED);
+ }
+ return;
+ }else{
+ throw new HttpParsingException(HttpStatusCode.CLIENT_ERROR_400_BAD_REQ);
+ }
+ }
+ if(_byte==SP){
+ if (!methodParsed) {
+ LOGGER.debug("Request Line METHOD to process : {}", processDataBuffer.toString());
+ try {
+ req.setMethod(processDataBuffer.toString());
+ methodParsed = true;
+ }catch (HttpParsingException e){
+ LOGGER.error("Invalid HTTP Method received : {}", e.getMessage());
+ throw new HttpParsingException(HttpStatusCode.SERVER_ERROR_501_NOT_IMPLEMENTED);
+ }
+ }else if (!reqTargetParsed) {
+ LOGGER.debug("Request Line REQ TARGET to process : {}", processDataBuffer.toString());
+ req.setRequestTarget(processDataBuffer.toString());
+ reqTargetParsed = true;
+ }
+ else{
+ throw new HttpParsingException(HttpStatusCode.CLIENT_ERROR_400_BAD_REQ);
+ }
+ processDataBuffer.delete(0, processDataBuffer.length());
+ }else{
+ processDataBuffer.append((char)_byte);
+ if(!methodParsed){
+ if(processDataBuffer.length()>HttpMethod.MAX_LENGTH){
+ LOGGER.error("Terminating connection, Bad Method received : {}", processDataBuffer.toString());
+ throw new HttpParsingException(HttpStatusCode.SERVER_ERROR_501_NOT_IMPLEMENTED);
+ }
+ }
+ }
+ }
+ }
+
+ private static void parseHeader(InputStreamReader isr, HttpRequest req) throws HttpParsingException, IOException {
+ StringBuilder processDataBuffer = new StringBuilder();
+ boolean headerParsed = false;
+ int _byte;
+ while ((_byte=isr.read()) >=0){
+ if(_byte==CR){
+ _byte=isr.read();
+ if(_byte==LF) {
+ String line = processDataBuffer.toString().trim();
+ if (line.isEmpty()) {
+ if(!headerParsed){
+ throw new HttpParsingException(HttpStatusCode.CLIENT_ERROR_400_BAD_REQ);
+ }
+ return;
+ }
+ processingHeaderField(processDataBuffer, req);
+ headerParsed = true;
+ processDataBuffer.delete(0, processDataBuffer.length());
+ } else{
+ throw new HttpParsingException(HttpStatusCode.CLIENT_ERROR_400_BAD_REQ);
+ }
+ } else{
+ processDataBuffer.append((char)_byte);
+ }
+ }
+ }
+
+ private static void processingHeaderField(StringBuilder processDataBuffer, HttpRequest req) throws HttpParsingException {
+ String rawHeaderField = processDataBuffer.toString();
+ if (rawHeaderField.length() > 8192) {
+ throw new HttpParsingException(HttpStatusCode.CLIENT_ERROR_414_URI_TOO_LONG);
+ }
+ int colonIndex = rawHeaderField.indexOf(':');
+ if(colonIndex == -1){
+ throw new HttpParsingException(HttpStatusCode.CLIENT_ERROR_400_BAD_REQ);
+ }
+ String fieldName = rawHeaderField.substring(0, colonIndex).trim();
+ String fieldValue = rawHeaderField.substring(colonIndex+1).trim();
+ if(fieldName.isEmpty()){
+ throw new HttpParsingException(HttpStatusCode.CLIENT_ERROR_400_BAD_REQ);
+ }
+ req.addHeader(fieldName, fieldValue);
+ }
+
+ private static void parseBody(InputStreamReader isr, HttpRequest req) {
+
+ }
+}
diff --git a/src/main/java/com/coderfromscratch/http/HttpParsingException.java b/httpserver/src/main/java/com/johan/http/HttpParsingException.java
similarity index 90%
rename from src/main/java/com/coderfromscratch/http/HttpParsingException.java
rename to httpserver/src/main/java/com/johan/http/HttpParsingException.java
index 1e372eb..d4474d5 100644
--- a/src/main/java/com/coderfromscratch/http/HttpParsingException.java
+++ b/httpserver/src/main/java/com/johan/http/HttpParsingException.java
@@ -1,4 +1,4 @@
-package com.coderfromscratch.http;
+package com.johan.http;
public class HttpParsingException extends Exception {
diff --git a/httpserver/src/main/java/com/johan/http/HttpRequest.java b/httpserver/src/main/java/com/johan/http/HttpRequest.java
new file mode 100644
index 0000000..32470c5
--- /dev/null
+++ b/httpserver/src/main/java/com/johan/http/HttpRequest.java
@@ -0,0 +1,65 @@
+package com.johan.http;
+
+import java.util.HashMap;
+import java.util.Set;
+
+public class HttpRequest {
+
+ private HttpMethod method;
+ private String requestTarget;
+ private String originalHttpVersion;
+ private HttpVersion getBestCompatibleVersion;
+ private HashMap headers = new HashMap<>();
+
+ HttpRequest() {
+ }
+
+ public HttpMethod getMethod() {
+ return method;
+ }
+
+ public String getRequestTarget() {
+ return requestTarget;
+ }
+
+ public HttpVersion getBestCompatibleVersion() { return getBestCompatibleVersion; }
+
+ public String getOriginalHttpVersion() { return originalHttpVersion; }
+
+ public Set getHeaderNames() {
+ return headers.keySet();
+ }
+
+ public String getHeader(String headerName) {
+ return headers.get(headerName.toLowerCase());
+ }
+
+ void setMethod(String methodName) throws HttpParsingException {
+ for (HttpMethod method: HttpMethod.values()) {
+ if(methodName.equals(method.name())){
+ this.method = method;
+ return;
+ }
+ }
+ throw new HttpParsingException(HttpStatusCode.SERVER_ERROR_501_NOT_IMPLEMENTED);
+ }
+
+ public void setRequestTarget(String requestTarget) throws HttpParsingException {
+ if (requestTarget == null || requestTarget.isEmpty()){
+ throw new HttpParsingException(HttpStatusCode.CLIENT_ERROR_400_BAD_REQ);
+ }
+ this.requestTarget = requestTarget;
+ }
+
+ public void setHttpVersion(String originalHttpVersion) throws BadHttpVersionException, HttpParsingException {
+ this.originalHttpVersion = originalHttpVersion;
+ this.getBestCompatibleVersion = HttpVersion.getBestCompatibleVersion(originalHttpVersion);
+ if(this.getBestCompatibleVersion == null){
+ throw new BadHttpVersionException();
+ }
+ }
+
+ void addHeader(String headerName, String HeaderField){
+ headers.put(headerName.toLowerCase(), HeaderField);
+ }
+}
diff --git a/httpserver/src/main/java/com/johan/http/HttpStatusCode.java b/httpserver/src/main/java/com/johan/http/HttpStatusCode.java
new file mode 100644
index 0000000..e13d252
--- /dev/null
+++ b/httpserver/src/main/java/com/johan/http/HttpStatusCode.java
@@ -0,0 +1,21 @@
+package com.johan.http;
+
+public enum HttpStatusCode {
+ /* ---Client Errors --- */
+ CLIENT_ERROR_400_BAD_REQ(400, "Bad Request"),
+ CLIENT_ERROR_401_METHOD_NOT_ALLOWED(401, "Method not allowed"),
+ CLIENT_ERROR_404_NOT_FOUND(404, "Request Target not found"),
+ CLIENT_ERROR_414_URI_TOO_LONG(414, "URI too long"),
+ /* ---Server Errors --- */
+ SERVER_ERROR_500_INTERNAL_SERVER_ERROR(500, "Internal server error"),
+ SERVER_ERROR_501_NOT_IMPLEMENTED(501, "Method Not implemented"),
+ SERVER_ERROR_505_HTTP_VERSION_NOT_SUPPORTED(505, "Http Version Not Supported");
+
+ public final int STATUS_CODE;
+ public final String MESSAGE;
+
+ HttpStatusCode(int STATUS_CODE, String MESSAGE) {
+ this.STATUS_CODE=STATUS_CODE;
+ this.MESSAGE = MESSAGE;
+ }
+}
diff --git a/httpserver/src/main/java/com/johan/http/HttpVersion.java b/httpserver/src/main/java/com/johan/http/HttpVersion.java
new file mode 100644
index 0000000..0ab9e6f
--- /dev/null
+++ b/httpserver/src/main/java/com/johan/http/HttpVersion.java
@@ -0,0 +1,29 @@
+package com.johan.http;
+
+public enum HttpVersion {
+
+ HTTP_1_1("HTTP/1.1", 1, 1),
+ HTTP_1_0("HTTP/1.0",1,0);
+
+ public final String literal;
+ public final int major;
+ public final int minor;
+
+ HttpVersion(String literal, int major, int minor){
+ this.literal = literal;
+ this.major = major;
+ this.minor = minor;
+ }
+
+ public static HttpVersion getBestCompatibleVersion(String version) throws BadHttpVersionException {
+ if(version == null){
+ throw new BadHttpVersionException("Version NULL");
+ }
+ for(HttpVersion v : HttpVersion.values()){
+ if(v.literal.equals(version)){
+ return v;
+ }
+ }
+ return null;
+ }
+}
\ No newline at end of file
diff --git a/httpserver/src/main/java/com/johan/httpserver/config/HttpConfigException.java b/httpserver/src/main/java/com/johan/httpserver/config/HttpConfigException.java
new file mode 100644
index 0000000..47c8f52
--- /dev/null
+++ b/httpserver/src/main/java/com/johan/httpserver/config/HttpConfigException.java
@@ -0,0 +1,18 @@
+package com.johan.httpserver.config;
+
+public class HttpConfigException extends RuntimeException{
+ public HttpConfigException() {
+ }
+
+ public HttpConfigException(String message) {
+ super(message);
+ }
+
+ public HttpConfigException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+ public HttpConfigException(Throwable cause) {
+ super(cause);
+ }
+}
diff --git a/httpserver/src/main/java/com/johan/httpserver/config/configmanager.java b/httpserver/src/main/java/com/johan/httpserver/config/configmanager.java
new file mode 100644
index 0000000..a703fe4
--- /dev/null
+++ b/httpserver/src/main/java/com/johan/httpserver/config/configmanager.java
@@ -0,0 +1,61 @@
+package com.johan.httpserver.config;
+
+import com.johan.httpserver.util.json;
+import com.fasterxml.jackson.databind.JsonNode;
+
+import java.io.FileNotFoundException;
+import java.io.FileReader;
+import java.io.IOException;
+
+public class configmanager {
+ private static configmanager myconfigmanager;
+ private static configuration mycurrentconfig;
+
+ private configmanager(){
+
+ }
+
+ public static configmanager getInstance(){
+ if(myconfigmanager==null)
+ myconfigmanager = new configmanager();
+ return myconfigmanager;
+ }
+
+ //method for loading a config file by the path provided
+ public void loadConfigFile(String filePath) {
+ FileReader fr = null;
+ try {
+ fr = new FileReader(filePath);
+ } catch (FileNotFoundException e) {
+ throw new HttpConfigException(e);
+ }
+ StringBuffer sb = new StringBuffer();
+ int i;
+ try {
+ while ((i = fr.read())!=-1){
+ sb.append((char)i);
+ }
+ } catch (IOException e) {
+ throw new HttpConfigException(e);
+ }
+ JsonNode conf = null;
+ try {
+ conf = json.parse(sb.toString());
+ } catch (IOException e) {
+ throw new HttpConfigException("Error parsing configuration file", e);
+ }
+ try {
+ mycurrentconfig = json.fromJson(conf, configuration.class);
+ } catch (IOException e) {
+ throw new HttpConfigException("Error parsing configuration file, internal", e);
+ }
+ }
+
+ //method for returning currently loaded config
+ public configuration getCurrentConfig(){
+ if (mycurrentconfig == null){
+ throw new HttpConfigException("No Current Configuration Set");
+ }
+ return mycurrentconfig;
+ }
+}
diff --git a/src/main/java/com/coderfromscratch/httpserver/config/Configuration.java b/httpserver/src/main/java/com/johan/httpserver/config/configuration.java
similarity index 79%
rename from src/main/java/com/coderfromscratch/httpserver/config/Configuration.java
rename to httpserver/src/main/java/com/johan/httpserver/config/configuration.java
index 91447e7..020ab2e 100644
--- a/src/main/java/com/coderfromscratch/httpserver/config/Configuration.java
+++ b/httpserver/src/main/java/com/johan/httpserver/config/configuration.java
@@ -1,22 +1,18 @@
-package com.coderfromscratch.httpserver.config;
-
-public class Configuration {
+package com.johan.httpserver.config;
+public class configuration {
private int port;
private String webroot;
-
+
public int getPort() {
return port;
}
-
public void setPort(int port) {
this.port = port;
}
-
public String getWebroot() {
return webroot;
}
-
public void setWebroot(String webroot) {
this.webroot = webroot;
}
diff --git a/httpserver/src/main/java/com/johan/httpserver/core/HttpConnectionWorkerThread.java b/httpserver/src/main/java/com/johan/httpserver/core/HttpConnectionWorkerThread.java
new file mode 100644
index 0000000..740ffd4
--- /dev/null
+++ b/httpserver/src/main/java/com/johan/httpserver/core/HttpConnectionWorkerThread.java
@@ -0,0 +1,105 @@
+package com.johan.httpserver.core;
+
+import com.johan.http.HttpParser;
+import com.johan.http.HttpParsingException;
+import com.johan.http.HttpRequest;
+import com.johan.http.HttpStatusCode;
+import org.slf4j.LoggerFactory;
+import org.slf4j.Logger;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.Socket;
+import java.nio.file.Files;
+
+public class HttpConnectionWorkerThread extends Thread{
+
+ final String CRLF = "\r\n"; //13, 10
+ private final static Logger LOGGER = LoggerFactory.getLogger(HttpConnectionWorkerThread.class);
+ private Socket socket;
+ public HttpConnectionWorkerThread(Socket socket){
+ this.socket=socket;
+ }
+
+ //For sending the Error code and Message to Client
+ private void sendErrorResponse(HttpStatusCode code, OutputStream op) throws IOException {
+ String body = code.MESSAGE;
+
+ String response =
+ "HTTP/1.1 " + code.STATUS_CODE + " " + code.MESSAGE + CRLF +
+ "Content-Length: " + body.length() + CRLF +
+ CRLF +
+ body;
+
+ op.write(response.getBytes());
+ }
+
+ @Override
+ public void run(){
+ InputStream ipStream = null;
+ OutputStream opStream = null;
+ try {
+ ipStream = socket.getInputStream();
+ opStream = socket.getOutputStream();
+ HttpRequest req = null;
+ try {
+ req = HttpParser.parseHttpReq(ipStream);
+ }catch (HttpParsingException e){
+ sendErrorResponse(e.getErrorCode(), opStream);
+ return;
+ }
+
+ //Get the file that the user wants
+ //finish working on this later
+ String path = req.getRequestTarget();
+ if ("/".equals(path)){
+ path="/Index.html";
+ }else{
+ LOGGER.error("Invalid Request Target received : {}", path);
+ throw new HttpParsingException(HttpStatusCode.CLIENT_ERROR_404_NOT_FOUND);
+ }
+
+ File file = new File(System.getProperty("user.dir") + "/httpserver/WebRoot" + path);
+
+ //Response
+ byte[] fileBytes = Files.readAllBytes(file.toPath());
+ String response =
+ "HTTP/1.1 200 OK" + CRLF + // Status Line : HTTP Version, Response_code, Response_msg
+ "Content-Length: " + fileBytes.length + CRLF + // Header
+ "Content-Type: text/html"+ CRLF + //Add MIME Files later
+ CRLF;
+
+ opStream.write(response.getBytes());
+ opStream.write(fileBytes);
+
+ LOGGER.info("Connection Processing Finished");
+ }catch(IOException e){
+ LOGGER.error("Problem with communication", e);
+ }catch(HttpParsingException e){
+ try {
+ sendErrorResponse(e.getErrorCode(), opStream);
+ } catch (IOException ex) {
+ throw new RuntimeException(ex);
+ }
+ }
+ finally {
+ if(ipStream!=null){
+ try {
+ ipStream.close();
+ }catch (IOException ignored) {}
+ }
+ if(opStream!=null){
+ try{
+ opStream.close();
+ }catch (IOException ignored){}
+ }
+ if(socket!=null){
+ try{
+ socket.close();
+ }catch (IOException ignored){}
+ }
+ }
+ }
+}
diff --git a/httpserver/src/main/java/com/johan/httpserver/core/ServerListenerThread.java b/httpserver/src/main/java/com/johan/httpserver/core/ServerListenerThread.java
new file mode 100644
index 0000000..be088fa
--- /dev/null
+++ b/httpserver/src/main/java/com/johan/httpserver/core/ServerListenerThread.java
@@ -0,0 +1,47 @@
+package com.johan.httpserver.core;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import java.io.IOException;
+import java.net.ServerSocket;
+import java.net.Socket;
+
+public class ServerListenerThread extends Thread{
+ private final static Logger LOGGER = LoggerFactory.getLogger(ServerListenerThread.class);
+
+ private int port;
+ private String webRoot;
+ private ServerSocket serverSocket;
+
+ public ServerListenerThread(int port, String webRoot) throws IOException {
+ this.port=port;
+ this.webRoot=webRoot;
+ this.serverSocket = new ServerSocket(this.port);
+ }
+
+ @Override
+ public void run(){
+
+ try {
+ while(serverSocket.isBound() && !serverSocket.isClosed()) {
+ Socket socket = serverSocket.accept();
+
+ LOGGER.info(" Connection accepted: " + socket.getInetAddress());
+
+ HttpConnectionWorkerThread workerThread = new HttpConnectionWorkerThread(socket);
+ workerThread.start();
+ }
+
+ }
+ catch (IOException e) {
+ LOGGER.error("Problem with setting socket", e);
+ }
+ finally {
+ if(serverSocket!=null){
+ try{
+ serverSocket.close();
+ }catch (IOException ignore){}
+ }
+ }
+ }
+}
diff --git a/httpserver/src/main/java/com/johan/httpserver/core/io/WebRootHandler.java b/httpserver/src/main/java/com/johan/httpserver/core/io/WebRootHandler.java
new file mode 100644
index 0000000..01fed10
--- /dev/null
+++ b/httpserver/src/main/java/com/johan/httpserver/core/io/WebRootHandler.java
@@ -0,0 +1,71 @@
+package com.johan.httpserver.core.io;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.net.URLConnection;
+
+public class WebRootHandler {
+ private File webRoot;
+
+ public WebRootHandler(String webRootPath) throws WebRootNotFoundException{
+ webRoot = new File(webRootPath);
+ if(!webRoot.exists() || !webRoot.isDirectory()){
+ throw new WebRootNotFoundException();
+ }
+ }
+
+ private boolean CheckIfEndsWithSlash(String relativePath){
+ return relativePath.endsWith("/");
+ }
+
+ private boolean CheckIfRelativePathExists(String relativePath){
+ File file = new File(webRoot, relativePath);
+ if(!file.exists()) {
+ return false;
+ }
+ try {
+ if (!file.getCanonicalPath().startsWith(webRoot.getCanonicalPath())) {
+ return true;
+ }
+ }catch (Exception e){
+ return false;
+ }
+ return false;
+ }
+
+ public String GetFileType(String relativePath) throws FileNotFoundException{
+ if (CheckIfEndsWithSlash(relativePath)) {
+ relativePath += "Index.html";
+ }
+ if(CheckIfRelativePathExists(relativePath)) {
+ throw new FileNotFoundException("File not found: "+relativePath);
+ }
+ File file = new File(webRoot, relativePath);;
+ String mimeType = URLConnection.getFileNameMap().getContentTypeFor(file.getName());
+ if(mimeType == null){
+ return "application/octet-stream";
+ }
+ return mimeType;
+ }
+
+ public byte[] GetFileByteArrayData(String relativePath) throws IOException {
+ if (CheckIfEndsWithSlash(relativePath)) {
+ relativePath += "Index.html";
+ }
+ if(CheckIfRelativePathExists(relativePath)) {
+ throw new FileNotFoundException("File not found: "+relativePath);
+ }
+ File file = new File(webRoot, relativePath);
+ FileInputStream fis = new FileInputStream(file);
+ byte[] fileBytes = new byte[(int)file.length()];
+ try{
+ fis.read(fileBytes);
+ fis.close();
+ }catch (IOException e){
+ throw new IOException();
+ }
+ return fileBytes;
+ }
+}
diff --git a/httpserver/src/main/java/com/johan/httpserver/core/io/WebRootNotFoundException.java b/httpserver/src/main/java/com/johan/httpserver/core/io/WebRootNotFoundException.java
new file mode 100644
index 0000000..d1c726f
--- /dev/null
+++ b/httpserver/src/main/java/com/johan/httpserver/core/io/WebRootNotFoundException.java
@@ -0,0 +1,5 @@
+package com.johan.httpserver.core.io;
+
+public class WebRootNotFoundException extends Exception{
+
+}
diff --git a/httpserver/src/main/java/com/johan/httpserver/httpserver.java b/httpserver/src/main/java/com/johan/httpserver/httpserver.java
new file mode 100644
index 0000000..f009280
--- /dev/null
+++ b/httpserver/src/main/java/com/johan/httpserver/httpserver.java
@@ -0,0 +1,32 @@
+package com.johan.httpserver;
+
+import com.johan.httpserver.config.configuration;
+import com.johan.httpserver.config.configmanager;
+import com.johan.httpserver.core.ServerListenerThread;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import java.io.IOException;
+
+public class httpserver {
+
+ private final static Logger LOGGER = LoggerFactory.getLogger(httpserver.class);
+ public static void main(String[] args)
+ {
+ LOGGER.info("Server Starting");
+
+ System.out.println("Server starting...");
+
+ configmanager.getInstance().loadConfigFile(("httpserver/src/main/resources/http.json"));
+ configuration conf = configmanager.getInstance().getCurrentConfig();
+
+ LOGGER.info("Using Port: "+conf.getPort());
+ LOGGER.info("Using WebRoot: "+ conf.getWebroot());
+
+ try {
+ ServerListenerThread serverListenerThread = new ServerListenerThread(conf.getPort(), conf.getWebroot());
+ serverListenerThread.start();
+ }catch (IOException e){
+ e.printStackTrace();
+ }
+ }
+}
\ No newline at end of file
diff --git a/httpserver/src/main/java/com/johan/httpserver/util/json.java b/httpserver/src/main/java/com/johan/httpserver/util/json.java
new file mode 100644
index 0000000..ea2e8ee
--- /dev/null
+++ b/httpserver/src/main/java/com/johan/httpserver/util/json.java
@@ -0,0 +1,45 @@
+package com.johan.httpserver.util;
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.*;
+
+import java.io.IOException;
+
+public class json {
+
+ private static ObjectMapper myobjectmapper = new ObjectMapper();
+
+ private static ObjectMapper defaultObjectMapper(){
+ ObjectMapper om = new ObjectMapper();
+ om.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
+ return om;
+ }
+
+ public static JsonNode parse(String jsonSrc) throws IOException {
+ return myobjectmapper.readTree(jsonSrc);
+ }
+
+ public static A fromJson(JsonNode node, Class c) throws IOException{
+ return myobjectmapper.treeToValue(node, c);
+ }
+
+ public static JsonNode toJson(Object obj){
+ return myobjectmapper.valueToTree(obj);
+ }
+
+ public static String stringify (JsonNode node) throws JsonProcessingException{
+ return generateJson(node, false);
+ }
+
+ public static String stringifyPretty (JsonNode node) throws JsonProcessingException{
+ return generateJson(node, true);
+ }
+
+ private static String generateJson (Object o, boolean pretty) throws JsonProcessingException {
+ ObjectWriter objectwriter = myobjectmapper.writer();
+ if(pretty){
+ objectwriter = objectwriter.with(SerializationFeature.INDENT_OUTPUT);
+ }
+ return objectwriter.writeValueAsString(o);
+ }
+}
diff --git a/httpserver/src/main/resources/http.json b/httpserver/src/main/resources/http.json
new file mode 100644
index 0000000..e530b6f
--- /dev/null
+++ b/httpserver/src/main/resources/http.json
@@ -0,0 +1,4 @@
+{
+ "port": 8080,
+ "webroot":"httpserver/WebRoot/Index.html"
+}
\ No newline at end of file
diff --git a/httpserver/src/test/java/com/johan/http/HttpParserTest.java b/httpserver/src/test/java/com/johan/http/HttpParserTest.java
new file mode 100644
index 0000000..fbe5185
--- /dev/null
+++ b/httpserver/src/test/java/com/johan/http/HttpParserTest.java
@@ -0,0 +1,131 @@
+package com.johan.http;
+
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.TestInstance;
+
+import java.io.ByteArrayInputStream;
+import java.io.InputStream;
+import java.nio.charset.StandardCharsets;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+@TestInstance(TestInstance.Lifecycle.PER_CLASS)
+class HttpParserTest {
+
+ private HttpParser httpParser;
+
+ @BeforeAll
+ public void beforeClass(){
+ httpParser = new HttpParser();
+ }
+
+ @Test
+ void parseHttpReq() {
+ HttpRequest request = null;
+ try {
+ request = HttpParser.parseHttpReq(generateValidTestCase());
+ } catch (HttpParsingException e){
+ fail(e);
+ }
+ assertNotNull(request);
+ }
+
+ @Test
+ void parseHttpReqBadMethod() {
+ try {
+ HttpRequest request = HttpParser.parseHttpReq(generateValidTestCaseBadMethod());
+ fail();
+ } catch (HttpParsingException e) {
+ assertEquals(e.getErrorCode(), HttpStatusCode.SERVER_ERROR_501_NOT_IMPLEMENTED);
+ }
+ }
+
+ @Test
+ void parseHttpReqBadMethod2() {
+ try {
+ HttpRequest request = HttpParser.parseHttpReq(generateValidTestCaseBadMethod2());
+ fail();
+ } catch (HttpParsingException e) {
+ assertEquals(e.getErrorCode(), HttpStatusCode.SERVER_ERROR_501_NOT_IMPLEMENTED);
+ }
+ }
+
+ @Test
+ void parseHttpReqReqLineInvalidItems() {
+ try {
+ HttpRequest request = HttpParser.parseHttpReq(generateValidTestCaseReqLineInvalidItems());
+ fail();
+ } catch (HttpParsingException e) {
+ assertEquals(e.getErrorCode(), HttpStatusCode.CLIENT_ERROR_400_BAD_REQ);
+ }
+ }
+
+ @Test
+ void parseHttpReqEmptyReq() {
+ try {
+ HttpRequest request = HttpParser.parseHttpReq(generateValidTestCaseEmptyReqLine());
+ fail();
+ } catch (HttpParsingException e) {
+ assertEquals(e.getErrorCode(), HttpStatusCode.CLIENT_ERROR_400_BAD_REQ);
+ }
+ }
+
+
+ private InputStream generateValidTestCase(){
+ String rawData="GET / HTTP/1.1\r\n" +
+ "Host: localhost:8080\r\n" +
+ "Connection: keep-alive\r\n" +
+ "sec-ch-ua: \"Not:A-Brand\";v=\"99\", \"Google Chrome\";v=\"145\", \"Chromium\";v=\"145\"\r\n" +
+ "sec-ch-ua-mobile: ?0\r\n" +
+ "sec-ch-ua-platform: \"Windows\"\r\n" +
+ "Upgrade-Insecure-Requests: 1\r\n" +
+ "User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/145.0.0.0 Safari/537.36\r\n" +
+ "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7\r\n" +
+ "Sec-Fetch-Site: none\r\n" +
+ "Sec-Fetch-Mode: navigate\r\n" +
+ "Sec-Fetch-User: ?1\r\n" +
+ "Sec-Fetch-Dest: document\r\n" +
+ "Accept-Encoding: gzip, deflate, br, zstd\r\n" +
+ "Accept-Language: en-US,en;q=0.9,fr;q=0.8\r\n"+
+ "\r\n";
+ InputStream ipStream = new ByteArrayInputStream(rawData.getBytes(StandardCharsets.US_ASCII));
+ return ipStream;
+ }
+
+ private InputStream generateValidTestCaseBadMethod(){
+ String rawData="TF / HTTP/1.1\r\n" +
+ "Host: localhost:8080\r\n" +
+ "Accept-Language: en-US,en;q=0.9,fr;q=0.8\r\n"+
+ "\r\n";
+ InputStream ipStream = new ByteArrayInputStream(rawData.getBytes(StandardCharsets.US_ASCII));
+ return ipStream;
+ }
+
+ private InputStream generateValidTestCaseBadMethod2(){
+ String rawData="GETTTT / HTTP/1.1\r\n" +
+ "Host: localhost:8080\r\n" +
+ "Accept-Language: en-US,en;q=0.9,fr;q=0.8\r\n"+
+ "\r\n";
+ InputStream ipStream = new ByteArrayInputStream(rawData.getBytes(StandardCharsets.US_ASCII));
+ return ipStream;
+ }
+
+ private InputStream generateValidTestCaseReqLineInvalidItems(){
+ String rawData="GET / AAAAA HTTP/1.1\r\n" +
+ "Host: localhost:8080\r\n" +
+ "Accept-Language: en-US,en;q=0.9,fr;q=0.8\r\n"+
+ "\r\n";
+ InputStream ipStream = new ByteArrayInputStream(rawData.getBytes(StandardCharsets.US_ASCII));
+ return ipStream;
+ }
+
+ private InputStream generateValidTestCaseEmptyReqLine(){
+ String rawData="\r\n" +
+ "Host: localhost:8080\r\n" +
+ "Accept-Language: en-US,en;q=0.9,fr;q=0.8\r\n"+
+ "\r\n";
+ InputStream ipStream = new ByteArrayInputStream(rawData.getBytes(StandardCharsets.US_ASCII));
+ return ipStream;
+ }
+}
\ No newline at end of file
diff --git a/src/test/java/com/coderfromscratch/http/HttpVersionTest.java b/httpserver/src/test/java/com/johan/http/HttpVersionTest.java
similarity index 76%
rename from src/test/java/com/coderfromscratch/http/HttpVersionTest.java
rename to httpserver/src/test/java/com/johan/http/HttpVersionTest.java
index eec0460..38ec7ea 100644
--- a/src/test/java/com/coderfromscratch/http/HttpVersionTest.java
+++ b/httpserver/src/test/java/com/johan/http/HttpVersionTest.java
@@ -1,4 +1,4 @@
-package com.coderfromscratch.http;
+package com.johan.http;
import org.junit.jupiter.api.Test;
@@ -7,11 +7,11 @@
public class HttpVersionTest {
@Test
- void getBestCompatibleVersionExactMatch() {
- HttpVersion version = null;
+ void getBestCompatibleVersionExactMatch(){
+ HttpVersion version=null;
try {
version = HttpVersion.getBestCompatibleVersion("HTTP/1.1");
- } catch (BadHttpVersionException e) {
+ }catch(BadHttpVersionException e){
fail();
}
assertNotNull(version);
@@ -19,7 +19,7 @@ void getBestCompatibleVersionExactMatch() {
}
@Test
- void getBestCompatibleVersionBadFormat() {
+ void getBestCompatibleVersionBadMatch(){
HttpVersion version = null;
try {
version = HttpVersion.getBestCompatibleVersion("http/1.1");
@@ -30,7 +30,7 @@ void getBestCompatibleVersionBadFormat() {
}
@Test
- void getBestCompatibleVersionHigherVersion() {
+ void getBestCompatibleVersionHigherVersion(){
HttpVersion version = null;
try {
version = HttpVersion.getBestCompatibleVersion("HTTP/1.2");
diff --git a/pom.xml b/pom.xml
deleted file mode 100644
index b589e83..0000000
--- a/pom.xml
+++ /dev/null
@@ -1,102 +0,0 @@
-
-
- 4.0.0
-
- com.coderfromscratch
- simplehttpserver
- 1.0-SNAPSHOT
-
-
- 1.8
- 1.8
-
-
-
-
-
- com.fasterxml.jackson.core
- jackson-core
- 2.9.9
-
-
- com.fasterxml.jackson.core
- jackson-databind
- 2.9.10.3
-
-
-
- org.slf4j
- slf4j-api
- 1.7.29
-
-
- ch.qos.logback
- logback-classic
- 1.2.3
-
-
-
-
- org.junit.jupiter
- junit-jupiter
- RELEASE
- test
-
-
-
-
-
-
-
- org.apache.maven.plugins
- maven-jar-plugin
- 3.3.0
-
-
-
- com.coderfromscratch.httpserver.HttpServer
-
-
-
-
-
-
-
- org.apache.maven.plugins
- maven-shade-plugin
- 3.2.4
-
-
- package
-
- shade
-
-
-
-
- com.coderfromscratch.httpserver.HttpServer
-
-
-
-
-
- *:*
-
- META-INF/*.SF
- META-INF/*.DSA
- META-INF/*.RSA
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/src/main/java/com/coderfromscratch/http/BadHttpVersionException.java b/src/main/java/com/coderfromscratch/http/BadHttpVersionException.java
deleted file mode 100644
index 6037c4c..0000000
--- a/src/main/java/com/coderfromscratch/http/BadHttpVersionException.java
+++ /dev/null
@@ -1,5 +0,0 @@
-package com.coderfromscratch.http;
-
-public class BadHttpVersionException extends Exception{
-
-}
diff --git a/src/main/java/com/coderfromscratch/http/HttpHeaderName.java b/src/main/java/com/coderfromscratch/http/HttpHeaderName.java
deleted file mode 100644
index 1ada9e1..0000000
--- a/src/main/java/com/coderfromscratch/http/HttpHeaderName.java
+++ /dev/null
@@ -1,12 +0,0 @@
-package com.coderfromscratch.http;
-
-public enum HttpHeaderName {
- CONTENT_TYPE("Content-Type"),
- CONTENT_LENGTH("Content-Length");
-
- public final String headerName;
-
- HttpHeaderName(String headerName) {
- this.headerName = headerName;
- }
-}
diff --git a/src/main/java/com/coderfromscratch/http/HttpMessage.java b/src/main/java/com/coderfromscratch/http/HttpMessage.java
deleted file mode 100644
index 1c2e665..0000000
--- a/src/main/java/com/coderfromscratch/http/HttpMessage.java
+++ /dev/null
@@ -1,31 +0,0 @@
-package com.coderfromscratch.http;
-
-import java.util.HashMap;
-import java.util.Set;
-
-public abstract class HttpMessage {
-
- private HashMap headers = new HashMap<>();
-
- private byte[] messageBody = new byte[0];
-
- public Set getHeaderNames() {
- return headers.keySet();
- }
-
- public String getHeader(String headerName) {
- return headers.get(headerName.toLowerCase());
- }
-
- void addHeader(String headerName, String headerField) {
- headers.put(headerName.toLowerCase(), headerField);
- }
-
- public byte[] getMessageBody() {
- return messageBody;
- }
-
- public void setMessageBody(byte[] messageBody) {
- this.messageBody = messageBody;
- }
-}
diff --git a/src/main/java/com/coderfromscratch/http/HttpMethod.java b/src/main/java/com/coderfromscratch/http/HttpMethod.java
deleted file mode 100644
index 0f91338..0000000
--- a/src/main/java/com/coderfromscratch/http/HttpMethod.java
+++ /dev/null
@@ -1,17 +0,0 @@
-package com.coderfromscratch.http;
-
-public enum HttpMethod {
- GET, HEAD;
-
- public static final int MAX_LENGTH;
-
- static {
- int tempMaxLength = -1;
- for (HttpMethod method : values()) {
- if (method.name().length() > tempMaxLength) {
- tempMaxLength = method.name().length();
- }
- }
- MAX_LENGTH = tempMaxLength;
- }
-}
diff --git a/src/main/java/com/coderfromscratch/http/HttpParser.java b/src/main/java/com/coderfromscratch/http/HttpParser.java
deleted file mode 100644
index d7e0341..0000000
--- a/src/main/java/com/coderfromscratch/http/HttpParser.java
+++ /dev/null
@@ -1,146 +0,0 @@
-package com.coderfromscratch.http;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.nio.charset.StandardCharsets;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-public class HttpParser {
-
- private final static Logger LOGGER = LoggerFactory.getLogger(HttpParser.class);
-
- private static final int SP = 0x20; // 32
- private static final int CR = 0x0D; // 13
- private static final int LF = 0x0A; // 10
-
- public HttpRequest parseHttpRequest(InputStream inputStream) throws HttpParsingException {
- InputStreamReader reader = new InputStreamReader(inputStream, StandardCharsets.US_ASCII);
-
- HttpRequest request = new HttpRequest();
-
- try {
- parseRequestLine(reader, request);
- } catch (IOException e) {
- e.printStackTrace();
- }
- try {
- parseHeaders(reader, request);
- } catch (IOException e) {
- e.printStackTrace();
- }
- parseBody(reader, request);
-
- return request;
- }
-
- private void parseRequestLine(InputStreamReader reader, HttpRequest request) throws IOException, HttpParsingException {
- StringBuilder processingDataBuffer = new StringBuilder();
-
- boolean methodParsed = false;
- boolean requestTargetParsed = false;
-
- // TODO validate URI size!
-
- int _byte;
- while ((_byte = reader.read()) >=0) {
- if (_byte == CR) {
- _byte = reader.read();
- if (_byte == LF) {
- LOGGER.debug("Request Line VERSION to Process : {}" , processingDataBuffer.toString());
- if (!methodParsed || !requestTargetParsed) {
- throw new HttpParsingException(HttpStatusCode.CLIENT_ERROR_400_BAD_REQUEST);
- }
-
- try {
- request.setHttpVersion(processingDataBuffer.toString());
- } catch (BadHttpVersionException e) {
- throw new HttpParsingException(HttpStatusCode.CLIENT_ERROR_400_BAD_REQUEST);
- }
-
- return;
- } else {
- throw new HttpParsingException(HttpStatusCode.CLIENT_ERROR_400_BAD_REQUEST);
- }
- }
-
- if (_byte == SP) {
- if (!methodParsed) {
- LOGGER.debug("Request Line METHOD to Process : {}" , processingDataBuffer.toString());
- request.setMethod(processingDataBuffer.toString());
- methodParsed = true;
- } else if (!requestTargetParsed) {
- LOGGER.debug("Request Line REQ TARGET to Process : {}" , processingDataBuffer.toString());
- request.setRequestTarget(processingDataBuffer.toString());
- requestTargetParsed = true;
- } else {
- throw new HttpParsingException(HttpStatusCode.CLIENT_ERROR_400_BAD_REQUEST);
- }
- processingDataBuffer.delete(0, processingDataBuffer.length());
- } else {
- processingDataBuffer.append((char)_byte);
- if (!methodParsed) {
- if (processingDataBuffer.length() > HttpMethod.MAX_LENGTH) {
- throw new HttpParsingException(HttpStatusCode.SERVER_ERROR_501_NOT_IMPLEMENTED);
- }
- }
- }
- }
-
- }
-
- private void parseHeaders(InputStreamReader reader, HttpRequest request) throws IOException, HttpParsingException {
- StringBuilder processingDataBuffer = new StringBuilder();
- boolean crlfFound = false;
-
- int _byte;
- while ((_byte = reader.read()) >=0) {
- if (_byte == CR) {
- _byte = reader.read();
- if (_byte == LF) {
- if (!crlfFound) {
- crlfFound = true;
-
- // Do Things like processing
- processSingleHeaderField(processingDataBuffer, request);
- // Clear the buffer
- processingDataBuffer.delete(0, processingDataBuffer.length());
- } else {
- // Two CRLF received, end of Headers section
- return;
- }
- } else {
- throw new HttpParsingException(HttpStatusCode.CLIENT_ERROR_400_BAD_REQUEST);
- }
- } else {
- crlfFound = false;
- // Append to Buffer
- processingDataBuffer.append((char)_byte);
- }
- }
- }
-
- private void processSingleHeaderField(StringBuilder processingDataBuffer, HttpRequest request) throws HttpParsingException {
- String rawHeaderField = processingDataBuffer.toString();
- Pattern pattern = Pattern.compile("^(?[!#$%&’*+\\-./^_‘|˜\\dA-Za-z]+):\\s?(?[!#$%&’*+\\-./^_‘|˜(),:;<=>?@[\\\\]{}\" \\dA-Za-z]+)\\s?$");
-
- Matcher matcher = pattern.matcher(rawHeaderField);
- if (matcher.matches()) {
- // We found a proper header
- String fieldName = matcher.group("fieldName");
- String fieldValue = matcher.group("fieldValue");
- request.addHeader(fieldName, fieldValue);
- } else{
- throw new HttpParsingException(HttpStatusCode.CLIENT_ERROR_400_BAD_REQUEST);
- }
- }
-
- private void parseBody(InputStreamReader reader, HttpRequest request) {
-
- }
-
-}
diff --git a/src/main/java/com/coderfromscratch/http/HttpRequest.java b/src/main/java/com/coderfromscratch/http/HttpRequest.java
deleted file mode 100644
index 3c99bb0..0000000
--- a/src/main/java/com/coderfromscratch/http/HttpRequest.java
+++ /dev/null
@@ -1,63 +0,0 @@
-package com.coderfromscratch.http;
-
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.Hashtable;
-import java.util.Set;
-
-public class HttpRequest extends HttpMessage{
-
- private HttpMethod method;
- private String requestTarget;
- private String originalHttpVersion; // literal from the request
- private HttpVersion bestCompatibleHttpVersion;
-
- HttpRequest() {
- }
-
- public HttpMethod getMethod() {
- return method;
- }
-
- public String getRequestTarget() {
- return requestTarget;
- }
-
- public HttpVersion getBestCompatibleHttpVersion() {
- return bestCompatibleHttpVersion;
- }
-
- public String getOriginalHttpVersion() {
- return originalHttpVersion;
- }
-
- void setMethod(String methodName) throws HttpParsingException {
- for (HttpMethod method : HttpMethod.values()) {
- if (methodName.equals(method.name())) {
- this.method = method;
- return;
- }
- }
- throw new HttpParsingException(
- HttpStatusCode.SERVER_ERROR_501_NOT_IMPLEMENTED
- );
- }
-
- void setRequestTarget(String requestTarget) throws HttpParsingException {
- if (requestTarget == null || requestTarget.length() == 0) {
- throw new HttpParsingException(HttpStatusCode.SERVER_ERROR_500_INTERNAL_SERVER_ERROR);
- }
- this.requestTarget = requestTarget;
- }
-
- void setHttpVersion(String originalHttpVersion) throws BadHttpVersionException, HttpParsingException {
- this.originalHttpVersion = originalHttpVersion;
- this.bestCompatibleHttpVersion = HttpVersion.getBestCompatibleVersion(originalHttpVersion);
- if (this.bestCompatibleHttpVersion == null) {
- throw new HttpParsingException(
- HttpStatusCode.SERVER_ERROR_505_HTTP_VERSION_NOT_SUPPORTED
- );
- }
- }
-
-}
diff --git a/src/main/java/com/coderfromscratch/http/HttpResponse.java b/src/main/java/com/coderfromscratch/http/HttpResponse.java
deleted file mode 100644
index 6336da0..0000000
--- a/src/main/java/com/coderfromscratch/http/HttpResponse.java
+++ /dev/null
@@ -1,108 +0,0 @@
-package com.coderfromscratch.http;
-
-public class HttpResponse extends HttpMessage {
-
- private final String CRLF = "\r\n";
-
- // status-line = HTTP-version SP status-code SP reason-phrase CRLF
- private String httpVersion;
-
- private HttpStatusCode statusCode;
-
- private String reasonPhrase = null;
-
- private HttpResponse() {
- }
-
- public String getHttpVersion() {
- return httpVersion;
- }
-
- public void setHttpVersion(String httpVersion) {
- this.httpVersion = httpVersion;
- }
-
- public HttpStatusCode getStatusCode() {
- return statusCode;
- }
-
- public void setStatusCode(HttpStatusCode statusCode) {
- this.statusCode = statusCode;
- }
-
- public String getReasonPhrase() {
- if (reasonPhrase == null && statusCode!=null) {
- return statusCode.MESSAGE;
- }
- return reasonPhrase;
- }
-
- public void setReasonPhrase(String reasonPhrase) {
- this.reasonPhrase = reasonPhrase;
- }
-
- public byte[] getResponseBytes() {
- StringBuilder responseBuilder = new StringBuilder();
- responseBuilder.append(httpVersion)
- .append(" ")
- .append(statusCode.STATUS_CODE)
- .append(" ")
- .append(getReasonPhrase())
- .append(CRLF);
-
- for (String headerName: getHeaderNames()) {
- responseBuilder.append(headerName)
- .append(": ")
- .append(getHeader(headerName))
- .append(CRLF);
- }
-
- responseBuilder.append(CRLF);
-
- byte[] responseBytes = responseBuilder.toString().getBytes();
-
- if (getMessageBody().length == 0)
- return responseBytes;
-
- byte[] responseWithBody = new byte[responseBytes.length + getMessageBody().length];
- System.arraycopy(responseBytes, 0, responseWithBody, 0, responseBytes.length);
- System.arraycopy(getMessageBody(), 0, responseWithBody, responseBytes.length, getMessageBody().length);
-
- return responseWithBody;
- }
-
- public static class Builder {
-
- private HttpResponse response = new HttpResponse();
-
- public Builder httpVersion ( String httpVersion) {
- response.setHttpVersion(httpVersion);
- return this;
- }
-
- public Builder statusCode(HttpStatusCode statusCode) {
- response.setStatusCode(statusCode);
- return this;
- }
-
- public Builder reasonPhrase(String reasonPhrase) {
- response.setReasonPhrase(reasonPhrase);
- return this;
- }
-
- public Builder addHeader(String headerName, String headerField) {
- response.addHeader(headerName, headerField);
- return this;
- }
-
- public Builder messageBody(byte[] messageBody) {
- response.setMessageBody(messageBody);
- return this;
- }
-
- public HttpResponse build() {
- return response;
- }
-
- }
-}
diff --git a/src/main/java/com/coderfromscratch/http/HttpStatusCode.java b/src/main/java/com/coderfromscratch/http/HttpStatusCode.java
deleted file mode 100644
index 4eaf380..0000000
--- a/src/main/java/com/coderfromscratch/http/HttpStatusCode.java
+++ /dev/null
@@ -1,26 +0,0 @@
-package com.coderfromscratch.http;
-
-public enum HttpStatusCode {
-
- /* --- CLIENT ERRORS --- */
- CLIENT_ERROR_400_BAD_REQUEST(400, "Bad Request"),
- CLIENT_ERROR_401_METHOD_NOT_ALLOWED(401, "Method Not Allowed"),
- CLIENT_ERROR_414_BAD_REQUEST(414, "URI Too Long"),
- CLIENT_ERROR_404_NOT_FOUND(404, "Not Found" ),
-
- /* --- SERVER ERRORS --- */
- SERVER_ERROR_500_INTERNAL_SERVER_ERROR(500, "Internal Server Error"),
- SERVER_ERROR_501_NOT_IMPLEMENTED(501, "Not Implemented"),
- SERVER_ERROR_505_HTTP_VERSION_NOT_SUPPORTED(505, "Http Version Not Supported"),
- OK(200,"OK" );
-
-
- public final int STATUS_CODE;
- public final String MESSAGE;
-
- HttpStatusCode(int STATUS_CODE, String MESSAGE) {
- this.STATUS_CODE = STATUS_CODE;
- this.MESSAGE = MESSAGE;
- }
-
-}
diff --git a/src/main/java/com/coderfromscratch/http/HttpVersion.java b/src/main/java/com/coderfromscratch/http/HttpVersion.java
deleted file mode 100644
index 74f6070..0000000
--- a/src/main/java/com/coderfromscratch/http/HttpVersion.java
+++ /dev/null
@@ -1,43 +0,0 @@
-package com.coderfromscratch.http;
-
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-public enum HttpVersion {
- HTTP_1_1("HTTP/1.1", 1 , 1);
-
- public final String LITERAL;
- public final int MAJOR;
- public final int MINOR;
-
- HttpVersion(String LITERAL, int MAJOR, int MINOR) {
- this.LITERAL = LITERAL;
- this.MAJOR = MAJOR;
- this.MINOR = MINOR;
- }
-
- private static final Pattern httpVersionRegexPattern = Pattern.compile("^HTTP/(?\\d+).(?\\d+)");
-
- public static HttpVersion getBestCompatibleVersion(String literalVersion) throws BadHttpVersionException {
- Matcher matcher = httpVersionRegexPattern.matcher(literalVersion);
- if (!matcher.find() || matcher.groupCount() != 2) {
- throw new BadHttpVersionException();
- }
- int major = Integer.parseInt(matcher.group("major"));
- int minor = Integer.parseInt(matcher.group("minor"));
-
- HttpVersion tempBestCompatible = null;
- for (HttpVersion version : HttpVersion.values()) {
- if (version.LITERAL.equals(literalVersion)) {
- return version;
- } else {
- if (version.MAJOR == major) {
- if (version.MINOR < minor) {
- tempBestCompatible = version;
- }
- }
- }
- }
- return tempBestCompatible;
- }
-}
diff --git a/src/main/java/com/coderfromscratch/httpserver/HttpServer.java b/src/main/java/com/coderfromscratch/httpserver/HttpServer.java
deleted file mode 100644
index 894c650..0000000
--- a/src/main/java/com/coderfromscratch/httpserver/HttpServer.java
+++ /dev/null
@@ -1,50 +0,0 @@
-package com.coderfromscratch.httpserver;
-
-import com.coderfromscratch.httpserver.config.Configuration;
-import com.coderfromscratch.httpserver.config.ConfigurationManager;
-import com.coderfromscratch.httpserver.core.ServerListenerThread;
-import com.coderfromscratch.httpserver.core.io.WebRootNotFoundException;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import java.io.IOException;
-
-/**
- *
- * Driver Class for the Http Server
- *
- */
-public class HttpServer {
-
- private final static Logger LOGGER = LoggerFactory.getLogger(HttpServer.class);
-
- public static void main(String[] args) {
-
- if (args.length != 1) {
- LOGGER.error("No configuration file provided.");
- LOGGER.error("Syntax: java -jar simplehttpserver-1.0-SNAPSHOT.jar ");
- return;
- }
-
- LOGGER.info("Server starting...");
-
- ConfigurationManager.getInstance().loadConfigurationFile(args[0]);
- Configuration conf = ConfigurationManager.getInstance().getCurrentConfiguration();
-
- LOGGER.info("Using Port: " + conf.getPort());
- LOGGER.info("Using WebRoot: " + conf.getWebroot());
-
- try {
- ServerListenerThread serverListenerThread = new ServerListenerThread(conf.getPort(), conf.getWebroot());
- serverListenerThread.start();
- } catch (IOException e) {
- e.printStackTrace();
- // TODO handle later.
- } catch (WebRootNotFoundException e) {
- LOGGER.error("Webroot folder not found",e);
- }
-
-
- }
-
-}
diff --git a/src/main/java/com/coderfromscratch/httpserver/config/ConfigurationManager.java b/src/main/java/com/coderfromscratch/httpserver/config/ConfigurationManager.java
deleted file mode 100644
index 8857d58..0000000
--- a/src/main/java/com/coderfromscratch/httpserver/config/ConfigurationManager.java
+++ /dev/null
@@ -1,66 +0,0 @@
-package com.coderfromscratch.httpserver.config;
-
-import com.coderfromscratch.httpserver.util.Json;
-import com.fasterxml.jackson.core.JsonProcessingException;
-import com.fasterxml.jackson.databind.JsonNode;
-
-import java.io.FileNotFoundException;
-import java.io.FileReader;
-import java.io.IOException;
-
-public class ConfigurationManager {
-
- private static ConfigurationManager myConfigurationManager;
- private static Configuration myCurrentConfiguration;
-
- private ConfigurationManager() {
- }
-
- public static ConfigurationManager getInstance() {
- if (myConfigurationManager==null)
- myConfigurationManager = new ConfigurationManager();
- return myConfigurationManager;
- }
-
- /**
- * Used to load a configuration file by the path provided
- */
- public void loadConfigurationFile(String filePath) {
- FileReader fileReader = null;
- try {
- fileReader = new FileReader(filePath);
- } catch (FileNotFoundException e) {
- throw new HttpConfigurationException(e);
- }
- StringBuffer sb = new StringBuffer();
- int i ;
- try {
- while ( ( i = fileReader.read()) != -1) {
- sb.append((char)i);
- }
- } catch (IOException e) {
- throw new HttpConfigurationException(e);
- }
- JsonNode conf = null;
- try {
- conf = Json.parse(sb.toString());
- } catch (IOException e) {
- throw new HttpConfigurationException("Error parsing the Configuration File", e);
- }
- try {
- myCurrentConfiguration = Json.fromJson(conf, Configuration.class);
- } catch (JsonProcessingException e) {
- throw new HttpConfigurationException("Error parsing the Configuration file, internal",e);
- }
- }
-
- /**
- * Returns the Current loaded Configuration
- */
- public Configuration getCurrentConfiguration() {
- if ( myCurrentConfiguration == null) {
- throw new HttpConfigurationException("No Current Configuration Set.");
- }
- return myCurrentConfiguration;
- }
-}
diff --git a/src/main/java/com/coderfromscratch/httpserver/config/HttpConfigurationException.java b/src/main/java/com/coderfromscratch/httpserver/config/HttpConfigurationException.java
deleted file mode 100644
index 516ddef..0000000
--- a/src/main/java/com/coderfromscratch/httpserver/config/HttpConfigurationException.java
+++ /dev/null
@@ -1,20 +0,0 @@
-package com.coderfromscratch.httpserver.config;
-
-public class HttpConfigurationException extends RuntimeException {
-
- public HttpConfigurationException() {
- }
-
- public HttpConfigurationException(String message) {
- super(message);
- }
-
- public HttpConfigurationException(String message, Throwable cause) {
- super(message, cause);
- }
-
- public HttpConfigurationException(Throwable cause) {
- super(cause);
- }
-
-}
diff --git a/src/main/java/com/coderfromscratch/httpserver/core/HttpConnectionWorkerThread.java b/src/main/java/com/coderfromscratch/httpserver/core/HttpConnectionWorkerThread.java
deleted file mode 100644
index d55311d..0000000
--- a/src/main/java/com/coderfromscratch/httpserver/core/HttpConnectionWorkerThread.java
+++ /dev/null
@@ -1,125 +0,0 @@
-package com.coderfromscratch.httpserver.core;
-
-import com.coderfromscratch.http.*;
-import com.coderfromscratch.httpserver.core.io.ReadFileException;
-import com.coderfromscratch.httpserver.core.io.WebRootHandler;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.net.Socket;
-
-public class HttpConnectionWorkerThread extends Thread {
- private final static Logger LOGGER = LoggerFactory.getLogger(HttpConnectionWorkerThread.class);
- private Socket socket;
- private WebRootHandler webRootHandler;
- private HttpParser httpParser = new HttpParser();
-
- public HttpConnectionWorkerThread(Socket socket, WebRootHandler webRootHandler) {
- this.socket = socket;
- this.webRootHandler = webRootHandler;
- }
-
- @Override
- public void run() {
- InputStream inputStream = null;
- OutputStream outputStream = null;
-
- try {
- inputStream = socket.getInputStream();
- outputStream = socket.getOutputStream();
-
- HttpRequest request = httpParser.parseHttpRequest(inputStream);
- HttpResponse response = handleRequest(request);
-
- outputStream.write(response.getResponseBytes());
-
- LOGGER.info(" * Connection Processing Finished.");
- } catch (IOException e) {
- LOGGER.error("Problem with communication", e);
- } catch (HttpParsingException e) {
- LOGGER.info("Bag Request", e);
-
- HttpResponse response = new HttpResponse.Builder()
- .httpVersion(HttpVersion.HTTP_1_1.LITERAL)
- .statusCode(e.getErrorCode())
- .build();
- try {
- outputStream.write(response.getResponseBytes());
- } catch (IOException ex) {
- LOGGER.error("Problem with communication", e);
- }
-
- } finally {
- if (inputStream!= null) {
- try {
- inputStream.close();
- } catch (IOException e) {}
- }
- if (outputStream!=null) {
- try {
- outputStream.close();
- } catch (IOException e) {}
- }
- if (socket!= null) {
- try {
- socket.close();
- } catch (IOException e) {}
- }
- }
- }
-
- private HttpResponse handleRequest(HttpRequest request) {
-
- switch (request.getMethod()) {
- case GET:
- LOGGER.info(" * GET Request");
- return handleGetRequest(request, true);
- case HEAD:
- LOGGER.info(" * HEAD Request");
- return handleGetRequest(request, false);
- default:
- return new HttpResponse.Builder()
- .httpVersion(request.getBestCompatibleHttpVersion().LITERAL)
- .statusCode(HttpStatusCode.SERVER_ERROR_501_NOT_IMPLEMENTED)
- .build();
- }
-
- }
-
- private HttpResponse handleGetRequest(HttpRequest request, boolean setMessageBody) {
- try {
-
- HttpResponse.Builder builder = new HttpResponse.Builder()
- .httpVersion(request.getBestCompatibleHttpVersion().LITERAL)
- .statusCode(HttpStatusCode.OK)
- .addHeader(HttpHeaderName.CONTENT_TYPE.headerName, webRootHandler.getFileMimeType(request.getRequestTarget()));
-
- if (setMessageBody) {
- byte[] messageBody = webRootHandler.getFileByteArrayData(request.getRequestTarget());
- builder.addHeader(HttpHeaderName.CONTENT_LENGTH.headerName, String.valueOf(messageBody.length))
- .messageBody(messageBody);
- }
-
- return builder.build();
-
- } catch (FileNotFoundException e) {
-
- return new HttpResponse.Builder()
- .httpVersion(request.getBestCompatibleHttpVersion().LITERAL)
- .statusCode(HttpStatusCode.CLIENT_ERROR_404_NOT_FOUND)
- .build();
-
- } catch (ReadFileException e) {
-
- return new HttpResponse.Builder()
- .httpVersion(request.getBestCompatibleHttpVersion().LITERAL)
- .statusCode(HttpStatusCode.SERVER_ERROR_500_INTERNAL_SERVER_ERROR)
- .build();
- }
-
- }
-}
diff --git a/src/main/java/com/coderfromscratch/httpserver/core/ServerListenerThread.java b/src/main/java/com/coderfromscratch/httpserver/core/ServerListenerThread.java
deleted file mode 100644
index c00766d..0000000
--- a/src/main/java/com/coderfromscratch/httpserver/core/ServerListenerThread.java
+++ /dev/null
@@ -1,57 +0,0 @@
-package com.coderfromscratch.httpserver.core;
-
-import com.coderfromscratch.httpserver.core.io.WebRootHandler;
-import com.coderfromscratch.httpserver.core.io.WebRootNotFoundException;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.net.ServerSocket;
-import java.net.Socket;
-
-public class ServerListenerThread extends Thread {
-
- private final static Logger LOGGER = LoggerFactory.getLogger(ServerListenerThread.class);
-
- private int port;
- private String webroot;
- private ServerSocket serverSocket;
-
- private WebRootHandler webRootHandler;
-
- public ServerListenerThread(int port, String webroot) throws IOException, WebRootNotFoundException {
- this.port = port;
- this.webroot = webroot;
- this.webRootHandler = new WebRootHandler(webroot);
- this.serverSocket = new ServerSocket(this.port);
- }
-
- @Override
- public void run() {
-
- try {
-
- while ( serverSocket.isBound() && !serverSocket.isClosed()) {
- Socket socket = serverSocket.accept();
-
- LOGGER.info(" * Connection accepted: " + socket.getInetAddress());
-
- HttpConnectionWorkerThread workerThread = new HttpConnectionWorkerThread(socket, webRootHandler);
- workerThread.start();
-
- }
-
- } catch (IOException e) {
- LOGGER.error("Problem with setting socket", e);
- } finally {
- if (serverSocket!=null) {
- try {
- serverSocket.close();
- } catch (IOException e) {}
- }
- }
-
- }
-}
diff --git a/src/main/java/com/coderfromscratch/httpserver/core/io/ReadFileException.java b/src/main/java/com/coderfromscratch/httpserver/core/io/ReadFileException.java
deleted file mode 100644
index b27608f..0000000
--- a/src/main/java/com/coderfromscratch/httpserver/core/io/ReadFileException.java
+++ /dev/null
@@ -1,22 +0,0 @@
-package com.coderfromscratch.httpserver.core.io;
-
-public class ReadFileException extends Throwable {
- public ReadFileException() {
- }
-
- public ReadFileException(String message) {
- super(message);
- }
-
- public ReadFileException(String message, Throwable cause) {
- super(message, cause);
- }
-
- public ReadFileException(Throwable cause) {
- super(cause);
- }
-
- public ReadFileException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
- super(message, cause, enableSuppression, writableStackTrace);
- }
-}
diff --git a/src/main/java/com/coderfromscratch/httpserver/core/io/WebRootHandler.java b/src/main/java/com/coderfromscratch/httpserver/core/io/WebRootHandler.java
deleted file mode 100644
index efcfc88..0000000
--- a/src/main/java/com/coderfromscratch/httpserver/core/io/WebRootHandler.java
+++ /dev/null
@@ -1,96 +0,0 @@
-package com.coderfromscratch.httpserver.core.io;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.net.URLConnection;
-
-public class WebRootHandler {
-
- private File webRoot;
-
- public WebRootHandler(String webRootPath) throws WebRootNotFoundException {
- webRoot = new File(webRootPath);
- if (!webRoot.exists() || !webRoot.isDirectory()) {
- throw new WebRootNotFoundException("Webroot provided does not exist or is not a folder");
- }
- }
-
- private boolean checkIfEndsWithSlash(String relativePath) {
- return relativePath.endsWith("/");
- }
-
- /**
- * This method checks to see if the relative path provided exists inside WebRoot
- *
- * @param relativePath
- * @return true if the path exists inside WebRoot, false if not.
- */
- private boolean checkIfProvidedRelativePathExists(String relativePath) {
- File file = new File(webRoot, relativePath);
-
- if (!file.exists())
- return false;
-
- try {
- if (file.getCanonicalPath().startsWith(webRoot.getCanonicalPath())) {
- return true;
- }
- } catch (IOException e) {
- return false;
- }
- return false;
- }
-
- public String getFileMimeType(String relativePath) throws FileNotFoundException {
- if (checkIfEndsWithSlash(relativePath)) {
- relativePath += "index.html"; // By default serve the index.html, if it exists.
- }
-
- if (!checkIfProvidedRelativePathExists(relativePath)) {
- throw new FileNotFoundException("File not found: " + relativePath);
- }
-
- File file = new File(webRoot, relativePath);
-
- String mimeType = URLConnection.getFileNameMap().getContentTypeFor(file.getName());
-
- if (mimeType == null) {
- return "application/octet-stream";
- }
-
- return mimeType;
- }
-
- /**
- * Returns a byte array of the content of a file.
- *
- * Todo - For large files a new strategy might be necessary.
- *
- * @param relativePath the path to the file inside the webroot folder.
- * @return a byte array of the data.
- * @throws FileNotFoundException if the file can not be found
- * @throws ReadFileException if there was a problem reading the file.
- */
- public byte[] getFileByteArrayData(String relativePath) throws FileNotFoundException, ReadFileException {
- if (checkIfEndsWithSlash(relativePath)) {
- relativePath += "index.html"; // By default serve the index.html, if it exists.
- }
-
- if (!checkIfProvidedRelativePathExists(relativePath)) {
- throw new FileNotFoundException("File not found: " + relativePath);
- }
-
- File file = new File(webRoot, relativePath);
- FileInputStream fileInputStream = new FileInputStream(file);
- byte[] fileBytes = new byte[(int)file.length()];
- try {
- fileInputStream.read(fileBytes);
- fileInputStream.close();
- } catch (IOException e) {
- throw new ReadFileException(e);
- }
- return fileBytes;
- }
-}
diff --git a/src/main/java/com/coderfromscratch/httpserver/core/io/WebRootNotFoundException.java b/src/main/java/com/coderfromscratch/httpserver/core/io/WebRootNotFoundException.java
deleted file mode 100644
index d597787..0000000
--- a/src/main/java/com/coderfromscratch/httpserver/core/io/WebRootNotFoundException.java
+++ /dev/null
@@ -1,7 +0,0 @@
-package com.coderfromscratch.httpserver.core.io;
-
-public class WebRootNotFoundException extends Throwable {
- public WebRootNotFoundException(String message) {
- super(message);
- }
-}
diff --git a/src/main/java/com/coderfromscratch/httpserver/util/Json.java b/src/main/java/com/coderfromscratch/httpserver/util/Json.java
deleted file mode 100644
index 04d3656..0000000
--- a/src/main/java/com/coderfromscratch/httpserver/util/Json.java
+++ /dev/null
@@ -1,45 +0,0 @@
-package com.coderfromscratch.httpserver.util;
-
-import com.fasterxml.jackson.core.JsonProcessingException;
-import com.fasterxml.jackson.databind.*;
-
-import java.io.IOException;
-
-public class Json {
-
- private static ObjectMapper myObjectMapper = defaultObjectMapper();
-
- private static ObjectMapper defaultObjectMapper() {
- ObjectMapper om = new ObjectMapper();
- om.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
- return om;
- }
-
- public static JsonNode parse(String jsonSrc) throws IOException {
- return myObjectMapper.readTree(jsonSrc);
- }
-
- public static A fromJson(JsonNode node , Class clazz) throws JsonProcessingException {
- return myObjectMapper.treeToValue(node, clazz);
- }
-
- public static JsonNode toJson(Object obj) {
- return myObjectMapper.valueToTree(obj);
- }
-
- public static String stringify(JsonNode node) throws JsonProcessingException {
- return generateJson(node, false);
- }
-
- public static String stringifyPretty(JsonNode node) throws JsonProcessingException {
- return generateJson(node, true);
- }
-
- private static String generateJson(Object o, boolean pretty) throws JsonProcessingException {
- ObjectWriter objectWriter = myObjectMapper.writer();
- if (pretty) {
- objectWriter = objectWriter.with(SerializationFeature.INDENT_OUTPUT);
- }
- return objectWriter.writeValueAsString(o);
- }
-}
diff --git a/src/main/resources/http.json b/src/main/resources/http.json
deleted file mode 100644
index e1e8221..0000000
--- a/src/main/resources/http.json
+++ /dev/null
@@ -1,4 +0,0 @@
-{
- "port": 8080,
- "webroot": "WebRoot"
-}
\ No newline at end of file
diff --git a/src/test/java/com/coderfromscratch/http/HttpHeadersParserTest.java b/src/test/java/com/coderfromscratch/http/HttpHeadersParserTest.java
deleted file mode 100644
index 21a960d..0000000
--- a/src/test/java/com/coderfromscratch/http/HttpHeadersParserTest.java
+++ /dev/null
@@ -1,129 +0,0 @@
-package com.coderfromscratch.http;
-
-import org.junit.jupiter.api.BeforeAll;
-import org.junit.jupiter.api.Test;
-import org.junit.jupiter.api.TestInstance;
-
-import java.io.ByteArrayInputStream;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.nio.charset.StandardCharsets;
-
-import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.fail;
-
-@TestInstance(TestInstance.Lifecycle.PER_CLASS)
-public class HttpHeadersParserTest {
-
- private HttpParser httpParser;
- private Method parseHeadersMethod;
-
- @BeforeAll
- public void beforeClass() throws NoSuchMethodException {
- httpParser = new HttpParser();
- Class cls = HttpParser.class;
- parseHeadersMethod = cls.getDeclaredMethod("parseHeaders", InputStreamReader.class, HttpRequest.class);
- parseHeadersMethod.setAccessible(true);
- }
-
- @Test
- public void testSimpleSingleHeader() throws InvocationTargetException, IllegalAccessException {
- HttpRequest request = new HttpRequest();
- parseHeadersMethod.invoke(
- httpParser,
- generateSimpleSingleHeaderMessage(),
- request);
- assertEquals(1, request.getHeaderNames().size());
- assertEquals("localhost:8080", request.getHeader("host"));
- }
-
- @Test
- public void testMultipleHeaders() throws InvocationTargetException, IllegalAccessException {
- HttpRequest request = new HttpRequest();
- parseHeadersMethod.invoke(
- httpParser,
- generateMultipleHeadersMessage(),
- request);
- assertEquals(10, request.getHeaderNames().size());
- assertEquals("localhost:8080", request.getHeader("host"));
- }
-
- @Test
- public void testErrorSpaceBeforeColonHeader() throws InvocationTargetException, IllegalAccessException {
- HttpRequest request = new HttpRequest();
-
- try {
- parseHeadersMethod.invoke(
- httpParser,
- generateSpaceBeforeColonErrorHeaderMessage(),
- request);
- } catch (InvocationTargetException e) {
- if (e.getCause() instanceof HttpParsingException) {
- assertEquals(HttpStatusCode.CLIENT_ERROR_400_BAD_REQUEST, ((HttpParsingException)e.getCause()).getErrorCode());
- }
- }
-
- }
-
- private InputStreamReader generateSimpleSingleHeaderMessage() {
- String rawData = "Host: localhost:8080\r\n" ;
-// "Connection: keep-alive\r\n" +
-// "Upgrade-Insecure-Requests: 1\r\n" +
-// "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.97 Safari/537.36\r\n" +
-// "Sec-Fetch-User: ?1\r\n" +
-// "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3\r\n" +
-// "Sec-Fetch-Site: none\r\n" +
-// "Sec-Fetch-Mode: navigate\r\n" +
-// "Accept-Encoding: gzip, deflate, br\r\n" +
-// "Accept-Language: en-US,en;q=0.9,es;q=0.8,pt;q=0.7,de-DE;q=0.6,de;q=0.5,la;q=0.4\r\n" +
-// "\r\n";
-
- InputStream inputStream = new ByteArrayInputStream(
- rawData.getBytes(
- StandardCharsets.US_ASCII
- )
- );
-
- InputStreamReader reader = new InputStreamReader(inputStream, StandardCharsets.US_ASCII);
- return reader;
- }
-
- private InputStreamReader generateMultipleHeadersMessage() {
- String rawData = "Host: localhost:8080\r\n" +
- "Connection: keep-alive\r\n" +
- "Upgrade-Insecure-Requests: 1\r\n" +
- "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.97 Safari/537.36\r\n" +
- "Sec-Fetch-User: ?1\r\n" +
- "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3\r\n" +
- "Sec-Fetch-Site: none\r\n" +
- "Sec-Fetch-Mode: navigate\r\n" +
- "Accept-Encoding: gzip, deflate, br\r\n" +
- "Accept-Language: en-US,en;q=0.9,es;q=0.8,pt;q=0.7,de-DE;q=0.6,de;q=0.5,la;q=0.4\r\n" +
- "\r\n";
-
- InputStream inputStream = new ByteArrayInputStream(
- rawData.getBytes(
- StandardCharsets.US_ASCII
- )
- );
-
- InputStreamReader reader = new InputStreamReader(inputStream, StandardCharsets.US_ASCII);
- return reader;
- }
-
- private InputStreamReader generateSpaceBeforeColonErrorHeaderMessage() {
- String rawData = "Host : localhost:8080\r\n\r\n" ;
-
- InputStream inputStream = new ByteArrayInputStream(
- rawData.getBytes(
- StandardCharsets.US_ASCII
- )
- );
-
- InputStreamReader reader = new InputStreamReader(inputStream, StandardCharsets.US_ASCII);
- return reader;
- }
-
-}
diff --git a/src/test/java/com/coderfromscratch/http/HttpParserTest.java b/src/test/java/com/coderfromscratch/http/HttpParserTest.java
deleted file mode 100644
index 1a5a867..0000000
--- a/src/test/java/com/coderfromscratch/http/HttpParserTest.java
+++ /dev/null
@@ -1,305 +0,0 @@
-package com.coderfromscratch.http;
-
-import org.junit.jupiter.api.BeforeAll;
-import org.junit.jupiter.api.Test;
-import org.junit.jupiter.api.TestInstance;
-
-import java.io.ByteArrayInputStream;
-import java.io.InputStream;
-import java.nio.charset.StandardCharsets;
-
-import static org.junit.jupiter.api.Assertions.*;
-
-@TestInstance(TestInstance.Lifecycle.PER_CLASS)
-class HttpParserTest {
-
- private HttpParser httpParser;
-
- @BeforeAll
- public void beforeClass() {
- httpParser = new HttpParser();
- }
-
- @Test
- void parseHttpRequest() {
- HttpRequest request = null;
- try {
- request = httpParser.parseHttpRequest(
- generateValidGETTestCase()
- );
- } catch (HttpParsingException e) {
- fail(e);
- }
-
- assertNotNull(request);
- assertEquals(request.getMethod(), HttpMethod.GET);
- assertEquals(request.getRequestTarget(), "/");
- assertEquals(request.getOriginalHttpVersion(), "HTTP/1.1");
- assertEquals(request.getBestCompatibleHttpVersion(), HttpVersion.HTTP_1_1);
- }
-
- @Test
- void parseHttpRequestBadMethod1() {
- try {
- HttpRequest request = httpParser.parseHttpRequest(
- generateBadTestCaseMethodName1()
- );
- fail();
- } catch (HttpParsingException e) {
- assertEquals(e.getErrorCode(), HttpStatusCode.SERVER_ERROR_501_NOT_IMPLEMENTED);
- }
- }
-
- @Test
- void parseHttpRequestBadMethod2() {
- try {
- HttpRequest request = httpParser.parseHttpRequest(
- generateBadTestCaseMethodName2()
- );
- fail();
- } catch (HttpParsingException e) {
- assertEquals(e.getErrorCode(), HttpStatusCode.SERVER_ERROR_501_NOT_IMPLEMENTED);
- }
- }
-
- @Test
- void parseHttpRequestInvNumItems1() {
- try {
- HttpRequest request = httpParser.parseHttpRequest(
- generateBadTestCaseRequestLineInvNumItems1()
- );
- fail();
- } catch (HttpParsingException e) {
- assertEquals(e.getErrorCode(), HttpStatusCode.CLIENT_ERROR_400_BAD_REQUEST);
- }
- }
-
- @Test
- void parseHttpEmptyRequestLine() {
- try {
- HttpRequest request = httpParser.parseHttpRequest(
- generateBadTestCaseEmptyRequestLine()
- );
- fail();
- } catch (HttpParsingException e) {
- assertEquals(e.getErrorCode(), HttpStatusCode.CLIENT_ERROR_400_BAD_REQUEST);
- }
- }
-
- @Test
- void parseHttpRequestLineCRnoLF() {
- try {
- HttpRequest request = httpParser.parseHttpRequest(
- generateBadTestCaseRequestLineOnlyCRnoLF()
- );
- fail();
- } catch (HttpParsingException e) {
- assertEquals(e.getErrorCode(), HttpStatusCode.CLIENT_ERROR_400_BAD_REQUEST);
- }
- }
-
- @Test
- void parseHttpRequestBadHttpVersion() {
- try {
- HttpRequest request = httpParser.parseHttpRequest(
- generateBadHttpVersionTestCase()
- );
- fail();
- } catch (HttpParsingException e) {
- assertEquals(e.getErrorCode(), HttpStatusCode.CLIENT_ERROR_400_BAD_REQUEST);
- }
- }
-
- @Test
- void parseHttpRequestUnsupportedHttpVersion() {
- try {
- HttpRequest request = httpParser.parseHttpRequest(
- generateUnsuportedHttpVersionTestCase()
- );
- fail();
- } catch (HttpParsingException e) {
- assertEquals(e.getErrorCode(), HttpStatusCode.SERVER_ERROR_505_HTTP_VERSION_NOT_SUPPORTED);
- }
- }
-
- @Test
- void parseHttpRequestSupportedHttpVersion1() {
- try {
- HttpRequest request = httpParser.parseHttpRequest(
- generateSupportedHttpVersion1()
- );
- assertNotNull(request);
- assertEquals(request.getBestCompatibleHttpVersion(), HttpVersion.HTTP_1_1);
- assertEquals(request.getOriginalHttpVersion(), "HTTP/1.2");
- } catch (HttpParsingException e) {
- fail();
- }
- }
-
- private InputStream generateValidGETTestCase() {
- String rawData = "GET / HTTP/1.1\r\n" +
- "Host: localhost:8080\r\n" +
- "Connection: keep-alive\r\n" +
- "Upgrade-Insecure-Requests: 1\r\n" +
- "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.97 Safari/537.36\r\n" +
- "Sec-Fetch-User: ?1\r\n" +
- "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3\r\n" +
- "Sec-Fetch-Site: none\r\n" +
- "Sec-Fetch-Mode: navigate\r\n" +
- "Accept-Encoding: gzip, deflate, br\r\n" +
- "Accept-Language: en-US,en;q=0.9,es;q=0.8,pt;q=0.7,de-DE;q=0.6,de;q=0.5,la;q=0.4\r\n" +
- "\r\n";
-
- InputStream inputStream = new ByteArrayInputStream(
- rawData.getBytes(
- StandardCharsets.US_ASCII
- )
- );
-
- return inputStream;
- }
-
- private InputStream generateBadTestCaseMethodName1() {
- String rawData = "GeT / HTTP/1.1\r\n" +
- "Host: localhost:8080\r\n" +
- "Accept-Language: en-US,en;q=0.9,es;q=0.8,pt;q=0.7,de-DE;q=0.6,de;q=0.5,la;q=0.4\r\n" +
- "\r\n";
-
- InputStream inputStream = new ByteArrayInputStream(
- rawData.getBytes(
- StandardCharsets.US_ASCII
- )
- );
-
- return inputStream;
- }
-
- private InputStream generateBadTestCaseMethodName2() {
- String rawData = "GETTTT / HTTP/1.1\r\n" +
- "Host: localhost:8080\r\n" +
- "Accept-Language: en-US,en;q=0.9,es;q=0.8,pt;q=0.7,de-DE;q=0.6,de;q=0.5,la;q=0.4\r\n" +
- "\r\n";
-
- InputStream inputStream = new ByteArrayInputStream(
- rawData.getBytes(
- StandardCharsets.US_ASCII
- )
- );
-
- return inputStream;
- }
-
- private InputStream generateBadTestCaseRequestLineInvNumItems1() {
- String rawData = "GET / AAAAAA HTTP/1.1\r\n" +
- "Host: localhost:8080\r\n" +
- "Accept-Language: en-US,en;q=0.9,es;q=0.8,pt;q=0.7,de-DE;q=0.6,de;q=0.5,la;q=0.4\r\n" +
- "\r\n";
-
- InputStream inputStream = new ByteArrayInputStream(
- rawData.getBytes(
- StandardCharsets.US_ASCII
- )
- );
-
- return inputStream;
- }
-
- private InputStream generateBadTestCaseEmptyRequestLine() {
- String rawData = "\r\n" +
- "Host: localhost:8080\r\n" +
- "Accept-Language: en-US,en;q=0.9,es;q=0.8,pt;q=0.7,de-DE;q=0.6,de;q=0.5,la;q=0.4\r\n" +
- "\r\n";
-
- InputStream inputStream = new ByteArrayInputStream(
- rawData.getBytes(
- StandardCharsets.US_ASCII
- )
- );
-
- return inputStream;
- }
-
- private InputStream generateBadTestCaseRequestLineOnlyCRnoLF() {
- String rawData = "GET / HTTP/1.1\r" + // <----- no LF
- "Host: localhost:8080\r\n" +
- "Accept-Language: en-US,en;q=0.9,es;q=0.8,pt;q=0.7,de-DE;q=0.6,de;q=0.5,la;q=0.4\r\n" +
- "\r\n";
-
- InputStream inputStream = new ByteArrayInputStream(
- rawData.getBytes(
- StandardCharsets.US_ASCII
- )
- );
-
- return inputStream;
- }
-
- private InputStream generateBadHttpVersionTestCase() {
- String rawData = "GET / HTP/1.1\r\n" +
- "Host: localhost:8080\r\n" +
- "Connection: keep-alive\r\n" +
- "Upgrade-Insecure-Requests: 1\r\n" +
- "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.97 Safari/537.36\r\n" +
- "Sec-Fetch-User: ?1\r\n" +
- "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3\r\n" +
- "Sec-Fetch-Site: none\r\n" +
- "Sec-Fetch-Mode: navigate\r\n" +
- "Accept-Encoding: gzip, deflate, br\r\n" +
- "Accept-Language: en-US,en;q=0.9,es;q=0.8,pt;q=0.7,de-DE;q=0.6,de;q=0.5,la;q=0.4\r\n" +
- "\r\n";
-
- InputStream inputStream = new ByteArrayInputStream(
- rawData.getBytes(
- StandardCharsets.US_ASCII
- )
- );
-
- return inputStream;
- }
-
- private InputStream generateUnsuportedHttpVersionTestCase() {
- String rawData = "GET / HTTP/2.1\r\n" +
- "Host: localhost:8080\r\n" +
- "Connection: keep-alive\r\n" +
- "Upgrade-Insecure-Requests: 1\r\n" +
- "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.97 Safari/537.36\r\n" +
- "Sec-Fetch-User: ?1\r\n" +
- "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3\r\n" +
- "Sec-Fetch-Site: none\r\n" +
- "Sec-Fetch-Mode: navigate\r\n" +
- "Accept-Encoding: gzip, deflate, br\r\n" +
- "Accept-Language: en-US,en;q=0.9,es;q=0.8,pt;q=0.7,de-DE;q=0.6,de;q=0.5,la;q=0.4\r\n" +
- "\r\n";
-
- InputStream inputStream = new ByteArrayInputStream(
- rawData.getBytes(
- StandardCharsets.US_ASCII
- )
- );
-
- return inputStream;
- }
-
- private InputStream generateSupportedHttpVersion1() {
- String rawData = "GET / HTTP/1.2\r\n" +
- "Host: localhost:8080\r\n" +
- "Connection: keep-alive\r\n" +
- "Upgrade-Insecure-Requests: 1\r\n" +
- "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.97 Safari/537.36\r\n" +
- "Sec-Fetch-User: ?1\r\n" +
- "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3\r\n" +
- "Sec-Fetch-Site: none\r\n" +
- "Sec-Fetch-Mode: navigate\r\n" +
- "Accept-Encoding: gzip, deflate, br\r\n" +
- "Accept-Language: en-US,en;q=0.9,es;q=0.8,pt;q=0.7,de-DE;q=0.6,de;q=0.5,la;q=0.4\r\n" +
- "\r\n";
-
- InputStream inputStream = new ByteArrayInputStream(
- rawData.getBytes(
- StandardCharsets.US_ASCII
- )
- );
-
- return inputStream;
- }
-}
\ No newline at end of file
diff --git a/src/test/java/com/coderfromscratch/httpserver/core/io/WebRootHandlerTest.java b/src/test/java/com/coderfromscratch/httpserver/core/io/WebRootHandlerTest.java
deleted file mode 100644
index c8d4a58..0000000
--- a/src/test/java/com/coderfromscratch/httpserver/core/io/WebRootHandlerTest.java
+++ /dev/null
@@ -1,229 +0,0 @@
-package com.coderfromscratch.httpserver.core.io;
-
-import com.coderfromscratch.http.HttpParser;
-import org.junit.jupiter.api.BeforeAll;
-import org.junit.jupiter.api.Test;
-import org.junit.jupiter.api.TestInstance;
-
-import java.io.FileNotFoundException;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-
-import static org.junit.jupiter.api.Assertions.*;
-
-@TestInstance(TestInstance.Lifecycle.PER_CLASS)
-public class WebRootHandlerTest {
-
- private WebRootHandler webRootHandler;
-
- private Method checkIfEndsWithSlashMethod;
-
- private Method checkIfProvidedRelativePathExistsMethod;
- @BeforeAll
- public void beforeClass() throws WebRootNotFoundException, NoSuchMethodException {
- webRootHandler = new WebRootHandler("WebRoot");
- Class cls = WebRootHandler.class;
- checkIfEndsWithSlashMethod = cls.getDeclaredMethod("checkIfEndsWithSlash", String.class);
- checkIfEndsWithSlashMethod.setAccessible(true);
-
- checkIfProvidedRelativePathExistsMethod = cls.getDeclaredMethod("checkIfProvidedRelativePathExists", String.class);
- checkIfProvidedRelativePathExistsMethod.setAccessible(true);
- }
-
- @Test
- void constructorGoodPath() {
- try {
- WebRootHandler webRootHandler = new WebRootHandler("E:\\Projects\\CoderFromScratch\\simple-java-http-server\\WebRoot");
- } catch (WebRootNotFoundException e) {
- fail(e);
- }
- }
-
- @Test
- void constructorBadPath() {
- try {
- WebRootHandler webRootHandler = new WebRootHandler("E:\\Projects\\CoderFromScratch\\simple-java-http-server\\WebRoot2");
- fail();
- } catch (WebRootNotFoundException e) {
- }
- }
-
- @Test
- void constructorGoodPath2() {
- try {
- WebRootHandler webRootHandler = new WebRootHandler("WebRoot");
- } catch (WebRootNotFoundException e) {
- fail(e);
- }
- }
-
- @Test
- void constructorBadPath2() {
- try {
- WebRootHandler webRootHandler = new WebRootHandler("WebRoot2");
- fail();
- } catch (WebRootNotFoundException e) {
- }
- }
-
- @Test
- void checkIfEndsWithSlashMethodFalse() {
- try {
- boolean result = (Boolean) checkIfEndsWithSlashMethod.invoke(webRootHandler,"index.html");
- assertFalse(result);
- } catch (IllegalAccessException e) {
- fail(e);
- } catch (InvocationTargetException e) {
- fail(e);
- }
- }
-
- @Test
- void checkIfEndsWithSlashMethodFalse2() {
- try {
- boolean result = (Boolean) checkIfEndsWithSlashMethod.invoke(webRootHandler,"/index.html");
- assertFalse(result);
- } catch (IllegalAccessException e) {
- fail(e);
- } catch (InvocationTargetException e) {
- fail(e);
- }
- }
-
- @Test
- void checkIfEndsWithSlashMethodFalse3() {
- try {
- boolean result = (Boolean) checkIfEndsWithSlashMethod.invoke(webRootHandler,"/private/index.html");
- assertFalse(result);
- } catch (IllegalAccessException e) {
- fail(e);
- } catch (InvocationTargetException e) {
- fail(e);
- }
- }
-
- @Test
- void checkIfEndsWithSlashMethodTrue() {
- try {
- boolean result = (Boolean) checkIfEndsWithSlashMethod.invoke(webRootHandler,"/");
- assertTrue(result);
- } catch (IllegalAccessException e) {
- fail(e);
- } catch (InvocationTargetException e) {
- fail(e);
- }
- }
-
- @Test
- void checkIfEndsWithSlashMethodTrue2() {
- try {
- boolean result = (Boolean) checkIfEndsWithSlashMethod.invoke(webRootHandler,"/private/");
- assertTrue(result);
- } catch (IllegalAccessException e) {
- fail(e);
- } catch (InvocationTargetException e) {
- fail(e);
- }
- }
-
- @Test
- void testWebRootFilePathExists() {
- try {
- boolean result = (boolean) checkIfProvidedRelativePathExistsMethod.invoke(webRootHandler, "/index.html");
- assertTrue(result);
- } catch (IllegalAccessException e) {
- fail(e);
- } catch (InvocationTargetException e) {
- fail(e);
- }
- }
-
- @Test
- void testWebRootFilePathExistsGoodRelative() {
- try {
- boolean result = (boolean) checkIfProvidedRelativePathExistsMethod.invoke(webRootHandler, "/./././index.html");
- assertTrue(result);
- } catch (IllegalAccessException e) {
- fail(e);
- } catch (InvocationTargetException e) {
- fail(e);
- }
- }
-
- @Test
- void testWebRootFilePathExistsDoesNotExist() {
- try {
- boolean result = (boolean) checkIfProvidedRelativePathExistsMethod.invoke(webRootHandler, "/indexNotHere.html");
- assertFalse(result);
- } catch (IllegalAccessException e) {
- fail(e);
- } catch (InvocationTargetException e) {
- fail(e);
- }
- }
-
- @Test
- void testWebRootFilePathExistsInvalid() {
- try {
- boolean result = (boolean) checkIfProvidedRelativePathExistsMethod.invoke(webRootHandler, "/../LICENSE");
- assertFalse(result);
- } catch (IllegalAccessException e) {
- fail(e);
- } catch (InvocationTargetException e) {
- fail(e);
- }
- }
-
- @Test
- void testGetFileMimeTypeText() {
- try {
- String mimeType = webRootHandler.getFileMimeType("/");
- assertEquals("text/html", mimeType);
- } catch (FileNotFoundException e) {
- fail(e);
- }
- }
-
- @Test
- void testGetFileMimeTypePng() {
- try {
- String mimeType = webRootHandler.getFileMimeType("/logo.png");
- assertEquals("image/png", mimeType);
- } catch (FileNotFoundException e) {
- fail(e);
- }
- }
-
- @Test
- void testGetFileMimeTypeDefault() {
- try {
- String mimeType = webRootHandler.getFileMimeType("/favicon.ico");
- assertEquals("application/octet-stream", mimeType);
- } catch (FileNotFoundException e) {
- fail(e);
- }
- }
-
- @Test
- void testGetFileByteArrayData() {
- try {
- assertTrue(webRootHandler.getFileByteArrayData("/").length > 0);
- } catch (FileNotFoundException e) {
- fail(e);
- } catch (ReadFileException e) {
- fail(e);
- }
- }
-
- @Test
- void testGetFileByteArrayDataFileNotThere() {
- try {
- webRootHandler.getFileByteArrayData("/test.html");
- fail();
- } catch (FileNotFoundException e) {
- // pass
- } catch (ReadFileException e) {
- fail(e);
- }
- }
-}