Skip to content

Commit 473ef6c

Browse files
authored
Update HTTPServer API (#424)
1 parent a1dd426 commit 473ef6c

File tree

6 files changed

+44
-62
lines changed

6 files changed

+44
-62
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ The Readium Swift toolkit now requires a minimum of iOS 13.
1313
#### Shared
1414

1515
* 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`.
16+
* The API of `HTTPServer` slightly changed to be more future-proof.
1617

1718
#### Navigator
1819

Sources/Adapters/GCDWebServer/GCDHTTPServer.swift

Lines changed: 8 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -18,19 +18,14 @@ public enum GCDHTTPServerError: Error {
1818

1919
/// Implementation of `HTTPServer` using ReadiumGCDWebServer under the hood.
2020
public class GCDHTTPServer: HTTPServer, Loggable {
21-
private struct EndpointHandler {
22-
let resourceHandler: (HTTPServerRequest) -> Resource
23-
let failureHandler: HTTPServer.FailureHandler?
24-
}
25-
2621
/// Shared instance of the HTTP server.
2722
public static let shared = GCDHTTPServer()
2823

2924
/// The actual underlying HTTP server instance.
3025
private let server = ReadiumGCDWebServer()
3126

3227
/// Mapping between endpoints and their handlers.
33-
private var handlers: [HTTPURL: EndpointHandler] = [:]
28+
private var handlers: [HTTPURL: HTTPRequestHandler] = [:]
3429

3530
/// Mapping between endpoints and resource transformers.
3631
private var transformers: [HTTPURL: [ResourceTransformer]] = [:]
@@ -114,7 +109,7 @@ public class GCDHTTPServer: HTTPServer, Loggable {
114109

115110
private func responseResource(
116111
for request: ReadiumGCDWebServerRequest,
117-
completion: @escaping (HTTPServerRequest, Resource, FailureHandler?) -> Void
112+
completion: @escaping (HTTPServerRequest, Resource, HTTPRequestHandler.OnFailure?) -> Void
118113
) {
119114
let completion = { request, resource, failureHandler in
120115
// Escape the queue to avoid deadlocks if something is using the
@@ -145,11 +140,11 @@ public class GCDHTTPServer: HTTPServer, Loggable {
145140
for (endpoint, handler) in handlers {
146141
if endpoint == pathWithoutAnchor {
147142
let request = HTTPServerRequest(url: url, href: nil)
148-
let resource = handler.resourceHandler(request)
143+
let resource = handler.onRequest(request)
149144
completion(
150145
request,
151146
transform(resource: resource, at: endpoint),
152-
handler.failureHandler
147+
handler.onFailure
153148
)
154149
return
155150

@@ -158,11 +153,11 @@ public class GCDHTTPServer: HTTPServer, Loggable {
158153
url: url,
159154
href: href
160155
)
161-
let resource = handler.resourceHandler(request)
156+
let resource = handler.onRequest(request)
162157
completion(
163158
request,
164159
transform(resource: resource, at: endpoint),
165-
handler.failureHandler
160+
handler.onFailure
166161
)
167162
return
168163
}
@@ -182,25 +177,17 @@ public class GCDHTTPServer: HTTPServer, Loggable {
182177

183178
// MARK: HTTPServer
184179

185-
public func serve(at endpoint: HTTPServerEndpoint, handler: @escaping (HTTPServerRequest) -> Resource) throws -> HTTPURL {
186-
try serve(at: endpoint, handler: handler, failureHandler: nil)
187-
}
188-
189180
public func serve(
190181
at endpoint: HTTPServerEndpoint,
191-
handler: @escaping (HTTPServerRequest) -> Resource,
192-
failureHandler: FailureHandler?
182+
handler: HTTPRequestHandler
193183
) throws -> HTTPURL {
194184
try queue.sync(flags: .barrier) {
195185
if case .stopped = state {
196186
try start()
197187
}
198188

199189
let url = try url(for: endpoint)
200-
handlers[url] = EndpointHandler(
201-
resourceHandler: handler,
202-
failureHandler: failureHandler
203-
)
190+
handlers[url] = handler
204191
return url
205192
}
206193
}

Sources/Navigator/CBZ/CBZNavigatorViewController.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ open class CBZNavigatorViewController: UIViewController, VisualNavigator, Loggab
5959
publicationBaseURL = try httpServer.serve(
6060
at: uuidEndpoint,
6161
publication: publication,
62-
failureHandler: { [weak self] request, error in
62+
onFailure: { [weak self] request, error in
6363
DispatchQueue.main.async { [weak self] in
6464
guard let self = self, let href = request.href else {
6565
return

Sources/Navigator/EPUB/EPUBNavigatorViewModel.swift

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -61,8 +61,7 @@ final class EPUBNavigatorViewModel: Loggable {
6161
assetsURL: httpServer.serve(
6262
at: "readium",
6363
contentsOf: Bundle.module.resourceURL!.fileURL!
64-
.appendingPath("Assets/Static", isDirectory: true),
65-
failureHandler: nil
64+
.appendingPath("Assets/Static", isDirectory: true)
6665
),
6766
useLegacySettings: false
6867
)
@@ -73,7 +72,7 @@ final class EPUBNavigatorViewModel: Loggable {
7372
publicationBaseURL = try httpServer.serve(
7473
at: uuidEndpoint, // serving the chapters endpoint
7574
publication: publication,
76-
failureHandler: { [weak self] request, error in
75+
onFailure: { [weak self] request, error in
7776
guard let self = self, let href = request.href else {
7877
return
7978
}
@@ -187,7 +186,7 @@ final class EPUBNavigatorViewModel: Loggable {
187186
throw Error.noHTTPServer
188187
}
189188
let endpoint = baseEndpoint.addingSuffix("/") + file.lastPathSegment
190-
let url = try httpServer.serve(at: endpoint, contentsOf: file, failureHandler: nil)
189+
let url = try httpServer.serve(at: endpoint, contentsOf: file)
191190
$servedFiles.write { $0[file] = url }
192191
return url
193192
}

Sources/Navigator/PDF/PDFNavigatorViewController.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,7 @@ open class PDFNavigatorViewController: UIViewController, VisualNavigator, Select
121121
publicationBaseURL = try httpServer.serve(
122122
at: uuidEndpoint,
123123
publication: publication,
124-
failureHandler: { request, error in
124+
onFailure: { request, error in
125125
DispatchQueue.main.async { [weak self] in
126126
guard let self = self, let href = request.href else {
127127
return

Sources/Shared/Toolkit/HTTP/HTTPServer.swift

Lines changed: 30 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -11,31 +11,15 @@ import Foundation
1111
/// This is required by some Navigators to access a local publication's
1212
/// resources.
1313
public protocol HTTPServer {
14-
typealias FailureHandler = (_ request: HTTPServerRequest, _ error: ResourceError) -> Void
15-
16-
/// Serves resources at the given `endpoint`.
17-
///
18-
/// Subsequent calls with the same `endpoint` overwrite each other.
19-
///
20-
/// - Returns the base URL for this endpoint.
21-
@discardableResult
22-
func serve(
23-
at endpoint: HTTPServerEndpoint,
24-
handler: @escaping (HTTPServerRequest) -> Resource
25-
) throws -> HTTPURL
26-
2714
/// Serves resources at the given `endpoint`.
2815
///
2916
/// Subsequent calls with the same `endpoint` overwrite each other.
3017
///
31-
/// If the resource cannot be served, the `failureHandler` is called.
32-
///
3318
/// - Returns the base URL for this endpoint.
3419
@discardableResult
3520
func serve(
3621
at endpoint: HTTPServerEndpoint,
37-
handler: @escaping (HTTPServerRequest) -> Resource,
38-
failureHandler: FailureHandler?
22+
handler: HTTPRequestHandler
3923
) throws -> HTTPURL
4024

4125
/// Registers a `Resource` transformer that will be run on all responses
@@ -48,15 +32,6 @@ public protocol HTTPServer {
4832
}
4933

5034
public extension HTTPServer {
51-
@discardableResult
52-
func serve(
53-
at endpoint: HTTPServerEndpoint,
54-
handler: @escaping (HTTPServerRequest) -> Resource,
55-
failureHandler: FailureHandler?
56-
) throws -> HTTPURL {
57-
try serve(at: endpoint, handler: handler)
58-
}
59-
6035
/// Serves the local file `url` at the given `endpoint`.
6136
///
6237
/// If the provided `url` is a directory, then all the files in the
@@ -70,9 +45,9 @@ public extension HTTPServer {
7045
func serve(
7146
at endpoint: HTTPServerEndpoint,
7247
contentsOf url: FileURL,
73-
failureHandler: FailureHandler? = nil
48+
onFailure: HTTPRequestHandler.OnFailure? = nil
7449
) throws -> HTTPURL {
75-
func handler(request: HTTPServerRequest) -> Resource {
50+
func onRequest(request: HTTPServerRequest) -> Resource {
7651
let file = request.href.flatMap { url.resolve($0) }
7752
?? url
7853

@@ -87,8 +62,10 @@ public extension HTTPServer {
8762

8863
return try serve(
8964
at: endpoint,
90-
handler: handler(request:),
91-
failureHandler: failureHandler
65+
handler: HTTPRequestHandler(
66+
onRequest: onRequest,
67+
onFailure: onFailure
68+
)
9269
)
9370
}
9471

@@ -102,11 +79,11 @@ public extension HTTPServer {
10279
func serve(
10380
at endpoint: HTTPServerEndpoint,
10481
publication: Publication,
105-
failureHandler: FailureHandler? = nil
82+
onFailure: HTTPRequestHandler.OnFailure? = nil
10683
) throws -> HTTPURL {
107-
func handler(request: HTTPServerRequest) -> Resource {
84+
func onRequest(request: HTTPServerRequest) -> Resource {
10885
guard let href = request.href else {
109-
failureHandler?(request, .notFound(nil))
86+
onFailure?(request, .notFound(nil))
11087

11188
return FailureResource(
11289
link: Link(href: request.url.string),
@@ -119,8 +96,10 @@ public extension HTTPServer {
11996

12097
return try serve(
12198
at: endpoint,
122-
handler: handler(request:),
123-
failureHandler: failureHandler
99+
handler: HTTPRequestHandler(
100+
onRequest: onRequest,
101+
onFailure: onFailure
102+
)
124103
)
125104
}
126105
}
@@ -141,3 +120,19 @@ public struct HTTPServerRequest {
141120
self.href = href
142121
}
143122
}
123+
124+
/// Callbacks handling a request.
125+
///
126+
/// If the resource cannot be served, the `onFailure` callback is called.
127+
public struct HTTPRequestHandler {
128+
public typealias OnRequest = (_ request: HTTPServerRequest) -> Resource
129+
public typealias OnFailure = (_ request: HTTPServerRequest, _ error: ResourceError) -> Void
130+
131+
public let onRequest: OnRequest
132+
public let onFailure: OnFailure?
133+
134+
public init(onRequest: @escaping OnRequest, onFailure: OnFailure? = nil) {
135+
self.onRequest = onRequest
136+
self.onFailure = onFailure
137+
}
138+
}

0 commit comments

Comments
 (0)