• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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