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 .. versionchanged:: 3.7 152 Attributes :attr:`~Morsel.key`, :attr:`~Morsel.value` and 153 :attr:`~Morsel.coded_value` are read-only. Use :meth:`~Morsel.set` for 154 setting them. 155 156 157.. attribute:: Morsel.value 158 159 The value of the cookie. 160 161 162.. attribute:: Morsel.coded_value 163 164 The encoded value of the cookie --- this is what should be sent. 165 166 167.. attribute:: Morsel.key 168 169 The name of the cookie. 170 171 172.. method:: Morsel.set(key, value, coded_value) 173 174 Set the *key*, *value* and *coded_value* attributes. 175 176 177.. method:: Morsel.isReservedKey(K) 178 179 Whether *K* is a member of the set of keys of a :class:`Morsel`. 180 181 182.. method:: Morsel.output(attrs=None, header='Set-Cookie:') 183 184 Return a string representation of the Morsel, suitable to be sent as an HTTP 185 header. By default, all the attributes are included, unless *attrs* is given, in 186 which case it should be a list of attributes to use. *header* is by default 187 ``"Set-Cookie:"``. 188 189 190.. method:: Morsel.js_output(attrs=None) 191 192 Return an embeddable JavaScript snippet, which, if run on a browser which 193 supports JavaScript, will act the same as if the HTTP header was sent. 194 195 The meaning for *attrs* is the same as in :meth:`output`. 196 197 198.. method:: Morsel.OutputString(attrs=None) 199 200 Return a string representing the Morsel, without any surrounding HTTP or 201 JavaScript. 202 203 The meaning for *attrs* is the same as in :meth:`output`. 204 205 206.. method:: Morsel.update(values) 207 208 Update the values in the Morsel dictionary with the values in the dictionary 209 *values*. Raise an error if any of the keys in the *values* dict is not a 210 valid :rfc:`2109` attribute. 211 212 .. versionchanged:: 3.5 213 an error is raised for invalid keys. 214 215 216.. method:: Morsel.copy(value) 217 218 Return a shallow copy of the Morsel object. 219 220 .. versionchanged:: 3.5 221 return a Morsel object instead of a dict. 222 223 224.. method:: Morsel.setdefault(key, value=None) 225 226 Raise an error if key is not a valid :rfc:`2109` attribute, otherwise 227 behave the same as :meth:`dict.setdefault`. 228 229 230.. _cookie-example: 231 232Example 233------- 234 235The following example demonstrates how to use the :mod:`http.cookies` module. 236 237.. doctest:: 238 :options: +NORMALIZE_WHITESPACE 239 240 >>> from http import cookies 241 >>> C = cookies.SimpleCookie() 242 >>> C["fig"] = "newton" 243 >>> C["sugar"] = "wafer" 244 >>> print(C) # generate HTTP headers 245 Set-Cookie: fig=newton 246 Set-Cookie: sugar=wafer 247 >>> print(C.output()) # same thing 248 Set-Cookie: fig=newton 249 Set-Cookie: sugar=wafer 250 >>> C = cookies.SimpleCookie() 251 >>> C["rocky"] = "road" 252 >>> C["rocky"]["path"] = "/cookie" 253 >>> print(C.output(header="Cookie:")) 254 Cookie: rocky=road; Path=/cookie 255 >>> print(C.output(attrs=[], header="Cookie:")) 256 Cookie: rocky=road 257 >>> C = cookies.SimpleCookie() 258 >>> C.load("chips=ahoy; vienna=finger") # load from a string (HTTP header) 259 >>> print(C) 260 Set-Cookie: chips=ahoy 261 Set-Cookie: vienna=finger 262 >>> C = cookies.SimpleCookie() 263 >>> C.load('keebler="E=everybody; L=\\"Loves\\"; fudge=\\012;";') 264 >>> print(C) 265 Set-Cookie: keebler="E=everybody; L=\"Loves\"; fudge=\012;" 266 >>> C = cookies.SimpleCookie() 267 >>> C["oreo"] = "doublestuff" 268 >>> C["oreo"]["path"] = "/" 269 >>> print(C) 270 Set-Cookie: oreo=doublestuff; Path=/ 271 >>> C = cookies.SimpleCookie() 272 >>> C["twix"] = "none for you" 273 >>> C["twix"].value 274 'none for you' 275 >>> C = cookies.SimpleCookie() 276 >>> C["number"] = 7 # equivalent to C["number"] = str(7) 277 >>> C["string"] = "seven" 278 >>> C["number"].value 279 '7' 280 >>> C["string"].value 281 'seven' 282 >>> print(C) 283 Set-Cookie: number=7 284 Set-Cookie: string=seven 285