~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tests/test_http.py

(gz) Fix test failure on alpha by correcting format string for
 gc_chk_sha1_record (Martin [gz])

Show diffs side-by-side

added added

removed removed

Lines of Context:
34
34
    bzrdir,
35
35
    cethread,
36
36
    config,
37
 
    debug,
38
37
    errors,
39
38
    osutils,
40
39
    remote as _mod_remote,
41
40
    tests,
42
 
    trace,
43
41
    transport,
44
42
    ui,
45
43
    )
93
91
        ]
94
92
 
95
93
 
 
94
def vary_by_http_proxy_auth_scheme():
 
95
    return [
 
96
        ('basic', dict(_auth_server=http_utils.ProxyBasicAuthServer)),
 
97
        ('digest', dict(_auth_server=http_utils.ProxyDigestAuthServer)),
 
98
        ('basicdigest',
 
99
            dict(_auth_server=http_utils.ProxyBasicAndDigestAuthServer)),
 
100
        ]
 
101
 
 
102
 
96
103
def vary_by_http_auth_scheme():
97
 
    scenarios = [
 
104
    return [
98
105
        ('basic', dict(_auth_server=http_utils.HTTPBasicAuthServer)),
99
106
        ('digest', dict(_auth_server=http_utils.HTTPDigestAuthServer)),
100
107
        ('basicdigest',
101
108
            dict(_auth_server=http_utils.HTTPBasicAndDigestAuthServer)),
102
109
        ]
103
 
    # Add some attributes common to all scenarios
104
 
    for scenario_id, scenario_dict in scenarios:
105
 
        scenario_dict.update(_auth_header='Authorization',
106
 
                             _username_prompt_prefix='',
107
 
                             _password_prompt_prefix='')
108
 
    return scenarios
109
 
 
110
 
 
111
 
def vary_by_http_proxy_auth_scheme():
112
 
    scenarios = [
113
 
        ('proxy-basic', dict(_auth_server=http_utils.ProxyBasicAuthServer)),
114
 
        ('proxy-digest', dict(_auth_server=http_utils.ProxyDigestAuthServer)),
115
 
        ('proxy-basicdigest',
116
 
            dict(_auth_server=http_utils.ProxyBasicAndDigestAuthServer)),
117
 
        ]
118
 
    # Add some attributes common to all scenarios
119
 
    for scenario_id, scenario_dict in scenarios:
120
 
        scenario_dict.update(_auth_header='Proxy-Authorization',
121
 
                             _username_prompt_prefix='Proxy ',
122
 
                             _password_prompt_prefix='Proxy ')
123
 
    return scenarios
124
110
 
125
111
 
126
112
def vary_by_http_activity():
128
114
        ('urllib,http', dict(_activity_server=ActivityHTTPServer,
129
115
                            _transport=_urllib.HttpTransport_urllib,)),
130
116
        ]
131
 
    if features.HTTPSServerFeature.available():
 
117
    if tests.HTTPSServerFeature.available():
132
118
        activity_scenarios.append(
133
119
            ('urllib,https', dict(_activity_server=ActivityHTTPSServer,
134
120
                                _transport=_urllib.HttpTransport_urllib,)),)
136
122
        activity_scenarios.append(
137
123
            ('pycurl,http', dict(_activity_server=ActivityHTTPServer,
138
124
                                _transport=PyCurlTransport,)),)
139
 
        if features.HTTPSServerFeature.available():
 
125
        if tests.HTTPSServerFeature.available():
140
126
            from bzrlib.tests import (
141
127
                ssl_certs,
142
128
                )
269
255
        self.assertEqual('realm="Thou should not pass"', remainder)
270
256
 
271
257
 
272
 
class TestHTTPRangeParsing(tests.TestCase):
273
 
 
274
 
    def setUp(self):
275
 
        super(TestHTTPRangeParsing, self).setUp()
276
 
        # We focus on range  parsing here and ignore everything else
