:mod:`http.cookiejar` --- Cookie handling for HTTP clients
==========================================================

.. module:: http.cookiejar
   :synopsis: Classes for automatic handling of HTTP cookies.
.. moduleauthor:: John J. Lee <jjl@pobox.com>
.. sectionauthor:: John J. Lee <jjl@pobox.com>

**Source code:** :source:`Lib/http/cookiejar.py`

--------------

The :mod:`http.cookiejar` module defines classes for automatic handling of HTTP
cookies.  It is useful for accessing web sites that require small pieces of data
-- :dfn:`cookies` -- to be set on the client machine by an HTTP response from a
web server, and then returned to the server in later HTTP requests.

Both the regular Netscape cookie protocol and the protocol defined by
:rfc:`2965` are handled.  RFC 2965 handling is switched off by default.
:rfc:`2109` cookies are parsed as Netscape cookies and subsequently treated
either as Netscape or RFC 2965 cookies according to the 'policy' in effect.
Note that the great majority of cookies on the Internet are Netscape cookies.
:mod:`http.cookiejar` attempts to follow the de-facto Netscape cookie protocol (which
differs substantially from that set out in the original Netscape specification),
including taking note of the ``max-age`` and ``port`` cookie-attributes
introduced with RFC 2965.

.. note::

   The various named parameters found in :mailheader:`Set-Cookie` and
   :mailheader:`Set-Cookie2` headers (eg. ``domain`` and ``expires``) are
   conventionally referred to as :dfn:`attributes`.  To distinguish them from
   Python attributes, the documentation for this module uses the term
   :dfn:`cookie-attribute` instead.


The module defines the following exception:


.. exception:: LoadError

   Instances of :class:`FileCookieJar` raise this exception on failure to load
   cookies from a file.  :exc:`LoadError` is a subclass of :exc:`OSError`.

   .. versionchanged:: 3.3
      LoadError was made a subclass of :exc:`OSError` instead of
      :exc:`IOError`.


The following classes are provided:


.. class:: CookieJar(policy=None)

   *policy* is an object implementing the :class:`CookiePolicy` interface.

   The :class:`CookieJar` class stores HTTP cookies.  It extracts cookies from HTTP
   requests, and returns them in HTTP responses. :class:`CookieJar` instances
   automatically expire contained cookies when necessary.  Subclasses are also
   responsible for storing and retrieving cookies from a file or database.


.. class:: FileCookieJar(filename, delayload=None, policy=None)

   *policy* is an object implementing the :class:`CookiePolicy` interface.  For the
   other arguments, see the documentation for the corresponding attributes.

   A :class:`CookieJar` which can load cookies from, and perhaps save cookies to, a
   file on disk.  Cookies are **NOT** loaded from the named file until either the
   :meth:`load` or :meth:`revert` method is called.  Subclasses of this class are
   documented in section :ref:`file-cookie-jar-classes`.


.. class:: CookiePolicy()

   This class is responsible for deciding whether each cookie should be accepted
   from / returned to the server.


.. class:: DefaultCookiePolicy( blocked_domains=None, allowed_domains=None, netscape=True, rfc2965=False, rfc2109_as_netscape=None, hide_cookie2=False, strict_domain=False, strict_rfc2965_unverifiable=True, strict_ns_unverifiable=False, strict_ns_domain=DefaultCookiePolicy.DomainLiberal, strict_ns_set_initial_dollar=False, strict_ns_set_path=False )

   Constructor arguments should be passed as keyword arguments only.
   *blocked_domains* is a sequence of domain names that we never accept cookies
   from, nor return cookies to. *allowed_domains* if not :const:`None`, this is a
   sequence of the only domains for which we accept and return cookies.  For all
   other arguments, see the documentation for :class:`CookiePolicy` and
   :class:`DefaultCookiePolicy` objects.

   :class:`DefaultCookiePolicy` implements the standard accept / reject rules for
   Netscape and RFC 2965 cookies.  By default, RFC 2109 cookies (ie. cookies
   received in a :mailheader:`Set-Cookie` header with a version cookie-attribute of
   1) are treated according to the RFC 2965 rules.  However, if RFC 2965 handling
   is turned off or :attr:`rfc2109_as_netscape` is True, RFC 2109 cookies are
   'downgraded' by the :class:`CookieJar` instance to Netscape cookies, by
   setting the :attr:`version` attribute of the :class:`Cookie` instance to 0.
   :class:`DefaultCookiePolicy` also provides some parameters to allow some
   fine-tuning of policy.


.. class:: Cookie()

   This class represents Netscape, RFC 2109 and RFC 2965 cookies.  It is not
   expected that users of :mod:`http.cookiejar` construct their own :class:`Cookie`
   instances.  Instead, if necessary, call :meth:`make_cookies` on a
   :class:`CookieJar` instance.


.. seealso::

   Module :mod:`urllib.request`
      URL opening with automatic cookie handling.

   Module :mod:`http.cookies`
      HTTP cookie classes, principally useful for server-side code.  The
      :mod:`http.cookiejar` and :mod:`http.cookies` modules do not depend on each
      other.

   http://wp.netscape.com/newsref/std/cookie_spec.html
      The specification of the original Netscape cookie protocol.  Though this is
      still the dominant protocol, the 'Netscape cookie protocol' implemented by all
      the major browsers (and :mod:`http.cookiejar`) only bears a passing resemblance to
      the one sketched out in ``cookie_spec.html``.

   :rfc:`2109` - HTTP State Management Mechanism
      Obsoleted by RFC 2965. Uses :mailheader:`Set-Cookie` with version=1.

   :rfc:`2965` - HTTP State Management Mechanism
      The Netscape protocol with the bugs fixed.  Uses :mailheader:`Set-Cookie2` in
      place of :mailheader:`Set-Cookie`.  Not widely used.

   http://kristol.org/cookie/errata.html
      Unfinished errata to RFC 2965.

   :rfc:`2964` - Use of HTTP State Management

.. _cookie-jar-objects:

CookieJar and FileCookieJar Objects
-----------------------------------

:class:`CookieJar` objects support the :term:`iterator` protocol for iterating over
contained :class:`Cookie` objects.

:class:`CookieJar` has the following methods:


.. method:: CookieJar.add_cookie_header(request)

   Add correct :mailheader:`Cookie` header to *request*.

   If policy allows (ie. the :attr:`rfc2965` and :attr:`hide_cookie2` attributes of
   the :class:`CookieJar`'s :class:`CookiePolicy` instance are true and false
   respectively), the :mailheader:`Cookie2` header is also added when appropriate.

   The *request* object (usually a :class:`urllib.request..Request` instance)
   must support the methods :meth:`get_full_url`, :meth:`get_host`,
   :meth:`get_type`, :meth:`unverifiable`, :meth:`get_origin_req_host`,
   :meth:`has_header`, :meth:`get_header`, :meth:`header_items`, and
   :meth:`add_unredirected_header`, as documented by :mod:`urllib.request`.


