/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar

« back to all changes in this revision

Viewing changes to breezy/tests/test_http.py

  • Committer: Jelmer Vernooij
  • Date: 2018-08-01 19:37:07 UTC
  • mto: This revision was merged to the branch mainline in revision 7058.
  • Revision ID: jelmer@jelmer.uk-20180801193707-dyecqwo0y2z4cpk9
Fix a few more tests.

Show diffs side-by-side

added added

removed removed

Lines of Context:
24
24
# TODO: What about renaming to breezy.tests.transport.http ?
25
25
 
26
26
try:
27
 
    from http.client import UnknownProtocol
 
27
    from http.client import UnknownProtocol, parse_headers
28
28
    from http.server import SimpleHTTPRequestHandler
29
29
except ImportError:  # python < 3
30
30
    from httplib import UnknownProtocol
50
50
from ..bzr import (
51
51
    remote as _mod_remote,
52
52
    )
 
53
from ..sixish import PY3
53
54
from . import (
54
55
    features,
55
56
    http_server,
172
173
        self._expect_body_tail = expect_body_tail
173
174
        self.host = None
174
175
        self.port = None
175
 
        self.received_bytes = ''
 
176
        self.received_bytes = b''
176
177
        self.scheme = scheme
177
178
 
178
179
    def get_url(self):
197
198
        if self._expect_body_tail is not None:
198
199
            while not self.received_bytes.endswith(self._expect_body_tail):
199
200
                self.received_bytes += conn.recv(4096)
200
 
            conn.sendall('HTTP/1.1 200 OK\r\n')
 
201
            conn.sendall(b'HTTP/1.1 200 OK\r\n')
201
202
        try:
202
203
            self._sock.close()
203
204
        except socket.error:
260
261
            _urllib2_wrappers.BasicAuthHandler)
261
262
        match, realm = self.auth_handler.extract_realm(remainder)
262
263
        self.assertTrue(match is not None)
263
 
        self.assertEqual('Thou should not pass', realm)
 
264
        self.assertEqual(u'Thou should not pass', realm)
264
265
 
265
266
    def test_digest_header(self):
266
267
        scheme, remainder = self.parse_header(
483
484
        )
484
485
 
485
486
    def test_post_body_is_received(self):
486
 
        server = RecordingServer(expect_body_tail='end-of-body',
 
487
        server = RecordingServer(expect_body_tail=b'end-of-body',
487
488
                                 scheme=self._url_protocol)
488
489
        self.start_server(server)
489
490
        url = server.get_url()
490
491
        # FIXME: needs a cleanup -- vila 20100611
491
492
        http_transport = transport.get_transport_from_url(url)
492
 
        code, response = http_transport._post('abc def end-of-body')
 
493
        code, response = http_transport._post(b'abc def end-of-body')
493
494
        self.assertTrue(
494
 
            server.received_bytes.startswith('POST /.bzr/smart HTTP/1.'))
495
 
        self.assertTrue('content-length: 19\r' in server.received_bytes.lower())
496
 
        self.assertTrue('content-type: application/octet-stream\r'
 
495
            server.received_bytes.startswith(b'POST /.bzr/smart HTTP/1.'))
 
496
        self.assertTrue(b'content-length: 19\r' in server.received_bytes.lower())
 
497
        self.assertTrue(b'content-type: application/octet-stream\r'
497
498
                        in server.received_bytes.lower())
498
499
        # The transport should not be assuming that the server can accept
499
500
        # chunked encoding the first time it connects, because HTTP/1.1, so we
500
501
        # check for the literal string.
501
502
        self.assertTrue(
502
 
            server.received_bytes.endswith('\r\n\r\nabc def end-of-body'))
 
503
            server.received_bytes.endswith(b'\r\n\r\nabc def end-of-body'))
503
504
 
504
505
 
505
506
class TestRangeHeader(tests.TestCase):
628
629
    def parse_request(self):
629
630
        """Fakes handling a single HTTP request, returns a bad status"""
630
631
        ignored = http_server.TestingHTTPRequestHandler.parse_request(self)
631
 
        self.wfile.write("Invalid status line\r\n")
 
632
        self.wfile.write(b"Invalid status line\r\n")
632
633
        # If we don't close the connection pycurl will hang. Since this is a
633
634
        # stress test we don't *have* to respect the protocol, but we don't
634
635
        # have to sabotage it too much either.
