]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
patch #848017: make Cookie more RFC-compliant.
authorGeorg Brandl <georg@python.org>
Wed, 24 Aug 2005 22:34:21 +0000 (22:34 +0000)
committerGeorg Brandl <georg@python.org>
Wed, 24 Aug 2005 22:34:21 +0000 (22:34 +0000)
Doc/lib/libcookie.tex
Lib/Cookie.py
Misc/NEWS

index bba9c79ed9335964ec3475dff6716eb9910df987..39b9cb4ebce3fc86593718af10e65b35b973726d 100644 (file)
@@ -98,7 +98,9 @@ In general, it should be the case that \method{value_encode()} and
 Return a string representation suitable to be sent as HTTP headers.
 \var{attrs} and \var{header} are sent to each \class{Morsel}'s
 \method{output()} method. \var{sep} is used to join the headers
-together, and is by default a newline.
+together, and is by default the combination '\r\n' (CRLF).
+\versionchanged[The default separator has been changed from '\n' to match the cookie
+specification]{2.5}
 \end{methoddesc}
 
 \begin{methoddesc}[BaseCookie]{js_output}{\optional{attrs}}
@@ -195,32 +197,32 @@ The following example demonstrates how to use the \module{Cookie} module.
 >>> C["fig"] = "newton"
 >>> C["sugar"] = "wafer"
 >>> print C # generate HTTP headers
-Set-Cookie: sugar=wafer;
-Set-Cookie: fig=newton;
+Set-Cookie: sugar=wafer
+Set-Cookie: fig=newton
 >>> print C.output() # same thing
-Set-Cookie: sugar=wafer;
-Set-Cookie: fig=newton;
+Set-Cookie: sugar=wafer
+Set-Cookie: fig=newton
 >>> C = Cookie.SmartCookie()
 >>> C["rocky"] = "road"
 >>> C["rocky"]["path"] = "/cookie"
 >>> print C.output(header="Cookie:")
-Cookie: rocky=road; Path=/cookie;
+Cookie: rocky=road; Path=/cookie
 >>> print C.output(attrs=[], header="Cookie:")
-Cookie: rocky=road;
+Cookie: rocky=road
 >>> C = Cookie.SmartCookie()
 >>> C.load("chips=ahoy; vienna=finger") # load from a string (HTTP header)
 >>> print C
-Set-Cookie: vienna=finger;
-Set-Cookie: chips=ahoy;
+Set-Cookie: vienna=finger
+Set-Cookie: chips=ahoy
 >>> C = Cookie.SmartCookie()
 >>> C.load('keebler="E=everybody; L=\\"Loves\\"; fudge=\\012;";')
 >>> print C
-Set-Cookie: keebler="E=everybody; L=\"Loves\"; fudge=\012;";
+Set-Cookie: keebler="E=everybody; L=\"Loves\"; fudge=\012;"
 >>> C = Cookie.SmartCookie()
 >>> C["oreo"] = "doublestuff"
 >>> C["oreo"]["path"] = "/"
 >>> print C
-Set-Cookie: oreo=doublestuff; Path=/;
+Set-Cookie: oreo=doublestuff; Path=/
 >>> C = Cookie.SmartCookie()
 >>> C["twix"] = "none for you"
 >>> C["twix"].value
@@ -233,8 +235,8 @@ Set-Cookie: oreo=doublestuff; Path=/;
 >>> C["string"].value
 'seven'
 >>> print C
-Set-Cookie: number=7;
-Set-Cookie: string=seven;
+Set-Cookie: number=7
+Set-Cookie: string=seven
 >>> C = Cookie.SerialCookie()
 >>> C["number"] = 7
 >>> C["string"] = "seven"
@@ -243,8 +245,8 @@ Set-Cookie: string=seven;
 >>> C["string"].value
 'seven'
 >>> print C
-Set-Cookie: number="I7\012.";
-Set-Cookie: string="S'seven'\012p1\012.";
+Set-Cookie: number="I7\012."
+Set-Cookie: string="S'seven'\012p1\012."
 >>> C = Cookie.SmartCookie()
 >>> C["number"] = 7
 >>> C["string"] = "seven"
@@ -253,6 +255,6 @@ Set-Cookie: string="S'seven'\012p1\012.";
 >>> C["string"].value
 'seven'
 >>> print C
-Set-Cookie: number="I7\012.";
-Set-Cookie: string=seven;
+Set-Cookie: number="I7\012."
+Set-Cookie: string=seven
 \end{verbatim}
index 4661d7c3ffabf81acc342a8a690319a0597793c9..fa2e05ec57239f16e898b01b5797feaa39ca8704 100644 (file)
@@ -69,9 +69,8 @@ a dictionary.
    >>> C = Cookie.SmartCookie()
    >>> C["fig"] = "newton"
    >>> C["sugar"] = "wafer"
-   >>> print C
-   Set-Cookie: fig=newton;
-   Set-Cookie: sugar=wafer;
+   >>> C.output()
+   'Set-Cookie: fig=newton\r\nSet-Cookie: sugar=wafer'
 
 Notice that the printable representation of a Cookie is the
 appropriate format for a Set-Cookie: header.  This is the
@@ -82,9 +81,9 @@ attributes by using the .output() function
    >>> C["rocky"] = "road"
    >>> C["rocky"]["path"] = "/cookie"
    >>> print C.output(header="Cookie:")
-   Cookie: rocky=road; Path=/cookie;
+   Cookie: rocky=road; Path=/cookie
    >>> print C.output(attrs=[], header="Cookie:")
-   Cookie: rocky=road;
+   Cookie: rocky=road
 
 The load() method of a Cookie extracts cookies from a string.  In a
 CGI script, you would use this method to extract the cookies from the
