summaryrefslogtreecommitdiff
path: root/extension/safari/TabFS/TabFSService
diff options
context:
space:
mode:
authorOmar Rizwan <omar@omar.website>2021-02-08 12:12:43 -0800
committerOmar Rizwan <omar@omar.website>2021-02-08 12:12:43 -0800
commit2f639e2a0276efb3dbb8a470e61ee8ffc2503f5b (patch)
treeb055805a6831b831c79627afaf35011e4f7e8a74 /extension/safari/TabFS/TabFSService
parent9b4abc40ee96711828fc6b0b425c5ea869a5f771 (diff)
downloadTabFS-2f639e2a0276efb3dbb8a470e61ee8ffc2503f5b.tar.gz
TabFS-2f639e2a0276efb3dbb8a470e61ee8ffc2503f5b.zip
safari: TabFSServer subprocess that can live long. fixes bug where fs would die after a minute or two
Diffstat (limited to 'extension/safari/TabFS/TabFSService')
-rw-r--r--extension/safari/TabFS/TabFSService/TabFSService.swift104
1 files changed, 7 insertions, 97 deletions
diff --git a/extension/safari/TabFS/TabFSService/TabFSService.swift b/extension/safari/TabFS/TabFSService/TabFSService.swift
index 86c39f8..4a86dd6 100644
--- a/extension/safari/TabFS/TabFSService/TabFSService.swift
+++ b/extension/safari/TabFS/TabFSService/TabFSService.swift
@@ -10,105 +10,15 @@ import Network
import os.log
class TabFSService: NSObject, TabFSServiceProtocol {
- var fs: Process!
- var fsInput: FileHandle!
- var fsOutput: FileHandle!
- func startFs() {
- let fileURL = URL(fileURLWithPath: #filePath)
- let repoURL = fileURL.deletingLastPathComponent().deletingLastPathComponent().deletingLastPathComponent().deletingLastPathComponent().deletingLastPathComponent()
-
- fs = Process()
- fs.executableURL = repoURL.appendingPathComponent("fs").appendingPathComponent("tabfs")
- fs.currentDirectoryURL = fs.executableURL?.deletingLastPathComponent()
-
- fs.arguments = []
-
- let inputPipe = Pipe(), outputPipe = Pipe()
- fs.standardInput = inputPipe
- fs.standardOutput = outputPipe
-
- fsInput = inputPipe.fileHandleForWriting
- fsOutput = outputPipe.fileHandleForReading
-
- try! fs.run()
- }
-
- var ws: NWListener!
- func startWs() {
- // TODO: randomly generate port and report back to caller?
- let port = NWEndpoint.Port(rawValue: 9991)!
-
- let parameters = NWParameters(tls: nil)
- parameters.allowLocalEndpointReuse = true
- parameters.includePeerToPeer = true
- // for security ? so people outside your computer can't hijack TabFS at least
- parameters.requiredInterfaceType = .loopback
-
- let opts = NWProtocolWebSocket.Options()
- opts.autoReplyPing = true
- parameters.defaultProtocolStack.applicationProtocols.insert(opts, at: 0)
-
- ws = try! NWListener(using: parameters, on: port)
- ws.start(queue: .main)
- }
-
- override init() {
- super.init()
-
- startFs()
- startWs()
-
- var handleRequest: ((_ req: Data) -> Void)?
- ws.newConnectionHandler = { conn in
- conn.start(queue: .main)
-
- handleRequest = { req in
- let metaData = NWProtocolWebSocket.Metadata(opcode: .text)
- let context = NWConnection.ContentContext(identifier: "context", metadata: [metaData])
- conn.send(content: req, contentContext: context, completion: .contentProcessed({ err in
- if err != nil {
- os_log(.default, "req %{public}@ error: %{public}@", String(data: req, encoding: .utf8)!, err!.debugDescription as CVarArg)
- // FIXME: ERROR
- }
- }))
- }
-
- 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)
- return
- }
-
- // Send the response back to tabfs.c.
- self.fsInput.write(withUnsafeBytes(of: UInt32(resp.count)) { Data($0) })
- self.fsInput.write(resp)
- read()
- }
- }
- read()
- }
-
- DispatchQueue.global(qos: .default).async {
- while true {
- // Blocking read from the tabfs process.
- let length = self.fsOutput.readData(ofLength: 4).withUnsafeBytes { $0.load(as: UInt32.self) }
- let req = self.fsOutput.readData(ofLength: Int(length))
-
- if let handleRequest = handleRequest {
- // Send the request over the WebSocket connection to background.js in browser.
- handleRequest(req)
- } else {
- // FIXME: ERROR
- }
- }
- }
- // FIXME: disable auto termination
- }
-
func start(withReply reply: @escaping () -> Void) {
// This XPC call is enough to just force the XPC service to be started.
+ os_log("HELLO")
+ let server = Process()
+ os_log("HOW ARE YOU?")
+ server.executableURL = Bundle.main.url(forResource: "TabFSServer", withExtension: "")!
+ os_log("I AM GOOD")
+ server.launch()
+ os_log("GREAT")
reply()
}
}