.. method:: CookieJar.extract_cookies(response, request)

   Extract cookies from HTTP *response* and store them in the :class:`CookieJar`,
   where allowed by policy.

   The :class:`CookieJar` will look for allowable :mailheader:`Set-Cookie` and
   :mailheader:`Set-Cookie2` headers in the *response* argument, and store cookies
   as appropriate (subject to the :meth:`CookiePolicy.set_ok` method's approval).

   The *response* object (usually the result of a call to
   :meth:`urllib.request.urlopen`, or similar) should support an :meth:`info`
   method, which returns a :class:`email.message.Message` instance.

   The *request* object (usually a :class:`urllib.request.Request` instance)
   must support the methods :meth:`get_full_url`, :meth:`get_host`,
   :meth:`unverifiable`, and :meth:`get_origin_req_host`, as documented by
   :mod:`urllib.request`.  The request is used to set default values for
   cookie-attributes as well as for checking that the cookie is allowed to be
   set.


.. method:: CookieJar.set_policy(policy)

   Set the :class:`CookiePolicy` instance to be used.


.. method:: CookieJar.make_cookies(response, request)

   Return sequence of :class:`Cookie` objects extracted from *response* object.

   See the documentation for :meth:`extract_cookies` for the interfaces required of
   the *response* and *request* arguments.


.. method:: CookieJar.set_cookie_if_ok(cookie, request)

   Set a :class:`Cookie` if policy says it's OK to do so.


.. method:: CookieJar.set_cookie(cookie)

   Set a :class:`Cookie`, without checking with policy to see whether or not it
   should be set.


.. method:: CookieJar.clear([domain[, path[, name]]])

   Clear some cookies.

   If invoked without arguments, clear all cookies.  If given a single argument,
   only cookies belonging to that *domain* will be removed. If given two arguments,
   cookies belonging to the specified *domain* and URL *path* are removed.  If
   given three arguments, then the cookie with the specified *domain*, *path* and
   *name* is removed.

   Raises :exc:`KeyError` if no matching cookie exists.


.. method:: CookieJar.clear_session_cookies()

   Discard all session cookies.

   Discards all contained cookies that have a true :attr:`discard` attribute
   (usually because they had either no ``max-age`` or ``expires`` cookie-attribute,
   or an explicit ``discard`` cookie-attribute).  For interactive browsers, the end
   of a session usually corresponds to closing the browser window.

   Note that the :meth:`save` method won't save session cookies anyway, unless you
   ask otherwise by passing a true *ignore_discard* argument.

:class:`FileCookieJar` implements the following additional methods:


.. method:: FileCookieJar.save(filename=None, ignore_discard=False, ignore_expires=False)

   Save cookies to a file.

   This base class raises :exc:`NotImplementedError`.  Subclasses may leave this
   method unimplemented.

   *filename* is the name of file in which to save cookies.  If *filename* is not
   specified, :attr:`self.filename` is used (whose default is the value passed to
   the constructor, if any); if :attr:`self.filename` is :const:`None`,
   :exc:`ValueError` is raised.

   *ignore_discard*: save even cookies set to be discarded. *ignore_expires*: save
   even cookies that have expired

   The file is overwritten if it already exists, thus wiping all the cookies it
   contains.  Saved cookies can be restored later using the :meth:`load` or
   :meth:`revert` methods.


.. method:: FileCookieJar.load(filename=None, ignore_discard=False, ignore_expires=False)

   Load cookies from a file.

   Old cookies are kept unless overwritten by newly loaded ones.

   Arguments are as for :meth:`save`.

   The named file must be in the format understood by the class, or
   :exc:`LoadError` will be raised.  Also, :exc:`OSError` may be raised, for
   example if the file does not exist.

   .. versionchanged:: 3.3
      :exc:`IOError` used to be raised, it is now an alias of :exc:`OSError`.


.. method:: FileCookieJar.revert(filename=None, ignore_discard=False, ignore_expires=False)

   Clear all cookies and reload cookies from a saved file.

   :meth:`revert` can raise the same exceptions as :meth:`load`. If there is a
   failure, the object's state will not be altered.

:class:`FileCookieJar` instances have the following public attributes:


.. attribute:: FileCookieJar.filename

   Filename of default file in which to keep cookies.  This attribute may be
   assigned to.


.. attribute:: FileCookieJar.delayload

   If true, load cookies lazily from disk.  This attribute should not be assigned
   to.  This is only a hint, since this only affects performance, not behaviour
   (unless the cookies on disk are changing). A :class:`CookieJar` object may
   ignore it.  None of the :class:`FileCookieJar` classes included in the standard
   library lazily loads cookies.


.. _file-cookie-jar-classes:

FileCookieJar subclasses and co-operation with web browsers
-----------------------------------------------------------

The following :class:`CookieJar` subclasses are provided for reading and
writing .

.. class:: MozillaCookieJar(filename, delayload=None, policy=None)

   A :class:`FileCookieJar` that can load from and save cookies to disk in the
   Mozilla ``cookies.txt`` file format (which is also used by the Lynx and Netscape
   browsers).

   .. note::

      This loses information about RFC 2965 cookies, and also about newer or
      non-standard cookie-attributes such as ``port``.

   .. warning::

      Back up your cookies before saving if you have cookies whose loss / corruption
      would be inconvenient (there are some subtleties which may lead to slight
      changes in the file over a load / save round-trip).

   Also note that cookies saved while Mozilla is running will get clobbered by
   Mozilla.


.. class:: LWPCookieJar(filename, delayload=None, policy=None)

   A :class:`FileCookieJar` that can load from and save cookies to disk in format
   compatible with the libwww-perl library's ``Set-Cookie3`` file format.  This is
   convenient if you want to store cookies in a human-readable file.


.. _cookie-policy-objects:

CookiePolicy Objects
--------------------

Objects implementing the :class:`CookiePolicy` interface have the following
methods:


.. method:: CookiePolicy.set_ok(cookie, request)

   Return boolean value indicating whether cookie should be accepted from server.

   *cookie* is a :class:`Cookie` instance.  *request* is an object
   implementing the interface defined by the documentation for
   :meth:`CookieJar.extract_cookies`.


.. method:: CookiePolicy.return_ok(cookie, request)

   Return boolean value indicating whether cookie should be returned to server.

   *cookie* is a :class:`Cookie` instance.  *request* is an object
   implementing the interface defined by the documentation for
   :meth:`CookieJar.add_cookie_header`.


.. method:: CookiePolicy.domain_return_ok(domain, request)

   Return false if cookies should not be returned, given cookie domain.

   This method is an optimization.  It removes the need for checking every cookie
   with a particular domain (which might involve reading many files).  Returning
   true from :meth:`domain_return_ok` and :meth:`path_return_ok` leaves all the
   work to :meth:`return_ok`.

   If :meth:`domain_return_ok` returns true for the cookie domain,
   :meth:`path_return_ok` is called for the cookie path.  Otherwise,
   :meth:`path_return_ok` and :meth:`return_ok` are never called for that cookie
   domain.  If :meth:`path_return_ok` returns true, :meth:`return_ok` is called
   with the :class:`Cookie` object itself for a full check.  Otherwise,
   :meth:`return_ok` is never called for that cookie path.

   Note that :meth:`domain_return_ok` is called for every *cookie* domain, not just
   for the *request* domain.  For example, the function might be called with both
   ``".example.com"`` and ``"www.example.com"`` if the request domain is
   ``"www.example.com"``.  The same goes for :meth:`path_return_ok`.

   The *request* argument is as documented for :meth:`return_ok`.


.. method:: CookiePolicy.path_return_ok(path, request)

   Return false if cookies should not be returned, given cookie path.

   See the documentation for :meth:`domain_return_ok`.

In addition to implementing the methods above, implementations of the
:class:`CookiePolicy` interface must also supply the following attributes,
indicating which protocols should be used, and how.  All of these attributes may
be assigned to.


.. attribute:: CookiePolicy.netscape

   Implement Netscape protocol.


.. attribute:: CookiePolicy.rfc2965

   Implement RFC 2965 protocol.


.. attribute:: CookiePolicy.hide_cookie2

   Don't add :mailheader:`Cookie2` header to requests (the presence of this header
   indicates to the server that we understand RFC 2965 cookies).

