fix(aws/router): build the S3 key from the baseless uri - #6980
Open
OmeshKandregula wants to merge 2 commits into
Open
fix(aws/router): build the S3 key from the baseless uri#6980OmeshKandregula wants to merge 2 commits into
OmeshKandregula wants to merge 2 commits into
Conversation
Both S3 branches match on baselessUri, then build the key from the full request uri, so a site with a base path asks S3 for <dir><base><path> while its assets are uploaded at <dir><path>. Every static asset 404s, surfacing as 403 AccessDenied because the OAC principal cannot list. The comment above the first branch already states the intent: files are stored in the root.
Four of these fail on the parent commit with the base left in the key, which is the bug: /_assets/admin/board/_next/static/css/abc123.css against assets uploaded at /_assets/_next/static/css/abc123.css. The other three are guards rather than reproductions. They pass either way and exist so a future change to the key building cannot quietly break the cases that already worked: a site with no base at all, the choice of S3 origin, and a path the S3 routes do not match still reaching the server. loadRouteSite now takes the same input type as createContext. It was declaring a narrower one, so a test could not stub the KV store or observe which origin was selected, which is what the KVS-matched file case needs.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.
The problem
A site deployed with
sst.aws.Nextjswhosenext.config.tssets abasePathserves its HTML fine and then fails to load a single stylesheet or script. The
page renders as unstyled markup. Every request under
<base>/_next/static/*comes back as:
The 403 is misleading and cost me a while: it is a missing key, not a
permissions problem. The OAC principal has
s3:GetObjectbut nots3:ListBucket, so S3 answers 403 rather than 404.Cause
Both S3 branches of the router function match against the baseless uri and
then build the S3 key from the full one, so the base path ends up in the key.
The assets are uploaded without it.
platform/src/components/aws/router.ts, insideCF_ROUTER_INJECTION:The comment on the first branch already states the intent: files are stored in
the root.
sst.aws.Nextjsuploads them accordingly, with no base awareness:So for a site based at
/admin/board, CloudFront asks S3 forwhile the deploy uploaded
The change
Two lines: build the key from
baselessUriin both branches, which is what theexisting comment says should happen.
Tests
Seven cases in
platform/test/components/cloudfront.test.ts. Four of them failon the parent commit with the base left in the key:
The other three pass either way on purpose. They are guards rather than
reproductions, so that a later change to the key building cannot quietly break
what already worked: a site with no base at all, the S3 origin actually being
selected, and a path the S3 routes do not match still reaching the server.
loadRouteSitenow takes the same input type ascreateContext. It wasdeclaring a narrower one, so a test could not stub the KV store or observe
which origin was chosen, and the KVS-matched case needs both.
Two things I did not touch
custom404branch goes the other way and adds the base explicitly(
metadata.s3.dir + (metadata.base ? metadata.base : "") + metadata.custom404).If files really are stored in the root then that looks wrong too, but I have
not exercised that path and did not want to change behaviour I could not
test.
site with no servers, where it exists to trigger
customErrorResponses, so Ileft it alone for the same reason.
Happy to fold either in if you would prefer them consistent.
Notes
CF_ROUTER_INJECTIONis size-sensitive against the 10KB CloudFront Functionslimit. This reuses the existing
baselessUrivariable, so the injected codegets slightly smaller.
4.17.1 and
dev.