Skip to content

Commit 677508c

Browse files
authored
Add support for S3 express endpoints (#629)
* Store credential in middleware context * Add support for S3 express endpoints * Update testMiddleware * Add S3Middleware executionContext task local * throw error if URL init fails * Make AWSClient.logger public
1 parent b763fa8 commit 677508c

File tree

11 files changed

+243
-73
lines changed

11 files changed

+243
-73
lines changed

Sources/SotoCore/AWSClient.swift

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ public final class AWSClient: Sendable {
4848
/// HTTP client used by AWSClient
4949
public let httpClient: AWSHTTPClient
5050
/// Logger used for non-request based output
51-
let clientLogger: Logger
51+
public let logger: Logger
5252
/// client options
5353
let options: Options
5454

@@ -71,13 +71,13 @@ public final class AWSClient: Sendable {
7171
middleware: some AWSMiddlewareProtocol,
7272
options: Options = Options(),
7373
httpClient: AWSHTTPClient = HTTPClient.shared,
74-
logger clientLogger: Logger = AWSClient.loggingDisabled
74+
logger: Logger = AWSClient.loggingDisabled
7575
) {
7676
self.httpClient = httpClient
7777
let credentialProvider = credentialProviderFactory.createProvider(
7878
context: .init(
7979
httpClient: self.httpClient,
80-
logger: clientLogger,
80+
logger: logger,
8181
options: options
8282
)
8383
)
@@ -88,7 +88,7 @@ public final class AWSClient: Sendable {
8888
RetryMiddleware(retryPolicy: retryPolicyFactory.retryPolicy)
8989
ErrorHandlingMiddleware(options: options)
9090
}
91-
self.clientLogger = clientLogger
91+
self.logger = logger
9292
self.options = options
9393
}
9494

@@ -105,13 +105,13 @@ public final class AWSClient: Sendable {
105105
retryPolicy retryPolicyFactory: RetryPolicyFactory = .default,
106106
options: Options = Options(),
107107
httpClient: AWSHTTPClient = HTTPClient.shared,
108-
logger clientLogger: Logger = AWSClient.loggingDisabled
108+
logger: Logger = AWSClient.loggingDisabled
109109
) {
110110
self.httpClient = httpClient
111111
let credentialProvider = credentialProviderFactory.createProvider(
112112
context: .init(
113113
httpClient: self.httpClient,
114-
logger: clientLogger,
114+
logger: logger,
115115
options: options
116116
)
117117
)
@@ -121,7 +121,7 @@ public final class AWSClient: Sendable {
121121
RetryMiddleware(retryPolicy: retryPolicyFactory.retryPolicy)
122122
ErrorHandlingMiddleware(options: options)
123123
}
124-
self.clientLogger = clientLogger
124+
self.logger = logger
125125
self.options = options
126126
}
127127

@@ -402,9 +402,15 @@ extension AWSClient {
402402
try Task.checkCancellation()
403403
// combine service and client middleware stacks
404404
let middlewareStack = config.middleware.map { AWSDynamicMiddlewareStack($0, self.middleware) } ?? self.middleware
405+
let credential = try await self.credentialProvider.getCredential(logger: logger)
405406
let middlewareContext = AWSMiddlewareContext(
406407
operation: operationName,
407408
serviceConfig: config,
409+
credential: StaticCredential(
410+
accessKeyId: credential.accessKeyId,
411+
secretAccessKey: credential.secretAccessKey,
412+
sessionToken: credential.sessionToken
413+
),
408414
logger: logger
409415
)
410416
// run middleware stack with httpClient execute at the end

Sources/SotoCore/Credential/Credential+IsEmpty.swift

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,4 +18,8 @@ extension Credential {
1818
func isEmpty() -> Bool {
1919
self.accessKeyId.isEmpty || self.secretAccessKey.isEmpty
2020
}
21+
22+
func getStaticCredential() -> StaticCredential {
23+
.init(accessKeyId: accessKeyId, secretAccessKey: secretAccessKey, sessionToken: sessionToken)
24+
}
2125
}

Sources/SotoCore/Credential/CredentialProvider.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -170,7 +170,7 @@ extension CredentialProviderFactory {
170170
/// Don't supply any credentials
171171
public static var empty: CredentialProviderFactory {
172172
Self { _ in
173-
StaticCredential(accessKeyId: "", secretAccessKey: "")
173+
EmptyCredential()
174174
}
175175
}
176176

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// This source file is part of the Soto for AWS open source project
4+
//
5+
// Copyright (c) 2017-2023 the Soto project authors
6+
// Licensed under Apache License v2.0
7+
//
8+
// See LICENSE.txt for license information
9+
// See CONTRIBUTORS.txt for the list of Soto project authors
10+
//
11+
// SPDX-License-Identifier: Apache-2.0
12+
//
13+
//===----------------------------------------------------------------------===//
14+
15+
/// Empty credentials
16+
public struct EmptyCredential: CredentialProvider, Credential {
17+
public var accessKeyId: String { "" }
18+
public var secretAccessKey: String { "" }
19+
public var sessionToken: String? { nil }
20+
21+
public func getCredential(logger: Logger) async throws -> any Credential {
22+
self
23+
}
24+
}

Sources/SotoCore/HTTP/AWSHTTPBody.swift

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,15 @@ public struct AWSHTTPBody: Sendable {
7474
}
7575
}
7676

77+
public var isEmpty: Bool {
78+
switch self.storage {
79+
case .byteBuffer(let buffer):
80+
return buffer.readableBytes == 0
81+
case .asyncSequence(_, let length):
82+
return length == 0
83+
}
84+
}
85+
7786
public var isStreaming: Bool {
7887
switch self.storage {
7988
case .byteBuffer:

Sources/SotoCore/Middleware/Middleware.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import Logging
1818
public struct AWSMiddlewareContext: Sendable {
1919
public var operation: String
2020
public var serviceConfig: AWSServiceConfig
21+
public var credential: StaticCredential
2122
public var logger: Logger
2223
}
2324

0 commit comments

Comments
 (0)