|
| 1 | +/* |
| 2 | + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. |
| 3 | + * SPDX-License-Identifier: Apache-2.0 |
| 4 | + */ |
| 5 | +package aws.sdk.kotlin.codegen.customization.s3 |
| 6 | + |
| 7 | +import software.amazon.smithy.kotlin.codegen.KotlinSettings |
| 8 | +import software.amazon.smithy.kotlin.codegen.core.KotlinWriter |
| 9 | +import software.amazon.smithy.kotlin.codegen.integration.KotlinIntegration |
| 10 | +import software.amazon.smithy.kotlin.codegen.model.buildSymbol |
| 11 | +import software.amazon.smithy.kotlin.codegen.model.expectShape |
| 12 | +import software.amazon.smithy.kotlin.codegen.model.isStreaming |
| 13 | +import software.amazon.smithy.kotlin.codegen.rendering.protocol.ProtocolGenerator |
| 14 | +import software.amazon.smithy.kotlin.codegen.rendering.protocol.ProtocolMiddleware |
| 15 | +import software.amazon.smithy.model.Model |
| 16 | +import software.amazon.smithy.model.shapes.OperationShape |
| 17 | +import software.amazon.smithy.model.shapes.ServiceShape |
| 18 | + |
| 19 | +/** |
| 20 | + * Register interceptor to handle S3 error responses returned with an HTTP 200 status code. |
| 21 | + * see [aws-sdk-kotlin#199](https://github.com/awslabs/aws-sdk-kotlin/issues/199) |
| 22 | + */ |
| 23 | +class S3ErrorWith200StatusIntegration : KotlinIntegration { |
| 24 | + override fun enabledForService(model: Model, settings: KotlinSettings): Boolean = |
| 25 | + model.expectShape<ServiceShape>(settings.service).isS3 |
| 26 | + |
| 27 | + override fun customizeMiddleware( |
| 28 | + ctx: ProtocolGenerator.GenerationContext, |
| 29 | + resolved: List<ProtocolMiddleware>, |
| 30 | + ): List<ProtocolMiddleware> = resolved + listOf(S3HandleError200ResponseMiddleware) |
| 31 | +} |
| 32 | + |
| 33 | +private object S3HandleError200ResponseMiddleware : ProtocolMiddleware { |
| 34 | + override fun isEnabledFor(ctx: ProtocolGenerator.GenerationContext, op: OperationShape): Boolean { |
| 35 | + // we don't know for sure what operations S3 does this on. Go customized this for only a select few |
| 36 | + // like CopyObject/UploadPartCopy/CompleteMultipartUpload but Rust hit it on additional operations |
| 37 | + // (DeleteObjects). |
| 38 | + // Instead of playing whack-a-mole broadly apply this interceptor to everything but streaming responses |
| 39 | + // which adds a small amount of overhead to response processing. |
| 40 | + val output = ctx.model.expectShape(op.output.get()) |
| 41 | + return output.members().none { it.isStreaming || ctx.model.expectShape(it.target).isStreaming } |
| 42 | + } |
| 43 | + |
| 44 | + override val name: String = "Handle200ErrorsInterceptor" |
| 45 | + override fun render(ctx: ProtocolGenerator.GenerationContext, op: OperationShape, writer: KotlinWriter) { |
| 46 | + val symbol = buildSymbol { |
| 47 | + name = this@S3HandleError200ResponseMiddleware.name |
| 48 | + namespace = ctx.settings.pkg.subpackage("internal") |
| 49 | + } |
| 50 | + |
| 51 | + writer.write("op.interceptors.add(#T)", symbol) |
| 52 | + } |
| 53 | +} |
0 commit comments