-
Notifications
You must be signed in to change notification settings - Fork 50
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Exception when using Flow#toByteStream
#1157
Comments
Hi, thanks for the report. It is indeed a bug and we will work on a fix. In the short term, you can work around this by overriding the fun hashSpecificationInterceptor(hash: String) = object : HttpInterceptor {
override suspend fun modifyBeforeSigning(context: ProtocolRequestInterceptorContext<Any, HttpRequest>): HttpRequest {
context.executionContext[AwsSigningAttributes.HashSpecification] = HashSpecification.Precalculated(hash)
return super.modifyBeforeSigning(context)
}
}
val bytes = "abc".toByteArray(Charsets.UTF_8)
client.withConfig {
interceptors = mutableListOf(hashSpecificationInterceptor(bytes.sha256().encodeToHex()))
}.putObject {
bucket = "test"
key = "object_non_repeatable_small"
checksumAlgorithm = ChecksumAlgorithm.Sha256
contentLength = bytes.size.toLong()
body = flow {
emit(bytes)
}.toByteStream(this@runBlocking)
} |
In my local testing, this is fixed by passing the client.putObject {
bucket = <bucket>
key = "object_non_repeatable_small"
checksumAlgorithm = ChecksumAlgorithm.Sha256
checksumSha256 = <your_checksum> // optional, request succeeds with or without this
// contentLength = bytes.size.toLong() // don't set contentLength here
body = flow {
emit(bytes)
}.toByteStream(this@runBlocking, contentLength = bytes.size.toLong()) // instead, set contentLength here
} Does this meet your expectations? The optimization to reuse a provided SHA-256 checksum is a great suggestion and we will continue tracking that. |
i can get it working by setting only |
Thanks @lauzadis setting |
|
Describe the bug
For example a
putObject
fails when usingflow { ... }.toByteStream()
This looks similar to #1130
Expected behavior
The object should be put successfully.
Current behavior
An exception is thrown"
Steps to Reproduce
I put up a example project to reproduce the issue here: https://github.com/felixscheinost/reproduce-aws-kotlin-s3-bytestream-oneshot-issue
The example requires Docker to be installed as it spins up a MinIO container.
Run
./gradlew :run
to reproduce the issue.Possible Solution
I included a workaround in the example project. Uncomment the lines doing an
interceptors.add
when constructing the S3Client.I think it is correct that the payload can't be signed when the stream is not replayable and when the SHA-256 isn't known in advance.
But I think the library could contain a special case similar to my workaround: When the stream is not replayable AND the SHA256 is known, use that for the signature.
(SIdenote: This might be a nice little optimization in general? Even when the stream is replayable? Users of the library might often set
checksumSha256
)Context
No response
AWS Kotlin SDK version used
1.0.19
Platform (JVM/JS/Native)
JVM
Operating System and version
macOS 13.6
The text was updated successfully, but these errors were encountered: