nathom / streamrip

A scriptable music downloader for Qobuz, Tidal, SoundCloud, and Deezer
GNU General Public License v3.0
2.55k stars 219 forks source link

[BUG] (Deezer) ClientConnectorCertificateError: Cannot connect to host cdnt-proxy-4.dzcdn.net:443 ssl:True #535

Open vantablack333 opened 8 months ago

vantablack333 commented 8 months ago

Describe the bug

This error only appears when I try to download from deezer (the search command rip search deezer album "A Life Worth Losing" works well). I also tested downloading from soundcloud - no errors or warnings.

ClientConnectorCertificateError: Cannot connect to host cdnt-proxy-a.dzcdn.net:443 ssl:True [SSLCertVerificationError: (1, '[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: certificate has expired (_ssl.c:1006)')]

However, when I enter https://cdnt-proxy-a.dzcdn.net:443 in browser it opens (the cert is valid until Tue, 16 Jan 2024 14:24:04 GMT)

Command Used

rip url https://www.deezer.com/en/album/426731267

Debug Traceback

m:\Temp>rip url https://www.deezer.com/en/album/426731267
──────────────────────────────────────────────────── Downloading  ─────────────────────────────────────────────────────
Track 1 -------------------------------------------------------------------------------------------- 0.0% • ? • -:--:--
Track 2 -------------------------------------------------------------------------------------------- 0.0% • ? • -:--:--
Track 9 -------------------------------------------------------------------------------------------- 0.0% • ? • -:--:--
Track 4 -------------------------------------------------------------------------------------------- 0.0% • ? • -:--:--
Track 3 -------------------------------------------------------------------------------------------- 0.0% • ? • -:--:--
Track 8 -------------------------------------------------------------------------------------------- 0.0% • ? • -:--:--
┌─────────────────────────────── Traceback (most recent call last) ────────────────────────────────┐
│ C:\Users\Admin\AppData\Local\Programs\Python\Python311\Lib\site-packages\aiohttp\connector.py:99 │
│ 2 in _wrap_create_connection                                                                     │
│                                                                                                  │
│    989 │   │   │   async with ceil_timeout(                                                      │
│    990 │   │   │   │   timeout.sock_connect, ceil_threshold=timeout.ceil_threshold               │
│    991 │   │   │   ):                                                                            │
│ >  992 │   │   │   │   return await self._loop.create_connection(*args, **kwargs)                │
│    993 │   │   except cert_errors as exc:                                                        │
│    994 │   │   │   raise ClientConnectorCertificateError(req.connection_key, exc) from exc       │
│    995 │   │   except ssl_errors as exc:                                                         │
│                                                                                                  │
│ C:\Users\Admin\AppData\Local\Programs\Python\Python311\Lib\asyncio\base_events.py:1112 in        │
│ create_connection                                                                                │
│                                                                                                  │
│                                     ... 2 frames hidden ...                                      │
│                                                                                                  │
│ C:\Users\Admin\AppData\Local\Programs\Python\Python311\Lib\asyncio\sslproto.py:557 in            │
│ _do_handshake                                                                                    │
│                                                                                                  │
│ C:\Users\Admin\AppData\Local\Programs\Python\Python311\Lib\ssl.py:979 in do_handshake            │
│                                                                                                  │
│    976 │                                                                                         │
│    977 │   def do_handshake(self):                                                               │
│    978 │   │   """Start the SSL/TLS handshake."""                                                │
│ >  979 │   │   self._sslobj.do_handshake()                                                       │
│    980 │                                                                                         │
│    981 │   def unwrap(self):                                                                     │
│    982 │   │   """Start the SSL shutdown handshake."""                                           │
└──────────────────────────────────────────────────────────────────────────────────────────────────┘
SSLCertVerificationError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: certificate has expired
(_ssl.c:1006)

The above exception was the direct cause of the following exception:

┌─────────────────────────────── Traceback (most recent call last) ────────────────────────────────┐
│ in _run_module_as_main:198                                                                       │
│ in _run_code:88                                                                                  │
│                                                                                                  │
│                                     ... 25 frames hidden ...                                     │
│                                                                                                  │
│ C:\Users\Admin\AppData\Local\Programs\Python\Python311\Lib\site-packages\aiohttp\connector.py:12 │
│ 04 in _create_direct_connection                                                                  │
│                                                                                                  │
│   1201 │   │   │   )                                                                             │
│   1202 │   │   │                                                                                 │
│   1203 │   │   │   try:                                                                          │
│ > 1204 │   │   │   │   transp, proto = await self._wrap_create_connection(                       │
│   1205 │   │   │   │   │   self._factory,                                                        │
│   1206 │   │   │   │   │   host,                                                                 │
│   1207 │   │   │   │   │   port,                                                                 │
│                                                                                                  │
│ C:\Users\Admin\AppData\Local\Programs\Python\Python311\Lib\site-packages\aiohttp\connector.py:99 │
│ 4 in _wrap_create_connection                                                                     │
│                                                                                                  │
│    991 │   │   │   ):                                                                            │
│    992 │   │   │   │   return await self._loop.create_connection(*args, **kwargs)                │
│    993 │   │   except cert_errors as exc:                                                        │
│ >  994 │   │   │   raise ClientConnectorCertificateError(req.connection_key, exc) from exc       │
│    995 │   │   except ssl_errors as exc:                                                         │
│    996 │   │   │   raise ClientConnectorSSLError(req.connection_key, exc) from exc               │
│    997 │   │   except OSError as exc:                                                            │
└──────────────────────────────────────────────────────────────────────────────────────────────────┘
ClientConnectorCertificateError: Cannot connect to host cdnt-proxy-a.dzcdn.net:443 ssl:True [SSLCertVerificationError:
(1, '[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: certificate has expired (_ssl.c:1006)')]

Config File

Default with just arl set to actual value

Operating System

Windows 10 (Python 3.11)

streamrip version

rip, version 2.0.2

Screenshots and recordings

No response

Additional context

No response

vantablack333 commented 8 months ago

It seems to be happening not always (I managed to download individual tracks).

nathom commented 7 months ago

Maybe this could be fixed with a "retry" feature...

MorisatoK commented 7 months ago

Tried the new version with 2.0.2 and had this issue and it is still happening in 2.0.5, but always. No succesful downloads from Deezer at all so far with 2.0+ - so I downgraded to 1.9.7 again.

Command Used

rip url https://www.deezer.com/en/album/426731267

Debug Traceback

$ rip url https://www.deezer.com/en/album/426731267
[19:22:53] WARNING  Connection pool is full, discarding connection: api.deezer.com. Connection     connectionpool.py:330
                    pool size: 10
           WARNING  Connection pool is full, discarding connection: api.deezer.com. Connection     connectionpool.py:330
                    pool size: 10
           WARNING  Connection pool is full, discarding connection: api.deezer.com. Connection     connectionpool.py:330
                    pool size: 10
           WARNING  Connection pool is full, discarding connection: api.deezer.com. Connection     connectionpool.py:330
                    pool size: 10
           WARNING  Connection pool is full, discarding connection: api.deezer.com. Connection     connectionpool.py:330
                    pool size: 10
           WARNING  Connection pool is full, discarding connection: api.deezer.com. Connection     connectionpool.py:330
                    pool size: 10
           WARNING  Connection pool is full, discarding connection: api.deezer.com. Connection     connectionpool.py:330
                    pool size: 10
───────────────────────────────────────────────────── Downloading  ─────────────────────────────────────────────────────
Track 2  ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 0.0% • ? • -:--:--
Track 3  ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 0.0% • ? • -:--:--
Track 11 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 0.0% • ? • -:--:--
Track 6  ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 0.0% • ? • -:--:--
Track 10 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 0.0% • ? • -:--:--
Track 7  ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 0.0% • ? • -:--:--
╭─────────────────────────────── Traceback (most recent call last) ────────────────────────────────╮
│ C:\Users\XXX\AppData\Local\Programs\Python\Python310\lib\site-packages\aiohttp\connector.py:988 │
│ in _wrap_create_connection                                                                       │
│                                                                                                  │
│    985 │   │   │   async with ceil_timeout(                                                      │
│    986 │   │   │   │   timeout.sock_connect, ceil_threshold=timeout.ceil_threshold               │
│    987 │   │   │   ):                                                                            │
│ ❱  988 │   │   │   │   return await self._loop.create_connection(*args, **kwargs)                │
│    989 │   │   except cert_errors as exc:                                                        │
│    990 │   │   │   raise ClientConnectorCertificateError(req.connection_key, exc) from exc       │
│    991 │   │   except ssl_errors as exc:                                                         │
│                                                                                                  │
│ C:\Users\XXX\AppData\Local\Programs\Python\Python310\lib\asyncio\base_events.py:1089 in         │
│ create_connection                                                                                │
│                                                                                                  │
│                                     ... 2 frames hidden ...                                      │
│                                                                                                  │
│ C:\Users\XXX\AppData\Local\Programs\Python\Python310\lib\asyncio\sslproto.py:188 in             │
│ feed_ssldata                                                                                     │
│                                                                                                  │
│ C:\Users\XXX\AppData\Local\Programs\Python\Python310\lib\ssl.py:975 in do_handshake             │
│                                                                                                  │
│    972 │                                                                                         │
│    973 │   def do_handshake(self):                                                               │
│    974 │   │   """Start the SSL/TLS handshake."""                                                │
│ ❱  975 │   │   self._sslobj.do_handshake()                                                       │
│    976 │                                                                                         │
│    977 │   def unwrap(self):                                                                     │
│    978 │   │   """Start the SSL shutdown handshake."""                                           │
╰──────────────────────────────────────────────────────────────────────────────────────────────────╯
SSLCertVerificationError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: certificate has expired
(_ssl.c:997)

The above exception was the direct cause of the following exception:

╭─────────────────────────────── Traceback (most recent call last) ────────────────────────────────╮
│ C:\Users\XXX\AppData\Local\Programs\Python\Python310\lib\runpy.py:196 in _run_module_as_main    │
│                                                                                                  │
│   193 │   main_globals = sys.modules["__main__"].__dict__                                        │
│   194 │   if alter_argv:                                                                         │
│   195 │   │   sys.argv[0] = mod_spec.origin                                                      │
│ ❱ 196 │   return _run_code(code, main_globals, None,                                             │
│   197 │   │   │   │   │    "__main__", mod_spec)                                                 │
│   198                                                                                            │
│   199 def run_module(mod_name, init_globals=None,                                                │
│                                                                                                  │
│ C:\Users\XXX\AppData\Local\Programs\Python\Python310\lib\runpy.py:86 in _run_code               │
│                                                                                                  │
│    83 │   │   │   │   │      __loader__ = loader,                                                │
│    84 │   │   │   │   │      __package__ = pkg_name,                                             │
│    85 │   │   │   │   │      __spec__ = mod_spec)                                                │
│ ❱  86 │   exec(code, run_globals)                                                                │
│    87 │   return run_globals                                                                     │
│    88                                                                                            │
│    89 def _run_module_code(code, init_globals=None,                                              │
│                                                                                                  │
│                                     ... 24 frames hidden ...                                     │
│                                                                                                  │
│ C:\Users\XXX\AppData\Local\Programs\Python\Python310\lib\site-packages\aiohttp\connector.py:120 │
│ 0 in _create_direct_connection                                                                   │
│                                                                                                  │
│   1197 │   │   │   )                                                                             │
│   1198 │   │   │                                                                                 │
│   1199 │   │   │   try:                                                                          │
│ ❱ 1200 │   │   │   │   transp, proto = await self._wrap_create_connection(                       │
│   1201 │   │   │   │   │   self._factory,                                                        │
│   1202 │   │   │   │   │   host,                                                                 │
│   1203 │   │   │   │   │   port,                                                                 │
│                                                                                                  │
│ C:\Users\XXX\AppData\Local\Programs\Python\Python310\lib\site-packages\aiohttp\connector.py:990 │
│ in _wrap_create_connection                                                                       │
│                                                                                                  │
│    987 │   │   │   ):                                                                            │
│    988 │   │   │   │   return await self._loop.create_connection(*args, **kwargs)                │
│    989 │   │   except cert_errors as exc:                                                        │
│ ❱  990 │   │   │   raise ClientConnectorCertificateError(req.connection_key, exc) from exc       │
│    991 │   │   except ssl_errors as exc:                                                         │
│    992 │   │   │   raise ClientConnectorSSLError(req.connection_key, exc) from exc               │
│    993 │   │   except OSError as exc:                                                            │
╰──────────────────────────────────────────────────────────────────────────────────────────────────╯
ClientConnectorCertificateError: Cannot connect to host cdnt-proxy-8.dzcdn.net:443 ssl:True [SSLCertVerificationError:
(1, '[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: certificate has expired (_ssl.c:997)')]

Config File

Default with just arl set to actual value and quality to 1

Operating System

Windows 10 (Python 3.10.6)

streamrip version

rip, version 2.0.5

Screenshots and recordings

No response

Additional context

No response

apostoiis commented 2 months ago

@MorisatoK can you elaborate on how you downgraded plz?

MorisatoK commented 2 months ago

@MorisatoK can you elaborate on how you downgraded plz?

I think I used pip3 install streamrip==1.9.7 --upgrade

mortalis13 commented 2 months ago

Maybe it's something about the relation of PC config (like some ssl libraries installed) + python version + network specifics. I can download from Deezer normally with the latest version or from the dev branch.

I'd suggest trying with different python versions, 3.11, 3.12, and clean versions, preferably with venv to keep it all isolated.

And for those who has time and are willing to experiment (or for the repo author), I'd create a simple script trying to connect directly to the target URL, but not to cdnt I guess, just to isolate better the case. And also try that script in different environments, maybe even from a virtual machine, or other PC if possible.

I don't think the test with browser accessing that URL from the error directly is useful here. Though it's interesting that the validity of the certificate has ended...

Also, does it happen just with any Deezer URL, for track or album? Or only specific ones?

MorisatoK commented 2 months ago

I finally had some time for testing. I uninstalled Python and reinstalled the latest 3.12.4. Created a venv just for streamrip. And it works without the mentioned errors now. Thank you.

I might consider downgrading again however, because of how the overall behaviour of the new version has changed in regards to my workflow.