277
 
        class RequestHandler(http_server.TestingHTTPRequestHandler):
278
 
            def setup(self): pass
279
 
            def handle(self): pass
280
 
            def finish(self): pass
281
 
 
282
 
        self.req_handler = RequestHandler(None, None, None)
283
 
 
284
 
    def assertRanges(self, ranges, header, file_size):
285
 
        self.assertEquals(ranges,
286
 
                          self.req_handler._parse_ranges(header, file_size))
287
 
 
288
 
    def test_simple_range(self):
289
 
        self.assertRanges([(0,2)], 'bytes=0-2', 12)
290
 
 
291
 
    def test_tail(self):
292
 
        self.assertRanges([(8, 11)], 'bytes=-4', 12)
293
 
 
294
 
    def test_tail_bigger_than_file(self):
295
 
        self.assertRanges([(0, 11)], 'bytes=-99', 12)
296
 
 
297
 
    def test_range_without_end(self):
298
 
        self.assertRanges([(4, 11)], 'bytes=4-', 12)
299
 
 
300
 
    def test_invalid_ranges(self):
301
 
        self.assertRanges(None, 'bytes=12-22', 12)
302
 
        self.assertRanges(None, 'bytes=1-3,12-22', 12)
303
 
        self.assertRanges(None, 'bytes=-', 12)
304
 
 
305
 
 
306
258
class TestHTTPServer(tests.TestCase):
307
259
    """Test the HTTP servers implementations."""
308
260
 
476
428
    """Test the http connections."""
477
429
 
478
430
    scenarios = multiply_scenarios(
479
 
        vary_by_http_client_implementation(),
 
431
        vary_by_http_client_implementation(), 
480
432
        vary_by_http_protocol_version(),
481
433
        )
482
434
 
533
485
    scenarios = vary_by_http_client_implementation()
534
486
 
535
487
    def test_http_registered(self):
536
 
        t = transport.get_transport_from_url(
537
 
            '%s://foo.com/' % self._url_protocol)
 
488
        t = transport.get_transport('%s://foo.com/' % self._url_protocol)
538
489
        self.assertIsInstance(t, transport.Transport)
539
490
        self.assertIsInstance(t, self._transport)
540
491
 
542
493
class TestPost(tests.TestCase):
543
494
 
544
495
    scenarios = multiply_scenarios(
545
 
        vary_by_http_client_implementation(),
 
496
        vary_by_http_client_implementation(), 
546
497
        vary_by_http_protocol_version(),
547
498
        )
548
499
 
552
503
        self.start_server(server)
553
504
        url = server.get_url()
554
505
        # FIXME: needs a cleanup -- vila 20100611
555
 
        http_transport = transport.get_transport_from_url(url)
 
506
        http_transport = transport.get_transport(url)
556
507
        code, response = http_transport._post('abc def end-of-body')
557
508
        self.assertTrue(
558
509
            server.received_bytes.startswith('POST /.bzr/smart HTTP/1.'))
