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