func downloadSourceArchive()

in Sources/PackageRegistryExample/Controllers/PackageResourcesController.swift [25:61]


    func downloadSourceArchive(request: Request) async throws -> Response {
        let package = try request.getPackageParam(validating: false)
        // Client may append .json extension to the URI (4.4)
        let version = try request.getVersionParam(removingExtension: ".zip")

        let release = try await self.packageReleases.get(package: package, version: version)
        guard release.status != .deleted else {
            throw PackageRegistry.APIError.resourceGone("\(package)@\(version) has been removed")
        }

        let sourceArchive = try await self.packageResources.get(package: package, version: version, type: .sourceArchive)

        var headers = HTTPHeaders()
        headers.replaceOrAdd(name: .acceptRanges, value: "bytes")
        headers.replaceOrAdd(name: .cacheControl, value: "public, immutable")
        headers.contentType = .zip
        headers.replaceOrAdd(name: .contentDisposition, value: "attachment; filename=\"\(package.name)-\(version).zip\"")
        headers.replaceOrAdd(name: "Digest", value: "sha-256=\(Data(SHA256.hash(data: sourceArchive.bytes)).base64EncodedString())")
        // Content-Length header is automatically set for us

        let response = Response(status: .ok, headers: headers)
        let buffer = ByteBuffer(data: sourceArchive.bytes)

        response.body = .init(stream: { stream in
            stream.write(.buffer(buffer))
                .whenComplete { result in
                    switch result {
                    case .success:
                        stream.write(.end, promise: nil)
                    case .failure(let error):
                        stream.write(.error(error), promise: nil)
                    }
                }
        }, count: buffer.readableBytes)

        return response
    }