localhost1978's picture
download
raw
12 kB
import CryptoKit
import Foundation
import SSK_Abstractions
@testable import SSK_Providers
import XCTest
@available(macOS 27.0, iOS 27.0, *)
final class HTTP3AudioArtifactTests: XCTestCase {
func testClientUsesHTTPSHTTP3AndValidatedPUTRoute() async throws {
let payload = Data("audio-fixture".utf8)
let hash = sha256(payload)
let jobID = AudioIngestionJobID(rawValue: UUID())
let uri = makeURI(jobID: jobID, kind: .sourceRecord, hash: hash)
let recorder = RequestRecorder()
let receiptData = try JSONEncoder().encode(
RemoteAudioArtifactReceipt(uri: uri, contentHash: hash, byteCount: payload.count)
)
let client = HTTP3AudioArtifactClient { request, limit in
await recorder.record(request, limit: limit)
return (
receiptData,
HTTPURLResponse(
url: request.url!,
statusCode: 201,
httpVersion: "HTTP/3",
headerFields: nil
)!
)
}
let receipt = try await client.putAudioArtifact(
endpoint: URL(string: "https://storage.example/ssk")!,
jobID: jobID,
kind: .sourceRecord,
contentHash: hash,
payload: payload
)
XCTAssertEqual(receipt, RemoteAudioArtifactReceipt(uri: uri, contentHash: hash, byteCount: payload.count))
let lastRequest = await recorder.last()
let recorded = try XCTUnwrap(lastRequest)
XCTAssertEqual(recorded.request.httpMethod, "PUT")
XCTAssertTrue(recorded.request.assumesHTTP3Capable)
XCTAssertEqual(
recorded.request.url?.path,
"/ssk/audio-artifacts/\(jobID.rawValue.uuidString.lowercased())/sourceRecord/\(hash)"
)
XCTAssertEqual(recorded.request.value(forHTTPHeaderField: "X-SSK-Content-SHA256"), hash)
XCTAssertEqual(recorded.request.httpBody, payload)
XCTAssertEqual(recorded.limit, 65_536)
}
func testClientRejectsInsecureEndpointAndNoncanonicalHashWithoutNetwork() async {
let recorder = RequestRecorder()
let client = HTTP3AudioArtifactClient { request, limit in
await recorder.record(request, limit: limit)
throw RemoteAudioArtifactTransportError.invalidResponse
}
do {
_ = try await client.putAudioArtifact(
endpoint: URL(string: "http://storage.example")!,
jobID: AudioIngestionJobID(rawValue: UUID()),
kind: .sourceRecord,
contentHash: "bad/hash",
payload: Data()
)
XCTFail("Expected a secure endpoint failure")
} catch {
XCTAssertEqual(error as? RemoteAudioArtifactTransportError, .secureEndpointRequired)
}
let lastRequest = await recorder.last()
XCTAssertNil(lastRequest)
}
func testClientRejectsOversizedOrHashMismatchedGETResponse() async throws {
let uri = makeURI(
jobID: AudioIngestionJobID(rawValue: UUID()),
kind: .metadata,
hash: String(repeating: "a", count: 64)
)
let oversized = Data(repeating: 0, count: 5)
let oversizedClient = HTTP3AudioArtifactClient(maximumArtifactByteCount: 4) { request, _ in
(
oversized,
HTTPURLResponse(url: request.url!, statusCode: 200, httpVersion: "HTTP/3", headerFields: nil)!
)
}
do {
_ = try await oversizedClient.getAudioArtifact(
endpoint: URL(string: "https://storage.example")!,
uri: uri,
expectedContentHash: String(repeating: "a", count: 64)
)
XCTFail("Expected an oversized response failure")
} catch {
XCTAssertEqual(error as? RemoteAudioArtifactTransportError, .responseTooLarge)
}
let mismatchClient = HTTP3AudioArtifactClient { request, _ in
(
Data("wrong".utf8),
HTTPURLResponse(url: request.url!, statusCode: 200, httpVersion: "HTTP/3", headerFields: nil)!
)
}
do {
_ = try await mismatchClient.getAudioArtifact(
endpoint: URL(string: "https://storage.example")!,
uri: uri,
expectedContentHash: String(repeating: "a", count: 64)
)
XCTFail("Expected a content hash failure")
} catch {
XCTAssertEqual(error as? RemoteAudioArtifactTransportError, .contentHashMismatch)
}
}
func testServerPUTGETDELETELifecycle() async throws {
let fixture = try makeServerFixture(maximumByteCount: 64)
defer { try? FileManager.default.removeItem(at: fixture.root) }
let payload = Data("audio-fixture".utf8)
let hash = sha256(payload)
let jobID = AudioIngestionJobID(rawValue: UUID())
let put = await fixture.server.handle(
HTTP3AudioArtifactRequest(
method: "PUT",
path: "/audio-artifacts/\(jobID.rawValue.uuidString.lowercased())/metadata/\(hash)",
headers: [
"content-type": "application/octet-stream",
"content-length": String(payload.count),
"x-ssk-content-sha256": hash,
],
body: payload
)
)
XCTAssertEqual(put.statusCode, 201)
let receipt = try JSONDecoder().decode(RemoteAudioArtifactReceipt.self, from: put.body)
XCTAssertEqual(receipt.contentHash, hash)
let get = await fixture.server.handle(
HTTP3AudioArtifactRequest(
method: "GET",
path: "/audio-artifacts/by-hash/\(hash)",
headers: ["x-ssk-artifact-uri": receipt.uri.stringValue],
body: Data()
)
)
XCTAssertEqual(get.statusCode, 200)
XCTAssertEqual(get.body, payload)
let encodedURI = base64URL(Data(receipt.uri.stringValue.utf8))
let delete = await fixture.server.handle(
HTTP3AudioArtifactRequest(
method: "DELETE",
path: "/audio-artifacts/by-uri/\(encodedURI)",
headers: [:],
body: Data()
)
)
XCTAssertEqual(delete.statusCode, 204)
let missing = await fixture.server.handle(
HTTP3AudioArtifactRequest(
method: "GET",
path: "/audio-artifacts/by-hash/\(hash)",
headers: ["x-ssk-artifact-uri": receipt.uri.stringValue],
body: Data()
)
)
XCTAssertEqual(missing.statusCode, 404)
}
func testServerFailsClosedForLargeMismatchAndTraversalRequests() async throws {
let fixture = try makeServerFixture(maximumByteCount: 4)
defer { try? FileManager.default.removeItem(at: fixture.root) }
let job = UUID().uuidString.lowercased()
let hash = String(repeating: "a", count: 64)
let tooLarge = await fixture.server.handle(
HTTP3AudioArtifactRequest(
method: "PUT",
path: "/audio-artifacts/\(job)/metadata/\(hash)",
headers: [
"content-type": "application/octet-stream",
"content-length": "5",
"x-ssk-content-sha256": hash,
],
body: Data(repeating: 0, count: 5)
)
)
XCTAssertEqual(tooLarge.statusCode, 413)
let mismatch = await fixture.server.handle(
HTTP3AudioArtifactRequest(
method: "PUT",
path: "/audio-artifacts/\(job)/metadata/\(hash)",
headers: [
"content-type": "application/octet-stream",
"content-length": "1",
"x-ssk-content-sha256": hash,
],
body: Data([0])
)
)
XCTAssertEqual(mismatch.statusCode, 422)
let traversal = await fixture.server.handle(
HTTP3AudioArtifactRequest(
method: "GET",
path: "/audio-artifacts/by-hash/%2E%2E",
headers: ["x-ssk-artifact-uri": "ssk://cas:\(hash)/media/audio-artifact/\(job)/metadata"],
body: Data()
)
)
XCTAssertEqual(traversal.statusCode, 400)
}
func testStoreRejectsSymlinkEscapeBeforeWrite() async throws {
let root = FileManager.default.temporaryDirectory
.appendingPathComponent("ssk-http3-root-\(UUID().uuidString)", isDirectory: true)
let outside = FileManager.default.temporaryDirectory
.appendingPathComponent("ssk-http3-outside-\(UUID().uuidString)", isDirectory: true)
defer {
try? FileManager.default.removeItem(at: root)
try? FileManager.default.removeItem(at: outside)
}
try FileManager.default.createDirectory(at: root, withIntermediateDirectories: true)
try FileManager.default.createDirectory(at: outside, withIntermediateDirectories: true)
let jobID = AudioIngestionJobID(rawValue: UUID())
try FileManager.default.createSymbolicLink(
at: root.appendingPathComponent(jobID.rawValue.uuidString.lowercased()),
withDestinationURL: outside
)
let store = try HTTP3AudioArtifactStore(rootURL: root, maximumArtifactByteCount: 64)
let payload = Data("fixture".utf8)
do {
_ = try await store.put(
jobID: jobID,
kind: .metadata,
contentHash: sha256(payload),
payload: payload
)
XCTFail("Expected containment failure")
} catch {
XCTAssertEqual(error as? HTTP3AudioArtifactServerError, .pathOutsideStore)
}
XCTAssertEqual(try FileManager.default.contentsOfDirectory(atPath: outside.path), [])
}
private func makeServerFixture(
maximumByteCount: Int
) throws -> (root: URL, server: HTTP3AudioArtifactServer) {
let root = FileManager.default.temporaryDirectory
.appendingPathComponent("ssk-http3-artifacts-\(UUID().uuidString)", isDirectory: true)
let store = try HTTP3AudioArtifactStore(
rootURL: root,
maximumArtifactByteCount: maximumByteCount
)
return (
root,
HTTP3AudioArtifactServer(
store: store,
maximumArtifactByteCount: maximumByteCount
)
)
}
private func makeURI(
jobID: AudioIngestionJobID,
kind: AudioArtifactKind,
hash: String
) -> SSKURI {
SSKURI(
authority: .cas(hash: .init(rawValue: hash)),
domain: .media,
subdomain: "audio-artifact",
pathComponents: [
.init(rawValue: jobID.rawValue.uuidString.lowercased()),
.init(rawValue: kind.rawValue),
]
)
}
private func sha256(_ data: Data) -> String {
SHA256.hash(data: data).map { String(format: "%02x", $0) }.joined()
}
private func base64URL(_ data: Data) -> String {
data.base64EncodedString()
.replacingOccurrences(of: "/", with: "_")
.replacingOccurrences(of: "+", with: "-")
.replacingOccurrences(of: "=", with: "")
}
}
@available(macOS 27.0, iOS 27.0, *)
private actor RequestRecorder {
struct Entry: Sendable {
let request: URLRequest
let limit: Int
}
private var entry: Entry?
func record(_ request: URLRequest, limit: Int) {
entry = Entry(request: request, limit: limit)
}
func last() -> Entry? {
entry
}
}

Xet Storage Details

Size:
12 kB
·
Xet hash:
3b91a69fbba2dfd64a1f47eef33ee43b73c8505af60e82aedd3f04167e2d8def

Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.