Update: Collected my thoughts better
I'm generating a unique identifier (UUID) for each user in the Viewer Request Lambda, and then selecting a cached page to return based upon that UUID. This works.
Ideally, this user would always have the same UUID.
I must generate that UUID in the Viewer Request if it is not present in a cookie on that Viewer Request. I also need that UUID to be set as a cookie, which of course happens in the response not the request.
Without caching, my server simply handles taking a custom header and creating a Set-Cookie in the response header.
I am not finding a way to handle this if I want to cache the page. I can ignore the request header for caching and serve the correct cached page, but then the user does not persist that UUID as no cookie is set to be utilized in their next request.
Has anyone accomplished something like this?
Things I'm trying
There are a few angles I'm working on with this, but haven't been able to get to work yet:
Some sort of setting in Cloudfront I'm unaware of that handles the header or other data pass-through from Viewer Request to Viewer Response, which could be used in a second lambda in Cloudfront.
Modify the response object headers preemptively in the Viewer Request. I don't think this is possible, as they return headers are not yet created, unless there's some built-in Cloudfront methodology I'm missing.
An existing pass-through header of some sort, I don't know if that's even a thing since I'm not intimately familiar with this aspect of request-response handling, but worth a shot.
Possibly (haven't tried yet though) I could create the entire response object in the Client Request lambda and somehow serve the cached page from there, modifying the response headers then passing it into the callback method.
Tobin's answer actually works, but is not a solid solution. If the user is not storing or serving their cookies it becomes an infinite loop, plus I'd rather not throw a redirect up in front of all of my pages if I can avoid it
Somewhat-working concept
- Viewer Request Lambda, when UUID not present in cookies, generates UUID
- Viewer Request Lambda sets UUID in cookies on header in request object. Callback with updated request object passed in
- Presence of UUID cookie busts Cloudfront cache
- Origin Request Lambda is triggered with UUID present
- Origin Request Lambda calls original request URL again via
http.get
with UUID cookie set (40KB limit makes doing this in the Viewer Request Lambda impractical) - Second scenario for Viewer Request Lambda, seeing UUID now present, strips the UUID cookie then continues the request normally
- Second Origin Request if not yet cached - Cached response if cached, as cache-busting UUID is not present - returns actual page HTML to First Origin Request
- First Origin Request receives response from
http.get
containing HTML - First Origin Request creates custom response object containing response body from
http.get
and Set-Cookie header set with our original UUID
Subsequent calls, having the UUID already set, will strip the UUID from the cookie (to prevent cache busting) and skip directly to the second-scenario in the Viewer Request Lambda which will directly load the cached version of the page.
I say "somewhat" because when I try to hit my endpoint, I get a binary file downloaded.
EDIT
This is because I was not setting the content-type
header. I now have only a 302 redirect problem... if I overcome this I'll post a full answer.
Original question
I have a function on the Viewer Request that picks an option and sets some things in the request before it's retrieved from the cache or server.
That works, but I want it to remember that choice for future users. The thought is to simply set a cookie I can read the next time that user comes through. As this is on the Viewer Request and not the Viewer Response I haven't figured out how to make that happen, or if it even is possible via the Lambda itself.
Viewer Request ->
Lambda picks options (needs to set cookie) ->
gets corresponding content ->
returns to Viewer with set-cookie header intact
I have seen the examples and been able to set cookies successfully in the Viewer Response via a Lambda. That doesn't help me much as the decision needs to be made on the request. Quite unsurprisingly adding this code into the Viewer Request shows nothing in the response.