44 */
55package aws.sdk.kotlin.e2etest
66
7- import aws.sdk.kotlin.services.s3.S3Client
7+ import aws.sdk.kotlin.services.s3.*
88import aws.sdk.kotlin.services.s3.express.S3_EXPRESS_SESSION_TOKEN_HEADER
99import aws.sdk.kotlin.services.s3.model.*
1010import aws.sdk.kotlin.services.s3.presigners.presignPutObject
11- import aws.sdk.kotlin.services.s3.putObject
12- import aws.sdk.kotlin.services.s3.withConfig
1311import aws.smithy.kotlin.runtime.client.ProtocolRequestInterceptorContext
1412import aws.smithy.kotlin.runtime.content.ByteStream
1513import aws.smithy.kotlin.runtime.content.decodeToString
@@ -47,6 +45,7 @@ class S3ExpressTest {
4745 @AfterAll
4846 fun cleanup (): Unit = runBlocking {
4947 testBuckets.forEach { bucket ->
48+ S3TestUtils .deleteMultiPartUploads(client, bucket)
5049 S3TestUtils .deleteBucketAndAllContents(client, bucket)
5150 }
5251 client.close()
@@ -136,6 +135,62 @@ class S3ExpressTest {
136135 }
137136 }
138137
138+ @Test
139+ fun testUploadPartContainsNoChecksums () = runTest {
140+ val testBucket = testBuckets.first()
141+ val testObject = " I-will-be-uploaded-in-parts-!"
142+
143+ // Parts need to be at least 5 MB
144+ val partOne = " Hello" .repeat(1_048_576 )
145+ val partTwo = " World" .repeat(1_048_576 )
146+
147+ val testUploadId = client.createMultipartUpload {
148+ bucket = testBucket
149+ key = testObject
150+ }.uploadId
151+
152+ var eTagPartOne: String?
153+ var eTagPartTwo: String?
154+
155+ client.withConfig {
156+ interceptors + = NoChecksumValidatingInterceptor ()
157+ }.use { validatingClient ->
158+ eTagPartOne = validatingClient.uploadPart {
159+ bucket = testBucket
160+ key = testObject
161+ partNumber = 1
162+ uploadId = testUploadId
163+ body = ByteStream .fromString(partOne)
164+ }.eTag
165+
166+ eTagPartTwo = validatingClient.uploadPart {
167+ bucket = testBucket
168+ key = testObject
169+ partNumber = 2
170+ uploadId = testUploadId
171+ body = ByteStream .fromString(partTwo)
172+ }.eTag
173+ }
174+
175+ client.completeMultipartUpload {
176+ bucket = testBucket
177+ key = testObject
178+ uploadId = testUploadId
179+ multipartUpload = CompletedMultipartUpload {
180+ parts = listOf (
181+ CompletedPart {
182+ partNumber = 1
183+ eTag = eTagPartOne
184+ },
185+ CompletedPart {
186+ partNumber = 2
187+ eTag = eTagPartTwo
188+ },
189+ )
190+ }
191+ }
192+ }
193+
139194 private class S3ExpressInvocationTrackingInterceptor : HttpInterceptor {
140195 var s3ExpressInvocations = 0
141196
@@ -155,4 +210,13 @@ class S3ExpressTest {
155210 }
156211 }
157212 }
213+
214+ private class NoChecksumValidatingInterceptor : HttpInterceptor {
215+ override fun readBeforeTransmit (context : ProtocolRequestInterceptorContext <Any , HttpRequest >) {
216+ val headers = context.protocolRequest.headers
217+ if (headers.contains(S3_EXPRESS_SESSION_TOKEN_HEADER )) {
218+ assertFalse(headers.names().any { it.startsWith(" x-amz-checksum-" ) })
219+ }
220+ }
221+ }
158222}
0 commit comments