Repository URL to install this package:
"""Tests for http/cookiejar.py."""
import os
import re
import test.support
import time
import unittest
import urllib.request
import pathlib
from http.cookiejar import (time2isoz, http2time, iso2time, time2netscape,
parse_ns_headers, join_header_words, split_header_words, Cookie,
CookieJar, DefaultCookiePolicy, LWPCookieJar, MozillaCookieJar,
LoadError, lwp_cookie_str, DEFAULT_HTTP_PORT, escape_path,
reach, is_HDN, domain_match, user_domain_match, request_path,
request_port, request_host)
class DateTimeTests(unittest.TestCase):
def test_time2isoz(self):
base = 1019227000
day = 24*3600
self.assertEqual(time2isoz(base), "2002-04-19 14:36:40Z")
self.assertEqual(time2isoz(base+day), "2002-04-20 14:36:40Z")
self.assertEqual(time2isoz(base+2*day), "2002-04-21 14:36:40Z")
self.assertEqual(time2isoz(base+3*day), "2002-04-22 14:36:40Z")
az = time2isoz()
bz = time2isoz(500000)
for text in (az, bz):
self.assertRegex(text, r"^\d{4}-\d\d-\d\d \d\d:\d\d:\d\dZ$",
"bad time2isoz format: %s %s" % (az, bz))
def test_time2netscape(self):
base = 1019227000
day = 24*3600
self.assertEqual(time2netscape(base), "Fri, 19-Apr-2002 14:36:40 GMT")
self.assertEqual(time2netscape(base+day),
"Sat, 20-Apr-2002 14:36:40 GMT")
self.assertEqual(time2netscape(base+2*day),
"Sun, 21-Apr-2002 14:36:40 GMT")
self.assertEqual(time2netscape(base+3*day),
"Mon, 22-Apr-2002 14:36:40 GMT")
az = time2netscape()
bz = time2netscape(500000)
for text in (az, bz):
# Format "%s, %02d-%s-%04d %02d:%02d:%02d GMT"
self.assertRegex(
text,
r"[a-zA-Z]{3}, \d{2}-[a-zA-Z]{3}-\d{4} \d{2}:\d{2}:\d{2} GMT$",
"bad time2netscape format: %s %s" % (az, bz))
def test_http2time(self):
def parse_date(text):
return time.gmtime(http2time(text))[:6]
self.assertEqual(parse_date("01 Jan 2001"), (2001, 1, 1, 0, 0, 0.0))
# this test will break around year 2070
self.assertEqual(parse_date("03-Feb-20"), (2020, 2, 3, 0, 0, 0.0))
# this test will break around year 2048
self.assertEqual(parse_date("03-Feb-98"), (1998, 2, 3, 0, 0, 0.0))
def test_http2time_formats(self):
# test http2time for supported dates. Test cases with 2 digit year
# will probably break in year 2044.
tests = [
'Thu, 03 Feb 1994 00:00:00 GMT', # proposed new HTTP format
'Thursday, 03-Feb-94 00:00:00 GMT', # old rfc850 HTTP format
'Thursday, 03-Feb-1994 00:00:00 GMT', # broken rfc850 HTTP format
'03 Feb 1994 00:00:00 GMT', # HTTP format (no weekday)
'03-Feb-94 00:00:00 GMT', # old rfc850 (no weekday)
'03-Feb-1994 00:00:00 GMT', # broken rfc850 (no weekday)
'03-Feb-1994 00:00 GMT', # broken rfc850 (no weekday, no seconds)
'03-Feb-1994 00:00', # broken rfc850 (no weekday, no seconds, no tz)
'02-Feb-1994 24:00', # broken rfc850 (no weekday, no seconds,
# no tz) using hour 24 with yesterday date
'03-Feb-94', # old rfc850 HTTP format (no weekday, no time)
'03-Feb-1994', # broken rfc850 HTTP format (no weekday, no time)
'03 Feb 1994', # proposed new HTTP format (no weekday, no time)
# A few tests with extra space at various places
' 03 Feb 1994 0:00 ',
' 03-Feb-1994 ',
]
test_t = 760233600 # assume broken POSIX counting of seconds
result = time2isoz(test_t)
expected = "1994-02-03 00:00:00Z"
self.assertEqual(result, expected,
"%s => '%s' (%s)" % (test_t, result, expected))
for s in tests:
self.assertEqual(http2time(s), test_t, s)
self.assertEqual(http2time(s.lower()), test_t, s.lower())
self.assertEqual(http2time(s.upper()), test_t, s.upper())
def test_http2time_garbage(self):
for test in [
'',
'Garbage',
'Mandag 16. September 1996',
'01-00-1980',
'01-13-1980',
'00-01-1980',
'32-01-1980',
'01-01-1980 25:00:00',
'01-01-1980 00:61:00',
'01-01-1980 00:00:62',
'08-Oct-3697739',
'08-01-3697739',
'09 Feb 19942632 22:23:32 GMT',
'Wed, 09 Feb 1994834 22:23:32 GMT',
]:
self.assertIsNone(http2time(test),
"http2time(%s) is not None\n"
"http2time(test) %s" % (test, http2time(test)))
def test_http2time_redos_regression_actually_completes(self):
# LOOSE_HTTP_DATE_RE was vulnerable to malicious input which caused catastrophic backtracking (REDoS).
# If we regress to cubic complexity, this test will take a very long time to succeed.
# If fixed, it should complete within a fraction of a second.
http2time("01 Jan 1970{}00:00:00 GMT!".format(" " * 10 ** 5))
http2time("01 Jan 1970 00:00:00{}GMT!".format(" " * 10 ** 5))
def test_iso2time(self):
def parse_date(text):
return time.gmtime(iso2time(text))[:6]
# ISO 8601 compact format
self.assertEqual(parse_date("19940203T141529Z"),
(1994, 2, 3, 14, 15, 29))
# ISO 8601 with time behind UTC
self.assertEqual(parse_date("1994-02-03 07:15:29 -0700"),
(1994, 2, 3, 14, 15, 29))
# ISO 8601 with time ahead of UTC
self.assertEqual(parse_date("1994-02-03 19:45:29 +0530"),
(1994, 2, 3, 14, 15, 29))
def test_iso2time_formats(self):
# test iso2time for supported dates.
tests = [
'1994-02-03 00:00:00 -0000', # ISO 8601 format
'1994-02-03 00:00:00 +0000', # ISO 8601 format
'1994-02-03 00:00:00', # zone is optional
'1994-02-03', # only date
'1994-02-03T00:00:00', # Use T as separator
'19940203', # only date
'1994-02-02 24:00:00', # using hour-24 yesterday date
'19940203T000000Z', # ISO 8601 compact format
# A few tests with extra space at various places
' 1994-02-03 ',
' 1994-02-03T00:00:00 ',
]
test_t = 760233600 # assume broken POSIX counting of seconds
for s in tests:
self.assertEqual(iso2time(s), test_t, s)
self.assertEqual(iso2time(s.lower()), test_t, s.lower())
self.assertEqual(iso2time(s.upper()), test_t, s.upper())
def test_iso2time_garbage(self):
for test in [
'',
'Garbage',
'Thursday, 03-Feb-94 00:00:00 GMT',
'1980-00-01',
'1980-13-01',
'1980-01-00',
'1980-01-32',
'1980-01-01 25:00:00',
'1980-01-01 00:61:00',
'01-01-1980 00:00:62',
'01-01-1980T00:00:62',
'19800101T250000Z',
]:
self.assertIsNone(iso2time(test),
"iso2time(%r)" % test)
def test_iso2time_performance_regression(self):
# If ISO_DATE_RE regresses to quadratic complexity, this test will take a very long time to succeed.
# If fixed, it should complete within a fraction of a second.
iso2time('1994-02-03{}14:15:29 -0100!'.format(' '*10**6))
iso2time('1994-02-03 14:15:29{}-0100!'.format(' '*10**6))
class HeaderTests(unittest.TestCase):
def test_parse_ns_headers(self):
# quotes should be stripped
expected = [[('foo', 'bar'), ('expires', 2209069412), ('version', '0')]]
for hdr in [
'foo=bar; expires=01 Jan 2040 22:23:32 GMT',
'foo=bar; expires="01 Jan 2040 22:23:32 GMT"',
]:
self.assertEqual(parse_ns_headers([hdr]), expected)
def test_parse_ns_headers_version(self):
# quotes should be stripped
expected = [[('foo', 'bar'), ('version', '1')]]
for hdr in [
'foo=bar; version="1"',
'foo=bar; Version="1"',
]:
self.assertEqual(parse_ns_headers([hdr]), expected)
def test_parse_ns_headers_special_names(self):
# names such as 'expires' are not special in first name=value pair
# of Set-Cookie: header
# Cookie with name 'expires'
hdr = 'expires=01 Jan 2040 22:23:32 GMT'
expected = [[("expires", "01 Jan 2040 22:23:32 GMT"), ("version", "0")]]
self.assertEqual(parse_ns_headers([hdr]), expected)
def test_join_header_words(self):
joined = join_header_words([[("foo", None), ("bar", "baz")]])
self.assertEqual(joined, "foo; bar=baz")
self.assertEqual(join_header_words([[]]), "")
def test_split_header_words(self):
tests = [
("foo", [[("foo", None)]]),
("foo=bar", [[("foo", "bar")]]),
(" foo ", [[("foo", None)]]),
(" foo= ", [[("foo", "")]]),
(" foo=", [[("foo", "")]]),
(" foo= ; ", [[("foo", "")]]),
(" foo= ; bar= baz ", [[("foo", ""), ("bar", "baz")]]),
("foo=bar bar=baz", [[("foo", "bar"), ("bar", "baz")]]),
# doesn't really matter if this next fails, but it works ATM
("foo= bar=baz", [[("foo", "bar=baz")]]),
("foo=bar;bar=baz", [[("foo", "bar"), ("bar", "baz")]]),
('foo bar baz', [[("foo", None), ("bar", None), ("baz", None)]]),
("a, b, c", [[("a", None)], [("b", None)], [("c", None)]]),
(r'foo; bar=baz, spam=, foo="\,\;\"", bar= ',
[[("foo", None), ("bar", "baz")],
[("spam", "")], [("foo", ',;"')], [("bar", "")]]),
]
for arg, expect in tests:
try:
result = split_header_words([arg])
except:
import traceback, io
f = io.StringIO()
traceback.print_exc(None, f)
result = "(error -- traceback follows)\n\n%s" % f.getvalue()
self.assertEqual(result, expect, """
When parsing: '%s'
Expected: '%s'
Got: '%s'
""" % (arg, expect, result))
def test_roundtrip(self):
tests = [
("foo", "foo"),
("foo=bar", "foo=bar"),
(" foo ", "foo"),
("foo=", 'foo=""'),
("foo=bar bar=baz", "foo=bar; bar=baz"),
("foo=bar;bar=baz", "foo=bar; bar=baz"),
('foo bar baz', "foo; bar; baz"),
(r'foo="\"" bar="\\"', r'foo="\""; bar="\\"'),
('foo,,,bar', 'foo, bar'),
('foo=bar,bar=baz', 'foo=bar, bar=baz'),
('text/html; charset=iso-8859-1',
'text/html; charset="iso-8859-1"'),
('foo="bar"; port="80,81"; discard, bar=baz',
'foo=bar; port="80,81"; discard, bar=baz'),
(r'Basic realm="\"foo\\\\bar\""',
r'Basic; realm="\"foo\\\\bar\""')
]
for arg, expect in tests:
input = split_header_words([arg])
res = join_header_words(input)
self.assertEqual(res, expect, """
When parsing: '%s'
Expected: '%s'
Got: '%s'
Input was: '%s'
""" % (arg, expect, res, input))
class FakeResponse:
def __init__(self, headers=[], url=None):
"""
headers: list of RFC822-style 'Key: value' strings
"""
import email
self._headers = email.message_from_string("\n".join(headers))
self._url = url
def info(self): return self._headers
def interact_2965(cookiejar, url, *set_cookie_hdrs):
return _interact(cookiejar, url, set_cookie_hdrs, "Set-Cookie2")
def interact_netscape(cookiejar, url, *set_cookie_hdrs):
return _interact(cookiejar, url, set_cookie_hdrs, "Set-Cookie")
def _interact(cookiejar, url, set_cookie_hdrs, hdr_name):
"""Perform a single request / response cycle, returning Cookie: header."""
req = urllib.request.Request(url)
cookiejar.add_cookie_header(req)
cookie_hdr = req.get_header("Cookie", "")
headers = []
for hdr in set_cookie_hdrs:
headers.append("%s: %s" % (hdr_name, hdr))
res = FakeResponse(headers, url)
cookiejar.extract_cookies(res, req)
return cookie_hdr
class FileCookieJarTests(unittest.TestCase):
def test_constructor_with_str(self):
filename = test.support.TESTFN
c = LWPCookieJar(filename)
self.assertEqual(c.filename, filename)
def test_constructor_with_path_like(self):
filename = pathlib.Path(test.support.TESTFN)
c = LWPCookieJar(filename)
self.assertEqual(c.filename, os.fspath(filename))
def test_constructor_with_none(self):
c = LWPCookieJar(None)
self.assertIsNone(c.filename)
def test_constructor_with_other_types(self):
class A:
Loading ...