feat: resolve AniList episodes through ZokoAnime

This commit is contained in:
2026-10-25 15:46:35 +01:00
parent 8c2a18df48
commit ab61d83c69
16 changed files with 492 additions and 21 deletions
+8 -2
View File
@@ -165,7 +165,7 @@ final class MiruroTransport: @unchecked Sendable {
static func prepare(_ source: ResolvedSource, deployment override: MiruroProxyDeployment? = nil) async throws -> ResolvedSource {
let rules = source.requirements
guard rules.embed || rules.proxy != nil || rules.segmentOrigin != nil || !rules.playlistQuery.isEmpty else { return source }
guard rules.zoko || rules.embed || rules.proxy != nil || rules.segmentOrigin != nil || !rules.playlistQuery.isEmpty else { return source }
do {
let deployment: MiruroProxyDeployment?
if let override { deployment = override }
@@ -185,6 +185,7 @@ final class MiruroTransport: @unchecked Sendable {
return prepared
} catch {
if Task.isCancelled || error is CancellationError { throw CancellationError() }
if rules.zoko { throw (error as? ZokoError) ?? ZokoError.transport }
throw MiruroPlaybackError()
}
}
@@ -233,6 +234,7 @@ final class MiruroTransport: @unchecked Sendable {
private func register(_ url: URL, kind: Kind, depth: Int) throws -> URL {
guard depth <= 12, ["http", "https"].contains(url.scheme), url.user == nil, url.password == nil,
(!requirements.zoko || ZokoResolver.validResource(url, playlist: kind == .playlist)),
url.fragment == nil, url.absoluteString.utf8.count <= 32768, let port = listener.port else { throw MiruroPlaybackError() }
return try lock.withLock {
let key = kind.rawValue + ":" + url.absoluteString
@@ -338,6 +340,9 @@ final class MiruroTransport: @unchecked Sendable {
func fetch(_ url: URL) async throws -> (Data, HTTPURLResponse) {
// Same-origin fixture/source access remains allowed. A manifest or
// decrypted token cannot turn the relay into a local-network proxy.
if requirements.zoko {
guard ZokoResolver.validResource(url, playlist: resource.kind == .playlist) else { throw ZokoError.malformed }
}
if !Self.sameOrigin(url, sourceURL) { try Self.requirePublicDestination(url) }
let target: URL
let requestHeaders: String
@@ -349,7 +354,8 @@ final class MiruroTransport: @unchecked Sendable {
} else {
target = url
// Only the embed's fixed public Referer has cross-origin scope.
requestHeaders = embed?.headers ?? (Self.sameOrigin(url, sourceURL) ? headers : "")
requestHeaders = requirements.zoko ? ZokoResolver.referer :
(embed?.headers ?? (Self.sameOrigin(url, sourceURL) ? headers : ""))
}
return try await MiruroMediaHTTP.read(target, headers: requestHeaders,
limit: resource.kind == .playlist ? 2 * 1024 * 1024 : 64 * 1024 * 1024,