1:mod:`http.cookies` --- HTTP state management 2============================================= 3 4.. module:: http.cookies 5 :synopsis: Support for HTTP state management (cookies). 6 7.. moduleauthor:: Timothy O'Malley <timo@alum.mit.edu> 8.. sectionauthor:: Moshe Zadka <moshez@zadka.site.co.il> 9 10**Source code:** :source:`Lib/http/cookies.py` 11 12-------------- 13 14The :mod:`http.cookies` module defines classes for abstracting the concept of 15cookies, an HTTP state management mechanism. It supports both simple string-only 16cookies, and provides an abstraction for having any serializable data-type as 17cookie value. 18 19The module formerly strictly applied the parsing rules described in the 20:rfc:`2109` and :rfc:`2068` specifications. It has since been discovered that 21MSIE 3.0x doesn't follow the character rules outlined in those specs and also 22many current day browsers and servers have relaxed parsing rules when comes to 23Cookie handling. As a result, the parsing rules used are a bit less strict. 24 25The character set, :data:`string.ascii_letters`, :data:`string.digits` and 26``!#$%&'*+-.^_`|~:`` denote the set of valid characters allowed by this module 27in Cookie name (as :attr:`~Morsel.key`). 28 29.. versionchanged:: 3.3 30 Allowed ':' as a valid Cookie name character. 31 32 33.. note:: 34 35 On encountering an invalid cookie, :exc:`CookieError` is raised, so if your 36 cookie data comes from a browser you should always prepare for invalid data 37 and catch :exc:`CookieError` on parsing. 38 39 40.. exception:: CookieError 41 42 Exception failing because of :rfc:`2109` invalidity: incorrect attributes, 43 incorrect :mailheader:`Set-Cookie` header, etc. 44 45 46.. class:: BaseCookie([input]) 47 48 This class is a dictionary-like object whose keys are strings and whose values 49 are :class:`Morsel` instances. Note that upon setting a key to a value, the 50 value is first converted to a :class:`Morsel` containing the key and the value. 51 52 If *input* is given, it is passed to the :meth:`load` method. 53 54 55.. class:: SimpleCookie([input]) 56 57 This class derives from :class:`BaseCookie` and overrides :meth:`value_decode` 58 and :meth:`value_encode` to be the identity and :func:`str` respectively. 59 60 61.. seealso:: 62 63 Module :mod:`http.cookiejar` 64 HTTP cookie handling for web *clients*. The :mod:`http.cookiejar` and 65 :mod:`http.cookies` modules do not depend on each other. 66 67 :rfc:`2109` - HTTP State Management Mechanism 68 This is the state management specification implemented by this module. 69 70 71.. _cookie-objects: 72 73Cookie Objects 74-------------- 75 76 77.. method:: BaseCookie.value_decode(val) 78 79 Return a decoded value from a string representation. Return value can be any 80 type. This method does nothing in :class:`BaseCookie` --- it exists so it can be 81 overridden. 82 83 84.. method:: BaseCookie.value_encode(val) 85 86 Return an encoded value. *val* can be any type, but return value must be a 87 string. This method does nothing in :class:`BaseCookie` --- it exists so it can 88 be overridden. 89 90 In general, it should be the case that :meth:`value_encode` and 91 :meth:`value_decode` are inverses on the range of *value_decode*. 92 93 94.. method:: BaseCookie.output(attrs=None, header='Set-Cookie:', sep='\\r\\n') 95 96 Return a string representation suitable to be sent as HTTP headers. *attrs* and 97 *header* are sent to each :class:`Morsel`'s :meth:`output` method. *sep* is used 98 to join the headers together, and is by default the combination ``'\r\n'`` 99 (CRLF). 100 101 102.. method:: BaseCookie.js_output(attrs=None) 103 104 Return an embeddable JavaScript snippet, which, if run on a browser which 105 supports JavaScript, will act the same as if the HTTP headers was sent. 106 107 The meaning for *attrs* is the same as in :meth:`output`. 108 109 110.. method:: BaseCookie.load(rawdata) 111 112 If *rawdata* is a string, parse it as an ``HTTP_COOKIE`` and add the values 113 found there as :class:`Morsel`\ s. If it is a dictionary, it is equivalent to:: 114 115 for k, v in rawdata.items(): 116 cookie[k] = v 117 118 119.. _morsel-objects: 120 121Morsel Objects 122-------------- 123 124 125.. class:: Morsel 126 127 Abstract a key/value pair, which has some :rfc:`2109` attributes. 128 129 Morsels are dictionary-like objects, whose set of keys is constant --- the valid 130 :rfc:`2109` attributes, which are 131 132 * ``expires`` 133 * ``path`` 134 * ``comment`` 135 * ``domain`` 136 * ``max-age`` 137 * ``secure`` 138 * ``version`` 139 * ``httponly`` 140 141 The attribute :attr:`httponly` specifies that the cookie is only transferred 142 in HTTP requests, and is not accessible through JavaScript. This is intended 143 to mitigate some forms of cross-site scripting. 144 145 The keys are case-insensitive and their default value is ``''``. 146 147 .. versionchanged:: 3.5 148 :meth:`~Morsel.__eq__` now takes :attr:`~Morsel.key` and :attr:`~Morsel.value` 149 into account. 150 151 152.. attribute:: Morsel.value 153 154 The value of the cookie. 155 156 .. deprecated:: 3.5 157 assigning to ``value``; use :meth:`~Morsel.set` instead. 158 159 160.. attribute:: Morsel.coded_value 161 162 The encoded value of the cookie --- this is what should be sent. 163 164 .. deprecated:: 3.5 165 assigning to ``coded_value``; use :meth:`~Morsel.set` instead. 166 167 168.. attribute:: Morsel.key 169 170 The name of the cookie. 171 172 .. deprecated:: 3.5 173 assigning to ``key``; use :meth:`~Morsel.set` instead. 174 175 176.. method:: Morsel.set(key, value, coded_value) 177 178 Set the *key*, *value* and *coded_value* attributes. 179 180 .. deprecated:: 3.5 181 The undocumented *LegalChars* parameter is ignored and will be removed in 182 a future version. 183 184 185.. method:: Morsel.isReservedKey(K) 186 187 Whether *K* is a member of the set of keys of a :class:`Morsel`. 188 189 190.. method:: Morsel.output(attrs=None, header='Set-Cookie:') 191 192 Return a string representation of the Morsel, suitable to be sent as an HTTP 193 header. By default, all the attributes are included, unless *attrs* is given, in 194 which case it should be a list of attributes to use. *header* is by default 195 ``"Set-Cookie:"``. 196 197 198.. method:: Morsel.js_output(attrs=None) 199 200 Return an embeddable JavaScript snippet, which, if run on a browser which 201 supports JavaScript, will act the same as if the HTTP header was sent. 202 203 The meaning for *attrs* is the same as in :meth:`output`. 204 205 206.. method:: Morsel.OutputString(attrs=None) 207 208 Return a string representing the Morsel, without any surrounding HTTP or 209 JavaScript. 210 211 The meaning for *attrs* is the same as in :meth:`output`. 212 213 214.. method:: Morsel.update(values) 215 216 Update the values in the Morsel dictionary with the values in the dictionary 217 *values*. Raise an error if any of the keys in the *values* dict is not a 218 valid :rfc:`2109` attribute. 219 220 .. versionchanged:: 3.5 221 an error is raised for invalid keys. 222 223 224.. method:: Morsel.copy(value) 225 226 Return a shallow copy of the Morsel object. 227 228 .. versionchanged:: 3.5 229 return a Morsel object instead of a dict. 230 231 232.. method:: Morsel.setdefault(key, value=None) 233 234 Raise an error if key is not a valid :rfc:`2109` attribute, otherwise 235 behave the same as :meth:`dict.setdefault`. 236 237 238.. _cookie-example: 239 240Example 241------- 242 243The following example demonstrates how to use the :mod:`http.cookies` module. 244 245.. doctest:: 246 :options: +NORMALIZE_WHITESPACE 247 248 >>> from http import cookies 249 >>> C = cookies.SimpleCookie() 250 >>> C["fig"] = "newton" 251 >>> C["sugar"] = "wafer" 252 >>> print(C) # generate HTTP headers 253 Set-Cookie: fig=newton 254 Set-Cookie: sugar=wafer 255 >>> print(C.output()) # same thing 256 Set-Cookie: fig=newton 257 Set-Cookie: sugar=wafer 258 >>> C = cookies.SimpleCookie() 259 >>> C["rocky"] = "road" 260 >>> C["rocky"]["path"] = "/cookie" 261 >>> print(C.output(header="Cookie:")) 262 Cookie: rocky=road; Path=/cookie 263 >>> print(C.output(attrs=[], header="Cookie:")) 264 Cookie: rocky=road 265 >>> C = cookies.SimpleCookie() 266 >>> C.load("chips=ahoy; vienna=finger") # load from a string (HTTP header) 267 >>> print(C) 268 Set-Cookie: chips=ahoy 269 Set-Cookie: vienna=finger 270 >>> C = cookies.SimpleCookie() 271 >>> C.load('keebler="E=everybody; L=\\"Loves\\"; fudge=\\012;";') 272 >>> print(C) 273 Set-Cookie: keebler="E=everybody; L=\"Loves\"; fudge=\012;" 274 >>> C = cookies.SimpleCookie() 275 >>> C["oreo"] = "doublestuff" 276 >>> C["oreo"]["path"] = "/" 277 >>> print(C) 278 Set-Cookie: oreo=doublestuff; Path=/ 279 >>> C = cookies.SimpleCookie() 280 >>> C["twix"] = "none for you" 281 >>> C["twix"].value 282 'none for you' 283 >>> C = cookies.SimpleCookie() 284 >>> C["number"] = 7 # equivalent to C["number"] = str(7) 285 >>> C["string"] = "seven" 286 >>> C["number"].value 287 '7' 288 >>> C["string"].value 289 'seven' 290 >>> print(C) 291 Set-Cookie: number=7 292 Set-Cookie: string=seven 293