SslAesTransport: handshake again when a camera answers 401 to passthrough (#1771)
Some checks failed
CI / Perform Lint Checks (3.14) (push) Has been cancelled
CI / Python 3.11 on macos-latest (push) Has been cancelled
CI / Python 3.12 on macos-latest (push) Has been cancelled
CI / Python 3.13 on macos-latest (push) Has been cancelled
CI / Python 3.14 on macos-latest (push) Has been cancelled
CI / Python 3.11 on ubuntu-latest (push) Has been cancelled
CI / Python 3.12 on ubuntu-latest (push) Has been cancelled
CI / Python 3.13 on ubuntu-latest (push) Has been cancelled
CI / Python 3.14 on ubuntu-latest (push) Has been cancelled
CI / Python 3.11 on windows-latest (push) Has been cancelled
CI / Python 3.12 on windows-latest (push) Has been cancelled
CI / Python 3.13 on windows-latest (push) Has been cancelled
CI / Python 3.14 on windows-latest (push) Has been cancelled
CodeQL Checks / Analyze (python) (push) Has been cancelled
Stale / stale (push) Has been cancelled

Some cameras (C220 and C100 on the 1.4.4 line in those reports) drop the
session about every ten minutes and answer the next `securePassthrough`
with HTTP 401 and `-40421` in the body.

With this change a 401 on passthrough marks the transport as needing a
handshake and raises `_RetryableError`, so the protocol logs in again
and retries the same request.

---------

Co-authored-by: freeKC <7538438+freeKC@users.noreply.github.com>
This commit is contained in:
FreeKC
2026-10-03 18:19:40 +02:00
committed by GitHub
parent 998ebe79e8
commit b0d77b35a2
2 changed files with 35 additions and 0 deletions

View File

@@ -274,6 +274,20 @@ class SslAesTransport(BaseTransport):
_LOGGER.debug(msg)
raise _RetryableError(msg)
# Some devices answer 401 when the session has expired and they
# require a new handshake: reauthenticate and retry the request.
if status_code == 401:
_LOGGER.debug(
"Device %s replied with status 401 to passthrough, "
"session expired, handshake required",
self._host,
)
self._state = TransportState.HANDSHAKE_REQUIRED
raise _RetryableError(
f"{self._host} responded with status 401 to passthrough, "
"session expired"
)
if status_code != 200:
raise KasaException(
f"{self._host} responded with an unexpected "