653
654
        ignored = http_server.TestingHTTPRequestHandler.parse_request(self)
654
655
        # Returns an invalid protocol version, but curl just
655
656
        # ignores it and those cannot be tested.
656
 
        self.wfile.write("%s %d %s\r\n" % ('HTTP/0.0',
657
 
                                           404,
658
 
                                           'Look at my protocol version'))
 
657
        self.wfile.write(b"%s %d %s\r\n" % (
 
658
            b'HTTP/0.0', 404, b'Look at my protocol version'))
659
659
        return False
660
660
 
661
661
 
701
701
 
702
702
    def test_create(self):
703
703
        server = RecordingServer(expect_body_tail=None)
704
 
        self.assertEqual('', server.received_bytes)
 
704
        self.assertEqual(b'', server.received_bytes)
705
705
        self.assertEqual(None, server.host)
706
706
        self.assertEqual(None, server.port)
707
707
 
717
717
        self.assertEqual(None, server.port)
718
718
 
719
719
    def test_send_receive_bytes(self):
720
 
        server = RecordingServer(expect_body_tail='c', scheme='http')
 
720
        server = RecordingServer(expect_body_tail=b'c', scheme='http')
721
721
        self.start_server(server)
722
722
        sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
723
723
        sock.connect((server.host, server.port))
724
 
        sock.sendall('abc')
725
 
        self.assertEqual('HTTP/1.1 200 OK\r\n',
 
724
        sock.sendall(b'abc')
 
725
        self.assertEqual(b'HTTP/1.1 200 OK\r\n',
726
726
                         osutils.recv_all(sock, 4096))
727
 
        self.assertEqual('abc', server.received_bytes)
 
727
        self.assertEqual(b'abc', server.received_bytes)
728
728
 
729
729
 
730
730
class TestRangeRequestServer(TestSpecificRequestHandler):
740
740
    def test_readv(self):
741
741
        t = self.get_readonly_transport()
742
742
        l = list(t.readv('a', ((0, 1), (1, 1), (3, 2), (9, 1))))
743
 
        self.assertEqual(l[0], (0, '0'))
744
 
        self.assertEqual(l[1], (1, '1'))
745
 
        self.assertEqual(l[2], (3, '34'))
746
 
        self.assertEqual(l[3], (9, '9'))
 
743
        self.assertEqual(l[0], (0, b'0'))
 
744
        self.assertEqual(l[1], (1, b'1'))
 
745
        self.assertEqual(l[2], (3, b'34'))
 
746
        self.assertEqual(l[3], (9, b'9'))
747
747
 
748
748
    def test_readv_out_of_order(self):
749
749
        t = self.get_readonly_transport()
750
750
        l = list(t.readv('a', ((1, 1), (9, 1), (0, 1), (3, 2))))
751
 
        self.assertEqual(l[0], (1, '1'))
752
 
        self.assertEqual(l[1], (9, '9'))
753
 
        self.assertEqual(l[2], (0, '0'))
754
 
        self.assertEqual(l[3], (3, '34'))
 
751
        self.assertEqual(l[0], (1, b'1'))
 
752
        self.assertEqual(l[1], (9, b'9'))
 
753
        self.assertEqual(l[2], (0, b'0'))
 
754
        self.assertEqual(l[3], (3, b'34'))
755
755
 
756
756
    def test_readv_invalid_ranges(self):
757
757
        t = self.get_readonly_transport()
773
773
        t._max_readv_combine = 1
774
774
        t._max_get_ranges = 1
775
775
        l = list(t.readv('a', ((0, 1), (1, 1), (3, 2), (9, 1))))
776
 
        self.assertEqual(l[0], (0, '0'))
777
 
        self.assertEqual(l[1], (1, '1'))
778
 
        self.assertEqual(l[2], (3, '34'))
779
 
        self.assertEqual(l[3], (9, '9'))
 
776
        self.assertEqual(l[0], (0, b'0'))
 
777
        self.assertEqual(l[1], (1, b'1'))
 
778
        self.assertEqual(l[2], (3, b'34'))
 
779
        self.assertEqual(l[3], (9, b'9'))
780
780
        # The server should have issued 4 requests
781
781
        self.assertEqual(4, server.GET_request_nb)
782
782
 
788
788
        # single range will keep its size even if bigger than the limit.
789
789
        t._get_max_size = 2
790
790
        l = list(t.readv('a', ((0, 1), (1, 1), (2, 4), (6, 4))))
791
 
        self.assertEqual(l[0], (0, '0'))
792
 
        self.assertEqual(l[1], (1, '1'))
793
 
        self.assertEqual(l[2], (2, '2345'))
794
 
        self.assertEqual(l[3], (6, '6789'))
 
791
        self.assertEqual(l[0], (0, b'0'))
 
792
        self.assertEqual(l[1], (1, b'1'))
 
793
        self.assertEqual(l[2], (2, b'2345'))
 
794
        self.assertEqual(l[3], (6, b'6789'))
795
795
        # The server should have issued 3 requests
796
796
        self.assertEqual(3, server.GET_request_nb)
797
797
 
803
803
        list(t.readv('a', ((0, 1), (1, 1), (2, 4), (6, 4))))
804
804
        # The server should have issued 3 requests
805
805
        self.assertEqual(3, server.GET_request_nb)
806
 
        self.assertEqual('0123456789', t.get_bytes('a'))
 
806
        self.assertEqual(b'0123456789', t.get_bytes('a'))
807
807
        self.assertEqual(4, server.GET_request_nb)
808
808
 
809
809
    def test_incomplete_readv_leave_pipe_clean(self):
814
814
        # Don't collapse readv results into a list so that we leave unread
815
815
        # bytes on the socket
816
816
        ireadv = iter(t.readv('a', ((0, 1), (1, 1), (2, 4), (6, 4))))
817
 
        self.assertEqual((0, '0'), next(ireadv))
 
817
        self.assertEqual((0, b'0'), next(ireadv))
818
818
        # The server should have issued one request so far
819
819
        self.assertEqual(1, server.GET_request_nb)
820
 
        self.assertEqual('0123456789', t.get_bytes('a'))
 
820
        self.assertEqual(b'0123456789', t.get_bytes('a'))
821
821
        # get_bytes issued an additional request, the readv pending ones are
822
822
        # lost
823
823
        self.assertEqual(2, server.GET_request_nb)
890
890
                         "multipart/byteranges; boundary=%s" % boundary)
891
891
        self.end_headers()
892
892
        for (start, end) in ranges:
893
 
            self.wfile.write("--%s\r\n" % boundary)
 
893
            self.wfile.write(b"--%s\r\n" % boundary.encode('ascii'))
894
894
            self.send_header("Content-type", 'application/octet-stream')
895
895
            self.send_header("Content-Range", "bytes %d-%d/%d" % (start,
896
896
                                                                  end,
898
898
            self.end_headers()
899
899
            self.send_range_content(file, start, end - start + 1)
900
900
        # Final boundary
901
 
        self.wfile.write("--%s\r\n" % boundary)
 
901
        self.wfile.write(b"--%s\r\n" % boundary)
902
902
 
903
903
 
904
904
class TestMultipleRangeWithoutContentLengthServer(TestRangeRequestServer):
923
923
        boundary = 'tagada'
924
924
        self.send_header('Content-Type',
925
925
                         'multipart/byteranges; boundary=%s' % boundary)
926
 
        boundary_line = '--%s\r\n' % boundary
 
926
        boundary_line = b'--%s\r\n' % boundary.encode('ascii')
927
927
        # Calculate the Content-Length
928
928
        content_length = 0
929
929
        for (start, end) in ranges:
970
970
        # Force separate ranges for each offset
971
971
        t._bytes_to_read_before_seek = 0
972
972
        ireadv = iter(t.readv('a', ((0, 1), (2, 1), (4, 2), (9, 1))))
973
 
        self.assertEqual((0, '0'), next(ireadv))
974
 
        self.assertEqual((2, '2'), next(ireadv))
 
973
        self.assertEqual((0, b'0'), next(ireadv))
 
974
        self.assertEqual((2, b'2'), next(ireadv))
975
975
        # Only one request have been issued so far
976
976
        self.assertEqual(1, server.GET_request_nb)
977
 
        self.assertEqual((4, '45'), next(ireadv))
978
 
        self.assertEqual((9, '9'), next(ireadv))
 
977
        self.assertEqual((4, b'45'), next(ireadv))
 
978
        self.assertEqual((9, b'9'), next(ireadv))
979
979
        # We issue 3 requests: two multiple (4 ranges, then 2 ranges) then a
980
980
        # single range.
981
981
        self.assertEqual(3, server.GET_request_nb)
996
996
        boundary = 'tagada'
997
997
        self.send_header('Content-Type',
998
998
                         'multipart/byteranges; boundary=%s' % boundary)
999
 
        boundary_line = '--%s\r\n' % boundary
 
999
        boundary_line = b'--%s\r\n' % boundary.encode('ascii')
1000
1000
        # Calculate the Content-Length
1001
1001
        content_length = 0
1002
1002
        for (start, end) in ranges:
1044
1044
        # Force separate ranges for each offset
1045
1045
        t._bytes_to_read_before_seek = 0
1046
1046
        ireadv = iter(t.readv('a', ((0, 1), (2, 1), (4, 2), (9, 1))))
1047
 
        self.assertEqual((0, '0'), next(ireadv))
1048
 
        self.assertEqual((2, '2'), next(ireadv))
1049
 
        self.assertEqual((4, '45'), next(ireadv))
1050
 
        self.assertEqual((9, '9'), next(ireadv))
 
1047
        self.assertEqual((0, b'0'), next(ireadv))
 
1048
        self.assertEqual((2, b'2'), next(ireadv))
 
1049
        self.assertEqual((4, b'45'), next(ireadv))
 
1050
        self.assertEqual((9, b'9'), next(ireadv))
1051
1051
 
1052
1052
 
1053
1053
class LimitedRangeRequestHandler(http_server.TestingHTTPRequestHandler):
1102
1102
    def test_few_ranges(self):
1103
1103
        t = self.get_readonly_transport()
1104
1104
        l = list(t.readv('a', ((0, 4), (1024, 4), )))
1105
 
        self.assertEqual(l[0], (0, '0000'))
1106
 
        self.assertEqual(l[1], (1024, '0001'))
 
1105
        self.assertEqual(l[0], (0, b'0000'))
 
1106
        self.assertEqual(l[1], (1024, b'0001'))
1107
1107
        self.assertEqual(1, self.get_readonly_server().GET_request_nb)
1108
1108
 
1109
1109
    def test_more_ranges(self):
1110
1110
        t = self.get_readonly_transport()
1111
1111
        l = list(t.readv('a', ((0, 4), (1024, 4), (4096, 4), (8192, 4))))
1112
 
        self.assertEqual(l[0], (0, '0000'))
1113
 
        self.assertEqual(l[1], (1024, '0001'))
1114
 
        self.assertEqual(l[2], (4096, '0004'))
1115
 
        self.assertEqual(l[3], (8192, '0008'))
 
1112
        self.assertEqual(l[0], (0, b'0000'))
 
1113
        self.assertEqual(l[1], (1024, b'0001'))
 
1114
        self.assertEqual(l[2], (4096, b'0004'))
 
1115
        self.assertEqual(l[3], (8192, b'0008'))
1116
1116
        # The server will refuse to serve the first request (too much ranges),
1117
1117
        # a second request will succeed.
1118
1118
        self.assertEqual(2, self.get_readonly_server().GET_request_nb)
1286
1286
    def test_range_header(self):
1287
1287
        # Valid ranges
1288
1288
        self.assertEqual(
1289
 
            ['0', '234'], list(self._file_contents('a', [(0, 0), (2, 4)])))
 
1289
            [b'0', b'234'], list(self._file_contents('a', [(0, 0), (2, 4)])))
1290
1290
 
1291
1291
    def test_range_header_tail(self):
1292
 
        self.assertEqual('789', self._file_tail('a', 3))
 
1292
        self.assertEqual(b'789', self._file_tail('a', 3))
1293
1293
 
1294
1294
    def test_syntactically_invalid_range_header(self):
1295
1295
        self.assertListRaises(errors.InvalidHttpRange,
1318
1318
    def test_redirected(self):
1319
1319
        self.assertRaises(errors.RedirectRequested,
1320
1320
                          self.get_old_transport().get, 'a')
1321
 
        self.assertEqual('0123456789', self.get_new_transport().get('a').read())
 
1321
        self.assertEqual(
 
1322
                b'0123456789',
 
1323
                self.get_new_transport().get('a').read())
1322
1324
 
1323
1325
 
1324
1326
class RedirectedRequest(_urllib2_wrappers.Request):
1400
1402
                                       self.new_server.port)
1401
1403
        self.old_server.redirections = \
1402
1404
            [('(.*)', r'%s/1\1' % (new_prefix), 301),]
1403
 
        self.assertEqual('redirected once', t._perform(req).read())
 
1405
        self.assertEqual(b'redirected once', t._perform(req).read())
1404
1406
 
1405
1407
    def test_five_redirections(self):
1406
1408
        t = self.get_old_transport()
1416
1418
            ('/4(.*)', r'%s/5\1' % (new_prefix), 301),
1417
1419
            ('(/[^/]+)', r'%s/1\1' % (old_prefix), 301),
1418
1420
            ]
1419
 
        self.assertEqual('redirected 5 times', t._perform(req).read())
 
1421
        self.assertEqual(b'redirected 5 times', t._perform(req).read())
1420
1422
 
1421
1423
 
1422
1424
class TestDoCatchRedirections(http_utils.TestCaseWithRedirectedWebserver):
1441
1443
        t = self.get_new_transport()
1442
1444
 
1443
1445
        # We use None for redirected so that we fail if redirected
1444
 
        self.assertEqual('0123456789',
 
1446
        self.assertEqual(b'0123456789',
1445
1447
                         transport.do_catching_redirections(
1446
1448
                self.get_a, t, None).read())
1447
1449
 
1453
1455
            redirected_t = t._redirected_to(exception.source, exception.target)
1454
1456
            return redirected_t
1455
1457
 
1456
 
        self.assertEqual('0123456789',
 
1458
        self.assertEqual(b'0123456789',
1457
1459
                         transport.do_catching_redirections(
1458
1460
                self.get_a, self.old_transport, redirected).read())
1459
1461
        self.assertEqual(1, self.redirections)
1495
1497
            protocol='http',
1496
1498
            host='localhost',
1497
1499
            path='/',
1498
 
            realm='Realm',
 
1500
            realm=u'Realm',
1499
1501
            ))
1500
1502
        self.assertEqual((user, password), got_pass)
1501
1503
 
1546
1548
    def test_empty_pass(self):
1547
1549
        self.server.add_user('joe', '')
1548
1550
        t = self.get_user_transport('joe', '')
1549
 
        self.assertEqual('contents of a\n', t.get('a').read())
 
1551
        self.assertEqual(b'contents of a\n', t.get('a').read())
1550
1552
        # Only one 'Authentication Required' error should occur
1551
1553
        self.assertEqual(1, self.server.auth_required_errors)
1552
1554
 
1553
1555
    def test_user_pass(self):
1554
1556
        self.server.add_user('joe', 'foo')
1555
1557
        t = self.get_user_transport('joe', 'foo')
1556
 
        self.assertEqual('contents of a\n', t.get('a').read())
 
1558
        self.assertEqual(b'contents of a\n', t.get('a').read())
1557
1559
        # Only one 'Authentication Required' error should occur
1558
1560
        self.assertEqual(1, self.server.auth_required_errors)
1559
1561
 
1579
1581
        t = self.get_user_transport(None, None)
1580
1582
        ui.ui_factory = tests.TestUIFactory(stdin='joe\nfoo\n')
1581
1583
        stdout, stderr = ui.ui_factory.stdout, ui.ui_factory.stderr
1582
 
        self.assertEqual('contents of a\n', t.get('a').read())
 
1584
        self.assertEqual(b'contents of a\n', t.get('a').read())
1583
1585
        # stdin should be empty
1584
1586
        self.assertEqual('', ui.ui_factory.stdin.readline())
1585
1587
        stderr.seek(0)
1594
1596
        t = self.get_user_transport('joe', None)
1595
1597
        ui.ui_factory = tests.TestUIFactory(stdin='foo\n')
1596
1598
        stdout, stderr = ui.ui_factory.stdout, ui.ui_factory.stderr
1597
 
        self.assertEqual('contents of a\n', t.get('a').read())
 
1599
        self.assertEqual(b'contents of a\n', t.get('a').read())
1598
1600
        # stdin should be empty
1599
1601
        self.assertEqual('', ui.ui_factory.stdin.readline())
1600
1602
        self._check_password_prompt(t._unqualified_scheme, 'joe',
1602
1604
        self.assertEqual('', stdout.getvalue())
1603
1605
        # And we shouldn't prompt again for a different request
1604
1606
        # against the same transport.
1605
 
        self.assertEqual('contents of b\n', t.get('b').read())
 
1607
        self.assertEqual(b'contents of b\n', t.get('b').read())
1606
1608
        t2 = t.clone()
1607
1609
        # And neither against a clone
1608
 
        self.assertEqual('contents of b\n', t2.get('b').read())
 
1610
        self.assertEqual(b'contents of b\n', t2.get('b').read())
1609
1611
        # Only one 'Authentication Required' error should occur
1610
1612
        self.assertEqual(1, self.server.auth_required_errors)
1611
1613
 
1634
1636
        _setup_authentication_config(scheme='http', port=self.server.port,
1635
1637
                                     user=user, password=password)
1636
1638
        # Issue a request to the server to connect
1637
 
        self.assertEqual('contents of a\n', t.get('a').read())
 
1639
        with t.get('a') as f:
 
1640
            self.assertEqual(b'contents of a\n', f.read())
1638
1641
        # stdin should have  been left untouched
1639
1642
        self.assertEqual(stdin_content, ui.ui_factory.stdin.readline())
1640
1643
        # Only one 'Authentication Required' error should occur
1646
1649
            raise tests.TestNotApplicable('HTTP/proxy auth digest only test')
1647
1650
        self.server.add_user('joe', 'foo')
1648
1651
        t = self.get_user_transport('joe', 'foo')
1649
 
        self.assertEqual('contents of a\n', t.get('a').read())
1650
 
        self.assertEqual('contents of b\n', t.get('b').read())
 
1652
        with t.get('a') as f:
 
1653
            self.assertEqual(b'contents of a\n', f.read())
 
1654
        with t.get('b') as f:
 
1655
            self.assertEqual(b'contents of b\n', f.read())
1651
1656
        # Only one 'Authentication Required' error should have
1652
1657
        # occured so far
1653
1658
        self.assertEqual(1, self.server.auth_required_errors)
1654
1659
        # The server invalidates the current nonce
1655
1660
        self.server.auth_nonce = self.server.auth_nonce + '. No, now!'
1656
 
        self.assertEqual('contents of a\n', t.get('a').read())
 
1661
        self.assertEqual(b'contents of a\n', t.get('a').read())
1657
1662
        # Two 'Authentication Required' errors should occur (the
1658
1663
        # initial 'who are you' and a second 'who are you' with the new nonce)
1659
1664
        self.assertEqual(2, self.server.auth_required_errors)
1666
1671
                                     user=user, password=password)
1667
1672
        t = self.get_user_transport(None, None)
1668
1673
        # Issue a request to the server to connect
1669
 
        self.assertEqual('contents of a\n', t.get('a').read())
 
1674
        with t.get('a') as f:
 
1675
            self.assertEqual(b'contents of a\n', f.read())
1670
1676
        # Only one 'Authentication Required' error should occur
1671
1677
        self.assertEqual(1, self.server.auth_required_errors)
1672
1678
 
1934
1940
    def _handle_one_request(self):
1935
1941
        tcs = self.server.test_case_server
1936
1942
        requestline = self.rfile.readline()
1937
 
        headers = self.MessageClass(self.rfile, 0)
1938
 
        # We just read: the request, the headers, an empty line indicating the
1939
 
        # end of the headers.
1940
 
        bytes_read = len(requestline)
1941
 
        for line in headers.headers:
1942
 
            bytes_read += len(line)
1943
 
        bytes_read += len(b'\r\n')
1944
 
        if requestline.startswith('POST'):
 
1943
        if PY3:
 
1944
            headers = parse_headers(self.rfile)
 
1945
            bytes_read = len(headers.as_bytes())
 
1946
            bytes_read += headers.as_bytes().count(b'\n')
 
1947
            bytes_read += len(requestline)
 
1948
        else:
 
1949
            headers = self.MessageClass(self.rfile, 0)
 
1950
            # We just read: the request, the headers, an empty line indicating the
 
1951
            # end of the headers.
 
1952
            bytes_read = len(requestline)
 
1953
            for line in headers.headers:
 
1954
                bytes_read += len(line)
 
1955
            bytes_read += len(b'\r\n')
 
1956
        if requestline.startswith(b'POST'):
1945
1957
            # The body should be a single line (or we don't know where it ends
1946
1958
            # and we don't want to issue a blocking read)
1947
1959
            body = self.rfile.readline()
2028
2040
Bazaar-NG meta directory, format 1
2029
2041
'''
2030
2042
        t = self.get_transport()
2031
 
        self.assertEqual('Bazaar-NG meta directory, format 1\n',
 
2043
        self.assertEqual(b'Bazaar-NG meta directory, format 1\n',
2032
2044
                         t.get('foo/bar').read())
2033
2045
        self.assertActivitiesMatch()
2034
2046