Moving ETags a layer higher (to make it faster and do no File operations).

This commit is contained in:
marcins78@gmail.com
2013-01-12 13:29:53 +00:00
parent 2d572571b7
commit 1ef011e66d
3 changed files with 37 additions and 35 deletions

View File

@@ -32,12 +32,10 @@ public class LotroHttpRequestHandler extends SimpleChannelUpstreamHandler {
private Map<Type, Object> _objects;
private UriRequestHandler _uriRequestHandler;
private String _uniqueEtag;
public LotroHttpRequestHandler(Map<Type, Object> objects, UriRequestHandler uriRequestHandler) {
_objects = objects;
_uriRequestHandler = uriRequestHandler;
_uniqueEtag = "\"" + String.valueOf(System.currentTimeMillis()) + "\"";
}
@Override
@@ -90,8 +88,8 @@ public class LotroHttpRequestHandler extends SimpleChannelUpstreamHandler {
}
@Override
public void writeFile(File file) {
writeFileResponse(request, file, e);
public void writeFile(File file, Map<String, String> headers) {
writeFileResponse(request, file, headers, e);
}
};
@@ -107,7 +105,7 @@ public class LotroHttpRequestHandler extends SimpleChannelUpstreamHandler {
private Map<String, byte[]> _fileCache = Collections.synchronizedMap(new HashMap<String, byte[]>());
private void writeFileResponse(HttpRequest request, File file, MessageEvent e) {
private void writeFileResponse(HttpRequest request, File file, Map<String, String> headers, MessageEvent e) {
try {
String canonicalPath = file.getCanonicalPath();
byte[] fileBytes = _fileCache.get(canonicalPath);
@@ -128,39 +126,21 @@ public class LotroHttpRequestHandler extends SimpleChannelUpstreamHandler {
}
}
if (clientHasCurrentVersion(request)) {
Map<String, String> headers = new HashMap<String, String>();
headers.put(ETAG, _uniqueEtag);
writeHttpErrorResponse(request, 304, headers, e);
} else {
writeHttpByteResponse(request, fileBytes, getHeadersForFile(file), e);
}
writeHttpByteResponse(request, fileBytes, getHeadersForFile(headers, file), e);
} catch (IOException exp) {
writeHttpErrorResponse(request, 500, null, e);
}
}
private boolean clientHasCurrentVersion(HttpRequest request) {
String ifNoneMatch = request.getHeader(IF_NONE_MATCH);
if (ifNoneMatch != null) {
String[] clientKnownVersions = ifNoneMatch.split(",");
for (String clientKnownVersion : clientKnownVersions) {
if (clientKnownVersion.trim().equals(_uniqueEtag))
return true;
}
}
return false;
}
private Map<String, String> getHeadersForFile(File file) {
Map<String, String> headers = new HashMap<String, String>();
private Map<String, String> getHeadersForFile(Map<String, String> headers, File file) {
Map<String, String> fileHeaders = new HashMap<String, String>(headers);
String fileName = file.getName();
String contentType;
if (fileName.endsWith(".html")) {
headers.put(CACHE_CONTROL, "no-cache");
headers.put(PRAGMA, "no-cache");
headers.put(EXPIRES, String.valueOf(-1));
fileHeaders.put(CACHE_CONTROL, "no-cache");
fileHeaders.put(PRAGMA, "no-cache");
fileHeaders.put(EXPIRES, String.valueOf(-1));
contentType = "text/html; charset=UTF-8";
} else if (fileName.endsWith(".js")) {
contentType = "application/javascript; charset=UTF-8";
@@ -177,9 +157,8 @@ public class LotroHttpRequestHandler extends SimpleChannelUpstreamHandler {
} else {
contentType = "application/octet-stream";
}
headers.put(CONTENT_TYPE, contentType);
headers.put(ETAG, _uniqueEtag);
return headers;
fileHeaders.put(CONTENT_TYPE, contentType);
return fileHeaders;
}
private void writeHttpErrorResponse(HttpRequest request, int status, Map<String, String> headers, MessageEvent e) {

View File

@@ -9,7 +9,7 @@ public interface ResponseWriter {
public void writeError(int status);
public void writeError(int status, Map<String, String> headers);
public void writeFile(File file);
public void writeFile(File file, Map<String, String> headers);
public void writeHtmlResponse(String html);

View File

@@ -2,21 +2,31 @@ package com.gempukku.lotro.async.handler;
import com.gempukku.lotro.async.ResponseWriter;
import org.jboss.netty.channel.MessageEvent;
import org.jboss.netty.handler.codec.http.HttpHeaders;
import static org.jboss.netty.handler.codec.http.HttpHeaders.Names.IF_NONE_MATCH;
import org.jboss.netty.handler.codec.http.HttpRequest;
import java.io.File;
import java.lang.reflect.Type;
import java.util.Collections;
import java.util.Map;
public class WebRequestHandler implements UriRequestHandler {
private String _root;
private String _uniqueEtag;
public WebRequestHandler(String root) {
_root = root;
_uniqueEtag = "\"" + String.valueOf(System.currentTimeMillis()) + "\"";
}
@Override
public void handleRequest(String uri, HttpRequest request, Map<Type, Object> context, ResponseWriter responseWriter, MessageEvent e) throws Exception {
if (clientHasCurrentVersion(request)) {
responseWriter.writeError(304);
return;
}
if (uri.equals(""))
uri = "index.html";
@@ -30,8 +40,21 @@ public class WebRequestHandler implements UriRequestHandler {
File file = new File(_root + uri);
if (!file.getCanonicalPath().startsWith(_root))
responseWriter.writeError(403);
else
responseWriter.writeFile(file);
else {
responseWriter.writeFile(file, Collections.singletonMap(HttpHeaders.Names.ETAG, _uniqueEtag));
}
}
}
private boolean clientHasCurrentVersion(HttpRequest request) {
String ifNoneMatch = request.getHeader(IF_NONE_MATCH);
if (ifNoneMatch != null) {
String[] clientKnownVersions = ifNoneMatch.split(",");
for (String clientKnownVersion : clientKnownVersions) {
if (clientKnownVersion.trim().equals(_uniqueEtag))
return true;
}
}
return false;
}
}