From 43c5307d52b161782f3a71a54765e2ebfe38e454 Mon Sep 17 00:00:00 2001 From: moonlight824 Date: Mon, 15 Dec 2025 16:19:56 +0800 Subject: [PATCH 1/4] add support for remote usbmux --- wda/__init__.py | 2 +- wda/usbmux/__init__.py | 5 +++++ wda/usbmux/pyusbmux.py | 9 +++++---- 3 files changed, 11 insertions(+), 5 deletions(-) diff --git a/wda/__init__.py b/wda/__init__.py index d011b8f..7fd47d7 100644 --- a/wda/__init__.py +++ b/wda/__init__.py @@ -222,7 +222,7 @@ def __init__(self, url=None, _session_id=None): """ if not url: url = os.environ.get('DEVICE_URL', 'http://localhost:8100') - assert re.match(r"^(http\+usbmux|https?)://", url), "Invalid URL: %r" % url + assert re.match(r"^(http\+usbmux|http\+usbmux\+remote|https?)://", url), "Invalid URL: %r" % url # Session variable self.__wda_url = url diff --git a/wda/usbmux/__init__.py b/wda/usbmux/__init__.py index b2dce4b..a634592 100644 --- a/wda/usbmux/__init__.py +++ b/wda/usbmux/__init__.py @@ -19,6 +19,11 @@ def http_create(url: str) -> HTTPConnection: udid, device_wda_port = u.netloc.split(":") device = select_device(udid) return device.make_http_connection(int(device_wda_port)) + elif u.scheme == "http+usbmux+remote": + remote_ip, remote_port, udid, device_wda_port = u.netloc.split(":") + usbmux_address = f"{remote_ip}:{remote_port}" + device = select_device(udid, usbmux_address=usbmux_address) + return device.make_http_connection(int(device_wda_port), usbmux_address=usbmux_address) elif u.scheme == "http": return HTTPConnection(u.netloc) elif u.scheme == "https": diff --git a/wda/usbmux/pyusbmux.py b/wda/usbmux/pyusbmux.py index b984a40..4365a5c 100644 --- a/wda/usbmux/pyusbmux.py +++ b/wda/usbmux/pyusbmux.py @@ -109,8 +109,8 @@ def is_network(self) -> bool: def matches_udid(self, udid: str) -> bool: return self.serial.replace('-', '') == udid.replace('-', '') - def make_http_connection(self, port: int) -> HTTPConnection: - return USBMuxHTTPConnection(self, port) + def make_http_connection(self, port: int, usbmux_address: Optional[str] = None) -> HTTPConnection: + return USBMuxHTTPConnection(self, port, usbmux_address=usbmux_address) class SafeStreamSocket: @@ -470,13 +470,14 @@ def select_devices_by_connection_type(connection_type: str, usbmux_address: Opti class USBMuxHTTPConnection(HTTPConnection): - def __init__(self, device: MuxDevice, port=8100): + def __init__(self, device: MuxDevice, port=8100, usbmux_address: Optional[str] = None): super().__init__("localhost", port) self.__device = device self.__port = port + self.__usbmux_address = usbmux_address def connect(self): - self.sock = self.__device.connect(self.__port) + self.sock = self.__device.connect(self.__port, self.__usbmux_address) def __enter__(self) -> HTTPConnection: return self From 41b36058e9d72a190de0888adc439e34348ebd17 Mon Sep 17 00:00:00 2001 From: moonlight824 Date: Wed, 17 Dec 2025 12:09:09 +0800 Subject: [PATCH 2/4] close http connection at the end of fetch method --- wda/usbmux/__init__.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/wda/usbmux/__init__.py b/wda/usbmux/__init__.py index a634592..5483a80 100644 --- a/wda/usbmux/__init__.py +++ b/wda/usbmux/__init__.py @@ -72,6 +72,8 @@ def fetch(url: str, method="GET", data=None, timeout=None, chunk_size: int = _DE return resp except Exception as e: raise HTTPError(e) + finally: + conn.close() def _read_response(response:HTTPResponse, chunk_size: int = _DEFAULT_CHUNK_SIZE) -> bytearray: From 30ed95249a0a43b16445e6f09a90c1658a813bab Mon Sep 17 00:00:00 2001 From: moonlight824 Date: Fri, 19 Dec 2025 14:44:27 +0800 Subject: [PATCH 3/4] fix: check http connection existed before close it --- wda/usbmux/__init__.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/wda/usbmux/__init__.py b/wda/usbmux/__init__.py index 5483a80..e646a02 100644 --- a/wda/usbmux/__init__.py +++ b/wda/usbmux/__init__.py @@ -55,6 +55,7 @@ def fetch(url: str, method="GET", data=None, timeout=None, chunk_size: int = _DE Raises: HTTPError """ + conn = None try: method = method.upper() conn = http_create(url) @@ -73,7 +74,8 @@ def fetch(url: str, method="GET", data=None, timeout=None, chunk_size: int = _DE except Exception as e: raise HTTPError(e) finally: - conn.close() + if conn: + conn.close() def _read_response(response:HTTPResponse, chunk_size: int = _DEFAULT_CHUNK_SIZE) -> bytearray: From 39710490333a4ecd0849418ccdc33647e9ba4883 Mon Sep 17 00:00:00 2001 From: moonlight824 Date: Fri, 19 Dec 2025 14:56:36 +0800 Subject: [PATCH 4/4] using a clearer URL for device connected to remote usbmux --- wda/usbmux/__init__.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/wda/usbmux/__init__.py b/wda/usbmux/__init__.py index e646a02..c8c71cb 100644 --- a/wda/usbmux/__init__.py +++ b/wda/usbmux/__init__.py @@ -20,8 +20,8 @@ def http_create(url: str) -> HTTPConnection: device = select_device(udid) return device.make_http_connection(int(device_wda_port)) elif u.scheme == "http+usbmux+remote": - remote_ip, remote_port, udid, device_wda_port = u.netloc.split(":") - usbmux_address = f"{remote_ip}:{remote_port}" + device_info, usbmux_address = u.netloc.split("@") + udid, device_wda_port = device_info.split(":") device = select_device(udid, usbmux_address=usbmux_address) return device.make_http_connection(int(device_wda_port), usbmux_address=usbmux_address) elif u.scheme == "http":