Update AppImage

This commit is contained in:
MacRimi
2026-05-24 11:37:20 +02:00
parent 4b934db7db
commit 105576cf17
7 changed files with 140 additions and 59 deletions
+14
View File
@@ -11789,6 +11789,20 @@ if __name__ == '__main__':
# `::` binds IPv6 + IPv4 (v4-mapped) on Linux when
# net.ipv6.bindv6only=0 (the default). Issue #192 — IPv4-only
# listening broke ProxMenux on dual-stack / v6-only hosts.
#
# NOTE: a prior version subclassed WSGIServer here to
# silence SSL handshake errors (memory leak workaround
# for clients opening ws:// against this https endpoint).
# The subclass interfered with gevent's SSL flow-control
# exceptions (SSLWantReadError) and caused
# ConcurrentObjectUseError on the wss handshake of
# /ws/script/<id>, which manifested only on clients that
# close the WS connection mid-handshake (iPad Safari for
# the updates modal). Since the root cause of the memory
# leak was fixed client-side in lib/terminal-ws.ts
# (getWsUrl now opens wss:// instead of ws:// against
# the https endpoint), the original SSL handshake errors
# are rare and the default gevent behaviour is fine.
server = pywsgi.WSGIServer(
('::', 8008),
app,
+11 -4
View File
@@ -39,13 +39,20 @@ _SAFE_ID_RE = re.compile(r'^[A-Za-z0-9_-]{1,64}$')
# atomically consumes the ticket — if the ticket is missing, expired, or
# already used, the WS is closed immediately.
#
# Tickets live in an in-memory dict guarded by a lock. TTL is intentionally
# short (5 s) — the client should issue and use the ticket immediately.
# See audit Tier 1 #2 + #17d.
# Tickets live in an in-memory dict guarded by a lock. The TTL is the
# window between POST /api/terminal/ticket and the WebSocket handshake
# that consumes it. The original 5 s was too tight for slower devices:
# on an iPad opening the post-install updates modal, xterm.js + the
# Nerd Font load took >5 s, the ticket expired before the wss handshake
# fired, and the modal hung at "Conectando" indefinitely — exactly the
# bug pattern that pushed the gevent server into the 4.4 GB OOM spiral.
# 60 s is wide enough to absorb mobile-rendering delays while still
# being one-shot (each ticket can only be consumed once), so the
# security model from audit Tier 1 #2 + #17d is unchanged.
_TERMINAL_TICKETS = {} # ticket (str) -> created_at_ts (float)
_TICKETS_LOCK = threading.Lock()
_TICKET_TTL = 5 # seconds
_TICKET_TTL = 60 # seconds
_TICKET_MAX_INFLIGHT = 256 # sanity cap to keep memory bounded