Skip to content

S3: fix CORS handler + GZIP handling #12855

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

Merged
merged 1 commit into from
Jul 11, 2025
Merged

S3: fix CORS handler + GZIP handling #12855

merged 1 commit into from
Jul 11, 2025

Conversation

bentsku
Copy link
Contributor

@bentsku bentsku commented Jul 11, 2025

Motivation

As reported by #12854, we had an issue in S3 with GZIP handling when disabling S3 CORS.

This is because the GZIP handler depends on the service name being set in the context. However, we were only attaching the S3 service name if S3 CORS was not disabled.
This is a consequence of the ServiceNameParser being moved further down the chain with #11800

As a quick fix and bandaid, I've moved the logic around to always try to determine if it's an S3 request, even if S3 CORS is disabled.

However, we're muddling a bit the responsibility of the "CORS" handler with a mini service name parser. I'd suggest to get this first PR as a quick fix for the issue, because the first part will always need to be executed anyway.

As a follow-up, we could either split this in 2 handlers: one "S3 Detection" and one "S3 CORS", however the order will need to be respected closely, and the ordering of handlers inside a CompositeHandler is not something that is defined. It is rather implicit depending on the order you are appending your handlers, but it could be modified somewhere else.

My problem is the naming of the "S3CORSHandler", which has more responsibilities than just CORS

So for now I'm proposing to do it this way to quickly solve the issue, which does not really have a cost anyway, but we'll need to address the naming + responsibility issue soon 👀

Changes

  • always execute the S3 detection in the S3 CORS handler
  • add a small test validating the fix

fixes #12854

@bentsku bentsku added this to the 4.7 milestone Jul 11, 2025
@bentsku bentsku self-assigned this Jul 11, 2025
@bentsku bentsku added aws:s3 Amazon Simple Storage Service semver: patch Non-breaking changes which can be included in patch releases labels Jul 11, 2025
@bentsku bentsku requested review from alexrashed, thrau and k-a-il July 11, 2025 10:33
Copy link

S3 Image Test Results (AMD64 / ARM64)

    2 files    2 suites   8m 46s ⏱️
  515 tests 465 ✅  50 💤 0 ❌
1 030 runs  930 ✅ 100 💤 0 ❌

Results for commit c646af8.

Copy link

Test Results - Preflight, Unit

21 854 tests  ±0   20 197 ✅ ±0   6m 18s ⏱️ ±0s
     1 suites ±0    1 657 💤 ±0 
     1 files   ±0        0 ❌ ±0 

Results for commit c646af8. ± Comparison against base commit f0f8045.

Copy link

Test Results (amd64) - Acceptance

7 tests  ±0   5 ✅ ±0   3m 9s ⏱️ -1s
1 suites ±0   2 💤 ±0 
1 files   ±0   0 ❌ ±0 

Results for commit c646af8. ± Comparison against base commit f0f8045.

Copy link

Test Results (amd64) - Integration, Bootstrap

    5 files  ±    0      5 suites  ±0   1h 26m 31s ⏱️ - 53m 59s
2 279 tests  - 3 003  1 664 ✅  - 2 689  615 💤  - 314  0 ❌ ±0 
2 285 runs   - 3 003  1 664 ✅  - 2 689  621 💤  - 314  0 ❌ ±0 

Results for commit c646af8. ± Comparison against base commit f0f8045.

This pull request removes 3004 and adds 1 tests. Note that renamed tests count towards both.
tests.aws.scenario.bookstore.test_bookstore.TestBookstoreApplication ‑ test_lambda_dynamodb
tests.aws.scenario.bookstore.test_bookstore.TestBookstoreApplication ‑ test_opensearch_crud
tests.aws.scenario.bookstore.test_bookstore.TestBookstoreApplication ‑ test_search_books
tests.aws.scenario.bookstore.test_bookstore.TestBookstoreApplication ‑ test_setup
tests.aws.scenario.kinesis_firehose.test_kinesis_firehose.TestKinesisFirehoseScenario ‑ test_kinesis_firehose_s3
tests.aws.scenario.lambda_destination.test_lambda_destination_scenario.TestLambdaDestinationScenario ‑ test_destination_sns
tests.aws.scenario.lambda_destination.test_lambda_destination_scenario.TestLambdaDestinationScenario ‑ test_infra
tests.aws.scenario.loan_broker.test_loan_broker.TestLoanBrokerScenario ‑ test_prefill_dynamodb_table
tests.aws.scenario.loan_broker.test_loan_broker.TestLoanBrokerScenario ‑ test_stepfunctions_input_recipient_list[step_function_input0-SUCCEEDED]
tests.aws.scenario.loan_broker.test_loan_broker.TestLoanBrokerScenario ‑ test_stepfunctions_input_recipient_list[step_function_input1-SUCCEEDED]
…
tests.aws.services.s3.test_s3_cors.TestS3Cors ‑ test_s3_cors_disabled

