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`. SimpleCookie supports strings as cookie values. 59 When setting the value, SimpleCookie calls the builtin :func:`str()` to convert 60 the value to a string. Values received from HTTP are kept as strings. 61 62.. seealso:: 63 64 Module :mod:`http.cookiejar` 65 HTTP cookie handling for web *clients*. The :mod:`http.cookiejar` and 66 :mod:`http.cookies` modules do not depend on each other. 67 68 :rfc:`2109` - HTTP State Management Mechanism 69 This is the state management specification implemented by this module. 70 71 72.. _cookie-objects: 73 74Cookie Objects 75-------------- 76 77 78.. method:: BaseCookie.value_decode(val) 79 80 Return a tuple ``(real_value, coded_value)`` from a string representation. 81 ``real_value`` can be any type. This method does no decoding in 82 :class:`BaseCookie` --- it exists so it can be overridden. 83 84 85.. method:: BaseCookie.value_encode(val) 86 87 Return a tuple ``(real_value, coded_value)``. *val* can be any type, but 88 ``coded_value`` will always be converted to a string. 89 This method does no encoding in :class:`BaseCookie` --- it exists so it can 90 be overridden. 91 92 In general, it should be the case that :meth:`value_encode` and 93 :meth:`value_decode` are inverses on the range of *value_decode*. 94 95 96.. method:: BaseCookie.output(attrs=None, header='Set-Cookie:', sep='\\r\\n') 97 98 Return a string representation suitable to be sent as HTTP headers. *attrs* and 99 *header* are sent to each :class:`Morsel`'s :meth:`output` method. *sep* is used 100 to join the headers together, and is by default the combination ``'\r\n'`` 101 (CRLF). 102 103 104.. method:: BaseCookie.js_output(attrs=None) 105 106 Return an embeddable JavaScript snippet, which, if run on a browser which 107 supports JavaScript, will act the same as if the HTTP headers was sent. 108 109 The meaning for *attrs* is the same as in :meth:`output`. 110 111 112.. method:: BaseCookie.load(rawdata) 113 114 If *rawdata* is a string, parse it as an ``HTTP_COOKIE`` and add the values 115 found there as :class:`Morsel`\ s. If it is a dictionary, it is equivalent to:: 116 117 for k, v in rawdata.items(): 118 cookie[k] = v 119 120 121.. _morsel-objects: 122 123Morsel Objects 124-------------- 125 126 127.. class:: Morsel 128 129 Abstract a key/value pair, which has some :rfc:`2109` attributes. 130 131 Morsels are dictionary-like objects, whose set of keys is constant --- the valid 132 :rfc:`2109` attributes, which are 133 134 * ``expires`` 135 * ``path`` 136 * ``comment`` 137 * ``domain`` 138 * ``max-age`` 139 * ``secure`` 140 * ``version`` 141 * ``httponly`` 142 * ``samesite`` 143 144 The attribute :attr:`httponly` specifies that the cookie is only transferred 145 in HTTP requests, and is not accessible through JavaScript. This is intended 146 to mitigate some forms of cross-site scripting. 147 148 The attribute :attr:`samesite` specifies that the browser is not allowed to 149 send the cookie along with cross-site requests. This helps to mitigate CSRF 150 attacks. Valid values for this attribute are "Strict" and "Lax". 151 152 The keys are case-insensitive and their default value is ``''``. 153 154 .. versionchanged:: 3.5 155 :meth:`~Morsel.__eq__` now takes :attr:`~Morsel.key` and :attr:`~Morsel.value` 156 into account. 157 158 .. versionchanged:: 3.7 159 Attributes :attr:`~Morsel.key`, :attr:`~Morsel.value` and 160 :attr:`~Morsel.coded_value` are read-only. Use :meth:`~Morsel.set` for 161 setting them. 162 163 .. versionchanged:: 3.8 164 Added support for the :attr:`samesite` attribute. 165 166 167.. attribute:: Morsel.value 168 169 The value of the cookie. 170 171 172.. attribute:: Morsel.coded_value 173 174 The encoded value of the cookie --- this is what should be sent. 175 176 177.. attribute:: Morsel.key 178 179 The name of the cookie. 180 181 182.. method:: Morsel.set(key, value, coded_value) 183 184 Set the *key*, *value* and *coded_value* attributes. 185 186 187.. method:: Morsel.isReservedKey(K) 188 189 Whether *K* is a member of the set of keys of a :class:`Morsel`. 190 191 192.. method:: Morsel.output(attrs=None, header='Set-Cookie:') 193 194 Return a string representation of the Morsel, suitable to be sent as an HTTP 195 header. By default, all the attributes are included, unless *attrs* is given, in 196 which case it should be a list of attributes to use. *header* is by default 197 ``"Set-Cookie:"``. 198 199 200.. method:: Morsel.js_output(attrs=None) 201 202 Return an embeddable JavaScript snippet, which, if run on a browser which 203 supports JavaScript, will act the same as if the HTTP header was sent. 204 205 The meaning for *attrs* is the same as in :meth:`output`. 206 207 208.. method:: Morsel.OutputString(attrs=None) 209 210 Return a string representing the Morsel, without any surrounding HTTP or 211 JavaScript. 212 213 The meaning for *attrs* is the same as in :meth:`output`. 214 215 216.. method:: Morsel.update(values) 217 218 Update the values in the Morsel dictionary with the values in the dictionary 219 *values*. Raise an error if any of the keys in the *values* dict is not a 220 valid :rfc:`2109` attribute. 221 222 .. versionchanged:: 3.5 223 an error is raised for invalid keys. 224 225 226.. method:: Morsel.copy(value) 227 228 Return a shallow copy of the Morsel object. 229 230 .. versionchanged:: 3.5 231 return a Morsel object instead of a dict. 232 233 234.. method:: Morsel.setdefault(key, value=None) 235 236 Raise an error if key is not a valid :rfc:`2109` attribute, otherwise 237 behave the same as :meth:`dict.setdefault`. 238 239 240.. _cookie-example: 241 242Example 243------- 244 245The following example demonstrates how to use the :mod:`http.cookies` module. 246 247.. doctest:: 248 :options: +NORMALIZE_WHITESPACE 249 250 >>> from http import cookies 251 >>> C = cookies.SimpleCookie() 252 >>> C["fig"] = "newton" 253 >>> C["sugar"] = "wafer" 254 >>> print(C) # generate HTTP headers 255 Set-Cookie: fig=newton 256 Set-Cookie: sugar=wafer 257 >>> print(C.output()) # same thing 258 Set-Cookie: fig=newton 259 Set-Cookie: sugar=wafer 260 >>> C = cookies.SimpleCookie() 261 >>> C["rocky"] = "road" 262 >>> C["rocky"]["path"] = "/cookie" 263 >>> print(C.output(header="Cookie:")) 264 Cookie: rocky=road; Path=/cookie 265 >>> print(C.output(attrs=[], header="Cookie:")) 266 Cookie: rocky=road 267 >>> C = cookies.SimpleCookie() 268 >>> C.load("chips=ahoy; vienna=finger") # load from a string (HTTP header) 269 >>> print(C) 270 Set-Cookie: chips=ahoy 271 Set-Cookie: vienna=finger 272 >>> C = cookies.SimpleCookie() 273 >>> C.load('keebler="E=everybody; L=\\"Loves\\"; fudge=\\012;";') 274 >>> print(C) 275 Set-Cookie: keebler="E=everybody; L=\"Loves\"; fudge=\012;" 276 >>> C = cookies.SimpleCookie() 277 >>> C["oreo"] = "doublestuff" 278 >>> C["oreo"]["path"] = "/" 279 >>> print(C) 280 Set-Cookie: oreo=doublestuff; Path=/ 281 >>> C = cookies.SimpleCookie() 282 >>> C["twix"] = "none for you" 283 >>> C["twix"].value 284 'none for you' 285 >>> C = cookies.SimpleCookie() 286 >>> C["number"] = 7 # equivalent to C["number"] = str(7) 287 >>> C["string"] = "seven" 288 >>> C["number"].value 289 '7' 290 >>> C["string"].value 291 'seven' 292 >>> print(C) 293 Set-Cookie: number=7 294 Set-Cookie: string=seven 295