10c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi# -*- coding: latin-1 -*-
20c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi"""Tests for cookielib.py."""
30c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
40c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yiimport cookielib
50c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yiimport os
60c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yiimport re
70c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yiimport time
80c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
90c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yifrom unittest import TestCase
100c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
110c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yifrom test import test_support
120c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
130c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
140c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yiclass DateTimeTests(TestCase):
150c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
160c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def test_time2isoz(self):
170c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        from cookielib import time2isoz
180c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
190c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        base = 1019227000
200c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        day = 24*3600
210c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertEqual(time2isoz(base), "2002-04-19 14:36:40Z")
220c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertEqual(time2isoz(base+day), "2002-04-20 14:36:40Z")
230c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertEqual(time2isoz(base+2*day), "2002-04-21 14:36:40Z")
240c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertEqual(time2isoz(base+3*day), "2002-04-22 14:36:40Z")
250c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
260c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        az = time2isoz()
270c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        bz = time2isoz(500000)
280c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        for text in (az, bz):
290c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self.assertTrue(re.search(r"^\d{4}-\d\d-\d\d \d\d:\d\d:\d\dZ$", text),
300c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                         "bad time2isoz format: %s %s" % (az, bz))
310c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
320c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def test_http2time(self):
330c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        from cookielib import http2time
340c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
350c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        def parse_date(text):
360c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            return time.gmtime(http2time(text))[:6]
370c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
380c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertEqual(parse_date("01 Jan 2001"), (2001, 1, 1, 0, 0, 0.0))
390c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
400c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # this test will break around year 2070
410c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertEqual(parse_date("03-Feb-20"), (2020, 2, 3, 0, 0, 0.0))
420c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
430c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # this test will break around year 2048
440c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertEqual(parse_date("03-Feb-98"), (1998, 2, 3, 0, 0, 0.0))
450c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
460c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def test_http2time_formats(self):
470c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        from cookielib import http2time, time2isoz
480c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
490c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # test http2time for supported dates.  Test cases with 2 digit year
500c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # will probably break in year 2044.
510c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        tests = [
520c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi         'Thu, 03 Feb 1994 00:00:00 GMT',  # proposed new HTTP format
530c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi         'Thursday, 03-Feb-94 00:00:00 GMT',  # old rfc850 HTTP format
540c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi         'Thursday, 03-Feb-1994 00:00:00 GMT',  # broken rfc850 HTTP format
550c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
560c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi         '03 Feb 1994 00:00:00 GMT',  # HTTP format (no weekday)
570c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi         '03-Feb-94 00:00:00 GMT',  # old rfc850 (no weekday)
580c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi         '03-Feb-1994 00:00:00 GMT',  # broken rfc850 (no weekday)
590c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi         '03-Feb-1994 00:00 GMT',  # broken rfc850 (no weekday, no seconds)
600c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi         '03-Feb-1994 00:00',  # broken rfc850 (no weekday, no seconds, no tz)
610c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
620c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi         '03-Feb-94',  # old rfc850 HTTP format (no weekday, no time)
630c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi         '03-Feb-1994',  # broken rfc850 HTTP format (no weekday, no time)
640c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi         '03 Feb 1994',  # proposed new HTTP format (no weekday, no time)
650c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
660c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi         # A few tests with extra space at various places
670c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi         '  03   Feb   1994  0:00  ',
680c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi         '  03-Feb-1994  ',
690c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        ]
700c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
710c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        test_t = 760233600  # assume broken POSIX counting of seconds
720c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        result = time2isoz(test_t)
730c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        expected = "1994-02-03 00:00:00Z"
740c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertEqual(result, expected,
750c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                         "%s  =>  '%s' (%s)" % (test_t, result, expected))
760c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
770c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        for s in tests:
780c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            t = http2time(s)
790c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            t2 = http2time(s.lower())
800c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            t3 = http2time(s.upper())
810c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
820c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self.assertTrue(t == t2 == t3 == test_t,
830c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                         "'%s'  =>  %s, %s, %s (%s)" % (s, t, t2, t3, test_t))
840c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
850c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def test_http2time_garbage(self):
860c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        from cookielib import http2time
870c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
880c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        for test in [
890c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            '',
900c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            'Garbage',
910c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            'Mandag 16. September 1996',
920c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            '01-00-1980',
930c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            '01-13-1980',
940c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            '00-01-1980',
950c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            '32-01-1980',
960c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            '01-01-1980 25:00:00',
970c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            '01-01-1980 00:61:00',
980c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            '01-01-1980 00:00:62',
990c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            ]:
1000c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self.assertTrue(http2time(test) is None,
1010c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                         "http2time(%s) is not None\n"
1020c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                         "http2time(test) %s" % (test, http2time(test))
1030c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                         )
1040c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
1050c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
1060c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yiclass HeaderTests(TestCase):
1070c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
1080c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def test_parse_ns_headers_expires(self):
1090c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        from cookielib import parse_ns_headers
1100c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
1110c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # quotes should be stripped
1120c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        expected = [[('foo', 'bar'), ('expires', 2209069412L), ('version', '0')]]
1130c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        for hdr in [
1140c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            'foo=bar; expires=01 Jan 2040 22:23:32 GMT',
1150c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            'foo=bar; expires="01 Jan 2040 22:23:32 GMT"',
1160c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            ]:
1170c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self.assertEqual(parse_ns_headers([hdr]), expected)
1180c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
1190c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def test_parse_ns_headers_version(self):
1200c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        from cookielib import parse_ns_headers
1210c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
1220c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # quotes should be stripped
1230c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        expected = [[('foo', 'bar'), ('version', '1')]]
1240c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        for hdr in [
1250c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            'foo=bar; version="1"',
1260c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            'foo=bar; Version="1"',
1270c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            ]:
1280c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self.assertEqual(parse_ns_headers([hdr]), expected)
1290c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
1300c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def test_parse_ns_headers_special_names(self):
1310c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # names such as 'expires' are not special in first name=value pair
1320c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # of Set-Cookie: header
1330c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        from cookielib import parse_ns_headers
1340c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
1350c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # Cookie with name 'expires'
1360c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        hdr = 'expires=01 Jan 2040 22:23:32 GMT'
1370c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        expected = [[("expires", "01 Jan 2040 22:23:32 GMT"), ("version", "0")]]
1380c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertEqual(parse_ns_headers([hdr]), expected)
1390c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
1400c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def test_join_header_words(self):
1410c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        from cookielib import join_header_words
1420c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
1430c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        joined = join_header_words([[("foo", None), ("bar", "baz")]])
1440c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertEqual(joined, "foo; bar=baz")
1450c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
1460c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertEqual(join_header_words([[]]), "")
1470c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
1480c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def test_split_header_words(self):
1490c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        from cookielib import split_header_words
1500c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
1510c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        tests = [
1520c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            ("foo", [[("foo", None)]]),
1530c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            ("foo=bar", [[("foo", "bar")]]),
1540c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            ("   foo   ", [[("foo", None)]]),
1550c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            ("   foo=   ", [[("foo", "")]]),
1560c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            ("   foo=", [[("foo", "")]]),
1570c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            ("   foo=   ; ", [[("foo", "")]]),
1580c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            ("   foo=   ; bar= baz ", [[("foo", ""), ("bar", "baz")]]),
1590c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            ("foo=bar bar=baz", [[("foo", "bar"), ("bar", "baz")]]),
1600c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            # doesn't really matter if this next fails, but it works ATM
1610c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            ("foo= bar=baz", [[("foo", "bar=baz")]]),
1620c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            ("foo=bar;bar=baz", [[("foo", "bar"), ("bar", "baz")]]),
1630c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            ('foo bar baz', [[("foo", None), ("bar", None), ("baz", None)]]),
1640c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            ("a, b, c", [[("a", None)], [("b", None)], [("c", None)]]),
1650c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            (r'foo; bar=baz, spam=, foo="\,\;\"", bar= ',
1660c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi             [[("foo", None), ("bar", "baz")],
1670c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi              [("spam", "")], [("foo", ',;"')], [("bar", "")]]),
1680c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            ]
1690c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
1700c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        for arg, expect in tests:
1710c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            try:
1720c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                result = split_header_words([arg])
1730c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            except:
1740c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                import traceback, StringIO
1750c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                f = StringIO.StringIO()
1760c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                traceback.print_exc(None, f)
1770c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                result = "(error -- traceback follows)\n\n%s" % f.getvalue()
1780c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self.assertEqual(result,  expect, """
1790c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiWhen parsing: '%s'
1800c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiExpected:     '%s'
1810c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiGot:          '%s'
1820c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi""" % (arg, expect, result))
1830c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
1840c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def test_roundtrip(self):
1850c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        from cookielib import split_header_words, join_header_words
1860c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
1870c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        tests = [
1880c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            ("foo", "foo"),
1890c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            ("foo=bar", "foo=bar"),
1900c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            ("   foo   ", "foo"),
1910c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            ("foo=", 'foo=""'),
1920c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            ("foo=bar bar=baz", "foo=bar; bar=baz"),
1930c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            ("foo=bar;bar=baz", "foo=bar; bar=baz"),
1940c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            ('foo bar baz', "foo; bar; baz"),
1950c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            (r'foo="\"" bar="\\"', r'foo="\""; bar="\\"'),
1960c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            ('foo,,,bar', 'foo, bar'),
1970c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            ('foo=bar,bar=baz', 'foo=bar, bar=baz'),
1980c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
1990c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            ('text/html; charset=iso-8859-1',
2000c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi             'text/html; charset="iso-8859-1"'),
2010c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
2020c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            ('foo="bar"; port="80,81"; discard, bar=baz',
2030c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi             'foo=bar; port="80,81"; discard, bar=baz'),
2040c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
2050c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            (r'Basic realm="\"foo\\\\bar\""',
2060c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi             r'Basic; realm="\"foo\\\\bar\""')
2070c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            ]
2080c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
2090c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        for arg, expect in tests:
2100c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            input = split_header_words([arg])
2110c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            res = join_header_words(input)
2120c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self.assertEqual(res, expect, """
2130c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiWhen parsing: '%s'
2140c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiExpected:     '%s'
2150c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiGot:          '%s'
2160c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiInput was:    '%s'
2170c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi""" % (arg, expect, res, input))
2180c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
2190c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
2200c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yiclass FakeResponse:
2210c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def __init__(self, headers=[], url=None):
2220c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """
2230c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        headers: list of RFC822-style 'Key: value' strings
2240c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """
2250c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        import mimetools, StringIO
2260c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        f = StringIO.StringIO("\n".join(headers))
2270c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self._headers = mimetools.Message(f)
2280c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self._url = url
2290c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def info(self): return self._headers
2300c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
2310c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yidef interact_2965(cookiejar, url, *set_cookie_hdrs):
2320c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    return _interact(cookiejar, url, set_cookie_hdrs, "Set-Cookie2")
2330c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
2340c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yidef interact_netscape(cookiejar, url, *set_cookie_hdrs):
2350c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    return _interact(cookiejar, url, set_cookie_hdrs, "Set-Cookie")
2360c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
2370c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yidef _interact(cookiejar, url, set_cookie_hdrs, hdr_name):
2380c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    """Perform a single request / response cycle, returning Cookie: header."""
2390c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    from urllib2 import Request
2400c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    req = Request(url)
2410c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    cookiejar.add_cookie_header(req)
2420c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    cookie_hdr = req.get_header("Cookie", "")
2430c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    headers = []
2440c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    for hdr in set_cookie_hdrs:
2450c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        headers.append("%s: %s" % (hdr_name, hdr))
2460c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    res = FakeResponse(headers, url)
2470c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    cookiejar.extract_cookies(res, req)
2480c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    return cookie_hdr
2490c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
2500c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
2510c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yiclass FileCookieJarTests(TestCase):
2520c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def test_lwp_valueless_cookie(self):
2530c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # cookies with no value should be saved and loaded consistently
2540c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        from cookielib import LWPCookieJar
2550c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        filename = test_support.TESTFN
2560c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        c = LWPCookieJar()
2570c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        interact_netscape(c, "http://www.acme.com/", 'boo')
2580c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertEqual(c._cookies["www.acme.com"]["/"]["boo"].value, None)
2590c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        try:
2600c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            c.save(filename, ignore_discard=True)
2610c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            c = LWPCookieJar()
2620c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            c.load(filename, ignore_discard=True)
2630c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        finally:
2640c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            try: os.unlink(filename)
2650c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            except OSError: pass
2660c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertEqual(c._cookies["www.acme.com"]["/"]["boo"].value, None)
2670c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
2680c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def test_bad_magic(self):
2690c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        from cookielib import LWPCookieJar, MozillaCookieJar, LoadError
2700c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # IOErrors (eg. file doesn't exist) are allowed to propagate
2710c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        filename = test_support.TESTFN
2720c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        for cookiejar_class in LWPCookieJar, MozillaCookieJar:
2730c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            c = cookiejar_class()
2740c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            try:
2750c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                c.load(filename="for this test to work, a file with this "
2760c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                                "filename should not exist")
2770c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            except IOError, exc:
2780c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                # exactly IOError, not LoadError
2790c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                self.assertEqual(exc.__class__, IOError)
2800c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            else:
2810c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                self.fail("expected IOError for invalid filename")
2820c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # Invalid contents of cookies file (eg. bad magic string)
2830c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # causes a LoadError.
2840c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        try:
2850c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            f = open(filename, "w")
2860c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            f.write("oops\n")
2870c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            for cookiejar_class in LWPCookieJar, MozillaCookieJar:
2880c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                c = cookiejar_class()
2890c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                self.assertRaises(LoadError, c.load, filename)
2900c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        finally:
2910c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            try: os.unlink(filename)
2920c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            except OSError: pass
2930c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
2940c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yiclass CookieTests(TestCase):
2950c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    # XXX
2960c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    # Get rid of string comparisons where not actually testing str / repr.
2970c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    # .clear() etc.
2980c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    # IP addresses like 50 (single number, no dot) and domain-matching
2990c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    #  functions (and is_HDN)?  See draft RFC 2965 errata.
3000c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    # Strictness switches
3010c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    # is_third_party()
3020c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    # unverifiability / third-party blocking
3030c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    # Netscape cookies work the same as RFC 2965 with regard to port.
3040c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    # Set-Cookie with negative max age.
3050c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    # If turn RFC 2965 handling off, Set-Cookie2 cookies should not clobber
3060c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    #  Set-Cookie cookies.
3070c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    # Cookie2 should be sent if *any* cookies are not V1 (ie. V0 OR V2 etc.).
3080c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    # Cookies (V1 and V0) with no expiry date should be set to be discarded.
3090c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    # RFC 2965 Quoting:
3100c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    #  Should accept unquoted cookie-attribute values?  check errata draft.
3110c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    #   Which are required on the way in and out?
3120c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    #  Should always return quoted cookie-attribute values?
3130c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    # Proper testing of when RFC 2965 clobbers Netscape (waiting for errata).
3140c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    # Path-match on return (same for V0 and V1).
3150c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    # RFC 2965 acceptance and returning rules
3160c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    #  Set-Cookie2 without version attribute is rejected.
3170c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
3180c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    # Netscape peculiarities list from Ronald Tschalar.
3190c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    # The first two still need tests, the rest are covered.
3200c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi## - Quoting: only quotes around the expires value are recognized as such
3210c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi##   (and yes, some folks quote the expires value); quotes around any other
3220c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi##   value are treated as part of the value.
3230c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi## - White space: white space around names and values is ignored
3240c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi## - Default path: if no path parameter is given, the path defaults to the
3250c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi##   path in the request-uri up to, but not including, the last '/'. Note
3260c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi##   that this is entirely different from what the spec says.
3270c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi## - Commas and other delimiters: Netscape just parses until the next ';'.
3280c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi##   This means it will allow commas etc inside values (and yes, both
3290c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi##   commas and equals are commonly appear in the cookie value). This also
3300c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi##   means that if you fold multiple Set-Cookie header fields into one,
3310c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi##   comma-separated list, it'll be a headache to parse (at least my head
3320c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi##   starts hurting everytime I think of that code).
3330c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi## - Expires: You'll get all sorts of date formats in the expires,
3340c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi##   including emtpy expires attributes ("expires="). Be as flexible as you
3350c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi##   can, and certainly don't expect the weekday to be there; if you can't
3360c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi##   parse it, just ignore it and pretend it's a session cookie.
3370c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi## - Domain-matching: Netscape uses the 2-dot rule for _all_ domains, not
3380c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi##   just the 7 special TLD's listed in their spec. And folks rely on
3390c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi##   that...
3400c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
3410c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def test_domain_return_ok(self):
3420c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # test optimization: .domain_return_ok() should filter out most
3430c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # domains in the CookieJar before we try to access them (because that
3440c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # may require disk access -- in particular, with MSIECookieJar)
3450c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # This is only a rough check for performance reasons, so it's not too
3460c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # critical as long as it's sufficiently liberal.
3470c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        import cookielib, urllib2
3480c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        pol = cookielib.DefaultCookiePolicy()
3490c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        for url, domain, ok in [
3500c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            ("http://foo.bar.com/", "blah.com", False),
3510c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            ("http://foo.bar.com/", "rhubarb.blah.com", False),
3520c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            ("http://foo.bar.com/", "rhubarb.foo.bar.com", False),
3530c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            ("http://foo.bar.com/", ".foo.bar.com", True),
3540c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            ("http://foo.bar.com/", "foo.bar.com", True),
3550c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            ("http://foo.bar.com/", ".bar.com", True),
3560c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            ("http://foo.bar.com/", "com", True),
3570c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            ("http://foo.com/", "rhubarb.foo.com", False),
3580c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            ("http://foo.com/", ".foo.com", True),
3590c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            ("http://foo.com/", "foo.com", True),
3600c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            ("http://foo.com/", "com", True),
3610c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            ("http://foo/", "rhubarb.foo", False),
3620c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            ("http://foo/", ".foo", True),
3630c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            ("http://foo/", "foo", True),
3640c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            ("http://foo/", "foo.local", True),
3650c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            ("http://foo/", ".local", True),
3660c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            ]:
3670c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            request = urllib2.Request(url)
3680c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            r = pol.domain_return_ok(domain, request)
3690c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            if ok: self.assertTrue(r)
3700c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            else: self.assertTrue(not r)
3710c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
3720c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def test_missing_value(self):
3730c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        from cookielib import MozillaCookieJar, lwp_cookie_str
3740c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
3750c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # missing = sign in Cookie: header is regarded by Mozilla as a missing
3760c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # name, and by cookielib as a missing value
3770c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        filename = test_support.TESTFN
3780c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        c = MozillaCookieJar(filename)
3790c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        interact_netscape(c, "http://www.acme.com/", 'eggs')
3800c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        interact_netscape(c, "http://www.acme.com/", '"spam"; path=/foo/')
3810c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        cookie = c._cookies["www.acme.com"]["/"]["eggs"]
3820c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertTrue(cookie.value is None)
3830c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertEqual(cookie.name, "eggs")
3840c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        cookie = c._cookies["www.acme.com"]['/foo/']['"spam"']
3850c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertTrue(cookie.value is None)
3860c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertEqual(cookie.name, '"spam"')
3870c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertEqual(lwp_cookie_str(cookie), (
3880c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            r'"spam"; path="/foo/"; domain="www.acme.com"; '
3890c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            'path_spec; discard; version=0'))
3900c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        old_str = repr(c)
3910c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        c.save(ignore_expires=True, ignore_discard=True)
3920c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        try:
3930c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            c = MozillaCookieJar(filename)
3940c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            c.revert(ignore_expires=True, ignore_discard=True)
3950c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        finally:
3960c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            os.unlink(c.filename)
3970c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # cookies unchanged apart from lost info re. whether path was specified
3980c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertEqual(
3990c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            repr(c),
4000c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            re.sub("path_specified=%s" % True, "path_specified=%s" % False,
4010c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                   old_str)
4020c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            )
4030c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertEqual(interact_netscape(c, "http://www.acme.com/foo/"),
4040c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                         '"spam"; eggs')
4050c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
4060c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def test_rfc2109_handling(self):
4070c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # RFC 2109 cookies are handled as RFC 2965 or Netscape cookies,
4080c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # dependent on policy settings
4090c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        from cookielib import CookieJar, DefaultCookiePolicy
4100c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
4110c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        for rfc2109_as_netscape, rfc2965, version in [
4120c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            # default according to rfc2965 if not explicitly specified
4130c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            (None, False, 0),
4140c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            (None, True, 1),
4150c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            # explicit rfc2109_as_netscape
4160c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            (False, False, None),  # version None here means no cookie stored
4170c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            (False, True, 1),
4180c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            (True, False, 0),
4190c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            (True, True, 0),
4200c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            ]:
4210c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            policy = DefaultCookiePolicy(
4220c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                rfc2109_as_netscape=rfc2109_as_netscape,
4230c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                rfc2965=rfc2965)
4240c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            c = CookieJar(policy)
4250c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            interact_netscape(c, "http://www.example.com/", "ni=ni; Version=1")
4260c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            try:
4270c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                cookie = c._cookies["www.example.com"]["/"]["ni"]
4280c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            except KeyError:
4290c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                self.assertTrue(version is None)  # didn't expect a stored cookie
4300c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            else:
4310c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                self.assertEqual(cookie.version, version)
4320c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                # 2965 cookies are unaffected
4330c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                interact_2965(c, "http://www.example.com/",
4340c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                              "foo=bar; Version=1")
4350c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                if rfc2965:
4360c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                    cookie2965 = c._cookies["www.example.com"]["/"]["foo"]
4370c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                    self.assertEqual(cookie2965.version, 1)
4380c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
4390c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def test_ns_parser(self):
4400c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        from cookielib import CookieJar, DEFAULT_HTTP_PORT
4410c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
4420c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        c = CookieJar()
4430c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        interact_netscape(c, "http://www.acme.com/",
4440c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                          'spam=eggs; DoMain=.acme.com; port; blArgh="feep"')
4450c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        interact_netscape(c, "http://www.acme.com/", 'ni=ni; port=80,8080')
4460c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        interact_netscape(c, "http://www.acme.com:80/", 'nini=ni')
4470c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        interact_netscape(c, "http://www.acme.com:80/", 'foo=bar; expires=')
4480c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        interact_netscape(c, "http://www.acme.com:80/", 'spam=eggs; '
4490c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                          'expires="Foo Bar 25 33:22:11 3022"')
4500c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
4510c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        cookie = c._cookies[".acme.com"]["/"]["spam"]
4520c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertEqual(cookie.domain, ".acme.com")
4530c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertTrue(cookie.domain_specified)
4540c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertEqual(cookie.port, DEFAULT_HTTP_PORT)
4550c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertTrue(not cookie.port_specified)
4560c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # case is preserved
4570c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertTrue(cookie.has_nonstandard_attr("blArgh") and
4580c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                     not cookie.has_nonstandard_attr("blargh"))
4590c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
4600c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        cookie = c._cookies["www.acme.com"]["/"]["ni"]
4610c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertEqual(cookie.domain, "www.acme.com")
4620c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertTrue(not cookie.domain_specified)
4630c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertEqual(cookie.port, "80,8080")
4640c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertTrue(cookie.port_specified)
4650c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
4660c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        cookie = c._cookies["www.acme.com"]["/"]["nini"]
4670c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertTrue(cookie.port is None)
4680c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertTrue(not cookie.port_specified)
4690c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
4700c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # invalid expires should not cause cookie to be dropped
4710c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        foo = c._cookies["www.acme.com"]["/"]["foo"]
4720c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        spam = c._cookies["www.acme.com"]["/"]["foo"]
4730c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertTrue(foo.expires is None)
4740c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertTrue(spam.expires is None)
4750c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
4760c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def test_ns_parser_special_names(self):
4770c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # names such as 'expires' are not special in first name=value pair
4780c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # of Set-Cookie: header
4790c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        from cookielib import CookieJar
4800c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
4810c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        c = CookieJar()
4820c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        interact_netscape(c, "http://www.acme.com/", 'expires=eggs')
4830c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        interact_netscape(c, "http://www.acme.com/", 'version=eggs; spam=eggs')
4840c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
4850c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        cookies = c._cookies["www.acme.com"]["/"]
4860c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertTrue('expires' in cookies)
4870c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertTrue('version' in cookies)
4880c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
4890c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def test_expires(self):
4900c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        from cookielib import time2netscape, CookieJar
4910c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
4920c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # if expires is in future, keep cookie...
4930c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        c = CookieJar()
4940c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        future = time2netscape(time.time()+3600)
4950c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        interact_netscape(c, "http://www.acme.com/", 'spam="bar"; expires=%s' %
4960c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                          future)
4970c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertEqual(len(c), 1)
4980c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        now = time2netscape(time.time()-1)
4990c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # ... and if in past or present, discard it
5000c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        interact_netscape(c, "http://www.acme.com/", 'foo="eggs"; expires=%s' %
5010c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                          now)
5020c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        h = interact_netscape(c, "http://www.acme.com/")
5030c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertEqual(len(c), 1)
5040c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertTrue('spam="bar"' in h and "foo" not in h)
5050c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
5060c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # max-age takes precedence over expires, and zero max-age is request to
5070c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # delete both new cookie and any old matching cookie
5080c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        interact_netscape(c, "http://www.acme.com/", 'eggs="bar"; expires=%s' %
5090c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                          future)
5100c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        interact_netscape(c, "http://www.acme.com/", 'bar="bar"; expires=%s' %
5110c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                          future)
5120c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertEqual(len(c), 3)
5130c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        interact_netscape(c, "http://www.acme.com/", 'eggs="bar"; '
5140c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                          'expires=%s; max-age=0' % future)
5150c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        interact_netscape(c, "http://www.acme.com/", 'bar="bar"; '
5160c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                          'max-age=0; expires=%s' % future)
5170c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        h = interact_netscape(c, "http://www.acme.com/")
5180c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertEqual(len(c), 1)
5190c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
5200c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # test expiry at end of session for cookies with no expires attribute
5210c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        interact_netscape(c, "http://www.rhubarb.net/", 'whum="fizz"')
5220c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertEqual(len(c), 2)
5230c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        c.clear_session_cookies()
5240c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertEqual(len(c), 1)
5250c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertIn('spam="bar"', h)
5260c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
5270c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # XXX RFC 2965 expiry rules (some apply to V0 too)
5280c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
5290c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def test_default_path(self):
5300c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        from cookielib import CookieJar, DefaultCookiePolicy
5310c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
5320c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # RFC 2965
5330c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        pol = DefaultCookiePolicy(rfc2965=True)
5340c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
5350c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        c = CookieJar(pol)
5360c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        interact_2965(c, "http://www.acme.com/", 'spam="bar"; Version="1"')
5370c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertIn("/", c._cookies["www.acme.com"])
5380c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
5390c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        c = CookieJar(pol)
5400c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        interact_2965(c, "http://www.acme.com/blah", 'eggs="bar"; Version="1"')
5410c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertIn("/", c._cookies["www.acme.com"])
5420c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
5430c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        c = CookieJar(pol)
5440c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        interact_2965(c, "http://www.acme.com/blah/rhubarb",
5450c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                      'eggs="bar"; Version="1"')
5460c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertIn("/blah/", c._cookies["www.acme.com"])
5470c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
5480c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        c = CookieJar(pol)
5490c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        interact_2965(c, "http://www.acme.com/blah/rhubarb/",
5500c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                      'eggs="bar"; Version="1"')
5510c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertIn("/blah/rhubarb/", c._cookies["www.acme.com"])
5520c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
5530c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # Netscape
5540c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
5550c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        c = CookieJar()
5560c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        interact_netscape(c, "http://www.acme.com/", 'spam="bar"')
5570c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertIn("/", c._cookies["www.acme.com"])
5580c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
5590c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        c = CookieJar()
5600c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        interact_netscape(c, "http://www.acme.com/blah", 'eggs="bar"')
5610c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertIn("/", c._cookies["www.acme.com"])
5620c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
5630c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        c = CookieJar()
5640c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        interact_netscape(c, "http://www.acme.com/blah/rhubarb", 'eggs="bar"')
5650c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertIn("/blah", c._cookies["www.acme.com"])
5660c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
5670c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        c = CookieJar()
5680c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        interact_netscape(c, "http://www.acme.com/blah/rhubarb/", 'eggs="bar"')
5690c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertIn("/blah/rhubarb", c._cookies["www.acme.com"])
5700c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
5710c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def test_default_path_with_query(self):
5720c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        cj = cookielib.CookieJar()
5730c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        uri = "http://example.com/?spam/eggs"
5740c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        value = 'eggs="bar"'
5750c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        interact_netscape(cj, uri, value)
5760c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # default path does not include query, so is "/", not "/?spam"
5770c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertIn("/", cj._cookies["example.com"])
5780c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # cookie is sent back to the same URI
5790c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertEqual(interact_netscape(cj, uri), value)
5800c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
5810c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def test_escape_path(self):
5820c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        from cookielib import escape_path
5830c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        cases = [
5840c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            # quoted safe
5850c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            ("/foo%2f/bar", "/foo%2F/bar"),
5860c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            ("/foo%2F/bar", "/foo%2F/bar"),
5870c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            # quoted %
5880c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            ("/foo%%/bar", "/foo%%/bar"),
5890c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            # quoted unsafe
5900c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            ("/fo%19o/bar", "/fo%19o/bar"),
5910c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            ("/fo%7do/bar", "/fo%7Do/bar"),
5920c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            # unquoted safe
5930c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            ("/foo/bar&", "/foo/bar&"),
5940c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            ("/foo//bar", "/foo//bar"),
5950c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            ("\176/foo/bar", "\176/foo/bar"),
5960c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            # unquoted unsafe
5970c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            ("/foo\031/bar", "/foo%19/bar"),
5980c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            ("/\175foo/bar", "/%7Dfoo/bar"),
5990c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            # unicode
6000c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            (u"/foo/bar\uabcd", "/foo/bar%EA%AF%8D"),  # UTF-8 encoded
6010c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            ]
6020c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        for arg, result in cases:
6030c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self.assertEqual(escape_path(arg), result)
6040c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
6050c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def test_request_path(self):
6060c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        from urllib2 import Request
6070c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        from cookielib import request_path
6080c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # with parameters
6090c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        req = Request("http://www.example.com/rheum/rhaponticum;"
6100c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                      "foo=bar;sing=song?apples=pears&spam=eggs#ni")
6110c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertEqual(request_path(req),
6120c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                         "/rheum/rhaponticum;foo=bar;sing=song")
6130c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # without parameters
6140c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        req = Request("http://www.example.com/rheum/rhaponticum?"
6150c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                      "apples=pears&spam=eggs#ni")
6160c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertEqual(request_path(req), "/rheum/rhaponticum")
6170c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # missing final slash
6180c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        req = Request("http://www.example.com")
6190c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertEqual(request_path(req), "/")
6200c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
6210c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def test_request_port(self):
6220c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        from urllib2 import Request
6230c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        from cookielib import request_port, DEFAULT_HTTP_PORT
6240c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        req = Request("http://www.acme.com:1234/",
6250c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                      headers={"Host": "www.acme.com:4321"})
6260c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertEqual(request_port(req), "1234")
6270c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        req = Request("http://www.acme.com/",
6280c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                      headers={"Host": "www.acme.com:4321"})
6290c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertEqual(request_port(req), DEFAULT_HTTP_PORT)
6300c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
6310c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def test_request_host(self):
6320c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        from urllib2 import Request
6330c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        from cookielib import request_host
6340c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # this request is illegal (RFC2616, 14.2.3)
6350c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        req = Request("http://1.1.1.1/",
6360c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                      headers={"Host": "www.acme.com:80"})
6370c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # libwww-perl wants this response, but that seems wrong (RFC 2616,
6380c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # section 5.2, point 1., and RFC 2965 section 1, paragraph 3)
6390c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        #self.assertEqual(request_host(req), "www.acme.com")
6400c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertEqual(request_host(req), "1.1.1.1")
6410c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        req = Request("http://www.acme.com/",
6420c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                      headers={"Host": "irrelevant.com"})
6430c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertEqual(request_host(req), "www.acme.com")
6440c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # not actually sure this one is valid Request object, so maybe should
6450c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # remove test for no host in url in request_host function?
6460c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        req = Request("/resource.html",
6470c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                      headers={"Host": "www.acme.com"})
6480c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertEqual(request_host(req), "www.acme.com")
6490c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # port shouldn't be in request-host
6500c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        req = Request("http://www.acme.com:2345/resource.html",
6510c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                      headers={"Host": "www.acme.com:5432"})
6520c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertEqual(request_host(req), "www.acme.com")
6530c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
6540c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def test_is_HDN(self):
6550c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        from cookielib import is_HDN
6560c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertTrue(is_HDN("foo.bar.com"))
6570c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertTrue(is_HDN("1foo2.3bar4.5com"))
6580c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertTrue(not is_HDN("192.168.1.1"))
6590c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertTrue(not is_HDN(""))
6600c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertTrue(not is_HDN("."))
6610c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertTrue(not is_HDN(".foo.bar.com"))
6620c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertTrue(not is_HDN("..foo"))
6630c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertTrue(not is_HDN("foo."))
6640c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
6650c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def test_reach(self):
6660c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        from cookielib import reach
6670c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertEqual(reach("www.acme.com"), ".acme.com")
6680c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertEqual(reach("acme.com"), "acme.com")
6690c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertEqual(reach("acme.local"), ".local")
6700c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertEqual(reach(".local"), ".local")
6710c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertEqual(reach(".com"), ".com")
6720c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertEqual(reach("."), ".")
6730c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertEqual(reach(""), "")
6740c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertEqual(reach("192.168.0.1"), "192.168.0.1")
6750c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
6760c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def test_domain_match(self):
6770c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        from cookielib import domain_match, user_domain_match
6780c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertTrue(domain_match("192.168.1.1", "192.168.1.1"))
6790c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertTrue(not domain_match("192.168.1.1", ".168.1.1"))
6800c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertTrue(domain_match("x.y.com", "x.Y.com"))
6810c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertTrue(domain_match("x.y.com", ".Y.com"))
6820c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertTrue(not domain_match("x.y.com", "Y.com"))
6830c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertTrue(domain_match("a.b.c.com", ".c.com"))
6840c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertTrue(not domain_match(".c.com", "a.b.c.com"))
6850c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertTrue(domain_match("example.local", ".local"))
6860c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertTrue(not domain_match("blah.blah", ""))
6870c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertTrue(not domain_match("", ".rhubarb.rhubarb"))
6880c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertTrue(domain_match("", ""))
6890c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
6900c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertTrue(user_domain_match("acme.com", "acme.com"))
6910c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertTrue(not user_domain_match("acme.com", ".acme.com"))
6920c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertTrue(user_domain_match("rhubarb.acme.com", ".acme.com"))
6930c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertTrue(user_domain_match("www.rhubarb.acme.com", ".acme.com"))
6940c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertTrue(user_domain_match("x.y.com", "x.Y.com"))
6950c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertTrue(user_domain_match("x.y.com", ".Y.com"))
6960c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertTrue(not user_domain_match("x.y.com", "Y.com"))
6970c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertTrue(user_domain_match("y.com", "Y.com"))
6980c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertTrue(not user_domain_match(".y.com", "Y.com"))
6990c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertTrue(user_domain_match(".y.com", ".Y.com"))
7000c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertTrue(user_domain_match("x.y.com", ".com"))
7010c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertTrue(not user_domain_match("x.y.com", "com"))
7020c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertTrue(not user_domain_match("x.y.com", "m"))
7030c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertTrue(not user_domain_match("x.y.com", ".m"))
7040c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertTrue(not user_domain_match("x.y.com", ""))
7050c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertTrue(not user_domain_match("x.y.com", "."))
7060c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertTrue(user_domain_match("192.168.1.1", "192.168.1.1"))
7070c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # not both HDNs, so must string-compare equal to match
7080c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertTrue(not user_domain_match("192.168.1.1", ".168.1.1"))
7090c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertTrue(not user_domain_match("192.168.1.1", "."))
7100c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # empty string is a special case
7110c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertTrue(not user_domain_match("192.168.1.1", ""))
7120c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
7130c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def test_wrong_domain(self):
7140c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # Cookies whose effective request-host name does not domain-match the
7150c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # domain are rejected.
7160c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
7170c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # XXX far from complete
7180c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        from cookielib import CookieJar
7190c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        c = CookieJar()
7200c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        interact_2965(c, "http://www.nasty.com/",
7210c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                      'foo=bar; domain=friendly.org; Version="1"')
7220c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertEqual(len(c), 0)
7230c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
7240c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def test_strict_domain(self):
7250c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # Cookies whose domain is a country-code tld like .co.uk should
7260c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # not be set if CookiePolicy.strict_domain is true.
7270c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        from cookielib import CookieJar, DefaultCookiePolicy
7280c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
7290c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        cp = DefaultCookiePolicy(strict_domain=True)
7300c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        cj = CookieJar(policy=cp)
7310c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        interact_netscape(cj, "http://example.co.uk/", 'no=problemo')
7320c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        interact_netscape(cj, "http://example.co.uk/",
7330c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                          'okey=dokey; Domain=.example.co.uk')
7340c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertEqual(len(cj), 2)
7350c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        for pseudo_tld in [".co.uk", ".org.za", ".tx.us", ".name.us"]:
7360c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            interact_netscape(cj, "http://example.%s/" % pseudo_tld,
7370c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                              'spam=eggs; Domain=.co.uk')
7380c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self.assertEqual(len(cj), 2)
7390c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
7400c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def test_two_component_domain_ns(self):
7410c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # Netscape: .www.bar.com, www.bar.com, .bar.com, bar.com, no domain
7420c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # should all get accepted, as should .acme.com, acme.com and no domain
7430c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # for 2-component domains like acme.com.
7440c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        from cookielib import CookieJar, DefaultCookiePolicy
7450c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
7460c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        c = CookieJar()
7470c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
7480c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # two-component V0 domain is OK
7490c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        interact_netscape(c, "http://foo.net/", 'ns=bar')
7500c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertEqual(len(c), 1)
7510c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertEqual(c._cookies["foo.net"]["/"]["ns"].value, "bar")
7520c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertEqual(interact_netscape(c, "http://foo.net/"), "ns=bar")
7530c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # *will* be returned to any other domain (unlike RFC 2965)...
7540c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertEqual(interact_netscape(c, "http://www.foo.net/"),
7550c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                         "ns=bar")
7560c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # ...unless requested otherwise
7570c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        pol = DefaultCookiePolicy(
7580c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            strict_ns_domain=DefaultCookiePolicy.DomainStrictNonDomain)
7590c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        c.set_policy(pol)
7600c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertEqual(interact_netscape(c, "http://www.foo.net/"), "")
7610c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
7620c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # unlike RFC 2965, even explicit two-component domain is OK,
7630c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # because .foo.net matches foo.net
7640c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        interact_netscape(c, "http://foo.net/foo/",
7650c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                          'spam1=eggs; domain=foo.net')
7660c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # even if starts with a dot -- in NS rules, .foo.net matches foo.net!
7670c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        interact_netscape(c, "http://foo.net/foo/bar/",
7680c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                          'spam2=eggs; domain=.foo.net')
7690c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertEqual(len(c), 3)
7700c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertEqual(c._cookies[".foo.net"]["/foo"]["spam1"].value,
7710c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                         "eggs")
7720c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertEqual(c._cookies[".foo.net"]["/foo/bar"]["spam2"].value,
7730c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                         "eggs")
7740c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertEqual(interact_netscape(c, "http://foo.net/foo/bar/"),
7750c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                         "spam2=eggs; spam1=eggs; ns=bar")
7760c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
7770c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # top-level domain is too general
7780c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        interact_netscape(c, "http://foo.net/", 'nini="ni"; domain=.net')
7790c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertEqual(len(c), 3)
7800c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
7810c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi##         # Netscape protocol doesn't allow non-special top level domains (such
7820c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi##         # as co.uk) in the domain attribute unless there are at least three
7830c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi##         # dots in it.
7840c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # Oh yes it does!  Real implementations don't check this, and real
7850c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # cookies (of course) rely on that behaviour.
7860c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        interact_netscape(c, "http://foo.co.uk", 'nasty=trick; domain=.co.uk')
7870c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi##         self.assertEqual(len(c), 2)
7880c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertEqual(len(c), 4)
7890c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
7900c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def test_two_component_domain_rfc2965(self):
7910c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        from cookielib import CookieJar, DefaultCookiePolicy
7920c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
7930c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        pol = DefaultCookiePolicy(rfc2965=True)
7940c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        c = CookieJar(pol)
7950c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
7960c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # two-component V1 domain is OK
7970c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        interact_2965(c, "http://foo.net/", 'foo=bar; Version="1"')
7980c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertEqual(len(c), 1)
7990c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertEqual(c._cookies["foo.net"]["/"]["foo"].value, "bar")
8000c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertEqual(interact_2965(c, "http://foo.net/"),
8010c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                         "$Version=1; foo=bar")
8020c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # won't be returned to any other domain (because domain was implied)
8030c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertEqual(interact_2965(c, "http://www.foo.net/"), "")
8040c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
8050c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # unless domain is given explicitly, because then it must be
8060c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # rewritten to start with a dot: foo.net --> .foo.net, which does
8070c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # not domain-match foo.net
8080c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        interact_2965(c, "http://foo.net/foo",
8090c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                      'spam=eggs; domain=foo.net; path=/foo; Version="1"')
8100c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertEqual(len(c), 1)
8110c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertEqual(interact_2965(c, "http://foo.net/foo"),
8120c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                         "$Version=1; foo=bar")
8130c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
8140c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # explicit foo.net from three-component domain www.foo.net *does* get
8150c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # set, because .foo.net domain-matches .foo.net
8160c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        interact_2965(c, "http://www.foo.net/foo/",
8170c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                      'spam=eggs; domain=foo.net; Version="1"')
8180c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertEqual(c._cookies[".foo.net"]["/foo/"]["spam"].value,
8190c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                         "eggs")
8200c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertEqual(len(c), 2)
8210c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertEqual(interact_2965(c, "http://foo.net/foo/"),
8220c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                         "$Version=1; foo=bar")
8230c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertEqual(interact_2965(c, "http://www.foo.net/foo/"),
8240c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                         '$Version=1; spam=eggs; $Domain="foo.net"')
8250c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
8260c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # top-level domain is too general
8270c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        interact_2965(c, "http://foo.net/",
8280c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                      'ni="ni"; domain=".net"; Version="1"')
8290c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertEqual(len(c), 2)
8300c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
8310c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # RFC 2965 doesn't require blocking this
8320c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        interact_2965(c, "http://foo.co.uk/",
8330c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                      'nasty=trick; domain=.co.uk; Version="1"')
8340c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertEqual(len(c), 3)
8350c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
8360c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def test_domain_allow(self):
8370c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        from cookielib import CookieJar, DefaultCookiePolicy
8380c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        from urllib2 import Request
8390c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
8400c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        c = CookieJar(policy=DefaultCookiePolicy(
8410c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            blocked_domains=["acme.com"],
8420c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            allowed_domains=["www.acme.com"]))
8430c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
8440c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        req = Request("http://acme.com/")
8450c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        headers = ["Set-Cookie: CUSTOMER=WILE_E_COYOTE; path=/"]
8460c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        res = FakeResponse(headers, "http://acme.com/")
8470c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        c.extract_cookies(res, req)
8480c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertEqual(len(c), 0)
8490c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
8500c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        req = Request("http://www.acme.com/")
8510c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        res = FakeResponse(headers, "http://www.acme.com/")
8520c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        c.extract_cookies(res, req)
8530c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertEqual(len(c), 1)
8540c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
8550c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        req = Request("http://www.coyote.com/")
8560c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        res = FakeResponse(headers, "http://www.coyote.com/")
8570c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        c.extract_cookies(res, req)
8580c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertEqual(len(c), 1)
8590c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
8600c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # set a cookie with non-allowed domain...
8610c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        req = Request("http://www.coyote.com/")
8620c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        res = FakeResponse(headers, "http://www.coyote.com/")
8630c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        cookies = c.make_cookies(res, req)
8640c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        c.set_cookie(cookies[0])
8650c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertEqual(len(c), 2)
8660c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # ... and check is doesn't get returned
8670c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        c.add_cookie_header(req)
8680c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertTrue(not req.has_header("Cookie"))
8690c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
8700c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def test_domain_block(self):
8710c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        from cookielib import CookieJar, DefaultCookiePolicy
8720c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        from urllib2 import Request
8730c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
8740c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        pol = DefaultCookiePolicy(
8750c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            rfc2965=True, blocked_domains=[".acme.com"])
8760c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        c = CookieJar(policy=pol)
8770c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        headers = ["Set-Cookie: CUSTOMER=WILE_E_COYOTE; path=/"]
8780c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
8790c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        req = Request("http://www.acme.com/")
8800c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        res = FakeResponse(headers, "http://www.acme.com/")
8810c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        c.extract_cookies(res, req)
8820c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertEqual(len(c), 0)
8830c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
8840c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        p = pol.set_blocked_domains(["acme.com"])
8850c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        c.extract_cookies(res, req)
8860c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertEqual(len(c), 1)
8870c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
8880c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        c.clear()
8890c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        req = Request("http://www.roadrunner.net/")
8900c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        res = FakeResponse(headers, "http://www.roadrunner.net/")
8910c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        c.extract_cookies(res, req)
8920c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertEqual(len(c), 1)
8930c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        req = Request("http://www.roadrunner.net/")
8940c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        c.add_cookie_header(req)
8950c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertTrue((req.has_header("Cookie") and
8960c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                      req.has_header("Cookie2")))
8970c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
8980c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        c.clear()
8990c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        pol.set_blocked_domains([".acme.com"])
9000c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        c.extract_cookies(res, req)
9010c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertEqual(len(c), 1)
9020c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
9030c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # set a cookie with blocked domain...
9040c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        req = Request("http://www.acme.com/")
9050c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        res = FakeResponse(headers, "http://www.acme.com/")
9060c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        cookies = c.make_cookies(res, req)
9070c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        c.set_cookie(cookies[0])
9080c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertEqual(len(c), 2)
9090c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # ... and check is doesn't get returned
9100c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        c.add_cookie_header(req)
9110c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertTrue(not req.has_header("Cookie"))
9120c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
9130c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def test_secure(self):
9140c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        from cookielib import CookieJar, DefaultCookiePolicy
9150c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
9160c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        for ns in True, False:
9170c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            for whitespace in " ", "":
9180c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                c = CookieJar()
9190c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                if ns:
9200c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                    pol = DefaultCookiePolicy(rfc2965=False)
9210c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                    int = interact_netscape
9220c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                    vs = ""
9230c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                else:
9240c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                    pol = DefaultCookiePolicy(rfc2965=True)
9250c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                    int = interact_2965
9260c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                    vs = "; Version=1"
9270c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                c.set_policy(pol)
9280c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                url = "http://www.acme.com/"
9290c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                int(c, url, "foo1=bar%s%s" % (vs, whitespace))
9300c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                int(c, url, "foo2=bar%s; secure%s" %  (vs, whitespace))
9310c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                self.assertTrue(
9320c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                    not c._cookies["www.acme.com"]["/"]["foo1"].secure,
9330c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                    "non-secure cookie registered secure")
9340c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                self.assertTrue(
9350c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                    c._cookies["www.acme.com"]["/"]["foo2"].secure,
9360c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                    "secure cookie registered non-secure")
9370c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
9380c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def test_quote_cookie_value(self):
9390c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        from cookielib import CookieJar, DefaultCookiePolicy
9400c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        c = CookieJar(policy=DefaultCookiePolicy(rfc2965=True))
9410c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        interact_2965(c, "http://www.acme.com/", r'foo=\b"a"r; Version=1')
9420c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        h = interact_2965(c, "http://www.acme.com/")
9430c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertEqual(h, r'$Version=1; foo=\\b\"a\"r')
9440c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
9450c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def test_missing_final_slash(self):
9460c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # Missing slash from request URL's abs_path should be assumed present.
9470c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        from cookielib import CookieJar, DefaultCookiePolicy
9480c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        from urllib2 import Request
9490c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        url = "http://www.acme.com"
9500c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        c = CookieJar(DefaultCookiePolicy(rfc2965=True))
9510c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        interact_2965(c, url, "foo=bar; Version=1")
9520c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        req = Request(url)
9530c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertEqual(len(c), 1)
9540c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        c.add_cookie_header(req)
9550c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertTrue(req.has_header("Cookie"))
9560c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
9570c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def test_domain_mirror(self):
9580c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        from cookielib import CookieJar, DefaultCookiePolicy
9590c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
9600c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        pol = DefaultCookiePolicy(rfc2965=True)
9610c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
9620c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        c = CookieJar(pol)
9630c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        url = "http://foo.bar.com/"
9640c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        interact_2965(c, url, "spam=eggs; Version=1")
9650c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        h = interact_2965(c, url)
9660c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertNotIn("Domain", h,
9670c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                         "absent domain returned with domain present")
9680c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
9690c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        c = CookieJar(pol)
9700c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        url = "http://foo.bar.com/"
9710c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        interact_2965(c, url, 'spam=eggs; Version=1; Domain=.bar.com')
9720c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        h = interact_2965(c, url)
9730c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertIn('$Domain=".bar.com"', h, "domain not returned")
9740c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
9750c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        c = CookieJar(pol)
9760c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        url = "http://foo.bar.com/"
9770c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # note missing initial dot in Domain
9780c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        interact_2965(c, url, 'spam=eggs; Version=1; Domain=bar.com')
9790c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        h = interact_2965(c, url)
9800c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertIn('$Domain="bar.com"', h, "domain not returned")
9810c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
9820c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def test_path_mirror(self):
9830c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        from cookielib import CookieJar, DefaultCookiePolicy
9840c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
9850c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        pol = DefaultCookiePolicy(rfc2965=True)
9860c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
9870c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        c = CookieJar(pol)
9880c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        url = "http://foo.bar.com/"
9890c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        interact_2965(c, url, "spam=eggs; Version=1")
9900c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        h = interact_2965(c, url)
9910c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertNotIn("Path", h, "absent path returned with path present")
9920c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
9930c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        c = CookieJar(pol)
9940c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        url = "http://foo.bar.com/"
9950c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        interact_2965(c, url, 'spam=eggs; Version=1; Path=/')
9960c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        h = interact_2965(c, url)
9970c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertIn('$Path="/"', h, "path not returned")
9980c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
9990c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def test_port_mirror(self):
10000c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        from cookielib import CookieJar, DefaultCookiePolicy
10010c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
10020c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        pol = DefaultCookiePolicy(rfc2965=True)
10030c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
10040c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        c = CookieJar(pol)
10050c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        url = "http://foo.bar.com/"
10060c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        interact_2965(c, url, "spam=eggs; Version=1")
10070c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        h = interact_2965(c, url)
10080c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertNotIn("Port", h, "absent port returned with port present")
10090c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
10100c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        c = CookieJar(pol)
10110c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        url = "http://foo.bar.com/"
10120c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        interact_2965(c, url, "spam=eggs; Version=1; Port")
10130c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        h = interact_2965(c, url)
10140c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertTrue(re.search("\$Port([^=]|$)", h),
10150c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                     "port with no value not returned with no value")
10160c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
10170c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        c = CookieJar(pol)
10180c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        url = "http://foo.bar.com/"
10190c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        interact_2965(c, url, 'spam=eggs; Version=1; Port="80"')
10200c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        h = interact_2965(c, url)
10210c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertIn('$Port="80"', h,
10220c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                      "port with single value not returned with single value")
10230c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
10240c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        c = CookieJar(pol)
10250c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        url = "http://foo.bar.com/"
10260c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        interact_2965(c, url, 'spam=eggs; Version=1; Port="80,8080"')
10270c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        h = interact_2965(c, url)
10280c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertIn('$Port="80,8080"', h,
10290c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                      "port with multiple values not returned with multiple "
10300c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                      "values")
10310c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
10320c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def test_no_return_comment(self):
10330c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        from cookielib import CookieJar, DefaultCookiePolicy
10340c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
10350c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        c = CookieJar(DefaultCookiePolicy(rfc2965=True))
10360c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        url = "http://foo.bar.com/"
10370c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        interact_2965(c, url, 'spam=eggs; Version=1; '
10380c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                      'Comment="does anybody read these?"; '
10390c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                      'CommentURL="http://foo.bar.net/comment.html"')
10400c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        h = interact_2965(c, url)
10410c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertTrue(
10420c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            "Comment" not in h,
10430c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            "Comment or CommentURL cookie-attributes returned to server")
10440c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
10450c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def test_Cookie_iterator(self):
10460c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        from cookielib import CookieJar, Cookie, DefaultCookiePolicy
10470c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
10480c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        cs = CookieJar(DefaultCookiePolicy(rfc2965=True))
10490c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # add some random cookies
10500c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        interact_2965(cs, "http://blah.spam.org/", 'foo=eggs; Version=1; '
10510c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                      'Comment="does anybody read these?"; '
10520c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                      'CommentURL="http://foo.bar.net/comment.html"')
10530c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        interact_netscape(cs, "http://www.acme.com/blah/", "spam=bar; secure")
10540c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        interact_2965(cs, "http://www.acme.com/blah/",
10550c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                      "foo=bar; secure; Version=1")
10560c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        interact_2965(cs, "http://www.acme.com/blah/",
10570c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                      "foo=bar; path=/; Version=1")
10580c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        interact_2965(cs, "http://www.sol.no",
10590c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                      r'bang=wallop; version=1; domain=".sol.no"; '
10600c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                      r'port="90,100, 80,8080"; '
10610c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                      r'max-age=100; Comment = "Just kidding! (\"|\\\\) "')
10620c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
10630c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        versions = [1, 1, 1, 0, 1]
10640c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        names = ["bang", "foo", "foo", "spam", "foo"]
10650c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        domains = [".sol.no", "blah.spam.org", "www.acme.com",
10660c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                   "www.acme.com", "www.acme.com"]
10670c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        paths = ["/", "/", "/", "/blah", "/blah/"]
10680c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
10690c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        for i in range(4):
10700c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            i = 0
10710c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            for c in cs:
10720c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                self.assertIsInstance(c, Cookie)
10730c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                self.assertEqual(c.version, versions[i])
10740c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                self.assertEqual(c.name, names[i])
10750c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                self.assertEqual(c.domain, domains[i])
10760c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                self.assertEqual(c.path, paths[i])
10770c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                i = i + 1
10780c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
10790c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def test_parse_ns_headers(self):
10800c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        from cookielib import parse_ns_headers
10810c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
10820c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # missing domain value (invalid cookie)
10830c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertEqual(
10840c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            parse_ns_headers(["foo=bar; path=/; domain"]),
10850c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            [[("foo", "bar"),
10860c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi              ("path", "/"), ("domain", None), ("version", "0")]]
10870c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            )
10880c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # invalid expires value
10890c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertEqual(
10900c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            parse_ns_headers(["foo=bar; expires=Foo Bar 12 33:22:11 2000"]),
10910c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            [[("foo", "bar"), ("expires", None), ("version", "0")]]
10920c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            )
10930c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # missing cookie value (valid cookie)
10940c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertEqual(
10950c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            parse_ns_headers(["foo"]),
10960c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            [[("foo", None), ("version", "0")]]
10970c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            )
10980c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # shouldn't add version if header is empty
10990c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertEqual(parse_ns_headers([""]), [])
11000c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
11010c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def test_bad_cookie_header(self):
11020c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
11030c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        def cookiejar_from_cookie_headers(headers):
11040c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            from cookielib import CookieJar
11050c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            from urllib2 import Request
11060c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            c = CookieJar()
11070c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            req = Request("http://www.example.com/")
11080c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            r = FakeResponse(headers, "http://www.example.com/")
11090c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            c.extract_cookies(r, req)
11100c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            return c
11110c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
11120c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # none of these bad headers should cause an exception to be raised
11130c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        for headers in [
11140c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            ["Set-Cookie: "],  # actually, nothing wrong with this
11150c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            ["Set-Cookie2: "],  # ditto
11160c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            # missing domain value
11170c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            ["Set-Cookie2: a=foo; path=/; Version=1; domain"],
11180c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            # bad max-age
11190c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            ["Set-Cookie: b=foo; max-age=oops"],
11200c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            # bad version
11210c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            ["Set-Cookie: b=foo; version=spam"],
11220c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            ]:
11230c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            c = cookiejar_from_cookie_headers(headers)
11240c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            # these bad cookies shouldn't be set
11250c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self.assertEqual(len(c), 0)
11260c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
11270c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # cookie with invalid expires is treated as session cookie
11280c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        headers = ["Set-Cookie: c=foo; expires=Foo Bar 12 33:22:11 2000"]
11290c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        c = cookiejar_from_cookie_headers(headers)
11300c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        cookie = c._cookies["www.example.com"]["/"]["c"]
11310c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertTrue(cookie.expires is None)
11320c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
11330c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
11340c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yiclass LWPCookieTests(TestCase):
11350c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    # Tests taken from libwww-perl, with a few modifications and additions.
11360c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
11370c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def test_netscape_example_1(self):
11380c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        from cookielib import CookieJar, DefaultCookiePolicy
11390c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        from urllib2 import Request
11400c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
11410c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        #-------------------------------------------------------------------
11420c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # First we check that it works for the original example at
11430c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # http://www.netscape.com/newsref/std/cookie_spec.html
11440c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
11450c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # Client requests a document, and receives in the response:
11460c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        #
11470c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        #       Set-Cookie: CUSTOMER=WILE_E_COYOTE; path=/; expires=Wednesday, 09-Nov-99 23:12:40 GMT
11480c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        #
11490c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # When client requests a URL in path "/" on this server, it sends:
11500c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        #
11510c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        #       Cookie: CUSTOMER=WILE_E_COYOTE
11520c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        #
11530c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # Client requests a document, and receives in the response:
11540c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        #
11550c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        #       Set-Cookie: PART_NUMBER=ROCKET_LAUNCHER_0001; path=/
11560c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        #
11570c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # When client requests a URL in path "/" on this server, it sends:
11580c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        #
11590c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        #       Cookie: CUSTOMER=WILE_E_COYOTE; PART_NUMBER=ROCKET_LAUNCHER_0001
11600c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        #
11610c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # Client receives:
11620c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        #
11630c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        #       Set-Cookie: SHIPPING=FEDEX; path=/fo
11640c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        #
11650c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # When client requests a URL in path "/" on this server, it sends:
11660c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        #
11670c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        #       Cookie: CUSTOMER=WILE_E_COYOTE; PART_NUMBER=ROCKET_LAUNCHER_0001
11680c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        #
11690c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # When client requests a URL in path "/foo" on this server, it sends:
11700c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        #
11710c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        #       Cookie: CUSTOMER=WILE_E_COYOTE; PART_NUMBER=ROCKET_LAUNCHER_0001; SHIPPING=FEDEX
11720c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        #
11730c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # The last Cookie is buggy, because both specifications say that the
11740c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # most specific cookie must be sent first.  SHIPPING=FEDEX is the
11750c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # most specific and should thus be first.
11760c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
11770c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        year_plus_one = time.localtime()[0] + 1
11780c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
11790c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        headers = []
11800c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
11810c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        c = CookieJar(DefaultCookiePolicy(rfc2965 = True))
11820c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
11830c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        #req = Request("http://1.1.1.1/",
11840c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        #              headers={"Host": "www.acme.com:80"})
11850c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        req = Request("http://www.acme.com:80/",
11860c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                      headers={"Host": "www.acme.com:80"})
11870c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
11880c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        headers.append(
11890c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            "Set-Cookie: CUSTOMER=WILE_E_COYOTE; path=/ ; "
11900c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            "expires=Wednesday, 09-Nov-%d 23:12:40 GMT" % year_plus_one)
11910c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        res = FakeResponse(headers, "http://www.acme.com/")
11920c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        c.extract_cookies(res, req)
11930c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
11940c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        req = Request("http://www.acme.com/")
11950c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        c.add_cookie_header(req)
11960c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
11970c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertEqual(req.get_header("Cookie"), "CUSTOMER=WILE_E_COYOTE")
11980c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertEqual(req.get_header("Cookie2"), '$Version="1"')
11990c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
12000c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        headers.append("Set-Cookie: PART_NUMBER=ROCKET_LAUNCHER_0001; path=/")
12010c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        res = FakeResponse(headers, "http://www.acme.com/")
12020c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        c.extract_cookies(res, req)
12030c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
12040c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        req = Request("http://www.acme.com/foo/bar")
12050c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        c.add_cookie_header(req)
12060c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
12070c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        h = req.get_header("Cookie")
12080c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertIn("PART_NUMBER=ROCKET_LAUNCHER_0001", h)
12090c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertIn("CUSTOMER=WILE_E_COYOTE", h)
12100c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
12110c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        headers.append('Set-Cookie: SHIPPING=FEDEX; path=/foo')
12120c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        res = FakeResponse(headers, "http://www.acme.com")
12130c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        c.extract_cookies(res, req)
12140c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
12150c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        req = Request("http://www.acme.com/")
12160c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        c.add_cookie_header(req)
12170c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
12180c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        h = req.get_header("Cookie")
12190c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertIn("PART_NUMBER=ROCKET_LAUNCHER_0001", h)
12200c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertIn("CUSTOMER=WILE_E_COYOTE", h)
12210c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertNotIn("SHIPPING=FEDEX", h)
12220c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
12230c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        req = Request("http://www.acme.com/foo/")
12240c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        c.add_cookie_header(req)
12250c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
12260c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        h = req.get_header("Cookie")
12270c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertIn("PART_NUMBER=ROCKET_LAUNCHER_0001", h)
12280c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertIn("CUSTOMER=WILE_E_COYOTE", h)
12290c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertTrue(h.startswith("SHIPPING=FEDEX;"))
12300c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
12310c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def test_netscape_example_2(self):
12320c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        from cookielib import CookieJar
12330c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        from urllib2 import Request
12340c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
12350c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # Second Example transaction sequence:
12360c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        #
12370c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # Assume all mappings from above have been cleared.
12380c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        #
12390c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # Client receives:
12400c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        #
12410c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        #       Set-Cookie: PART_NUMBER=ROCKET_LAUNCHER_0001; path=/
12420c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        #
12430c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # When client requests a URL in path "/" on this server, it sends:
12440c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        #
12450c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        #       Cookie: PART_NUMBER=ROCKET_LAUNCHER_0001
12460c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        #
12470c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # Client receives:
12480c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        #
12490c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        #       Set-Cookie: PART_NUMBER=RIDING_ROCKET_0023; path=/ammo
12500c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        #
12510c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # When client requests a URL in path "/ammo" on this server, it sends:
12520c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        #
12530c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        #       Cookie: PART_NUMBER=RIDING_ROCKET_0023; PART_NUMBER=ROCKET_LAUNCHER_0001
12540c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        #
12550c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        #       NOTE: There are two name/value pairs named "PART_NUMBER" due to
12560c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        #       the inheritance of the "/" mapping in addition to the "/ammo" mapping.
12570c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
12580c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        c = CookieJar()
12590c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        headers = []
12600c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
12610c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        req = Request("http://www.acme.com/")
12620c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        headers.append("Set-Cookie: PART_NUMBER=ROCKET_LAUNCHER_0001; path=/")
12630c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        res = FakeResponse(headers, "http://www.acme.com/")
12640c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
12650c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        c.extract_cookies(res, req)
12660c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
12670c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        req = Request("http://www.acme.com/")
12680c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        c.add_cookie_header(req)
12690c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
12700c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertEqual(req.get_header("Cookie"),
12710c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                          "PART_NUMBER=ROCKET_LAUNCHER_0001")
12720c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
12730c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        headers.append(
12740c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            "Set-Cookie: PART_NUMBER=RIDING_ROCKET_0023; path=/ammo")
12750c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        res = FakeResponse(headers, "http://www.acme.com/")
12760c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        c.extract_cookies(res, req)
12770c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
12780c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        req = Request("http://www.acme.com/ammo")
12790c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        c.add_cookie_header(req)
12800c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
12810c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertTrue(re.search(r"PART_NUMBER=RIDING_ROCKET_0023;\s*"
12820c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                               "PART_NUMBER=ROCKET_LAUNCHER_0001",
12830c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                               req.get_header("Cookie")))
12840c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
12850c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def test_ietf_example_1(self):
12860c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        from cookielib import CookieJar, DefaultCookiePolicy
12870c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        #-------------------------------------------------------------------
12880c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # Then we test with the examples from draft-ietf-http-state-man-mec-03.txt
12890c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        #
12900c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # 5.  EXAMPLES
12910c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
12920c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        c = CookieJar(DefaultCookiePolicy(rfc2965=True))
12930c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
12940c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        #
12950c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # 5.1  Example 1
12960c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        #
12970c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # Most detail of request and response headers has been omitted.  Assume
12980c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # the user agent has no stored cookies.
12990c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        #
13000c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        #   1.  User Agent -> Server
13010c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        #
13020c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        #       POST /acme/login HTTP/1.1
13030c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        #       [form data]
13040c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        #
13050c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        #       User identifies self via a form.
13060c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        #
13070c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        #   2.  Server -> User Agent
13080c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        #
13090c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        #       HTTP/1.1 200 OK
13100c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        #       Set-Cookie2: Customer="WILE_E_COYOTE"; Version="1"; Path="/acme"
13110c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        #
13120c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        #       Cookie reflects user's identity.
13130c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
13140c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        cookie = interact_2965(
13150c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            c, 'http://www.acme.com/acme/login',
13160c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            'Customer="WILE_E_COYOTE"; Version="1"; Path="/acme"')
13170c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertTrue(not cookie)
13180c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
13190c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        #
13200c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        #   3.  User Agent -> Server
13210c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        #
13220c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        #       POST /acme/pickitem HTTP/1.1
13230c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        #       Cookie: $Version="1"; Customer="WILE_E_COYOTE"; $Path="/acme"
13240c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        #       [form data]
13250c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        #
13260c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        #       User selects an item for ``shopping basket.''
13270c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        #
13280c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        #   4.  Server -> User Agent
13290c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        #
13300c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        #       HTTP/1.1 200 OK
13310c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        #       Set-Cookie2: Part_Number="Rocket_Launcher_0001"; Version="1";
13320c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        #               Path="/acme"
13330c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        #
13340c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        #       Shopping basket contains an item.
13350c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
13360c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        cookie = interact_2965(c, 'http://www.acme.com/acme/pickitem',
13370c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                               'Part_Number="Rocket_Launcher_0001"; '
13380c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                               'Version="1"; Path="/acme"');
13390c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertTrue(re.search(
13400c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            r'^\$Version="?1"?; Customer="?WILE_E_COYOTE"?; \$Path="/acme"$',
13410c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            cookie))
13420c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
13430c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        #
13440c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        #   5.  User Agent -> Server
13450c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        #
13460c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        #       POST /acme/shipping HTTP/1.1
13470c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        #       Cookie: $Version="1";
13480c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        #               Customer="WILE_E_COYOTE"; $Path="/acme";
13490c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        #               Part_Number="Rocket_Launcher_0001"; $Path="/acme"
13500c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        #       [form data]
13510c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        #
13520c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        #       User selects shipping method from form.
13530c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        #
13540c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        #   6.  Server -> User Agent
13550c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        #
13560c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        #       HTTP/1.1 200 OK
13570c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        #       Set-Cookie2: Shipping="FedEx"; Version="1"; Path="/acme"
13580c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        #
13590c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        #       New cookie reflects shipping method.
13600c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
13610c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        cookie = interact_2965(c, "http://www.acme.com/acme/shipping",
13620c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                               'Shipping="FedEx"; Version="1"; Path="/acme"')
13630c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
13640c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertTrue(re.search(r'^\$Version="?1"?;', cookie))
13650c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertTrue(re.search(r'Part_Number="?Rocket_Launcher_0001"?;'
13660c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                               '\s*\$Path="\/acme"', cookie))
13670c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertTrue(re.search(r'Customer="?WILE_E_COYOTE"?;\s*\$Path="\/acme"',
13680c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                               cookie))
13690c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
13700c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        #
13710c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        #   7.  User Agent -> Server
13720c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        #
13730c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        #       POST /acme/process HTTP/1.1
13740c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        #       Cookie: $Version="1";
13750c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        #               Customer="WILE_E_COYOTE"; $Path="/acme";
13760c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        #               Part_Number="Rocket_Launcher_0001"; $Path="/acme";
13770c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        #               Shipping="FedEx"; $Path="/acme"
13780c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        #       [form data]
13790c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        #
13800c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        #       User chooses to process order.
13810c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        #
13820c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        #   8.  Server -> User Agent
13830c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        #
13840c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        #       HTTP/1.1 200 OK
13850c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        #
13860c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        #       Transaction is complete.
13870c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
13880c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        cookie = interact_2965(c, "http://www.acme.com/acme/process")
13890c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertTrue(
13900c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            re.search(r'Shipping="?FedEx"?;\s*\$Path="\/acme"', cookie) and
13910c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            "WILE_E_COYOTE" in cookie)
13920c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
13930c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        #
13940c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # The user agent makes a series of requests on the origin server, after
13950c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # each of which it receives a new cookie.  All the cookies have the same
13960c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # Path attribute and (default) domain.  Because the request URLs all have
13970c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # /acme as a prefix, and that matches the Path attribute, each request
13980c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # contains all the cookies received so far.
13990c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
14000c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def test_ietf_example_2(self):
14010c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        from cookielib import CookieJar, DefaultCookiePolicy
14020c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
14030c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # 5.2  Example 2
14040c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        #
14050c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # This example illustrates the effect of the Path attribute.  All detail
14060c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # of request and response headers has been omitted.  Assume the user agent
14070c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # has no stored cookies.
14080c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
14090c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        c = CookieJar(DefaultCookiePolicy(rfc2965=True))
14100c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
14110c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # Imagine the user agent has received, in response to earlier requests,
14120c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # the response headers
14130c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        #
14140c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # Set-Cookie2: Part_Number="Rocket_Launcher_0001"; Version="1";
14150c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        #         Path="/acme"
14160c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        #
14170c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # and
14180c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        #
14190c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # Set-Cookie2: Part_Number="Riding_Rocket_0023"; Version="1";
14200c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        #         Path="/acme/ammo"
14210c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
14220c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        interact_2965(
14230c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            c, "http://www.acme.com/acme/ammo/specific",
14240c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            'Part_Number="Rocket_Launcher_0001"; Version="1"; Path="/acme"',
14250c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            'Part_Number="Riding_Rocket_0023"; Version="1"; Path="/acme/ammo"')
14260c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
14270c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # A subsequent request by the user agent to the (same) server for URLs of
14280c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # the form /acme/ammo/...  would include the following request header:
14290c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        #
14300c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # Cookie: $Version="1";
14310c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        #         Part_Number="Riding_Rocket_0023"; $Path="/acme/ammo";
14320c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        #         Part_Number="Rocket_Launcher_0001"; $Path="/acme"
14330c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        #
14340c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # Note that the NAME=VALUE pair for the cookie with the more specific Path
14350c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # attribute, /acme/ammo, comes before the one with the less specific Path
14360c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # attribute, /acme.  Further note that the same cookie name appears more
14370c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # than once.
14380c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
14390c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        cookie = interact_2965(c, "http://www.acme.com/acme/ammo/...")
14400c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertTrue(
14410c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            re.search(r"Riding_Rocket_0023.*Rocket_Launcher_0001", cookie))
14420c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
14430c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # A subsequent request by the user agent to the (same) server for a URL of
14440c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # the form /acme/parts/ would include the following request header:
14450c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        #
14460c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # Cookie: $Version="1"; Part_Number="Rocket_Launcher_0001"; $Path="/acme"
14470c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        #
14480c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # Here, the second cookie's Path attribute /acme/ammo is not a prefix of
14490c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # the request URL, /acme/parts/, so the cookie does not get forwarded to
14500c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # the server.
14510c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
14520c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        cookie = interact_2965(c, "http://www.acme.com/acme/parts/")
14530c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertIn("Rocket_Launcher_0001", cookie)
14540c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertNotIn("Riding_Rocket_0023", cookie)
14550c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
14560c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def test_rejection(self):
14570c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # Test rejection of Set-Cookie2 responses based on domain, path, port.
14580c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        from cookielib import DefaultCookiePolicy, LWPCookieJar
14590c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
14600c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        pol = DefaultCookiePolicy(rfc2965=True)
14610c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
14620c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        c = LWPCookieJar(policy=pol)
14630c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
14640c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        max_age = "max-age=3600"
14650c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
14660c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # illegal domain (no embedded dots)
14670c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        cookie = interact_2965(c, "http://www.acme.com",
14680c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                               'foo=bar; domain=".com"; version=1')
14690c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertTrue(not c)
14700c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
14710c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # legal domain
14720c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        cookie = interact_2965(c, "http://www.acme.com",
14730c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                               'ping=pong; domain="acme.com"; version=1')
14740c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertEqual(len(c), 1)
14750c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
14760c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # illegal domain (host prefix "www.a" contains a dot)
14770c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        cookie = interact_2965(c, "http://www.a.acme.com",
14780c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                               'whiz=bang; domain="acme.com"; version=1')
14790c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertEqual(len(c), 1)
14800c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
14810c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # legal domain
14820c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        cookie = interact_2965(c, "http://www.a.acme.com",
14830c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                               'wow=flutter; domain=".a.acme.com"; version=1')
14840c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertEqual(len(c), 2)
14850c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
14860c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # can't partially match an IP-address
14870c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        cookie = interact_2965(c, "http://125.125.125.125",
14880c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                               'zzzz=ping; domain="125.125.125"; version=1')
14890c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertEqual(len(c), 2)
14900c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
14910c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # illegal path (must be prefix of request path)
14920c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        cookie = interact_2965(c, "http://www.sol.no",
14930c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                               'blah=rhubarb; domain=".sol.no"; path="/foo"; '
14940c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                               'version=1')
14950c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertEqual(len(c), 2)
14960c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
14970c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # legal path
14980c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        cookie = interact_2965(c, "http://www.sol.no/foo/bar",
14990c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                               'bing=bong; domain=".sol.no"; path="/foo"; '
15000c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                               'version=1')
15010c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertEqual(len(c), 3)
15020c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
15030c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # illegal port (request-port not in list)
15040c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        cookie = interact_2965(c, "http://www.sol.no",
15050c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                               'whiz=ffft; domain=".sol.no"; port="90,100"; '
15060c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                               'version=1')
15070c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertEqual(len(c), 3)
15080c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
15090c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # legal port
15100c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        cookie = interact_2965(
15110c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            c, "http://www.sol.no",
15120c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            r'bang=wallop; version=1; domain=".sol.no"; '
15130c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            r'port="90,100, 80,8080"; '
15140c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            r'max-age=100; Comment = "Just kidding! (\"|\\\\) "')
15150c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertEqual(len(c), 4)
15160c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
15170c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # port attribute without any value (current port)
15180c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        cookie = interact_2965(c, "http://www.sol.no",
15190c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                               'foo9=bar; version=1; domain=".sol.no"; port; '
15200c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                               'max-age=100;')
15210c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertEqual(len(c), 5)
15220c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
15230c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # encoded path
15240c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # LWP has this test, but unescaping allowed path characters seems
15250c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # like a bad idea, so I think this should fail:
15260c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi##         cookie = interact_2965(c, "http://www.sol.no/foo/",
15270c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi##                           r'foo8=bar; version=1; path="/%66oo"')
15280c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # but this is OK, because '<' is not an allowed HTTP URL path
15290c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # character:
15300c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        cookie = interact_2965(c, "http://www.sol.no/<oo/",
15310c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                               r'foo8=bar; version=1; path="/%3coo"')
15320c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertEqual(len(c), 6)
15330c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
15340c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # save and restore
15350c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        filename = test_support.TESTFN
15360c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
15370c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        try:
15380c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            c.save(filename, ignore_discard=True)
15390c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            old = repr(c)
15400c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
15410c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            c = LWPCookieJar(policy=pol)
15420c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            c.load(filename, ignore_discard=True)
15430c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        finally:
15440c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            try: os.unlink(filename)
15450c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            except OSError: pass
15460c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
15470c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertEqual(old, repr(c))
15480c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
15490c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def test_url_encoding(self):
15500c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # Try some URL encodings of the PATHs.
15510c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # (the behaviour here has changed from libwww-perl)
15520c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        from cookielib import CookieJar, DefaultCookiePolicy
15530c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
15540c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        c = CookieJar(DefaultCookiePolicy(rfc2965=True))
15550c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        interact_2965(c, "http://www.acme.com/foo%2f%25/%3c%3c%0Anew%E5/%E5",
15560c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                      "foo  =   bar; version    =   1")
15570c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
15580c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        cookie = interact_2965(
15590c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            c, "http://www.acme.com/foo%2f%25/<<%0anew�/���",
15600c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            'bar=baz; path="/foo/"; version=1');
15610c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        version_re = re.compile(r'^\$version=\"?1\"?', re.I)
15620c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertTrue("foo=bar" in cookie and version_re.search(cookie))
15630c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
15640c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        cookie = interact_2965(
15650c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            c, "http://www.acme.com/foo/%25/<<%0anew�/���")
15660c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertTrue(not cookie)
15670c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
15680c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # unicode URL doesn't raise exception
15690c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        cookie = interact_2965(c, u"http://www.acme.com/\xfc")
15700c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
15710c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def test_mozilla(self):
15720c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # Save / load Mozilla/Netscape cookie file format.
15730c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        from cookielib import MozillaCookieJar, DefaultCookiePolicy
15740c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
15750c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        year_plus_one = time.localtime()[0] + 1
15760c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
15770c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        filename = test_support.TESTFN
15780c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
15790c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        c = MozillaCookieJar(filename,
15800c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                             policy=DefaultCookiePolicy(rfc2965=True))
15810c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        interact_2965(c, "http://www.acme.com/",
15820c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                      "foo1=bar; max-age=100; Version=1")
15830c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        interact_2965(c, "http://www.acme.com/",
15840c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                      'foo2=bar; port="80"; max-age=100; Discard; Version=1')
15850c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        interact_2965(c, "http://www.acme.com/", "foo3=bar; secure; Version=1")
15860c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
15870c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        expires = "expires=09-Nov-%d 23:12:40 GMT" % (year_plus_one,)
15880c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        interact_netscape(c, "http://www.foo.com/",
15890c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                          "fooa=bar; %s" % expires)
15900c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        interact_netscape(c, "http://www.foo.com/",
15910c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                          "foob=bar; Domain=.foo.com; %s" % expires)
15920c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        interact_netscape(c, "http://www.foo.com/",
15930c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                          "fooc=bar; Domain=www.foo.com; %s" % expires)
15940c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
15950c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        def save_and_restore(cj, ignore_discard):
15960c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            try:
15970c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                cj.save(ignore_discard=ignore_discard)
15980c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                new_c = MozillaCookieJar(filename,
15990c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                                         DefaultCookiePolicy(rfc2965=True))
16000c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                new_c.load(ignore_discard=ignore_discard)
16010c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            finally:
16020c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                try: os.unlink(filename)
16030c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                except OSError: pass
16040c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            return new_c
16050c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
16060c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        new_c = save_and_restore(c, True)
16070c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertEqual(len(new_c), 6)  # none discarded
16080c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertIn("name='foo1', value='bar'", repr(new_c))
16090c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
16100c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        new_c = save_and_restore(c, False)
16110c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertEqual(len(new_c), 4)  # 2 of them discarded on save
16120c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertIn("name='foo1', value='bar'", repr(new_c))
16130c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
16140c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def test_netscape_misc(self):
16150c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # Some additional Netscape cookies tests.
16160c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        from cookielib import CookieJar
16170c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        from urllib2 import Request
16180c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
16190c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        c = CookieJar()
16200c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        headers = []
16210c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        req = Request("http://foo.bar.acme.com/foo")
16220c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
16230c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # Netscape allows a host part that contains dots
16240c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        headers.append("Set-Cookie: Customer=WILE_E_COYOTE; domain=.acme.com")
16250c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        res = FakeResponse(headers, "http://www.acme.com/foo")
16260c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        c.extract_cookies(res, req)
16270c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
16280c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # and that the domain is the same as the host without adding a leading
16290c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # dot to the domain.  Should not quote even if strange chars are used
16300c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # in the cookie value.
16310c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        headers.append("Set-Cookie: PART_NUMBER=3,4; domain=foo.bar.acme.com")
16320c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        res = FakeResponse(headers, "http://www.acme.com/foo")
16330c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        c.extract_cookies(res, req)
16340c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
16350c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        req = Request("http://foo.bar.acme.com/foo")
16360c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        c.add_cookie_header(req)
16370c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertTrue(
16380c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            "PART_NUMBER=3,4" in req.get_header("Cookie") and
16390c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            "Customer=WILE_E_COYOTE" in req.get_header("Cookie"))
16400c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
16410c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def test_intranet_domains_2965(self):
16420c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # Test handling of local intranet hostnames without a dot.
16430c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        from cookielib import CookieJar, DefaultCookiePolicy
16440c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
16450c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        c = CookieJar(DefaultCookiePolicy(rfc2965=True))
16460c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        interact_2965(c, "http://example/",
16470c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                      "foo1=bar; PORT; Discard; Version=1;")
16480c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        cookie = interact_2965(c, "http://example/",
16490c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                               'foo2=bar; domain=".local"; Version=1')
16500c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertIn("foo1=bar", cookie)
16510c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
16520c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        interact_2965(c, "http://example/", 'foo3=bar; Version=1')
16530c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        cookie = interact_2965(c, "http://example/")
16540c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertIn("foo2=bar", cookie)
16550c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertEqual(len(c), 3)
16560c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
16570c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def test_intranet_domains_ns(self):
16580c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        from cookielib import CookieJar, DefaultCookiePolicy
16590c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
16600c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        c = CookieJar(DefaultCookiePolicy(rfc2965 = False))
16610c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        interact_netscape(c, "http://example/", "foo1=bar")
16620c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        cookie = interact_netscape(c, "http://example/",
16630c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                                   'foo2=bar; domain=.local')
16640c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertEqual(len(c), 2)
16650c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertIn("foo1=bar", cookie)
16660c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
16670c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        cookie = interact_netscape(c, "http://example/")
16680c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertIn("foo2=bar", cookie)
16690c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertEqual(len(c), 2)
16700c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
16710c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def test_empty_path(self):
16720c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        from cookielib import CookieJar, DefaultCookiePolicy
16730c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        from urllib2 import Request
16740c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
16750c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # Test for empty path
16760c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # Broken web-server ORION/1.3.38 returns to the client response like
16770c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        #
16780c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        #       Set-Cookie: JSESSIONID=ABCDERANDOM123; Path=
16790c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        #
16800c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # ie. with Path set to nothing.
16810c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # In this case, extract_cookies() must set cookie to / (root)
16820c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        c = CookieJar(DefaultCookiePolicy(rfc2965 = True))
16830c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        headers = []
16840c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
16850c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        req = Request("http://www.ants.com/")
16860c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        headers.append("Set-Cookie: JSESSIONID=ABCDERANDOM123; Path=")
16870c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        res = FakeResponse(headers, "http://www.ants.com/")
16880c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        c.extract_cookies(res, req)
16890c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
16900c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        req = Request("http://www.ants.com/")
16910c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        c.add_cookie_header(req)
16920c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
16930c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertEqual(req.get_header("Cookie"),
16940c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                         "JSESSIONID=ABCDERANDOM123")
16950c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertEqual(req.get_header("Cookie2"), '$Version="1"')
16960c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
16970c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # missing path in the request URI
16980c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        req = Request("http://www.ants.com:8080")
16990c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        c.add_cookie_header(req)
17000c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
17010c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertEqual(req.get_header("Cookie"),
17020c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                         "JSESSIONID=ABCDERANDOM123")
17030c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertEqual(req.get_header("Cookie2"), '$Version="1"')
17040c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
17050c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def test_session_cookies(self):
17060c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        from cookielib import CookieJar
17070c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        from urllib2 import Request
17080c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
17090c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        year_plus_one = time.localtime()[0] + 1
17100c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
17110c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # Check session cookies are deleted properly by
17120c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # CookieJar.clear_session_cookies method
17130c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
17140c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        req = Request('http://www.perlmeister.com/scripts')
17150c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        headers = []
17160c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        headers.append("Set-Cookie: s1=session;Path=/scripts")
17170c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        headers.append("Set-Cookie: p1=perm; Domain=.perlmeister.com;"
17180c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                       "Path=/;expires=Fri, 02-Feb-%d 23:24:20 GMT" %
17190c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                       year_plus_one)
17200c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        headers.append("Set-Cookie: p2=perm;Path=/;expires=Fri, "
17210c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                       "02-Feb-%d 23:24:20 GMT" % year_plus_one)
17220c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        headers.append("Set-Cookie: s2=session;Path=/scripts;"
17230c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                       "Domain=.perlmeister.com")
17240c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        headers.append('Set-Cookie2: s3=session;Version=1;Discard;Path="/"')
17250c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        res = FakeResponse(headers, 'http://www.perlmeister.com/scripts')
17260c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
17270c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        c = CookieJar()
17280c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        c.extract_cookies(res, req)
17290c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # How many session/permanent cookies do we have?
17300c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        counter = {"session_after": 0,
17310c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                   "perm_after": 0,
17320c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                   "session_before": 0,
17330c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                   "perm_before": 0}
17340c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        for cookie in c:
17350c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            key = "%s_before" % cookie.value
17360c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            counter[key] = counter[key] + 1
17370c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        c.clear_session_cookies()
17380c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # How many now?
17390c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        for cookie in c:
17400c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            key = "%s_after" % cookie.value
17410c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            counter[key] = counter[key] + 1
17420c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
17430c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertTrue(not (
17440c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            # a permanent cookie got lost accidentally
17450c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            counter["perm_after"] != counter["perm_before"] or
17460c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            # a session cookie hasn't been cleared
17470c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            counter["session_after"] != 0 or
17480c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            # we didn't have session cookies in the first place
17490c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            counter["session_before"] == 0))
17500c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
17510c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
17520c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yidef test_main(verbose=None):
17530c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    test_support.run_unittest(
17540c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        DateTimeTests,
17550c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        HeaderTests,
17560c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        CookieTests,
17570c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        FileCookieJarTests,
17580c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        LWPCookieTests,
17590c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        )
17600c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
17610c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yiif __name__ == "__main__":
17620c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    test_main(verbose=True)
1763