601
552
    """
602
553
 
603
554
    scenarios = multiply_scenarios(
604
 
        vary_by_http_client_implementation(),
 
555
        vary_by_http_client_implementation(), 
605
556
        vary_by_http_protocol_version(),
606
557
        )
607
558
 
1049
1000
        self.assertEqual('single', t._range_hint)
1050
1001
 
1051
1002
 
1052
 
class TruncatedBeforeBoundaryRequestHandler(
1053
 
    http_server.TestingHTTPRequestHandler):
1054
 
    """Truncation before a boundary, like in bug 198646"""
1055
 
 
1056
 
    _truncated_ranges = 1
1057
 
 
1058
 
    def get_multiple_ranges(self, file, file_size, ranges):
1059
 
        self.send_response(206)
1060
 
        self.send_header('Accept-Ranges', 'bytes')
1061
 
        boundary = 'tagada'
1062
 
        self.send_header('Content-Type',
1063
 
                         'multipart/byteranges; boundary=%s' % boundary)
1064
 
        boundary_line = '--%s\r\n' % boundary
1065
 
        # Calculate the Content-Length
1066
 
        content_length = 0
1067
 
        for (start, end) in ranges:
1068
 
            content_length += len(boundary_line)
1069
 
            content_length += self._header_line_length(
1070
 
                'Content-type', 'application/octet-stream')
1071
 
            content_length += self._header_line_length(
1072
 
                'Content-Range', 'bytes %d-%d/%d' % (start, end, file_size))
1073
 
            content_length += len('\r\n') # end headers
1074
 
            content_length += end - start # + 1
1075
 
        content_length += len(boundary_line)
1076
 
        self.send_header('Content-length', content_length)
1077
 
        self.end_headers()
1078
 
 
1079
 
        # Send the multipart body
1080
 
        cur = 0
1081
 
        for (start, end) in ranges:
1082
 
            if cur + self._truncated_ranges >= len(ranges):
1083
 
                # Abruptly ends the response and close the connection
1084
 
                self.close_connection = 1
1085
 
                return
1086
 
            self.wfile.write(boundary_line)
1087
 
            self.send_header('Content-type', 'application/octet-stream')
1088
 
            self.send_header('Content-Range', 'bytes %d-%d/%d'
1089
 
                             % (start, end, file_size))
1090
 
            self.end_headers()
1091
 
            self.send_range_content(file, start, end - start + 1)
1092
 
            cur += 1
1093
 
        # Final boundary
1094
 
        self.wfile.write(boundary_line)
1095
 
 
1096
 
 
1097
 
class TestTruncatedBeforeBoundary(TestSpecificRequestHandler):
1098
 
    """Tests the case of bug 198646, disconnecting before a boundary."""
1099
 
 
1100
 
    _req_handler_class = TruncatedBeforeBoundaryRequestHandler
1101
 
 
1102
 
    def setUp(self):
1103
 
        super(TestTruncatedBeforeBoundary, self).setUp()
1104
 
        self.build_tree_contents([('a', '0123456789')],)
1105
 
 
1106
 
    def test_readv_with_short_reads(self):
1107
 
        server = self.get_readonly_server()
1108
 
        t = self.get_readonly_transport()
1109
 
        # Force separate ranges for each offset
1110
 
        t._bytes_to_read_before_seek = 0
1111
 
        ireadv = iter(t.readv('a', ((0, 1), (2, 1), (4, 2), (9, 1))))
1112
 
        self.assertEqual((0, '0'), ireadv.next())
1113
 
        self.assertEqual((2, '2'), ireadv.next())
1114
 
        self.assertEqual((4, '45'), ireadv.next())
1115
 
        self.assertEqual((9, '9'), ireadv.next())
1116
 
 
1117
 
 
1118
1003
class LimitedRangeRequestHandler(http_server.TestingHTTPRequestHandler):
1119
1004
    """Errors out when range specifiers exceed the limit"""
1120
1005
 
1145
1030
    """Tests readv requests against a server erroring out on too much ranges."""
1146
1031
 
1147
1032
    scenarios = multiply_scenarios(
1148
 
        vary_by_http_client_implementation(),
 
1033
        vary_by_http_client_implementation(), 
1149
1034
        vary_by_http_protocol_version(),
1150
1035
        )
1151
1036
 
1191
1076
 
1192
1077
    def _proxied_request(self):
1193
1078
        handler = _urllib2_wrappers.ProxyHandler()
1194
 
        request = _urllib2_wrappers.Request('GET', 'http://baz/buzzle')
 
1079
        request = _urllib2_wrappers.Request('GET','http://baz/buzzle')
1195
1080
        handler.set_proxy(request, 'http')
1196
1081
        return request
1197
1082
 
1205
1090
        request = self._proxied_request()
1206
1091
        self.assertFalse(request.headers.has_key('Proxy-authorization'))
1207
1092
 
1208
 
    def test_user_with_at(self):
1209
 
        self.overrideEnv('http_proxy',
1210
 
                         'http://username@domain:password@proxy_host:1234')
1211
 
        request = self._proxied_request()
1212
 
        self.assertFalse(request.headers.has_key('Proxy-authorization'))
1213
 
 
1214
1093
    def test_invalid_proxy(self):
1215
1094
        """A proxy env variable without scheme"""
1216
1095
        self.overrideEnv('http_proxy', 'host:1234')
1247
1126
    """
1248
1127
 
1249
1128
    scenarios = multiply_scenarios(
1250
 
        vary_by_http_client_implementation(),
 
1129
        vary_by_http_client_implementation(), 
1251
1130
        vary_by_http_protocol_version(),
1252
1131
        )
1253
1132
 
1344
1223
    """Test the Range header in GET methods."""
1345
1224
 
1346
1225
    scenarios = multiply_scenarios(
1347
 
        vary_by_http_client_implementation(),
 
1226
        vary_by_http_client_implementation(), 
1348
1227
        vary_by_http_protocol_version(),
1349
1228
        )
1350
1229
 
1394
1273
    """Test redirection between http servers."""
1395
1274
 
1396
1275
    scenarios = multiply_scenarios(
1397
 
        vary_by_http_client_implementation(),
 
1276
        vary_by_http_client_implementation(), 
1398
1277
        vary_by_http_protocol_version(),
1399
1278
        )
1400
1279
 
1467
1346
    """
1468
1347
 
1469
1348
    scenarios = multiply_scenarios(
1470
 
        vary_by_http_client_implementation(),
 
1349
        vary_by_http_client_implementation(), 
1471
1350
        vary_by_http_protocol_version(),
1472
1351
        )
1473
1352
 
1522
1401
    """Test transport.do_catching_redirections."""
1523
1402
 
1524
1403
    scenarios = multiply_scenarios(
1525
 
        vary_by_http_client_implementation(),
 
1404
        vary_by_http_client_implementation(), 
1526
1405
        vary_by_http_protocol_version(),
1527
1406
        )
1528
1407
 
1570
1449
                          self.get_a, self.old_transport, redirected)
1571
1450
 
1572
1451
 
1573
 
def _setup_authentication_config(**kwargs):
1574
 
    conf = config.AuthenticationConfig()
1575
 
    conf._get_config().update({'httptest': kwargs})
1576
 
    conf._save()
1577
 
 
1578
 
 
1579
 
class TestUrllib2AuthHandler(tests.TestCaseWithTransport):
1580
 
    """Unit tests for glue by which urllib2 asks us for authentication"""
1581
 
 
1582
 
    def test_get_user_password_without_port(self):
1583
 
        """We cope if urllib2 doesn't tell us the port.
1584
 
 
1585
 
        See https://bugs.launchpad.net/bzr/+bug/654684
