fix: threaded HTTP server so the RAM modal progress is live (v3.6.39)
__main__ built a plain HTTPServer (single-threaded): during a RAM install POST every other request waited in the accept queue, including the 2 s /api/status poll that feeds the operation modal - its bar and step headline never moved and the whole result appeared only at the end (live 2026-09-29). _build_http_server() now returns a ThreadingHTTPServer (daemon threads). Card access is unchanged: it is serialized by _CARD_LOCK, not by the server - every POST is blanket-wrapped in do_POST, every /api/ GET except /api/status and /api/test/status is wrapped in do_GET, and the background threads (STATUS poll, _bip_data_available, test runner) take the lock; the audit found no card-access holes. do_GET also lets non-/api (static PWA) paths bypass the lock, so page assets stay answerable during long operations. Regression test tests/test_http_concurrency.py: a fast request must complete while a slow one is in flight (fails on HTTPServer with exactly the reported symptom: 1.01 s vs 0.20 s); test_startup_cardless patches the new factory. sw cache simple-v312; tests: 519 Python / 674 Node.
This commit is contained in:
@@ -31,7 +31,7 @@ from osmocom.tlv import BER_TLV_IE
|
||||
from osmocom.utils import rpad
|
||||
|
||||
|
||||
VERSION = '3.6.38'
|
||||
VERSION = '3.6.39'
|
||||
|
||||
MAX_ENVELOPE_SEGMENTS = 5 # max SMS segments for outgoing C-APDU in ENVELOPE
|
||||
|
||||
@@ -5328,7 +5328,11 @@ class PysimHandler(BaseHTTPRequestHandler):
|
||||
# keeping them out of the lock lets the UI report 'initializing' while a
|
||||
# long equip (or a test script step) holds the card lock. Result-shaping
|
||||
# masks everything card-derived when the session is not connected.
|
||||
if self.path in ('/api/status', '/api/test/status'):
|
||||
# Static PWA files are card-free too: they must stay answerable while a
|
||||
# long card operation holds the lock (the server is threaded, so this
|
||||
# bypass is what actually serves the modal's progress poll and page
|
||||
# assets during a RAM install).
|
||||
if self.path in ('/api/status', '/api/test/status') or not self.path.startswith('/api/'):
|
||||
self._do_GET()
|
||||
return
|
||||
# Serialize all card access: the background STATUS poll runs in its own
|
||||
|
||||
Reference in New Issue
Block a user