[Checkins] SVN: zope.publisher/branches/achapman-lenient-cookie-parsing/src/zope/publisher/ - lenient cookie

Alex Chapman achapman at zope.com
Tue Dec 13 22:23:15 UTC 2011


Log message for revision 123810:
   - lenient cookie
  

Changed:
  U   zope.publisher/branches/achapman-lenient-cookie-parsing/src/zope/publisher/http.py
  U   zope.publisher/branches/achapman-lenient-cookie-parsing/src/zope/publisher/tests/test_http.py

-=-
Modified: zope.publisher/branches/achapman-lenient-cookie-parsing/src/zope/publisher/http.py
===================================================================
--- zope.publisher/branches/achapman-lenient-cookie-parsing/src/zope/publisher/http.py	2011-12-13 22:21:39 UTC (rev 123809)
+++ zope.publisher/branches/achapman-lenient-cookie-parsing/src/zope/publisher/http.py	2011-12-13 22:23:14 UTC (rev 123810)
@@ -152,6 +152,49 @@
 init_status_codes()
 
 
+class LenientCookie(Cookie.SimpleCookie):
+    """LenientCookie will not destroy all cookies
+       in a request when one invalid key is used
+    """
+
+    def __setitem__(self, key, value):
+        rval, cval = self.value_encode(value)
+        try:
+            self._BaseCookie__set(key, rval, cval)
+        except Cookie.CookieError, e:
+            eventlog.warning(e)
+
+    def _BaseCookie__ParseString(self, str, patt=Cookie._CookiePattern):
+        i = 0            # Our starting point
+        n = len(str)     # Length of string
+        M = None         # current morsel
+    
+        while 0 <= i < n:
+            # Start looking for a cookie
+            match = patt.search(str, i)
+            if not match: break          # No more cookies
+    
+            K,V = match.group("key"), match.group("val")
+            i = match.end(0)
+    
+            # Parse the key, value in case it's metainfo
+            if K[0] == "$":
+                # We ignore attributes which pertain to the cookie
+                # mechanism as a whole.  See RFC 2109.
+                # (Does anyone care?)
+                if M:
+                    M[ K[1:] ] = V
+            elif K.lower() in Cookie.Morsel._reserved:
+                if M:
+                    M[ K ] = _unquote(V)
+            else:
+                rval, cval = self.value_decode(V)
+                try:
+                    self._BaseCookie__set(K, rval, cval)
+                except Cookie.CookieError, e:
+                    eventlog.warning(e)
+        
+
 class URLGetter(object):
 
     __slots__ = "__request"
@@ -401,7 +444,7 @@
 
         # ignore cookies on a CookieError
         try:
-            c = Cookie.SimpleCookie(text)
+            c = LenientCookie(text)
         except Cookie.CookieError, e:
             eventlog.warn(e)
             return result
@@ -900,7 +943,7 @@
 
     def _cookie_list(self):
         try:
-            c = Cookie.SimpleCookie()
+            c = LenientCookie()
         except Cookie.CookieError, e:
             eventlog.warn(e)
             return []

Modified: zope.publisher/branches/achapman-lenient-cookie-parsing/src/zope/publisher/tests/test_http.py
===================================================================
--- zope.publisher/branches/achapman-lenient-cookie-parsing/src/zope/publisher/tests/test_http.py	2011-12-13 22:21:39 UTC (rev 123809)
+++ zope.publisher/branches/achapman-lenient-cookie-parsing/src/zope/publisher/tests/test_http.py	2011-12-13 22:23:14 UTC (rev 123810)
@@ -461,17 +461,18 @@
         self.failIf(req.cookies.has_key('path'))
 
     def testCookieErrorToLog(self):
+        # Cookies accompanying an invalid one shouldn't be trashed.
         cookies = {
             'HTTP_COOKIE':
                 'foo=bar; path=/; spam="eggs", ldap/OU="Williams"'
         }
         req = self._createRequest(extra_env=cookies)
 
-        self.failIf(req.cookies.has_key('foo'))
-        self.failIf(req.has_key('foo'))
+        self.assertEquals(req.cookies[u'foo'], u'bar')
+        self.assertEquals(req[u'foo'], u'bar')
 
-        self.failIf(req.cookies.has_key('spam'))
-        self.failIf(req.has_key('spam'))
+        self.assertEquals(req.cookies[u'spam'], u'eggs')
+        self.assertEquals(req[u'spam'], u'eggs')
 
         self.failIf(req.cookies.has_key('ldap/OU'))
         self.failIf(req.has_key('ldap/OU'))
@@ -862,12 +863,6 @@
         self.failUnless((r'sign="\342\230\243";' in c) or
                         (r'sign="\342\230\243"' in c))
 
-        self.assertRaises(
-                CookieError,
-                self._getCookieFromResponse,
-                [('path', 'invalid key', {}),]
-                )
-
         c = self._getCookieFromResponse([
                 ('foo', 'bar', {
                     'Expires': 'Sat, 12 Jul 2014 23:26:28 GMT',



More information about the checkins mailing list