The most useful way to define a :class:`CookiePolicy` class is by subclassing
from :class:`DefaultCookiePolicy` and overriding some or all of the methods
above.  :class:`CookiePolicy` itself may be used as a 'null policy' to allow
setting and receiving any and all cookies (this is unlikely to be useful).


.. _default-cookie-policy-objects:

DefaultCookiePolicy Objects
---------------------------

Implements the standard rules for accepting and returning cookies.

Both RFC 2965 and Netscape cookies are covered.  RFC 2965 handling is switched
off by default.

The easiest way to provide your own policy is to override this class and call
its methods in your overridden implementations before adding your own additional
checks::

   import http.cookiejar
   class MyCookiePolicy(http.cookiejar.DefaultCookiePolicy):
       def set_ok(self, cookie, request):
           if not http.cookiejar.DefaultCookiePolicy.set_ok(self, cookie, request):
               return False
           if i_dont_want_to_store_this_cookie(cookie):
               return False
           return True

In addition to the features required to implement the :class:`CookiePolicy`
interface, this class allows you to block and allow domains from setting and
receiving cookies.  There are also some strictness switches that allow you to
tighten up the rather loose Netscape protocol rules a little bit (at the cost of
blocking some benign cookies).

A domain blacklist and whitelist is provided (both off by default). Only domains
not in the blacklist and present in the whitelist (if the whitelist is active)
participate in cookie setting and returning.  Use the *blocked_domains*
constructor argument, and :meth:`blocked_domains` and
:meth:`set_blocked_domains` methods (and the corresponding argument and methods
for *allowed_domains*).  If you set a whitelist, you can turn it off again by
setting it to :const:`None`.

Domains in block or allow lists that do not start with a dot must equal the
cookie domain to be matched.  For example, ``"example.com"`` matches a blacklist
entry of ``"example.com"``, but ``"www.example.com"`` does not.  Domains that do
start with a dot are matched by more specific domains too. For example, both
``"www.example.com"`` and ``"www.coyote.example.com"`` match ``".example.com"``
(but ``"example.com"`` itself does not).  IP addresses are an exception, and
must match exactly.  For example, if blocked_domains contains ``"192.168.1.2"``
and ``".168.1.2"``, 192.168.1.2 is blocked, but 193.168.1.2 is not.

:class:`DefaultCookiePolicy` implements the following additional methods:


.. method:: DefaultCookiePolicy.blocked_domains()

   Return the sequence of blocked domains (as a tuple).


