Skip to content

Commit

Permalink
Merge branch 'main' into jbe/better_bridge
Browse files Browse the repository at this point in the history
  • Loading branch information
jbelkins committed Nov 18, 2024
2 parents 59df489 + f5e6c7f commit 66dfd76
Show file tree
Hide file tree
Showing 429 changed files with 17,886 additions and 920 deletions.
20 changes: 20 additions & 0 deletions IntegrationTests/AWSIntegrationTestUtils/GenerateDataHelper.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
//
// Copyright Amazon.com Inc. or its affiliates.
// All Rights Reserved.
//
// SPDX-License-Identifier: Apache-2.0
//

import Foundation

public func generateRandomTextData(ofSizeInBytes byteCount: Int) -> Data {
let allowedCharacters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890".utf8
let allowedBytes = Array(allowedCharacters)
let randomBytes = (0..<byteCount).map { _ in allowedBytes.randomElement()! }
return Data(randomBytes)
}

public func generateRandomTextData(ofSizeInMB megabytes: Double) -> Data {
let byteCount = Int(megabytes * 1024 * 1024) // Convert megabytes to bytes
return generateRandomTextData(ofSizeInBytes: byteCount)
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,38 +18,26 @@ final class S3ConcurrentTests: S3XCTestCase {
// Payload just below chunked threshold
// Tests concurrent upload of simple data payloads
func test_10x_1MB_getObject() async throws {
fileData = try generateDummyTextData(count: CHUNKED_THRESHOLD - 1)
fileData = generateRandomTextData(ofSizeInMB: 1)
try await repeatConcurrentlyWithArgs(count: 10, test: getObject, args: fileData!)
}

// Payload at chunked threshold, just large enough to chunk
// Tests concurrent upload with aws-chunked encoding & flexible checksums
func test_10x_1_5MB_getObject() async throws {
fileData = try generateDummyTextData(count: CHUNKED_THRESHOLD)
fileData = generateRandomTextData(ofSizeInMB: 1.5)
try await repeatConcurrentlyWithArgs(count: 10, test: getObject, args: fileData!)
}

// Payload 256 bytes with 200 concurrent requests, sends as simple data
// Tests very high concurrency with small data payloads
func test_200x_256B_getObject() async throws {
fileData = try generateDummyTextData(count: 256)
fileData = generateRandomTextData(ofSizeInBytes: 256)
try await repeatConcurrentlyWithArgs(count: 200, test: getObject, args: fileData!)
}

// MARK: - Private methods

// Generates text data of the exact length requested
private func generateDummyTextData(count: Int) throws -> Data {
let segment = "ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890"
let segmentData = Data(segment.utf8)
var wholeData = Data()
for _ in 0..<(count / segmentData.count + 1) {
wholeData.append(contentsOf: segmentData.shuffled())
}
// Truncate data to exactly the required length
return wholeData.subdata(in: 0..<count)
}

// Puts data to S3, gets the uploaded file, asserts retrieved data == original data, deletes S3 object
private func getObject(args: Any...) async throws {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import XCTest
import AWSS3
import SmithyHTTPAPI
@testable import ClientRuntime
import AWSIntegrationTestUtils
import class SmithyStreams.BufferedStream
import class SmithyChecksums.ValidatingBufferedStream

Expand All @@ -19,7 +20,7 @@ final class S3FlexibleChecksumsTests: S3XCTestCase {
override func setUp() {
super.setUp()
// Fill one MB with random data. Data is refreshed for each flexible checksums tests below.
originalData = Data((0..<(1024 * 1024)).map { _ in UInt8.random(in: UInt8.min...UInt8.max) })
originalData = generateRandomTextData(ofSizeInMB: 1)
}

// MARK: - Data uploads
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
//
// Copyright Amazon.com Inc. or its affiliates.
// All Rights Reserved.
//
// SPDX-License-Identifier: Apache-2.0
//

import AWSSDKHTTPAuth
import XCTest
import AWSS3
import ClientRuntime
import AWSClientRuntime
import SmithyHTTPAPI
import AWSIntegrationTestUtils
import class SmithyStreams.BufferedStream

/// Tests toggle unsigned payload using S3.
class S3ToggleUnsignedPayloadTests: S3XCTestCase {
private var s3Config: S3Client.S3ClientConfiguration!

override func setUp() async throws {
try await super.setUp()
s3Config = try await S3Client.S3ClientConfiguration(region: region)
s3Config.authSchemes = [SigV4AuthScheme(requestUnsignedBody: true)]
}

class CheckUnsignedPayloadHeader<InputType, OutputType>: Interceptor {
typealias RequestType = HTTPRequest
typealias ResponseType = HTTPResponse

func readBeforeTransmit(context: some AfterSerialization<InputType, RequestType>) async throws {
XCTAssertTrue(
context.getRequest().headers.value(for: "x-amz-content-sha256") == "UNSIGNED-PAYLOAD"
)
}
}

class CheckStreamingUnsignedPayloadHeader<InputType, OutputType>: Interceptor {
typealias RequestType = HTTPRequest
typealias ResponseType = HTTPResponse

func readBeforeTransmit(context: some AfterSerialization<InputType, RequestType>) async throws {
XCTAssertTrue(
context.getRequest().headers.value(for: "x-amz-content-sha256") == "STREAMING-UNSIGNED-PAYLOAD-TRAILER"
)
}
}

class CheckUnsignedPayloadHeaderProvider: HttpInterceptorProvider {
func create<InputType, OutputType>() -> any Interceptor<InputType, OutputType, HTTPRequest, HTTPResponse> {
return CheckUnsignedPayloadHeader()
}
}

class CheckStreamingUnsignedPayloadHeaderProvider: HttpInterceptorProvider {
func create<InputType, OutputType>() -> any Interceptor<InputType, OutputType, HTTPRequest, HTTPResponse> {
return CheckStreamingUnsignedPayloadHeader()
}
}

func testS3ToggleUnsignedPayloadNonStreaming() async throws {
let key = "test.txt"
let putObjectInput = PutObjectInput(
body: .noStream,
bucket: bucketName,
key: key,
metadata: ["filename": key]
)

// Upload
s3Config.addInterceptorProvider(CheckUnsignedPayloadHeaderProvider())
let s3Client = S3Client(config: s3Config)
_ = try await s3Client.putObject(input: putObjectInput)

// Get
let getObjectInput = GetObjectInput(bucket: bucketName, key: key)
let fetchedObject = try await client.getObject(input: getObjectInput)

XCTAssertNotNil(fetchedObject.metadata)
let metadata = try XCTUnwrap(fetchedObject.metadata)
XCTAssertEqual(metadata["filename"], key)
}

func testS3ToggleUnsignedPayloadStreaming() async throws {
let key = "test-streaming.txt"
let data = generateRandomTextData(ofSizeInMB: 1)
let bufferedStream = BufferedStream(data: data, isClosed: true)
let putObjectInput = PutObjectInput(
body: .stream(bufferedStream),
bucket: bucketName,
key: key,
metadata: ["filename": key]
)

// Upload
s3Config.addInterceptorProvider(CheckStreamingUnsignedPayloadHeaderProvider())
let s3Client = S3Client(config: s3Config)
_ = try await s3Client.putObject(input: putObjectInput)

// Get
let getObjectInput = GetObjectInput(bucket: bucketName, key: key)
let fetchedObject = try await client.getObject(input: getObjectInput)

XCTAssertNotNil(fetchedObject.metadata)
let metadata = try XCTUnwrap(fetchedObject.metadata)
XCTAssertEqual(metadata["filename"], key)
}
}
1 change: 1 addition & 0 deletions Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,7 @@ let serviceTargets: [String] = [
"AWSConfigService",
"AWSConnect",
"AWSConnectCampaigns",
"AWSConnectCampaignsV2",
"AWSConnectCases",
"AWSConnectContactLens",
"AWSConnectParticipant",
Expand Down
2 changes: 1 addition & 1 deletion Package.version
Original file line number Diff line number Diff line change
@@ -1 +1 @@
1.0.41
1.0.42
2 changes: 1 addition & 1 deletion Package.version.next
Original file line number Diff line number Diff line change
@@ -1 +1 @@
1.0.42
1.0.43
Original file line number Diff line number Diff line change
Expand Up @@ -253,6 +253,8 @@ This SDK is open-source. Code is available on Github [here](https://github.com/

[AWSConnectCampaigns](../../../../../swift/api/awsconnectcampaigns/latest)

[AWSConnectCampaignsV2](../../../../../swift/api/awsconnectcampaignsv2/latest)

[AWSConnectCases](../../../../../swift/api/awsconnectcases/latest)

[AWSConnectContactLens](../../../../../swift/api/awsconnectcontactlens/latest)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -127,11 +127,12 @@ public class AWSSigV4Signer: SmithyHTTPAuthAPI.Signer {
let checksumIsPresent = signingProperties.get(key: SigningPropertyKeys.checksum) != nil
let isChunkedEligibleStream = signingProperties.get(key: SigningPropertyKeys.isChunkedEligibleStream) ?? false
let preComputedSha256 = signingProperties.get(key: AttributeKey<String>(name: "SignedBodyValue"))
let requestedUnsignedBody = signingProperties.get(key: SigningPropertyKeys.requestUnsignedBody)

let signedBodyValue: AWSSignedBodyValue = determineSignedBodyValue(
checksumIsPresent: checksumIsPresent,
isChunkedEligbleStream: isChunkedEligibleStream,
isUnsignedBody: unsignedBody,
isUnsignedBody: requestedUnsignedBody ?? unsignedBody,
preComputedSha256: preComputedSha256
)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,15 @@ import struct Smithy.Attributes
public struct SigV4AuthScheme: AuthScheme {
public let schemeID: String = "aws.auth#sigv4"
public let signer: Signer = AWSSigV4Signer()
public let requestUnsignedBody: Bool

public init() {}
public init() {
self.requestUnsignedBody = false
}

public init(requestUnsignedBody: Bool) {
self.requestUnsignedBody = requestUnsignedBody
}

public func customizeSigningProperties(signingProperties: Attributes, context: Context) throws -> Attributes {
var updatedSigningProperties = signingProperties
Expand Down Expand Up @@ -69,6 +76,11 @@ public struct SigV4AuthScheme: AuthScheme {
value: context.isChunkedEligibleStream
)

// Optionally toggle unsigned body
if self.requestUnsignedBody {
updatedSigningProperties.set(key: SigningPropertyKeys.requestUnsignedBody, value: true)
}

// Set service-specific signing properties if needed.
try CustomSigningPropertiesSetter().setServiceSpecificSigningProperties(
signingProperties: &updatedSigningProperties,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -283,4 +283,20 @@ class SigV4AuthSchemeTests: XCTestCase {
let updatedProperties = try sigV4AuthScheme.customizeSigningProperties(signingProperties: Attributes(), context: context)
XCTAssertTrue(try XCTUnwrap(updatedProperties.get(key: SigningPropertyKeys.shouldNormalizeURIPath)))
}

func testRequestUnsignedBody() throws {
let customSigV4AuthScheme = SigV4AuthScheme(requestUnsignedBody: true)
let context = contextBuilder
.withBidirectionalStreamingEnabled(value: true)
.withServiceName(value: "filler")
.withFlowType(value: .NORMAL)
.withOperation(value: "filler")
.withUnsignedPayloadTrait(value: false)
.build()
let updatedProperties = try customSigV4AuthScheme.customizeSigningProperties(signingProperties: Attributes(), context: context)
let unwrappedRequestUnsignedBodyValue = try XCTUnwrap(
updatedProperties.get(key: SigningPropertyKeys.requestUnsignedBody)
)
XCTAssertTrue(unwrappedRequestUnsignedBodyValue)
}
}
2 changes: 1 addition & 1 deletion Sources/Services/AWSACM/Sources/AWSACM/ACMClient.swift
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ import typealias SmithyHTTPAuthAPI.AuthSchemes

public class ACMClient: ClientRuntime.Client {
public static let clientName = "ACMClient"
public static let version = "1.0.41"
public static let version = "1.0.42"
let client: ClientRuntime.SdkHttpClient
let config: ACMClient.ACMClientConfiguration
let serviceName = "ACM"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ import typealias SmithyHTTPAuthAPI.AuthSchemes

public class ACMPCAClient: ClientRuntime.Client {
public static let clientName = "ACMPCAClient"
public static let version = "1.0.41"
public static let version = "1.0.42"
let client: ClientRuntime.SdkHttpClient
let config: ACMPCAClient.ACMPCAClientConfiguration
let serviceName = "ACM PCA"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ import typealias SmithyHTTPAuthAPI.AuthSchemes

public class APIGatewayClient: ClientRuntime.Client {
public static let clientName = "APIGatewayClient"
public static let version = "1.0.41"
public static let version = "1.0.42"
let client: ClientRuntime.SdkHttpClient
let config: APIGatewayClient.APIGatewayClientConfiguration
let serviceName = "API Gateway"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ import typealias SmithyHTTPAuthAPI.AuthSchemes

public class ARCZonalShiftClient: ClientRuntime.Client {
public static let clientName = "ARCZonalShiftClient"
public static let version = "1.0.41"
public static let version = "1.0.42"
let client: ClientRuntime.SdkHttpClient
let config: ARCZonalShiftClient.ARCZonalShiftClientConfiguration
let serviceName = "ARC Zonal Shift"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ import typealias SmithyHTTPAuthAPI.AuthSchemes

public class AccessAnalyzerClient: ClientRuntime.Client {
public static let clientName = "AccessAnalyzerClient"
public static let version = "1.0.41"
public static let version = "1.0.42"
let client: ClientRuntime.SdkHttpClient
let config: AccessAnalyzerClient.AccessAnalyzerClientConfiguration
let serviceName = "AccessAnalyzer"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ import typealias SmithyHTTPAuthAPI.AuthSchemes

public class AccountClient: ClientRuntime.Client {
public static let clientName = "AccountClient"
public static let version = "1.0.41"
public static let version = "1.0.42"
let client: ClientRuntime.SdkHttpClient
let config: AccountClient.AccountClientConfiguration
let serviceName = "Account"
Expand Down
2 changes: 1 addition & 1 deletion Sources/Services/AWSAmp/Sources/AWSAmp/AmpClient.swift
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ import typealias SmithyHTTPAuthAPI.AuthSchemes

public class AmpClient: ClientRuntime.Client {
public static let clientName = "AmpClient"
public static let version = "1.0.41"
public static let version = "1.0.42"
let client: ClientRuntime.SdkHttpClient
let config: AmpClient.AmpClientConfiguration
let serviceName = "amp"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ import typealias SmithyHTTPAuthAPI.AuthSchemes

public class AmplifyClient: ClientRuntime.Client {
public static let clientName = "AmplifyClient"
public static let version = "1.0.41"
public static let version = "1.0.42"
let client: ClientRuntime.SdkHttpClient
let config: AmplifyClient.AmplifyClientConfiguration
let serviceName = "Amplify"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ import typealias SmithyHTTPAuthAPI.AuthSchemes

public class AmplifyBackendClient: ClientRuntime.Client {
public static let clientName = "AmplifyBackendClient"
public static let version = "1.0.41"
public static let version = "1.0.42"
let client: ClientRuntime.SdkHttpClient
let config: AmplifyBackendClient.AmplifyBackendClientConfiguration
let serviceName = "AmplifyBackend"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ import typealias SmithyHTTPAuthAPI.AuthSchemes

public class AmplifyUIBuilderClient: ClientRuntime.Client {
public static let clientName = "AmplifyUIBuilderClient"
public static let version = "1.0.41"
public static let version = "1.0.42"
let client: ClientRuntime.SdkHttpClient
let config: AmplifyUIBuilderClient.AmplifyUIBuilderClientConfiguration
let serviceName = "AmplifyUIBuilder"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ import typealias SmithyHTTPAuthAPI.AuthSchemes

public class ApiGatewayManagementApiClient: ClientRuntime.Client {
public static let clientName = "ApiGatewayManagementApiClient"
public static let version = "1.0.41"
public static let version = "1.0.42"
let client: ClientRuntime.SdkHttpClient
let config: ApiGatewayManagementApiClient.ApiGatewayManagementApiClientConfiguration
let serviceName = "ApiGatewayManagementApi"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ import typealias SmithyHTTPAuthAPI.AuthSchemes

public class ApiGatewayV2Client: ClientRuntime.Client {
public static let clientName = "ApiGatewayV2Client"
public static let version = "1.0.41"
public static let version = "1.0.42"
let client: ClientRuntime.SdkHttpClient
let config: ApiGatewayV2Client.ApiGatewayV2ClientConfiguration
let serviceName = "ApiGatewayV2"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ import typealias SmithyHTTPAuthAPI.AuthSchemes

public class AppConfigClient: ClientRuntime.Client {
public static let clientName = "AppConfigClient"
public static let version = "1.0.41"
public static let version = "1.0.42"
let client: ClientRuntime.SdkHttpClient
let config: AppConfigClient.AppConfigClientConfiguration
let serviceName = "AppConfig"
Expand Down
Loading

0 comments on commit 66dfd76

Please sign in to comment.