From 306e68798856a2f08acf59378921098582b6c1cd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D0=BD=D0=B4=D1=80=D0=B5=D0=B9=20=D0=91=D0=BE=D0=B1?= =?UTF-8?q?=D1=8B=D1=80=D0=B5=D0=B2?= Date: Fri, 22 May 2026 03:22:25 +0300 Subject: [PATCH] fix(keenetic): reset session after auth probe, retry 503 Probing used short timeouts on the session reused for RCI calls. Recreate the session after auth and treat 503 as transient. Co-authored-by: Cursor --- server/services/keenetic_client.py | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/server/services/keenetic_client.py b/server/services/keenetic_client.py index f0fcccb..1dc6d43 100644 --- a/server/services/keenetic_client.py +++ b/server/services/keenetic_client.py @@ -177,11 +177,12 @@ class KeeneticClient: ) return self._session - async def _reset_session(self): + async def _reset_session(self, *, keep_auth: bool = False): if self._session and not self._session.closed: await self._session.close() self._session = None - self._authenticated = False + if not keep_auth: + self._authenticated = False def _timeout_error_message(self) -> str: if is_public_ip_host(self._host_key): @@ -213,13 +214,16 @@ class KeeneticClient: async with session.get(auth_url, ssl=False) as resp: if resp.status == 200: self._authenticated = True + await self._reset_session(keep_auth=True) return True if resp.status != 401: if resp.status in (400, 403): self.last_error = "Wrong protocol or port (try http/https)" - else: - self.last_error = f"Auth HTTP {resp.status}" + return False + if resp.status in (502, 503, 504): + continue + self.last_error = f"Auth HTTP {resp.status}" logger.error( f"Keenetic auth unexpected status: {resp.status} @ {auth_url}" ) @@ -246,6 +250,7 @@ class KeeneticClient: ) as resp: if resp.status == 200: self._authenticated = True + await self._reset_session(keep_auth=True) return True self.last_error = "Wrong login or password" logger.error(f"Keenetic auth failed: {resp.status} @ {auth_url}")