1586
 
        """
1587
 
        user = 'joe'
1588
 
        password = 'foo'
1589
 
        _setup_authentication_config(scheme='http', host='localhost',
1590
 
                                     user=user, password=password)
1591
 
        handler = _urllib2_wrappers.HTTPAuthHandler()
1592
 
        got_pass = handler.get_user_password(dict(
1593
 
            user='joe',
1594
 
            protocol='http',
1595
 
            host='localhost',
1596
 
            path='/',
1597
 
            realm='Realm',
1598
 
            ))
1599
 
        self.assertEquals((user, password), got_pass)
1600
 
 
1601
 
 
1602
1452
class TestAuth(http_utils.TestCaseWithWebserver):
1603
1453
    """Test authentication scheme"""
1604
1454
 
1608
1458
        vary_by_http_auth_scheme(),
1609
1459
        )
1610
1460
 
 
1461
    _auth_header = 'Authorization'
 
1462
    _password_prompt_prefix = ''
 
1463
    _username_prompt_prefix = ''
 
1464
    # Set by load_tests
 
1465
    _auth_server = None
 
1466
 
1611
1467
    def setUp(self):
1612
1468
        super(TestAuth, self).setUp()
1613
1469
        self.server = self.get_readonly_server()
1636
1492
        return url
1637
1493
 
1638
1494
    def get_user_transport(self, user, password):
1639
 
        t = transport.get_transport_from_url(
1640
 
            self.get_user_url(user, password))
 
1495
        t = transport.get_transport(self.get_user_url(user, password))
1641
1496
        return t
1642
1497
 
1643
1498
    def test_no_user(self):
1755
1610
        ui.ui_factory = tests.TestUIFactory(stdin=stdin_content,
1756
1611
                                            stderr=tests.StringIOWrapper())
1757
1612
        # Create a minimal config file with the right password
1758
 
        _setup_authentication_config(scheme='http', port=self.server.port,
1759
 
                                     user=user, password=password)
 
1613
        _setup_authentication_config(
 
1614
            scheme='http', 
 
1615
            port=self.server.port,
 
1616
            user=user,
 
1617
            password=password)
1760
1618
        # Issue a request to the server to connect
1761
1619
        self.assertEqual('contents of a\n',t.get('a').read())
1762
1620
        # stdin should have  been left untouched
1769
1627
                                     http_utils.ProxyDigestAuthServer):
1770
1628
            raise tests.TestNotApplicable('HTTP/proxy auth digest only test')
1771
1629
        if self._testing_pycurl():
1772
 
            self.knownFailure(
 
1630
            raise tests.KnownFailure(
1773
1631
                'pycurl does not handle a nonce change')
1774
1632
        self.server.add_user('joe', 'foo')
1775
1633
        t = self.get_user_transport('joe', 'foo')
1792
1650
        user = 'joe'
1793
1651
        password = 'foo'
1794
1652
        self.server.add_user(user, password)
1795
 
        _setup_authentication_config(scheme='http', port=self.server.port,
1796
 
                                     user=user, password=password)
 
1653
        _setup_authentication_config(
 
1654
            scheme='http', 
 
1655
            port=self.server.port,
 
1656
            user=user,
 
1657
            password=password)
1797
1658
        t = self.get_user_transport(None, None)
1798
1659
        # Issue a request to the server to connect
1799
1660
        self.assertEqual('contents of a\n', t.get('a').read())
1800
1661
        # Only one 'Authentication Required' error should occur
1801
1662
        self.assertEqual(1, self.server.auth_required_errors)
1802
1663
 
1803
 
    def test_no_credential_leaks_in_log(self):
1804
 
        self.overrideAttr(debug, 'debug_flags', set(['http']))
 
1664
 
 
1665
def _setup_authentication_config(**kwargs):
 
1666
    conf = config.AuthenticationConfig()
 
1667
    conf._get_config().update({'httptest': kwargs})
 
1668
    conf._save()
 
1669
 
 
1670
 
 
1671
 
 
1672
class TestUrllib2AuthHandler(tests.TestCaseWithTransport):
 
1673
    """Unit tests for glue by which urllib2 asks us for authentication"""
 
1674
 
 
1675
    def test_get_user_password_without_port(self):
 
1676
        """We cope if urllib2 doesn't tell us the port.
 
1677
 
 
1678
        See https://bugs.launchpad.net/bzr/+bug/654684
 
