MultiMap<String, Cookie> ret = new WrappedMultiMap<String, Cookie>(new TreeMap<String, Collection<Cookie>>());
for(String in : req.inheaders().values("Cookie")) {
try {
- StringReader r = new StringReader(in);
+ PushbackReader r = new PushbackReader(new StringReader(in));
Cookie c = null;
while(true) {
String k = Http.tokenunquote(r);
+ Misc.eatws(r);
+ if((k == null) || (r.read() != '='))
+ throw(new Http.EncodingException("Illegal cookie header format"));
String v = Http.tokenunquote(r);
- if(k == null)
- break;
if(k.equals("$Version")) {
if(Integer.parseInt(v) != 1)
throw(new Http.EncodingException("Unknown cookie format version"));
c = new Cookie(k, v);
ret.add(k, c);
}
+ Misc.eatws(r);
+ int sep = r.read();
+ if(sep < 0)
+ break;
+ if(sep != ';')
+ throw(new Http.EncodingException("Illegal cookie header format"));
}
} catch(IOException e) {
throw(new Error(e));
return(buf.toString());
}
- public static String tokenunquote(Reader in) throws IOException {
+ public static String tokenunquote(PushbackReader in) throws IOException {
StringBuilder buf = new StringBuilder();
String st = "eatws";
int c = in.read();
else
st = "token";
} else if(st == "token") {
- if((c < 0) || Character.isWhitespace((char)c) || (tspecials.indexOf((char)c) >= 0)) {
+ if(c == '"') {
+ st = "quoted";
+ c = in.read();
+ } else if((c < 0) || Character.isWhitespace((char)c) || (tspecials.indexOf((char)c) >= 0)) {
+ if(c >= 0)
+ in.unread(c);
if(buf.length() == 0)
return(null);
return(buf.toString());
} else if((c < 32) || (c >= 127)) {
throw(new EncodingException("Invalid characters in header"));
- } else if(c == '"') {
- st = "quoted";
- c = in.read();
} else {
buf.append((char)c);
c = in.read();
return(false);
throw(new IllegalArgumentException("value not recognized as boolean: " + val));
}
+
+ public static void eatws(PushbackReader in) throws IOException {
+ int c;
+ do {
+ c = in.read();
+ if(c < 0)
+ return;
+ } while(Character.isWhitespace(c));
+ in.unread(c);
+ }
}