You are viewing a plain text version of this content. The canonical link for it is here.
Posted to awf-commits@incubator.apache.org by jm...@apache.org on 2011/08/03 17:36:30 UTC
svn commit: r1153593 [1/3] - in /incubator/deft/sandbox/src:
main/java/org/deftserver/example/handler/
main/java/org/deftserver/example/keyvalue/ main/java/org/deftserver/util/
main/java/org/deftserver/web/ main/java/org/deftserver/web/handler/
main/ja...
Author: jmeehan
Date: Wed Aug 3 17:36:25 2011
New Revision: 1153593
URL: http://svn.apache.org/viewvc?rev=1153593&view=rev
Log:
DEFT-178: Extract HttpRequest and HttpResponse interfaces; sundry clean-up.
Added:
incubator/deft/sandbox/src/main/java/org/deftserver/web/http/HttpRequestImpl.java (with props)
incubator/deft/sandbox/src/main/java/org/deftserver/web/http/HttpResponseImpl.java (with props)
Modified:
incubator/deft/sandbox/src/main/java/org/deftserver/example/handler/BasicHandlerExample.java
incubator/deft/sandbox/src/main/java/org/deftserver/example/handler/CookieHandlerExample.java
incubator/deft/sandbox/src/main/java/org/deftserver/example/handler/PatternHandlerExample.java
incubator/deft/sandbox/src/main/java/org/deftserver/example/keyvalue/KeyValueStoreExample.java
incubator/deft/sandbox/src/main/java/org/deftserver/util/HttpUtil.java
incubator/deft/sandbox/src/main/java/org/deftserver/web/Application.java
incubator/deft/sandbox/src/main/java/org/deftserver/web/handler/BadRequestRequestHandler.java
incubator/deft/sandbox/src/main/java/org/deftserver/web/handler/ForbiddenRequestHandler.java
incubator/deft/sandbox/src/main/java/org/deftserver/web/handler/NotFoundRequestHandler.java
incubator/deft/sandbox/src/main/java/org/deftserver/web/handler/RequestHandler.java
incubator/deft/sandbox/src/main/java/org/deftserver/web/handler/StaticContentHandler.java
incubator/deft/sandbox/src/main/java/org/deftserver/web/http/HttpProtocol.java
incubator/deft/sandbox/src/main/java/org/deftserver/web/http/HttpRequest.java
incubator/deft/sandbox/src/main/java/org/deftserver/web/http/HttpRequestDispatcher.java
incubator/deft/sandbox/src/main/java/org/deftserver/web/http/HttpResponse.java
incubator/deft/sandbox/src/main/java/org/deftserver/web/http/MalFormedHttpRequest.java
incubator/deft/sandbox/src/main/java/org/deftserver/web/http/PartialHttpRequest.java
incubator/deft/sandbox/src/test/java/org/deftserver/web/ApplicationTest.java
incubator/deft/sandbox/src/test/java/org/deftserver/web/DeftSystemTest.java
incubator/deft/sandbox/src/test/java/org/deftserver/web/handler/RequestHandlerTest.java
incubator/deft/sandbox/src/test/java/org/deftserver/web/http/HttpRequestTest.java
Modified: incubator/deft/sandbox/src/main/java/org/deftserver/example/handler/BasicHandlerExample.java
URL: http://svn.apache.org/viewvc/incubator/deft/sandbox/src/main/java/org/deftserver/example/handler/BasicHandlerExample.java?rev=1153593&r1=1153592&r2=1153593&view=diff
==============================================================================
--- incubator/deft/sandbox/src/main/java/org/deftserver/example/handler/BasicHandlerExample.java (original)
+++ incubator/deft/sandbox/src/main/java/org/deftserver/example/handler/BasicHandlerExample.java Wed Aug 3 17:36:25 2011
@@ -26,10 +26,8 @@ import org.deftserver.web.http.HttpReque
import org.deftserver.web.http.HttpResponse;
/**
- * This is a basic handler, which does nothing more than write output and
- * associate itself with a path. The {@link Path} annotation below defines the
- * path on which this handler is invoked. When executed as part of the server
- * example:
+ * This is a basic handler, which does nothing more than write output and associate itself with a path. The {@link Path}
+ * annotation below defines the path on which this handler is invoked. When executed as part of the server example:
* <p>
* <code>http://localhost:8080/</code>
* </p>
Modified: incubator/deft/sandbox/src/main/java/org/deftserver/example/handler/CookieHandlerExample.java
URL: http://svn.apache.org/viewvc/incubator/deft/sandbox/src/main/java/org/deftserver/example/handler/CookieHandlerExample.java?rev=1153593&r1=1153592&r2=1153593&view=diff
==============================================================================
--- incubator/deft/sandbox/src/main/java/org/deftserver/example/handler/CookieHandlerExample.java (original)
+++ incubator/deft/sandbox/src/main/java/org/deftserver/example/handler/CookieHandlerExample.java Wed Aug 3 17:36:25 2011
@@ -28,15 +28,14 @@ import org.deftserver.web.http.HttpReque
import org.deftserver.web.http.HttpResponse;
/**
- * This handler demonstrates usage of cookie-related functionality. The
- * {@link Path} annotation below defines the path on which this handler is
- * invoked. When executed as part of the server example:
+ * This handler demonstrates usage of cookie-related functionality. The {@link Path} annotation below defines the path
+ * on which this handler is invoked. When executed as part of the server example:
* <p>
* <code>http://localhost:8080/cookie</code>
* </p>
* <p>
- * This handler will set a cookie when a page is first viewed, with a limited
- * lifetime and unique identifier. Upon refresh, this cookie will be cleared.
+ * This handler will set a cookie when a page is first viewed, with a limited lifetime and unique identifier. Upon
+ * refresh, this cookie will be cleared.
* </p>
*
* @see Path
Modified: incubator/deft/sandbox/src/main/java/org/deftserver/example/handler/PatternHandlerExample.java
URL: http://svn.apache.org/viewvc/incubator/deft/sandbox/src/main/java/org/deftserver/example/handler/PatternHandlerExample.java?rev=1153593&r1=1153592&r2=1153593&view=diff
==============================================================================
--- incubator/deft/sandbox/src/main/java/org/deftserver/example/handler/PatternHandlerExample.java (original)
+++ incubator/deft/sandbox/src/main/java/org/deftserver/example/handler/PatternHandlerExample.java Wed Aug 3 17:36:25 2011
@@ -28,16 +28,15 @@ import org.deftserver.web.http.HttpReque
import org.deftserver.web.http.HttpResponse;
/**
- * This handler is invoked as a result of the combination of path and Regular
- * Expression. When executed as part of the server example:
+ * This handler is invoked as a result of the combination of path and Regular Expression. When executed as part of the
+ * server example:
* <p>
- * <code>http://localhost:8080/pattern/123</code> will be found.
- * <code>http://localhost:8080/pattern/abc</code> will not be found.
+ * <code>http://localhost:8080/pattern/123</code> will be found. <code>http://localhost:8080/pattern/abc</code> will not
+ * be found.
* </p>
* <p>
- * In the annotation below, the regular expression is "[0-9]+" which indicates
- * that any number will be matched. Any pattern as understood by {@link Pattern}
- * is suitable, and the handler will be invoked only when this pattern is
+ * In the annotation below, the regular expression is "[0-9]+" which indicates that any number will be matched. Any
+ * pattern as understood by {@link Pattern} is suitable, and the handler will be invoked only when this pattern is
* matched.
* </p>
*
Modified: incubator/deft/sandbox/src/main/java/org/deftserver/example/keyvalue/KeyValueStoreExample.java
URL: http://svn.apache.org/viewvc/incubator/deft/sandbox/src/main/java/org/deftserver/example/keyvalue/KeyValueStoreExample.java?rev=1153593&r1=1153592&r2=1153593&view=diff
==============================================================================
--- incubator/deft/sandbox/src/main/java/org/deftserver/example/keyvalue/KeyValueStoreExample.java (original)
+++ incubator/deft/sandbox/src/main/java/org/deftserver/example/keyvalue/KeyValueStoreExample.java Wed Aug 3 17:36:25 2011
@@ -49,10 +49,13 @@ public class KeyValueStoreExample {
public void get(HttpRequest request, final HttpResponse response) {
client.get("deft", new AsyncResult<byte[]>() {
@Override
- public void onFailure(Throwable caught) { /* ignore */ }
+ public void onFailure(Throwable caught) { /* ignore */
+ }
@Override
- public void onSuccess(byte[] result) { response.write(new String(result)).finish(); }
+ public void onSuccess(byte[] result) {
+ response.write(new String(result)).finish();
+ }
});
}
}
Modified: incubator/deft/sandbox/src/main/java/org/deftserver/util/HttpUtil.java
URL: http://svn.apache.org/viewvc/incubator/deft/sandbox/src/main/java/org/deftserver/util/HttpUtil.java?rev=1153593&r1=1153592&r2=1153593&view=diff
==============================================================================
--- incubator/deft/sandbox/src/main/java/org/deftserver/util/HttpUtil.java (original)
+++ incubator/deft/sandbox/src/main/java/org/deftserver/util/HttpUtil.java Wed Aug 3 17:36:25 2011
@@ -28,166 +28,168 @@ import org.deftserver.web.http.HttpReque
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-
public class HttpUtil {
- private static final Logger logger = LoggerFactory.getLogger(HttpUtil.class);
-
- /* MessageDigest are not thread-safe and are expensive to create.
- * Do it lazily for each thread that need access to one.*/
- private static final ThreadLocal<MessageDigest> md = new ThreadLocal<MessageDigest>();
-
- private static final String _200_OK = "HTTP/1.1 200 OK\r\n";
- private static final String _201_CREATED = "HTTP/1.1 201 Created\r\n";
- private static final String _202_ACCEPTED = "HTTP/1.1 202 Accepted\r\n";
- private static final String _203_NON_AUTHORITATIVE_INFO = "HTTP/1.1 203 Non-Authoritative Information\r\n";
- private static final String _204_NO_CONTENT = "HTTP/1.1 204 No Content\r\n";
- private static final String _205_RESET_CONTENT = "HTTP/1.1 205 Reset Content\r\n";
- private static final String _206_PARTIAL_CONTENT = "HTTP/1.1 206 Partial Content\r\n";
- private static final String _300_MULTIPLE_CHOICES = "HTTP/1.1 300 Multiple Choices\r\n";
- private static final String _301_MOVED_PERMANENTLY = "HTTP/1.1 301 Moved Permanently\r\n";
- private static final String _302_NOT_FOUND = "HTTP/1.1 302 Found\r\n";
- private static final String _303_SEE_OTHER = "HTTP/1.1 303 See Other\r\n";
- private static final String _304_NOT_MODIFIED = "HTTP/1.1 304 Not Modified\r\n";
- private static final String _305_USE_PROXY = "HTTP/1.1 305 Use Proxy\r\n";
- private static final String _307_TEMPORARY_REDIRECT = "HTTP/1.1 307 Temporary Redirect\r\n";
- private static final String _400_BAD_REQUEST = "HTTP/1.1 400 Bad Request\r\n";
- private static final String _401_UNAUTHORIZED = "HTTP/1.1 401 Unauthorized\r\n";
- private static final String _403_FORBIDDEN = "HTTP/1.1 403 Forbidden\r\n";
- private static final String _404_NOT_FOUND = "HTTP/1.1 404 Not Found\r\n";
- private static final String _405_METHOD_NOT_ALLOWED = "HTTP/1.1 405 Method Not Allowed\r\n";
- private static final String _406_NOT_ACCEPTABLE = "HTTP/1.1 406 Not Acceptable\r\n";
- private static final String _407_PROXY_AUTH_REQUIRED = "HTTP/1.1 407 Proxy Authentication Required\r\n";
- private static final String _408_REQUEST_TIMEOUT = "HTTP/1.1 408 Request Timeout\r\n";
- private static final String _409_CONFLICT = "HTTP/1.1 409 Conflict\r\n";
- private static final String _410_GONE = "HTTP/1.1 410 Gone\r\n";
- private static final String _411_LENGTH_REQUIRED = "HTTP/1.1 411 Length Required\r\n";
- private static final String _412_PRECONDITION_FAILED = "HTTP/1.1 412 Precondition Failed\r\n";
- private static final String _413_REQUEST_ENTITY_LARGE = "HTTP/1.1 413 Request Entity Too Large\r\n";
- private static final String _414_REQUEST_URI_TOO_LONG = "HTTP/1.1 414 Request-URI Too Long\r\n";
- private static final String _415_UNSUPPORTED_MEDIA_TYPE = "HTTP/1.1 415 Unsupported Media Type\r\n";
- private static final String _416_REQUEST_RANGE_NOT_SAT = "HTTP/1.1 416 Requested Range Not Satisfiable\r\n";
- private static final String _417_EXPECTATION_FAILED = "HTTP/1.1 417 Expectation Failed\r\n";
- private static final String _500_INTERNAL_SERVER_ERROR = "HTTP/1.1 500 Internal Server Error\r\n";
- private static final String _501_NOT_IMPLEMENTED = "HTTP/1.1 501 Not Implemented\r\n";
- private static final String _502_BAD_GATEWAY = "HTTP/1.1 502 Bad Gateway\r\n";
- private static final String _503_SERVICE_UNAVAILABLE = "HTTP/1.1 503 Service Unavailable\r\n";
- private static final String _504_GATEWAY_TIMEOUT = "HTTP/1.1 504 Gateway Timeout\r\n";
- private static final String _505_VERSION_NOT_SUPPORTED = "HTTP/1.1 505 HTTP Version Not Supported\r\n";
-
- // e.g. HTTP/1.0 200 OK or HTTP/1.0 404 Not Found (HTTP version + response status code + reason phrase)
- public static String createInitialLine(int statusCode) {
-
- switch (statusCode) {
- case 200:
- return _200_OK;
- case 201:
- return _201_CREATED;
- case 202:
- return _202_ACCEPTED;
- case 203:
- return _203_NON_AUTHORITATIVE_INFO;
- case 204:
- return _204_NO_CONTENT;
- case 205:
- return _205_RESET_CONTENT;
- case 206:
- return _206_PARTIAL_CONTENT;
- case 300:
- return _300_MULTIPLE_CHOICES;
- case 301:
- return _301_MOVED_PERMANENTLY;
- case 302:
- return _302_NOT_FOUND;
- case 303:
- return _303_SEE_OTHER;
- case 304:
- return _304_NOT_MODIFIED;
- case 305:
- return _305_USE_PROXY;
- case 307:
- return _307_TEMPORARY_REDIRECT;
- case 400:
- return _400_BAD_REQUEST;
- case 401:
- return _401_UNAUTHORIZED;
- case 403:
- return _403_FORBIDDEN;
- case 404:
- return _404_NOT_FOUND;
- case 405:
- return _405_METHOD_NOT_ALLOWED;
- case 406:
- return _406_NOT_ACCEPTABLE;
- case 407:
- return _407_PROXY_AUTH_REQUIRED;
- case 408:
- return _408_REQUEST_TIMEOUT;
- case 409:
- return _409_CONFLICT;
- case 410:
- return _410_GONE;
- case 411:
- return _411_LENGTH_REQUIRED;
- case 412:
- return _412_PRECONDITION_FAILED;
- case 413:
- return _413_REQUEST_ENTITY_LARGE;
- case 414:
- return _414_REQUEST_URI_TOO_LONG;
- case 415:
- return _415_UNSUPPORTED_MEDIA_TYPE;
- case 416:
- return _416_REQUEST_RANGE_NOT_SAT;
- case 417:
- return _417_EXPECTATION_FAILED;
- case 500:
- return _500_INTERNAL_SERVER_ERROR;
- case 501:
- return _501_NOT_IMPLEMENTED;
- case 502:
- return _502_BAD_GATEWAY;
- case 503:
- return _503_SERVICE_UNAVAILABLE;
- case 504:
- return _504_GATEWAY_TIMEOUT;
- case 505:
- return _505_VERSION_NOT_SUPPORTED;
- default:
- logger.error("Uknonwn Http status code: " + statusCode);
- throw new IllegalArgumentException("Unknow Http status code: " + statusCode);
- }
- }
-
-
- public static boolean verifyRequest(HttpRequest request) {
- String version = request.getVersion();
- boolean requestOk = true;
- if (version.equals("HTTP/1.1")) { //TODO might be optimized? Could do version.endsWith("1"), or similar
- requestOk = (request.getHeader("host") != null);
- }
-
- return requestOk;
- }
-
-
- public static String getEtag(byte[] bytes) {
- if (md.get() == null) {
- try {
- md.set(MessageDigest.getInstance("MD5"));
- } catch (NoSuchAlgorithmException e) {
- throw new RuntimeException("MD5 cryptographic algorithm is not available.", e);
- }
- }
- byte[] digest = md.get().digest(bytes);
- BigInteger number = new BigInteger(1, digest);
- return '0' + number.toString(16); // prepend a '0' to get a proper MD5 hash
- }
-
-
- public static String getEtag(File file) {
- // TODO RS 101011 Implement if etag response header should be present while static file serving.
- return "";
- }
+ private static final Logger logger = LoggerFactory.getLogger(HttpUtil.class);
+ /*
+ * MessageDigest are not thread-safe and are expensive to create. Do it
+ * lazily for each thread that need access to one.
+ */
+ private static final ThreadLocal<MessageDigest> md = new ThreadLocal<MessageDigest>();
+
+ private static final String _200_OK = "HTTP/1.1 200 OK\r\n";
+ private static final String _201_CREATED = "HTTP/1.1 201 Created\r\n";
+ private static final String _202_ACCEPTED = "HTTP/1.1 202 Accepted\r\n";
+ private static final String _203_NON_AUTHORITATIVE_INFO = "HTTP/1.1 203 Non-Authoritative Information\r\n";
+ private static final String _204_NO_CONTENT = "HTTP/1.1 204 No Content\r\n";
+ private static final String _205_RESET_CONTENT = "HTTP/1.1 205 Reset Content\r\n";
+ private static final String _206_PARTIAL_CONTENT = "HTTP/1.1 206 Partial Content\r\n";
+ private static final String _300_MULTIPLE_CHOICES = "HTTP/1.1 300 Multiple Choices\r\n";
+ private static final String _301_MOVED_PERMANENTLY = "HTTP/1.1 301 Moved Permanently\r\n";
+ private static final String _302_NOT_FOUND = "HTTP/1.1 302 Found\r\n";
+ private static final String _303_SEE_OTHER = "HTTP/1.1 303 See Other\r\n";
+ private static final String _304_NOT_MODIFIED = "HTTP/1.1 304 Not Modified\r\n";
+ private static final String _305_USE_PROXY = "HTTP/1.1 305 Use Proxy\r\n";
+ private static final String _307_TEMPORARY_REDIRECT = "HTTP/1.1 307 Temporary Redirect\r\n";
+ private static final String _400_BAD_REQUEST = "HTTP/1.1 400 Bad Request\r\n";
+ private static final String _401_UNAUTHORIZED = "HTTP/1.1 401 Unauthorized\r\n";
+ private static final String _403_FORBIDDEN = "HTTP/1.1 403 Forbidden\r\n";
+ private static final String _404_NOT_FOUND = "HTTP/1.1 404 Not Found\r\n";
+ private static final String _405_METHOD_NOT_ALLOWED = "HTTP/1.1 405 Method Not Allowed\r\n";
+ private static final String _406_NOT_ACCEPTABLE = "HTTP/1.1 406 Not Acceptable\r\n";
+ private static final String _407_PROXY_AUTH_REQUIRED = "HTTP/1.1 407 Proxy Authentication Required\r\n";
+ private static final String _408_REQUEST_TIMEOUT = "HTTP/1.1 408 Request Timeout\r\n";
+ private static final String _409_CONFLICT = "HTTP/1.1 409 Conflict\r\n";
+ private static final String _410_GONE = "HTTP/1.1 410 Gone\r\n";
+ private static final String _411_LENGTH_REQUIRED = "HTTP/1.1 411 Length Required\r\n";
+ private static final String _412_PRECONDITION_FAILED = "HTTP/1.1 412 Precondition Failed\r\n";
+ private static final String _413_REQUEST_ENTITY_LARGE = "HTTP/1.1 413 Request Entity Too Large\r\n";
+ private static final String _414_REQUEST_URI_TOO_LONG = "HTTP/1.1 414 Request-URI Too Long\r\n";
+ private static final String _415_UNSUPPORTED_MEDIA_TYPE = "HTTP/1.1 415 Unsupported Media Type\r\n";
+ private static final String _416_REQUEST_RANGE_NOT_SAT = "HTTP/1.1 416 Requested Range Not Satisfiable\r\n";
+ private static final String _417_EXPECTATION_FAILED = "HTTP/1.1 417 Expectation Failed\r\n";
+ private static final String _500_INTERNAL_SERVER_ERROR = "HTTP/1.1 500 Internal Server Error\r\n";
+ private static final String _501_NOT_IMPLEMENTED = "HTTP/1.1 501 Not Implemented\r\n";
+ private static final String _502_BAD_GATEWAY = "HTTP/1.1 502 Bad Gateway\r\n";
+ private static final String _503_SERVICE_UNAVAILABLE = "HTTP/1.1 503 Service Unavailable\r\n";
+ private static final String _504_GATEWAY_TIMEOUT = "HTTP/1.1 504 Gateway Timeout\r\n";
+ private static final String _505_VERSION_NOT_SUPPORTED = "HTTP/1.1 505 HTTP Version Not Supported\r\n";
+
+ // e.g. HTTP/1.0 200 OK or HTTP/1.0 404 Not Found (HTTP version + response
+ // status code + reason phrase)
+ public static String createInitialLine(int statusCode) {
+
+ switch (statusCode) {
+ case 200:
+ return _200_OK;
+ case 201:
+ return _201_CREATED;
+ case 202:
+ return _202_ACCEPTED;
+ case 203:
+ return _203_NON_AUTHORITATIVE_INFO;
+ case 204:
+ return _204_NO_CONTENT;
+ case 205:
+ return _205_RESET_CONTENT;
+ case 206:
+ return _206_PARTIAL_CONTENT;
+ case 300:
+ return _300_MULTIPLE_CHOICES;
+ case 301:
+ return _301_MOVED_PERMANENTLY;
+ case 302:
+ return _302_NOT_FOUND;
+ case 303:
+ return _303_SEE_OTHER;
+ case 304:
+ return _304_NOT_MODIFIED;
+ case 305:
+ return _305_USE_PROXY;
+ case 307:
+ return _307_TEMPORARY_REDIRECT;
+ case 400:
+ return _400_BAD_REQUEST;
+ case 401:
+ return _401_UNAUTHORIZED;
+ case 403:
+ return _403_FORBIDDEN;
+ case 404:
+ return _404_NOT_FOUND;
+ case 405:
+ return _405_METHOD_NOT_ALLOWED;
+ case 406:
+ return _406_NOT_ACCEPTABLE;
+ case 407:
+ return _407_PROXY_AUTH_REQUIRED;
+ case 408:
+ return _408_REQUEST_TIMEOUT;
+ case 409:
+ return _409_CONFLICT;
+ case 410:
+ return _410_GONE;
+ case 411:
+ return _411_LENGTH_REQUIRED;
+ case 412:
+ return _412_PRECONDITION_FAILED;
+ case 413:
+ return _413_REQUEST_ENTITY_LARGE;
+ case 414:
+ return _414_REQUEST_URI_TOO_LONG;
+ case 415:
+ return _415_UNSUPPORTED_MEDIA_TYPE;
+ case 416:
+ return _416_REQUEST_RANGE_NOT_SAT;
+ case 417:
+ return _417_EXPECTATION_FAILED;
+ case 500:
+ return _500_INTERNAL_SERVER_ERROR;
+ case 501:
+ return _501_NOT_IMPLEMENTED;
+ case 502:
+ return _502_BAD_GATEWAY;
+ case 503:
+ return _503_SERVICE_UNAVAILABLE;
+ case 504:
+ return _504_GATEWAY_TIMEOUT;
+ case 505:
+ return _505_VERSION_NOT_SUPPORTED;
+ default:
+ logger.error("Uknonwn Http status code: " + statusCode);
+ throw new IllegalArgumentException("Unknow Http status code: " + statusCode);
+ }
+ }
+
+ public static boolean verifyRequest(HttpRequest request) {
+ String version = request.getVersion();
+ boolean requestOk = true;
+ if (version.equals("HTTP/1.1")) { // TODO might be optimized? Could do
+ // version.endsWith("1"), or similar
+ requestOk = request.getHeader("host") != null;
+ }
+
+ return requestOk;
+ }
+
+ public static String getEtag(byte[] bytes) {
+ if (md.get() == null) {
+ try {
+ md.set(MessageDigest.getInstance("MD5"));
+ } catch (NoSuchAlgorithmException e) {
+ throw new RuntimeException("MD5 cryptographic algorithm is not available.", e);
+ }
+ }
+ byte[] digest = md.get().digest(bytes);
+ BigInteger number = new BigInteger(1, digest);
+ // prepend a '0' to get a proper MD5 hash
+ return '0' + number.toString(16);
+
+ }
+
+ public static String getEtag(File file) {
+ // TODO RS 101011 Implement if etag response header should be present
+ // while static file serving.
+ return "";
+ }
}
Modified: incubator/deft/sandbox/src/main/java/org/deftserver/web/Application.java
URL: http://svn.apache.org/viewvc/incubator/deft/sandbox/src/main/java/org/deftserver/web/Application.java?rev=1153593&r1=1153592&r2=1153593&view=diff
==============================================================================
--- incubator/deft/sandbox/src/main/java/org/deftserver/web/Application.java (original)
+++ incubator/deft/sandbox/src/main/java/org/deftserver/web/Application.java Wed Aug 3 17:36:25 2011
@@ -33,119 +33,128 @@ import org.deftserver.web.http.HttpReque
import com.google.common.collect.ImmutableMap;
public class Application {
-
- /**
- * "Normal/Absolute" (non group capturing) RequestHandlers
- * e.g. "/", "/persons"
- */
- private final ImmutableMap<String, RequestHandler> absoluteHandlers;
-
- /**
- * Group capturing RequestHandlers
- * e.g. "/persons/([0-9]+)", "/persons/(\\d{1,3})"
- */
- private final ImmutableMap<String, RequestHandler> capturingHandlers;
-
- /**
- * A mapping between group capturing RequestHandlers and their corresponding pattern ( e.g. "([0-9]+)" )
- */
- private final ImmutableMap<RequestHandler, Pattern> patterns;
-
- /**
- * The directory where static content (files) will be served from.
- */
- private String staticContentDir;
-
- public Application(Map<String, RequestHandler> handlers) {
- ImmutableMap.Builder<String, RequestHandler> builder = new ImmutableMap.Builder<String, RequestHandler>();
- ImmutableMap.Builder<String, RequestHandler> capturingBuilder = new ImmutableMap.Builder<String, RequestHandler>();
- ImmutableMap.Builder<RequestHandler, Pattern> patternsBuilder = new ImmutableMap.Builder<RequestHandler, Pattern>();
-
- for (String path : handlers.keySet()) {
- int index = path.lastIndexOf("/");
- String group = path.substring(index+1, path.length());
- if (containsCapturingGroup(group)) {
- // path ends with capturing group, e.g path == "/person/([0-9]+)"
- capturingBuilder.put(path.substring(0, index+1), handlers.get(path));
- patternsBuilder.put(handlers.get(path), Pattern.compile(group));
- } else {
- // "normal" path, e.g. path == "/"
- builder.put(path, handlers.get(path));
- }
- }
- absoluteHandlers = builder.build();
- capturingHandlers = capturingBuilder.build();
- patterns = patternsBuilder.build();
- }
-
- /**
- *
- * @param path Requested path
- * @return Returns the {@link RequestHandler} associated with the given path. If no mapping exists a
- * {@link NotFoundRequestHandler} is returned.
- */
- private RequestHandler getHandler(String path) {
- RequestHandler rh = absoluteHandlers.get(path);
- if (rh == null) {
- // path could contain capturing groups which we could have a handler associated with.
- rh = getCapturingHandler(path);
- if (rh == null) {
- // path could be prefixed with the 'static content directory'
- rh = getStaticContentHandler(path);
- }
- }
- return rh != null ? rh : NotFoundRequestHandler.getInstance(); // TODO RS store in a final field for improved performance?
- }
-
- public RequestHandler getHandler(HttpRequest request) {
- if (!HttpUtil.verifyRequest(request)) {
- return BadRequestRequestHandler.getInstance();
- }
- // if @Authenticated annotation is present, make sure that the request/user is authenticated
- // (i.e RequestHandler.getCurrentUser() != null).
- RequestHandler rh = getHandler(request.getRequestedPath());;
- if (rh.isMethodAuthenticated(request.getMethod()) && rh.getCurrentUser(request) == null) {
- return ForbiddenRequestHandler.getInstance();
- }
- return rh;
- }
-
- private boolean containsCapturingGroup(String group) {
- boolean containsGroup = group.matches("^\\(.*\\)$");
- Pattern.compile(group); // throws PatternSyntaxException if group is malformed regular expression
- return containsGroup;
- }
-
- private RequestHandler getCapturingHandler(String path) {
- int index = path.lastIndexOf("/");
- if (index != -1) {
- String init = path.substring(0, index+1); // path without its last segment
- String group = path.substring(index+1, path.length());
- RequestHandler handler = capturingHandlers.get(init);
- if (handler != null) {
- Pattern regex = patterns.get(handler);
- if (regex.matcher(group).matches()) {
- return handler;
- }
- }
- }
- return null;
- }
-
- private RequestHandler getStaticContentHandler(String path) {
- if (staticContentDir == null || path.length() <= staticContentDir.length()) {
- return null; // quick reject (no static dir or simple contradiction)
- }
-
- if (path.substring(1).startsWith(staticContentDir)) {
- return StaticContentHandler.getInstance();
- } else {
- return null;
- }
- }
-
- public void setStaticContentDir(String scd) {
- this.staticContentDir = scd;
- }
+ /**
+ * "Normal/Absolute" (non group capturing) RequestHandlers e.g. "/",
+ * "/persons"
+ */
+ private final ImmutableMap<String, RequestHandler> absoluteHandlers;
+
+ /**
+ * Group capturing RequestHandlers e.g. "/persons/([0-9]+)",
+ * "/persons/(\\d{1,3})"
+ */
+ private final ImmutableMap<String, RequestHandler> capturingHandlers;
+
+ /**
+ * A mapping between group capturing RequestHandlers and their corresponding
+ * pattern ( e.g. "([0-9]+)" )
+ */
+ private final ImmutableMap<RequestHandler, Pattern> patterns;
+
+ /**
+ * The directory where static content (files) will be served from.
+ */
+ private String staticContentDir;
+
+ public Application(Map<String, RequestHandler> handlers) {
+ ImmutableMap.Builder<String, RequestHandler> builder = new ImmutableMap.Builder<String, RequestHandler>();
+ ImmutableMap.Builder<String, RequestHandler> capturingBuilder = new ImmutableMap.Builder<String, RequestHandler>();
+ ImmutableMap.Builder<RequestHandler, Pattern> patternsBuilder = new ImmutableMap.Builder<RequestHandler, Pattern>();
+
+ for (String path : handlers.keySet()) {
+ int index = path.lastIndexOf("/");
+ String group = path.substring(index + 1, path.length());
+ if (containsCapturingGroup(group)) {
+ // path ends with capturing group, e.g path ==
+ // "/person/([0-9]+)"
+ capturingBuilder.put(path.substring(0, index + 1), handlers.get(path));
+ patternsBuilder.put(handlers.get(path), Pattern.compile(group));
+ } else {
+ // "normal" path, e.g. path == "/"
+ builder.put(path, handlers.get(path));
+ }
+ }
+ absoluteHandlers = builder.build();
+ capturingHandlers = capturingBuilder.build();
+ patterns = patternsBuilder.build();
+ }
+
+ /**
+ *
+ * @param path Requested path
+ * @return Returns the {@link RequestHandler} associated with the given
+ * path. If no mapping exists a {@link NotFoundRequestHandler} is
+ * returned.
+ */
+ private RequestHandler getHandler(String path) {
+ RequestHandler rh = absoluteHandlers.get(path);
+ if (rh == null) {
+ // path could contain capturing groups which we could have a handler
+ // associated with.
+ rh = getCapturingHandler(path);
+ if (rh == null) {
+ // path could be prefixed with the 'static content directory'
+ rh = getStaticContentHandler(path);
+ }
+ }
+
+ // TODO RS store in a final field for improved performance?
+ return rh != null ? rh : NotFoundRequestHandler.getInstance();
+ }
+
+ public RequestHandler getHandler(HttpRequest request) {
+ if (!HttpUtil.verifyRequest(request)) {
+ return BadRequestRequestHandler.getInstance();
+ }
+ // if @Authenticated annotation is present, make sure that the
+ // request/user is authenticated
+ // (i.e RequestHandler.getCurrentUser() != null).
+ RequestHandler rh = getHandler(request.getRequestedPath());
+ ;
+ if (rh.isMethodAuthenticated(request.getMethod()) && rh.getCurrentUser(request) == null) {
+ return ForbiddenRequestHandler.getInstance();
+ }
+ return rh;
+ }
+
+ private boolean containsCapturingGroup(String group) {
+ boolean containsGroup = group.matches("^\\(.*\\)$");
+ Pattern.compile(group); // throws PatternSyntaxException if group is
+ // malformed regular expression
+ return containsGroup;
+ }
+
+ private RequestHandler getCapturingHandler(String path) {
+ int index = path.lastIndexOf("/");
+ if (index != -1) {
+ String init = path.substring(0, index + 1); // path without its last
+ // segment
+ String group = path.substring(index + 1, path.length());
+ RequestHandler handler = capturingHandlers.get(init);
+ if (handler != null) {
+ Pattern regex = patterns.get(handler);
+ if (regex.matcher(group).matches()) {
+ return handler;
+ }
+ }
+ }
+ return null;
+ }
+
+ private RequestHandler getStaticContentHandler(String path) {
+ if (staticContentDir == null || path.length() <= staticContentDir.length()) {
+ return null; // quick reject (no static dir or simple contradiction)
+ }
+
+ if (path.substring(1).startsWith(staticContentDir)) {
+ return StaticContentHandler.getInstance();
+ } else {
+ return null;
+ }
+ }
+
+ public void setStaticContentDir(String scd) {
+ staticContentDir = scd;
+ }
}
Modified: incubator/deft/sandbox/src/main/java/org/deftserver/web/handler/BadRequestRequestHandler.java
URL: http://svn.apache.org/viewvc/incubator/deft/sandbox/src/main/java/org/deftserver/web/handler/BadRequestRequestHandler.java?rev=1153593&r1=1153592&r2=1153593&view=diff
==============================================================================
--- incubator/deft/sandbox/src/main/java/org/deftserver/web/handler/BadRequestRequestHandler.java (original)
+++ incubator/deft/sandbox/src/main/java/org/deftserver/web/handler/BadRequestRequestHandler.java Wed Aug 3 17:36:25 2011
@@ -24,18 +24,19 @@ import org.deftserver.web.http.HttpRespo
public class BadRequestRequestHandler extends RequestHandler {
-private final static BadRequestRequestHandler instance = new BadRequestRequestHandler();
-
- private BadRequestRequestHandler() { }
-
- public static final BadRequestRequestHandler getInstance() {
- return instance;
- }
-
- @Override
- public void get(HttpRequest request, HttpResponse response) {
- response.setStatusCode(400);
- response.setHeader("Connection", "close");
- response.write("HTTP 1.1 requests must include the Host: header");
- }
+ private final static BadRequestRequestHandler instance = new BadRequestRequestHandler();
+
+ private BadRequestRequestHandler() {
+ }
+
+ public static final BadRequestRequestHandler getInstance() {
+ return instance;
+ }
+
+ @Override
+ public void get(HttpRequest request, HttpResponse response) {
+ response.setStatusCode(400);
+ response.setHeader("Connection", "close");
+ response.write("HTTP 1.1 requests must include the Host: header");
+ }
}
Modified: incubator/deft/sandbox/src/main/java/org/deftserver/web/handler/ForbiddenRequestHandler.java
URL: http://svn.apache.org/viewvc/incubator/deft/sandbox/src/main/java/org/deftserver/web/handler/ForbiddenRequestHandler.java?rev=1153593&r1=1153592&r2=1153593&view=diff
==============================================================================
--- incubator/deft/sandbox/src/main/java/org/deftserver/web/handler/ForbiddenRequestHandler.java (original)
+++ incubator/deft/sandbox/src/main/java/org/deftserver/web/handler/ForbiddenRequestHandler.java Wed Aug 3 17:36:25 2011
@@ -24,18 +24,19 @@ import org.deftserver.web.http.HttpRespo
public class ForbiddenRequestHandler extends RequestHandler {
-private final static ForbiddenRequestHandler instance = new ForbiddenRequestHandler();
-
- private ForbiddenRequestHandler() { }
-
- public static final ForbiddenRequestHandler getInstance() {
- return instance;
- }
-
- @Override
- public void get(HttpRequest request, HttpResponse response) {
- response.setStatusCode(403);
- response.setHeader("Connection", "close");
- response.write("Authentication failed");
- }
-}
\ No newline at end of file
+ private final static ForbiddenRequestHandler instance = new ForbiddenRequestHandler();
+
+ private ForbiddenRequestHandler() {
+ }
+
+ public static final ForbiddenRequestHandler getInstance() {
+ return instance;
+ }
+
+ @Override
+ public void get(HttpRequest request, HttpResponse response) {
+ response.setStatusCode(403);
+ response.setHeader("Connection", "close");
+ response.write("Authentication failed");
+ }
+}
Modified: incubator/deft/sandbox/src/main/java/org/deftserver/web/handler/NotFoundRequestHandler.java
URL: http://svn.apache.org/viewvc/incubator/deft/sandbox/src/main/java/org/deftserver/web/handler/NotFoundRequestHandler.java?rev=1153593&r1=1153592&r2=1153593&view=diff
==============================================================================
--- incubator/deft/sandbox/src/main/java/org/deftserver/web/handler/NotFoundRequestHandler.java (original)
+++ incubator/deft/sandbox/src/main/java/org/deftserver/web/handler/NotFoundRequestHandler.java Wed Aug 3 17:36:25 2011
@@ -22,21 +22,21 @@ package org.deftserver.web.handler;
import org.deftserver.web.http.HttpRequest;
import org.deftserver.web.http.HttpResponse;
-
public class NotFoundRequestHandler extends RequestHandler {
- private final static NotFoundRequestHandler instance = new NotFoundRequestHandler();
-
- private NotFoundRequestHandler() { }
-
- public static final NotFoundRequestHandler getInstance() {
- return instance;
- }
-
- @Override
- public void get(HttpRequest request, HttpResponse response) {
- response.setStatusCode(404);
- response.setHeader("Connection", "close");
- response.write("Requested URL: " + request.getRequestedPath() + " was not found");
- }
+ private final static NotFoundRequestHandler instance = new NotFoundRequestHandler();
+
+ private NotFoundRequestHandler() {
+ }
+
+ public static final NotFoundRequestHandler getInstance() {
+ return instance;
+ }
+
+ @Override
+ public void get(HttpRequest request, HttpResponse response) {
+ response.setStatusCode(404);
+ response.setHeader("Connection", "close");
+ response.write("Requested URL: " + request.getRequestedPath() + " was not found");
+ }
}
Modified: incubator/deft/sandbox/src/main/java/org/deftserver/web/handler/RequestHandler.java
URL: http://svn.apache.org/viewvc/incubator/deft/sandbox/src/main/java/org/deftserver/web/handler/RequestHandler.java?rev=1153593&r1=1153592&r2=1153593&view=diff
==============================================================================
--- incubator/deft/sandbox/src/main/java/org/deftserver/web/handler/RequestHandler.java (original)
+++ incubator/deft/sandbox/src/main/java/org/deftserver/web/handler/RequestHandler.java Wed Aug 3 17:36:25 2011
@@ -33,65 +33,64 @@ import com.google.common.collect.Maps;
public abstract class RequestHandler {
- private final ImmutableMap<HttpVerb, Boolean> asynchVerbs;
- private final ImmutableMap<HttpVerb, Boolean> authVerbs;
-
- public RequestHandler() {
- Map<HttpVerb, Boolean> asyncV = Maps.newHashMap();
- Map<HttpVerb, Boolean> authV = Maps.newHashMap();
- for (HttpVerb verb : HttpVerb.values()) {
- authV.put(verb, isMethodAnnotated(verb, Authenticated.class));
- asyncV.put(verb, isMethodAnnotated(verb, Asynchronous.class));
- }
- asynchVerbs = ImmutableMap.copyOf(asyncV);
- authVerbs = ImmutableMap.copyOf(authV);
- }
-
- private boolean isMethodAnnotated(HttpVerb verb, Class<? extends Annotation> annotation) {
- try {
- Class<?>[] parameterTypes = {HttpRequest.class, HttpResponse.class};
- return getClass().getMethod(verb.toString().toLowerCase(), parameterTypes).getAnnotation(annotation) != null;
- } catch (NoSuchMethodException nsme) {
- return false;
- }
- }
-
- public boolean isMethodAsynchronous(HttpVerb verb) {
- return asynchVerbs.get(verb);
- }
-
- public boolean isMethodAuthenticated(HttpVerb verb) {
- return authVerbs.get(verb);
- }
-
- //Default implementation of HttpMethods return a 501 page
- public void get(HttpRequest request, HttpResponse response) {
- response.setStatusCode(501);
- response.write("");
- }
-
- public void post(HttpRequest request, HttpResponse response) {
- response.setStatusCode(501);
- response.write("");
- }
-
- public void put(HttpRequest request, HttpResponse response) {
- response.setStatusCode(501);
- response.write("");
- }
-
- public void delete(HttpRequest request, HttpResponse response) {
- response.setStatusCode(501);
- response.write("");
- }
-
- public void head(HttpRequest request, HttpResponse response) {
- response.setStatusCode(501);
- response.write("");
- }
-
- public String getCurrentUser(HttpRequest request) {
- return null;
- }
+ private final ImmutableMap<HttpVerb, Boolean> asynchVerbs;
+ private final ImmutableMap<HttpVerb, Boolean> authVerbs;
+ public RequestHandler() {
+ Map<HttpVerb, Boolean> asyncV = Maps.newHashMap();
+ Map<HttpVerb, Boolean> authV = Maps.newHashMap();
+ for (HttpVerb verb : HttpVerb.values()) {
+ authV.put(verb, isMethodAnnotated(verb, Authenticated.class));
+ asyncV.put(verb, isMethodAnnotated(verb, Asynchronous.class));
+ }
+ asynchVerbs = ImmutableMap.copyOf(asyncV);
+ authVerbs = ImmutableMap.copyOf(authV);
+ }
+
+ private boolean isMethodAnnotated(HttpVerb verb, Class<? extends Annotation> annotation) {
+ try {
+ Class<?>[] parameterTypes = { HttpRequest.class, HttpResponse.class };
+ return getClass().getMethod(verb.toString().toLowerCase(), parameterTypes).getAnnotation(annotation) != null;
+ } catch (NoSuchMethodException nsme) {
+ return false;
+ }
+ }
+
+ public boolean isMethodAsynchronous(HttpVerb verb) {
+ return asynchVerbs.get(verb);
+ }
+
+ public boolean isMethodAuthenticated(HttpVerb verb) {
+ return authVerbs.get(verb);
+ }
+
+ // Default implementation of HttpMethods return a 501 page
+ public void get(HttpRequest request, HttpResponse response) {
+ response.setStatusCode(501);
+ response.write("");
+ }
+
+ public void post(HttpRequest request, HttpResponse response) {
+ response.setStatusCode(501);
+ response.write("");
+ }
+
+ public void put(HttpRequest request, HttpResponse response) {
+ response.setStatusCode(501);
+ response.write("");
+ }
+
+ public void delete(HttpRequest request, HttpResponse response) {
+ response.setStatusCode(501);
+ response.write("");
+ }
+
+ public void head(HttpRequest request, HttpResponse response) {
+ response.setStatusCode(501);
+ response.write("");
+ }
+
+ public String getCurrentUser(HttpRequest request) {
+ return null;
+ }
}
Modified: incubator/deft/sandbox/src/main/java/org/deftserver/web/handler/StaticContentHandler.java
URL: http://svn.apache.org/viewvc/incubator/deft/sandbox/src/main/java/org/deftserver/web/handler/StaticContentHandler.java?rev=1153593&r1=1153592&r2=1153593&view=diff
==============================================================================
--- incubator/deft/sandbox/src/main/java/org/deftserver/web/handler/StaticContentHandler.java (original)
+++ incubator/deft/sandbox/src/main/java/org/deftserver/web/handler/StaticContentHandler.java Wed Aug 3 17:36:25 2011
@@ -27,7 +27,6 @@ package org.deftserver.web.handler;
import java.io.File;
import javax.activation.FileTypeMap;
-import javax.activation.MimetypesFileTypeMap;
import org.deftserver.util.DateUtil;
import org.deftserver.web.http.HttpException;
@@ -37,71 +36,73 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
- * A RequestHandler that serves static content (files) from a predefined directory.
- *
- * "Cache-Control: public" indicates that the response MAY be cached by any cache, even if it would normally be
- * non-cacheable or cacheable only within a non- shared cache.
- *
+ * A RequestHandler that serves static content (files) from a predefined
+ * directory.
+ *
+ * "Cache-Control: public" indicates that the response MAY be cached by any
+ * cache, even if it would normally be non-cacheable or cacheable only within a
+ * non- shared cache.
*/
public class StaticContentHandler extends RequestHandler {
- private final static Logger logger = LoggerFactory.getLogger(StaticContentHandler.class);
+ private final static Logger logger = LoggerFactory.getLogger(StaticContentHandler.class);
- private final static StaticContentHandler instance = new StaticContentHandler();
+ private final static StaticContentHandler instance = new StaticContentHandler();
- private final FileTypeMap mimeTypeMap = MimetypesFileTypeMap.getDefaultFileTypeMap();
+ private final FileTypeMap mimeTypeMap = FileTypeMap.getDefaultFileTypeMap();
- public static StaticContentHandler getInstance() {
- return instance;
- }
-
- /** {inheritDoc} */
- @Override
- public void get(HttpRequest request, HttpResponse response) {
- this.perform(request, response, true);
- }
-
- /** {inheritDoc} */
- @Override
- public void head(final HttpRequest request, final HttpResponse response) {
- this.perform(request, response, false);
- }
-
- /**
- * @param request the <code>HttpRequest</code>
- * @param response the <code>HttpResponse</code>
- * @param hasBody <code>true</code> to write the message body; <code>false</code> otherwise.
- */
- private void perform(final HttpRequest request, final HttpResponse response, boolean hasBody) {
-
- final String path = request.getRequestedPath();
- final File file = new File(path.substring(1)); // remove the leading '/'
- if (!file.exists()) {
- throw new HttpException(404);
- } else if (!file.isFile()) {
- throw new HttpException(403, path + "is not a file");
- }
-
- final long lastModified = file.lastModified();
- response.setHeader("Last-Modified", DateUtil.parseToRFC1123(lastModified));
- response.setHeader("Cache-Control", "public");
- String mimeType = mimeTypeMap.getContentType(file);
- if ("text/plain".equals(mimeType)) {
- mimeType += "; charset=utf-8";
- }
- response.setHeader("Content-Type", mimeType);
- final String ifModifiedSince = request.getHeader("If-Modified-Since");
- if (ifModifiedSince != null) {
- final long ims = DateUtil.parseToMilliseconds(ifModifiedSince);
- if (lastModified <= ims) {
- response.setStatusCode(304); //Not Modified
- logger.debug("not modified");
- return;
- }
- }
-
- if(hasBody) {
- response.write(file);
- }
- }
+ public static StaticContentHandler getInstance() {
+ return instance;
+ }
+
+ /** {inheritDoc} */
+ @Override
+ public void get(HttpRequest request, HttpResponse response) {
+ perform(request, response, true);
+ }
+
+ /** {inheritDoc} */
+ @Override
+ public void head(final HttpRequest request, final HttpResponse response) {
+ perform(request, response, false);
+ }
+
+ /**
+ * @param request the <code>HttpRequest</code>
+ * @param response the <code>HttpResponse</code>
+ * @param hasBody <code>true</code> to write the message body;
+ * <code>false</code> otherwise.
+ */
+ private void perform(final HttpRequest request, final HttpResponse response, boolean hasBody) {
+
+ final String path = request.getRequestedPath();
+ final File file = new File(path.substring(1)); // remove the leading '/'
+ if (!file.exists()) {
+ throw new HttpException(404);
+ } else if (!file.isFile()) {
+ throw new HttpException(403, path + "is not a file");
+ }
+
+ final long lastModified = file.lastModified();
+ response.setHeader("Last-Modified", DateUtil.parseToRFC1123(lastModified));
+ response.setHeader("Cache-Control", "public");
+ String mimeType = mimeTypeMap.getContentType(file);
+ if ("text/plain".equals(mimeType)) {
+ mimeType += "; charset=utf-8";
+ }
+ response.setHeader("Content-Type", mimeType);
+ final String ifModifiedSince = request.getHeader("If-Modified-Since");
+ if (ifModifiedSince != null) {
+ final long ims = DateUtil.parseToMilliseconds(ifModifiedSince);
+ if (lastModified <= ims) {
+ response.setStatusCode(304); // Not Modified
+ logger.debug("not modified");
+ return;
+ }
+ }
+
+ if (hasBody) {
+ response.write(file);
+ }
+ }
}
Modified: incubator/deft/sandbox/src/main/java/org/deftserver/web/http/HttpProtocol.java
URL: http://svn.apache.org/viewvc/incubator/deft/sandbox/src/main/java/org/deftserver/web/http/HttpProtocol.java?rev=1153593&r1=1153592&r2=1153593&view=diff
==============================================================================
--- incubator/deft/sandbox/src/main/java/org/deftserver/web/http/HttpProtocol.java (original)
+++ incubator/deft/sandbox/src/main/java/org/deftserver/web/http/HttpProtocol.java Wed Aug 3 17:36:25 2011
@@ -45,201 +45,204 @@ import org.slf4j.LoggerFactory;
import com.google.common.collect.Maps;
public class HttpProtocol implements IOHandler {
-
- private final static Logger logger = LoggerFactory.getLogger(HttpProtocol.class);
- private final IOLoop ioLoop;
- private final Application application;
+ private final static Logger logger = LoggerFactory.getLogger(HttpProtocol.class);
-
- // a queue of half-baked (pending/unfinished) HTTP post request
- private final Map<SelectableChannel, PartialHttpRequest> partials = Maps.newHashMap();
-
- public HttpProtocol(Application app) {
- this(IOLoop.INSTANCE, app);
- }
-
- public HttpProtocol(IOLoop ioLoop, Application app) {
- this.ioLoop = ioLoop;
- application = app;
- }
-
- @Override
- public void handleAccept(SelectionKey key) throws IOException {
- logger.debug("handle accept...");
- SocketChannel clientChannel = ((ServerSocketChannel) key.channel()).accept();
- if (clientChannel != null) {
- // could be null in a multithreaded deft environment because another ioloop was "faster" to accept()
- clientChannel.configureBlocking(false);
- ioLoop.addHandler(clientChannel, this, SelectionKey.OP_READ, ByteBuffer.allocate(READ_BUFFER_SIZE));
- }
- }
-
- @Override
- public void handleConnect(SelectionKey key) throws IOException {
- logger.error("handle connect in HttpProcotol...");
- }
-
- @Override
- public void handleRead(SelectionKey key) throws IOException {
- logger.debug("handle read...");
- SocketChannel clientChannel = (SocketChannel) key.channel();
- HttpRequest request = getHttpRequest(key, clientChannel);
-
- if (request.isKeepAlive()) {
- ioLoop.addKeepAliveTimeout(
- clientChannel,
- Timeout.newKeepAliveTimeout(ioLoop, clientChannel, KEEP_ALIVE_TIMEOUT)
- );
- }
- HttpResponse response = new HttpResponse(this, key, request.isKeepAlive());
- RequestHandler rh = application.getHandler(request);
- HttpRequestDispatcher.dispatch(rh, request, response);
-
- //Only close if not async. In that case its up to RH to close it (+ don't close if it's a partial request).
- if (!rh.isMethodAsynchronous(request.getMethod()) && ! (request instanceof PartialHttpRequest)) {
- response.finish();
- }
- }
-
- @Override
- public void handleWrite(SelectionKey key) {
- logger.debug("handle write...");
- SocketChannel channel = ((SocketChannel) key.channel());
-
- if (key.attachment() instanceof MappedByteBuffer) {
- writeMappedByteBuffer(key, channel);
- } else if (key.attachment() instanceof DynamicByteBuffer) {
- writeDynamicByteBuffer(key, channel);
- }
- if (ioLoop.hasKeepAliveTimeout(channel)) {
- prolongKeepAliveTimeout(channel);
- }
-
- }
-
- private void writeMappedByteBuffer(SelectionKey key, SocketChannel channel) {
- MappedByteBuffer mbb = (MappedByteBuffer) key.attachment();
- if (mbb.hasRemaining()) {
- try {
- channel.write(mbb);
- } catch (IOException e) {
- logger.error("Failed to send data to client: {}", e.getMessage());
- Closeables.closeQuietly(channel);
- }
- }
- if (!mbb.hasRemaining()) {
- closeOrRegisterForRead(key);
- }
- }
-
- private void writeDynamicByteBuffer(SelectionKey key, SocketChannel channel) {
- DynamicByteBuffer dbb = (DynamicByteBuffer) key.attachment();
- logger.debug("pending data about to be written");
- ByteBuffer toSend = dbb.getByteBuffer();
- toSend.flip(); // prepare for write
- long bytesWritten = 0;
- try {
- bytesWritten = channel.write(toSend);
- } catch (IOException e) {
- logger.error("Failed to send data to client: {}", e.getMessage());
- Closeables.closeQuietly(channel);
- }
- logger.debug("sent {} bytes to wire", bytesWritten);
- if (!toSend.hasRemaining()) {
- logger.debug("sent all data in toSend buffer");
- closeOrRegisterForRead(key); // should probably only be done if the HttpResponse is finished
- } else {
- toSend.compact(); // make room for more data be "read" in
- }
- }
-
- public void closeOrRegisterForRead(SelectionKey key) {
- if (key.isValid() && ioLoop.hasKeepAliveTimeout(key.channel())) {
- try {
- key.channel().register(key.selector(), SelectionKey.OP_READ, reuseAttachment(key));
- prolongKeepAliveTimeout(key.channel());
- logger.debug("keep-alive connection. registrating for read.");
- } catch (ClosedChannelException e) {
- logger.debug("ClosedChannelException while registrating key for read: {}", e.getMessage());
- Closeables.closeQuietly(ioLoop, key.channel());
- }
- } else {
- // http request should be finished and no 'keep-alive' => close connection
- logger.debug("Closing finished (non keep-alive) http connection");
- Closeables.closeQuietly(ioLoop, key.channel());
- }
- }
-
- public void prolongKeepAliveTimeout(SelectableChannel channel) {
- ioLoop.addKeepAliveTimeout(
- channel,
- Timeout.newKeepAliveTimeout(ioLoop, channel, KEEP_ALIVE_TIMEOUT)
- );
- }
-
- public IOLoop getIOLoop() {
- return ioLoop;
- }
-
- /**
- * Clears the buffer (prepares for reuse) attached to the given SelectionKey.
- * @return A cleared (position=0, limit=capacity) ByteBuffer which is ready for new reads
- */
- private ByteBuffer reuseAttachment(SelectionKey key) {
- Object o = key.attachment();
- ByteBuffer attachment = null;
- if (o instanceof MappedByteBuffer) {
- attachment = ByteBuffer.allocate(READ_BUFFER_SIZE);
- } else if (o instanceof DynamicByteBuffer) {
- attachment = ((DynamicByteBuffer) o).getByteBuffer();
- } else {
- attachment = (ByteBuffer) o;
- }
-
- if (attachment.capacity() < READ_BUFFER_SIZE) {
- attachment = ByteBuffer.allocate(READ_BUFFER_SIZE);
- }
- attachment.clear(); // prepare for reuse
- return attachment;
- }
-
- private HttpRequest getHttpRequest(SelectionKey key, SocketChannel clientChannel) {
- ByteBuffer buffer = (ByteBuffer) key.attachment();
- try {
- clientChannel.read(buffer);
- } catch (IOException e) {
- logger.warn("Could not read buffer: {}", e.getMessage());
- Closeables.closeQuietly(ioLoop, clientChannel);
- }
- buffer.flip();
-
- return doGetHttpRequest(key, clientChannel, buffer);
- }
-
- private HttpRequest doGetHttpRequest(SelectionKey key, SocketChannel clientChannel, ByteBuffer buffer) {
- //do we have any unfinished http post requests for this channel?
- HttpRequest request = null;
- if (partials.containsKey(clientChannel)) {
- request = HttpRequest.continueParsing(buffer, partials.get(clientChannel));
- if (! (request instanceof PartialHttpRequest)) { // received the entire payload/body
- partials.remove(clientChannel);
- }
- } else {
- request = HttpRequest.of(buffer);
- if (request instanceof PartialHttpRequest) {
- partials.put(key.channel(), (PartialHttpRequest) request);
- }
- }
- //set extra request info
- request.setRemoteHost(clientChannel.socket().getInetAddress());
- request.setRemotePort(clientChannel.socket().getPort());
- request.setServerHost(clientChannel.socket().getLocalAddress());
- request.setServerPort(clientChannel.socket().getLocalPort());
- return request;
- }
-
- @Override
- public String toString() { return "HttpProtocol"; }
-
+ private final IOLoop ioLoop;
+ private final Application application;
+
+ // a queue of half-baked (pending/unfinished) HTTP post request
+ private final Map<SelectableChannel, PartialHttpRequest> partials = Maps.newHashMap();
+
+ public HttpProtocol(Application app) {
+ this(IOLoop.INSTANCE, app);
+ }
+
+ public HttpProtocol(IOLoop ioLoop, Application app) {
+ this.ioLoop = ioLoop;
+ application = app;
+ }
+
+ @Override
+ public void handleAccept(SelectionKey key) throws IOException {
+ logger.debug("handle accept...");
+ SocketChannel clientChannel = ((ServerSocketChannel) key.channel()).accept();
+ if (clientChannel != null) {
+ // could be null in a multithreaded deft environment because another
+ // ioloop was "faster" to accept()
+ clientChannel.configureBlocking(false);
+ ioLoop.addHandler(clientChannel, this, SelectionKey.OP_READ, ByteBuffer.allocate(READ_BUFFER_SIZE));
+ }
+ }
+
+ @Override
+ public void handleConnect(SelectionKey key) throws IOException {
+ logger.error("handle connect in HttpProcotol...");
+ }
+
+ @Override
+ public void handleRead(SelectionKey key) throws IOException {
+ logger.debug("handle read...");
+ SocketChannel clientChannel = (SocketChannel) key.channel();
+ HttpRequest request = getHttpRequest(key, clientChannel);
+
+ if (request.isKeepAlive()) {
+ ioLoop.addKeepAliveTimeout(clientChannel, Timeout.newKeepAliveTimeout(ioLoop, clientChannel,
+ KEEP_ALIVE_TIMEOUT));
+ }
+ HttpResponse response = new HttpResponseImpl(this, key, request.isKeepAlive());
+ RequestHandler rh = application.getHandler(request);
+ HttpRequestDispatcher.dispatch(rh, request, response);
+
+ // Only close if not async. In that case its up to RH to close it (+
+ // don't close if it's a partial request).
+ if (!rh.isMethodAsynchronous(request.getMethod()) && !(request instanceof PartialHttpRequest)) {
+ response.finish();
+ }
+ }
+
+ @Override
+ public void handleWrite(SelectionKey key) {
+ logger.debug("handle write...");
+ SocketChannel channel = (SocketChannel) key.channel();
+
+ if (key.attachment() instanceof MappedByteBuffer) {
+ writeMappedByteBuffer(key, channel);
+ } else if (key.attachment() instanceof DynamicByteBuffer) {
+ writeDynamicByteBuffer(key, channel);
+ }
+ if (ioLoop.hasKeepAliveTimeout(channel)) {
+ prolongKeepAliveTimeout(channel);
+ }
+
+ }
+
+ private void writeMappedByteBuffer(SelectionKey key, SocketChannel channel) {
+ MappedByteBuffer mbb = (MappedByteBuffer) key.attachment();
+ if (mbb.hasRemaining()) {
+ try {
+ channel.write(mbb);
+ } catch (IOException e) {
+ logger.error("Failed to send data to client: {}", e.getMessage());
+ Closeables.closeQuietly(channel);
+ }
+ }
+ if (!mbb.hasRemaining()) {
+ closeOrRegisterForRead(key);
+ }
+ }
+
+ private void writeDynamicByteBuffer(SelectionKey key, SocketChannel channel) {
+ DynamicByteBuffer dbb = (DynamicByteBuffer) key.attachment();
+ logger.debug("pending data about to be written");
+ ByteBuffer toSend = dbb.getByteBuffer();
+ toSend.flip(); // prepare for write
+ long bytesWritten = 0;
+ try {
+ bytesWritten = channel.write(toSend);
+ } catch (IOException e) {
+ logger.error("Failed to send data to client: {}", e.getMessage());
+ Closeables.closeQuietly(channel);
+ }
+ logger.debug("sent {} bytes to wire", bytesWritten);
+ if (!toSend.hasRemaining()) {
+ logger.debug("sent all data in toSend buffer");
+ closeOrRegisterForRead(key); // should probably only be done if the
+ // HttpResponse is finished
+ } else {
+ toSend.compact(); // make room for more data be "read" in
+ }
+ }
+
+ public void closeOrRegisterForRead(SelectionKey key) {
+ if (key.isValid() && ioLoop.hasKeepAliveTimeout(key.channel())) {
+ try {
+ key.channel().register(key.selector(), SelectionKey.OP_READ, reuseAttachment(key));
+ prolongKeepAliveTimeout(key.channel());
+ logger.debug("keep-alive connection. registrating for read.");
+ } catch (ClosedChannelException e) {
+ logger.debug("ClosedChannelException while registrating key for read: {}", e.getMessage());
+ Closeables.closeQuietly(ioLoop, key.channel());
+ }
+ } else {
+ // http request should be finished and no 'keep-alive' => close
+ // connection
+ logger.debug("Closing finished (non keep-alive) http connection");
+ Closeables.closeQuietly(ioLoop, key.channel());
+ }
+ }
+
+ public void prolongKeepAliveTimeout(SelectableChannel channel) {
+ ioLoop.addKeepAliveTimeout(channel, Timeout.newKeepAliveTimeout(ioLoop, channel, KEEP_ALIVE_TIMEOUT));
+ }
+
+ public IOLoop getIOLoop() {
+ return ioLoop;
+ }
+
+ /**
+ * Clears the buffer (prepares for reuse) attached to the given
+ * SelectionKey.
+ *
+ * @return A cleared (position=0, limit=capacity) ByteBuffer which is ready
+ * for new reads
+ */
+ private ByteBuffer reuseAttachment(SelectionKey key) {
+ Object o = key.attachment();
+ ByteBuffer attachment = null;
+ if (o instanceof MappedByteBuffer) {
+ attachment = ByteBuffer.allocate(READ_BUFFER_SIZE);
+ } else if (o instanceof DynamicByteBuffer) {
+ attachment = ((DynamicByteBuffer) o).getByteBuffer();
+ } else {
+ attachment = (ByteBuffer) o;
+ }
+
+ if (attachment.capacity() < READ_BUFFER_SIZE) {
+ attachment = ByteBuffer.allocate(READ_BUFFER_SIZE);
+ }
+ attachment.clear(); // prepare for reuse
+ return attachment;
+ }
+
+ private HttpRequest getHttpRequest(SelectionKey key, SocketChannel clientChannel) {
+ ByteBuffer buffer = (ByteBuffer) key.attachment();
+ try {
+ clientChannel.read(buffer);
+ } catch (IOException e) {
+ logger.warn("Could not read buffer: {}", e.getMessage());
+ Closeables.closeQuietly(ioLoop, clientChannel);
+ }
+ buffer.flip();
+
+ return doGetHttpRequest(key, clientChannel, buffer);
+ }
+
+ private HttpRequest doGetHttpRequest(SelectionKey key, SocketChannel clientChannel, ByteBuffer buffer) {
+ // do we have any unfinished http post requests for this channel?
+ HttpRequestImpl request = null;
+ if (partials.containsKey(clientChannel)) {
+ request = HttpRequestImpl.continueParsing(buffer, partials.get(clientChannel));
+ if (!(request instanceof PartialHttpRequest)) {
+ // received the entire payload/body
+ partials.remove(clientChannel);
+ }
+ } else {
+ request = HttpRequestImpl.of(buffer);
+ if (request instanceof PartialHttpRequest) {
+ partials.put(key.channel(), (PartialHttpRequest) request);
+ }
+ }
+ // set extra request info
+ request.setRemoteHost(clientChannel.socket().getInetAddress());
+ request.setRemotePort(clientChannel.socket().getPort());
+ request.setServerHost(clientChannel.socket().getLocalAddress());
+ request.setServerPort(clientChannel.socket().getLocalPort());
+ return request;
+ }
+
+ @Override
+ public String toString() {
+ return "HttpProtocol";
+ }
}
Modified: incubator/deft/sandbox/src/main/java/org/deftserver/web/http/HttpRequest.java
URL: http://svn.apache.org/viewvc/incubator/deft/sandbox/src/main/java/org/deftserver/web/http/HttpRequest.java?rev=1153593&r1=1153592&r2=1153593&view=diff
==============================================================================
--- incubator/deft/sandbox/src/main/java/org/deftserver/web/http/HttpRequest.java (original)
+++ incubator/deft/sandbox/src/main/java/org/deftserver/web/http/HttpRequest.java Wed Aug 3 17:36:25 2011
@@ -20,319 +20,164 @@
package org.deftserver.web.http;
import java.net.InetAddress;
-import java.nio.ByteBuffer;
import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
import java.util.Map;
-import java.util.regex.Pattern;
-import org.deftserver.io.IOLoop;
-import org.deftserver.util.ArrayUtil;
import org.deftserver.web.HttpVerb;
-import com.google.common.base.Charsets;
-import com.google.common.base.Strings;
-import com.google.common.collect.ImmutableMultimap;
-import com.google.common.collect.Maps;
-
-public class HttpRequest {
-
- private IOLoop ioLoop;
-
- private final String requestLine;
- private final HttpVerb method;
- private final String requestedPath; // correct name?
- private final String version;
- private Map<String, String> headers;
- private ImmutableMultimap<String, String> parameters;
- private String body;
- private boolean keepAlive;
- private InetAddress remoteHost;
- private InetAddress serverHost;
- private int remotePort;
- private int serverPort;
- private Map<String, String> cookies = null;
-
- /** Regex to parse HttpRequest Request Line */
- public static final Pattern REQUEST_LINE_PATTERN = Pattern.compile(" ") ;
- /** Regex to parse out QueryString from HttpRequest */
- public static final Pattern QUERY_STRING_PATTERN = Pattern.compile("\\?") ;
- /** Regex to parse out parameters from query string */
- public static final Pattern PARAM_STRING_PATTERN = Pattern.compile("\\&|;"); //Delimiter is either & or ;
- /** Regex to parse out key/value pairs */
- public static final Pattern KEY_VALUE_PATTERN = Pattern.compile("=");
- /** Regex to parse raw headers and body */
- public static final Pattern RAW_VALUE_PATTERN = Pattern.compile("\\r\\n\\r\\n"); //TODO fix a better regexp for this
- /** Regex to parse raw headers from body */
- public static final Pattern HEADERS_BODY_PATTERN = Pattern.compile("\\r\\n");
- /** Regex to parse header name and value */
- public static final Pattern HEADER_VALUE_PATTERN = Pattern.compile(": ");
- /** Regex to split cookie header following RFC6265 Section 5.4 */
- public static final Pattern COOKIE_SEPARATOR_PATTERN = Pattern.compile(";");
-
- /**
- * Creates a new HttpRequest
- * @param requestLine The Http request text line
- * @param headers The Http request headers
- */
- public HttpRequest(String requestLine, Map<String, String> headers) {
- this.requestLine = requestLine;
- String[] elements = REQUEST_LINE_PATTERN.split(requestLine);
- method = HttpVerb.valueOf(elements[0]);
- String[] pathFrags = QUERY_STRING_PATTERN.split(elements[1]);
- requestedPath = pathFrags[0];
- version = elements[2];
- this.headers = headers;
- body = null;
- initKeepAlive();
- parameters = parseParameters(elements[1]);
- }
-
- /**
- * Creates a new HttpRequest
- * @param requestLine The Http request text line
- * @param headers The Http request headers
- * @param body The Http request posted body
- */
- public HttpRequest(String requestLine, Map<String, String> headers, String body) {
- this(requestLine, headers);
- this.body = body;
- }
-
- public static HttpRequest of(ByteBuffer buffer) {
- try {
- String raw = new String(buffer.array(), 0, buffer.limit(), Charsets.ISO_8859_1);
- String[] headersAndBody = RAW_VALUE_PATTERN.split(raw);
- String[] headerFields = HEADERS_BODY_PATTERN.split(headersAndBody[0]);
- headerFields = ArrayUtil.dropFromEndWhile(headerFields, "");
-
- String requestLine = headerFields[0];
- Map<String, String> generalHeaders = new HashMap<String, String>();
- for (int i = 1; i < headerFields.length; i++) {
- String[] header = HEADER_VALUE_PATTERN.split(headerFields[i]);
- generalHeaders.put(header[0].toLowerCase(), header[1]);
- }
-
- String body = "";
- for (int i = 1; i < headersAndBody.length; ++i) { //First entry contains headers
- body += headersAndBody[i];
- }
-
- if (requestLine.contains("POST")) {
- int contentLength = Integer.parseInt(generalHeaders.get("content-length"));
- if (contentLength > body.length()) {
- return new PartialHttpRequest(requestLine, generalHeaders, body);
- }
- }
- return new HttpRequest(requestLine, generalHeaders, body);
- } catch (Exception t) {
- return MalFormedHttpRequest.instance;
- }
- }
-
- public static HttpRequest continueParsing(ByteBuffer buffer, PartialHttpRequest unfinished) {
- String nextChunk = new String(buffer.array(), 0, buffer.limit(), Charsets.US_ASCII);
- unfinished.appendBody(nextChunk);
-
- int contentLength = Integer.parseInt(unfinished.getHeader("Content-Length"));
- if (contentLength > unfinished.getBody().length()) {
- return unfinished;
- } else {
- return new HttpRequest(unfinished.getRequestLine(), unfinished.getHeaders(), unfinished.getBody());
- }
- }
-
- protected void setIOLoop(IOLoop ioLoop) {
- this.ioLoop = ioLoop;
- }
-
- public IOLoop getIOLoop() {
- return ioLoop;
- }
-
- public String getRequestLine() {
- return requestLine;
- }
-
- public String getRequestedPath() {
- return requestedPath;
- }
-
- public String getVersion() {
- return version;
- }
-
- public Map<String, String> getHeaders() {
- return Collections.unmodifiableMap(headers);
- }
-
- public String getHeader(String name) {
- return headers.get(name.toLowerCase());
- }
-
- public HttpVerb getMethod() {
- return method;
- }
-
- /**
- * Returns the value of a request parameter as a String, or null if the parameter does not exist.
- *
- * You should only use this method when you are sure the parameter has only one value. If the parameter
- * might have more than one value, use getParameterValues(java.lang.String).
- * If you use this method with a multi-valued parameter, the value returned is equal to the first value in
- * the array returned by getParameterValues.
- */
- public String getParameter(String name) {
- Collection<String> values = parameters.get(name);
- return values.isEmpty() ? null : values.iterator().next();
- }
-
- public Map<String, Collection<String>> getParameters() {
- return parameters.asMap();
- }
-
- public String getBody() {
- return body;
- }
-
- public InetAddress getRemoteHost() {
- return remoteHost;
- }
-
- public InetAddress getServerHost() {
- return serverHost;
- }
-
- public int getRemotePort() {
- return remotePort;
- }
-
- public int getServerPort() {
- return serverPort;
- }
-
- protected void setRemoteHost(InetAddress host) {
- remoteHost = host;
- }
-
- protected void setServerHost(InetAddress host) {
- serverHost = host;
- }
-
- protected void setRemotePort(int port) {
- remotePort = port;
- }
-
- protected void setServerPort(int port) {
- serverPort = port;
- }
-
- /**
- * Returns a map with all cookies contained in the request. Cookies are represented as strings,
- * and are parsed at the first invocation of this method
- *
- * @return a map containing all cookies of request
- */
- public Map<String, String> getCookies() {
- if (cookies == null) {
- parseCookies();
- }
- return Collections.unmodifiableMap(cookies);
- }
-
- /**
- * Returns a given cookie. Cookies are represented as strings,
- * and are parsed at the first invocation of this method
- *
- * @param name the name of cookie
- * @return the corresponding cookie, or null if the cookie does not exist
- */
- public String getCookie(String name) {
- if (cookies == null) {
- parseCookies();
- }
- return cookies.get(name);
- }
-
- /**
- * Returns a collection of all values associated with the provided parameter.
- * If no values are found and empty collection is returned.
- */
- public Collection<String> getParameterValues(String name) {
- return parameters.get(name);
- }
-
- public boolean isKeepAlive() {
- return keepAlive;
- }
-
- @Override
- public String toString() {
- String result = "METHOD: " + method + "\n";
- result += "VERSION: " + version + "\n";
- result += "PATH: " + requestedPath + "\n";
-
- result += "--- HEADER --- \n";
- for (String key : headers.keySet()) {
- String value = headers.get(key);
- result += key + ":" + value + "\n";
- }
-
- result += "--- PARAMETERS --- \n";
- for (String key : parameters.keySet()) {
- Collection<String> values = parameters.get(key);
- for (String value : values) {
- result += key + ":" + value + "\n";
- }
- }
- return result;
- }
-
-
-
- private ImmutableMultimap<String, String> parseParameters(String requestLine) {
- ImmutableMultimap.Builder<String, String> builder = ImmutableMultimap.builder();
- String[] str = QUERY_STRING_PATTERN.split(requestLine);
-
- //Parameters exist
- if (str.length > 1) {
- String[] paramArray = PARAM_STRING_PATTERN.split(str[1]);
- for (String keyValue : paramArray) {
- String[] keyValueArray = KEY_VALUE_PATTERN.split(keyValue);
- //We need to check if the parameter has a value associated with it.
- if (keyValueArray.length > 1) {
- builder.put(keyValueArray[0], keyValueArray[1]); //name, value
- }
- }
- }
- return builder.build();
- }
-
- /**
- * Parse the cookie's http header (RFC6265 Section 5.4)
- */
- private void parseCookies() {
- String cookiesHeader = Strings.nullToEmpty(getHeader("Cookie")).trim();
- cookies = Maps.newHashMap();
- if (!cookiesHeader.equals("")) {
- String[] cookiesStrings = COOKIE_SEPARATOR_PATTERN.split(cookiesHeader);
- for (String cookieString : cookiesStrings) {
- String[] cookie = KEY_VALUE_PATTERN.split(cookieString, 2);
- cookies.put(cookie[0].trim(), cookie[1].trim());
- }
- }
- }
-
- private void initKeepAlive() {
- String connection = getHeader("Connection");
- if ("keep-alive".equalsIgnoreCase(connection)) {
- keepAlive = true;
- } else if ("close".equalsIgnoreCase(connection) || requestLine.contains("1.0")) {
- keepAlive = false;
- } else {
- keepAlive = true;
- }
- }
+/**
+ * An HTTP request received from a client
+ */
+public interface HttpRequest {
+
+ /**
+ * Get the HTTP request line for the request.
+ * <p>
+ * Ex :
+ *
+ * <pre>
+ * GET http://www.w3.org/pub/WWW/TheProject.html HTTP/1.1
+ * </pre>
+ *
+ * @return
+ */
+ public String getRequestLine();
+
+ /**
+ * The path of this request
+ * <p>
+ * Ex :
+ *
+ * <pre>
+ * http://www.w3.org/pub/WWW/TheProject.html
+ * </pre>
+ *
+ * @return the path requested
+ */
+ public String getRequestedPath();
+
+ /**
+ * The version of the HTTP protocol.
+ * <p>
+ * Can be <tt>HTTP/1.0</tt> or <tt>HTTP/1.1</tt>.
+ *
+ * @return the HTTP version
+ */
+ public String getVersion();
+
+ /**
+ * Get the read-only header of this request.
+ *
+ * @see HttpRequest#getHeader(String)
+ *
+ * @return the header.
+ */
+ public Map<String, String> getHeaders();
+
+ /**
+ * Get the value of a given HTTP header.
+ *
+ * @see HttpRequest#getHeaders()
+ * @param name the name of the requested header
+ * @return the value or <code>null</code> if the header is not found.
+ */
+ public String getHeader(String name);
+
+ /**
+ * The method (POST,GET ..) used for this request.
+ *
+ * @see HttpVerb
+ *
+ * @return the method
+ */
+ public HttpVerb getMethod();
+
+ /**
+ * Returns the value of a request parameter as a String, or null if the
+ * parameter does not exist.
+ *
+ * You should only use this method when you are sure the parameter has only
+ * one value. If the parameter might have more than one value, use
+ * getParameterValues(java.lang.String). If you use this method with a
+ * multi-valued parameter, the value returned is equal to the first value in
+ * the array returned by getParameterValues.
+ */
+ public String getParameter(String name);
+
+ /**
+ * TODO: JAVADOC, it's unclear to me (jvermillard)
+ *
+ * @return all the request parameters
+ */
+ public Map<String, Collection<String>> getParameters();
+
+ /**
+ * Returns a collection of all values associated with the provided
+ * parameter. If no values are found and empty collection is returned.
+ */
+ public Collection<String> getParameterValues(String name);
+
+ /**
+ * The body of this request
+ *
+ * @return the body as a {@link String}
+ */
+ public String getBody();
+
+ /**
+ * The address of the client which issued this request.
+ *
+ * @return the address
+ */
+ public InetAddress getRemoteHost();
+
+ /**
+ * The TCP port of the client which issued this request.
+ *
+ * @return
+ */
+ public int getRemotePort();
+
+ /**
+ * The address of the server which received this request.
+ *
+ * @return
+ */
+ public InetAddress getServerHost();
+
+ /**
+ * The TCP port of the server which received this request.
+ *
+ * @return
+ */
+ public int getServerPort();
+
+ /**
+ * Returns a map with all cookies contained in the request. Cookies are
+ * represented as strings, and are parsed at the first invocation of this
+ * method
+ *
+ * @return a map containing all cookies of request
+ */
+ public Map<String, String> getCookies();
+
+ /**
+ * Returns a given cookie. Cookies are represented as strings, and are
+ * parsed at the first invocation of this method
+ *
+ * @param name the name of cookie
+ * @return the corresponding cookie, or null if the cookie does not exist
+ */
+ public String getCookie(String name);
+
+ /**
+ * Does keep-alive was requested.
+ *
+ * @see <a
+ * href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec8.html">HTTP/1.1
+ * persistent connections</a>
+ * @return <code>true</code> if keep-alive requested
+ */
+ public boolean isKeepAlive();
}
Modified: incubator/deft/sandbox/src/main/java/org/deftserver/web/http/HttpRequestDispatcher.java
URL: http://svn.apache.org/viewvc/incubator/deft/sandbox/src/main/java/org/deftserver/web/http/HttpRequestDispatcher.java?rev=1153593&r1=1153592&r2=1153593&view=diff
==============================================================================
--- incubator/deft/sandbox/src/main/java/org/deftserver/web/http/HttpRequestDispatcher.java (original)
+++ incubator/deft/sandbox/src/main/java/org/deftserver/web/http/HttpRequestDispatcher.java Wed Aug 3 17:36:25 2011
@@ -26,42 +26,42 @@ import org.slf4j.LoggerFactory;
public class HttpRequestDispatcher {
- private static final Logger logger = LoggerFactory.getLogger(HttpRequestDispatcher.class);
+ private static final Logger logger = LoggerFactory.getLogger(HttpRequestDispatcher.class);
- public static void dispatch(RequestHandler rh, HttpRequest request, HttpResponse response) {
- if (rh != null) {
- HttpVerb method = request.getMethod();
- try {
- switch (method) {
- case GET:
- rh.get(request, response);
- break;
- case POST:
- rh.post(request, response);
- break;
- case HEAD:
- rh.head(request, response);
- break;
- case PUT:
- rh.put(request, response);
- break;
- case DELETE:
- rh.delete(request, response);
- break;
- case OPTIONS: //Fall through
- case TRACE:
- case CONNECT:
- default:
- logger.warn("Unimplemented Http metod received: {}", method);
- //TODO send "not supported page (501) back to client"
- }
- } catch (HttpException he) {
- response.setStatusCode(he.getStatusCode());
- response.write(he.getMessage());
- if (rh.isMethodAsynchronous(request.getMethod())) {
- response.finish();
- }
- }
- }
- }
+ public static void dispatch(RequestHandler rh, HttpRequest request, HttpResponse response) {
+ if (rh != null) {
+ HttpVerb method = request.getMethod();
+ try {
+ switch (method) {
+ case GET:
+ rh.get(request, response);
+ break;
+ case POST:
+ rh.post(request, response);
+ break;
+ case HEAD:
+ rh.head(request, response);
+ break;
+ case PUT:
+ rh.put(request, response);
+ break;
+ case DELETE:
+ rh.delete(request, response);
+ break;
+ case OPTIONS: // Fall through
+ case TRACE:
+ case CONNECT:
+ default:
+ logger.warn("Unimplemented Http metod received: {}", method);
+ // TODO send "not supported page (501) back to client"
+ }
+ } catch (HttpException he) {
+ response.setStatusCode(he.getStatusCode());
+ response.write(he.getMessage());
+ if (rh.isMethodAsynchronous(request.getMethod())) {
+ response.finish();
+ }
+ }
+ }
+ }
}