From 0f2ab4b4de7e828757091e323be1caab0a70b770 Mon Sep 17 00:00:00 2001 From: Omar Rizwan Date: Mon, 8 Feb 2021 13:45:26 -0800 Subject: [PATCH] safari: fix some races when you reload Web inspector, make ws connection retry --- extension/background.js | 25 ++++++++++---- extension/safari/README.md | 10 ++++-- .../SafariWebExtensionHandler.swift | 17 ++++++---- .../UserInterfaceState.xcuserstate | Bin 61961 -> 64115 bytes extension/safari/TabFS/TabFSServer/main.swift | 9 ++--- .../TabFS/TabFSService/TabFSService.swift | 31 +++++++++++++++--- 6 files changed, 68 insertions(+), 24 deletions(-) diff --git a/extension/background.js b/extension/background.js index 62ec7d0..e31a4c4 100644 --- a/extension/background.js +++ b/extension/background.js @@ -720,15 +720,26 @@ function tryConnect() { if (chrome.runtime.getURL('/').startsWith('safari-web-extension://')) { // Safari-only chrome.runtime.sendNativeMessage('com.rsnous.tabfs', {op: 'safari_did_connect'}, resp => { console.log(resp); - const socket = new WebSocket('ws://localhost:9991'); - socket.addEventListener('message', event => { - onMessage(JSON.parse(event.data)); - }); + let socket; + function connectSocket(checkAfterTime) { + socket = new WebSocket('ws://localhost:9991'); + socket.addEventListener('message', event => { + onMessage(JSON.parse(event.data)); + }); - port = { postMessage(message) { - socket.send(JSON.stringify(message)); - } }; + port = { postMessage(message) { + socket.send(JSON.stringify(message)); + } }; + + setTimeout(() => { + if (socket.readyState !== 1) { + console.log('ws connection failed, retrying in', checkAfterTime); + connectSocket(checkAfterTime * 2); + } + }, checkAfterTime); + } + connectSocket(200); }); return; } diff --git a/extension/safari/README.md b/extension/safari/README.md index 9ceafdc..8a47d23 100644 --- a/extension/safari/README.md +++ b/extension/safari/README.md @@ -24,8 +24,12 @@ it's mounted. ### tips - To open Web inspector: Safari -> Develop menu -> Web Extension - Background Pages -> TabFS + Background Pages -> TabFS. -- You need to rebuild if you change background.js. This is pretty - annoying. + Refreshing this inspector should reload the tabfs filesystem, also. + +- You need to rebuild in Xcode any time you change background.js + (because the extension files are copied into the extension, rather + than running directly from folder as in Firefox and Chrome). This is + pretty annoying. diff --git a/extension/safari/TabFS/TabFS Extension/SafariWebExtensionHandler.swift b/extension/safari/TabFS/TabFS Extension/SafariWebExtensionHandler.swift index 75790fa..dc30cc4 100644 --- a/extension/safari/TabFS/TabFS Extension/SafariWebExtensionHandler.swift +++ b/extension/safari/TabFS/TabFS Extension/SafariWebExtensionHandler.swift @@ -17,16 +17,20 @@ class SafariWebExtensionHandler: NSObject, NSExtensionRequestHandling { guard message["op"] as! String == "safari_did_connect" else { return } - // The XPC service is a subprocess that lives outside the macOS App Sandbox. + // The XPC service is a process that can live outside the macOS App Sandbox. // (Safari extension native code, including this file, has to live in the sandbox.) // It can do forbidden things like spawn tabfs filesystem and set up WebSocket server. - // We only use one native message to bootstrap the XPC service, then do all communications - // to that service (which in turn talks to tabfs.c) over WebSocket instead. + // We only use one native message, to bootstrap the XPC service (TabFSService). + // Then the XPC service starts TabFSServer. TabFSServer is separate because + // XPC services get killed by the OS after a minute or two; TabFSServer + // is just a normal process that can live on. It talks straight + // to background.js (which in turn talks to tabfs.c) over a WebSocket. + // (Safari makes doing native messaging quite painful, so we try to avoid it. // It forces the browser to pop to front if you message Safari in the obvious way, // for instance: https://developer.apple.com/forums/thread/122232 - // And with the WebSocket, the XPC service can talk straight to background.js, whereas + // And with the WebSocket, the server can talk straight to background.js, whereas // native messaging would require us here to sit in the middle.) let connection = NSXPCConnection(serviceName: "com.rsnous.TabFSService") @@ -44,8 +48,9 @@ class SafariWebExtensionHandler: NSObject, NSExtensionRequestHandling { // FIXME: report port back? let response = NSExtensionItem() response.userInfo = [ "message": "alive" ] - // This response (over native messaging) prompts background.js to - // connect to the WebSocket server that the XPC service should now be running. + // This response (over native messaging) will prompt background.js to + // connect to the WebSocket server of TabFSServer, which should + // now be running. context.completeRequest(returningItems: [response]) { (what) in print(what) } diff --git a/extension/safari/TabFS/TabFS.xcodeproj/project.xcworkspace/xcuserdata/osnr.xcuserdatad/UserInterfaceState.xcuserstate b/extension/safari/TabFS/TabFS.xcodeproj/project.xcworkspace/xcuserdata/osnr.xcuserdatad/UserInterfaceState.xcuserstate index db4d28a4586d55fe2fec66a1786a1afbb034a065..96586efa5188d1811771b04dc6e136c4b0a21815 100644 GIT binary patch delta 27086 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 OzwR6V*Z)uU+W!CrNn5)B delta 25886 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 diff --git a/extension/safari/TabFS/TabFSServer/main.swift b/extension/safari/TabFS/TabFSServer/main.swift index 245bfb1..76da2a0 100644 --- a/extension/safari/TabFS/TabFSServer/main.swift +++ b/extension/safari/TabFS/TabFSServer/main.swift @@ -75,8 +75,9 @@ class TabFSServer { func read() { conn.receiveMessage { (resp, context, isComplete, err) in guard let resp = resp else { - // FIXME err - os_log(.default, "resp error: %{public}@", err!.debugDescription as CVarArg) + if let err = err { + os_log(.default, "resp error: %{public}@", err.debugDescription as CVarArg) + } return } @@ -104,10 +105,10 @@ class TabFSServer { } } - // FIXME: notify - + print("OK") } } let server = TabFSServer() + dispatchMain() diff --git a/extension/safari/TabFS/TabFSService/TabFSService.swift b/extension/safari/TabFS/TabFSService/TabFSService.swift index 4a86dd6..5bf55ee 100644 --- a/extension/safari/TabFS/TabFSService/TabFSService.swift +++ b/extension/safari/TabFS/TabFSService/TabFSService.swift @@ -12,13 +12,36 @@ import os.log class TabFSService: NSObject, TabFSServiceProtocol { func start(withReply reply: @escaping () -> Void) { // This XPC call is enough to just force the XPC service to be started. - os_log("HELLO") + + // kill old copies of TabFSServer + let killall = Process() + killall.launchPath = "/usr/bin/killall" + killall.arguments = ["TabFSServer"] + killall.launch() + killall.waitUntilExit() + + // spin until old TabFSServer (if any) is gone + while true { + let pgrep = Process() + pgrep.launchPath = "/usr/bin/pgrep" + pgrep.arguments = ["TabFSServer"] + pgrep.launch() + pgrep.waitUntilExit() + if pgrep.terminationStatus != 0 { break } + + Thread.sleep(forTimeInterval: 0.01) + } + let server = Process() - os_log("HOW ARE YOU?") + let serverOutput = Pipe() server.executableURL = Bundle.main.url(forResource: "TabFSServer", withExtension: "")! - os_log("I AM GOOD") + server.standardOutput = serverOutput server.launch() - os_log("GREAT") + + // FIXME: should we wait for some signal that the server is ready? + // right now, background.js will just periodically retry until it can connect. + + // tell background.js to try to connect. reply() } }