mirror of
https://github.com/apple/swift-nio-extras.git
synced 2025-05-31 01:37:03 +08:00
75 lines
2.5 KiB
Swift
75 lines
2.5 KiB
Swift
//===----------------------------------------------------------------------===//
|
|
//
|
|
// This source file is part of the SwiftNIO open source project
|
|
//
|
|
// Copyright (c) 2023-2024 Apple Inc. and the SwiftNIO project authors
|
|
// Licensed under Apache License v2.0
|
|
//
|
|
// See LICENSE.txt for license information
|
|
// See CONTRIBUTORS.txt for the list of SwiftNIO project authors
|
|
//
|
|
// SPDX-License-Identifier: Apache-2.0
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
import NIOConcurrencyHelpers
|
|
import NIOCore
|
|
|
|
/// `HTTPResumableUploadContext` manages ongoing uploads.
|
|
public final class HTTPResumableUploadContext {
|
|
let origin: String
|
|
let path: String
|
|
let timeout: TimeAmount
|
|
private let uploads: NIOLockedValueBox<[String: HTTPResumableUpload]> = .init([:])
|
|
|
|
/// Create an `HTTPResumableUploadContext` for use with `HTTPResumableUploadHandler`.
|
|
/// - Parameters:
|
|
/// - origin: Scheme and authority of the upload server. For example, "https://www.example.com".
|
|
/// - path: Request path for resumption URLs. `HTTPResumableUploadHandler` intercepts all requests to this path.
|
|
/// - timeout: Time to wait before failure if the client didn't attempt an upload resumption.
|
|
public init(origin: String, path: String = "/resumable_upload/", timeout: TimeAmount = .hours(1)) {
|
|
self.origin = origin
|
|
self.path = path
|
|
self.timeout = timeout
|
|
}
|
|
|
|
func isResumption(path: String) -> Bool {
|
|
path.hasPrefix(self.path)
|
|
}
|
|
|
|
private func path(fromToken token: String) -> String {
|
|
"\(self.path)\(token)"
|
|
}
|
|
|
|
private func token(fromPath path: String) -> String {
|
|
assert(self.isResumption(path: path))
|
|
return String(path.dropFirst(self.path.count))
|
|
}
|
|
|
|
func startUpload(_ upload: HTTPResumableUpload) -> String {
|
|
var random = SystemRandomNumberGenerator()
|
|
let token = "\(random.next())-\(random.next())"
|
|
self.uploads.withLockedValue {
|
|
assert($0[token] == nil)
|
|
$0[token] = upload
|
|
}
|
|
return self.path(fromToken: token)
|
|
}
|
|
|
|
func stopUpload(_ upload: HTTPResumableUpload) {
|
|
if let path = upload.resumePath {
|
|
let token = token(fromPath: path)
|
|
self.uploads.withLockedValue {
|
|
$0[token] = nil
|
|
}
|
|
}
|
|
}
|
|
|
|
func findUpload(path: String) -> HTTPResumableUpload? {
|
|
let token = token(fromPath: path)
|
|
return self.uploads.withLockedValue {
|
|
$0[token]
|
|
}
|
|
}
|
|
}
|