@@ -92,9 +91,8 @@ HTTP_COOKIE environment variable.
 
    >>> C = Cookie.SmartCookie()
    >>> C.load("chips=ahoy; vienna=finger")
-   >>> print C
-   Set-Cookie: chips=ahoy;
-   Set-Cookie: vienna=finger;
+   >>> C.output()
+   'Set-Cookie: chips=ahoy\r\nSet-Cookie: vienna=finger'
 
 The load() method is darn-tootin smart about identifying cookies
 within a string.  Escaped quotation marks, nested semicolons, and other
@@ -103,7 +101,7 @@ such trickeries do not confuse it.
    >>> C = Cookie.SmartCookie()
    >>> C.load('keebler="E=everybody; L=\\"Loves\\"; fudge=\\012;";')
    >>> print C
-   Set-Cookie: keebler="E=everybody; L=\"Loves\"; fudge=\012;";
+   Set-Cookie: keebler="E=everybody; L=\"Loves\"; fudge=\012;"
 
 Each element of the Cookie also supports all of the RFC 2109
 Cookie attributes.  Here's an example which sets the Path
@@ -113,7 +111,7 @@ attribute.
    >>> C["oreo"] = "doublestuff"
    >>> C["oreo"]["path"] = "/"
    >>> print C
-   Set-Cookie: oreo=doublestuff; Path=/;
+   Set-Cookie: oreo=doublestuff; Path=/
 
 Each dictionary element has a 'value' attribute, which gives you
 back the value associated with the key.
@@ -144,9 +142,8 @@ the value to a string, when the values are set dictionary-style.
    '7'
    >>> C["string"].value
    'seven'
-   >>> print C
-   Set-Cookie: number=7;
-   Set-Cookie: string=seven;
+   >>> C.output()
+   'Set-Cookie: number=7\r\nSet-Cookie: string=seven'
 
 
 SerialCookie
@@ -165,9 +162,8 @@ values, however.)
    7
    >>> C["string"].value
    'seven'
-   >>> print C
-   Set-Cookie: number="I7\012.";
-   Set-Cookie: string="S'seven'\012p1\012.";
+   >>> C.output()
+   'Set-Cookie: number="I7\\012."\r\nSet-Cookie: string="S\'seven\'\\012p1\\012."'
 
 Be warned, however, if SerialCookie cannot de-serialize a value (because
 it isn't a valid pickle'd object), IT WILL RAISE AN EXCEPTION.
@@ -190,9 +186,8 @@ as a string.
    7
    >>> C["string"].value
    'seven'
-   >>> print C
-   Set-Cookie: number="I7\012.";
-   Set-Cookie: string=seven;
+   >>> C.output()
+   'Set-Cookie: number="I7\\012."\r\nSet-Cookie: string=seven'
 
 
 Backwards Compatibility
@@ -228,7 +223,7 @@ __all__ = ["CookieError","BaseCookie","SimpleCookie","SerialCookie",
            "SmartCookie","Cookie"]
 
 _nulljoin = ''.join
-_spacejoin = ' '.join
+_semispacejoin = '; '.join
 
 #
 # Define an exception visible to External modules
@@ -485,7 +480,7 @@ class Morsel(dict):
         RA = result.append
 
         # First, the key=value pair
-        RA("%s=%s;" % (self.key, self.coded_value))
+        RA("%s=%s" % (self.key, self.coded_value))
 
         # Now add any defined attributes
         if attrs is None:
@@ -496,16 +491,16 @@ class Morsel(dict):
             if V == "": continue
             if K not in attrs: continue
             if K == "expires" and type(V) == type(1):
-                RA("%s=%s;" % (self._reserved[K], _getdate(V)))
+                RA("%s=%s" % (self._reserved[K], _getdate(V)))
             elif K == "max-age" and type(V) == type(1):
-                RA("%s=%d;" % (self._reserved[K], V))
+                RA("%s=%d" % (self._reserved[K], V))
             elif K == "secure":
-                RA("%s;" % self._reserved[K])
+                RA(str(self._reserved[K]))
             else:
-                RA("%s=%s;" % (self._reserved[K], V))
+                RA("%s=%s" % (self._reserved[K], V))
 
         # Return the result
-        return _spacejoin(result)
+        return _semispacejoin(result)
     # end OutputString
 # end Morsel class
 
@@ -581,7 +576,7 @@ class BaseCookie(dict):
         self.__set(key, rval, cval)
     # end __setitem__
 
-    def output(self, attrs=None, header="Set-Cookie:", sep="\n"):
+    def output(self, attrs=None, header="Set-Cookie:", sep="\015\012"):
         """Return a string suitable for HTTP."""
         result = []
         items = self.items()
@@ -599,7 +594,7 @@ class BaseCookie(dict):
         items.sort()
         for K,V in items:
             L.append( '%s=%s' % (K,repr(V.value) ) )
-        return '<%s: %s>' % (self.__class__.__name__, _spacejoin(L))
+        return '<%s: %s>' % (self.__class__.__name__, _semispacejoin(L))
 
     def js_output(self, attrs=None):
         """Return a string suitable for JavaScript."""
index fab6163a58a8977f798e93b1994386aa76a1f8ee..20e1f8938d64085e2181b3adfd4f8a62c557c93f 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -193,6 +193,9 @@ Extension Modules
 Library
 -------
 
+- Patch #848017: Make Cookie more RFC-compliant. Use CRLF as default output
+  separator and do not output trailing semicola.
+
 - Patch #1062060: urllib.urlretrieve() now raises a new exception, named
   ContentTooShortException, when the actually downloaded size does not
   match the Content-Length header.