From 6895149e5a952eca694417433765d388cf5a6988 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micka=C3=ABl=20Menu?= Date: Wed, 15 May 2024 10:29:19 +0200 Subject: [PATCH 1/4] Remove deprecated `HTTPServer` APIs --- .../Adapters/GCDWebServer/GCDHTTPServer.swift | 4 ---- Sources/Shared/Toolkit/HTTP/HTTPServer.swift | 19 ------------------- 2 files changed, 23 deletions(-) diff --git a/Sources/Adapters/GCDWebServer/GCDHTTPServer.swift b/Sources/Adapters/GCDWebServer/GCDHTTPServer.swift index 185061979..4f5f0d485 100644 --- a/Sources/Adapters/GCDWebServer/GCDHTTPServer.swift +++ b/Sources/Adapters/GCDWebServer/GCDHTTPServer.swift @@ -182,10 +182,6 @@ public class GCDHTTPServer: HTTPServer, Loggable { // MARK: HTTPServer - public func serve(at endpoint: HTTPServerEndpoint, handler: @escaping (HTTPServerRequest) -> Resource) throws -> HTTPURL { - try serve(at: endpoint, handler: handler, failureHandler: nil) - } - public func serve( at endpoint: HTTPServerEndpoint, handler: @escaping (HTTPServerRequest) -> Resource, diff --git a/Sources/Shared/Toolkit/HTTP/HTTPServer.swift b/Sources/Shared/Toolkit/HTTP/HTTPServer.swift index d76d08521..095b748f7 100644 --- a/Sources/Shared/Toolkit/HTTP/HTTPServer.swift +++ b/Sources/Shared/Toolkit/HTTP/HTTPServer.swift @@ -13,17 +13,6 @@ import Foundation public protocol HTTPServer { typealias FailureHandler = (_ request: HTTPServerRequest, _ error: ResourceError) -> Void - /// Serves resources at the given `endpoint`. - /// - /// Subsequent calls with the same `endpoint` overwrite each other. - /// - /// - Returns the base URL for this endpoint. - @discardableResult - func serve( - at endpoint: HTTPServerEndpoint, - handler: @escaping (HTTPServerRequest) -> Resource - ) throws -> HTTPURL - /// Serves resources at the given `endpoint`. /// /// Subsequent calls with the same `endpoint` overwrite each other. @@ -48,14 +37,6 @@ public protocol HTTPServer { } public extension HTTPServer { - @discardableResult - func serve( - at endpoint: HTTPServerEndpoint, - handler: @escaping (HTTPServerRequest) -> Resource, - failureHandler: FailureHandler? - ) throws -> HTTPURL { - try serve(at: endpoint, handler: handler) - } /// Serves the local file `url` at the given `endpoint`. /// From 583f1d17ab660dda2db81d671cbfb5bbff8c1e0e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micka=C3=ABl=20Menu?= Date: Wed, 15 May 2024 10:44:13 +0200 Subject: [PATCH 2/4] Add an `HTTPRequestHandler` --- .../Adapters/GCDWebServer/GCDHTTPServer.swift | 25 ++++------ .../CBZ/CBZNavigatorViewController.swift | 2 +- .../EPUB/EPUBNavigatorViewModel.swift | 6 +-- .../PDF/PDFNavigatorViewController.swift | 2 +- Sources/Shared/Toolkit/HTTP/HTTPServer.swift | 46 ++++++++++++------- 5 files changed, 43 insertions(+), 38 deletions(-) diff --git a/Sources/Adapters/GCDWebServer/GCDHTTPServer.swift b/Sources/Adapters/GCDWebServer/GCDHTTPServer.swift index 4f5f0d485..3a36e51e2 100644 --- a/Sources/Adapters/GCDWebServer/GCDHTTPServer.swift +++ b/Sources/Adapters/GCDWebServer/GCDHTTPServer.swift @@ -18,11 +18,6 @@ public enum GCDHTTPServerError: Error { /// Implementation of `HTTPServer` using ReadiumGCDWebServer under the hood. public class GCDHTTPServer: HTTPServer, Loggable { - private struct EndpointHandler { - let resourceHandler: (HTTPServerRequest) -> Resource - let failureHandler: HTTPServer.FailureHandler? - } - /// Shared instance of the HTTP server. public static let shared = GCDHTTPServer() @@ -30,7 +25,7 @@ public class GCDHTTPServer: HTTPServer, Loggable { private let server = ReadiumGCDWebServer() /// Mapping between endpoints and their handlers. - private var handlers: [HTTPURL: EndpointHandler] = [:] + private var handlers: [HTTPURL: HTTPRequestHandler] = [:] /// Mapping between endpoints and resource transformers. private var transformers: [HTTPURL: [ResourceTransformer]] = [:] @@ -114,7 +109,7 @@ public class GCDHTTPServer: HTTPServer, Loggable { private func responseResource( for request: ReadiumGCDWebServerRequest, - completion: @escaping (HTTPServerRequest, Resource, FailureHandler?) -> Void + completion: @escaping (HTTPServerRequest, Resource, HTTPRequestHandler.OnFailure?) -> Void ) { let completion = { request, resource, failureHandler in // Escape the queue to avoid deadlocks if something is using the @@ -145,11 +140,11 @@ public class GCDHTTPServer: HTTPServer, Loggable { for (endpoint, handler) in handlers { if endpoint == pathWithoutAnchor { let request = HTTPServerRequest(url: url, href: nil) - let resource = handler.resourceHandler(request) + let resource = handler.onRequest(request) completion( request, transform(resource: resource, at: endpoint), - handler.failureHandler + handler.onFailure ) return @@ -158,11 +153,11 @@ public class GCDHTTPServer: HTTPServer, Loggable { url: url, href: href ) - let resource = handler.resourceHandler(request) + let resource = handler.onRequest(request) completion( request, transform(resource: resource, at: endpoint), - handler.failureHandler + handler.onFailure ) return } @@ -184,8 +179,7 @@ public class GCDHTTPServer: HTTPServer, Loggable { public func serve( at endpoint: HTTPServerEndpoint, - handler: @escaping (HTTPServerRequest) -> Resource, - failureHandler: FailureHandler? + handler: HTTPRequestHandler ) throws -> HTTPURL { try queue.sync(flags: .barrier) { if case .stopped = state { @@ -193,10 +187,7 @@ public class GCDHTTPServer: HTTPServer, Loggable { } let url = try url(for: endpoint) - handlers[url] = EndpointHandler( - resourceHandler: handler, - failureHandler: failureHandler - ) + handlers[url] = handler return url } } diff --git a/Sources/Navigator/CBZ/CBZNavigatorViewController.swift b/Sources/Navigator/CBZ/CBZNavigatorViewController.swift index 1097bd0ae..6ccca29d2 100644 --- a/Sources/Navigator/CBZ/CBZNavigatorViewController.swift +++ b/Sources/Navigator/CBZ/CBZNavigatorViewController.swift @@ -59,7 +59,7 @@ open class CBZNavigatorViewController: UIViewController, VisualNavigator, Loggab publicationBaseURL = try httpServer.serve( at: uuidEndpoint, publication: publication, - failureHandler: { [weak self] request, error in + onFailure: { [weak self] request, error in DispatchQueue.main.async { [weak self] in guard let self = self, let href = request.href else { return diff --git a/Sources/Navigator/EPUB/EPUBNavigatorViewModel.swift b/Sources/Navigator/EPUB/EPUBNavigatorViewModel.swift index fe1a13adf..d145d6441 100644 --- a/Sources/Navigator/EPUB/EPUBNavigatorViewModel.swift +++ b/Sources/Navigator/EPUB/EPUBNavigatorViewModel.swift @@ -62,7 +62,7 @@ final class EPUBNavigatorViewModel: Loggable { at: "readium", contentsOf: Bundle.module.resourceURL!.fileURL! .appendingPath("Assets/Static", isDirectory: true), - failureHandler: nil + onFailure: nil ), useLegacySettings: false ) @@ -73,7 +73,7 @@ final class EPUBNavigatorViewModel: Loggable { publicationBaseURL = try httpServer.serve( at: uuidEndpoint, // serving the chapters endpoint publication: publication, - failureHandler: { [weak self] request, error in + onFailure: { [weak self] request, error in guard let self = self, let href = request.href else { return } @@ -187,7 +187,7 @@ final class EPUBNavigatorViewModel: Loggable { throw Error.noHTTPServer } let endpoint = baseEndpoint.addingSuffix("/") + file.lastPathSegment - let url = try httpServer.serve(at: endpoint, contentsOf: file, failureHandler: nil) + let url = try httpServer.serve(at: endpoint, contentsOf: file) $servedFiles.write { $0[file] = url } return url } diff --git a/Sources/Navigator/PDF/PDFNavigatorViewController.swift b/Sources/Navigator/PDF/PDFNavigatorViewController.swift index b05a6cb9e..e120da6ec 100644 --- a/Sources/Navigator/PDF/PDFNavigatorViewController.swift +++ b/Sources/Navigator/PDF/PDFNavigatorViewController.swift @@ -121,7 +121,7 @@ open class PDFNavigatorViewController: UIViewController, VisualNavigator, Select publicationBaseURL = try httpServer.serve( at: uuidEndpoint, publication: publication, - failureHandler: { request, error in + onFailure: { request, error in DispatchQueue.main.async { [weak self] in guard let self = self, let href = request.href else { return diff --git a/Sources/Shared/Toolkit/HTTP/HTTPServer.swift b/Sources/Shared/Toolkit/HTTP/HTTPServer.swift index 095b748f7..6cd3fcb21 100644 --- a/Sources/Shared/Toolkit/HTTP/HTTPServer.swift +++ b/Sources/Shared/Toolkit/HTTP/HTTPServer.swift @@ -11,20 +11,15 @@ import Foundation /// This is required by some Navigators to access a local publication's /// resources. public protocol HTTPServer { - typealias FailureHandler = (_ request: HTTPServerRequest, _ error: ResourceError) -> Void - /// Serves resources at the given `endpoint`. /// /// Subsequent calls with the same `endpoint` overwrite each other. /// - /// If the resource cannot be served, the `failureHandler` is called. - /// /// - Returns the base URL for this endpoint. @discardableResult func serve( at endpoint: HTTPServerEndpoint, - handler: @escaping (HTTPServerRequest) -> Resource, - failureHandler: FailureHandler? + handler: HTTPRequestHandler ) throws -> HTTPURL /// Registers a `Resource` transformer that will be run on all responses @@ -37,7 +32,6 @@ public protocol HTTPServer { } public extension HTTPServer { - /// Serves the local file `url` at the given `endpoint`. /// /// If the provided `url` is a directory, then all the files in the @@ -51,9 +45,9 @@ public extension HTTPServer { func serve( at endpoint: HTTPServerEndpoint, contentsOf url: FileURL, - failureHandler: FailureHandler? = nil + onFailure: HTTPRequestHandler.OnFailure? = nil ) throws -> HTTPURL { - func handler(request: HTTPServerRequest) -> Resource { + func onRequest(request: HTTPServerRequest) -> Resource { let file = request.href.flatMap { url.resolve($0) } ?? url @@ -68,8 +62,10 @@ public extension HTTPServer { return try serve( at: endpoint, - handler: handler(request:), - failureHandler: failureHandler + handler: HTTPRequestHandler( + onRequest: onRequest, + onFailure: onFailure + ) ) } @@ -83,11 +79,11 @@ public extension HTTPServer { func serve( at endpoint: HTTPServerEndpoint, publication: Publication, - failureHandler: FailureHandler? = nil + onFailure: HTTPRequestHandler.OnFailure? = nil ) throws -> HTTPURL { - func handler(request: HTTPServerRequest) -> Resource { + func onRequest(request: HTTPServerRequest) -> Resource { guard let href = request.href else { - failureHandler?(request, .notFound(nil)) + onFailure?(request, .notFound(nil)) return FailureResource( link: Link(href: request.url.string), @@ -100,8 +96,10 @@ public extension HTTPServer { return try serve( at: endpoint, - handler: handler(request:), - failureHandler: failureHandler + handler: HTTPRequestHandler( + onRequest: onRequest, + onFailure: onFailure + ) ) } } @@ -122,3 +120,19 @@ public struct HTTPServerRequest { self.href = href } } + +/// Callbacks handling a request. +/// +/// If the resource cannot be served, the `onFailure` callback is called. +public struct HTTPRequestHandler { + public typealias OnRequest = (_ request: HTTPServerRequest) -> Resource + public typealias OnFailure = (_ request: HTTPServerRequest, _ error: ResourceError) -> Void + + public let onRequest: OnRequest + public let onFailure: OnFailure? + + public init(onRequest: @escaping OnRequest, onFailure: OnFailure? = nil) { + self.onRequest = onRequest + self.onFailure = onFailure + } +} From f62edc7941591173892097fe9729ff43b6428ba7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micka=C3=ABl=20Menu?= Date: Wed, 15 May 2024 10:45:02 +0200 Subject: [PATCH 3/4] CHANGELOG --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2869e6c35..16b02ffed 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,7 @@ All notable changes to this project will be documented in this file. Take a look #### Shared * The `Link` property key for archive-based publication assets (e.g. an EPUB/ZIP) is now `https://readium.org/webpub-manifest/properties#archive` instead of `archive`. +* The API of `HTTPServer` slightly changed to be more future-proof. #### Navigator From 697be6a78a07de60e5fa0dad726b022689199531 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micka=C3=ABl=20Menu?= Date: Fri, 17 May 2024 12:10:59 +0200 Subject: [PATCH 4/4] Minor change --- Sources/Navigator/EPUB/EPUBNavigatorViewModel.swift | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Sources/Navigator/EPUB/EPUBNavigatorViewModel.swift b/Sources/Navigator/EPUB/EPUBNavigatorViewModel.swift index d145d6441..312a339b5 100644 --- a/Sources/Navigator/EPUB/EPUBNavigatorViewModel.swift +++ b/Sources/Navigator/EPUB/EPUBNavigatorViewModel.swift @@ -61,8 +61,7 @@ final class EPUBNavigatorViewModel: Loggable { assetsURL: httpServer.serve( at: "readium", contentsOf: Bundle.module.resourceURL!.fileURL! - .appendingPath("Assets/Static", isDirectory: true), - onFailure: nil + .appendingPath("Assets/Static", isDirectory: true) ), useLegacySettings: false )