.. method:: DefaultCookiePolicy.set_blocked_domains(blocked_domains)

   Set the sequence of blocked domains.


.. method:: DefaultCookiePolicy.is_blocked(domain)

   Return whether *domain* is on the blacklist for setting or receiving cookies.


.. method:: DefaultCookiePolicy.allowed_domains()

   Return :const:`None`, or the sequence of allowed domains (as a tuple).


.. method:: DefaultCookiePolicy.set_allowed_domains(allowed_domains)

   Set the sequence of allowed domains, or :const:`None`.


.. method:: DefaultCookiePolicy.is_not_allowed(domain)

   Return whether *domain* is not on the whitelist for setting or receiving
   cookies.

:class:`DefaultCookiePolicy` instances have the following attributes, which are
all initialised from the constructor arguments of the same name, and which may
all be assigned to.


.. attribute:: DefaultCookiePolicy.rfc2109_as_netscape

   If true, request that the :class:`CookieJar` instance downgrade RFC 2109 cookies
   (ie. cookies received in a :mailheader:`Set-Cookie` header with a version
   cookie-attribute of 1) to Netscape cookies by setting the version attribute of
   the :class:`Cookie` instance to 0.  The default value is :const:`None`, in which
   case RFC 2109 cookies are downgraded if and only if RFC 2965 handling is turned
   off.  Therefore, RFC 2109 cookies are downgraded by default.


General strictness switches:

.. attribute:: DefaultCookiePolicy.strict_domain

   Don't allow sites to set two-component domains with country-code top-level
   domains like ``.co.uk``, ``.gov.uk``, ``.co.nz``.etc.  This is far from perfect
   and isn't guaranteed to work!


RFC 2965 protocol strictness switches:

.. attribute:: DefaultCookiePolicy.strict_rfc2965_unverifiable

   Follow RFC 2965 rules on unverifiable transactions (usually, an unverifiable
   transaction is one resulting from a redirect or a request for an image hosted on
   another site).  If this is false, cookies are *never* blocked on the basis of
   verifiability


Netscape protocol strictness switches:

.. attribute:: DefaultCookiePolicy.strict_ns_unverifiable

   apply RFC 2965 rules on unverifiable transactions even to Netscape cookies


.. attribute:: DefaultCookiePolicy.strict_ns_domain

   Flags indicating how strict to be with domain-matching rules for Netscape
   cookies.  See below for acceptable values.


.. attribute:: DefaultCookiePolicy.strict_ns_set_initial_dollar

   Ignore cookies in Set-Cookie: headers that have names starting with ``'$'``.


.. attribute:: DefaultCookiePolicy.strict_ns_set_path

   Don't allow setting cookies whose path doesn't path-match request URI.

:attr:`strict_ns_domain` is a collection of flags.  Its value is constructed by
or-ing together (for example, ``DomainStrictNoDots|DomainStrictNonDomain`` means
both flags are set).


.. attribute:: DefaultCookiePolicy.DomainStrictNoDots

   When setting cookies, the 'host prefix' must not contain a dot (eg.
   ``www.foo.bar.com`` can't set a cookie for ``.bar.com``, because ``www.foo``
   contains a dot).


.. attribute:: DefaultCookiePolicy.DomainStrictNonDomain

   Cookies that did not explicitly specify a ``domain`` cookie-attribute can only
   be returned to a domain equal to the domain that set the cookie (eg.
   ``spam.example.com`` won't be returned cookies from ``example.com`` that had no
   ``domain`` cookie-attribute).


.. attribute:: DefaultCookiePolicy.DomainRFC2965Match

   When setting cookies, require a full RFC 2965 domain-match.

The following attributes are provided for convenience, and are the most useful
combinations of the above flags:


.. attribute:: DefaultCookiePolicy.DomainLiberal

   Equivalent to 0 (ie. all of the above Netscape domain strictness flags switched
   off).


.. attribute:: DefaultCookiePolicy.DomainStrict

   Equivalent to ``DomainStrictNoDots|DomainStrictNonDomain``.


Cookie Objects
--------------

:class:`Cookie` instances have Python attributes roughly corresponding to the
standard cookie-attributes specified in the various cookie standards.  The
correspondence is not one-to-one, because there are complicated rules for
assigning default values, because the ``max-age`` and ``expires``
cookie-attributes contain equivalent information, and because RFC 2109 cookies
may be 'downgraded' by :mod:`http.cookiejar` from version 1 to version 0 (Netscape)
cookies.