1679
        """
1805
1680
        user = 'joe'
1806
 
        password = 'very-sensitive-password'
1807
 
        self.server.add_user(user, password)
1808
 
        t = self.get_user_transport(user, password)
1809
 
        # Capture the debug calls to mutter
1810
 
        self.mutters = []
1811
 
        def mutter(*args):
1812
 
            lines = args[0] % args[1:]
1813
 
            # Some calls output multiple lines, just split them now since we
1814
 
            # care about a single one later.
1815
 
            self.mutters.extend(lines.splitlines())
1816
 
        self.overrideAttr(trace, 'mutter', mutter)
1817
 
        # Issue a request to the server to connect
1818
 
        self.assertEqual(True, t.has('a'))
1819
 
        # Only one 'Authentication Required' error should occur
1820
 
        self.assertEqual(1, self.server.auth_required_errors)
1821
 
        # Since the authentification succeeded, there should be a corresponding
1822
 
        # debug line
1823
 
        sent_auth_headers = [line for line in self.mutters
1824
 
                             if line.startswith('> %s' % (self._auth_header,))]
1825
 
        self.assertLength(1, sent_auth_headers)
1826
 
        self.assertStartsWith(sent_auth_headers[0],
1827
 
                              '> %s: <masked>' % (self._auth_header,))
 
1681
        password = 'foo'
 
1682
        _setup_authentication_config(
 
1683
            scheme='http', 
 
1684
            host='localhost',
 
1685
            user=user,
 
1686
            password=password)
 
1687
        handler = _urllib2_wrappers.HTTPAuthHandler()
 
1688
        got_pass = handler.get_user_password(dict(
 
1689
            user='joe',
 
1690
            protocol='http',
 
1691
            host='localhost',
 
1692
            path='/',
 
1693
            realm='Realm',
 
1694
            ))
 
1695
        self.assertEquals((user, password), got_pass)
1828
1696
 
1829
1697
 
1830
1698
class TestProxyAuth(TestAuth):
1831
 
    """Test proxy authentication schemes.
1832
 
 
1833
 
    This inherits from TestAuth to tweak the setUp and filter some failing
1834
 
    tests.
