diff --git a/pom.xml b/pom.xml
index 12d48c2..6394361 100644
--- a/pom.xml
+++ b/pom.xml
@@ -60,8 +60,8 @@
2.3.2
true
- 1.6
- 1.6
+ 1.7
+ 1.7
false
true
true
diff --git a/src/main/java/net/gescobar/httpserver/HttpConnection.java b/src/main/java/net/gescobar/httpserver/HttpConnection.java
index 0b2aaa5..47f1196 100644
--- a/src/main/java/net/gescobar/httpserver/HttpConnection.java
+++ b/src/main/java/net/gescobar/httpserver/HttpConnection.java
@@ -6,8 +6,6 @@
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.Socket;
-import java.util.HashMap;
-import java.util.Map;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -20,17 +18,17 @@
*/
public class HttpConnection implements Runnable {
- private Logger log = LoggerFactory.getLogger(HttpConnection.class);
+ private final Logger log = LoggerFactory.getLogger(HttpConnection.class);
/**
* The socket with the underlying connection.
*/
- private Socket socket;
+ private final Socket socket;
/**
* The implementation that will handle requests.
*/
- private Handler handler;
+ private final Handler handler;
/**
* Constructor.
@@ -48,18 +46,16 @@ public void run() {
log.trace("handling HTTP request ... ");
- try {
-
- InputStream is = socket.getInputStream();
- BufferedReader reader = new BufferedReader( new InputStreamReader(is) );
-
+ try (InputStream is = socket.getInputStream();
+ BufferedReader reader = new BufferedReader( new InputStreamReader(is) );
+ OutputStream os = socket.getOutputStream();) {
+
// build the request and response object
RequestImpl request = new RequestImpl(reader);
ResponseImpl response = new ResponseImpl();
handler.handle(request, response);
- OutputStream os = socket.getOutputStream();
os.write(response.toString().getBytes());
os.flush();
os.close();
@@ -72,179 +68,4 @@ public void run() {
}
- /**
- * This is an internal implementation of the {@link Request} interface.
- *
- * @author German Escobar
- */
- private class RequestImpl implements Request {
-
- /**
- * The Host header.
- */
- private String host;
-
- /**
- * The HTTP method
- */
- private String method;
-
- /**
- * The request path
- */
- private String path;
-
- /**
- * The request headers
- */
- private Map headers;
-
- /**
- * Constructor.
- *
- * @param reader from which we are reading the headers.
- *
- * @throws IOException if an I/O error occurs in the underlying connection.
- */
- public RequestImpl(BufferedReader reader) throws IOException {
-
- String request = reader.readLine();
-
- // get the method and the path
- method = request.split(" ")[0];
- path = request.split(" ")[1];
-
- // get the headers
- headers = retrieveHeaders(reader);
-
- }
-
- /**
- * Helper method. Retrieves the headers of the request.
- *
- * @param reader the reader from which we are retrieving the request information.
- *
- * @return a Map object with the headers of the request.
- * @throws IOException if an I/O error occurs in the underlying communication.
- */
- private Map retrieveHeaders(BufferedReader reader) throws IOException {
-
- Map headers = new HashMap();
-
- // iterate through the headers
- String headerLine = reader.readLine();
- while( !headerLine.equals("") ) {
-
- // headers come in the form "name: value"
- String name = headerLine.split(":")[0].trim();
- String value = headerLine.split(":")[1].trim();
-
- // add to the headers only if there is no corresponding field (e.g. "Host" header is mapped to the
- // *host* field of the request)
- if ( !isKnownHeader(name, value) ) {
- headers.put(name, value);
- }
-
- // read next line
- headerLine = reader.readLine();
- }
-
- return headers;
-
- }
-
- /**
- * Checks if it is a known header and sets the corresponding field.
- *
- * @param name the name of the header to check.
- * @param value the value of the header to check.
- *
- * @return true if it is a known header, false otherwise
- */
- private boolean isKnownHeader(String name, String value) {
-
- boolean ret = false;
-
- if (name.equalsIgnoreCase("host")) {
- host = value;
- return true;
- }
-
- return ret;
-
- }
-
- @Override
- public String getMethod() {
- return method;
- }
-
- @Override
- public String getPath() {
- return path;
- }
-
- @Override
- public String getHost() {
- return host;
- }
-
- @Override
- public Map getHeaders() {
- return headers;
- }
-
- @Override
- public String getHeader(String name) {
- return headers.get(name);
- }
-
- }
-
- /**
- * This is a private implementation of the {@link Response interface}
- *
- * @author German Escobar
- */
- private class ResponseImpl implements Response {
-
- private HttpStatus status = HttpStatus.OK;
-
- private String contentType;
-
- @Override
- public Response status(HttpStatus status) {
- this.status = status;
-
- return this;
- }
-
- @Override
- public Response ok() {
- return status(HttpStatus.OK);
- }
-
- @Override
- public Response notFound() {
- return status(HttpStatus.NOT_FOUND);
- }
-
- @Override
- public Response contentType(String contentType) {
- this.contentType = contentType;
-
- return this;
- }
-
- public String toString() {
- String ret = "HTTP/1.1 " + status.getCode() + " " + status.getReason() + "\r\n";
-
- if (contentType != null) {
- ret += "Content-Type: " + contentType + "\r\n";
- }
-
- return ret + "\r\n";
- }
-
- }
}
diff --git a/src/main/java/net/gescobar/httpserver/HttpServer.java b/src/main/java/net/gescobar/httpserver/HttpServer.java
index f353bed..60e8580 100644
--- a/src/main/java/net/gescobar/httpserver/HttpServer.java
+++ b/src/main/java/net/gescobar/httpserver/HttpServer.java
@@ -33,7 +33,7 @@
*/
public class HttpServer {
- private Logger log = LoggerFactory.getLogger(HttpServer.class);
+ private final Logger log = LoggerFactory.getLogger(HttpServer.class);
/**
* The default port to use unless other is specified.
@@ -68,7 +68,7 @@ public class HttpServer {
/**
* Tells if the server is running or not.
*/
- private boolean running;
+ private volatile boolean running;
/**
* Constructor. Initializes the server with the default port and {@link Handler} implementation.
diff --git a/src/main/java/net/gescobar/httpserver/RequestImpl.java b/src/main/java/net/gescobar/httpserver/RequestImpl.java
new file mode 100644
index 0000000..bfb9c25
--- /dev/null
+++ b/src/main/java/net/gescobar/httpserver/RequestImpl.java
@@ -0,0 +1,136 @@
+package net.gescobar.httpserver;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Map;
+
+
+/**
+ * This is an internal implementation of the {@link Request} interface.
+ *
+ * @author German Escobar
+ */
+class RequestImpl implements Request {
+
+ /**
+ * The Host header.
+ */
+ private String host;
+
+ /**
+ * The HTTP method
+ */
+ private final String method;
+
+ /**
+ * The request path
+ */
+ private final String path;
+
+ /**
+ * The request headers
+ */
+ private final Map headers;
+
+ /**
+ * Constructor.
+ *
+ * @param reader from which we are reading the headers.
+ *
+ * @throws IOException if an I/O error occurs in the underlying connection.
+ */
+ public RequestImpl(BufferedReader reader) throws IOException {
+
+ String request = reader.readLine();
+
+ // get the method and the path
+ method = request.split(" ")[0];
+ path = request.split(" ")[1];
+
+ // get the headers
+ headers = retrieveHeaders(reader);
+
+ }
+
+ /**
+ * Helper method. Retrieves the headers of the request.
+ *
+ * @param reader the reader from which we are retrieving the request information.
+ *
+ * @return a Map object with the headers of the request.
+ * @throws IOException if an I/O error occurs in the underlying communication.
+ */
+ private Map retrieveHeaders(BufferedReader reader) throws IOException {
+
+ Map headers = new HashMap();
+
+ // iterate through the headers
+ String headerLine = reader.readLine();
+ while( !headerLine.equals("") ) {
+
+ // headers come in the form "name: value"
+ String name = headerLine.split(":")[0].trim();
+ String value = headerLine.split(":")[1].trim();
+
+ // add to the headers only if there is no corresponding field (e.g. "Host" header is mapped to the
+ // *host* field of the request)
+ if ( !isKnownHeader(name, value) ) {
+ headers.put(name, value);
+ }
+
+ // read next line
+ headerLine = reader.readLine();
+ }
+
+ return headers;
+
+ }
+
+ /**
+ * Checks if it is a known header and sets the corresponding field.
+ *
+ * @param name the name of the header to check.
+ * @param value the value of the header to check.
+ *
+ * @return true if it is a known header, false otherwise
+ */
+ private boolean isKnownHeader(String name, String value) {
+
+ boolean ret = false;
+
+ if (name.equalsIgnoreCase("host")) {
+ host = value;
+ return true;
+ }
+
+ return ret;
+
+ }
+
+ @Override
+ public String getMethod() {
+ return method;
+ }
+
+ @Override
+ public String getPath() {
+ return path;
+ }
+
+ @Override
+ public String getHost() {
+ return host;
+ }
+
+ @Override
+ public Map getHeaders() {
+ return headers;
+ }
+
+ @Override
+ public String getHeader(String name) {
+ return headers.get(name);
+ }
+
+}
\ No newline at end of file
diff --git a/src/main/java/net/gescobar/httpserver/Response.java b/src/main/java/net/gescobar/httpserver/Response.java
index f6a2aaf..d3b36d3 100644
--- a/src/main/java/net/gescobar/httpserver/Response.java
+++ b/src/main/java/net/gescobar/httpserver/Response.java
@@ -28,9 +28,9 @@ public enum HttpStatus {
OVERLOADED(502, "Overloaded"),
GATEWAY_TIMEOUT(503, "Gateway Timeout");
- private int code;
+ private final int code;
- private String reason;
+ private final String reason;
private HttpStatus(int code, String reason) {
this.code = code;
diff --git a/src/main/java/net/gescobar/httpserver/ResponseImpl.java b/src/main/java/net/gescobar/httpserver/ResponseImpl.java
new file mode 100644
index 0000000..fffc6cd
--- /dev/null
+++ b/src/main/java/net/gescobar/httpserver/ResponseImpl.java
@@ -0,0 +1,50 @@
+
+package net.gescobar.httpserver;
+
+/**
+ * This is a private implementation of the {@link Response interface}
+ *
+ * @author German Escobar
+ */
+class ResponseImpl implements Response {
+
+ private Response.HttpStatus status = Response.HttpStatus.OK;
+
+ private String contentType;
+
+ @Override
+ public Response status(Response.HttpStatus status) {
+ this.status = status;
+
+ return this;
+ }
+
+ @Override
+ public Response ok() {
+ return status(Response.HttpStatus.OK);
+ }
+
+ @Override
+ public Response notFound() {
+ return status(Response.HttpStatus.NOT_FOUND);
+ }
+
+ @Override
+ public Response contentType(String contentType) {
+ this.contentType = contentType;
+
+ return this;
+ }
+
+ @Override
+ public String toString() {
+ String ret = "HTTP/1.1 " + status.getCode() + " " + status.getReason() + "\r\n";
+
+ if (contentType != null) {
+ ret += "Content-Type: " + contentType + "\r\n";
+ }
+
+ return ret + "\r\n";
+ }
+
+}
diff --git a/src/test/java/net/gescobar/httpserver/HttpServerTest.java b/src/test/java/net/gescobar/httpserver/HttpServerTest.java
index 79141a6..6363450 100644
--- a/src/test/java/net/gescobar/httpserver/HttpServerTest.java
+++ b/src/test/java/net/gescobar/httpserver/HttpServerTest.java
@@ -123,26 +123,4 @@ public void doHandle(Request request, Response response) {
}
-
- private class TestHandler implements Handler {
-
- private Request request;
-
- @Override
- public final void handle(Request request, Response response) {
- this.request = request;
-
- doHandle(request, response);
- }
-
- public void doHandle(Request request, Response response) {
-
- }
-
- public Request getRequest() {
- return request;
- }
-
- }
-
}
diff --git a/src/test/java/net/gescobar/httpserver/TestHandler.java b/src/test/java/net/gescobar/httpserver/TestHandler.java
new file mode 100644
index 0000000..23f1a22
--- /dev/null
+++ b/src/test/java/net/gescobar/httpserver/TestHandler.java
@@ -0,0 +1,23 @@
+
+package net.gescobar.httpserver;
+
+class TestHandler implements Handler {
+
+ private Request request;
+
+ @Override
+ public final void handle(Request request, Response response) {
+ this.request = request;
+
+ doHandle(request, response);
+ }
+
+ public void doHandle(Request request, Response response) {
+
+ }
+
+ public Request getRequest() {
+ return request;
+ }
+
+}