fix(s3): Force pathstyle when detecting custom endpoint url #7137
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Issue
#7136
Description
S3 requests fail against emulators such as LocalStack if they use virtual-host-style S3 requests with a single endpoint for all services (e.g.,
AWS_ENDPOINT_URL=https://localhost.localstack.cloud:4566
) rather than specifically configure a service-specific endpoint (e.g.,AWS_ENDPOINT_URL_S3=https://s3.localhost.localstack.cloud:4566
). This default behavior breaks seamless emulator compatibility with tools that depend on the JavaScript SDK, including the AWS Toolkit for VSCode and AWS CDK.The Python-based botocore library solves this problem here by adjusting the addressing style (i.e., whether to force path style) before passing the options to the endpoint ruleset resolver. Therefore, Python-based AWS tools (e.g., AWS CLI, AWS SAM) support S3 requests with emulators correctly.
Similar to botocore, the proposed change adjusts the default behavior to work seamlessly with emulators to support a single endpoint URL for all services, following this AWS specification: https://docs.aws.amazon.com/sdkref/latest/guide/feature-ss-endpoints.html
Testing
How was this change tested?
This change solves the default behavior when using a single endpoint (i.e.,
AWS_ENDPOINT_URL
) instead of service-specific endpoints (e.g.,AWS_ENDPOINT_URL_S3
) of the following cases:http://localhost.localstack.cloud:4566
http://localhost:4566
Testing and comparison to botocore is done using the following reproducer: https://github.com/joe4dev/s3-endpoint-url-testing
TODO: add SDK-specific tests
Additional context
Add any other context about the PR here.
The botocore solution here is not directly portable to the JavaScript SDK due to differences in configuration:
addressing_style=auto|virtual|path
forcePathStyle=false|true
We should maintain the option to test virtual-host-style S3 requests with emulators when providing a compatible endpoint. Therefore, we assume that a custom endpoint that includes
s3.
can resolve sub-domains and support virtual-host-style S3 requests.The conditional
!options.useAccelerateEndpoint
attempts to mirror the botocore implementationnot is_s3_accelerate_url(client_endpoint_url)
.The conditional
!options.endpoint.includes("s3.")
should rather be!options.endpoint.startsWith("s3.")
because everything befores3.
is treated as a bucket name in virtual-host-style requests. However, this results in a typing error because the "Property 'startsWith' does not exist on type 'Provider'.".Should such a change be part of the Smithy rules engine to be applicable for all AWS SDKs? Example from botocore for S3 endpoint ruleset: https://github.com/boto/botocore/blob/d1fd992119b5df4f4d2169e2383ab99288466e8b/botocore/data/s3/2006-03-01/endpoint-rule-set-1.json
Checklist
@public
tag and enable doc generation on the package?By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice.
Disclaimer: I work for LocalStack