]>
Commit | Line | Data |
---|---|---|
cc52de43 | 1 | #!/usr/bin/env python3 |
54007a45 | 2 | |
ba515388 S |
3 | # Allow direct execution |
4 | import os | |
ba515388 S |
5 | import sys |
6 | import unittest | |
f8271158 | 7 | |
ba515388 S |
8 | sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) |
9 | ||
ac668111 | 10 | |
54007a45 | 11 | import http.server |
ac668111 | 12 | import re |
f8271158 | 13 | import threading |
f8271158 | 14 | |
54007a45 | 15 | from test.helper import http_server_port, try_rm |
7a5c1cfe | 16 | from yt_dlp import YoutubeDL |
7a5c1cfe P |
17 | from yt_dlp.downloader.http import HttpFD |
18 | from yt_dlp.utils import encodeFilename | |
1b392f90 | 19 | from yt_dlp.utils._utils import _YDLLogger as FakeLogger |
ba515388 S |
20 | |
21 | TEST_DIR = os.path.dirname(os.path.abspath(__file__)) | |
22 | ||
23 | ||
ba515388 S |
24 | TEST_SIZE = 10 * 1024 |
25 | ||
26 | ||
ac668111 | 27 | class HTTPTestRequestHandler(http.server.BaseHTTPRequestHandler): |
ba515388 S |
28 | def log_message(self, format, *args): |
29 | pass | |
30 | ||
31 | def send_content_range(self, total=None): | |
32 | range_header = self.headers.get('Range') | |
33 | start = end = None | |
34 | if range_header: | |
35 | mobj = re.search(r'^bytes=(\d+)-(\d+)', range_header) | |
36 | if mobj: | |
37 | start = int(mobj.group(1)) | |
38 | end = int(mobj.group(2)) | |
39 | valid_range = start is not None and end is not None | |
40 | if valid_range: | |
41 | content_range = 'bytes %d-%d' % (start, end) | |
42 | if total: | |
43 | content_range += '/%d' % total | |
44 | self.send_header('Content-Range', content_range) | |
45 | return (end - start + 1) if valid_range else total | |
46 | ||
47 | def serve(self, range=True, content_length=True): | |
48 | self.send_response(200) | |
49 | self.send_header('Content-Type', 'video/mp4') | |
50 | size = TEST_SIZE | |
51 | if range: | |
52 | size = self.send_content_range(TEST_SIZE) | |
53 | if content_length: | |
54 | self.send_header('Content-Length', size) | |
55 | self.end_headers() | |
56 | self.wfile.write(b'#' * size) | |
57 | ||
58 | def do_GET(self): | |
59 | if self.path == '/regular': | |
60 | self.serve() | |
61 | elif self.path == '/no-content-length': | |
62 | self.serve(content_length=False) | |
63 | elif self.path == '/no-range': | |
64 | self.serve(range=False) | |
65 | elif self.path == '/no-range-no-content-length': | |
66 | self.serve(range=False, content_length=False) | |
67 | else: | |
68 | assert False | |
69 | ||
70 | ||
ba515388 S |
71 | class TestHttpFD(unittest.TestCase): |
72 | def setUp(self): | |
ac668111 | 73 | self.httpd = http.server.HTTPServer( |
ba515388 S |
74 | ('127.0.0.1', 0), HTTPTestRequestHandler) |
75 | self.port = http_server_port(self.httpd) | |
76 | self.server_thread = threading.Thread(target=self.httpd.serve_forever) | |
77 | self.server_thread.daemon = True | |
78 | self.server_thread.start() | |
79 | ||
80 | def download(self, params, ep): | |
81 | params['logger'] = FakeLogger() | |
82 | ydl = YoutubeDL(params) | |
83 | downloader = HttpFD(ydl, params) | |
84 | filename = 'testfile.mp4' | |
6fcc0539 | 85 | try_rm(encodeFilename(filename)) |
ba515388 S |
86 | self.assertTrue(downloader.real_download(filename, { |
87 | 'url': 'http://127.0.0.1:%d/%s' % (self.port, ep), | |
be5c1ae8 | 88 | }), ep) |
89 | self.assertEqual(os.path.getsize(encodeFilename(filename)), TEST_SIZE, ep) | |
6fcc0539 | 90 | try_rm(encodeFilename(filename)) |
ba515388 S |
91 | |
92 | def download_all(self, params): | |
93 | for ep in ('regular', 'no-content-length', 'no-range', 'no-range-no-content-length'): | |
94 | self.download(params, ep) | |
95 | ||
96 | def test_regular(self): | |
97 | self.download_all({}) | |
98 | ||
99 | def test_chunked(self): | |
100 | self.download_all({ | |
101 | 'http_chunk_size': 1000, | |
102 | }) | |
103 | ||
104 | ||
105 | if __name__ == '__main__': | |
106 | unittest.main() |