Skip to content

Commit f77047f

Browse files
committed
webext: Rewrite native app starting logic
Using asyncio.run is preferred by Python. `asyncio.get_event_loop` raises a `RuntimeError` on my machine, which means that there is no event loop set. This is a change in 3.14, seems that we need to use `asyncio.set_event_loop` before running. So I use `asyncio.run` directly to avoid this. Handle `SIGTERM` signal so we can quit gracefully. Firefox will send `SIGTERM` on *nix systems, and use Windows's way to kill the native app. Not using Windows so not sure if `SIGTERM` will also be raised on Windows, but I do not find a clean way to notify killing. See also: https://docs.python.org/3.14/library/asyncio-eventloop.html#asyncio.get_event_loop https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/Native_messaging#closing_the_native_app
1 parent a6679dd commit f77047f

1 file changed

Lines changed: 24 additions & 20 deletions

File tree

webext/app/credential_manager_shim.py

Lines changed: 24 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
from enum import Enum
88
import json
99
import logging
10+
import signal
1011
import struct
1112
import sys
1213
from typing import Optional
@@ -395,23 +396,26 @@ async def run(cmd, options, origin, top_origin):
395396
raise Exception(f"unknown cmd: {cmd}")
396397

397398

398-
logging.info("starting credential_manager_shim")
399-
while True:
400-
logging.debug("starting event loop message")
401-
receivedMessage = getMessage()
402-
request_id = receivedMessage["requestId"]
403-
try:
404-
cmd = receivedMessage["cmd"]
405-
406-
options = None
407-
if "options" in receivedMessage:
408-
options = receivedMessage["options"]
409-
origin = receivedMessage["origin"]
410-
top_origin = receivedMessage["topOrigin"]
411-
loop = asyncio.get_event_loop()
412-
auth_data = loop.run_until_complete(run(cmd, options, origin, top_origin))
413-
sendMessage(encodeMessage({"requestId": request_id, "data": auth_data}))
414-
except Exception as e:
415-
logging.error("Failed to send message", exc_info=e)
416-
sendMessage(encodeMessage({"requestId": request_id, "error": str(e)}))
417-
logging.debug("Sent error message")
399+
quit = asyncio.Event()
400+
401+
async def main():
402+
logging.info("starting credential_manager_shim")
403+
while not quit.is_set():
404+
logging.debug("starting event loop message")
405+
receivedMessage = getMessage()
406+
request_id = receivedMessage["requestId"]
407+
try:
408+
cmd = receivedMessage["cmd"]
409+
options = receivedMessage.get("options", None)
410+
origin = receivedMessage["origin"]
411+
top_origin = receivedMessage["topOrigin"]
412+
auth_data = await run(cmd, options, origin, top_origin)
413+
sendMessage(encodeMessage({"requestId": request_id, "data": auth_data}))
414+
except Exception as e:
415+
logging.error("Failed to send message", exc_info=e)
416+
sendMessage(encodeMessage({"requestId": request_id, "error": str(e)}))
417+
logging.debug("Sent error message")
418+
logging.info("quitting credential_manager_shim")
419+
420+
signal.signal(signal.SIGTERM, lambda _, __ : quit.set())
421+
asyncio.run(main())

0 commit comments

Comments
 (0)