/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_response.py

  • Committer: Martin
  • Date: 2018-06-30 22:18:39 UTC
  • mfrom: (7010 work)
  • mto: This revision was merged to the branch mainline in revision 7012.
  • Revision ID: gzlist@googlemail.com-20180630221839-98zi78xwcggestse
Merge trunk to fix conflict

Show diffs side-by-side

added added

removed removed

Lines of Context:
88
88
 
89
89
    def test_iter_many(self):
90
90
        f = response.ResponseFile('many', BytesIO(b'0\n1\nboo!\n'))
91
 
        self.assertEqual(['0\n', '1\n', 'boo!\n'], list(f))
 
91
        self.assertEqual([b'0\n', b'1\n', b'boo!\n'], list(f))
92
92
 
93
93
 
94
94
class TestHTTPConnection(tests.TestCase):
95
95
 
96
96
    def test_cleanup_pipe(self):
97
 
        sock = ReadSocket("""HTTP/1.1 200 OK\r
 
97
        sock = ReadSocket(b"""HTTP/1.1 200 OK\r
98
98
Content-Type: text/plain; charset=UTF-8\r
99
99
Content-Length: 18
100
100
\r
108
108
        # Now, get the response
109
109
        resp = conn.getresponse()
110
110
        # Read part of the response
111
 
        self.assertEqual('0123456789\n', resp.read(11))
 
111
        self.assertEqual(b'0123456789\n', resp.read(11))
112
112
        # Override the thresold to force the warning emission
113
113
        conn._range_warning_thresold = 6 # There are 7 bytes pending
114
114
        conn.cleanup_pipe()
122
122
    # which offsets are easy to calculate for test writers. It's used as a
123
123
    # building block with slight variations but basically 'a' is the first char
124
124
    # of the range and 'z' is the last.
125
 
    alpha = 'abcdefghijklmnopqrstuvwxyz'
 
125
    alpha = b'abcdefghijklmnopqrstuvwxyz'
126
126
 
127
127
    def test_can_read_at_first_access(self):
128
128
        """Test that the just created file can be read."""
137
137
        cur = start # For an overall offset assertion
138
138
        f.seek(start + 3)
139
139
        cur += 3
140
 
        self.assertEqual('def', f.read(3))
 
140
        self.assertEqual(b'def', f.read(3))
141
141
        cur += len('def')
142
142
        f.seek(4, 1)
143
143
        cur += 4
144
 
        self.assertEqual('klmn', f.read(4))
 
144
        self.assertEqual(b'klmn', f.read(4))
145
145
        cur += len('klmn')
146
146
        # read(0) in the middle of a range
147
 
        self.assertEqual('', f.read(0))
 
147
        self.assertEqual(b'', f.read(0))
148
148
        # seek in place
149
149
        here = f.tell()
150
150
        f.seek(0, 1)
153
153
 
154
154
    def test_read_zero(self):
155
155
        f = self._file
156
 
        self.assertEqual('', f.read(0))
 
156
        self.assertEqual(b'', f.read(0))
157
157
        f.seek(10, 1)
158
 
        self.assertEqual('', f.read(0))
 
158
        self.assertEqual(b'', f.read(0))
159
159
 
160
160
    def test_seek_at_range_end(self):
161
161
        f = self._file
165
165
        """Test read behaviour at range end."""
166
166
        f = self._file
167
167
        self.assertEqual(self.alpha, f.read())
168
 
        self.assertEqual('', f.read(0))
 
168
        self.assertEqual(b'', f.read(0))
169
169
        self.assertRaises(errors.InvalidRange, f.read, 1)
170
170
 
171
171
    def test_unbounded_read_after_seek(self):
172
172
        f = self._file
173
173
        f.seek(24, 1)
174
174
        # Should not cross ranges
175
 
        self.assertEqual('yz', f.read())
 
175
        self.assertEqual(b'yz', f.read())
176
176
 
177
177
    def test_seek_backwards(self):
178
178
        f = self._file
212
212
       """
213
213
       f = self._file
214
214
       f.seek(-2, 2)
215
 
       self.assertEqual('yz', f.read())
 
215
       self.assertEqual(b'yz', f.read())
216
216
 
217
217
 
218
218
class TestRangeFileSizeUnknown(tests.TestCase, TestRangeFileMixin):
236
236
        """Test read behaviour at range end."""
237
237
        f = self._file
238
238
        self.assertEqual(self.alpha, f.read())
239
 
        self.assertEqual('', f.read(0))
240
 
        self.assertEqual('', f.read(1))
 
239
        self.assertEqual(b'', f.read(0))
 
240
        self.assertEqual(b'', f.read(1))
241
241
 
242
242
 
243
243
class TestRangeFileSizeKnown(tests.TestCase, TestRangeFileMixin):
286
286
    # in HTTP response headers and the boundary lines that separate
287
287
    # multipart content.
288
288
 
289
 
    boundary = "separation"
 
289
    boundary = b"separation"
290
290
 
291
291
    def setUp(self):
292
292
        super(TestRangeFileMultipleRanges, self).setUp()
293
293
 
294
294
        boundary = self.boundary
295
295
 
296
 
        content = ''
 
296
        content = b''
297
297
        self.first_range_start = 25
298
298
        file_size = 200 # big enough to encompass all ranges
299
299
        for (start, part) in [(self.first_range_start, self.alpha),
311
311
 
312
312
    def _boundary_line(self):
313
313
        """Helper to build the formatted boundary line."""
314
 
        return '--' + self.boundary + '\r\n'
 
314
        return b'--' + self.boundary + b'\r\n'
315
315
 
316
316
    def set_file_boundary(self):
317
317
        # Ranges are set by decoding the range headers, the RangeFile user is
320
320
        # which is part of the Content-Type header).
321
321
        self._file.set_boundary(self.boundary)
322
322
 
323
 
    def _multipart_byterange(self, data, offset, boundary, file_size='*'):
 
323
    def _multipart_byterange(self, data, offset, boundary, file_size=b'*'):
324
324
        """Encode a part of a file as a multipart/byterange MIME type.
325
325
 
326
326
        When a range request is issued, the HTTP response body can be
342
342
        # A range is described by a set of headers, but only 'Content-Range' is
343
343
        # required for our implementation (TestHandleResponse below will
344
344
        # exercise ranges with multiple or missing headers')
345
 
        range += 'Content-Range: bytes %d-%d/%d\r\n' % (offset,
346
 
                                                        offset+len(data)-1,
347
 
                                                        file_size)
348
 
        range += '\r\n'
 
345
        if isinstance(file_size, int):
 
346
            file_size = b'%d' % file_size
 
347
        range += b'Content-Range: bytes %d-%d/%s\r\n' % (offset,
 
348
                                                         offset+len(data)-1,
 
349
                                                         file_size)
 
350
        range += b'\r\n'
349
351
        # Finally the raw bytes
350
352
        range += data
351
353
        return range
357
359
        self.assertEqual(self.alpha, f.read()) # Read second range
358
360
        self.assertEqual(126, f.tell())
359
361
        f.seek(126) # Start of third range which is also the current pos !
360
 
        self.assertEqual('A', f.read(1))
 
362
        self.assertEqual(b'A', f.read(1))
361
363
        f.seek(10, 1)
362
 
        self.assertEqual('LMN', f.read(3))
 
364
        self.assertEqual(b'LMN', f.read(3))
363
365
 
364
366
    def test_seek_from_end(self):
365
367
        """See TestRangeFileMixin.test_seek_from_end."""
369
371
        # behaviour.
370
372
        f = self._file
371
373
        f.seek(-2, 2)
372
 
        self.assertEqual('yz', f.read())
 
374
        self.assertEqual(b'yz', f.read())
373
375
        self.assertRaises(errors.InvalidRange, f.seek, -2, 2)
374
376
 
375
377
    def test_seek_into_void(self):
387
389
    def test_seek_across_ranges(self):
388
390
        f = self._file
389
391
        f.seek(126) # skip the two first ranges
390
 
        self.assertEqual('AB', f.read(2))
 
392
        self.assertEqual(b'AB', f.read(2))
391
393
 
392
394
    def test_checked_read_dont_overflow_buffers(self):
393
395
        f = self._file
394
396
        # We force a very low value to exercise all code paths in _checked_read
395
397
        f._discarded_buf_size = 8
396
398
        f.seek(126) # skip the two first ranges
397
 
        self.assertEqual('AB', f.read(2))
 
399
        self.assertEqual(b'AB', f.read(2))
398
400
 
399
401
    def test_seek_twice_between_ranges(self):
400
402
        f = self._file
435
437
    """
436
438
    # The boundary as it appears in boundary lines
437
439
    # IIS 6 and 7 use this value
438
 
    _boundary_trimmed = "q1w2e3r4t5y6u7i8o9p0zaxscdvfbgnhmjklkl"
439
 
    boundary = '<' + _boundary_trimmed + '>'
 
440
    _boundary_trimmed = b"q1w2e3r4t5y6u7i8o9p0zaxscdvfbgnhmjklkl"
 
441
    boundary = b'<' + _boundary_trimmed + b'>'
440
442
 
441
443
    def set_file_boundary(self):
442
444
        # Emulate broken rfc822.unquote() here by removing angles
485
487
 
486
488
 
487
489
# Taken from real request responses
488
 
_full_text_response = (200, """HTTP/1.1 200 OK\r
 
490
_full_text_response = (200, b"""HTTP/1.1 200 OK\r
489
491
Date: Tue, 11 Jul 2006 04:32:56 GMT\r
490
492
Server: Apache/2.0.54 (Fedora)\r
491
493
Last-Modified: Sun, 23 Apr 2006 19:35:20 GMT\r
495
497
Connection: close\r
496
498
Content-Type: text/plain; charset=UTF-8\r
497
499
\r
498
 
""", """Bazaar-NG meta directory, format 1
 
500
""", b"""Bazaar-NG meta directory, format 1
499
501
""")
500
502
 
501
503
 
502
 
_single_range_response = (206, """HTTP/1.1 206 Partial Content\r
 
504
_single_range_response = (206, b"""HTTP/1.1 206 Partial Content\r
503
505
Date: Tue, 11 Jul 2006 04:45:22 GMT\r
504
506
Server: Apache/2.0.54 (Fedora)\r
505
507
Last-Modified: Thu, 06 Jul 2006 20:22:05 GMT\r
510
512
Connection: close\r
511
513
Content-Type: text/plain; charset=UTF-8\r
512
514
\r
513
 
""", """mbp@sourcefrog.net-20050309040815-13242001617e4a06
 
515
""", b"""mbp@sourcefrog.net-20050309040815-13242001617e4a06
514
516
mbp@sourcefrog.net-20050309040929-eee0eb3e6d1e762""")
515
517
 
516
518
 
517
 
_single_range_no_content_type = (206, """HTTP/1.1 206 Partial Content\r
 
519
_single_range_no_content_type = (206, b"""HTTP/1.1 206 Partial Content\r
518
520
Date: Tue, 11 Jul 2006 04:45:22 GMT\r
519
521
Server: Apache/2.0.54 (Fedora)\r
520
522
Last-Modified: Thu, 06 Jul 2006 20:22:05 GMT\r
524
526
Content-Range: bytes 100-199/93890\r
525
527
Connection: close\r
526
528
\r
527
 
""", """mbp@sourcefrog.net-20050309040815-13242001617e4a06
 
529
""", b"""mbp@sourcefrog.net-20050309040815-13242001617e4a06
528
530
mbp@sourcefrog.net-20050309040929-eee0eb3e6d1e762""")
529
531
 
530
532
 
531
 
_multipart_range_response = (206, """HTTP/1.1 206 Partial Content\r
 
533
_multipart_range_response = (206, b"""HTTP/1.1 206 Partial Content\r
532
534
Date: Tue, 11 Jul 2006 04:49:48 GMT\r
533
535
Server: Apache/2.0.54 (Fedora)\r
534
536
Last-Modified: Thu, 06 Jul 2006 20:22:05 GMT\r
538
540
Connection: close\r
539
541
Content-Type: multipart/byteranges; boundary=418470f848b63279b\r
540
542
\r
541
 
\r""", """--418470f848b63279b\r
 
543
\r""", b"""--418470f848b63279b\r
542
544
Content-type: text/plain; charset=UTF-8\r
543
545
Content-range: bytes 0-254/93890\r
544
546
\r
578
580
""")
579
581
 
580
582
 
581
 
_multipart_squid_range_response = (206, """HTTP/1.0 206 Partial Content\r
 
583
_multipart_squid_range_response = (206, b"""HTTP/1.0 206 Partial Content\r
582
584
Date: Thu, 31 Aug 2006 21:16:22 GMT\r
583
585
Server: Apache/2.2.2 (Unix) DAV/2\r
584
586
Last-Modified: Thu, 31 Aug 2006 17:57:06 GMT\r
590
592
Proxy-Connection: keep-alive\r
591
593
\r
592
594
""",
593
 
"""\r
 
595
b"""\r
594
596
--squid/2.5.STABLE12:C99323425AD4FE26F726261FA6C24196\r
595
597
Content-Type: text/plain\r
596
598
Content-Range: bytes 0-99/18672\r
611
613
 
612
614
 
613
615
# This is made up
614
 
_full_text_response_no_content_type = (200, """HTTP/1.1 200 OK\r
 
616
_full_text_response_no_content_type = (200, b"""HTTP/1.1 200 OK\r
615
617
Date: Tue, 11 Jul 2006 04:32:56 GMT\r
616
618
Server: Apache/2.0.54 (Fedora)\r
617
619
Last-Modified: Sun, 23 Apr 2006 19:35:20 GMT\r
620
622
Content-Length: 35\r
621
623
Connection: close\r
622
624
\r
623
 
""", """Bazaar-NG meta directory, format 1
 
625
""", b"""Bazaar-NG meta directory, format 1
624
626
""")
625
627
 
626
628
 
627
 
_full_text_response_no_content_length = (200, """HTTP/1.1 200 OK\r
 
629
_full_text_response_no_content_length = (200, b"""HTTP/1.1 200 OK\r
628
630
Date: Tue, 11 Jul 2006 04:32:56 GMT\r
629
631
Server: Apache/2.0.54 (Fedora)\r
630
632
Last-Modified: Sun, 23 Apr 2006 19:35:20 GMT\r
633
635
Connection: close\r
634
636
Content-Type: text/plain; charset=UTF-8\r
635
637
\r
636
 
""", """Bazaar-NG meta directory, format 1
 
638
""", b"""Bazaar-NG meta directory, format 1
637
639
""")
638
640
 
639
641
 
640
 
_single_range_no_content_range = (206, """HTTP/1.1 206 Partial Content\r
 
642
_single_range_no_content_range = (206, b"""HTTP/1.1 206 Partial Content\r
641
643
Date: Tue, 11 Jul 2006 04:45:22 GMT\r
642
644
Server: Apache/2.0.54 (Fedora)\r
643
645
Last-Modified: Thu, 06 Jul 2006 20:22:05 GMT\r
646
648
Content-Length: 100\r
647
649
Connection: close\r
648
650
\r
649
 
""", """mbp@sourcefrog.net-20050309040815-13242001617e4a06
 
651
""", b"""mbp@sourcefrog.net-20050309040815-13242001617e4a06
650
652
mbp@sourcefrog.net-20050309040929-eee0eb3e6d1e762""")
651
653
 
652
654
 
653
 
_single_range_response_truncated = (206, """HTTP/1.1 206 Partial Content\r
 
655
_single_range_response_truncated = (206, b"""HTTP/1.1 206 Partial Content\r
654
656
Date: Tue, 11 Jul 2006 04:45:22 GMT\r
655
657
Server: Apache/2.0.54 (Fedora)\r
656
658
Last-Modified: Thu, 06 Jul 2006 20:22:05 GMT\r
661
663
Connection: close\r
662
664
Content-Type: text/plain; charset=UTF-8\r
663
665
\r
664
 
""", """mbp@sourcefrog.net-20050309040815-13242001617e4a06""")
665
 
 
666
 
 
667
 
_invalid_response = (444, """HTTP/1.1 444 Bad Response\r
 
666
""", b"""mbp@sourcefrog.net-20050309040815-13242001617e4a06""")
 
667
 
 
668
 
 
669
_invalid_response = (444, b"""HTTP/1.1 444 Bad Response\r
668
670
Date: Tue, 11 Jul 2006 04:32:56 GMT\r
669
671
Connection: close\r
670
672
Content-Type: text/html; charset=iso-8859-1\r
671
673
\r
672
 
""", """<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
 
674
""", b"""<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
673
675
<html><head>
674
676
<title>404 Not Found</title>
675
677
</head><body>
680
682
""")
681
683
 
682
684
 
683
 
_multipart_no_content_range = (206, """HTTP/1.0 206 Partial Content\r
 
685
_multipart_no_content_range = (206, b"""HTTP/1.0 206 Partial Content\r
684
686
Content-Type: multipart/byteranges; boundary=THIS_SEPARATES\r
685
687
Content-Length: 598\r
686
688
\r
687
689
""",
688
 
"""\r
 
690
b"""\r
689
691
--THIS_SEPARATES\r
690
692
Content-Type: text/plain\r
691
693
\r
694
696
""")
695
697
 
696
698
 
697
 
_multipart_no_boundary = (206, """HTTP/1.0 206 Partial Content\r
 
699
_multipart_no_boundary = (206, b"""HTTP/1.0 206 Partial Content\r
698
700
Content-Type: multipart/byteranges; boundary=THIS_SEPARATES\r
699
701
Content-Length: 598\r
700
702
\r
701
703
""",
702
 
"""\r
 
704
b"""\r
703
705
--THIS_SEPARATES\r
704
706
Content-Type: text/plain\r
705
707
Content-Range: bytes 0-18/18672\r
816
818
        super(TestRangeFileSizeReadLimited, self).setUp()
817
819
        # create a test datablock larger than _max_read_size.
818
820
        chunk_size = response.RangeFile._max_read_size
819
 
        test_pattern = '0123456789ABCDEF'
820
 
        self.test_data =  test_pattern * (3 * chunk_size / len(test_pattern))
 
821
        test_pattern = b'0123456789ABCDEF'
 
822
        self.test_data =  test_pattern * (3 * chunk_size // len(test_pattern))
821
823
        self.test_data_len = len(self.test_data)
822
824
 
823
825
    def test_max_read_size(self):