📄 cachefilter.java
字号:
synchronized(this) { size += ce.getSize() ; CacheEntry old = (CacheEntry) entries.put(ce.getURL(),ce) ; if(old!=null) lruList.remove(old) ; lruList.toHead(ce) ; } } /** * Retrieves a CacheEntry corresponding to the request. * Should mark it as MRU */ public CacheEntry retrieve(Request request) { String url = getNormalizedURL(request) ; CacheEntry ce = (CacheEntry) entries.get(url) ; return ce==null ? null : ce ; } /** * Removes the CacheEntry corresponding to the request. */ public synchronized void remove(Request request) { System.out.println("**** Removing from cache") ; CacheEntry ce = (CacheEntry) entries.remove(getNormalizedURL(request)) ; if(ce == null) return ; lruList.remove(ce) ; } /** * Gets rid of the LRU element */ private synchronized final boolean flushLRU() { if(entries.size() == 0) return false ; CacheEntry ce = (CacheEntry) lruList.removeTail() ; entries.remove(ce.getURL()) ; size -= ce.getSize() ; return true ; } /** This might be unnecessary */ static String getNormalizedURL(Request request) { String nurl = (String) request.getState(STATE_NORM_URL) ; if(nurl!=null) return nurl ; URL url = request.getURL() ; nurl = url.getFile() ; request.setState(STATE_NORM_URL,nurl) ; return nurl ; }}public class CacheFilter extends ResourceFilter { protected Cache cache = null ; protected final static String STATE_TAG = "org.w3c.jigsaw.filters.CacheFilter.tag" ; protected static int ATTR_MAX_SIZE = -1 ; protected static int ATTR_MAX_ENTRIES = -1 ; protected static int ATTR_DEFAULT_MAX_AGE = -1 ; static { Attribute a = null; Class cls = null; try { cls = Class.forName("org.w3c.jigsaw.filters.CacheFilter"); } catch (Exception ex) { ex.printStackTrace(); System.exit(1); } // Declare the maximum cache size attribute: a = new IntegerAttribute("maxSize" , new Integer(8192) , Attribute.EDITABLE); ATTR_MAX_SIZE= AttributeRegistry.registerAttribute(cls, a); // Declare the maximum number of entries attribute: a = new IntegerAttribute("maxEntries" , new Integer(-1) , Attribute.EDITABLE); ATTR_MAX_ENTRIES = AttributeRegistry.registerAttribute(cls, a); // Declare the default maxage attribute a = new IntegerAttribute("defaultMaxAge" , new Integer(300) // 5min , Attribute.EDITABLE); ATTR_DEFAULT_MAX_AGE = AttributeRegistry.registerAttribute(cls, a); } public int getMaxSize() { return ((Integer) getValue(ATTR_MAX_SIZE, new Integer(-1))).intValue() ; } public int getMaxEntries() { return ((Integer) getValue(ATTR_MAX_ENTRIES, new Integer(-1))).intValue() ; } public int getDefaultMaxAge() { return ((Integer) getValue(ATTR_DEFAULT_MAX_AGE, new Integer(300))) .intValue() ; } private final void tag(Request request) { request.setState(STATE_TAG,Boolean.TRUE) ; } private final boolean isTagged(Request request) { return request.hasState(STATE_TAG) ; } private Reply applyIn(Request request, FilterInterface[] filters, int fidx) throws ProtocolException { // Apply remaining ingoing filters Reply fr = null ; for(int i = fidx+1 ; i<filters.length && filters[i] != null ; ++i) { fr = (Reply) (filters[i].ingoingFilter(request, filters, i)) ; if(fr != null) return fr ; } return null ; } private Reply applyOut(Request request, Reply reply, FilterInterface[] filters, int fidx) throws ProtocolException { Reply fr = null ; for(int i=fidx-1; i>=0 && filters[i] != null; i--) { fr = (Reply) (filters[i].outgoingFilter(request,reply,filters,i)) ; if(fr != null) return fr ; } return null ; } private final Reply applyOut(Request request, Reply reply, FilterInterface[] filters ) throws ProtocolException { return applyOut(request,reply,filters,filters.length) ; } private void makeInconditional(Request request) { request.setHeaderValue(request.H_IF_MATCH, null) ; request.setHeaderValue(request.H_IF_MODIFIED_SINCE, null) ; request.setHeaderValue(request.H_IF_NONE_MATCH, null) ; request.setHeaderValue(request.H_IF_RANGE, null) ; request.setHeaderValue(request.H_IF_UNMODIFIED_SINCE, null) ; } /** * @return A Reply instance, if the filter did know how to answer * the request without further processing, <strong>null</strong> * otherwise. * @exception ProtocolException * If processing should be interrupted, * because an abnormal situation occured. */ public ReplyInterface ingoingFilter(RequestInterface req, FilterInterface[] filters, int fidx) throws ProtocolException { Request request = (Request) req; if(cache == null) cache = new Cache(getMaxSize(), getMaxEntries(), getDefaultMaxAge()) ; String method = request.getMethod() ; if(! ( method.equals("HEAD") || method.equals("GET") ) ) return null ; // Enforce write-through tag(request) ; if(isCachable(request)) { CacheEntry cachEnt = cache.retrieve(request) ; if(cachEnt != null) { System.out.println("**** Examining entry: "+cachEnt) ; Reply fRep = null ; if( cachEnt.isFresh(request) ) { fRep = applyIn(request,filters,fidx) ; if(fRep != null) return fRep ; // Get the reply (adjusting age too) [?] Reply reply = cachEnt.getReply(request) ; fRep = applyOut(request,reply,filters) ; if(fRep != null) return fRep ; System.out.println("**** Replying from cache") ; return reply ; } else { cachEnt.makeConditional(request) ; return null ; } } else { System.out.println("**** Not in cache") ; } } else { System.out.println("**** Request not cachable") ; } makeInconditional(request) ; return null ; } /** * @param request The original request. * @param reply It's original reply. * @return A Reply instance, or <strong>null</strong> if processing * should continue normally. * @exception ProtocolException If processing should be interrupted * because an abnormal situation occured. */ public ReplyInterface outgoingFilter(RequestInterface req, ReplyInterface rep, FilterInterface[] filters, int fidx) throws ProtocolException { Request request = (Request) req; Reply reply = (Reply) rep; // Be transparent if request is not "ours" if(!isTagged(request)) return null ; if(isCachable(reply)) { switch(reply.getStatus()) { case HTTP.OK: case HTTP.NO_CONTENT: case HTTP.MULTIPLE_CHOICE: case HTTP.MOVED_PERMANENTLY: // Store the reply and let it through try { cache.store(request,reply) ; } catch(CacheException ex) { // not much to do... } finally { return null ; } case HTTP.NOT_MODIFIED: // This means we're validating CacheEntry cachEnt = cache.retrieve(request) ; if(cachEnt != null) reply = cachEnt.getReply(request,reply) ; break ; default: cache.remove(request) ; return null ; } } else { System.out.println("**** Reply not cachable") ; cache.remove(request) ; } // Apply remaining filters and return modified reply Reply fRep = applyOut(request,reply,filters,fidx) ; if(fRep != null) return fRep ; else return reply ; } /** * Does this request permit caching? * (It's still half-baked) */ private boolean isCachable(Request request) { if(request.checkNoStore()) return false ; String[] nc = request.getNoCache() ; if(nc != null) return false ; // for now return true ; } /** * Does this reply permit caching? * (It's still half-baked) */ private boolean isCachable(Reply reply) { if(reply.checkNoStore() || reply.getPrivate() != null) return false ; return true ; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -