mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-08-15 08:53:07 +09:00
88 lines
3.8 KiB
Swift
88 lines
3.8 KiB
Swift
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
|
|
import Foundation
|
|
import GCDWebServers
|
|
import Shared
|
|
|
|
class WebServer {
|
|
private let log = Logger.browserLogger
|
|
|
|
static let WebServerSharedInstance = WebServer()
|
|
|
|
class var sharedInstance: WebServer {
|
|
return WebServerSharedInstance
|
|
}
|
|
|
|
let server: GCDWebServer = GCDWebServer()
|
|
|
|
var base: String {
|
|
return "http://localhost:\(server.port)"
|
|
}
|
|
|
|
/// The private credentials for accessing resources on this Web server.
|
|
let credentials: URLCredential
|
|
|
|
/// A random, transient token used for authenticating requests.
|
|
/// Other apps are able to make requests to our local Web server,
|
|
/// so this prevents them from accessing any resources.
|
|
fileprivate let sessionToken = UUID().uuidString
|
|
|
|
init() {
|
|
credentials = URLCredential(user: sessionToken, password: "", persistence: .forSession)
|
|
}
|
|
|
|
@discardableResult func start() throws -> Bool {
|
|
if !server.isRunning {
|
|
try server.start(options: [
|
|
GCDWebServerOption_Port: 6571,
|
|
GCDWebServerOption_BindToLocalhost: true,
|
|
GCDWebServerOption_AutomaticallySuspendInBackground: true,
|
|
GCDWebServerOption_AuthenticationMethod: GCDWebServerAuthenticationMethod_Basic,
|
|
GCDWebServerOption_AuthenticationAccounts: [sessionToken: ""]
|
|
])
|
|
}
|
|
return server.isRunning
|
|
}
|
|
|
|
/// Convenience method to register a dynamic handler. Will be mounted at $base/$module/$resource
|
|
func registerHandlerForMethod(_ method: String, module: String, resource: String, handler: @escaping (_ request: GCDWebServerRequest?) -> GCDWebServerResponse!) {
|
|
// Prevent serving content if the requested host isn't a whitelisted local host.
|
|
let wrappedHandler = {(request: GCDWebServerRequest?) -> GCDWebServerResponse? in
|
|
guard let request = request, request.url.isLocal else {
|
|
return GCDWebServerResponse(statusCode: 403)
|
|
}
|
|
|
|
return handler(request)
|
|
}
|
|
server.addHandler(forMethod: method, path: "/\(module)/\(resource)", request: GCDWebServerRequest.self, processBlock: wrappedHandler)
|
|
}
|
|
|
|
/// Convenience method to register a resource in the main bundle. Will be mounted at $base/$module/$resource
|
|
func registerMainBundleResource(_ resource: String, module: String) {
|
|
if let path = Bundle.main.path(forResource: resource, ofType: nil) {
|
|
server.addGETHandler(forPath: "/\(module)/\(resource)", filePath: path, isAttachment: false, cacheAge: UInt.max, allowRangeRequests: true)
|
|
}
|
|
}
|
|
|
|
/// Convenience method to register all resources in the main bundle of a specific type. Will be mounted at $base/$module/$resource
|
|
func registerMainBundleResourcesOfType(_ type: String, module: String) {
|
|
for path: String in Bundle.paths(forResourcesOfType: type, inDirectory: Bundle.main.bundlePath) {
|
|
if let resource = NSURL(string: path)?.lastPathComponent {
|
|
server.addGETHandler(forPath: "/\(module)/\(resource)", filePath: path as String, isAttachment: false, cacheAge: UInt.max, allowRangeRequests: true)
|
|
} else {
|
|
log.warning("Unable to locate resource at path: '\(path)'")
|
|
}
|
|
}
|
|
}
|
|
|
|
/// Return a full url, as a string, for a resource in a module. No check is done to find out if the resource actually exist.
|
|
func URLForResource(_ resource: String, module: String) -> String {
|
|
return "\(base)/\(module)/\(resource)"
|
|
}
|
|
|
|
func baseReaderModeURL() -> String {
|
|
return WebServer.sharedInstance.URLForResource("page", module: "reader-mode")
|
|
}
|
|
}
|