Copy link

LocalStack Community integration with Pro

    2 files  ±    0      2 suites  ±0   1h 3m 25s ⏱️ - 39m 40s
2 255 tests  - 2 668  1 637 ✅  - 2 508  618 💤  - 158  0 ❌  - 2 
2 257 runs   - 2 668  1 637 ✅  - 2 508  620 💤  - 158  0 ❌  - 2 

Results for commit c646af8. ± Comparison against base commit f0f8045.

This pull request removes 2669 and adds 1 tests. Note that renamed tests count towards both.
tests.aws.scenario.bookstore.test_bookstore.TestBookstoreApplication ‑ test_lambda_dynamodb
tests.aws.scenario.bookstore.test_bookstore.TestBookstoreApplication ‑ test_opensearch_crud
tests.aws.scenario.bookstore.test_bookstore.TestBookstoreApplication ‑ test_search_books
tests.aws.scenario.bookstore.test_bookstore.TestBookstoreApplication ‑ test_setup
tests.aws.scenario.kinesis_firehose.test_kinesis_firehose.TestKinesisFirehoseScenario ‑ test_kinesis_firehose_s3
tests.aws.scenario.lambda_destination.test_lambda_destination_scenario.TestLambdaDestinationScenario ‑ test_destination_sns
tests.aws.scenario.lambda_destination.test_lambda_destination_scenario.TestLambdaDestinationScenario ‑ test_infra
tests.aws.scenario.loan_broker.test_loan_broker.TestLoanBrokerScenario ‑ test_prefill_dynamodb_table
tests.aws.scenario.loan_broker.test_loan_broker.TestLoanBrokerScenario ‑ test_stepfunctions_input_recipient_list[step_function_input0-SUCCEEDED]
tests.aws.scenario.loan_broker.test_loan_broker.TestLoanBrokerScenario ‑ test_stepfunctions_input_recipient_list[step_function_input1-SUCCEEDED]
…
tests.aws.services.s3.test_s3_cors.TestS3Cors ‑ test_s3_cors_disabled

Copy link
Member

@alexrashed alexrashed left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice catch! I added a comment just to verify that I did grasp the implications of this PR correctly, but in my opinion they are minimal and this PR is good to go.

On the broader topic: I think the problem here is just that this is a conceptional problem we are having with our one-dimensional handler chain, in combination with multiple different routing mechanisms (internal endpoints, dynamic edge routes, service routes), and a clean solution to this issue would mean that we would have to have a generalized routing which then invokes service specific handler chains... 🤔

context.service = self._service

if config.DISABLE_CUSTOM_CORS_S3:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thought: I'll just ramble around here, just to make sure that we are on the same page when it comes to the (performance) implications of this PR. Please correct me if any of this is wrong 😅

So this config is false by default. This means in the vast majority of cases, we already already did execute the minimum S3 service detection, and for this (default) case, this PR does not have any implications.

However, for users who actively set DISABLE_CUSTOM_CORS_S3 in their configuration, this PR will change the behavior such that this simplified service routing heuristic is now being executed.

If this is the case, I would say that this change is absolutely reasonable, and the implications are pretty much minimal.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Exactly, this is exactly it. Thanks for making it clearer 👌

Copy link
Contributor Author

@bentsku bentsku left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed about the conceptual problem. This problem, plus the fact that S3 "is a web server" and is really hard to route does not help us into generalizing this. Thanks for the quick review!

context.service = self._service

if config.DISABLE_CUSTOM_CORS_S3:
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Exactly, this is exactly it. Thanks for making it clearer 👌

@bentsku bentsku merged commit fc4c928 into master Jul 11, 2025
59 checks passed
@bentsku bentsku deleted the fix-s3-gzip-cors branch July 11, 2025 13:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
aws:s3 Amazon Simple Storage Service semver: patch Non-breaking changes which can be included in patch releases
Projects
None yet
Development

Successfully merging this pull request may close these issues.

bug: setting DISABLE_CUSTOM_CORS_S3=1 decodes S3 objects with Content-Encoding: gzip
2 participants