diff --git a/src/main/java/org/dynmap/web/HttpErrorHandler.java b/src/main/java/org/dynmap/web/HttpErrorHandler.java deleted file mode 100644 index 189ee78f..00000000 --- a/src/main/java/org/dynmap/web/HttpErrorHandler.java +++ /dev/null @@ -1,24 +0,0 @@ -package org.dynmap.web; - -import java.io.IOException; - -public class HttpErrorHandler { - public static void handle(HttpResponse response, int statusCode, String statusMessage) throws IOException { - response.statusCode = statusCode; - response.statusMessage = statusMessage; - response.fields.put("Content-Length", "0"); - response.getBody(); - } - - public static void handleForbidden(HttpResponse response) throws IOException { - handle(response, 403, "Forbidden"); - } - - public static void handleNotFound(HttpResponse response) throws IOException { - handle(response, 404, "Not found"); - } - - public static void handleMethodNotAllowed(HttpResponse response) throws IOException { - handle(response, 405, "Method not allowed"); - } -} diff --git a/src/main/java/org/dynmap/web/HttpField.java b/src/main/java/org/dynmap/web/HttpField.java index 06535189..8a1a5f2e 100644 --- a/src/main/java/org/dynmap/web/HttpField.java +++ b/src/main/java/org/dynmap/web/HttpField.java @@ -1,6 +1,52 @@ package org.dynmap.web; public class HttpField { - public static final String contentLength = "Content-Length"; - public static final String contentType = "Content-Type"; + // Reference: http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html + public static final String Accept = "Accept"; + public static final String AcceptCharset = "Accept-Charset"; + public static final String AcceptEncoding = "Accept-Encoding"; + public static final String AcceptLanguage = "Accept-Language"; + public static final String AcceptRanges = "Accept-Ranges"; + public static final String Age = "Age"; + public static final String Allow = "Allow"; + public static final String Authorization = "Authorization"; + public static final String CacheControl = "Cache-Control"; + public static final String Connection = "Connection"; + public static final String ContentEncoding = "Content-Encoding"; + public static final String ContentLanguage = "Content-Language"; + public static final String ContentLength = "Content-Length"; + public static final String ContentLocation = "Content-Location"; + public static final String ContentRange = "Content-Range"; + public static final String ContentType = "Content-Type"; + public static final String Date = "Date"; + public static final String ETag = "ETag"; + public static final String Expect = "Expect"; + public static final String Expires = "Expires"; + public static final String From = "From"; + public static final String Host = "Host"; + public static final String IfMatch = "If-Match"; + public static final String IfModifiedSince = "If-Modified-Since"; + public static final String IfNoneMatch = "If-None-Match"; + public static final String IfRange = "If-Range"; + public static final String IfUnmodifiedSince = "If-Unmodified-Since"; + public static final String LastModified = "Last-Modified"; + public static final String Location = "Location"; + public static final String MaxForwards = "Max-Forwards"; + public static final String Pragma = "Pragma"; + public static final String ProxyAuthenticate = "Proxy-Authenticate"; + public static final String ProxyAuthorization = "Proxy-Authorization"; + public static final String Range = "Range"; + public static final String Referer = "Referer"; + public static final String RetryAfter = "Retry-After"; + public static final String Server = "Server"; + public static final String TE = "TE"; + public static final String Trailer = "Trailer"; + public static final String TransferEncoding = "Transfer-Encoding"; + public static final String Upgrade = "Upgrade"; + public static final String UserAgent = "User-Agent"; + public static final String Vary = "Vary"; + public static final String Via = "Via"; + public static final String Warning = "Warning"; + public static final String WwwAuthenticate = "WWW-Authenticate"; + } diff --git a/src/main/java/org/dynmap/web/HttpMethods.java b/src/main/java/org/dynmap/web/HttpMethod.java similarity index 86% rename from src/main/java/org/dynmap/web/HttpMethods.java rename to src/main/java/org/dynmap/web/HttpMethod.java index 8c116519..bb6d28b7 100644 --- a/src/main/java/org/dynmap/web/HttpMethods.java +++ b/src/main/java/org/dynmap/web/HttpMethod.java @@ -1,6 +1,6 @@ package org.dynmap.web; -public class HttpMethods { +public final class HttpMethod { public static final String Get = "GET"; public static final String Post = "POST"; public static final String Put = "PUT"; diff --git a/src/main/java/org/dynmap/web/HttpResponse.java b/src/main/java/org/dynmap/web/HttpResponse.java index 0a6813b5..102f249e 100644 --- a/src/main/java/org/dynmap/web/HttpResponse.java +++ b/src/main/java/org/dynmap/web/HttpResponse.java @@ -8,8 +8,7 @@ import java.util.Map; public class HttpResponse { private HttpServerConnection connection; public String version = "1.1"; - public int statusCode = 200; - public String statusMessage = "OK"; + public HttpStatus status = null; public Map fields = new HashMap(); private OutputStream body; diff --git a/src/main/java/org/dynmap/web/HttpServerConnection.java b/src/main/java/org/dynmap/web/HttpServerConnection.java index 830ed5ae..4cc630f3 100644 --- a/src/main/java/org/dynmap/web/HttpServerConnection.java +++ b/src/main/java/org/dynmap/web/HttpServerConnection.java @@ -95,9 +95,9 @@ public class HttpServerConnection extends Thread { out.append("HTTP/"); out.append(response.version); out.append(" "); - out.append(String.valueOf(response.statusCode)); + out.append(String.valueOf(response.status.getCode())); out.append(" "); - out.append(response.statusMessage); + out.append(response.status.getText()); out.append("\r\n"); for (Entry field : response.fields.entrySet()) { out.append(field.getKey()); @@ -131,7 +131,7 @@ public class HttpServerConnection extends Thread { long bound = -1; BoundInputStream boundBody = null; { - String contentLengthStr = request.fields.get(HttpField.contentLength); + String contentLengthStr = request.fields.get(HttpField.ContentLength); if (contentLengthStr != null) { try { bound = Long.parseLong(contentLengthStr); diff --git a/src/main/java/org/dynmap/web/HttpStatus.java b/src/main/java/org/dynmap/web/HttpStatus.java new file mode 100644 index 00000000..e4aaa3d6 --- /dev/null +++ b/src/main/java/org/dynmap/web/HttpStatus.java @@ -0,0 +1,61 @@ +package org.dynmap.web; + +public final class HttpStatus { + private int code; + private String text; + + public int getCode() { + return code; + } + + public String getText() { + return text; + } + + public HttpStatus(int code, String text) { + this.code = code; + this.text = text; + } + + // Reference: http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html + public static final HttpStatus Continue = new HttpStatus(100, "Continue"); + public static final HttpStatus SwitchingProtocols = new HttpStatus(101, "Switching Protocols"); + public static final HttpStatus OK = new HttpStatus(200, "OK"); + public static final HttpStatus Created = new HttpStatus(201, "Created"); + public static final HttpStatus Accepted = new HttpStatus(202, "Accepted"); + public static final HttpStatus NonAuthoritativeInformation = new HttpStatus(203, "Non-Authoritative Information"); + public static final HttpStatus NoContent = new HttpStatus(204, "No Content"); + public static final HttpStatus ResetContent = new HttpStatus(205, "Reset Content"); + public static final HttpStatus PartialContent = new HttpStatus(206, "Partial Content"); + public static final HttpStatus MultipleChoices = new HttpStatus(300, "Multiple Choices"); + public static final HttpStatus MovedPermanently = new HttpStatus(301, "Moved Permanently"); + public static final HttpStatus Found = new HttpStatus(302, "Found"); + public static final HttpStatus SeeOther = new HttpStatus(303, "See Other"); + public static final HttpStatus NotModified = new HttpStatus(304, "Not Modified"); + public static final HttpStatus UseProxy = new HttpStatus(305, "Use Proxy"); + public static final HttpStatus TemporaryRedirect = new HttpStatus(307, "Temporary Redirect"); + public static final HttpStatus BadRequest = new HttpStatus(400, "Bad Request"); + public static final HttpStatus Unauthorized = new HttpStatus(401, "Unauthorized"); + public static final HttpStatus PaymentRequired = new HttpStatus(402, "Payment Required"); + public static final HttpStatus Forbidden = new HttpStatus(403, "Forbidden"); + public static final HttpStatus NotFound = new HttpStatus(404, "Not Found"); + public static final HttpStatus MethodNotAllowed = new HttpStatus(405, "Method Not Allowed"); + public static final HttpStatus NotAcceptable = new HttpStatus(406, "Not Acceptable"); + public static final HttpStatus ProxyAuthenticationRequired = new HttpStatus(407, "Proxy Authentication Required"); + public static final HttpStatus RequestTimeout = new HttpStatus(408, "Request Timeout"); + public static final HttpStatus Conflict = new HttpStatus(409, "Conflict"); + public static final HttpStatus Gone = new HttpStatus(410, "Gone"); + public static final HttpStatus LengthRequired = new HttpStatus(411, "Length Required"); + public static final HttpStatus PreconditionFailed = new HttpStatus(412, "Precondition Failed"); + public static final HttpStatus RequestEntityTooLarge = new HttpStatus(413, "Request Entity Too Large"); + public static final HttpStatus RequestURITooLong = new HttpStatus(414, "Request-URI Too Long"); + public static final HttpStatus UnsupportedMediaType = new HttpStatus(415, "Unsupported Media Type"); + public static final HttpStatus RequestedRangeNotSatisfiable = new HttpStatus(416, "Requested Range Not Satisfiable"); + public static final HttpStatus ExpectationFailed = new HttpStatus(417, "Expectation Failed"); + public static final HttpStatus InternalServerError = new HttpStatus(500, "Internal Server Error"); + public static final HttpStatus NotImplemented = new HttpStatus(501, "Not Implemented"); + public static final HttpStatus BadGateway = new HttpStatus(502, "Bad Gateway"); + public static final HttpStatus ServiceUnavailable = new HttpStatus(503, "Service Unavailable"); + public static final HttpStatus GatewayTimeout = new HttpStatus(504, "Gateway Timeout"); + public static final HttpStatus HttpVersionNotSupported = new HttpStatus(505, "HTTP Version Not Supported"); +} diff --git a/src/main/java/org/dynmap/web/handlers/ClientConfigurationHandler.java b/src/main/java/org/dynmap/web/handlers/ClientConfigurationHandler.java index 70659d85..3117d0e2 100644 --- a/src/main/java/org/dynmap/web/handlers/ClientConfigurationHandler.java +++ b/src/main/java/org/dynmap/web/handlers/ClientConfigurationHandler.java @@ -7,6 +7,7 @@ import java.util.Map; import org.dynmap.web.HttpHandler; import org.dynmap.web.HttpRequest; import org.dynmap.web.HttpResponse; +import org.dynmap.web.HttpStatus; import org.dynmap.web.Json; public class ClientConfigurationHandler implements HttpHandler { @@ -29,6 +30,8 @@ public class ClientConfigurationHandler implements HttpHandler { response.fields.put("Expires", "Thu, 01 Dec 1994 16:00:00 GMT"); response.fields.put("Last-modified", dateStr); response.fields.put("Content-Length", Integer.toString(cachedConfiguration.length)); + response.status = HttpStatus.OK; + BufferedOutputStream out = new BufferedOutputStream(response.getBody()); out.write(cachedConfiguration); out.flush(); diff --git a/src/main/java/org/dynmap/web/handlers/ClientUpdateHandler.java b/src/main/java/org/dynmap/web/handlers/ClientUpdateHandler.java index 5954af02..8cacc932 100644 --- a/src/main/java/org/dynmap/web/handlers/ClientUpdateHandler.java +++ b/src/main/java/org/dynmap/web/handlers/ClientUpdateHandler.java @@ -12,10 +12,11 @@ import org.bukkit.entity.Player; import org.dynmap.Client; import org.dynmap.MapManager; import org.dynmap.PlayerList; -import org.dynmap.web.HttpErrorHandler; +import org.dynmap.web.HttpField; import org.dynmap.web.HttpHandler; import org.dynmap.web.HttpRequest; import org.dynmap.web.HttpResponse; +import org.dynmap.web.HttpStatus; import org.dynmap.web.Json; public class ClientUpdateHandler implements HttpHandler { @@ -30,13 +31,14 @@ public class ClientUpdateHandler implements HttpHandler { } Pattern updatePathPattern = Pattern.compile("world/([a-zA-Z0-9_-\\.]+)/([0-9]*)"); + private static final HttpStatus WorldNotFound = new HttpStatus(HttpStatus.NotFound.getCode(), "World Not Found"); @Override public void handle(String path, HttpRequest request, HttpResponse response) throws Exception { Matcher match = updatePathPattern.matcher(path); if (!match.matches()) { - HttpErrorHandler.handleForbidden(response); + response.status = HttpStatus.Forbidden; return; } @@ -45,7 +47,7 @@ public class ClientUpdateHandler implements HttpHandler { World world = server.getWorld(worldName); if (world == null) { - HttpErrorHandler.handleNotFound(response); + response.status = WorldNotFound; return; } @@ -78,11 +80,13 @@ public class ClientUpdateHandler implements HttpHandler { byte[] bytes = Json.stringifyJson(update).getBytes(); String dateStr = new Date().toString(); - response.fields.put("Date", dateStr); - response.fields.put("Content-Type", "text/plain"); - response.fields.put("Expires", "Thu, 01 Dec 1994 16:00:00 GMT"); - response.fields.put("Last-modified", dateStr); - response.fields.put("Content-Length", Integer.toString(bytes.length)); + response.fields.put(HttpField.Date, dateStr); + response.fields.put(HttpField.ContentType, "text/plain"); + response.fields.put(HttpField.Expires, "Thu, 01 Dec 1994 16:00:00 GMT"); + response.fields.put(HttpField.LastModified, dateStr); + response.fields.put(HttpField.ContentLength, Integer.toString(bytes.length)); + response.status = HttpStatus.OK; + BufferedOutputStream out = new BufferedOutputStream(response.getBody()); out.write(bytes); out.flush(); diff --git a/src/main/java/org/dynmap/web/handlers/FileHandler.java b/src/main/java/org/dynmap/web/handlers/FileHandler.java index 89c2dc9c..240c9979 100644 --- a/src/main/java/org/dynmap/web/handlers/FileHandler.java +++ b/src/main/java/org/dynmap/web/handlers/FileHandler.java @@ -7,9 +7,11 @@ import java.util.HashMap; import java.util.Map; import java.util.logging.Logger; +import org.dynmap.web.HttpField; import org.dynmap.web.HttpHandler; import org.dynmap.web.HttpRequest; import org.dynmap.web.HttpResponse; +import org.dynmap.web.HttpStatus; public abstract class FileHandler implements HttpHandler { protected static final Logger log = Logger.getLogger("Minecraft"); @@ -64,17 +66,15 @@ public abstract class FileHandler implements HttpHandler { path = formatPath(path); fileInput = getFileInput(path, request, response); if (fileInput == null) { - response.statusCode = 404; - response.statusMessage = "Not found"; - response.fields.put("Content-Length", "0"); - response.getBody(); + response.status = HttpStatus.NotFound; return; } String extension = getExtension(path); String mimeType = getMimeTypeFromExtension(extension); - response.fields.put("Content-Type", mimeType); + response.fields.put(HttpField.ContentType, mimeType); + response.status = HttpStatus.OK; OutputStream out = response.getBody(); try { int readBytes; diff --git a/src/main/java/org/dynmap/web/handlers/FilesystemHandler.java b/src/main/java/org/dynmap/web/handlers/FilesystemHandler.java index 96d8858b..9ad5a3dc 100644 --- a/src/main/java/org/dynmap/web/handlers/FilesystemHandler.java +++ b/src/main/java/org/dynmap/web/handlers/FilesystemHandler.java @@ -5,6 +5,7 @@ import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.InputStream; +import org.dynmap.web.HttpField; import org.dynmap.web.HttpRequest; import org.dynmap.web.HttpResponse; @@ -26,7 +27,7 @@ public class FilesystemHandler extends FileHandler { } catch (FileNotFoundException e) { return null; } - response.fields.put("Content-Length", Long.toString(file.length())); + response.fields.put(HttpField.ContentLength, Long.toString(file.length())); return result; } return null; diff --git a/src/main/java/org/dynmap/web/handlers/SendMessageHandler.java b/src/main/java/org/dynmap/web/handlers/SendMessageHandler.java index e410b7da..d33cd20f 100644 --- a/src/main/java/org/dynmap/web/handlers/SendMessageHandler.java +++ b/src/main/java/org/dynmap/web/handlers/SendMessageHandler.java @@ -4,12 +4,12 @@ import java.io.InputStreamReader; import java.util.logging.Logger; import org.dynmap.Event; -import org.dynmap.web.HttpErrorHandler; import org.dynmap.web.HttpField; import org.dynmap.web.HttpHandler; -import org.dynmap.web.HttpMethods; +import org.dynmap.web.HttpMethod; import org.dynmap.web.HttpRequest; import org.dynmap.web.HttpResponse; +import org.dynmap.web.HttpStatus; import org.json.simple.JSONObject; import org.json.simple.parser.JSONParser; @@ -20,8 +20,9 @@ public class SendMessageHandler implements HttpHandler { public Event onMessageReceived = new Event(); @Override public void handle(String path, HttpRequest request, HttpResponse response) throws Exception { - if (!request.method.equals(HttpMethods.Post)) { - HttpErrorHandler.handleMethodNotAllowed(response); + if (!request.method.equals(HttpMethod.Post)) { + response.status = HttpStatus.MethodNotAllowed; + response.fields.put(HttpField.Accept, HttpMethod.Post); return; } @@ -34,7 +35,8 @@ public class SendMessageHandler implements HttpHandler { onMessageReceived.trigger(message); - response.fields.put(HttpField.contentLength, "0"); + response.fields.put(HttpField.ContentLength, "0"); + response.status = HttpStatus.OK; response.getBody(); } public class Message {