Assignment to these attributes should not be necessary other than in rare
circumstances in a :class:`CookiePolicy` method.  The class does not enforce
internal consistency, so you should know what you're doing if you do that.


.. attribute:: Cookie.version

   Integer or :const:`None`.  Netscape cookies have :attr:`version` 0. RFC 2965 and
   RFC 2109 cookies have a ``version`` cookie-attribute of 1.  However, note that
   :mod:`http.cookiejar` may 'downgrade' RFC 2109 cookies to Netscape cookies, in which
   case :attr:`version` is 0.


.. attribute:: Cookie.name

   Cookie name (a string).


.. attribute:: Cookie.value

   Cookie value (a string), or :const:`None`.


.. attribute:: Cookie.port

   String representing a port or a set of ports (eg. '80', or '80,8080'), or
   :const:`None`.


.. attribute:: Cookie.path

   Cookie path (a string, eg. ``'/acme/rocket_launchers'``).


.. attribute:: Cookie.secure

   True if cookie should only be returned over a secure connection.


.. attribute:: Cookie.expires

   Integer expiry date in seconds since epoch, or :const:`None`.  See also the
   :meth:`is_expired` method.


.. attribute:: Cookie.discard

   True if this is a session cookie.


.. attribute:: Cookie.comment

   String comment from the server explaining the function of this cookie, or
   :const:`None`.


.. attribute:: Cookie.comment_url

   URL linking to a comment from the server explaining the function of this cookie,
   or :const:`None`.


.. attribute:: Cookie.rfc2109

   True if this cookie was received as an RFC 2109 cookie (ie. the cookie
   arrived in a :mailheader:`Set-Cookie` header, and the value of the Version
   cookie-attribute in that header was 1).  This attribute is provided because
   :mod:`http.cookiejar` may 'downgrade' RFC 2109 cookies to Netscape cookies, in
   which case :attr:`version` is 0.


.. attribute:: Cookie.port_specified

   True if a port or set of ports was explicitly specified by the server (in the
   :mailheader:`Set-Cookie` / :mailheader:`Set-Cookie2` header).


.. attribute:: Cookie.domain_specified

   True if a domain was explicitly specified by the server.


.. attribute:: Cookie.domain_initial_dot

   True if the domain explicitly specified by the server began with a dot
   (``'.'``).

Cookies may have additional non-standard cookie-attributes.  These may be
accessed using the following methods:


.. method:: Cookie.has_nonstandard_attr(name)

   Return true if cookie has the named cookie-attribute.


.. method:: Cookie.get_nonstandard_attr(name, default=None)

   If cookie has the named cookie-attribute, return its value. Otherwise, return
   *default*.


.. method:: Cookie.set_nonstandard_attr(name, value)

   Set the value of the named cookie-attribute.

The :class:`Cookie` class also defines the following method:


.. method:: Cookie.is_expired(now=None)

   True if cookie has passed the time at which the server requested it should
   expire.  If *now* is given (in seconds since the epoch), return whether the
   cookie has expired at the specified time.


Examples
--------

The first example shows the most common usage of :mod:`http.cookiejar`::

   import http.cookiejar, urllib.request
   cj = http.cookiejar.CookieJar()
   opener = urllib.request.build_opener(urllib.request.HTTPCookieProcessor(cj))
   r = opener.open("http://example.com/")

This example illustrates how to open a URL using your Netscape, Mozilla, or Lynx
cookies (assumes Unix/Netscape convention for location of the cookies file)::

   import os, http.cookiejar, urllib.request
   cj = http.cookiejar.MozillaCookieJar()
   cj.load(os.path.join(os.path.expanduser("~"), ".netscape", "cookies.txt"))
   opener = urllib.request.build_opener(urllib.request.HTTPCookieProcessor(cj))
   r = opener.open("http://example.com/")

The next example illustrates the use of :class:`DefaultCookiePolicy`. Turn on
RFC 2965 cookies, be more strict about domains when setting and returning
Netscape cookies, and block some domains from setting cookies or having them
returned::

   import urllib.request
   from http.cookiejar import CookieJar, DefaultCookiePolicy
   policy = DefaultCookiePolicy(
       rfc2965=True, strict_ns_domain=Policy.DomainStrict,
       blocked_domains=["ads.net", ".ads.net"])
   cj = CookieJar(policy)
   opener = urllib.request.build_opener(urllib.request.HTTPCookieProcessor(cj))
   r = opener.open("http://example.com/")

