0

I am doing something probably unusual and ill-advised to overcome a limitation with request and response behavior.

I am having an Origin Request Lambda call back to the initial URL via https.get, with a parameter passed in the header. This will cause a secondary behavior for the same URL request, allowing me to mutate the response in the original Origin Request Lambda before returning a custom response.

The long version:

  1. Function 1 of Viewer Request Lambda fires when there is not the custom property my-uuid in the header. It will create the UUID, set that UUID in the my-uuid property on the header, and then fire the callback with the updated header.

  2. Function 1 of the Origin Request Lambda fires where my-uuid header is present. Cloudfront is configured to cache based on this header alone, so that the generated UUID will always trigger Function 1 of the Origin Request Lambda. Function 1 makes an https.get call to the URL called in the original request, but passed along the my-uuid header.

  3. Function 2 of the Viewer Request Lambda fires based on the presence of the my-uuid header in this second run. This simply strips the my-uuid header and fires the callback sans my-uuid header property.

    1. This page has been called before and is in the Cloudfront cache. As the request does not have the my-uuid header property, there is no cache-busting, and the cached page is returned to Function 1 of the Origin Request Lambda. OR:

    2. This page has not yet been cached, so Function 2 of the Origin Request Lambda is invoked. In the absence of the my-uuid header property, it simply fires the callback with the request as-is.

  4. Either way, Function 1 of the Origin Request Lambda receives the HTML from the https.get call, and uses this to create a custom response object with the body of the desired page but also the set-cookie header containing the UUID I generated in the initial Viewer Request Lambda. This custom response object is passed into the callback.

While on that path, the solution I crafted brought me to another issue:

Steps 3 and 4.2 (the Function 2 of either Request Lambda) are not logging at all when I call my endpoint via Postman. I have a plethora of console logs to track what's happening internally. However, the response has any headers I try to set in the final response (except, annoyingly, the set-cookie header which appears to simply disappear and is why I need the logging to work).

If I set the my-uuid header on my Postman request to trigger the Function 2 behavior, I do see those in the log.

John Rotenstein
  • 241,921
  • 22
  • 380
  • 470
Randy Hall
  • 7,716
  • 16
  • 73
  • 151
  • Well, I can't accuse you of not trying to think outside the box... but it's ultimately not clear exactly why you are going through all these gyrations. The correct way to set a nonexistent cookie would be to return a 30x redirect to the same URI with `Set-Cookie`. But if you insist on not doing that, then inject the cookie into the request with a Viewer Request trigger and then emit a `Set-Cookie` with the same value in a Viewer Response trigger. – Michael - sqlbot Mar 28 '19 at 21:23
  • (A viewer response trigger can access the request object as it existed after modification by a viewer request trigger for the same HTTP transaction). – Michael - sqlbot Mar 28 '19 at 21:25
  • Can you try to add set-cookies in the origin response lambda@edge function itself ? It can be then used as cache key as well. – James Dean Mar 29 '19 at 04:49
  • @Michael-sqlbot How do you access the request object in the viewer response? I've been looking for literally that for two weeks, this whole work-around is because I couldn't figure that out (and ideally didn't want to do the redirect) – Randy Hall Mar 29 '19 at 13:31
  • @RandyHall the request is at the same place in a [response event](https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/lambda-event-structure.html#lambda-event-structure-response) as it is the request event, `event.Records[0].cf.request`. In a viewer-response trigger, this part of the structure contains the *"request that CloudFront received from the viewer and that might have been modified by the Lambda function that was triggered by a viewer request event."* – Michael - sqlbot Mar 29 '19 at 14:44
  • @Michael-sqlbot Seriously, 17 days ago I posted this question looking for exactly what you just said and I completely missed. Go post that as an answer over here and I'll give you the credit for this simple thing: https://stackoverflow.com/questions/55128624/cloudfront-lambdaedge-set-cookie-on-viewer-request – Randy Hall Mar 29 '19 at 19:31

1 Answers1

0

I just came across the same issue today and found this SO question.

I was able to make the cookies set by origin request Lambda work by changing the "Forward Cookies" chache behavior setting from "None (Improves Caching)" to "Forward all, cache based on all"

Tomasz
  • 657
  • 3
  • 9