pushcachefilter.java
来自「很棒的web服务器源代码」· Java 代码 · 共 317 行
JAVA
317 行
// PushCacheFilter.java// $Id: PushCacheFilter.java,v 1.1 2001/10/03 15:00:46 ylafon Exp $// (c) COPYRIGHT MIT, INRIA and Keio, 2001.// Please first read the full copyright statement in file COPYRIGHT.htmlpackage org.w3c.www.protocol.http.cache.push;import java.net.URL;import org.w3c.www.http.HTTP;import org.w3c.www.protocol.http.Reply;import org.w3c.www.protocol.http.Request;import org.w3c.www.protocol.http.HttpException;import org.w3c.www.protocol.http.HttpManager;import org.w3c.www.protocol.http.PropRequestFilterException;import org.w3c.www.protocol.http.cache.CacheFilter;import org.w3c.www.protocol.http.cache.CacheSweeper;import org.w3c.www.protocol.http.cache.CachedResource;import org.w3c.www.protocol.http.cache.EntityCachedResource;import org.w3c.www.protocol.http.cache.InvalidCacheException;import org.w3c.www.protocol.http.cache.CacheState;import org.w3c.www.protocol.http.cache.CacheValidator;import org.w3c.www.protocol.http.cache.CacheSerializer;import org.w3c.www.protocol.http.cache.ActiveStream;/** * PushCacheFilter * Based heavily on (much code stolen from) CacheFilter * The important differences are in the initialization where the * PushCacheListener is started, and in ingoingFilter where if * the requested resource is present in the cache and is a PUSH * resource, then the resource is returned immediately without * checking for expiry etc. This allows us to insert pages from * "virtual" web sites such as http://www.push.data/sensor1.html * * @author Paul Henshaw, The Fantastic Corporation, Paul.Henshaw@fantastic.com * @version $Revision: 1.1 $ * $Id: PushCacheFilter.java,v 1.1 2001/10/03 15:00:46 ylafon Exp $ */public class PushCacheFilter extends CacheFilter { /** * Property name used to acquire port number for {@link PushCacheListener} * value is "org.w3c.www.protocol.http.cache.push.portnumber"; */ public static final String PORT_NUM_P = "org.w3c.www.protocol.http.cache.push.portnumber"; /** * Default port number to use if property value is not supplied * value is 9876 */ public static final int DEFAULT_PORT_NUM=9876; /** * Access to PushCacheStore */ public PushCacheStore getPushCacheStore() { return((PushCacheStore)super.getStore()); } /** * check if we can use the cache or not for this request * It marks the request as being not cachable if false. * @param a request, the incoming client-side request * @return a boolean, true if we can use the cache */ public boolean canUseCache(Request req) { return true; } /** * The request pre-processing hook. * Before each request is launched, all filters will be called back through * this method. They will generally set up additional request header * fields to enhance the request. * @param request The request that is about to be launched. * @return An instance of Reply if the filter could handle the request, * or <strong>null</strong> if processing should continue normally. * @exception HttpException If the filter is supposed to fulfill the * request, but some error happened during that processing. */ public Reply ingoingFilter(Request request) throws HttpException { // can we use the cache? if (!canUseCache(request)) { if (debug) { trace(request, "*** Can't use cache"); } // we will invalidate this resource, will do that only // on real entity resource, not on negotiated ones if (connected) { CachedResource res = null; EntityCachedResource invalidRes = null; try { String requrl = request.getURL().toExternalForm(); res = store.getCachedResourceReference(requrl); if (res != null) { invalidRes = (EntityCachedResource) res.lookupResource(request); } } catch (InvalidCacheException ex) { invalidRes = null; } if (invalidRes != null) { invalidRes.setWillRevalidate(true); } request.setState(STATE_NOCACHE, Boolean.TRUE); return null; } else { // disconnected, abort now! Reply reply = request.makeReply(HTTP.GATEWAY_TIMEOUT); reply.setContent("The cache cannot be use for " + "<p><code>"+request.getMethod()+"</code> " + "<strong>"+request.getURL()+"</strong>" + ". <p>It is disconnected."); return reply; } } // let's try to get the resource! String requrl = request.getURL().toExternalForm(); // in the pre-cache, wait for full download // FIXME should be better than this behaviour... // see EntityCachedResource perform's FIXME ;) if (precache.containsKey(requrl)) { if (debug) System.out.println("*** Already downloading: "+ requrl); try { CachedResource cr = (CachedResource)precache.get(requrl); return cr.perform(request); } catch (Exception ex) { // there was a problem with the previous request, // it may be better to do it by ourself } } CachedResource res = null; try { res = store.getCachedResourceReference(requrl); } catch (InvalidCacheException ex) { res = null; } // Is this a push resource ? try { if(PushCacheManager.instance().isPushResource(res)) { EntityCachedResource ecr=(EntityCachedResource) res.lookupResource(request); if(ecr!=null) { Reply reply = ecr.perform(request); return reply; } } } catch(Exception e) { e.printStackTrace(); } // /PSLH // are we disconnected? if (request.checkOnlyIfCached() || !connected ) { // and no entries... EntityCachedResource ecr = null; if (res != null) { ecr = (EntityCachedResource) res.lookupResource(request); } if ((res == null) || (ecr == null)) { if ( debug ) trace(request, "unavailable (disconnected)."); Reply reply = request.makeReply(HTTP.GATEWAY_TIMEOUT); reply.setContent("The cache doesn't have an entry for " + "<p><strong>"+request.getURL()+"</strong>" + ". <p>And it is disconnected."); return reply; } // yeah! if (debug) { trace(request, (connected) ? " hit - only if cached" : " hit while disconneced" ); } if (!validator.isValid(ecr, request)) { addWarning(request, WARN_STALE); } addWarning(request, WARN_DISCONNECTED); Reply reply = ecr.perform(request); // Add any warnings collected during processing to the reply: setWarnings(request, reply);//FIXME request.setState(STATE_HOW, HOW_HIT); return reply; } // in connected mode, we should now take care of revalidation and such if (res != null) { // if not fully loaded, ask for a revalidation FIXME if ((res.getLoadState() == CachedResource.STATE_LOAD_PARTIAL) || (res.getLoadState() == CachedResource.STATE_LOAD_ERROR)) { setRequestRevalidation(res, request); return null; } if ( validator.isValid(res, request) ) { try { store.updateResourceGeneration(res); } catch (InvalidCacheException ex) { // should be ok so... }//FIXME request.setState(STATE_HOW, HOW_HIT); Reply rep = res.perform(request); return rep; } else { if (debug) { System.out.println("*** Revalidation asked for " + requrl); } // ask for a revalidation setRequestRevalidation(res, request); return null; } } // lock here while we are waiting for the download while (uritable.containsKey(requrl)) { synchronized (uritable) { try { uritable.wait(); } catch (InterruptedException ex) {} } if (precache.containsKey(requrl)) { if (debug) System.out.println("*** Already downloading: "+ requrl); CachedResource cr = (CachedResource)precache.get(requrl); return cr.perform(request); } uritable.put(requrl, requrl); } return null; } /** * Almost identical to CacheFilter.initialize, but creates a * PushCacheStore instead of a CacheStore and additionaly * starts the PushCacheListener */ public void initialize(HttpManager manager) throws PropRequestFilterException { try { String validator_c; String sweeper_c; String serializer_c; props = manager.getProperties(); shared = props.getBoolean(SHARED_P, false); connected = props.getBoolean(CACHE_CONNECTED_P, true); debug = props.getBoolean(DEBUG_P, false); // now create the add-on classes validator_c = props.getString(VALIDATOR_P, "org.w3c.www.protocol.http.cache.SimpleCacheValidator"); sweeper_c = props.getString(SWEEPER_P, "org.w3c.www.protocol.http.cache.SimpleCacheSweeper"); serializer_c = props.getString(SERIALIZER_P, "org.w3c.www.protocol.http.cache.SimpleCacheSerializer"); try { Class c; c = Class.forName(validator_c); validator = (CacheValidator) c.newInstance(); validator.initialize(this); c = Class.forName(sweeper_c); sweeper = (CacheSweeper) c.newInstance(); sweeper.initialize(this); c = Class.forName(serializer_c); serializer = (CacheSerializer) c.newInstance(); } catch (Exception ex) { // a fatal error! The cache won't be loaded... ex.printStackTrace(); throw new PropRequestFilterException("Unable to start cache"); } // now create the store as we have the basic things here store = new PushCacheStore(); try { store.initialize(this); } catch (InvalidCacheException ex) { // hum no worky, should do some action there! if (debug) { ex.printStackTrace(); } } // now start the sweeper sweeper.start(); // Start the ActiveStream handler: ActiveStream.initialize(); // Register for property changes: props.registerObserver(this); // Now, we are ready, register that filter: manager.setFilter(this); // // Create and start a PushCacheListener // int portNum=props.getInteger(PORT_NUM_P,DEFAULT_PORT_NUM); PushCacheListener listener=new PushCacheListener(portNum); listener.start(); // // Register this filter with the PushCacheManager // PushCacheManager.instance().registerFilter(this); } catch(Exception e) { e.printStackTrace(); } }}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?