diff options
| -rw-r--r-- | Sora/Data/Booru/BooruManager.swift | 12 | ||||
| -rw-r--r-- | SoraTests/ViewDerivedDataTests.swift | 26 |
2 files changed, 30 insertions, 8 deletions
diff --git a/Sora/Data/Booru/BooruManager.swift b/Sora/Data/Booru/BooruManager.swift index 68d5079..f5fcf89 100644 --- a/Sora/Data/Booru/BooruManager.swift +++ b/Sora/Data/Booru/BooruManager.swift @@ -26,6 +26,7 @@ class BooruManager: ObservableObject { // swiftlint:disable:this type_body_leng private let pageCache = NSCache<NSString, BooruPageCacheEntry>() // swiftlint:disable:this legacy_objc_type private let cacheDuration: TimeInterval private let credentials: BooruProviderCredentials? + private let referer: String private let userAgent: String? private let showHeldMoebooruPosts: Bool private var urlCache: [String: URL] = [:] @@ -61,6 +62,7 @@ class BooruManager: ObservableObject { // swiftlint:disable:this type_body_leng pageCache.countLimit = 50 pageCache.totalCostLimit = 50 * 1_024 * 1_024 + self.referer = Self.baseReferer(for: provider.domain) self.userAgent = Self.resolvedUserAgent( sendUserAgent: sendUserAgent, customUserAgent: customUserAgent @@ -220,6 +222,10 @@ class BooruManager: ObservableObject { // swiftlint:disable:this type_body_leng return "Sora/\(version) (Build \(buildNumber))" } + private static func baseReferer(for domain: String) -> String { + "https://\(domain)/" + } + func clearCachedPages() { pageCache.removeAllObjects() urlCache.removeAll() @@ -593,8 +599,10 @@ class BooruManager: ObservableObject { // swiftlint:disable:this type_body_leng } func requestURL(_ url: URL) async throws -> Data { - let headers = userAgent.map { value in - HTTPHeaders([HTTPHeader(name: "User-Agent", value: value)]) + var headers = HTTPHeaders([HTTPHeader(name: "Referer", value: referer)]) + + if let userAgent { + headers.add(name: "User-Agent", value: userAgent) } return try await AF.request(url, headers: headers) diff --git a/SoraTests/ViewDerivedDataTests.swift b/SoraTests/ViewDerivedDataTests.swift index f844a7c..28fd59e 100644 --- a/SoraTests/ViewDerivedDataTests.swift +++ b/SoraTests/ViewDerivedDataTests.swift @@ -1094,6 +1094,10 @@ final class ViewDerivedDataTests: XCTestCase { // swiftlint:disable:this type_b named: "private static func resolvedUserAgent(", from: source ) + let refererResolverSection = try extractFunction( + named: "private static func baseReferer(for domain: String) -> String", + from: source + ) let requestURLSection = try extractFunction( named: "func requestURL(_ url: URL) async throws -> Data", from: source @@ -1106,12 +1110,16 @@ final class ViewDerivedDataTests: XCTestCase { // swiftlint:disable:this type_b matching: #"customUserAgent\.trimmingCharacters"#, in: userAgentResolverSection ) - let optionalHeaderMappingCount = tokenCount( - matching: #"userAgent\.map"#, + let refererFormatCount = tokenCount( + matching: #""https://\\\#\(domain\)/""#, + in: refererResolverSection + ) + let refererHeaderCount = tokenCount( + matching: #"HTTPHeader\(name:\s*"Referer",\s*value:\s*referer\)"#, in: requestURLSection ) let explicitUserAgentHeaderCount = tokenCount( - matching: #"HTTPHeader\(name:\s*"User-Agent",\s*value:\s*value\)"#, + matching: #"headers\.add\(name:\s*"User-Agent",\s*value:\s*userAgent\)"#, in: requestURLSection ) @@ -1135,15 +1143,21 @@ final class ViewDerivedDataTests: XCTestCase { // swiftlint:disable:this type_b ) // swiftlint:disable:next prefer_nimble XCTAssertGreaterThan( - optionalHeaderMappingCount, + refererFormatCount, + 0, + "BooruManager should derive booru Referer headers from the provider base URL with a trailing slash." + ) + // swiftlint:disable:next prefer_nimble + XCTAssertGreaterThan( + refererHeaderCount, 0, - "BooruManager should only attach request headers when a User-Agent is available." + "BooruManager should always attach a Referer header for booru requests." ) // swiftlint:disable:next prefer_nimble XCTAssertGreaterThan( explicitUserAgentHeaderCount, 0, - "BooruManager should keep using the User-Agent header name for booru requests." + "BooruManager should continue attaching the User-Agent header only when available." ) } |