Home | History | Annotate | Download | only in library
      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 (a] alum.mit.edu>
      8 .. sectionauthor:: Moshe Zadka <moshez (a] zadka.site.co.il>
      9 
     10 **Source code:** :source:`Lib/http/cookies.py`
     11 
     12 --------------
     13 
     14 The :mod:`http.cookies` module defines classes for abstracting the concept of
     15 cookies, an HTTP state management mechanism. It supports both simple string-only
     16 cookies, and provides an abstraction for having any serializable data-type as
     17 cookie value.
     18 
     19 The module formerly strictly applied the parsing rules described in the
     20 :rfc:`2109` and :rfc:`2068` specifications.  It has since been discovered that
     21 MSIE 3.0x doesn't follow the character rules outlined in those specs and also
     22 many current day browsers and servers have relaxed parsing rules when comes to
     23 Cookie handling.  As a result, the parsing rules used are a bit less strict.
     24 
     25 The character set, :data:`string.ascii_letters`, :data:`string.digits` and
     26 ``!#$%&'*+-.^_`|~:`` denote the set of valid characters allowed by this module
     27 in 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 
     73 Cookie 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 
    121 Morsel 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 
    232 Example
    233 -------
    234 
    235 The 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