1835
 
    """
 
1699
    """Test proxy authentication schemes."""
1836
1700
 
1837
1701
    scenarios = multiply_scenarios(
1838
1702
        vary_by_http_client_implementation(),
1840
1704
        vary_by_http_proxy_auth_scheme(),
1841
1705
        )
1842
1706
 
 
1707
    _auth_header = 'Proxy-authorization'
 
1708
    _password_prompt_prefix = 'Proxy '
 
1709
    _username_prompt_prefix = 'Proxy '
 
1710
 
1843
1711
    def setUp(self):
1844
1712
        super(TestProxyAuth, self).setUp()
1845
1713
        # Override the contents to avoid false positives
1857
1725
        if self._testing_pycurl():
1858
1726
            import pycurl
1859
1727
            if pycurl.version_info()[1] < '7.16.0':
1860
 
                self.knownFailure(
 
1728
                raise tests.KnownFailure(
1861
1729
                    'pycurl < 7.16.0 does not handle empty proxy passwords')
1862
1730
        super(TestProxyAuth, self).test_empty_pass()
1863
1731
 
1888
1756
class SmartHTTPTunnellingTest(tests.TestCaseWithTransport):
1889
1757
 
1890
1758
    scenarios = multiply_scenarios(
1891
 
        vary_by_http_client_implementation(),
 
1759
        vary_by_http_client_implementation(), 
1892
1760
        vary_by_http_protocol_version(),
1893
1761
        )
1894
1762
 
1917
1785
        # The 'readv' command in the smart protocol both sends and receives
1918
1786
        # bulk data, so we use that.
1919
1787
        self.build_tree(['data-file'])
1920
 
        http_transport = transport.get_transport_from_url(
1921
 
            self.http_server.get_url())
 
1788
        http_transport = transport.get_transport(self.http_server.get_url())
1922
1789
        medium = http_transport.get_smart_medium()
1923
1790
        # Since we provide the medium, the url below will be mostly ignored
1924
1791
        # during the test, as long as the path is '/'.
1932
1799
        post_body = 'hello\n'
1933
1800
        expected_reply_body = 'ok\x012\n'
1934
1801
 
1935
 
        http_transport = transport.get_transport_from_url(
1936
 
            self.http_server.get_url())
 
1802
        http_transport = transport.get_transport(self.http_server.get_url())
1937
1803
        medium = http_transport.get_smart_medium()
1938
1804
        response = medium.send_http_smart_request(post_body)
1939
1805
        reply_body = response.read()
1997
1863
        self.assertIsInstance(r, type(t))
1998
1864
        # Both transports share the some connection
1999
1865
        self.assertEqual(t._get_connection(), r._get_connection())
2000
 
        self.assertEquals('http://www.example.com/foo/subdir/', r.base)
2001
1866
 
2002
1867
    def test_redirected_to_self_with_slash(self):
2003
1868
        t = self._transport('http://www.example.com/foo')
2014
1879
        r = t._redirected_to('http://www.example.com/foo',
2015
1880
                             'http://foo.example.com/foo/subdir')
2016
1881
        self.assertIsInstance(r, type(t))
2017
 
        self.assertEquals('http://foo.example.com/foo/subdir/',
2018
 
            r.external_url())
2019
1882
 
2020
1883
    def test_redirected_to_same_host_sibling_protocol(self):
2021
1884
        t = self._transport('http://www.example.com/foo')
2022
1885
        r = t._redirected_to('http://www.example.com/foo',
2023
1886
                             'https://www.example.com/foo')
2024
1887
        self.assertIsInstance(r, type(t))
2025
 
        self.assertEquals('https://www.example.com/foo/',
2026
 
            r.external_url())
2027
1888
 
2028
1889
    def test_redirected_to_same_host_different_protocol(self):
2029
1890
        t = self._transport('http://www.example.com/foo')
2030
1891
        r = t._redirected_to('http://www.example.com/foo',
2031
1892
                             'ftp://www.example.com/foo')
2032
1893
        self.assertNotEquals(type(r), type(t))
2033
 
        self.assertEquals('ftp://www.example.com/foo/', r.external_url())
2034
 
 
2035
 
    def test_redirected_to_same_host_specific_implementation(self):
2036
 
        t = self._transport('http://www.example.com/foo')
2037
 
        r = t._redirected_to('http://www.example.com/foo',
2038
 
                             'https+urllib://www.example.com/foo')
2039
 
        self.assertEquals('https://www.example.com/foo/', r.external_url())
2040
1894
 
2041
1895
    def test_redirected_to_different_host_same_user(self):
2042
1896
        t = self._transport('http://joe@www.example.com/foo')
2043
1897
        r = t._redirected_to('http://www.example.com/foo',
2044
1898
                             'https://foo.example.com/foo')
2045
1899
        self.assertIsInstance(r, type(t))
2046
 
        self.assertEqual(t._parsed_url.user, r._parsed_url.user)
2047
 
        self.assertEquals('https://joe@foo.example.com/foo/', r.external_url())
 
1900
        self.assertEqual(t._user, r._user)
2048
1901
 
2049
1902
 
2050
1903
class PredefinedRequestHandler(http_server.TestingHTTPRequestHandler):
2103
1956
    pass
2104
1957
 
2105
1958
 
2106
 
if features.HTTPSServerFeature.available():
 
1959
if tests.HTTPSServerFeature.available():
2107
1960
    from bzrlib.tests import https_server
2108
1961
    class ActivityHTTPSServer(ActivityServerMixin, https_server.HTTPSServer):
2109
1962
        pass
2120
1973
        tests.TestCase.setUp(self)
2121
1974
        self.server = self._activity_server(self._protocol_version)
2122
1975
        self.server.start_server()
2123
 
        _activities = {} # Don't close over self and create a cycle
 
1976
        self.activities = {}
2124
1977
        def report_activity(t, bytes, direction):
2125
 
            count = _activities.get(direction, 0)
 
1978
            count = self.activities.get(direction, 0)
2126
1979
            count += bytes
2127
 
            _activities[direction] = count
2128
 
        self.activities = _activities
 
1980
            self.activities[direction] = count
2129
1981
 
2130
1982
        # We override at class level because constructors may propagate the
2131
1983
        # bound method and render instance overriding ineffective (an
2356
2208
        # stdout should be empty, stderr will contains the prompts
2357
2209
        self.assertEqual('', stdout.getvalue())
2358
2210
 
 
2211