Mercurial Hosting > nabble
diff src/cachingfilter/CachingRequestWrapper.java @ 0:7ecd1a4ef557
add content
author | Franklin Schmidt <fschmidt@gmail.com> |
---|---|
date | Thu, 21 Mar 2019 19:15:52 -0600 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/cachingfilter/CachingRequestWrapper.java Thu Mar 21 19:15:52 2019 -0600 @@ -0,0 +1,119 @@ +package cachingfilter; + +import java.io.IOException; +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.Enumeration; +import java.util.TimeZone; +import java.util.Date; +import java.util.Locale; +import java.util.Map; +import java.util.HashMap; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletRequestWrapper; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.eclipse.jetty.server.AbstractHttpConnection; + + +final class CachingRequestWrapper extends HttpServletRequestWrapper { + private static final Logger logger = LoggerFactory.getLogger(CachingRequestWrapper.class); + + static final String IF_MODIFIED_SINCE = "If-Modified-Since".toLowerCase(); + static final String IF_NONE_MATCH = "If-None-Match".toLowerCase(); + static final String ACCEPT_ENCODING = "Accept-Encoding".toLowerCase(); + + final Map<String,Object> headerMap = new HashMap<String,Object>(); + + CachingRequestWrapper(HttpServletRequest request) throws IOException { + super(request); + checkRequest(request); + } + + private static void checkRequest(HttpServletRequest request) throws IOException { + AbstractHttpConnection c = ((org.eclipse.jetty.server.Request) request).getConnection(); + if (c.getRequestFields().containsKey("Host")) { + for (Enumeration<String> e2 = c.getRequestFields().getValues("Host"); e2.hasMoreElements();) { + if (e2.nextElement().trim().endsWith(":")) { + throw new IOException("Bad 'Host' request header (ends with colon)"); + } + } + } + } + + public String getHeader(String name) { +/* + String v = getHeader2(name); + logger.trace("getHeader "+name+" = "+v); + return v; + } + public String getHeader2(String name) { +*/ + String key = name.toLowerCase(); + if( headerMap.containsKey(key) ) { + Object val = headerMap.get(key); + if( val instanceof Long ) { + long date = (Long)val; + if( date == -1 ) + return null; + return formatDate(date); + } + return (String)val; + } + return super.getHeader(name); + } + + public long getDateHeader(String name) { +/* + long v = getDateHeader2(name); + logger.trace("getDateHeader "+name+" = "+v); + return v; + } + public long getDateHeader2(String name) { +*/ + String key = name.toLowerCase(); + if( headerMap.containsKey(key) ) + return (Long)headerMap.get(key); + return super.getDateHeader(name); + } + + boolean isCacheable() { + boolean isCacheable = false; + Long val = (Long)headerMap.get(IF_MODIFIED_SINCE); + if( val!=null ) { + try { + long cachedLastModified = val; + if( cachedLastModified != -1 ) { + long ifModifiedSince = super.getDateHeader(IF_MODIFIED_SINCE); + //logger.trace("cachedLastModified = "+cachedLastModified+" ifModifiedSince = "+ifModifiedSince); + if( cachedLastModified > ifModifiedSince ) + return false; + isCacheable = true; + } + } catch(IllegalArgumentException e) { + logger.warn("bad date, user-agent="+getHeader("user-agent"),e); + } + } + String etag = (String)headerMap.get(IF_NONE_MATCH); + if( etag != null ) { + String ifNoneMatch = super.getHeader(IF_NONE_MATCH); + if( !etag.equals(ifNoneMatch) ) + return false; + isCacheable = true; + } + return isCacheable; + } + + + private static ThreadLocal<DateFormat> dateFormat = new ThreadLocal<DateFormat>() { + protected synchronized DateFormat initialValue() { + DateFormat httpDateFormat = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss z", Locale.US); + httpDateFormat.setTimeZone(TimeZone.getTimeZone("GMT")); + return httpDateFormat; + } + }; + + private String formatDate(long date) { + return dateFormat.get().format(new Date(date)); + } +}