diff --git a/mopidy_bandcamp/bandcamp.py b/mopidy_bandcamp/bandcamp.py index ff8c737..7d0b866 100644 --- a/mopidy_bandcamp/bandcamp.py +++ b/mopidy_bandcamp/bandcamp.py @@ -2,11 +2,38 @@ import json import mopidy_bandcamp import re import requests +import ssl from html import unescape from mopidy import httpclient from time import time +from requests.adapters import HTTPAdapter +class BandcampHTTPAdapter(HTTPAdapter): + def init_poolmanager(self, *args, **kwargs): + context = ssl.create_default_context() + DEFAULT_CIPHERS = ":".join( + [ + "ECDHE+AESGCM", + "ECDHE+CHACHA20", + "DHE+AESGCM", + "DHE+CHACHA20", + "ECDH+AESGCM", + "DH+AESGCM", + "ECDH+AES", + "DH+AES", + "RSA+AESGCM", + "RSA+AES", + "!aNULL", + "!eNULL", + "!MD5", + "!DSS", + "!AESCCM", + ] + ) + context.set_ciphers(DEFAULT_CIPHERS) + kwargs["ssl_context"] = context + return super().init_poolmanager(*args, **kwargs) class BandcampClient: BASE_URL = "https://bandcamp.com/api" @@ -43,6 +70,8 @@ class BandcampClient: } def __init__(self, config): + self.bandcamp_session = requests.Session() + self.bandcamp_session.mount("https://", BandcampHTTPAdapter()) self.proxy = httpclient.format_proxy(config["proxy"]) self.ua_str = httpclient.format_user_agent( f"{mopidy_bandcamp.Extension.dist_name}/{mopidy_bandcamp.__version__}" @@ -53,7 +82,7 @@ class BandcampClient: def _get(self, *args, **kwargs): headers = {"User-Agent": self.ua_str} - resp = requests.get(*args, **kwargs, headers=headers, proxies=self.proxy) + resp = self.bandcamp_session.get(*args, **kwargs, headers=headers, proxies=self.proxy) resp.raise_for_status() js = resp.json() if "error" in js: @@ -62,7 +91,7 @@ class BandcampClient: def _post(self, *args, **kwargs): headers = {"User-Agent": self.ua_str} - resp = requests.post(*args, **kwargs, headers=headers, proxies=self.proxy) + resp = self.bandcamp_session.post(*args, **kwargs, headers=headers, proxies=self.proxy) resp.raise_for_status() js = resp.json() if "error" in js: @@ -73,7 +102,7 @@ class BandcampClient: headers = {"User-Agent": self.ua_str} if self.identity: headers["Cookie"] = f"identity={self.identity}" - resp = requests.get(uri, headers=headers, proxies=self.proxy) + resp = self.bandcamp_session.get(uri, headers=headers, proxies=self.proxy) resp.raise_for_status() # Build the tralbum data by joining multiple json chunks. data = re.search(r'\s+data-tralbum="(.*?)"', resp.text) @@ -127,7 +156,7 @@ class BandcampClient: return [] headers = {"User-Agent": self.ua_str, "Cookie": f"identity={self.identity}"} if self.fan_id is None: - resp = requests.get( + resp = self.bandcamp_session.get( self.BASE_URL + "/fan/2/collection_summary", headers=headers, proxies=self.proxy, @@ -141,7 +170,7 @@ class BandcampClient: endpoint = "wishlist_items" elif ctype == "following": endpoint = "following_bands" - resp = requests.post( + resp = self.bandcamp_session.post( self.BASE_URL + "/fancollection/1/" + endpoint, headers=headers, proxies=self.proxy,