Cleaned Http handling a bit.

This commit is contained in:
FrozenCow 2011-03-04 21:31:16 +01:00
parent 9ce160f1b9
commit d1f280eb0f
11 changed files with 143 additions and 51 deletions

View File

@ -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");
}
}

View File

@ -1,6 +1,52 @@
package org.dynmap.web; package org.dynmap.web;
public class HttpField { public class HttpField {
public static final String contentLength = "Content-Length"; // Reference: http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html
public static final String contentType = "Content-Type"; 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";
} }

View File

@ -1,6 +1,6 @@
package org.dynmap.web; package org.dynmap.web;
public class HttpMethods { public final class HttpMethod {
public static final String Get = "GET"; public static final String Get = "GET";
public static final String Post = "POST"; public static final String Post = "POST";
public static final String Put = "PUT"; public static final String Put = "PUT";

View File

@ -8,8 +8,7 @@ import java.util.Map;
public class HttpResponse { public class HttpResponse {
private HttpServerConnection connection; private HttpServerConnection connection;
public String version = "1.1"; public String version = "1.1";
public int statusCode = 200; public HttpStatus status = null;
public String statusMessage = "OK";
public Map<String, String> fields = new HashMap<String, String>(); public Map<String, String> fields = new HashMap<String, String>();
private OutputStream body; private OutputStream body;

View File

@ -95,9 +95,9 @@ public class HttpServerConnection extends Thread {
out.append("HTTP/"); out.append("HTTP/");
out.append(response.version); out.append(response.version);
out.append(" "); out.append(" ");
out.append(String.valueOf(response.statusCode)); out.append(String.valueOf(response.status.getCode()));
out.append(" "); out.append(" ");
out.append(response.statusMessage); out.append(response.status.getText());
out.append("\r\n"); out.append("\r\n");
for (Entry<String, String> field : response.fields.entrySet()) { for (Entry<String, String> field : response.fields.entrySet()) {
out.append(field.getKey()); out.append(field.getKey());
@ -131,7 +131,7 @@ public class HttpServerConnection extends Thread {
long bound = -1; long bound = -1;
BoundInputStream boundBody = null; BoundInputStream boundBody = null;
{ {
String contentLengthStr = request.fields.get(HttpField.contentLength); String contentLengthStr = request.fields.get(HttpField.ContentLength);
if (contentLengthStr != null) { if (contentLengthStr != null) {
try { try {
bound = Long.parseLong(contentLengthStr); bound = Long.parseLong(contentLengthStr);

View File

@ -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");
}

View File

@ -7,6 +7,7 @@ import java.util.Map;
import org.dynmap.web.HttpHandler; import org.dynmap.web.HttpHandler;
import org.dynmap.web.HttpRequest; import org.dynmap.web.HttpRequest;
import org.dynmap.web.HttpResponse; import org.dynmap.web.HttpResponse;
import org.dynmap.web.HttpStatus;
import org.dynmap.web.Json; import org.dynmap.web.Json;
public class ClientConfigurationHandler implements HttpHandler { 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("Expires", "Thu, 01 Dec 1994 16:00:00 GMT");
response.fields.put("Last-modified", dateStr); response.fields.put("Last-modified", dateStr);
response.fields.put("Content-Length", Integer.toString(cachedConfiguration.length)); response.fields.put("Content-Length", Integer.toString(cachedConfiguration.length));
response.status = HttpStatus.OK;
BufferedOutputStream out = new BufferedOutputStream(response.getBody()); BufferedOutputStream out = new BufferedOutputStream(response.getBody());
out.write(cachedConfiguration); out.write(cachedConfiguration);
out.flush(); out.flush();

View File

@ -12,10 +12,11 @@ import org.bukkit.entity.Player;
import org.dynmap.Client; import org.dynmap.Client;
import org.dynmap.MapManager; import org.dynmap.MapManager;
import org.dynmap.PlayerList; import org.dynmap.PlayerList;
import org.dynmap.web.HttpErrorHandler; import org.dynmap.web.HttpField;
import org.dynmap.web.HttpHandler; import org.dynmap.web.HttpHandler;
import org.dynmap.web.HttpRequest; import org.dynmap.web.HttpRequest;
import org.dynmap.web.HttpResponse; import org.dynmap.web.HttpResponse;
import org.dynmap.web.HttpStatus;
import org.dynmap.web.Json; import org.dynmap.web.Json;
public class ClientUpdateHandler implements HttpHandler { 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]*)"); 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 @Override
public void handle(String path, HttpRequest request, HttpResponse response) throws Exception { public void handle(String path, HttpRequest request, HttpResponse response) throws Exception {
Matcher match = updatePathPattern.matcher(path); Matcher match = updatePathPattern.matcher(path);
if (!match.matches()) { if (!match.matches()) {
HttpErrorHandler.handleForbidden(response); response.status = HttpStatus.Forbidden;
return; return;
} }
@ -45,7 +47,7 @@ public class ClientUpdateHandler implements HttpHandler {
World world = server.getWorld(worldName); World world = server.getWorld(worldName);
if (world == null) { if (world == null) {
HttpErrorHandler.handleNotFound(response); response.status = WorldNotFound;
return; return;
} }
@ -78,11 +80,13 @@ public class ClientUpdateHandler implements HttpHandler {
byte[] bytes = Json.stringifyJson(update).getBytes(); byte[] bytes = Json.stringifyJson(update).getBytes();
String dateStr = new Date().toString(); String dateStr = new Date().toString();
response.fields.put("Date", dateStr); response.fields.put(HttpField.Date, dateStr);
response.fields.put("Content-Type", "text/plain"); response.fields.put(HttpField.ContentType, "text/plain");
response.fields.put("Expires", "Thu, 01 Dec 1994 16:00:00 GMT"); response.fields.put(HttpField.Expires, "Thu, 01 Dec 1994 16:00:00 GMT");
response.fields.put("Last-modified", dateStr); response.fields.put(HttpField.LastModified, dateStr);
response.fields.put("Content-Length", Integer.toString(bytes.length)); response.fields.put(HttpField.ContentLength, Integer.toString(bytes.length));
response.status = HttpStatus.OK;
BufferedOutputStream out = new BufferedOutputStream(response.getBody()); BufferedOutputStream out = new BufferedOutputStream(response.getBody());
out.write(bytes); out.write(bytes);
out.flush(); out.flush();

View File

@ -7,9 +7,11 @@ import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.logging.Logger; import java.util.logging.Logger;
import org.dynmap.web.HttpField;
import org.dynmap.web.HttpHandler; import org.dynmap.web.HttpHandler;
import org.dynmap.web.HttpRequest; import org.dynmap.web.HttpRequest;
import org.dynmap.web.HttpResponse; import org.dynmap.web.HttpResponse;
import org.dynmap.web.HttpStatus;
public abstract class FileHandler implements HttpHandler { public abstract class FileHandler implements HttpHandler {
protected static final Logger log = Logger.getLogger("Minecraft"); protected static final Logger log = Logger.getLogger("Minecraft");
@ -64,17 +66,15 @@ public abstract class FileHandler implements HttpHandler {
path = formatPath(path); path = formatPath(path);
fileInput = getFileInput(path, request, response); fileInput = getFileInput(path, request, response);
if (fileInput == null) { if (fileInput == null) {
response.statusCode = 404; response.status = HttpStatus.NotFound;
response.statusMessage = "Not found";
response.fields.put("Content-Length", "0");
response.getBody();
return; return;
} }
String extension = getExtension(path); String extension = getExtension(path);
String mimeType = getMimeTypeFromExtension(extension); String mimeType = getMimeTypeFromExtension(extension);
response.fields.put("Content-Type", mimeType); response.fields.put(HttpField.ContentType, mimeType);
response.status = HttpStatus.OK;
OutputStream out = response.getBody(); OutputStream out = response.getBody();
try { try {
int readBytes; int readBytes;

View File

@ -5,6 +5,7 @@ import java.io.FileInputStream;
import java.io.FileNotFoundException; import java.io.FileNotFoundException;
import java.io.InputStream; import java.io.InputStream;
import org.dynmap.web.HttpField;
import org.dynmap.web.HttpRequest; import org.dynmap.web.HttpRequest;
import org.dynmap.web.HttpResponse; import org.dynmap.web.HttpResponse;
@ -26,7 +27,7 @@ public class FilesystemHandler extends FileHandler {
} catch (FileNotFoundException e) { } catch (FileNotFoundException e) {
return null; return null;
} }
response.fields.put("Content-Length", Long.toString(file.length())); response.fields.put(HttpField.ContentLength, Long.toString(file.length()));
return result; return result;
} }
return null; return null;

View File

@ -4,12 +4,12 @@ import java.io.InputStreamReader;
import java.util.logging.Logger; import java.util.logging.Logger;
import org.dynmap.Event; import org.dynmap.Event;
import org.dynmap.web.HttpErrorHandler;
import org.dynmap.web.HttpField; import org.dynmap.web.HttpField;
import org.dynmap.web.HttpHandler; import org.dynmap.web.HttpHandler;
import org.dynmap.web.HttpMethods; import org.dynmap.web.HttpMethod;
import org.dynmap.web.HttpRequest; import org.dynmap.web.HttpRequest;
import org.dynmap.web.HttpResponse; import org.dynmap.web.HttpResponse;
import org.dynmap.web.HttpStatus;
import org.json.simple.JSONObject; import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser; import org.json.simple.parser.JSONParser;
@ -20,8 +20,9 @@ public class SendMessageHandler implements HttpHandler {
public Event<Message> onMessageReceived = new Event<SendMessageHandler.Message>(); public Event<Message> onMessageReceived = new Event<SendMessageHandler.Message>();
@Override @Override
public void handle(String path, HttpRequest request, HttpResponse response) throws Exception { public void handle(String path, HttpRequest request, HttpResponse response) throws Exception {
if (!request.method.equals(HttpMethods.Post)) { if (!request.method.equals(HttpMethod.Post)) {
HttpErrorHandler.handleMethodNotAllowed(response); response.status = HttpStatus.MethodNotAllowed;
response.fields.put(HttpField.Accept, HttpMethod.Post);
return; return;
} }
@ -34,7 +35,8 @@ public class SendMessageHandler implements HttpHandler {
onMessageReceived.trigger(message); onMessageReceived.trigger(message);
response.fields.put(HttpField.contentLength, "0"); response.fields.put(HttpField.ContentLength, "0");
response.status = HttpStatus.OK;
response.getBody(); response.getBody();
} }
public class Message { public class Message {