Bugfixed cookie parsing.
[jsvc.git] / src / dolda / jsvc / util / Cookie.java
index 8783427..b85a7ff 100644 (file)
@@ -6,6 +6,7 @@ import java.text.*;
 import java.io.*;
 
 public class Cookie {
+    private final static Map<Request, MultiMap<String, Cookie>> cache = new WeakHashMap<Request, MultiMap<String, Cookie>>();
     public final static DateFormat datefmt;
     static {
        datefmt = new SimpleDateFormat("EEE, dd-MMM-yyyy HH:mm:ss z", Locale.ENGLISH);
@@ -60,13 +61,14 @@ public class Cookie {
        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"));
@@ -80,6 +82,12 @@ public class Cookie {
                        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));
@@ -88,6 +96,17 @@ public class Cookie {
        return(ret);
     }
     
+    public static MultiMap<String, Cookie> get(Request req) {
+       synchronized(cache) {
+           MultiMap<String, Cookie> ret = cache.get(req);
+           if(ret == null) {
+               ret = parse(req);
+               cache.put(req, ret);
+           }
+           return(ret);
+       }
+    }
+
     public String toString() {
        StringBuilder buf = new StringBuilder();
        buf.append("Cookie(");