httpcachecontrol.java

来自「很棒的web服务器源代码」· Java 代码 · 共 835 行 · 第 1/2 页

JAVA
835
字号
// HttpCacheControl.java// $Id: HttpCacheControl.java,v 1.22 2003/02/24 14:25:19 ylafon Exp $// (c) COPYRIGHT MIT and INRIA, 1996.// Please first read the full copyright statement in file COPYRIGHT.htmlpackage org.w3c.www.http;import java.util.Enumeration;import java.util.Vector;/** * The parsed cache-control directive of HTTP/1.1 * This object gives access to the parsed value of the cache-control * directive of HTTP/1.1, as defined in section 14.9 of the specification. */public class HttpCacheControl extends BasicValue {    private static final String EMPTY_LIST[] = { };    private String  nocache[] = null ;    private boolean nostore  = false;    private int     maxage   = -1;    private int     maxstale = -1;    private int     minfresh = -1;    private boolean onlyifcached = false;    private boolean pub = false ;    private String  priv[] = null ;    private boolean notransform = false;    private boolean mustrevalidate = false;    private boolean proxyrevalidate = false;    private int     s_maxage = -1;    private Vector  extensions = null;    private static final int NOCACHE = (1<<0);    private static final int NOSTORE = (1<<1);    private static final int MAXAGE  = (1<<2);    private static final int MINVERS = (1<<3);    private static final int ONLYIFCACHED = (1<<4);    private static final int PUB = (1<<5);    private static final int PRIV = (1<<6);    private static final int NOTRANSFORM = (1<<7);    private static final int MUSTREVALIDATE = (1<<8);    private static final int PROXYREVALIDATE = (1<<9);    private static final int MAXSTALE = (1<<10);    private static final int MINFRESH = (1<<11);    private static final int S_MAXAGE = (1<<12);    private int defined = 0 ;    /**     * Check if the given field has been explictly set.     * @param id The field identifier.     * @return A boolean.     */    private final boolean checkDirective(int id) {	return (defined & id) != 0;    }    /**     * Mark the given field as being set.     * @param id The field identifier.     */    private final void setDirective(int id) {	defined |= id;    }    /**     * Mark the given field as being unset.     * @param id The field identifier.     */    private final void unsetDirective(int id) {	defined &= (~id);    }    /**     * Recompute the byte value for this header.     */    protected void updateByteValue() {	// Dump the value, using my own version of the StringBuffer:	HttpBuffer buf = new HttpBuffer();	boolean    cnt = false;	if (checkDirective(NOCACHE)) {	    if ( nocache != null )		buf.appendQuoted("no-cache", (byte) '=', nocache);	    else		buf.append("no-cache");	    cnt = true;	}	if(checkDirective(NOSTORE) && nostore) {	    buf.append("no-store");	    cnt = true;	}	if (checkDirective(MAXAGE) && (maxage >= 0)) {	    if ( cnt )		buf.append(',');	    buf.append("max-age", (byte) '=', maxage);	    cnt = true;	}	if (checkDirective(ONLYIFCACHED) && onlyifcached) {	    if ( cnt )		buf.append(',');	    buf.append("only-if-cached");	    cnt = true;	}	if (checkDirective(PUB) && pub) {	    if ( cnt )		buf.append(',');	    buf.append("public");	    cnt = true;	}	if (checkDirective(PRIV) && (priv != null)) {	    if ( cnt )		buf.append(',');	    buf.appendQuoted("private", (byte) '=', priv);	    cnt = true;	}	if (checkDirective(NOTRANSFORM) && notransform) {	    if ( cnt )		buf.append(',');	    buf.append("no-transform");	    cnt = true;	}	if (checkDirective(MUSTREVALIDATE) && mustrevalidate) { 	    if ( cnt )		buf.append(',');	    buf.append("must-revalidate");	    cnt = true;	}	if (checkDirective(PROXYREVALIDATE) && proxyrevalidate) {	    if ( cnt )		buf.append(',');	    buf.append("proxy-revalidate");	    cnt = true;	}	if (checkDirective(MAXSTALE) && (maxstale >= 0)) {	    if ( cnt )		buf.append(',');	    buf.append("max-stale", (byte) '=', maxstale);	    cnt = true;	}	if (checkDirective(MINFRESH) && (minfresh >= 0)) {	    if ( cnt )		buf.append(',');	    buf.append("min-fresh", (byte) '=', minfresh);	    cnt = true;	}	if (checkDirective(S_MAXAGE) && (s_maxage >= 0)) {	    if ( cnt )		buf.append(',');	    buf.append("s_maxage", (byte) '=', s_maxage);	    cnt = true;	}	if (extensions != null) {	    Enumeration e = extensions.elements();	    while (e.hasMoreElements()) {		if (cnt) {		    buf.append(',');		    cnt = true;		}		buf.append((String) e.nextElement());	    }	}	// Keep track of the string, for potential reuse:	raw  = buf.getByteCopy();	roff = 0;	rlen = raw.length;    }    // Efficient regular expression is what I would do in C    private static byte bnocache[] = { 	(byte) 'n', (byte) 'o', (byte) '-', (byte) 'c', 	(byte) 'a', (byte) 'c', (byte) 'h', (byte) 'e'     } ;    private static byte bnostore[] = {	(byte) 'n', (byte) 'o', (byte) '-', (byte) 's',	(byte) 't', (byte) 'o', (byte) 'r', (byte) 'e'    };    private static final byte bmaxage[] = {	(byte) 'm', (byte) 'a', (byte) 'x', (byte) '-',	(byte) 'a', (byte) 'g', (byte) 'e'    };    private static final byte bs_maxage[] = {	(byte) 's', (byte) '-', (byte) 'm', (byte) 'a',	(byte) 'x', (byte) 'a', (byte) 'g', (byte) 'e'    };    private static final byte bmaxstale[] = {	(byte) 'm', (byte) 'a', (byte) 'x', (byte) '-', 	(byte) 's', (byte) 't', (byte) 'a', (byte) 'l',	(byte) 'e'    };    private static final byte bminfresh[] = {	(byte) 'm', (byte) 'i', (byte) 'n', (byte) '-',	(byte) 'f', (byte) 'r', (byte) 'e', (byte) 's',	(byte) 'h'    };    private static final byte bonlyifcached[] = {	(byte) 'o', (byte) 'n', (byte) 'l', (byte) 'y', 	(byte) '-', (byte) 'i', (byte) 'f', (byte) '-', 	(byte) 'c', (byte) 'a', (byte) 'c', (byte) 'h', 	(byte) 'e', (byte) 'd'    };    private static final byte bpublic[] = {	(byte) 'p', (byte) 'u', (byte) 'b', (byte) 'l',	(byte) 'i', (byte) 'c',     };    private static final byte bprivate[] = {	(byte) 'p', (byte) 'r', (byte) 'i', (byte) 'v',	(byte) 'a', (byte) 't', (byte) 'e'    };    private static final byte bnotransform[] = {	(byte) 'n', (byte) 'o', (byte) '-', (byte) 't',	(byte) 'r', (byte) 'a', (byte) 'n', (byte) 's',	(byte) 'f', (byte) 'o', (byte) 'r', (byte) 'm'     };    private static final byte bmustrevalidate[] = {	(byte) 'm', (byte) 'u', (byte) 's', (byte) 't',	(byte) '-', (byte) 'r', (byte) 'e', (byte) 'v', 	(byte) 'a', (byte) 'l', (byte) 'i', (byte) 'd', 	(byte) 'a', (byte) 't', (byte) 'e'    };    private static final byte bproxyrevalidate[] = {	(byte) 'p', (byte) 'r', (byte) 'o', (byte) 'x',	(byte) 'y', (byte) '-', (byte) 'r', (byte) 'e',	(byte) 'v', (byte) 'a', (byte) 'l', (byte) 'i', 	(byte) 'd', (byte) 'a', (byte) 't', (byte) 'e'    };    // Parse a valued-directive    private final void parseDirective(int ds, int de, ParseState pval)	throws HttpParserException    {	if (HttpParser.compare(raw, ds, de, bmaxage) == 0) {	    pval.ioff   = pval.start;	    pval.bufend = pval.end;	    maxage = HttpParser.parseInt(raw, pval);	    setDirective(MAXAGE);	} else if (HttpParser.compare(raw, ds, de, bmaxstale) == 0) {	    pval.ioff   = pval.start;	    pval.bufend = pval.end;	    maxstale = HttpParser.parseInt(raw, pval);	    setDirective(MAXSTALE);	} else if (HttpParser.compare(raw, ds, de, bminfresh) == 0) {	    pval.ioff   = pval.start;	    pval.bufend = pval.end;	    minfresh = HttpParser.parseInt(raw, pval);	    setDirective(MINFRESH);	} else if (HttpParser.compare(raw, ds, de, bs_maxage) == 0) {	    pval.ioff   = pval.start;	    pval.bufend = pval.end;	    s_maxage = HttpParser.parseInt(raw, pval);	    setDirective(S_MAXAGE);	} else if (HttpParser.compare(raw, ds, de, bnocache) == 0) {	    Vector fields = new Vector(8);	    ParseState sp = new ParseState();	    sp.ioff       = pval.start;	    sp.bufend     = pval.end;	    HttpParser.unquote(raw, sp);	    while (HttpParser.nextItem(raw, sp) >= 0) {		fields.addElement(new String(raw,0,sp.start,sp.end-sp.start));		sp.prepare();	    }	    if (nocache == null) {		nocache = new String[fields.size()];		fields.copyInto(nocache);	    } else {		int num = fields.size();		String t_nocache[] = new String[nocache.length+num];		System.arraycopy(nocache, 0, t_nocache, 0, nocache.length);		for (int i=0; i< num; i++) {		    t_nocache[nocache.length+i] = (String) fields.elementAt(i);		}		nocache = t_nocache;	    }	    setDirective(NOCACHE);	} else if (HttpParser.compare(raw, ds, de, bprivate) == 0) {	    Vector fields = new Vector(8);	    ParseState sp = new ParseState();	    sp.ioff   = pval.start;	    sp.bufend = pval.end;	    HttpParser.unquote(raw, sp);	    while (HttpParser.nextItem(raw, sp) >= 0) {		fields.addElement(new String(raw,0,sp.start,sp.end-sp.start));		sp.prepare();	    }	    if (priv == null) {		priv = new String[fields.size()];		fields.copyInto(priv);	    } else {		int num = fields.size();		String t_priv[] = new String[priv.length+num];		System.arraycopy(priv, 0, t_priv, 0, priv.length);		for (int i=0; i< num; i++) {		    t_priv[priv.length+i] = (String) fields.elementAt(i);		}		priv = t_priv;	    }	    setDirective(PRIV);	} else {	    if (extensions == null) {		extensions = new Vector(4);		extensions.add(new String(raw,0,ds,de-ds));	    }//	    error("Unknown directive "+new String(raw, 0, ds, de-ds));	}    }    // Parse a boolean directive    private final void parseDirective(int ds, int de)	throws HttpParserException    {	if (HttpParser.compare(raw, ds, de, bnocache) == 0) {	    setDirective(NOCACHE);	    nocache = EMPTY_LIST;	} else if (HttpParser.compare(raw, ds, de, bnostore) == 0) {	    setDirective(NOSTORE);	    nostore = true;	} else if (HttpParser.compare(raw, ds, de, bonlyifcached) == 0) {	    setDirective(ONLYIFCACHED);	    onlyifcached = true;	} else if (HttpParser.compare(raw, ds, de, bpublic) == 0) {	    setDirective(PUB);	    pub = true;	} else if (HttpParser.compare(raw, ds, de, bprivate) == 0) {	    setDirective(PRIV);	    priv = EMPTY_LIST;	} else if (HttpParser.compare(raw, ds, de, bnotransform) == 0) {	    setDirective(NOTRANSFORM);	    notransform = true;	} else if (HttpParser.compare(raw, ds, de, bmustrevalidate) == 0) {	    setDirective(MUSTREVALIDATE);	    mustrevalidate = true;	} else if (HttpParser.compare(raw, ds, de, bproxyrevalidate) == 0) {	    setDirective(PROXYREVALIDATE);	    proxyrevalidate = true;	} else {	    if (extensions == null) {		extensions = new Vector(4);		extensions.add(new String(raw,0,ds,de-ds));	    }//	    error("Unknown or invalid directive: "+new String(raw,0,ds,de));	}    }    /**     * parse.     * @exception HttpParserException if parsing failed.     */    protected void parse() 	throws HttpParserException    {	// Parse the raw value, this is the right time to do it:	ParseState ls = new ParseState(0);	ls.ioff       = 0;	ls.bufend     = raw.length;	ls.separator  = (byte) ',';	ls.spaceIsSep = false; // gift for broken implementations	ParseState ld = new ParseState(0);	ld.separator  = (byte) '=';	ld.spaceIsSep = false; // gift for broken implementations//	HttpParser.unquote(raw, ls); 	while (HttpParser.nextItem(raw, ls) >= 0) {	    ld.bufend = ls.end;	    ld.ioff   = ls.start;	    if ( HttpParser.nextItem(raw, ld) >= 0 ) {		int dstart = ld.start;		int dend   = ld.end;		ld.prepare();		if ( HttpParser.nextItem(raw, ld) >= 0 )		    parseDirective(dstart, dend, ld);		else		    parseDirective(dstart, dend);	    } else {		parseDirective(ls.start, ls.end);	    }	    ls.prepare();	}    }	    /**     * HeaderValue implementation - Get this header value.     * @return Itself !     */    public Object getValue() {	validate();	return this;    }    /**     * Get and test the no-cache directive setting.     * @return A field-list as an array of String, or <strong>null</strong>     * if the directive is undefined.     */    public String[] getNoCache() {	validate();	return checkDirective(NOCACHE) ? nocache : null;    }    /**     * Set the no cache directive to the given list of fields.     * @param fields The fields to set in the no-cache directive, encoded     * as a String array (whose length can be <strong>0</strong>), or     * <strong>null</strong> to reset the value.     */    public void setNoCache(String fields[]) {	validate();	if ( fields == null ) {	    if ( checkDirective(NOCACHE) )		invalidateByteValue();	    unsetDirective(NOCACHE) ;	} else {

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?