更新 Package.swift 中的依赖项和目标
dependencies: [
...
.package(url: "https://github.com/LiveUI/S3.git", from: "3.0.0-RC3.2"),
],
targets: [
.target(name: "App", dependencies: ["Vapor", "S3"]),
...
]
运行 vapor update
在您的 configure 方法中将 S3Client 注册为服务
try services.register(s3: S3Signer.Config(...), defaultBucket: "my-bucket")
要使用自定义 Minio 服务器,请使用此 Config/Region
S3Signer.Config(accessKey: accessKey,
secretKey: secretKey,
region: Region(name: RegionName.usEast1,
hostName: "127.0.0.1:9000",
useTLS: false)
使用 S3Client
import S3
let s3 = try req.makeS3Client() // or req.make(S3Client.self) as? S3
s3.put(...)
s3.get(...)
s3.delete(...)
如果您只想使用签名器
import S3Signer
let s3 = try req.makeS3Signer() // or req.make(S3Signer.self)
s3.headers(...)
/// S3 client Protocol
public protocol S3Client: Service {
/// Get list of objects
func buckets(on: Container) -> EventLoopFuture<BucketsInfo>
/// Create a bucket
func create(bucket: String, region: Region?, on container: Container) -> EventLoopFuture<Void>
/// Delete a bucket
func delete(bucket: String, region: Region?, on container: Container) -> EventLoopFuture<Void>
/// Get bucket location
func location(bucket: String, on container: Container) -> EventLoopFuture<Region>
/// Get list of objects
func list(bucket: String, region: Region?, on container: Container) -> EventLoopFuture<BucketResults>
/// Get list of objects
func list(bucket: String, region: Region?, headers: [String: String], on container: Container) -> EventLoopFuture<BucketResults>
/// Upload file to S3
func put(file: File.Upload, headers: [String: String], on: Container) throws -> EventLoopEventLoopFuture<File.Response>
/// Upload file to S3
func put(file url: URL, destination: String, access: AccessControlList, on: Container) -> EventLoopFuture<File.Response>
/// Upload file to S3
func put(file url: URL, destination: String, bucket: String?, access: AccessControlList, on: Container) -> EventLoopFuture<File.Response>
/// Upload file to S3
func put(file path: String, destination: String, access: AccessControlList, on: Container) -> EventLoopFuture<File.Response>
/// Upload file to S3
func put(file path: String, destination: String, bucket: String?, access: AccessControlList, on: Container) -> EventLoopFuture<File.Response>
/// Upload file to S3
func put(string: String, destination: String, on: Container) -> EventLoopFuture<File.Response>
/// Upload file to S3
func put(string: String, destination: String, access: AccessControlList, on: Container) -> EventLoopFuture<File.Response>
/// Upload file to S3
func put(string: String, mime: MediaType, destination: String, on: Container) -> EventLoopFuture<File.Response>
/// Upload file to S3
func put(string: String, mime: MediaType, destination: String, access: AccessControlList, on: Container) -> EventLoopFuture<File.Response>
/// Upload file to S3
func put(string: String, mime: MediaType, destination: String, bucket: String?, access: AccessControlList, on: Container) -> EventLoopFuture<File.Response>
/// Retrieve file data from S3
func get(fileInfo file: LocationConvertible, on container: Container) -> EventLoopFuture<File.Info>
/// Retrieve file data from S3
func get(fileInfo file: LocationConvertible, headers: [String: String], on container: Container) -> EventLoopFuture<File.Info>
/// Retrieve file data from S3
func get(file: LocationConvertible, on: Container) -> EventLoopFuture<File.Response>
/// Retrieve file data from S3
func get(file: LocationConvertible, headers: [String: String], on: Container) -> EventLoopFuture<File.Response>
/// Delete file from S3
func delete(file: LocationConvertible, on: Container) -> EventLoopFuture<Void>
/// Delete file from S3
func delete(file: LocationConvertible, headers: [String: String], on: Container) -> EventLoopFuture<Void>
}
public func routes(_ router: Router) throws {
// Get all available buckets
router.get("buckets") { req -> EventLoopFuture<BucketsInfo> in
let s3 = try req.makeS3Client()
return try s3.buckets(on: req)
}
// Create new bucket
router.put("bucket") { req -> EventLoopFuture<String> in
let s3 = try req.makeS3Client()
return try s3.create(bucket: "api-created-bucket", region: .euCentral1, on: req).map(to: String.self) {
return ":)"
}.catchMap({ (error) -> (String) in
if let error = error.s3ErrorMessage() {
return error.message
}
return ":("
}
)
}
// Locate bucket (get region)
router.get("bucket/location") { req -> EventLoopFuture<String> in
let s3 = try req.makeS3Client()
return try s3.location(bucket: "bucket-name", on: req).map(to: String.self) { region in
return region.hostUrlString()
}.catchMap({ (error) -> (String) in
if let error = error as? S3.Error {
switch error {
case .errorResponse(_, let error):
return error.message
default:
return "S3 :("
}
}
return ":("
}
)
}
// Delete bucket
router.delete("bucket") { req -> EventLoopFuture<String> in
let s3 = try req.makeS3Client()
return try s3.delete(bucket: "api-created-bucket", region: .euCentral1, on: req).map(to: String.self) {
return ":)"
}.catchMap({ (error) -> (String) in
if let error = error.s3ErrorMessage() {
return error.message
}
return ":("
}
)
}
// Get list of objects
router.get("files") { req -> EventLoopFuture<BucketResults> in
let s3 = try req.makeS3Client()
return try s3.list(bucket: "booststore", region: .usEast1, headers: [:], on: req).catchMap({ (error) -> (BucketResults) in
if let error = error.s3ErrorMessage() {
print(error.message)
}
throw error
})
}
// Demonstrate work with files
router.get("files/test") { req -> EventLoopFuture<String> in
let string = "Content of my example file"
let fileName = "file-hu.txt"
let s3 = try req.makeS3Client()
do {
// Upload a file from string
return try s3.put(string: string, destination: fileName, access: .publicRead, on: req).flatMap(to: String.self) { putResponse in
print("PUT response:")
print(putResponse)
// Get the content of the newly uploaded file
return try s3.get(file: fileName, on: req).flatMap(to: String.self) { getResponse in
print("GET response:")
print(getResponse)
print(String(data: getResponse.data, encoding: .utf8) ?? "Unknown content!")
// Get info about the file (HEAD)
return try s3.get(fileInfo: fileName, on: req).flatMap(to: String.self) { infoResponse in
print("HEAD/Info response:")
print(infoResponse)
// Delete the file
return try s3.delete(file: fileName, on: req).map() { response in
print("DELETE response:")
print(response)
let json = try JSONEncoder().encode(infoResponse)
return String(data: json, encoding: .utf8) ?? "Unknown content!"
}.catchMap({ error -> (String) in
if let error = error.s3ErrorMessage() {
return error.message
}
return ":("
}
)
}
}
}
} catch {
print(error)
fatalError()
}
}
}
加入我们的 Slack,频道 #help-boost 来... 获得帮助 :)
Einstore 的核心包,一个完全开源的 Swift 企业应用商店!
我们喜欢 PR,我们对它们的需求永不满足...所以如果您有一个有趣的改进、错误修复或新功能,请随时与我们联系。如果您在开始开发之前对某些事情不确定,您可以随时通过我们的 Slack 联系我们的开发和产品团队。
Ondrej Rafaj(在 Github 上 @rafiki270,在 Twitter 上 @rafiki270,在 LiveUI Slack 和 Vapor Slack)
Anthoni Castelli(在 Github 上 @anthonycastelli,在 Vapor Slack 上 @anthony)感谢他在更新 Vapor3 的 S3Signer 方面的帮助
JustinM1(在 Github 上 @JustinM1)感谢他的精彩原创签名器包
有关更多信息,请参见 LICENSE 文件。