diff --git a/test/test_networking.py b/test/test_networking.py index 926dc97e97..92fbdc97d9 100644 --- a/test/test_networking.py +++ b/test/test_networking.py @@ -61,7 +61,7 @@ from yt_dlp.networking.impersonate import ( ImpersonateRequestHandler, ImpersonateTarget, ) -from yt_dlp.utils import YoutubeDLError +from yt_dlp.utils import YoutubeDLError, traverse_obj from yt_dlp.utils._utils import _YDLLogger as FakeLogger from yt_dlp.utils.networking import HTTPHeaderDict, std_headers @@ -1762,6 +1762,7 @@ class TestYoutubeDLNetworking: 'compat_opts': ['no-certifi'], 'nocheckcertificate': True, 'legacyserverconnect': True, + 'proxy_nocheckcertificate': True, }) as ydl: rh = self.build_handler(ydl) assert rh.headers.get('test') == 'testtest' @@ -1773,6 +1774,7 @@ class TestYoutubeDLNetworking: assert rh.prefer_system_certs is True assert rh.verify is False assert rh.legacy_ssl_support is True + assert rh.proxy_verify is False @pytest.mark.parametrize('ydl_params', [ {'client_certificate': 'fakecert.crt'}, @@ -1785,6 +1787,22 @@ class TestYoutubeDLNetworking: rh = self.build_handler(ydl) assert rh._client_cert == ydl_params # XXX: Too bound to implementation + @pytest.mark.parametrize('client_cert', [ + {'client_certificate': 'fakecert.crt'}, + {'client_certificate': 'fakecert.crt', 'client_certificate_key': 'fakekey.key'}, + {'client_certificate': 'fakecert.crt', 'client_certificate_key': 'fakekey.key', 'client_certificate_password': 'foobar'}, + {'client_certificate_key': 'fakekey.key', 'client_certificate_password': 'foobar'}, + ]) + def test_proxy_client_certificate(self, client_cert): + ydl_params = traverse_obj(client_cert, { + 'proxy_client_certificate': 'client_certificate', + 'proxy_client_certificate_key': 'client_certificate_key', + 'proxy_client_certificate_password': 'client_certificate_password', + }) + with FakeYDL(ydl_params) as ydl: + rh = self.build_handler(ydl) + assert rh._proxy_client_cert == client_cert + def test_urllib_file_urls(self): with FakeYDL({'enable_file_urls': False}) as ydl: rh = self.build_handler(ydl, UrllibRH) diff --git a/yt_dlp/YoutubeDL.py b/yt_dlp/YoutubeDL.py index 9691a1ea7c..ee7880c12b 100644 --- a/yt_dlp/YoutubeDL.py +++ b/yt_dlp/YoutubeDL.py @@ -340,10 +340,15 @@ class YoutubeDL: legacyserverconnect: Explicitly allow HTTPS connection to servers that do not support RFC 5746 secure renegotiation nocheckcertificate: Do not verify SSL certificates + proxy_nocheckcertificate: Do not verify SSL certificates for HTTPS proxy client_certificate: Path to client certificate file in PEM format. May include the private key client_certificate_key: Path to private key file for client certificate client_certificate_password: Password for client certificate private key, if encrypted. If not provided and the key is encrypted, yt-dlp will ask interactively + proxy_client_certificate: Path to client certificate file in PEM format for HTTPS proxy. May include the private key + proxy_client_certificate_key: Path to private key file for client certificate for HTTPS proxy. + proxy_client_certificate_password: Password for client certificate private key, if encrypted, for HTTPS proxy. + If not provided and the key is encrypted, yt-dlp will ask interactively prefer_insecure: Use HTTP instead of HTTPS to retrieve information. (Only supported by some extractors) enable_file_urls: Enable file:// URLs. This is disabled by default for security reasons. @@ -4221,6 +4226,7 @@ class YoutubeDL: proxies=proxies, prefer_system_certs='no-certifi' in self.params['compat_opts'], verify=not self.params.get('nocheckcertificate'), + proxy_verify=not self.params.get('proxy_nocheckcertificate'), **traverse_obj(self.params, { 'verbose': 'debug_printtraffic', 'source_address': 'source_address', @@ -4233,6 +4239,11 @@ class YoutubeDL: 'client_certificate_key': 'client_certificate_key', 'client_certificate_password': 'client_certificate_password', }, + 'proxy_client_cert': { + 'client_certificate': 'proxy_client_certificate', + 'client_certificate_key': 'proxy_client_certificate_key', + 'client_certificate_password': 'proxy_client_certificate_password', + }, }), )) director.preferences.update(preferences or [])