feat(cloudfront): serve POST, PUT, PATCH and DELETE viewer requests (#4229) #4

Merged
Zakaria merged 6 commits from feat/cloudfront-upstream-fixes into main 2026-10-24 18:38:32 +00:00
Owner
No description provided.
Zakaria added 6 commits 2026-10-24 18:38:15 +00:00
The serving controller only declared GET, HEAD and OPTIONS, so a write
method on a distribution host matched the resource class but no method
and fell through to a bare 405, even when the cache behavior allowed all
seven methods.

POST, PUT, PATCH and DELETE are now served under the same AllowedMethods
check (403 "Invalid method." otherwise) and the same trusted key group
enforcement as the read methods. Custom origins receive the method, the
viewer request body, its Content-Type and its Authorization header, with
Content-Length taken from the body; GET and HEAD still reach the origin
without Authorization, as on CloudFront. In-process S3 origins answer
these methods with 403 Access Denied instead of forwarding them, which
is documented.

Closes #4216

(cherry picked from commit 4ca0e085cd9064cf7672cb050049e9564b48ed55)
Custom origins only ever received the origin custom headers: the serving
controller built each origin request from them alone and dropped the
query string, whatever cache policy, origin request policy or legacy
ForwardedValues the matched cache behavior carried.

CloudFrontOriginRequestBuilder now decides what reaches the origin. With
a cache policy it forwards the union of the cache policy's
ParametersInCacheKeyAndForwardedToOrigin and the origin request policy
(every HeaderBehavior, CookieBehavior and QueryStringBehavior value).
Without one it applies legacy ForwardedValues, including the headers
CloudFront forwards by default. It also adds what CloudFront always
sends: Host for the origin unless the viewer Host is forwarded,
User-Agent "Amazon CloudFront", X-Forwarded-For, Via and X-Amz-Cf-Id.
Authorization is kept on the methods CloudFront does not cache, and
CloudFront-Forwarded-Proto, -Viewer-Address and -Viewer-Http-Version are
generated when a policy asks for them. Origin custom headers now replace
every same-named viewer header, and signing parameters are still never
forwarded.

The eight AWS managed origin request policies are served by their AWS
IDs and cannot be updated or deleted. With no origin request policy and
nothing selected by the cache policy, no cookies or query strings are
forwarded, as before.

Closes #4217

(cherry picked from commit f8f1b56ce9e9a1cbd63642ec1c4144fe8f6dd661)
A distribution read every origin response whole before answering the
viewer: an S3 origin's object through getObject, a custom origin's body
through the HTTP client into a byte array. A viewer's POST, PUT, PATCH
or DELETE body was likewise read whole before it was forwarded. So an
object or upload of about 2 GiB or more failed, and a smaller one could
run the heap out of memory.

S3 origins now open the object as a stream, the snapshot GetObject
serves, and custom origins return their response before its body is
read; either body is written to the viewer as it arrives, with its
Content-Length, or chunked as the origin sent it. A viewer's body is
streamed to the custom origin with its Content-Length, or chunked when
the viewer sent it chunked or, as HTTP/2 allows, with no length.

An origin response closed before its end, as when the viewer goes away
or a custom error page replaces it, cancels its request instead of
reading the rest of the body to reuse the connection. Since a streamed
response holds its connection for the whole transfer, one origin may
now use the whole connection pool, as CloudFront sets no per-origin
limit.

(cherry picked from commit 1f1d4f94dd8a179972bda124bc3aa47b9704f69b)
Closes #5425

Adapted: kept only the runtime check; the duplicate-name check that surrounds it
upstream comes from a later CloudFront Functions change not taken here.

(cherry picked from commit 8deac0a4244449470d6bd4bfa8769f8921d1533d)
(cherry picked from commit ee229af97569d5876f756f65ce7956726e2ed696)
The streaming change from upstream (#5278) serves S3 origins through
S3Service.openObject, which upstream added in a larger disk-streaming rework
(#4691) not taken here. This adds the same method on top of the existing
openObjectStream.
Zakaria merged commit 2969939a99 into main 2026-10-24 18:38:32 +00:00
Sign in to join this conversation.
No Reviewers
No Label
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: Zakaria/FlociClone#4