in api_dev/src/main/java/com/google/appengine/tools/util/ClientCookie.java [355:480]
private static List<ClientCookie> parseSetCookie1(String setCookie1Header,
URL url)
throws HttpHeaderParseException {
final HttpHeaderParser parser = new HttpHeaderParser(setCookie1Header);
final ArrayList<ClientCookie> results = new ArrayList<ClientCookie>();
parser.eatLWS();
while (true) {
// read name=value
final ClientCookie cookie = new ClientCookie();
cookie.effectiveVersion_ = 1;
cookie.name_ = parser.eatToken();
parser.eatLWS();
parser.eatChar('=');
parser.eatLWS();
cookie.value_ = parser.eatTokenOrQuotedString();
parser.eatLWS();
// read cookie attributes
while (parser.peek() == ';') {
parser.eatChar(';');
parser.eatLWS();
final String name = parser.eatToken().toLowerCase();
parser.eatLWS();
if (name.equals("secure")) {
cookie.secure_ = true;
} else if (name.equals("httponly")) {
cookie.httponly_ = true;
} else {
parser.eatChar('=');
parser.eatLWS();
final String value = parser.eatTokenOrQuotedString();
if (name.equals("comment")) {
cookie.comment_ = value;
} else if (name.equals("domain")) {
cookie.domain_ = value.toLowerCase();
} else if (name.equals("max-age")) {
final int maxAge;
try {
maxAge = Integer.parseInt(value);
if (maxAge < 0) {
throw new NumberFormatException(value);
}
} catch (NumberFormatException e) {
throw new HttpHeaderParseException("invalid max-age: " +
setCookie1Header);
}
cookie.expires_ = System.currentTimeMillis() + 1000 * maxAge;
} else if (name.equals("path")) {
cookie.path_ = value;
} else if (name.equals("version")) {
try {
cookie.version_ = Integer.parseInt(value);
if (cookie.version_ <= 0) {
throw new NumberFormatException(value);
}
} catch (NumberFormatException e) {
throw new HttpHeaderParseException("invalid version: " +
setCookie1Header);
}
} else if (name.equals("expires")) {
throw new HttpHeaderParseException("this is a v0 cookie");
} else {
logger.info("unrecognized v1 cookie attribute: " +
name + "=" + value);
}
}
parser.eatLWS();
}
// validate the cookie - see RFC 2109 sec. 4.3.1, 4.3.2
boolean valid = true;
final String requestHost = url.getHost().toLowerCase();
final String requestPath = url.getPath();
if (cookie.domain_ == null) {
cookie.effectiveDomain_ = requestHost;
} else {
if (!cookie.domain_.startsWith(".") ||
cookie.domain_.substring(1, cookie.domain_.length() - 1)
.indexOf('.') < 0) {
logger.info("rejecting v1 cookie [bad domain - no periods]: " +
setCookie1Header);
valid = false;
} else if (!requestHost.endsWith(cookie.domain_)) {
logger.info("rejecting v1 cookie [bad domain - no match]: " +
setCookie1Header);
valid = false;
} else if (requestHost
.substring(0, requestHost.length() - cookie.domain_.length())
.indexOf('.') >= 0) {
logger.info("rejecting v1 cookie [bad domain - extra periods]: " +
setCookie1Header);
valid = false;
} else {
cookie.effectiveDomain_ = cookie.domain_;
}
}
if (cookie.path_ == null) {
int index = requestPath.lastIndexOf('/');
if (index < 0) {
cookie.effectivePath_ = requestPath;
} else {
// trailing slash not included
cookie.effectivePath_ = requestPath.substring(0, index);
}
} else {
if (!requestPath.startsWith(cookie.path_)) {
logger.info("rejecting v1 cookie [bad path]: " +
setCookie1Header);
valid = false;
} else {
cookie.effectivePath_ = cookie.path_;
}
}
if (valid) {
results.add(cookie);
}
// on to next cookie
if (!parser.isEnd()) {
parser.eatChar(',');
} else {
break;
}
}
return results;
}