Server-side cookie representation.
Allows recycling and uses MessageBytes as low-level
representation ( and thus the byte-> char conversion can be delayed
until we know the charset ).
Tomcat.core uses this recyclable object to represent cookies,
and the facade will convert it to the external representation.
| Method from org.apache.tomcat.util.http.ServerCookie Detail: |
public static boolean alreadyQuoted(String value) {
if (value==null || value.length()==0) return false;
return (value.charAt(0)=='\"" && value.charAt(value.length()-1)=='\"");
}
|
public static void appendCookieValue(StringBuffer headerBuf,
int version,
String name,
String value,
String path,
String domain,
String comment,
int maxAge,
boolean isSecure) {
// TODO RFC2965 fields also need to be passed
StringBuffer buf = new StringBuffer();
// Servlet implementation checks name
buf.append( name );
buf.append("=");
// Servlet implementation does not check anything else
maybeQuote2(version, buf, value);
// Add version 1 specific information
if (version == 1) {
// Version=1 ... required
buf.append ("; Version=1");
// Comment=comment
if ( comment!=null ) {
buf.append ("; Comment=");
maybeQuote2(version, buf, comment);
}
}
// Add domain information, if present
if (domain!=null) {
buf.append("; Domain=");
maybeQuote2(version, buf, domain);
}
// Max-Age=secs ... or use old "Expires" format
// TODO RFC2965 Discard
if (maxAge >= 0) {
if (version == 0) {
// Wdy, DD-Mon-YY HH:MM:SS GMT ( Expires Netscape format )
buf.append ("; Expires=");
// To expire immediately we need to set the time in past
if (maxAge == 0)
buf.append( ancientDate );
else
DateTool.formatOldCookie
(new Date( System.currentTimeMillis() +
maxAge *1000L), buf,
new FieldPosition(0));
} else {
buf.append ("; Max-Age=");
buf.append (maxAge);
}
}
// Path=path
if (path!=null) {
buf.append ("; Path=");
maybeQuote2(version, buf, path);
}
// Secure
if (isSecure) {
buf.append ("; Secure");
}
headerBuf.append(buf);
}
|
public static boolean checkName(String name) {
if (!isToken(name)
|| name.equalsIgnoreCase("Comment") // rfc2019
|| name.equalsIgnoreCase("Discard") // rfc2965
|| name.equalsIgnoreCase("Domain") // rfc2019
|| name.equalsIgnoreCase("Expires") // Netscape
|| name.equalsIgnoreCase("Max-Age") // rfc2019
|| name.equalsIgnoreCase("Path") // rfc2019
|| name.equalsIgnoreCase("Secure") // rfc2019
|| name.equalsIgnoreCase("Version") // rfc2019
// TODO remaining RFC2965 attributes
) {
return false;
}
return true;
} Deprecated! - - Not used
|
public static boolean containsCTL(String value,
int version) {
if( value==null) return false;
int len = value.length();
for (int i = 0; i < len; i++) {
char c = value.charAt(i);
if (c < 0x20 || c >= 0x7f) {
if (c == 0x09)
continue; //allow horizontal tabs
return true;
}
}
return false;
}
|
public MessageBytes getComment() {
return comment;
}
|
public String getCookieHeaderName() {
return getCookieHeaderName(version);
}
Return the header name to set the cookie, based on cookie version. |
public static String getCookieHeaderName(int version) {
// TODO Re-enable logging when RFC2965 is implemented
// log( (version==1) ? "Set-Cookie2" : "Set-Cookie");
if (version == 1) {
// XXX RFC2965 not referenced in Servlet Spec
// Set-Cookie2 is not supported by Netscape 4, 6, IE 3, 5
// Set-Cookie2 is supported by Lynx and Opera
// Need to check on later IE and FF releases but for now...
// RFC2109
return "Set-Cookie";
// return "Set-Cookie2";
} else {
// Old Netscape
return "Set-Cookie";
}
}
Return the header name to set the cookie, based on cookie version. |
public MessageBytes getDomain() {
return domain;
}
|
public int getMaxAge() {
return maxAge;
}
|
public MessageBytes getName() {
return name;
}
|
public MessageBytes getPath() {
return path;
}
|
public boolean getSecure() {
return secure;
}
|
public MessageBytes getValue() {
return value;
}
|
public int getVersion() {
return version;
}
|
public static boolean isToken(String value) {
/*
* Tests a string and returns true if the string counts as a
* reserved token in the Java language.
*
* @param value the < code >String< /code > to be tested
*
* @return < code >true< /code > if the < code >String< /code > is a reserved
* token; < code >false< /code > if it is not
*/
if( value==null) return true;
int len = value.length();
for (int i = 0; i < len; i++) {
char c = value.charAt(i);
if (tspecials.indexOf(c) != -1)
return false;
}
return true;
}
|
public static boolean isToken2(String value) {
if( value==null) return true;
int len = value.length();
for (int i = 0; i < len; i++) {
char c = value.charAt(i);
if (tspecials2.indexOf(c) != -1)
return false;
}
return true;
}
|
public static void maybeQuote(int version,
StringBuffer buf,
String value) {
// special case - a \n or \r shouldn't happen in any case
if (isToken(value)) {
buf.append(value);
} else {
buf.append('"");
buf.append(escapeDoubleQuotes(value,0,value.length()));
buf.append('"");
}
} Deprecated! - - Not used
|
public static void maybeQuote2(int version,
StringBuffer buf,
String value) {
if (value==null || value.length()==0) {
buf.append("\"\"");
}else if (containsCTL(value,version))
throw new IllegalArgumentException("Control character in cookie value, consider BASE64 encoding your value");
else if (alreadyQuoted(value)) {
buf.append('"");
buf.append(escapeDoubleQuotes(value,1,value.length()-1));
buf.append('"");
} else if (version==0 && !isToken(value)) {
buf.append('"");
buf.append(escapeDoubleQuotes(value,0,value.length()));
buf.append('"");
} else if (version==1 && !isToken2(value)) {
buf.append('"");
buf.append(escapeDoubleQuotes(value,0,value.length()));
buf.append('"");
}else {
buf.append(value);
}
}
Quotes values using rules that vary depending on Cookie version. |
public void recycle() {
path.recycle();
name.recycle();
value.recycle();
comment.recycle();
maxAge=-1;
path.recycle();
domain.recycle();
version=0;
secure=false;
}
|
public void setMaxAge(int expiry) {
maxAge = expiry;
}
|
public void setSecure(boolean flag) {
secure = flag;
}
|
public void setVersion(int v) {
version = v;
}
|
public String toString() {
return "Cookie " + getName() + "=" + getValue() + " ; "
+ getVersion() + " " + getPath() + " " + getDomain();
}
|
public static void unescapeDoubleQuotes(ByteChunk bc) {
if (bc == null || bc.getLength() == 0 || bc.indexOf('"", 0) == -1) {
return;
}
int src = bc.getStart();
int end = bc.getEnd();
int dest = src;
byte[] buffer = bc.getBuffer();
while (src < end) {
if (buffer[src] == '\\" && src < end && buffer[src+1] == '"") {
src++;
}
buffer[dest] = buffer[src];
dest ++;
src ++;
}
bc.setEnd(dest);
}
Unescapes any double quotes in the given cookie value. |