0

I'm using a URL query string to debug my viewer-request and viewer-response lambda@edge functions by returning the event as JSON to the frontend (FYI so I can check for the presence/absence of certain things via an external monitoring tool).

This works fine with the viewer-request: if I go to https://example.org/?debug_viewer_request_event I get a JSON of the viewer-request event:

import json

def lambda_handler(event, context):

    request = event["Records"][0]["cf"]["request"]
    if "debug_viewer_request_event" in request["querystring"]:
        response = {
            "status": "200",
            "statusDescription": "OK",
            "headers": {
                "cache-control": [
                      {
                          "key": "Cache-Control",
                          "value": "no-cache"
                      }
                ],
                "content-type": [
                    {
                        "key": "Content-Type",
                        "value": "application/json"
                    }
                ]
            },
            "body": json.dumps(event)
        }
        return response
   # rest of viewer-request logic...

Testing with cURL:

curl -i https://example.org/?debug_viewer_request_event
HTTP/2 200 
content-type: application/json
content-length: 854
server: CloudFront
date: Mon, 26 Apr 2021 06:05:28 GMT
cache-control: no-cache
x-cache: LambdaGeneratedResponse from cloudfront
via: 1.1 xxxxxxxxxxx.cloudfront.net (CloudFront)
x-amz-cf-pop: AMS50-C1
x-amz-cf-id: pU0ItvQA1-r5v3yR1Dl6Z3VpPW_EuuUCHhnOD60uLhng...

{"Records": [{"cf": {"config": {"distributionDomainName": "xxxxxxx.cloudfront.net", "distributionId": "xxxxxxx", "eventType": "viewer-request", "requestId": "pU0ItvQA1-r5v3yR1Dl6Z3VpPW_EuuUCHhnOD60uLhng...

However when I do the same with the viewer-response I get a 502 error:

  • the code is the same except debug_viewer_request_event is debug_viewer_response_event
  • if I don't include the debug query string, the response is 200 OK so I know overall both lambdas are working properly (with the exception of the debug for the viewer-response)

Here is the cURL output:

curl -i https://example.org/?debug_viewer_response_event
HTTP/2 502 
content-type: text/html
content-length: 1013
server: CloudFront
date: Mon, 26 Apr 2021 06:07:39 GMT
x-cache: LambdaValidationError from cloudfront
via: 1.1 xxxxxxxxx.cloudfront.net (CloudFront)
x-amz-cf-pop: AMS50-C1
x-amz-cf-id: NqXQ-FFEsIX-fEt8IvlHFTYoQdrZSGPScq1H-KNwVWR0-xxxxxx

The Lambda function result failed validation: The function tried to add, delete, or change a read-only header

If I look at the docs, the list of "Read-only Headers for CloudFront Viewer Response Events" is:

  • Content-Encoding
  • Content-Length
  • Transfer-Encoding
  • Warning
  • Via

As far as I can see I'm not directly changing any of these headers, but I'm guessing because I'm modifying the response, headers such as Content-Length are modified

Q: Is there a way to return the viewer-response event as JSON to the frontend for debugging or is it simply not possible due to not being able to change Content-Length?

Max
  • 12,794
  • 30
  • 90
  • 142

1 Answers1

1

As far as I can see I'm not directly changing any of these headers, but I'm guessing because I'm modifying the response, headers such as Content-Length are modified

I agree, I think your issue is that you are returning the response instead of calling

callback(null, response);

where callback should be the third argument to your lambda handler func:

def lambda_handler(event, context, callback):

Since content-length is not mutable, we should assume (and I checked this is true in practice at least for viewer request functions), cloudfront will generate it for you when you generate a response in the edge function.

Johnny C
  • 1,799
  • 1
  • 16
  • 27