diff --git a/librespot/zeroconf.py b/librespot/zeroconf.py index 038aa8e..0c00a25 100644 --- a/librespot/zeroconf.py +++ b/librespot/zeroconf.py @@ -62,21 +62,27 @@ class ZeroconfServer(Closeable): if listen_port == -1: listen_port = random.randint(self.__min_port + 1, self.__max_port) self.__runner = ZeroconfServer.HttpRunner(self, listen_port) - threading.Thread(target=self.__runner.run, name="zeroconf-http-server").start() + threading.Thread(target=self.__runner.run, + name="zeroconf-http-server").start() self.__zeroconf = zeroconf.Zeroconf() self.__service_info = zeroconf.ServiceInfo( ZeroconfServer.service, inner.device_name + "." + ZeroconfServer.service, - listen_port, 0, 0, { + listen_port, + 0, + 0, { "CPath": "/", "VERSION": "1.0", "STACK": "SP", }, self.get_useful_hostname() + ".", - addresses=[socket.inet_aton(socket.gethostbyname(self.get_useful_hostname()))] - ) + addresses=[ + socket.inet_aton( + socket.gethostbyname(self.get_useful_hostname())) + ]) self.__zeroconf.register_service(self.__service_info) - threading.Thread(target=self.__zeroconf.start, name="zeroconf-multicast-dns-server").start() + threading.Thread(target=self.__zeroconf.start, + name="zeroconf-multicast-dns-server").start() def close(self) -> None: self.__zeroconf.close() @@ -89,7 +95,8 @@ class ZeroconfServer(Closeable): else: return host - def handle_add_user(self, __socket: socket.socket, params: dict[str, str], http_version: str) -> None: + def handle_add_user(self, __socket: socket.socket, params: dict[str, str], + http_version: str) -> None: username = params.get("userName") if not username: logging.error("Missing userName!") @@ -103,13 +110,16 @@ class ZeroconfServer(Closeable): logging.error("Missing clientKey!") with self.__connection_lock: if username == self.__connecting_username: - logging.info("{} is already trying to connect.".format(username)) + logging.info( + "{} is already trying to connect.".format(username)) __socket.send(http_version.encode()) __socket.send(b" 403 Forbidden") __socket.send(self.__eol) __socket.send(self.__eol) return - shared_key = util.int_to_bytes(self.__keys.compute_shared_key(base64.b64decode(client_key_str.encode()))) + shared_key = util.int_to_bytes( + self.__keys.compute_shared_key( + base64.b64decode(client_key_str.encode()))) blob_bytes = base64.b64decode(blob_str) iv = blob_bytes[:16] encrypted = blob_bytes[16:len(blob_bytes) - 20] @@ -137,7 +147,8 @@ class ZeroconfServer(Closeable): decrypted = aes.decrypt(encrypted) with self.__connection_lock: self.__connecting_username = username - logging.info("Accepted new user from {}. [deviceId: {}]".format(params.get("deviceName"), self.__inner.device_id)) + logging.info("Accepted new user from {}. [deviceId: {}]".format( + params.get("deviceName"), self.__inner.device_id)) response = json.dumps(self.__default_successful_add_user) __socket.send(http_version.encode()) __socket.send(b" 200 OK") @@ -157,14 +168,18 @@ class ZeroconfServer(Closeable): with self.__connection_lock: self.__connecting_username = None - def handle_get_info(self, __socket: socket.socket, http_version: str) -> None: + def handle_get_info(self, __socket: socket.socket, + http_version: str) -> None: info = copy.deepcopy(self.__default_get_info_fields) info["device_id"] = self.__inner.device_id info["remoteName"] = self.__inner.device_name - info["publicKey"] = base64.b64encode(self.__keys.public_key_bytes()).decode() + info["publicKey"] = base64.b64encode( + self.__keys.public_key_bytes()).decode() info["deviceType"] = Connect.DeviceType.Name(self.__inner.device_type) with self.__connection_lock: - info["activeUser"] = self.__connecting_username if self.__connecting_username is not None else self.__session.username() if self.has_valid_session() else "" + info[ + "activeUser"] = self.__connecting_username if self.__connecting_username is not None else self.__session.username( + ) if self.has_valid_session() else "" def has_valid_session(self) -> bool: valid = self.__session and self.__session.is_valid() @@ -203,13 +218,15 @@ class ZeroconfServer(Closeable): def anonymous(): self.__handle(__socket) __socket.close() + self.__worker.submit(anonymous) def __handle(self, __socket: socket.socket) -> None: request = io.BytesIO(__socket.recv(1024 * 1024)) request_line = request.readline().split(b" ") if len(request_line) != 3: - logging.warning("Unexpected request line: {}".format(request_line)) + logging.warning( + "Unexpected request line: {}".format(request_line)) method = request_line[0].decode() path = request_line[1].decode() http_version = request_line[2].decode() @@ -221,7 +238,9 @@ class ZeroconfServer(Closeable): split = header.split(b":") headers[split[0].decode()] = split[1].strip().decode() if not self.__zeroconf_server.has_valid_session(): - logging.debug("Handling request: {}, {}, {}, headers: {}".format(method, path, http_version, headers)) + logging.debug( + "Handling request: {}, {}, {}, headers: {}".format( + method, path, http_version, headers)) params = {} if method == "POST": content_type = headers.get("Content-Type") @@ -237,7 +256,8 @@ class ZeroconfServer(Closeable): pairs = body.split("&") for pair in pairs: split = pair.split("=") - params[urllib.parse.unquote(split[0])] = urllib.parse.unquote(split[1]) + params[urllib.parse.unquote( + split[0])] = urllib.parse.unquote(split[1]) else: params = self.__zeroconf_server.parse_path(path) action = params.get("action") @@ -246,12 +266,12 @@ class ZeroconfServer(Closeable): return self.handle_request(__socket, http_version, action, params) - def handle_request(self, __socket: socket.socket, http_version: str, action: str, params: dict[str, str]) -> None: + def handle_request(self, __socket: socket.socket, http_version: str, + action: str, params: dict[str, str]) -> None: if action == "addUser": if params is None: raise RuntimeError - class Inner: conf: typing.Final[Session.Configuration] device_name: typing.Final[str] @@ -259,9 +279,12 @@ class ZeroconfServer(Closeable): device_type: typing.Final[Connect.DeviceType] preferred_locale: typing.Final[str] - def __init__(self, device_type: Connect.DeviceType, device_name: str, device_id: str, preferred_locale: str, conf: Session.Configuration): + def __init__(self, device_type: Connect.DeviceType, device_name: str, + device_id: str, preferred_locale: str, + conf: Session.Configuration): self.conf = conf self.device_name = device_name - self.device_id = util.random_hex_string(40).lower() if device_id else device_id + self.device_id = util.random_hex_string( + 40).lower() if device_id else device_id self.device_type = device_type self.preferred_locale = preferred_locale