Skip to content

Commit 5278ddc

Browse files
committed
Fix serving EPUB hrefs with anchor or query parameters (#66)
1 parent 213b4b2 commit 5278ddc

File tree

9 files changed

+3378
-150
lines changed

9 files changed

+3378
-150
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ All notable changes to this project will be documented in this file. Take a look
1818
#### Navigator
1919

2020
* Fixed memory leaks in the EPUB and PDF navigators.
21+
* [#61](https://github.com/readium/swift-toolkit/issues/61) Fixed serving EPUB resources when the HREF contains an anchor or query parameters.
2122

2223
#### Streamer
2324

Sources/Shared/Fetcher/ArchiveFetcher.swift

Lines changed: 18 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,7 @@
11
//
2-
// ArchiveFetcher.swift
3-
// r2-shared-swift
4-
//
5-
// Created by Mickaël Menu on 11/05/2020.
6-
//
7-
// Copyright 2020 Readium Foundation. All rights reserved.
8-
// Use of this source code is governed by a BSD-style license which is detailed
9-
// in the LICENSE file present in the project repository where this source code is maintained.
2+
// Copyright 2022 Readium Foundation. All rights reserved.
3+
// Use of this source code is governed by the BSD-style license
4+
// available in the top-level LICENSE file of the project.
105
//
116

127
import Foundation
@@ -31,15 +26,28 @@ public final class ArchiveFetcher: Fetcher, Loggable {
3126

3227
public func get(_ link: Link) -> Resource {
3328
guard
34-
let entry = archive.entry(at: link.href),
35-
let reader = archive.readEntry(at: link.href)
29+
let entry = findEntry(at: link.href),
30+
let reader = archive.readEntry(at: entry.path)
3631
else {
3732
return FailureResource(link: link, error: .notFound(nil))
3833
}
3934

4035
return ArchiveResource(link: link, entry: entry, reader: reader)
4136
}
4237

38+
private func findEntry(at href: String) -> ArchiveEntry? {
39+
if let entry = archive.entry(at: href) {
40+
return entry
41+
}
42+
43+
// Try after removing query parameters and anchors from the href.
44+
guard let href = href.components(separatedBy: .init(charactersIn: "#?")).first else {
45+
return nil
46+
}
47+
48+
return archive.entry(at: href)
49+
}
50+
4351
public func close() {}
4452

4553
private final class ArchiveResource: Resource {

Support/Carthage/.xcodegen

Lines changed: 3321 additions & 112 deletions
Large diffs are not rendered by default.

Support/Carthage/Readium.xcodeproj/xcshareddata/xcschemes/R2Navigator.xcscheme

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,10 +27,8 @@
2727
buildConfiguration = "Debug"
2828
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
2929
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
30-
onlyGenerateCoverageForSpecifiedTargets = "NO"
31-
shouldUseLaunchSchemeArgsEnv = "YES">
32-
<Testables>
33-
</Testables>
30+
shouldUseLaunchSchemeArgsEnv = "YES"
31+
onlyGenerateCoverageForSpecifiedTargets = "NO">
3432
<MacroExpansion>
3533
<BuildableReference
3634
BuildableIdentifier = "primary"
@@ -40,6 +38,8 @@
4038
ReferencedContainer = "container:Readium.xcodeproj">
4139
</BuildableReference>
4240
</MacroExpansion>
41+
<Testables>
42+
</Testables>
4343
</TestAction>
4444
<LaunchAction
4545
buildConfiguration = "Debug"

Support/Carthage/Readium.xcodeproj/xcshareddata/xcschemes/R2Shared.xcscheme

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,10 +27,8 @@
2727
buildConfiguration = "Debug"
2828
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
2929
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
30-
onlyGenerateCoverageForSpecifiedTargets = "NO"
31-
shouldUseLaunchSchemeArgsEnv = "YES">
32-
<Testables>
33-
</Testables>
30+
shouldUseLaunchSchemeArgsEnv = "YES"
31+
onlyGenerateCoverageForSpecifiedTargets = "NO">
3432
<MacroExpansion>
3533
<BuildableReference
3634
BuildableIdentifier = "primary"
@@ -40,6 +38,8 @@
4038
ReferencedContainer = "container:Readium.xcodeproj">
4139
</BuildableReference>
4240
</MacroExpansion>
41+
<Testables>
42+
</Testables>
4343
</TestAction>
4444
<LaunchAction
4545
buildConfiguration = "Debug"

Support/Carthage/Readium.xcodeproj/xcshareddata/xcschemes/R2Streamer.xcscheme

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,10 +27,8 @@
2727
buildConfiguration = "Debug"
2828
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
2929
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
30-
onlyGenerateCoverageForSpecifiedTargets = "NO"
31-
shouldUseLaunchSchemeArgsEnv = "YES">
32-
<Testables>
33-
</Testables>
30+
shouldUseLaunchSchemeArgsEnv = "YES"
31+
onlyGenerateCoverageForSpecifiedTargets = "NO">
3432
<MacroExpansion>
3533
<BuildableReference
3634
BuildableIdentifier = "primary"
@@ -40,6 +38,8 @@
4038
ReferencedContainer = "container:Readium.xcodeproj">
4139
</BuildableReference>
4240
</MacroExpansion>
41+
<Testables>
42+
</Testables>
4343
</TestAction>
4444
<LaunchAction
4545
buildConfiguration = "Debug"

Support/Carthage/Readium.xcodeproj/xcshareddata/xcschemes/ReadiumLCP.xcscheme

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,10 +27,8 @@
2727
buildConfiguration = "Debug"
2828
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
2929
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
30-
onlyGenerateCoverageForSpecifiedTargets = "NO"
31-
shouldUseLaunchSchemeArgsEnv = "YES">
32-
<Testables>
33-
</Testables>
30+
shouldUseLaunchSchemeArgsEnv = "YES"
31+
onlyGenerateCoverageForSpecifiedTargets = "NO">
3432
<MacroExpansion>
3533
<BuildableReference
3634
BuildableIdentifier = "primary"
@@ -40,6 +38,8 @@
4038
ReferencedContainer = "container:Readium.xcodeproj">
4139
</BuildableReference>
4240
</MacroExpansion>
41+
<Testables>
42+
</Testables>
4343
</TestAction>
4444
<LaunchAction
4545
buildConfiguration = "Debug"

Support/Carthage/Readium.xcodeproj/xcshareddata/xcschemes/ReadiumOPDS.xcscheme

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,10 +27,8 @@
2727
buildConfiguration = "Debug"
2828
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
2929
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
30-
onlyGenerateCoverageForSpecifiedTargets = "NO"
31-
shouldUseLaunchSchemeArgsEnv = "YES">
32-
<Testables>
33-
</Testables>
30+
shouldUseLaunchSchemeArgsEnv = "YES"
31+
onlyGenerateCoverageForSpecifiedTargets = "NO">
3432
<MacroExpansion>
3533
<BuildableReference
3634
BuildableIdentifier = "primary"
@@ -40,6 +38,8 @@
4038
ReferencedContainer = "container:Readium.xcodeproj">
4139
</BuildableReference>
4240
</MacroExpansion>
41+
<Testables>
42+
</Testables>
4343
</TestAction>
4444
<LaunchAction
4545
buildConfiguration = "Debug"

Tests/SharedTests/Fetcher/ArchiveFetcherTests.swift

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,7 @@
11
//
2-
// ArchiveFetcherTests.swift
3-
// r2-shared-swift
4-
//
5-
// Created by Mickaël Menu on 11/05/2020.
6-
//
7-
// Copyright 2020 Readium Foundation. All rights reserved.
8-
// Use of this source code is governed by a BSD-style license which is detailed
9-
// in the LICENSE file present in the project repository where this source code is maintained.
2+
// Copyright 2022 Readium Foundation. All rights reserved.
3+
// Use of this source code is governed by the BSD-style license
4+
// available in the top-level LICENSE file of the project.
105
//
116

127
import XCTest
@@ -104,4 +99,19 @@ class ArchiveFetcherTests: XCTestCase {
10499
)
105100
}
106101

102+
/// When the HREF contains query parameters, the fetcher should first be able to remove them as
103+
/// a fallback.
104+
func testHREFWithQueryParameters() {
105+
let resource = fetcher.get(Link(href: "/mimetype?query=param"))
106+
let result = resource.readAsString(encoding: .ascii)
107+
XCTAssertEqual(result.getOrNil(), "application/epub+zip")
108+
}
109+
110+
/// When the HREF contains an anchor, the fetcher should first be able to remove them as
111+
/// a fallback.
112+
func testHREFWithAnchor() {
113+
let resource = fetcher.get(Link(href: "/mimetype#anchor"))
114+
let result = resource.readAsString(encoding: .ascii)
115+
XCTAssertEqual(result.getOrNil(), "application/epub+zip")
116+
}
107117
}

0 commit comments

Comments
 (0)