symbian-qemu-0.9.1-12/python-2.6.1/Lib/test/test_cookielib.py
changeset 1 2fb8b9db1c86
equal deleted inserted replaced
0:ffa851df0825 1:2fb8b9db1c86
       
     1 # -*- coding: latin-1 -*-
       
     2 """Tests for cookielib.py."""
       
     3 
       
     4 import re, os, time
       
     5 from unittest import TestCase
       
     6 
       
     7 from test import test_support
       
     8 
       
     9 class DateTimeTests(TestCase):
       
    10 
       
    11     def test_time2isoz(self):
       
    12         from cookielib import time2isoz
       
    13 
       
    14         base = 1019227000
       
    15         day = 24*3600
       
    16         self.assertEquals(time2isoz(base), "2002-04-19 14:36:40Z")
       
    17         self.assertEquals(time2isoz(base+day), "2002-04-20 14:36:40Z")
       
    18         self.assertEquals(time2isoz(base+2*day), "2002-04-21 14:36:40Z")
       
    19         self.assertEquals(time2isoz(base+3*day), "2002-04-22 14:36:40Z")
       
    20 
       
    21         az = time2isoz()
       
    22         bz = time2isoz(500000)
       
    23         for text in (az, bz):
       
    24             self.assert_(re.search(r"^\d{4}-\d\d-\d\d \d\d:\d\d:\d\dZ$", text),
       
    25                          "bad time2isoz format: %s %s" % (az, bz))
       
    26 
       
    27     def test_http2time(self):
       
    28         from cookielib import http2time
       
    29 
       
    30         def parse_date(text):
       
    31             return time.gmtime(http2time(text))[:6]
       
    32 
       
    33         self.assertEquals(parse_date("01 Jan 2001"), (2001, 1, 1, 0, 0, 0.0))
       
    34 
       
    35         # this test will break around year 2070
       
    36         self.assertEquals(parse_date("03-Feb-20"), (2020, 2, 3, 0, 0, 0.0))
       
    37 
       
    38         # this test will break around year 2048
       
    39         self.assertEquals(parse_date("03-Feb-98"), (1998, 2, 3, 0, 0, 0.0))
       
    40 
       
    41     def test_http2time_formats(self):
       
    42         from cookielib import http2time, time2isoz
       
    43 
       
    44         # test http2time for supported dates.  Test cases with 2 digit year
       
    45         # will probably break in year 2044.
       
    46         tests = [
       
    47          'Thu, 03 Feb 1994 00:00:00 GMT',  # proposed new HTTP format
       
    48          'Thursday, 03-Feb-94 00:00:00 GMT',  # old rfc850 HTTP format
       
    49          'Thursday, 03-Feb-1994 00:00:00 GMT',  # broken rfc850 HTTP format
       
    50 
       
    51          '03 Feb 1994 00:00:00 GMT',  # HTTP format (no weekday)
       
    52          '03-Feb-94 00:00:00 GMT',  # old rfc850 (no weekday)
       
    53          '03-Feb-1994 00:00:00 GMT',  # broken rfc850 (no weekday)
       
    54          '03-Feb-1994 00:00 GMT',  # broken rfc850 (no weekday, no seconds)
       
    55          '03-Feb-1994 00:00',  # broken rfc850 (no weekday, no seconds, no tz)
       
    56 
       
    57          '03-Feb-94',  # old rfc850 HTTP format (no weekday, no time)
       
    58          '03-Feb-1994',  # broken rfc850 HTTP format (no weekday, no time)
       
    59          '03 Feb 1994',  # proposed new HTTP format (no weekday, no time)
       
    60 
       
    61          # A few tests with extra space at various places
       
    62          '  03   Feb   1994  0:00  ',
       
    63          '  03-Feb-1994  ',
       
    64         ]
       
    65 
       
    66         test_t = 760233600  # assume broken POSIX counting of seconds
       
    67         result = time2isoz(test_t)
       
    68         expected = "1994-02-03 00:00:00Z"
       
    69         self.assertEquals(result, expected,
       
    70                           "%s  =>  '%s' (%s)" % (test_t, result, expected))
       
    71 
       
    72         for s in tests:
       
    73             t = http2time(s)
       
    74             t2 = http2time(s.lower())
       
    75             t3 = http2time(s.upper())
       
    76 
       
    77             self.assert_(t == t2 == t3 == test_t,
       
    78                          "'%s'  =>  %s, %s, %s (%s)" % (s, t, t2, t3, test_t))
       
    79 
       
    80     def test_http2time_garbage(self):
       
    81         from cookielib import http2time
       
    82 
       
    83         for test in [
       
    84             '',
       
    85             'Garbage',
       
    86             'Mandag 16. September 1996',
       
    87             '01-00-1980',
       
    88             '01-13-1980',
       
    89             '00-01-1980',
       
    90             '32-01-1980',
       
    91             '01-01-1980 25:00:00',
       
    92             '01-01-1980 00:61:00',
       
    93             '01-01-1980 00:00:62',
       
    94             ]:
       
    95             self.assert_(http2time(test) is None,
       
    96                          "http2time(%s) is not None\n"
       
    97                          "http2time(test) %s" % (test, http2time(test))
       
    98                          )
       
    99 
       
   100 
       
   101 class HeaderTests(TestCase):
       
   102     def test_parse_ns_headers(self):
       
   103         from cookielib import parse_ns_headers
       
   104 
       
   105         # quotes should be stripped
       
   106         expected = [[('foo', 'bar'), ('expires', 2209069412L), ('version', '0')]]
       
   107         for hdr in [
       
   108             'foo=bar; expires=01 Jan 2040 22:23:32 GMT',
       
   109             'foo=bar; expires="01 Jan 2040 22:23:32 GMT"',
       
   110             ]:
       
   111             self.assertEquals(parse_ns_headers([hdr]), expected)
       
   112 
       
   113     def test_parse_ns_headers_special_names(self):
       
   114         # names such as 'expires' are not special in first name=value pair
       
   115         # of Set-Cookie: header
       
   116         from cookielib import parse_ns_headers
       
   117 
       
   118         # Cookie with name 'expires'
       
   119         hdr = 'expires=01 Jan 2040 22:23:32 GMT'
       
   120         expected = [[("expires", "01 Jan 2040 22:23:32 GMT"), ("version", "0")]]
       
   121         self.assertEquals(parse_ns_headers([hdr]), expected)
       
   122 
       
   123     def test_join_header_words(self):
       
   124         from cookielib import join_header_words
       
   125 
       
   126         joined = join_header_words([[("foo", None), ("bar", "baz")]])
       
   127         self.assertEquals(joined, "foo; bar=baz")
       
   128 
       
   129         self.assertEquals(join_header_words([[]]), "")
       
   130 
       
   131     def test_split_header_words(self):
       
   132         from cookielib import split_header_words
       
   133 
       
   134         tests = [
       
   135             ("foo", [[("foo", None)]]),
       
   136             ("foo=bar", [[("foo", "bar")]]),
       
   137             ("   foo   ", [[("foo", None)]]),
       
   138             ("   foo=   ", [[("foo", "")]]),
       
   139             ("   foo=", [[("foo", "")]]),
       
   140             ("   foo=   ; ", [[("foo", "")]]),
       
   141             ("   foo=   ; bar= baz ", [[("foo", ""), ("bar", "baz")]]),
       
   142             ("foo=bar bar=baz", [[("foo", "bar"), ("bar", "baz")]]),
       
   143             # doesn't really matter if this next fails, but it works ATM
       
   144             ("foo= bar=baz", [[("foo", "bar=baz")]]),
       
   145             ("foo=bar;bar=baz", [[("foo", "bar"), ("bar", "baz")]]),
       
   146             ('foo bar baz', [[("foo", None), ("bar", None), ("baz", None)]]),
       
   147             ("a, b, c", [[("a", None)], [("b", None)], [("c", None)]]),
       
   148             (r'foo; bar=baz, spam=, foo="\,\;\"", bar= ',
       
   149              [[("foo", None), ("bar", "baz")],
       
   150               [("spam", "")], [("foo", ',;"')], [("bar", "")]]),
       
   151             ]
       
   152 
       
   153         for arg, expect in tests:
       
   154             try:
       
   155                 result = split_header_words([arg])
       
   156             except:
       
   157                 import traceback, StringIO
       
   158                 f = StringIO.StringIO()
       
   159                 traceback.print_exc(None, f)
       
   160                 result = "(error -- traceback follows)\n\n%s" % f.getvalue()
       
   161             self.assertEquals(result,  expect, """
       
   162 When parsing: '%s'
       
   163 Expected:     '%s'
       
   164 Got:          '%s'
       
   165 """ % (arg, expect, result))
       
   166 
       
   167     def test_roundtrip(self):
       
   168         from cookielib import split_header_words, join_header_words
       
   169 
       
   170         tests = [
       
   171             ("foo", "foo"),
       
   172             ("foo=bar", "foo=bar"),
       
   173             ("   foo   ", "foo"),
       
   174             ("foo=", 'foo=""'),
       
   175             ("foo=bar bar=baz", "foo=bar; bar=baz"),
       
   176             ("foo=bar;bar=baz", "foo=bar; bar=baz"),
       
   177             ('foo bar baz', "foo; bar; baz"),
       
   178             (r'foo="\"" bar="\\"', r'foo="\""; bar="\\"'),
       
   179             ('foo,,,bar', 'foo, bar'),
       
   180             ('foo=bar,bar=baz', 'foo=bar, bar=baz'),
       
   181 
       
   182             ('text/html; charset=iso-8859-1',
       
   183              'text/html; charset="iso-8859-1"'),
       
   184 
       
   185             ('foo="bar"; port="80,81"; discard, bar=baz',
       
   186              'foo=bar; port="80,81"; discard, bar=baz'),
       
   187 
       
   188             (r'Basic realm="\"foo\\\\bar\""',
       
   189              r'Basic; realm="\"foo\\\\bar\""')
       
   190             ]
       
   191 
       
   192         for arg, expect in tests:
       
   193             input = split_header_words([arg])
       
   194             res = join_header_words(input)
       
   195             self.assertEquals(res, expect, """
       
   196 When parsing: '%s'
       
   197 Expected:     '%s'
       
   198 Got:          '%s'
       
   199 Input was:    '%s'
       
   200 """ % (arg, expect, res, input))
       
   201 
       
   202 
       
   203 class FakeResponse:
       
   204     def __init__(self, headers=[], url=None):
       
   205         """
       
   206         headers: list of RFC822-style 'Key: value' strings
       
   207         """
       
   208         import mimetools, StringIO
       
   209         f = StringIO.StringIO("\n".join(headers))
       
   210         self._headers = mimetools.Message(f)
       
   211         self._url = url
       
   212     def info(self): return self._headers
       
   213 
       
   214 def interact_2965(cookiejar, url, *set_cookie_hdrs):
       
   215     return _interact(cookiejar, url, set_cookie_hdrs, "Set-Cookie2")
       
   216 
       
   217 def interact_netscape(cookiejar, url, *set_cookie_hdrs):
       
   218     return _interact(cookiejar, url, set_cookie_hdrs, "Set-Cookie")
       
   219 
       
   220 def _interact(cookiejar, url, set_cookie_hdrs, hdr_name):
       
   221     """Perform a single request / response cycle, returning Cookie: header."""
       
   222     from urllib2 import Request
       
   223     req = Request(url)
       
   224     cookiejar.add_cookie_header(req)
       
   225     cookie_hdr = req.get_header("Cookie", "")
       
   226     headers = []
       
   227     for hdr in set_cookie_hdrs:
       
   228         headers.append("%s: %s" % (hdr_name, hdr))
       
   229     res = FakeResponse(headers, url)
       
   230     cookiejar.extract_cookies(res, req)
       
   231     return cookie_hdr
       
   232 
       
   233 
       
   234 class FileCookieJarTests(TestCase):
       
   235     def test_lwp_valueless_cookie(self):
       
   236         # cookies with no value should be saved and loaded consistently
       
   237         from cookielib import LWPCookieJar
       
   238         filename = test_support.TESTFN
       
   239         c = LWPCookieJar()
       
   240         interact_netscape(c, "http://www.acme.com/", 'boo')
       
   241         self.assertEqual(c._cookies["www.acme.com"]["/"]["boo"].value, None)
       
   242         try:
       
   243             c.save(filename, ignore_discard=True)
       
   244             c = LWPCookieJar()
       
   245             c.load(filename, ignore_discard=True)
       
   246         finally:
       
   247             try: os.unlink(filename)
       
   248             except OSError: pass
       
   249         self.assertEqual(c._cookies["www.acme.com"]["/"]["boo"].value, None)
       
   250 
       
   251     def test_bad_magic(self):
       
   252         from cookielib import LWPCookieJar, MozillaCookieJar, LoadError
       
   253         # IOErrors (eg. file doesn't exist) are allowed to propagate
       
   254         filename = test_support.TESTFN
       
   255         for cookiejar_class in LWPCookieJar, MozillaCookieJar:
       
   256             c = cookiejar_class()
       
   257             try:
       
   258                 c.load(filename="for this test to work, a file with this "
       
   259                                 "filename should not exist")
       
   260             except IOError, exc:
       
   261                 # exactly IOError, not LoadError
       
   262                 self.assertEqual(exc.__class__, IOError)
       
   263             else:
       
   264                 self.fail("expected IOError for invalid filename")
       
   265         # Invalid contents of cookies file (eg. bad magic string)
       
   266         # causes a LoadError.
       
   267         try:
       
   268             f = open(filename, "w")
       
   269             f.write("oops\n")
       
   270             for cookiejar_class in LWPCookieJar, MozillaCookieJar:
       
   271                 c = cookiejar_class()
       
   272                 self.assertRaises(LoadError, c.load, filename)
       
   273         finally:
       
   274             try: os.unlink(filename)
       
   275             except OSError: pass
       
   276 
       
   277 class CookieTests(TestCase):
       
   278     # XXX
       
   279     # Get rid of string comparisons where not actually testing str / repr.
       
   280     # .clear() etc.
       
   281     # IP addresses like 50 (single number, no dot) and domain-matching
       
   282     #  functions (and is_HDN)?  See draft RFC 2965 errata.
       
   283     # Strictness switches
       
   284     # is_third_party()
       
   285     # unverifiability / third-party blocking
       
   286     # Netscape cookies work the same as RFC 2965 with regard to port.
       
   287     # Set-Cookie with negative max age.
       
   288     # If turn RFC 2965 handling off, Set-Cookie2 cookies should not clobber
       
   289     #  Set-Cookie cookies.
       
   290     # Cookie2 should be sent if *any* cookies are not V1 (ie. V0 OR V2 etc.).
       
   291     # Cookies (V1 and V0) with no expiry date should be set to be discarded.
       
   292     # RFC 2965 Quoting:
       
   293     #  Should accept unquoted cookie-attribute values?  check errata draft.
       
   294     #   Which are required on the way in and out?
       
   295     #  Should always return quoted cookie-attribute values?
       
   296     # Proper testing of when RFC 2965 clobbers Netscape (waiting for errata).
       
   297     # Path-match on return (same for V0 and V1).
       
   298     # RFC 2965 acceptance and returning rules
       
   299     #  Set-Cookie2 without version attribute is rejected.
       
   300 
       
   301     # Netscape peculiarities list from Ronald Tschalar.
       
   302     # The first two still need tests, the rest are covered.
       
   303 ## - Quoting: only quotes around the expires value are recognized as such
       
   304 ##   (and yes, some folks quote the expires value); quotes around any other
       
   305 ##   value are treated as part of the value.
       
   306 ## - White space: white space around names and values is ignored
       
   307 ## - Default path: if no path parameter is given, the path defaults to the
       
   308 ##   path in the request-uri up to, but not including, the last '/'. Note
       
   309 ##   that this is entirely different from what the spec says.
       
   310 ## - Commas and other delimiters: Netscape just parses until the next ';'.
       
   311 ##   This means it will allow commas etc inside values (and yes, both
       
   312 ##   commas and equals are commonly appear in the cookie value). This also
       
   313 ##   means that if you fold multiple Set-Cookie header fields into one,
       
   314 ##   comma-separated list, it'll be a headache to parse (at least my head
       
   315 ##   starts hurting everytime I think of that code).
       
   316 ## - Expires: You'll get all sorts of date formats in the expires,
       
   317 ##   including emtpy expires attributes ("expires="). Be as flexible as you
       
   318 ##   can, and certainly don't expect the weekday to be there; if you can't
       
   319 ##   parse it, just ignore it and pretend it's a session cookie.
       
   320 ## - Domain-matching: Netscape uses the 2-dot rule for _all_ domains, not
       
   321 ##   just the 7 special TLD's listed in their spec. And folks rely on
       
   322 ##   that...
       
   323 
       
   324     def test_domain_return_ok(self):
       
   325         # test optimization: .domain_return_ok() should filter out most
       
   326         # domains in the CookieJar before we try to access them (because that
       
   327         # may require disk access -- in particular, with MSIECookieJar)
       
   328         # This is only a rough check for performance reasons, so it's not too
       
   329         # critical as long as it's sufficiently liberal.
       
   330         import cookielib, urllib2
       
   331         pol = cookielib.DefaultCookiePolicy()
       
   332         for url, domain, ok in [
       
   333             ("http://foo.bar.com/", "blah.com", False),
       
   334             ("http://foo.bar.com/", "rhubarb.blah.com", False),
       
   335             ("http://foo.bar.com/", "rhubarb.foo.bar.com", False),
       
   336             ("http://foo.bar.com/", ".foo.bar.com", True),
       
   337             ("http://foo.bar.com/", "foo.bar.com", True),
       
   338             ("http://foo.bar.com/", ".bar.com", True),
       
   339             ("http://foo.bar.com/", "com", True),
       
   340             ("http://foo.com/", "rhubarb.foo.com", False),
       
   341             ("http://foo.com/", ".foo.com", True),
       
   342             ("http://foo.com/", "foo.com", True),
       
   343             ("http://foo.com/", "com", True),
       
   344             ("http://foo/", "rhubarb.foo", False),
       
   345             ("http://foo/", ".foo", True),
       
   346             ("http://foo/", "foo", True),
       
   347             ("http://foo/", "foo.local", True),
       
   348             ("http://foo/", ".local", True),
       
   349             ]:
       
   350             request = urllib2.Request(url)
       
   351             r = pol.domain_return_ok(domain, request)
       
   352             if ok: self.assert_(r)
       
   353             else: self.assert_(not r)
       
   354 
       
   355     def test_missing_value(self):
       
   356         from cookielib import MozillaCookieJar, lwp_cookie_str
       
   357 
       
   358         # missing = sign in Cookie: header is regarded by Mozilla as a missing
       
   359         # name, and by cookielib as a missing value
       
   360         filename = test_support.TESTFN
       
   361         c = MozillaCookieJar(filename)
       
   362         interact_netscape(c, "http://www.acme.com/", 'eggs')
       
   363         interact_netscape(c, "http://www.acme.com/", '"spam"; path=/foo/')
       
   364         cookie = c._cookies["www.acme.com"]["/"]["eggs"]
       
   365         self.assert_(cookie.value is None)
       
   366         self.assertEquals(cookie.name, "eggs")
       
   367         cookie = c._cookies["www.acme.com"]['/foo/']['"spam"']
       
   368         self.assert_(cookie.value is None)
       
   369         self.assertEquals(cookie.name, '"spam"')
       
   370         self.assertEquals(lwp_cookie_str(cookie), (
       
   371             r'"spam"; path="/foo/"; domain="www.acme.com"; '
       
   372             'path_spec; discard; version=0'))
       
   373         old_str = repr(c)
       
   374         c.save(ignore_expires=True, ignore_discard=True)
       
   375         try:
       
   376             c = MozillaCookieJar(filename)
       
   377             c.revert(ignore_expires=True, ignore_discard=True)
       
   378         finally:
       
   379             os.unlink(c.filename)
       
   380         # cookies unchanged apart from lost info re. whether path was specified
       
   381         self.assertEquals(
       
   382             repr(c),
       
   383             re.sub("path_specified=%s" % True, "path_specified=%s" % False,
       
   384                    old_str)
       
   385             )
       
   386         self.assertEquals(interact_netscape(c, "http://www.acme.com/foo/"),
       
   387                           '"spam"; eggs')
       
   388 
       
   389     def test_rfc2109_handling(self):
       
   390         # RFC 2109 cookies are handled as RFC 2965 or Netscape cookies,
       
   391         # dependent on policy settings
       
   392         from cookielib import CookieJar, DefaultCookiePolicy
       
   393 
       
   394         for rfc2109_as_netscape, rfc2965, version in [
       
   395             # default according to rfc2965 if not explicitly specified
       
   396             (None, False, 0),
       
   397             (None, True, 1),
       
   398             # explicit rfc2109_as_netscape
       
   399             (False, False, None),  # version None here means no cookie stored
       
   400             (False, True, 1),
       
   401             (True, False, 0),
       
   402             (True, True, 0),
       
   403             ]:
       
   404             policy = DefaultCookiePolicy(
       
   405                 rfc2109_as_netscape=rfc2109_as_netscape,
       
   406                 rfc2965=rfc2965)
       
   407             c = CookieJar(policy)
       
   408             interact_netscape(c, "http://www.example.com/", "ni=ni; Version=1")
       
   409             try:
       
   410                 cookie = c._cookies["www.example.com"]["/"]["ni"]
       
   411             except KeyError:
       
   412                 self.assert_(version is None)  # didn't expect a stored cookie
       
   413             else:
       
   414                 self.assertEqual(cookie.version, version)
       
   415                 # 2965 cookies are unaffected
       
   416                 interact_2965(c, "http://www.example.com/",
       
   417                               "foo=bar; Version=1")
       
   418                 if rfc2965:
       
   419                     cookie2965 = c._cookies["www.example.com"]["/"]["foo"]
       
   420                     self.assertEqual(cookie2965.version, 1)
       
   421 
       
   422     def test_ns_parser(self):
       
   423         from cookielib import CookieJar, DEFAULT_HTTP_PORT
       
   424 
       
   425         c = CookieJar()
       
   426         interact_netscape(c, "http://www.acme.com/",
       
   427                           'spam=eggs; DoMain=.acme.com; port; blArgh="feep"')
       
   428         interact_netscape(c, "http://www.acme.com/", 'ni=ni; port=80,8080')
       
   429         interact_netscape(c, "http://www.acme.com:80/", 'nini=ni')
       
   430         interact_netscape(c, "http://www.acme.com:80/", 'foo=bar; expires=')
       
   431         interact_netscape(c, "http://www.acme.com:80/", 'spam=eggs; '
       
   432                           'expires="Foo Bar 25 33:22:11 3022"')
       
   433 
       
   434         cookie = c._cookies[".acme.com"]["/"]["spam"]
       
   435         self.assertEquals(cookie.domain, ".acme.com")
       
   436         self.assert_(cookie.domain_specified)
       
   437         self.assertEquals(cookie.port, DEFAULT_HTTP_PORT)
       
   438         self.assert_(not cookie.port_specified)
       
   439         # case is preserved
       
   440         self.assert_(cookie.has_nonstandard_attr("blArgh") and
       
   441                      not cookie.has_nonstandard_attr("blargh"))
       
   442 
       
   443         cookie = c._cookies["www.acme.com"]["/"]["ni"]
       
   444         self.assertEquals(cookie.domain, "www.acme.com")
       
   445         self.assert_(not cookie.domain_specified)
       
   446         self.assertEquals(cookie.port, "80,8080")
       
   447         self.assert_(cookie.port_specified)
       
   448 
       
   449         cookie = c._cookies["www.acme.com"]["/"]["nini"]
       
   450         self.assert_(cookie.port is None)
       
   451         self.assert_(not cookie.port_specified)
       
   452 
       
   453         # invalid expires should not cause cookie to be dropped
       
   454         foo = c._cookies["www.acme.com"]["/"]["foo"]
       
   455         spam = c._cookies["www.acme.com"]["/"]["foo"]
       
   456         self.assert_(foo.expires is None)
       
   457         self.assert_(spam.expires is None)
       
   458 
       
   459     def test_ns_parser_special_names(self):
       
   460         # names such as 'expires' are not special in first name=value pair
       
   461         # of Set-Cookie: header
       
   462         from cookielib import CookieJar
       
   463 
       
   464         c = CookieJar()
       
   465         interact_netscape(c, "http://www.acme.com/", 'expires=eggs')
       
   466         interact_netscape(c, "http://www.acme.com/", 'version=eggs; spam=eggs')
       
   467 
       
   468         cookies = c._cookies["www.acme.com"]["/"]
       
   469         self.assert_('expires' in cookies)
       
   470         self.assert_('version' in cookies)
       
   471 
       
   472     def test_expires(self):
       
   473         from cookielib import time2netscape, CookieJar
       
   474 
       
   475         # if expires is in future, keep cookie...
       
   476         c = CookieJar()
       
   477         future = time2netscape(time.time()+3600)
       
   478         interact_netscape(c, "http://www.acme.com/", 'spam="bar"; expires=%s' %
       
   479                           future)
       
   480         self.assertEquals(len(c), 1)
       
   481         now = time2netscape(time.time()-1)
       
   482         # ... and if in past or present, discard it
       
   483         interact_netscape(c, "http://www.acme.com/", 'foo="eggs"; expires=%s' %
       
   484                           now)
       
   485         h = interact_netscape(c, "http://www.acme.com/")
       
   486         self.assertEquals(len(c), 1)
       
   487         self.assert_('spam="bar"' in h and "foo" not in h)
       
   488 
       
   489         # max-age takes precedence over expires, and zero max-age is request to
       
   490         # delete both new cookie and any old matching cookie
       
   491         interact_netscape(c, "http://www.acme.com/", 'eggs="bar"; expires=%s' %
       
   492                           future)
       
   493         interact_netscape(c, "http://www.acme.com/", 'bar="bar"; expires=%s' %
       
   494                           future)
       
   495         self.assertEquals(len(c), 3)
       
   496         interact_netscape(c, "http://www.acme.com/", 'eggs="bar"; '
       
   497                           'expires=%s; max-age=0' % future)
       
   498         interact_netscape(c, "http://www.acme.com/", 'bar="bar"; '
       
   499                           'max-age=0; expires=%s' % future)
       
   500         h = interact_netscape(c, "http://www.acme.com/")
       
   501         self.assertEquals(len(c), 1)
       
   502 
       
   503         # test expiry at end of session for cookies with no expires attribute
       
   504         interact_netscape(c, "http://www.rhubarb.net/", 'whum="fizz"')
       
   505         self.assertEquals(len(c), 2)
       
   506         c.clear_session_cookies()
       
   507         self.assertEquals(len(c), 1)
       
   508         self.assert_('spam="bar"' in h)
       
   509 
       
   510         # XXX RFC 2965 expiry rules (some apply to V0 too)
       
   511 
       
   512     def test_default_path(self):
       
   513         from cookielib import CookieJar, DefaultCookiePolicy
       
   514 
       
   515         # RFC 2965
       
   516         pol = DefaultCookiePolicy(rfc2965=True)
       
   517 
       
   518         c = CookieJar(pol)
       
   519         interact_2965(c, "http://www.acme.com/", 'spam="bar"; Version="1"')
       
   520         self.assert_("/" in c._cookies["www.acme.com"])
       
   521 
       
   522         c = CookieJar(pol)
       
   523         interact_2965(c, "http://www.acme.com/blah", 'eggs="bar"; Version="1"')
       
   524         self.assert_("/" in c._cookies["www.acme.com"])
       
   525 
       
   526         c = CookieJar(pol)
       
   527         interact_2965(c, "http://www.acme.com/blah/rhubarb",
       
   528                       'eggs="bar"; Version="1"')
       
   529         self.assert_("/blah/" in c._cookies["www.acme.com"])
       
   530 
       
   531         c = CookieJar(pol)
       
   532         interact_2965(c, "http://www.acme.com/blah/rhubarb/",
       
   533                       'eggs="bar"; Version="1"')
       
   534         self.assert_("/blah/rhubarb/" in c._cookies["www.acme.com"])
       
   535 
       
   536         # Netscape
       
   537 
       
   538         c = CookieJar()
       
   539         interact_netscape(c, "http://www.acme.com/", 'spam="bar"')
       
   540         self.assert_("/" in c._cookies["www.acme.com"])
       
   541 
       
   542         c = CookieJar()
       
   543         interact_netscape(c, "http://www.acme.com/blah", 'eggs="bar"')
       
   544         self.assert_("/" in c._cookies["www.acme.com"])
       
   545 
       
   546         c = CookieJar()
       
   547         interact_netscape(c, "http://www.acme.com/blah/rhubarb", 'eggs="bar"')
       
   548         self.assert_("/blah" in c._cookies["www.acme.com"])
       
   549 
       
   550         c = CookieJar()
       
   551         interact_netscape(c, "http://www.acme.com/blah/rhubarb/", 'eggs="bar"')
       
   552         self.assert_("/blah/rhubarb" in c._cookies["www.acme.com"])
       
   553 
       
   554     def test_escape_path(self):
       
   555         from cookielib import escape_path
       
   556         cases = [
       
   557             # quoted safe
       
   558             ("/foo%2f/bar", "/foo%2F/bar"),
       
   559             ("/foo%2F/bar", "/foo%2F/bar"),
       
   560             # quoted %
       
   561             ("/foo%%/bar", "/foo%%/bar"),
       
   562             # quoted unsafe
       
   563             ("/fo%19o/bar", "/fo%19o/bar"),
       
   564             ("/fo%7do/bar", "/fo%7Do/bar"),
       
   565             # unquoted safe
       
   566             ("/foo/bar&", "/foo/bar&"),
       
   567             ("/foo//bar", "/foo//bar"),
       
   568             ("\176/foo/bar", "\176/foo/bar"),
       
   569             # unquoted unsafe
       
   570             ("/foo\031/bar", "/foo%19/bar"),
       
   571             ("/\175foo/bar", "/%7Dfoo/bar"),
       
   572             # unicode
       
   573             (u"/foo/bar\uabcd", "/foo/bar%EA%AF%8D"),  # UTF-8 encoded
       
   574             ]
       
   575         for arg, result in cases:
       
   576             self.assertEquals(escape_path(arg), result)
       
   577 
       
   578     def test_request_path(self):
       
   579         from urllib2 import Request
       
   580         from cookielib import request_path
       
   581         # with parameters
       
   582         req = Request("http://www.example.com/rheum/rhaponicum;"
       
   583                       "foo=bar;sing=song?apples=pears&spam=eggs#ni")
       
   584         self.assertEquals(request_path(req), "/rheum/rhaponicum;"
       
   585                      "foo=bar;sing=song?apples=pears&spam=eggs#ni")
       
   586         # without parameters
       
   587         req = Request("http://www.example.com/rheum/rhaponicum?"
       
   588                       "apples=pears&spam=eggs#ni")
       
   589         self.assertEquals(request_path(req), "/rheum/rhaponicum?"
       
   590                      "apples=pears&spam=eggs#ni")
       
   591         # missing final slash
       
   592         req = Request("http://www.example.com")
       
   593         self.assertEquals(request_path(req), "/")
       
   594 
       
   595     def test_request_port(self):
       
   596         from urllib2 import Request
       
   597         from cookielib import request_port, DEFAULT_HTTP_PORT
       
   598         req = Request("http://www.acme.com:1234/",
       
   599                       headers={"Host": "www.acme.com:4321"})
       
   600         self.assertEquals(request_port(req), "1234")
       
   601         req = Request("http://www.acme.com/",
       
   602                       headers={"Host": "www.acme.com:4321"})
       
   603         self.assertEquals(request_port(req), DEFAULT_HTTP_PORT)
       
   604 
       
   605     def test_request_host(self):
       
   606         from urllib2 import Request
       
   607         from cookielib import request_host
       
   608         # this request is illegal (RFC2616, 14.2.3)
       
   609         req = Request("http://1.1.1.1/",
       
   610                       headers={"Host": "www.acme.com:80"})
       
   611         # libwww-perl wants this response, but that seems wrong (RFC 2616,
       
   612         # section 5.2, point 1., and RFC 2965 section 1, paragraph 3)
       
   613         #self.assertEquals(request_host(req), "www.acme.com")
       
   614         self.assertEquals(request_host(req), "1.1.1.1")
       
   615         req = Request("http://www.acme.com/",
       
   616                       headers={"Host": "irrelevant.com"})
       
   617         self.assertEquals(request_host(req), "www.acme.com")
       
   618         # not actually sure this one is valid Request object, so maybe should
       
   619         # remove test for no host in url in request_host function?
       
   620         req = Request("/resource.html",
       
   621                       headers={"Host": "www.acme.com"})
       
   622         self.assertEquals(request_host(req), "www.acme.com")
       
   623         # port shouldn't be in request-host
       
   624         req = Request("http://www.acme.com:2345/resource.html",
       
   625                       headers={"Host": "www.acme.com:5432"})
       
   626         self.assertEquals(request_host(req), "www.acme.com")
       
   627 
       
   628     def test_is_HDN(self):
       
   629         from cookielib import is_HDN
       
   630         self.assert_(is_HDN("foo.bar.com"))
       
   631         self.assert_(is_HDN("1foo2.3bar4.5com"))
       
   632         self.assert_(not is_HDN("192.168.1.1"))
       
   633         self.assert_(not is_HDN(""))
       
   634         self.assert_(not is_HDN("."))
       
   635         self.assert_(not is_HDN(".foo.bar.com"))
       
   636         self.assert_(not is_HDN("..foo"))
       
   637         self.assert_(not is_HDN("foo."))
       
   638 
       
   639     def test_reach(self):
       
   640         from cookielib import reach
       
   641         self.assertEquals(reach("www.acme.com"), ".acme.com")
       
   642         self.assertEquals(reach("acme.com"), "acme.com")
       
   643         self.assertEquals(reach("acme.local"), ".local")
       
   644         self.assertEquals(reach(".local"), ".local")
       
   645         self.assertEquals(reach(".com"), ".com")
       
   646         self.assertEquals(reach("."), ".")
       
   647         self.assertEquals(reach(""), "")
       
   648         self.assertEquals(reach("192.168.0.1"), "192.168.0.1")
       
   649 
       
   650     def test_domain_match(self):
       
   651         from cookielib import domain_match, user_domain_match
       
   652         self.assert_(domain_match("192.168.1.1", "192.168.1.1"))
       
   653         self.assert_(not domain_match("192.168.1.1", ".168.1.1"))
       
   654         self.assert_(domain_match("x.y.com", "x.Y.com"))
       
   655         self.assert_(domain_match("x.y.com", ".Y.com"))
       
   656         self.assert_(not domain_match("x.y.com", "Y.com"))
       
   657         self.assert_(domain_match("a.b.c.com", ".c.com"))
       
   658         self.assert_(not domain_match(".c.com", "a.b.c.com"))
       
   659         self.assert_(domain_match("example.local", ".local"))
       
   660         self.assert_(not domain_match("blah.blah", ""))
       
   661         self.assert_(not domain_match("", ".rhubarb.rhubarb"))
       
   662         self.assert_(domain_match("", ""))
       
   663 
       
   664         self.assert_(user_domain_match("acme.com", "acme.com"))
       
   665         self.assert_(not user_domain_match("acme.com", ".acme.com"))
       
   666         self.assert_(user_domain_match("rhubarb.acme.com", ".acme.com"))
       
   667         self.assert_(user_domain_match("www.rhubarb.acme.com", ".acme.com"))
       
   668         self.assert_(user_domain_match("x.y.com", "x.Y.com"))
       
   669         self.assert_(user_domain_match("x.y.com", ".Y.com"))
       
   670         self.assert_(not user_domain_match("x.y.com", "Y.com"))
       
   671         self.assert_(user_domain_match("y.com", "Y.com"))
       
   672         self.assert_(not user_domain_match(".y.com", "Y.com"))
       
   673         self.assert_(user_domain_match(".y.com", ".Y.com"))
       
   674         self.assert_(user_domain_match("x.y.com", ".com"))
       
   675         self.assert_(not user_domain_match("x.y.com", "com"))
       
   676         self.assert_(not user_domain_match("x.y.com", "m"))
       
   677         self.assert_(not user_domain_match("x.y.com", ".m"))
       
   678         self.assert_(not user_domain_match("x.y.com", ""))
       
   679         self.assert_(not user_domain_match("x.y.com", "."))
       
   680         self.assert_(user_domain_match("192.168.1.1", "192.168.1.1"))
       
   681         # not both HDNs, so must string-compare equal to match
       
   682         self.assert_(not user_domain_match("192.168.1.1", ".168.1.1"))
       
   683         self.assert_(not user_domain_match("192.168.1.1", "."))
       
   684         # empty string is a special case
       
   685         self.assert_(not user_domain_match("192.168.1.1", ""))
       
   686 
       
   687     def test_wrong_domain(self):
       
   688         # Cookies whose effective request-host name does not domain-match the
       
   689         # domain are rejected.
       
   690 
       
   691         # XXX far from complete
       
   692         from cookielib import CookieJar
       
   693         c = CookieJar()
       
   694         interact_2965(c, "http://www.nasty.com/",
       
   695                       'foo=bar; domain=friendly.org; Version="1"')
       
   696         self.assertEquals(len(c), 0)
       
   697 
       
   698     def test_strict_domain(self):
       
   699         # Cookies whose domain is a country-code tld like .co.uk should
       
   700         # not be set if CookiePolicy.strict_domain is true.
       
   701         from cookielib import CookieJar, DefaultCookiePolicy
       
   702 
       
   703         cp = DefaultCookiePolicy(strict_domain=True)
       
   704         cj = CookieJar(policy=cp)
       
   705         interact_netscape(cj, "http://example.co.uk/", 'no=problemo')
       
   706         interact_netscape(cj, "http://example.co.uk/",
       
   707                           'okey=dokey; Domain=.example.co.uk')
       
   708         self.assertEquals(len(cj), 2)
       
   709         for pseudo_tld in [".co.uk", ".org.za", ".tx.us", ".name.us"]:
       
   710             interact_netscape(cj, "http://example.%s/" % pseudo_tld,
       
   711                               'spam=eggs; Domain=.co.uk')
       
   712             self.assertEquals(len(cj), 2)
       
   713 
       
   714     def test_two_component_domain_ns(self):
       
   715         # Netscape: .www.bar.com, www.bar.com, .bar.com, bar.com, no domain
       
   716         # should all get accepted, as should .acme.com, acme.com and no domain
       
   717         # for 2-component domains like acme.com.
       
   718         from cookielib import CookieJar, DefaultCookiePolicy
       
   719 
       
   720         c = CookieJar()
       
   721 
       
   722         # two-component V0 domain is OK
       
   723         interact_netscape(c, "http://foo.net/", 'ns=bar')
       
   724         self.assertEquals(len(c), 1)
       
   725         self.assertEquals(c._cookies["foo.net"]["/"]["ns"].value, "bar")
       
   726         self.assertEquals(interact_netscape(c, "http://foo.net/"), "ns=bar")
       
   727         # *will* be returned to any other domain (unlike RFC 2965)...
       
   728         self.assertEquals(interact_netscape(c, "http://www.foo.net/"),
       
   729                           "ns=bar")
       
   730         # ...unless requested otherwise
       
   731         pol = DefaultCookiePolicy(
       
   732             strict_ns_domain=DefaultCookiePolicy.DomainStrictNonDomain)
       
   733         c.set_policy(pol)
       
   734         self.assertEquals(interact_netscape(c, "http://www.foo.net/"), "")
       
   735 
       
   736         # unlike RFC 2965, even explicit two-component domain is OK,
       
   737         # because .foo.net matches foo.net
       
   738         interact_netscape(c, "http://foo.net/foo/",
       
   739                           'spam1=eggs; domain=foo.net')
       
   740         # even if starts with a dot -- in NS rules, .foo.net matches foo.net!
       
   741         interact_netscape(c, "http://foo.net/foo/bar/",
       
   742                           'spam2=eggs; domain=.foo.net')
       
   743         self.assertEquals(len(c), 3)
       
   744         self.assertEquals(c._cookies[".foo.net"]["/foo"]["spam1"].value,
       
   745                           "eggs")
       
   746         self.assertEquals(c._cookies[".foo.net"]["/foo/bar"]["spam2"].value,
       
   747                           "eggs")
       
   748         self.assertEquals(interact_netscape(c, "http://foo.net/foo/bar/"),
       
   749                           "spam2=eggs; spam1=eggs; ns=bar")
       
   750 
       
   751         # top-level domain is too general
       
   752         interact_netscape(c, "http://foo.net/", 'nini="ni"; domain=.net')
       
   753         self.assertEquals(len(c), 3)
       
   754 
       
   755 ##         # Netscape protocol doesn't allow non-special top level domains (such
       
   756 ##         # as co.uk) in the domain attribute unless there are at least three
       
   757 ##         # dots in it.
       
   758         # Oh yes it does!  Real implementations don't check this, and real
       
   759         # cookies (of course) rely on that behaviour.
       
   760         interact_netscape(c, "http://foo.co.uk", 'nasty=trick; domain=.co.uk')
       
   761 ##         self.assertEquals(len(c), 2)
       
   762         self.assertEquals(len(c), 4)
       
   763 
       
   764     def test_two_component_domain_rfc2965(self):
       
   765         from cookielib import CookieJar, DefaultCookiePolicy
       
   766 
       
   767         pol = DefaultCookiePolicy(rfc2965=True)
       
   768         c = CookieJar(pol)
       
   769 
       
   770         # two-component V1 domain is OK
       
   771         interact_2965(c, "http://foo.net/", 'foo=bar; Version="1"')
       
   772         self.assertEquals(len(c), 1)
       
   773         self.assertEquals(c._cookies["foo.net"]["/"]["foo"].value, "bar")
       
   774         self.assertEquals(interact_2965(c, "http://foo.net/"),
       
   775                           "$Version=1; foo=bar")
       
   776         # won't be returned to any other domain (because domain was implied)
       
   777         self.assertEquals(interact_2965(c, "http://www.foo.net/"), "")
       
   778 
       
   779         # unless domain is given explicitly, because then it must be
       
   780         # rewritten to start with a dot: foo.net --> .foo.net, which does
       
   781         # not domain-match foo.net
       
   782         interact_2965(c, "http://foo.net/foo",
       
   783                       'spam=eggs; domain=foo.net; path=/foo; Version="1"')
       
   784         self.assertEquals(len(c), 1)
       
   785         self.assertEquals(interact_2965(c, "http://foo.net/foo"),
       
   786                           "$Version=1; foo=bar")
       
   787 
       
   788         # explicit foo.net from three-component domain www.foo.net *does* get
       
   789         # set, because .foo.net domain-matches .foo.net
       
   790         interact_2965(c, "http://www.foo.net/foo/",
       
   791                       'spam=eggs; domain=foo.net; Version="1"')
       
   792         self.assertEquals(c._cookies[".foo.net"]["/foo/"]["spam"].value,
       
   793                           "eggs")
       
   794         self.assertEquals(len(c), 2)
       
   795         self.assertEquals(interact_2965(c, "http://foo.net/foo/"),
       
   796                           "$Version=1; foo=bar")
       
   797         self.assertEquals(interact_2965(c, "http://www.foo.net/foo/"),
       
   798                           '$Version=1; spam=eggs; $Domain="foo.net"')
       
   799 
       
   800         # top-level domain is too general
       
   801         interact_2965(c, "http://foo.net/",
       
   802                       'ni="ni"; domain=".net"; Version="1"')
       
   803         self.assertEquals(len(c), 2)
       
   804 
       
   805         # RFC 2965 doesn't require blocking this
       
   806         interact_2965(c, "http://foo.co.uk/",
       
   807                       'nasty=trick; domain=.co.uk; Version="1"')
       
   808         self.assertEquals(len(c), 3)
       
   809 
       
   810     def test_domain_allow(self):
       
   811         from cookielib import CookieJar, DefaultCookiePolicy
       
   812         from urllib2 import Request
       
   813 
       
   814         c = CookieJar(policy=DefaultCookiePolicy(
       
   815             blocked_domains=["acme.com"],
       
   816             allowed_domains=["www.acme.com"]))
       
   817 
       
   818         req = Request("http://acme.com/")
       
   819         headers = ["Set-Cookie: CUSTOMER=WILE_E_COYOTE; path=/"]
       
   820         res = FakeResponse(headers, "http://acme.com/")
       
   821         c.extract_cookies(res, req)
       
   822         self.assertEquals(len(c), 0)
       
   823 
       
   824         req = Request("http://www.acme.com/")
       
   825         res = FakeResponse(headers, "http://www.acme.com/")
       
   826         c.extract_cookies(res, req)
       
   827         self.assertEquals(len(c), 1)
       
   828 
       
   829         req = Request("http://www.coyote.com/")
       
   830         res = FakeResponse(headers, "http://www.coyote.com/")
       
   831         c.extract_cookies(res, req)
       
   832         self.assertEquals(len(c), 1)
       
   833 
       
   834         # set a cookie with non-allowed domain...
       
   835         req = Request("http://www.coyote.com/")
       
   836         res = FakeResponse(headers, "http://www.coyote.com/")
       
   837         cookies = c.make_cookies(res, req)
       
   838         c.set_cookie(cookies[0])
       
   839         self.assertEquals(len(c), 2)
       
   840         # ... and check is doesn't get returned
       
   841         c.add_cookie_header(req)
       
   842         self.assert_(not req.has_header("Cookie"))
       
   843 
       
   844     def test_domain_block(self):
       
   845         from cookielib import CookieJar, DefaultCookiePolicy
       
   846         from urllib2 import Request
       
   847 
       
   848         pol = DefaultCookiePolicy(
       
   849             rfc2965=True, blocked_domains=[".acme.com"])
       
   850         c = CookieJar(policy=pol)
       
   851         headers = ["Set-Cookie: CUSTOMER=WILE_E_COYOTE; path=/"]
       
   852 
       
   853         req = Request("http://www.acme.com/")
       
   854         res = FakeResponse(headers, "http://www.acme.com/")
       
   855         c.extract_cookies(res, req)
       
   856         self.assertEquals(len(c), 0)
       
   857 
       
   858         p = pol.set_blocked_domains(["acme.com"])
       
   859         c.extract_cookies(res, req)
       
   860         self.assertEquals(len(c), 1)
       
   861 
       
   862         c.clear()
       
   863         req = Request("http://www.roadrunner.net/")
       
   864         res = FakeResponse(headers, "http://www.roadrunner.net/")
       
   865         c.extract_cookies(res, req)
       
   866         self.assertEquals(len(c), 1)
       
   867         req = Request("http://www.roadrunner.net/")
       
   868         c.add_cookie_header(req)
       
   869         self.assert_((req.has_header("Cookie") and
       
   870                       req.has_header("Cookie2")))
       
   871 
       
   872         c.clear()
       
   873         pol.set_blocked_domains([".acme.com"])
       
   874         c.extract_cookies(res, req)
       
   875         self.assertEquals(len(c), 1)
       
   876 
       
   877         # set a cookie with blocked domain...
       
   878         req = Request("http://www.acme.com/")
       
   879         res = FakeResponse(headers, "http://www.acme.com/")
       
   880         cookies = c.make_cookies(res, req)
       
   881         c.set_cookie(cookies[0])
       
   882         self.assertEquals(len(c), 2)
       
   883         # ... and check is doesn't get returned
       
   884         c.add_cookie_header(req)
       
   885         self.assert_(not req.has_header("Cookie"))
       
   886 
       
   887     def test_secure(self):
       
   888         from cookielib import CookieJar, DefaultCookiePolicy
       
   889 
       
   890         for ns in True, False:
       
   891             for whitespace in " ", "":
       
   892                 c = CookieJar()
       
   893                 if ns:
       
   894                     pol = DefaultCookiePolicy(rfc2965=False)
       
   895                     int = interact_netscape
       
   896                     vs = ""
       
   897                 else:
       
   898                     pol = DefaultCookiePolicy(rfc2965=True)
       
   899                     int = interact_2965
       
   900                     vs = "; Version=1"
       
   901                 c.set_policy(pol)
       
   902                 url = "http://www.acme.com/"
       
   903                 int(c, url, "foo1=bar%s%s" % (vs, whitespace))
       
   904                 int(c, url, "foo2=bar%s; secure%s" %  (vs, whitespace))
       
   905                 self.assert_(
       
   906                     not c._cookies["www.acme.com"]["/"]["foo1"].secure,
       
   907                     "non-secure cookie registered secure")
       
   908                 self.assert_(
       
   909                     c._cookies["www.acme.com"]["/"]["foo2"].secure,
       
   910                     "secure cookie registered non-secure")
       
   911 
       
   912     def test_quote_cookie_value(self):
       
   913         from cookielib import CookieJar, DefaultCookiePolicy
       
   914         c = CookieJar(policy=DefaultCookiePolicy(rfc2965=True))
       
   915         interact_2965(c, "http://www.acme.com/", r'foo=\b"a"r; Version=1')
       
   916         h = interact_2965(c, "http://www.acme.com/")
       
   917         self.assertEquals(h, r'$Version=1; foo=\\b\"a\"r')
       
   918 
       
   919     def test_missing_final_slash(self):
       
   920         # Missing slash from request URL's abs_path should be assumed present.
       
   921         from cookielib import CookieJar, DefaultCookiePolicy
       
   922         from urllib2 import Request
       
   923         url = "http://www.acme.com"
       
   924         c = CookieJar(DefaultCookiePolicy(rfc2965=True))
       
   925         interact_2965(c, url, "foo=bar; Version=1")
       
   926         req = Request(url)
       
   927         self.assertEquals(len(c), 1)
       
   928         c.add_cookie_header(req)
       
   929         self.assert_(req.has_header("Cookie"))
       
   930 
       
   931     def test_domain_mirror(self):
       
   932         from cookielib import CookieJar, DefaultCookiePolicy
       
   933 
       
   934         pol = DefaultCookiePolicy(rfc2965=True)
       
   935 
       
   936         c = CookieJar(pol)
       
   937         url = "http://foo.bar.com/"
       
   938         interact_2965(c, url, "spam=eggs; Version=1")
       
   939         h = interact_2965(c, url)
       
   940         self.assert_("Domain" not in h,
       
   941                      "absent domain returned with domain present")
       
   942 
       
   943         c = CookieJar(pol)
       
   944         url = "http://foo.bar.com/"
       
   945         interact_2965(c, url, 'spam=eggs; Version=1; Domain=.bar.com')
       
   946         h = interact_2965(c, url)
       
   947         self.assert_('$Domain=".bar.com"' in h, "domain not returned")
       
   948 
       
   949         c = CookieJar(pol)
       
   950         url = "http://foo.bar.com/"
       
   951         # note missing initial dot in Domain
       
   952         interact_2965(c, url, 'spam=eggs; Version=1; Domain=bar.com')
       
   953         h = interact_2965(c, url)
       
   954         self.assert_('$Domain="bar.com"' in h, "domain not returned")
       
   955 
       
   956     def test_path_mirror(self):
       
   957         from cookielib import CookieJar, DefaultCookiePolicy
       
   958 
       
   959         pol = DefaultCookiePolicy(rfc2965=True)
       
   960 
       
   961         c = CookieJar(pol)
       
   962         url = "http://foo.bar.com/"
       
   963         interact_2965(c, url, "spam=eggs; Version=1")
       
   964         h = interact_2965(c, url)
       
   965         self.assert_("Path" not in h,
       
   966                      "absent path returned with path present")
       
   967 
       
   968         c = CookieJar(pol)
       
   969         url = "http://foo.bar.com/"
       
   970         interact_2965(c, url, 'spam=eggs; Version=1; Path=/')
       
   971         h = interact_2965(c, url)
       
   972         self.assert_('$Path="/"' in h, "path not returned")
       
   973 
       
   974     def test_port_mirror(self):
       
   975         from cookielib import CookieJar, DefaultCookiePolicy
       
   976 
       
   977         pol = DefaultCookiePolicy(rfc2965=True)
       
   978 
       
   979         c = CookieJar(pol)
       
   980         url = "http://foo.bar.com/"
       
   981         interact_2965(c, url, "spam=eggs; Version=1")
       
   982         h = interact_2965(c, url)
       
   983         self.assert_("Port" not in h,
       
   984                      "absent port returned with port present")
       
   985 
       
   986         c = CookieJar(pol)
       
   987         url = "http://foo.bar.com/"
       
   988         interact_2965(c, url, "spam=eggs; Version=1; Port")
       
   989         h = interact_2965(c, url)
       
   990         self.assert_(re.search("\$Port([^=]|$)", h),
       
   991                      "port with no value not returned with no value")
       
   992 
       
   993         c = CookieJar(pol)
       
   994         url = "http://foo.bar.com/"
       
   995         interact_2965(c, url, 'spam=eggs; Version=1; Port="80"')
       
   996         h = interact_2965(c, url)
       
   997         self.assert_('$Port="80"' in h,
       
   998                      "port with single value not returned with single value")
       
   999 
       
  1000         c = CookieJar(pol)
       
  1001         url = "http://foo.bar.com/"
       
  1002         interact_2965(c, url, 'spam=eggs; Version=1; Port="80,8080"')
       
  1003         h = interact_2965(c, url)
       
  1004         self.assert_('$Port="80,8080"' in h,
       
  1005                      "port with multiple values not returned with multiple "
       
  1006                      "values")
       
  1007 
       
  1008     def test_no_return_comment(self):
       
  1009         from cookielib import CookieJar, DefaultCookiePolicy
       
  1010 
       
  1011         c = CookieJar(DefaultCookiePolicy(rfc2965=True))
       
  1012         url = "http://foo.bar.com/"
       
  1013         interact_2965(c, url, 'spam=eggs; Version=1; '
       
  1014                       'Comment="does anybody read these?"; '
       
  1015                       'CommentURL="http://foo.bar.net/comment.html"')
       
  1016         h = interact_2965(c, url)
       
  1017         self.assert_(
       
  1018             "Comment" not in h,
       
  1019             "Comment or CommentURL cookie-attributes returned to server")
       
  1020 
       
  1021     def test_Cookie_iterator(self):
       
  1022         from cookielib import CookieJar, Cookie, DefaultCookiePolicy
       
  1023 
       
  1024         cs = CookieJar(DefaultCookiePolicy(rfc2965=True))
       
  1025         # add some random cookies
       
  1026         interact_2965(cs, "http://blah.spam.org/", 'foo=eggs; Version=1; '
       
  1027                       'Comment="does anybody read these?"; '
       
  1028                       'CommentURL="http://foo.bar.net/comment.html"')
       
  1029         interact_netscape(cs, "http://www.acme.com/blah/", "spam=bar; secure")
       
  1030         interact_2965(cs, "http://www.acme.com/blah/",
       
  1031                       "foo=bar; secure; Version=1")
       
  1032         interact_2965(cs, "http://www.acme.com/blah/",
       
  1033                       "foo=bar; path=/; Version=1")
       
  1034         interact_2965(cs, "http://www.sol.no",
       
  1035                       r'bang=wallop; version=1; domain=".sol.no"; '
       
  1036                       r'port="90,100, 80,8080"; '
       
  1037                       r'max-age=100; Comment = "Just kidding! (\"|\\\\) "')
       
  1038 
       
  1039         versions = [1, 1, 1, 0, 1]
       
  1040         names = ["bang", "foo", "foo", "spam", "foo"]
       
  1041         domains = [".sol.no", "blah.spam.org", "www.acme.com",
       
  1042                    "www.acme.com", "www.acme.com"]
       
  1043         paths = ["/", "/", "/", "/blah", "/blah/"]
       
  1044 
       
  1045         for i in range(4):
       
  1046             i = 0
       
  1047             for c in cs:
       
  1048                 self.assert_(isinstance(c, Cookie))
       
  1049                 self.assertEquals(c.version, versions[i])
       
  1050                 self.assertEquals(c.name, names[i])
       
  1051                 self.assertEquals(c.domain, domains[i])
       
  1052                 self.assertEquals(c.path, paths[i])
       
  1053                 i = i + 1
       
  1054 
       
  1055     def test_parse_ns_headers(self):
       
  1056         from cookielib import parse_ns_headers
       
  1057 
       
  1058         # missing domain value (invalid cookie)
       
  1059         self.assertEquals(
       
  1060             parse_ns_headers(["foo=bar; path=/; domain"]),
       
  1061             [[("foo", "bar"),
       
  1062               ("path", "/"), ("domain", None), ("version", "0")]]
       
  1063             )
       
  1064         # invalid expires value
       
  1065         self.assertEquals(
       
  1066             parse_ns_headers(["foo=bar; expires=Foo Bar 12 33:22:11 2000"]),
       
  1067             [[("foo", "bar"), ("expires", None), ("version", "0")]]
       
  1068             )
       
  1069         # missing cookie value (valid cookie)
       
  1070         self.assertEquals(
       
  1071             parse_ns_headers(["foo"]),
       
  1072             [[("foo", None), ("version", "0")]]
       
  1073             )
       
  1074         # shouldn't add version if header is empty
       
  1075         self.assertEquals(parse_ns_headers([""]), [])
       
  1076 
       
  1077     def test_bad_cookie_header(self):
       
  1078 
       
  1079         def cookiejar_from_cookie_headers(headers):
       
  1080             from cookielib import CookieJar
       
  1081             from urllib2 import Request
       
  1082             c = CookieJar()
       
  1083             req = Request("http://www.example.com/")
       
  1084             r = FakeResponse(headers, "http://www.example.com/")
       
  1085             c.extract_cookies(r, req)
       
  1086             return c
       
  1087 
       
  1088         # none of these bad headers should cause an exception to be raised
       
  1089         for headers in [
       
  1090             ["Set-Cookie: "],  # actually, nothing wrong with this
       
  1091             ["Set-Cookie2: "],  # ditto
       
  1092             # missing domain value
       
  1093             ["Set-Cookie2: a=foo; path=/; Version=1; domain"],
       
  1094             # bad max-age
       
  1095             ["Set-Cookie: b=foo; max-age=oops"],
       
  1096             ]:
       
  1097             c = cookiejar_from_cookie_headers(headers)
       
  1098             # these bad cookies shouldn't be set
       
  1099             self.assertEquals(len(c), 0)
       
  1100 
       
  1101         # cookie with invalid expires is treated as session cookie
       
  1102         headers = ["Set-Cookie: c=foo; expires=Foo Bar 12 33:22:11 2000"]
       
  1103         c = cookiejar_from_cookie_headers(headers)
       
  1104         cookie = c._cookies["www.example.com"]["/"]["c"]
       
  1105         self.assert_(cookie.expires is None)
       
  1106 
       
  1107 
       
  1108 class LWPCookieTests(TestCase):
       
  1109     # Tests taken from libwww-perl, with a few modifications and additions.
       
  1110 
       
  1111     def test_netscape_example_1(self):
       
  1112         from cookielib import CookieJar, DefaultCookiePolicy
       
  1113         from urllib2 import Request
       
  1114 
       
  1115         #-------------------------------------------------------------------
       
  1116         # First we check that it works for the original example at
       
  1117         # http://www.netscape.com/newsref/std/cookie_spec.html
       
  1118 
       
  1119         # Client requests a document, and receives in the response:
       
  1120         #
       
  1121         #       Set-Cookie: CUSTOMER=WILE_E_COYOTE; path=/; expires=Wednesday, 09-Nov-99 23:12:40 GMT
       
  1122         #
       
  1123         # When client requests a URL in path "/" on this server, it sends:
       
  1124         #
       
  1125         #       Cookie: CUSTOMER=WILE_E_COYOTE
       
  1126         #
       
  1127         # Client requests a document, and receives in the response:
       
  1128         #
       
  1129         #       Set-Cookie: PART_NUMBER=ROCKET_LAUNCHER_0001; path=/
       
  1130         #
       
  1131         # When client requests a URL in path "/" on this server, it sends:
       
  1132         #
       
  1133         #       Cookie: CUSTOMER=WILE_E_COYOTE; PART_NUMBER=ROCKET_LAUNCHER_0001
       
  1134         #
       
  1135         # Client receives:
       
  1136         #
       
  1137         #       Set-Cookie: SHIPPING=FEDEX; path=/fo
       
  1138         #
       
  1139         # When client requests a URL in path "/" on this server, it sends:
       
  1140         #
       
  1141         #       Cookie: CUSTOMER=WILE_E_COYOTE; PART_NUMBER=ROCKET_LAUNCHER_0001
       
  1142         #
       
  1143         # When client requests a URL in path "/foo" on this server, it sends:
       
  1144         #
       
  1145         #       Cookie: CUSTOMER=WILE_E_COYOTE; PART_NUMBER=ROCKET_LAUNCHER_0001; SHIPPING=FEDEX
       
  1146         #
       
  1147         # The last Cookie is buggy, because both specifications say that the
       
  1148         # most specific cookie must be sent first.  SHIPPING=FEDEX is the
       
  1149         # most specific and should thus be first.
       
  1150 
       
  1151         year_plus_one = time.localtime()[0] + 1
       
  1152 
       
  1153         headers = []
       
  1154 
       
  1155         c = CookieJar(DefaultCookiePolicy(rfc2965 = True))
       
  1156 
       
  1157         #req = Request("http://1.1.1.1/",
       
  1158         #              headers={"Host": "www.acme.com:80"})
       
  1159         req = Request("http://www.acme.com:80/",
       
  1160                       headers={"Host": "www.acme.com:80"})
       
  1161 
       
  1162         headers.append(
       
  1163             "Set-Cookie: CUSTOMER=WILE_E_COYOTE; path=/ ; "
       
  1164             "expires=Wednesday, 09-Nov-%d 23:12:40 GMT" % year_plus_one)
       
  1165         res = FakeResponse(headers, "http://www.acme.com/")
       
  1166         c.extract_cookies(res, req)
       
  1167 
       
  1168         req = Request("http://www.acme.com/")
       
  1169         c.add_cookie_header(req)
       
  1170 
       
  1171         self.assertEqual(req.get_header("Cookie"), "CUSTOMER=WILE_E_COYOTE")
       
  1172         self.assertEqual(req.get_header("Cookie2"), '$Version="1"')
       
  1173 
       
  1174         headers.append("Set-Cookie: PART_NUMBER=ROCKET_LAUNCHER_0001; path=/")
       
  1175         res = FakeResponse(headers, "http://www.acme.com/")
       
  1176         c.extract_cookies(res, req)
       
  1177 
       
  1178         req = Request("http://www.acme.com/foo/bar")
       
  1179         c.add_cookie_header(req)
       
  1180 
       
  1181         h = req.get_header("Cookie")
       
  1182         self.assert_("PART_NUMBER=ROCKET_LAUNCHER_0001" in h and
       
  1183                      "CUSTOMER=WILE_E_COYOTE" in h)
       
  1184 
       
  1185         headers.append('Set-Cookie: SHIPPING=FEDEX; path=/foo')
       
  1186         res = FakeResponse(headers, "http://www.acme.com")
       
  1187         c.extract_cookies(res, req)
       
  1188 
       
  1189         req = Request("http://www.acme.com/")
       
  1190         c.add_cookie_header(req)
       
  1191 
       
  1192         h = req.get_header("Cookie")
       
  1193         self.assert_("PART_NUMBER=ROCKET_LAUNCHER_0001" in h and
       
  1194                      "CUSTOMER=WILE_E_COYOTE" in h and
       
  1195                      "SHIPPING=FEDEX" not in h)
       
  1196 
       
  1197         req = Request("http://www.acme.com/foo/")
       
  1198         c.add_cookie_header(req)
       
  1199 
       
  1200         h = req.get_header("Cookie")
       
  1201         self.assert_(("PART_NUMBER=ROCKET_LAUNCHER_0001" in h and
       
  1202                       "CUSTOMER=WILE_E_COYOTE" in h and
       
  1203                       h.startswith("SHIPPING=FEDEX;")))
       
  1204 
       
  1205     def test_netscape_example_2(self):
       
  1206         from cookielib import CookieJar
       
  1207         from urllib2 import Request
       
  1208 
       
  1209         # Second Example transaction sequence:
       
  1210         #
       
  1211         # Assume all mappings from above have been cleared.
       
  1212         #
       
  1213         # Client receives:
       
  1214         #
       
  1215         #       Set-Cookie: PART_NUMBER=ROCKET_LAUNCHER_0001; path=/
       
  1216         #
       
  1217         # When client requests a URL in path "/" on this server, it sends:
       
  1218         #
       
  1219         #       Cookie: PART_NUMBER=ROCKET_LAUNCHER_0001
       
  1220         #
       
  1221         # Client receives:
       
  1222         #
       
  1223         #       Set-Cookie: PART_NUMBER=RIDING_ROCKET_0023; path=/ammo
       
  1224         #
       
  1225         # When client requests a URL in path "/ammo" on this server, it sends:
       
  1226         #
       
  1227         #       Cookie: PART_NUMBER=RIDING_ROCKET_0023; PART_NUMBER=ROCKET_LAUNCHER_0001
       
  1228         #
       
  1229         #       NOTE: There are two name/value pairs named "PART_NUMBER" due to
       
  1230         #       the inheritance of the "/" mapping in addition to the "/ammo" mapping.
       
  1231 
       
  1232         c = CookieJar()
       
  1233         headers = []
       
  1234 
       
  1235         req = Request("http://www.acme.com/")
       
  1236         headers.append("Set-Cookie: PART_NUMBER=ROCKET_LAUNCHER_0001; path=/")
       
  1237         res = FakeResponse(headers, "http://www.acme.com/")
       
  1238 
       
  1239         c.extract_cookies(res, req)
       
  1240 
       
  1241         req = Request("http://www.acme.com/")
       
  1242         c.add_cookie_header(req)
       
  1243 
       
  1244         self.assertEquals(req.get_header("Cookie"),
       
  1245                           "PART_NUMBER=ROCKET_LAUNCHER_0001")
       
  1246 
       
  1247         headers.append(
       
  1248             "Set-Cookie: PART_NUMBER=RIDING_ROCKET_0023; path=/ammo")
       
  1249         res = FakeResponse(headers, "http://www.acme.com/")
       
  1250         c.extract_cookies(res, req)
       
  1251 
       
  1252         req = Request("http://www.acme.com/ammo")
       
  1253         c.add_cookie_header(req)
       
  1254 
       
  1255         self.assert_(re.search(r"PART_NUMBER=RIDING_ROCKET_0023;\s*"
       
  1256                                "PART_NUMBER=ROCKET_LAUNCHER_0001",
       
  1257                                req.get_header("Cookie")))
       
  1258 
       
  1259     def test_ietf_example_1(self):
       
  1260         from cookielib import CookieJar, DefaultCookiePolicy
       
  1261         #-------------------------------------------------------------------
       
  1262         # Then we test with the examples from draft-ietf-http-state-man-mec-03.txt
       
  1263         #
       
  1264         # 5.  EXAMPLES
       
  1265 
       
  1266         c = CookieJar(DefaultCookiePolicy(rfc2965=True))
       
  1267 
       
  1268         #
       
  1269         # 5.1  Example 1
       
  1270         #
       
  1271         # Most detail of request and response headers has been omitted.  Assume
       
  1272         # the user agent has no stored cookies.
       
  1273         #
       
  1274         #   1.  User Agent -> Server
       
  1275         #
       
  1276         #       POST /acme/login HTTP/1.1
       
  1277         #       [form data]
       
  1278         #
       
  1279         #       User identifies self via a form.
       
  1280         #
       
  1281         #   2.  Server -> User Agent
       
  1282         #
       
  1283         #       HTTP/1.1 200 OK
       
  1284         #       Set-Cookie2: Customer="WILE_E_COYOTE"; Version="1"; Path="/acme"
       
  1285         #
       
  1286         #       Cookie reflects user's identity.
       
  1287 
       
  1288         cookie = interact_2965(
       
  1289             c, 'http://www.acme.com/acme/login',
       
  1290             'Customer="WILE_E_COYOTE"; Version="1"; Path="/acme"')
       
  1291         self.assert_(not cookie)
       
  1292 
       
  1293         #
       
  1294         #   3.  User Agent -> Server
       
  1295         #
       
  1296         #       POST /acme/pickitem HTTP/1.1
       
  1297         #       Cookie: $Version="1"; Customer="WILE_E_COYOTE"; $Path="/acme"
       
  1298         #       [form data]
       
  1299         #
       
  1300         #       User selects an item for ``shopping basket.''
       
  1301         #
       
  1302         #   4.  Server -> User Agent
       
  1303         #
       
  1304         #       HTTP/1.1 200 OK
       
  1305         #       Set-Cookie2: Part_Number="Rocket_Launcher_0001"; Version="1";
       
  1306         #               Path="/acme"
       
  1307         #
       
  1308         #       Shopping basket contains an item.
       
  1309 
       
  1310         cookie = interact_2965(c, 'http://www.acme.com/acme/pickitem',
       
  1311                                'Part_Number="Rocket_Launcher_0001"; '
       
  1312                                'Version="1"; Path="/acme"');
       
  1313         self.assert_(re.search(
       
  1314             r'^\$Version="?1"?; Customer="?WILE_E_COYOTE"?; \$Path="/acme"$',
       
  1315             cookie))
       
  1316 
       
  1317         #
       
  1318         #   5.  User Agent -> Server
       
  1319         #
       
  1320         #       POST /acme/shipping HTTP/1.1
       
  1321         #       Cookie: $Version="1";
       
  1322         #               Customer="WILE_E_COYOTE"; $Path="/acme";
       
  1323         #               Part_Number="Rocket_Launcher_0001"; $Path="/acme"
       
  1324         #       [form data]
       
  1325         #
       
  1326         #       User selects shipping method from form.
       
  1327         #
       
  1328         #   6.  Server -> User Agent
       
  1329         #
       
  1330         #       HTTP/1.1 200 OK
       
  1331         #       Set-Cookie2: Shipping="FedEx"; Version="1"; Path="/acme"
       
  1332         #
       
  1333         #       New cookie reflects shipping method.
       
  1334 
       
  1335         cookie = interact_2965(c, "http://www.acme.com/acme/shipping",
       
  1336                                'Shipping="FedEx"; Version="1"; Path="/acme"')
       
  1337 
       
  1338         self.assert_(re.search(r'^\$Version="?1"?;', cookie))
       
  1339         self.assert_(re.search(r'Part_Number="?Rocket_Launcher_0001"?;'
       
  1340                                '\s*\$Path="\/acme"', cookie))
       
  1341         self.assert_(re.search(r'Customer="?WILE_E_COYOTE"?;\s*\$Path="\/acme"',
       
  1342                                cookie))
       
  1343 
       
  1344         #
       
  1345         #   7.  User Agent -> Server
       
  1346         #
       
  1347         #       POST /acme/process HTTP/1.1
       
  1348         #       Cookie: $Version="1";
       
  1349         #               Customer="WILE_E_COYOTE"; $Path="/acme";
       
  1350         #               Part_Number="Rocket_Launcher_0001"; $Path="/acme";
       
  1351         #               Shipping="FedEx"; $Path="/acme"
       
  1352         #       [form data]
       
  1353         #
       
  1354         #       User chooses to process order.
       
  1355         #
       
  1356         #   8.  Server -> User Agent
       
  1357         #
       
  1358         #       HTTP/1.1 200 OK
       
  1359         #
       
  1360         #       Transaction is complete.
       
  1361 
       
  1362         cookie = interact_2965(c, "http://www.acme.com/acme/process")
       
  1363         self.assert_(
       
  1364             re.search(r'Shipping="?FedEx"?;\s*\$Path="\/acme"', cookie) and
       
  1365             "WILE_E_COYOTE" in cookie)
       
  1366 
       
  1367         #
       
  1368         # The user agent makes a series of requests on the origin server, after
       
  1369         # each of which it receives a new cookie.  All the cookies have the same
       
  1370         # Path attribute and (default) domain.  Because the request URLs all have
       
  1371         # /acme as a prefix, and that matches the Path attribute, each request
       
  1372         # contains all the cookies received so far.
       
  1373 
       
  1374     def test_ietf_example_2(self):
       
  1375         from cookielib import CookieJar, DefaultCookiePolicy
       
  1376 
       
  1377         # 5.2  Example 2
       
  1378         #
       
  1379         # This example illustrates the effect of the Path attribute.  All detail
       
  1380         # of request and response headers has been omitted.  Assume the user agent
       
  1381         # has no stored cookies.
       
  1382 
       
  1383         c = CookieJar(DefaultCookiePolicy(rfc2965=True))
       
  1384 
       
  1385         # Imagine the user agent has received, in response to earlier requests,
       
  1386         # the response headers
       
  1387         #
       
  1388         # Set-Cookie2: Part_Number="Rocket_Launcher_0001"; Version="1";
       
  1389         #         Path="/acme"
       
  1390         #
       
  1391         # and
       
  1392         #
       
  1393         # Set-Cookie2: Part_Number="Riding_Rocket_0023"; Version="1";
       
  1394         #         Path="/acme/ammo"
       
  1395 
       
  1396         interact_2965(
       
  1397             c, "http://www.acme.com/acme/ammo/specific",
       
  1398             'Part_Number="Rocket_Launcher_0001"; Version="1"; Path="/acme"',
       
  1399             'Part_Number="Riding_Rocket_0023"; Version="1"; Path="/acme/ammo"')
       
  1400 
       
  1401         # A subsequent request by the user agent to the (same) server for URLs of
       
  1402         # the form /acme/ammo/...  would include the following request header:
       
  1403         #
       
  1404         # Cookie: $Version="1";
       
  1405         #         Part_Number="Riding_Rocket_0023"; $Path="/acme/ammo";
       
  1406         #         Part_Number="Rocket_Launcher_0001"; $Path="/acme"
       
  1407         #
       
  1408         # Note that the NAME=VALUE pair for the cookie with the more specific Path
       
  1409         # attribute, /acme/ammo, comes before the one with the less specific Path
       
  1410         # attribute, /acme.  Further note that the same cookie name appears more
       
  1411         # than once.
       
  1412 
       
  1413         cookie = interact_2965(c, "http://www.acme.com/acme/ammo/...")
       
  1414         self.assert_(
       
  1415             re.search(r"Riding_Rocket_0023.*Rocket_Launcher_0001", cookie))
       
  1416 
       
  1417         # A subsequent request by the user agent to the (same) server for a URL of
       
  1418         # the form /acme/parts/ would include the following request header:
       
  1419         #
       
  1420         # Cookie: $Version="1"; Part_Number="Rocket_Launcher_0001"; $Path="/acme"
       
  1421         #
       
  1422         # Here, the second cookie's Path attribute /acme/ammo is not a prefix of
       
  1423         # the request URL, /acme/parts/, so the cookie does not get forwarded to
       
  1424         # the server.
       
  1425 
       
  1426         cookie = interact_2965(c, "http://www.acme.com/acme/parts/")
       
  1427         self.assert_("Rocket_Launcher_0001" in cookie and
       
  1428                      "Riding_Rocket_0023" not in cookie)
       
  1429 
       
  1430     def test_rejection(self):
       
  1431         # Test rejection of Set-Cookie2 responses based on domain, path, port.
       
  1432         from cookielib import DefaultCookiePolicy, LWPCookieJar
       
  1433 
       
  1434         pol = DefaultCookiePolicy(rfc2965=True)
       
  1435 
       
  1436         c = LWPCookieJar(policy=pol)
       
  1437 
       
  1438         max_age = "max-age=3600"
       
  1439 
       
  1440         # illegal domain (no embedded dots)
       
  1441         cookie = interact_2965(c, "http://www.acme.com",
       
  1442                                'foo=bar; domain=".com"; version=1')
       
  1443         self.assert_(not c)
       
  1444 
       
  1445         # legal domain
       
  1446         cookie = interact_2965(c, "http://www.acme.com",
       
  1447                                'ping=pong; domain="acme.com"; version=1')
       
  1448         self.assertEquals(len(c), 1)
       
  1449 
       
  1450         # illegal domain (host prefix "www.a" contains a dot)
       
  1451         cookie = interact_2965(c, "http://www.a.acme.com",
       
  1452                                'whiz=bang; domain="acme.com"; version=1')
       
  1453         self.assertEquals(len(c), 1)
       
  1454 
       
  1455         # legal domain
       
  1456         cookie = interact_2965(c, "http://www.a.acme.com",
       
  1457                                'wow=flutter; domain=".a.acme.com"; version=1')
       
  1458         self.assertEquals(len(c), 2)
       
  1459 
       
  1460         # can't partially match an IP-address
       
  1461         cookie = interact_2965(c, "http://125.125.125.125",
       
  1462                                'zzzz=ping; domain="125.125.125"; version=1')
       
  1463         self.assertEquals(len(c), 2)
       
  1464 
       
  1465         # illegal path (must be prefix of request path)
       
  1466         cookie = interact_2965(c, "http://www.sol.no",
       
  1467                                'blah=rhubarb; domain=".sol.no"; path="/foo"; '
       
  1468                                'version=1')
       
  1469         self.assertEquals(len(c), 2)
       
  1470 
       
  1471         # legal path
       
  1472         cookie = interact_2965(c, "http://www.sol.no/foo/bar",
       
  1473                                'bing=bong; domain=".sol.no"; path="/foo"; '
       
  1474                                'version=1')
       
  1475         self.assertEquals(len(c), 3)
       
  1476 
       
  1477         # illegal port (request-port not in list)
       
  1478         cookie = interact_2965(c, "http://www.sol.no",
       
  1479                                'whiz=ffft; domain=".sol.no"; port="90,100"; '
       
  1480                                'version=1')
       
  1481         self.assertEquals(len(c), 3)
       
  1482 
       
  1483         # legal port
       
  1484         cookie = interact_2965(
       
  1485             c, "http://www.sol.no",
       
  1486             r'bang=wallop; version=1; domain=".sol.no"; '
       
  1487             r'port="90,100, 80,8080"; '
       
  1488             r'max-age=100; Comment = "Just kidding! (\"|\\\\) "')
       
  1489         self.assertEquals(len(c), 4)
       
  1490 
       
  1491         # port attribute without any value (current port)
       
  1492         cookie = interact_2965(c, "http://www.sol.no",
       
  1493                                'foo9=bar; version=1; domain=".sol.no"; port; '
       
  1494                                'max-age=100;')
       
  1495         self.assertEquals(len(c), 5)
       
  1496 
       
  1497         # encoded path
       
  1498         # LWP has this test, but unescaping allowed path characters seems
       
  1499         # like a bad idea, so I think this should fail:
       
  1500 ##         cookie = interact_2965(c, "http://www.sol.no/foo/",
       
  1501 ##                           r'foo8=bar; version=1; path="/%66oo"')
       
  1502         # but this is OK, because '<' is not an allowed HTTP URL path
       
  1503         # character:
       
  1504         cookie = interact_2965(c, "http://www.sol.no/<oo/",
       
  1505                                r'foo8=bar; version=1; path="/%3coo"')
       
  1506         self.assertEquals(len(c), 6)
       
  1507 
       
  1508         # save and restore
       
  1509         filename = test_support.TESTFN
       
  1510 
       
  1511         try:
       
  1512             c.save(filename, ignore_discard=True)
       
  1513             old = repr(c)
       
  1514 
       
  1515             c = LWPCookieJar(policy=pol)
       
  1516             c.load(filename, ignore_discard=True)
       
  1517         finally:
       
  1518             try: os.unlink(filename)
       
  1519             except OSError: pass
       
  1520 
       
  1521         self.assertEquals(old, repr(c))
       
  1522 
       
  1523     def test_url_encoding(self):
       
  1524         # Try some URL encodings of the PATHs.
       
  1525         # (the behaviour here has changed from libwww-perl)
       
  1526         from cookielib import CookieJar, DefaultCookiePolicy
       
  1527 
       
  1528         c = CookieJar(DefaultCookiePolicy(rfc2965=True))
       
  1529         interact_2965(c, "http://www.acme.com/foo%2f%25/%3c%3c%0Anew%E5/%E5",
       
  1530                       "foo  =   bar; version    =   1")
       
  1531 
       
  1532         cookie = interact_2965(
       
  1533             c, "http://www.acme.com/foo%2f%25/<<%0anewå/æøå",
       
  1534             'bar=baz; path="/foo/"; version=1');
       
  1535         version_re = re.compile(r'^\$version=\"?1\"?', re.I)
       
  1536         self.assert_("foo=bar" in cookie and version_re.search(cookie))
       
  1537 
       
  1538         cookie = interact_2965(
       
  1539             c, "http://www.acme.com/foo/%25/<<%0anewå/æøå")
       
  1540         self.assert_(not cookie)
       
  1541 
       
  1542         # unicode URL doesn't raise exception
       
  1543         cookie = interact_2965(c, u"http://www.acme.com/\xfc")
       
  1544 
       
  1545     def test_mozilla(self):
       
  1546         # Save / load Mozilla/Netscape cookie file format.
       
  1547         from cookielib import MozillaCookieJar, DefaultCookiePolicy
       
  1548 
       
  1549         year_plus_one = time.localtime()[0] + 1
       
  1550 
       
  1551         filename = test_support.TESTFN
       
  1552 
       
  1553         c = MozillaCookieJar(filename,
       
  1554                              policy=DefaultCookiePolicy(rfc2965=True))
       
  1555         interact_2965(c, "http://www.acme.com/",
       
  1556                       "foo1=bar; max-age=100; Version=1")
       
  1557         interact_2965(c, "http://www.acme.com/",
       
  1558                       'foo2=bar; port="80"; max-age=100; Discard; Version=1')
       
  1559         interact_2965(c, "http://www.acme.com/", "foo3=bar; secure; Version=1")
       
  1560 
       
  1561         expires = "expires=09-Nov-%d 23:12:40 GMT" % (year_plus_one,)
       
  1562         interact_netscape(c, "http://www.foo.com/",
       
  1563                           "fooa=bar; %s" % expires)
       
  1564         interact_netscape(c, "http://www.foo.com/",
       
  1565                           "foob=bar; Domain=.foo.com; %s" % expires)
       
  1566         interact_netscape(c, "http://www.foo.com/",
       
  1567                           "fooc=bar; Domain=www.foo.com; %s" % expires)
       
  1568 
       
  1569         def save_and_restore(cj, ignore_discard):
       
  1570             try:
       
  1571                 cj.save(ignore_discard=ignore_discard)
       
  1572                 new_c = MozillaCookieJar(filename,
       
  1573                                          DefaultCookiePolicy(rfc2965=True))
       
  1574                 new_c.load(ignore_discard=ignore_discard)
       
  1575             finally:
       
  1576                 try: os.unlink(filename)
       
  1577                 except OSError: pass
       
  1578             return new_c
       
  1579 
       
  1580         new_c = save_and_restore(c, True)
       
  1581         self.assertEquals(len(new_c), 6)  # none discarded
       
  1582         self.assert_("name='foo1', value='bar'" in repr(new_c))
       
  1583 
       
  1584         new_c = save_and_restore(c, False)
       
  1585         self.assertEquals(len(new_c), 4)  # 2 of them discarded on save
       
  1586         self.assert_("name='foo1', value='bar'" in repr(new_c))
       
  1587 
       
  1588     def test_netscape_misc(self):
       
  1589         # Some additional Netscape cookies tests.
       
  1590         from cookielib import CookieJar
       
  1591         from urllib2 import Request
       
  1592 
       
  1593         c = CookieJar()
       
  1594         headers = []
       
  1595         req = Request("http://foo.bar.acme.com/foo")
       
  1596 
       
  1597         # Netscape allows a host part that contains dots
       
  1598         headers.append("Set-Cookie: Customer=WILE_E_COYOTE; domain=.acme.com")
       
  1599         res = FakeResponse(headers, "http://www.acme.com/foo")
       
  1600         c.extract_cookies(res, req)
       
  1601 
       
  1602         # and that the domain is the same as the host without adding a leading
       
  1603         # dot to the domain.  Should not quote even if strange chars are used
       
  1604         # in the cookie value.
       
  1605         headers.append("Set-Cookie: PART_NUMBER=3,4; domain=foo.bar.acme.com")
       
  1606         res = FakeResponse(headers, "http://www.acme.com/foo")
       
  1607         c.extract_cookies(res, req)
       
  1608 
       
  1609         req = Request("http://foo.bar.acme.com/foo")
       
  1610         c.add_cookie_header(req)
       
  1611         self.assert_(
       
  1612             "PART_NUMBER=3,4" in req.get_header("Cookie") and
       
  1613             "Customer=WILE_E_COYOTE" in req.get_header("Cookie"))
       
  1614 
       
  1615     def test_intranet_domains_2965(self):
       
  1616         # Test handling of local intranet hostnames without a dot.
       
  1617         from cookielib import CookieJar, DefaultCookiePolicy
       
  1618 
       
  1619         c = CookieJar(DefaultCookiePolicy(rfc2965=True))
       
  1620         interact_2965(c, "http://example/",
       
  1621                       "foo1=bar; PORT; Discard; Version=1;")
       
  1622         cookie = interact_2965(c, "http://example/",
       
  1623                                'foo2=bar; domain=".local"; Version=1')
       
  1624         self.assert_("foo1=bar" in cookie)
       
  1625 
       
  1626         interact_2965(c, "http://example/", 'foo3=bar; Version=1')
       
  1627         cookie = interact_2965(c, "http://example/")
       
  1628         self.assert_("foo2=bar" in cookie and len(c) == 3)
       
  1629 
       
  1630     def test_intranet_domains_ns(self):
       
  1631         from cookielib import CookieJar, DefaultCookiePolicy
       
  1632 
       
  1633         c = CookieJar(DefaultCookiePolicy(rfc2965 = False))
       
  1634         interact_netscape(c, "http://example/", "foo1=bar")
       
  1635         cookie = interact_netscape(c, "http://example/",
       
  1636                                    'foo2=bar; domain=.local')
       
  1637         self.assertEquals(len(c), 2)
       
  1638         self.assert_("foo1=bar" in cookie)
       
  1639 
       
  1640         cookie = interact_netscape(c, "http://example/")
       
  1641         self.assert_("foo2=bar" in cookie)
       
  1642         self.assertEquals(len(c), 2)
       
  1643 
       
  1644     def test_empty_path(self):
       
  1645         from cookielib import CookieJar, DefaultCookiePolicy
       
  1646         from urllib2 import Request
       
  1647 
       
  1648         # Test for empty path
       
  1649         # Broken web-server ORION/1.3.38 returns to the client response like
       
  1650         #
       
  1651         #       Set-Cookie: JSESSIONID=ABCDERANDOM123; Path=
       
  1652         #
       
  1653         # ie. with Path set to nothing.
       
  1654         # In this case, extract_cookies() must set cookie to / (root)
       
  1655         c = CookieJar(DefaultCookiePolicy(rfc2965 = True))
       
  1656         headers = []
       
  1657 
       
  1658         req = Request("http://www.ants.com/")
       
  1659         headers.append("Set-Cookie: JSESSIONID=ABCDERANDOM123; Path=")
       
  1660         res = FakeResponse(headers, "http://www.ants.com/")
       
  1661         c.extract_cookies(res, req)
       
  1662 
       
  1663         req = Request("http://www.ants.com/")
       
  1664         c.add_cookie_header(req)
       
  1665 
       
  1666         self.assertEquals(req.get_header("Cookie"),
       
  1667                           "JSESSIONID=ABCDERANDOM123")
       
  1668         self.assertEquals(req.get_header("Cookie2"), '$Version="1"')
       
  1669 
       
  1670         # missing path in the request URI
       
  1671         req = Request("http://www.ants.com:8080")
       
  1672         c.add_cookie_header(req)
       
  1673 
       
  1674         self.assertEquals(req.get_header("Cookie"),
       
  1675                           "JSESSIONID=ABCDERANDOM123")
       
  1676         self.assertEquals(req.get_header("Cookie2"), '$Version="1"')
       
  1677 
       
  1678     def test_session_cookies(self):
       
  1679         from cookielib import CookieJar
       
  1680         from urllib2 import Request
       
  1681 
       
  1682         year_plus_one = time.localtime()[0] + 1
       
  1683 
       
  1684         # Check session cookies are deleted properly by
       
  1685         # CookieJar.clear_session_cookies method
       
  1686 
       
  1687         req = Request('http://www.perlmeister.com/scripts')
       
  1688         headers = []
       
  1689         headers.append("Set-Cookie: s1=session;Path=/scripts")
       
  1690         headers.append("Set-Cookie: p1=perm; Domain=.perlmeister.com;"
       
  1691                        "Path=/;expires=Fri, 02-Feb-%d 23:24:20 GMT" %
       
  1692                        year_plus_one)
       
  1693         headers.append("Set-Cookie: p2=perm;Path=/;expires=Fri, "
       
  1694                        "02-Feb-%d 23:24:20 GMT" % year_plus_one)
       
  1695         headers.append("Set-Cookie: s2=session;Path=/scripts;"
       
  1696                        "Domain=.perlmeister.com")
       
  1697         headers.append('Set-Cookie2: s3=session;Version=1;Discard;Path="/"')
       
  1698         res = FakeResponse(headers, 'http://www.perlmeister.com/scripts')
       
  1699 
       
  1700         c = CookieJar()
       
  1701         c.extract_cookies(res, req)
       
  1702         # How many session/permanent cookies do we have?
       
  1703         counter = {"session_after": 0,
       
  1704                    "perm_after": 0,
       
  1705                    "session_before": 0,
       
  1706                    "perm_before": 0}
       
  1707         for cookie in c:
       
  1708             key = "%s_before" % cookie.value
       
  1709             counter[key] = counter[key] + 1
       
  1710         c.clear_session_cookies()
       
  1711         # How many now?
       
  1712         for cookie in c:
       
  1713             key = "%s_after" % cookie.value
       
  1714             counter[key] = counter[key] + 1
       
  1715 
       
  1716         self.assert_(not (
       
  1717             # a permanent cookie got lost accidently
       
  1718             counter["perm_after"] != counter["perm_before"] or
       
  1719             # a session cookie hasn't been cleared
       
  1720             counter["session_after"] != 0 or
       
  1721             # we didn't have session cookies in the first place
       
  1722             counter["session_before"] == 0))
       
  1723 
       
  1724 
       
  1725 def test_main(verbose=None):
       
  1726     from test import test_sets
       
  1727     test_support.run_unittest(
       
  1728         DateTimeTests,
       
  1729         HeaderTests,
       
  1730         CookieTests,
       
  1731         FileCookieJarTests,
       
  1732         LWPCookieTests,
       
  1733         )
       
  1734 
       
  1735 if __name__ == "__main__":
       
  1736     test_main(verbose=True)