Skip to content

Commit

Permalink
refactored how Request-objects is created
Browse files Browse the repository at this point in the history
  • Loading branch information
mbknor committed Mar 22, 2011
1 parent 7c62d20 commit 56bd129
Show file tree
Hide file tree
Showing 4 changed files with 236 additions and 108 deletions.
100 changes: 98 additions & 2 deletions framework/src/play/mvc/Http.java
Original file line number Diff line number Diff line change
Expand Up @@ -205,11 +205,11 @@ public static class Request implements Serializable {
/**
* HTTP Headers
*/
public Map<String, Http.Header> headers = new HashMap<String, Http.Header>(16);
public Map<String, Http.Header> headers = null;
/**
* HTTP Cookies
*/
public Map<String, Http.Cookie> cookies = new HashMap<String, Http.Cookie>(16);
public Map<String, Http.Cookie> cookies = null;
/**
* Body stream
*/
Expand Down Expand Up @@ -271,7 +271,103 @@ public static class Request implements Serializable {
*/
public final Scope.Params params = new Scope.Params();


/**
* Deprecate the default constructor to encourage the use of createRequest() when creating new
* requests.
*
* Cannot hide it with protected because we have to be backward compatible with modules - ie PlayGrizzlyAdapter.java
*/
@Deprecated
public Request() {
headers = new HashMap<String, Http.Header>(16);
cookies = new HashMap<String, Http.Cookie>(16);
}

/**
* All creation / initing of new requests should use this method.
* The purpose of this is to "show" what is needed when creating new Requests.
* @return the newly created Request object
*/
public static Request createRequest(
String _remoteAddress,
String _method,
String _path,
String _querystring,
String _contentType,
InputStream _body,
String _url,
String _host,
boolean _isLoopback,
int _port,
String _domain,
boolean _secure,
Map<String, Http.Header> _headers,
Map<String, Http.Cookie> _cookies
) {
Request newRequest = new Request();

newRequest.remoteAddress = _remoteAddress;
newRequest.method = _method;
newRequest.path = _path;
newRequest.querystring = _querystring;
newRequest.contentType = _contentType;
newRequest.body = _body;
newRequest.url = _url;
newRequest.host = _host;
newRequest.isLoopback = _isLoopback;
newRequest.port = _port;
newRequest.domain = _domain;
newRequest.secure = _secure;

if(_headers == null) {
_headers = new HashMap<String, Http.Header>(16);
}
newRequest.headers = _headers;

if(_cookies == null) {
_cookies = new HashMap<String, Http.Cookie>(16);
}
newRequest.cookies = _cookies;

newRequest.parseXForwarded();

newRequest.resolveFormat();

newRequest.authorizationInit();

return newRequest;
}

protected void parseXForwarded() {

if (Play.configuration.containsKey("XForwardedSupport") && headers.get("X-Forwarded-For") != null) {
if (!Arrays.asList(Play.configuration.getProperty("XForwardedSupport", "127.0.0.1").split(",")).contains(remoteAddress)) {
throw new RuntimeException("This proxy request is not authorized: " + remoteAddress);
} else {
secure = ("https".equals(Play.configuration.get("XForwardedProto")) || "https".equals(headers.get("X-Forwarded-Proto").value()) || "on".equals(headers.get("X-Forwarded-Ssl").value()));
if (Play.configuration.containsKey("XForwardedHost")) {
host = (String) Play.configuration.get("XForwardedHost");
} else if (headers.get("X-Forwarded-Host") != null) {
host = headers.get("X-Forwarded-Host").value();
}
if (headers.get("X-Forwarded-For") != null) {
remoteAddress = headers.get("X-Forwarded-For").value();
}
}
}

}

/**
* Deprecated to encourage users to use createRequest() instead.
*/
@Deprecated
public void _init() {
authorizationInit();
}

protected void authorizationInit() {
Header header = headers.get("authorization");
if (header != null && header.value().startsWith("Basic ")) {
String data = header.value().substring(6);
Expand Down
115 changes: 60 additions & 55 deletions framework/src/play/server/PlayHandler.java
Original file line number Diff line number Diff line change
Expand Up @@ -486,120 +486,125 @@ public Request parseRequest(ChannelHandlerContext ctx, HttpRequest nettyRequest)
querystring = uri.substring(index + 1);
}

final Request request = new Request();

request.remoteAddress = getRemoteIPAddress(ctx);
request.method = nettyRequest.getMethod().getName();
request.path = path;
request.querystring = querystring;
final String contentType = nettyRequest.getHeader(CONTENT_TYPE);
if (contentType != null) {
request.contentType = contentType.split(";")[0].trim().toLowerCase();
String remoteAddress = getRemoteIPAddress(ctx);
String method = nettyRequest.getMethod().getName();
final String nettyContentType = nettyRequest.getHeader(CONTENT_TYPE);
String contentType = null;
if (nettyContentType != null) {
contentType = nettyContentType.split(";")[0].trim().toLowerCase();
} else {
request.contentType = "text/html";
contentType = "text/html";
}

if (nettyRequest.getHeader("X-HTTP-Method-Override") != null) {
request.method = nettyRequest.getHeader("X-HTTP-Method-Override").intern();
method = nettyRequest.getHeader("X-HTTP-Method-Override").intern();
}

InputStream body = null;
ChannelBuffer b = nettyRequest.getContent();
if (b instanceof FileChannelBuffer) {
FileChannelBuffer buffer = (FileChannelBuffer) b;
// An error occurred
Integer max = Integer.valueOf(Play.configuration.getProperty("play.netty.maxContentLength", "-1"));

request.body = buffer.getInputStream();
if (!(max == -1 || request.body.available() < max)) {
request.body = new ByteArrayInputStream(new byte[0]);
body = buffer.getInputStream();
if (!(max == -1 || body.available() < max)) {
body = new ByteArrayInputStream(new byte[0]);
}

} else {
ByteArrayOutputStream out = new ByteArrayOutputStream();
IOUtils.copy(new ChannelBufferInputStream(b), out);
byte[] n = out.toByteArray();
request.body = new ByteArrayInputStream(n);
body = new ByteArrayInputStream(n);
}

request.url = uri;
request.host = nettyRequest.getHeader(HOST);
String host = nettyRequest.getHeader(HOST);
boolean isLoopback = false;
try {
request.isLoopback = ((InetSocketAddress) ctx.getChannel().getRemoteAddress()).getAddress().isLoopbackAddress() && request.host.matches("^127\\.0\\.0\\.1:?[0-9]*$");
isLoopback = ((InetSocketAddress) ctx.getChannel().getRemoteAddress()).getAddress().isLoopbackAddress() && host.matches("^127\\.0\\.0\\.1:?[0-9]*$");
} catch(Exception e) {
// ignore it
}

if (request.host == null) {
request.host = "";
request.port = 80;
request.domain = "";
int port = 0;
String domain = null;
if (host == null) {
host = "";
port = 80;
domain = "";
} else {
if (request.host.contains(":")) {
final String[] host = request.host.split(":");
request.port = Integer.parseInt(host[1]);
request.domain = host[0];
if (host.contains(":")) {
final String[] hosts = host.split(":");
port = Integer.parseInt(hosts[1]);
domain = hosts[0];
} else {
request.port = 80;
request.domain = request.host;
}
}

if (Play.configuration.containsKey("XForwardedSupport") && nettyRequest.getHeader("X-Forwarded-For") != null) {
if (!Arrays.asList(Play.configuration.getProperty("XForwardedSupport", "127.0.0.1").split(",")).contains(request.remoteAddress)) {
throw new RuntimeException("This proxy request is not authorized: " + request.remoteAddress);
} else {
request.secure = ("https".equals(Play.configuration.get("XForwardedProto")) || "https".equals(nettyRequest.getHeader("X-Forwarded-Proto")) || "on".equals(nettyRequest.getHeader("X-Forwarded-Ssl")));
if (Play.configuration.containsKey("XForwardedHost")) {
request.host = (String) Play.configuration.get("XForwardedHost");
} else if (nettyRequest.getHeader("X-Forwarded-Host") != null) {
request.host = nettyRequest.getHeader("X-Forwarded-Host");
}
if (nettyRequest.getHeader("X-Forwarded-For") != null) {
request.remoteAddress = nettyRequest.getHeader("X-Forwarded-For");
}
port = 80;
domain = host;
}
}

boolean secure = false;

final Request request = Request.createRequest(
remoteAddress,
method,
path,
querystring,
contentType,
body,
uri,
host,
isLoopback,
port,
domain,
secure,
getHeaders(nettyRequest),
getCookies(nettyRequest));

addToRequest(nettyRequest, request);

request.resolveFormat();

request._init();

Logger.trace("parseRequest: end");
return request;
}

protected static void addToRequest(HttpRequest nettyRequest, Request request) {
protected static Map<String, Http.Header> getHeaders(HttpRequest nettyRequest) {
Map<String, Http.Header> headers = new HashMap<String, Http.Header>(16);

for (String key : nettyRequest.getHeaderNames()) {
Http.Header hd = new Http.Header();
hd.name = key.toLowerCase();
hd.values = new ArrayList<String>();
for (String next : nettyRequest.getHeaders(key)) {
hd.values.add(next);
}
request.headers.put(hd.name, hd);
headers.put(hd.name, hd);
}

return headers;
}

protected static Map<String, Http.Cookie> getCookies(HttpRequest nettyRequest) {
Map<String, Http.Cookie> cookies = new HashMap<String, Http.Cookie>(16);
String value = nettyRequest.getHeader(COOKIE);
if (value != null) {
Set<Cookie> cookies = new CookieDecoder().decode(value);
if (cookies != null) {
for (Cookie cookie : cookies) {
Set<Cookie> cookieSet = new CookieDecoder().decode(value);
if (cookieSet != null) {
for (Cookie cookie : cookieSet) {
Http.Cookie playCookie = new Http.Cookie();
playCookie.name = cookie.getName();
playCookie.path = cookie.getPath();
playCookie.domain = cookie.getDomain();
playCookie.secure = cookie.isSecure();
playCookie.value = cookie.getValue();
playCookie.httpOnly = cookie.isHttpOnly();
request.cookies.put(playCookie.name, playCookie);
cookies.put(playCookie.name, playCookie);
}
}
}
return cookies;
}


@Override
public void exceptionCaught(ChannelHandlerContext ctx, ExceptionEvent e) throws Exception {
try {
Expand Down
Loading

0 comments on commit 56bd129

Please sign in to comment.