CloudFront 함수 이벤트 구조 - Amazon CloudFront

CloudFront 함수 이벤트 구조

CloudFront 함수는 함수를 실행할 때 event 객체를 함수 코드에 입력으로 전달합니다. 함수를 테스트할 때 event 객체를 생성하여 함수에 전달합니다. 함수를 테스트하기 위해 event 객체를 생성할 때 distributionDomainName 객체의 distributionId, requestIdcontext 필드를 생략할 수 있습니다. 헤더의 이름이 소문자인지 확인합니다. CloudFront Functions가 프로덕션 환경에서 함수에 전달하는 event 객체의 경우 항상 소문자입니다.

다음은 이 이벤트 객체의 구조에 대한 개요를 보여 줍니다.

{ "version": "1.0", "context": { <context object> }, "viewer": { <viewer object> }, "request": { <request object> }, "response": { <response object> } }

자세한 정보는 다음 주제를 참조하세요.

버전 필드

version 필드에는 CloudFront 함수 이벤트 객체의 버전을 지정하는 문자열이 포함되어 있습니다. 현재 버전은 1.0입니다.

컨텍스트 객체

context 객체는 이벤트에 대한 컨텍스트 정보를 포함합니다. 여기에는 다음 필드가 포함됩니다.

distributionDomainName

이벤트와 연결된 배포의 CloudFront 도메인 이름(예: d111111abcdef8.cloudfront.net)입니다.

distributionId

이벤트와 연결된 배포의 ID(예: EDFDVBD6EXAMPLE)입니다.

eventType

이벤트 유형(viewer-request 또는 viewer-response)입니다.

requestId

CloudFront 요청(및 연결된 응답)을 고유하게 식별하는 문자열입니다.

최종 사용자 객체

viewer 객체는 요청을 보낸 최종 사용자(클라이언트)의 IP 주소 값이 있는 ip 필드를 포함합니다. 최종 사용자가 HTTP 프록시 또는 로드 밸런서를 사용하여 요청을 전송한 경우 이 값은 프록시 또는 로드 밸런서의 IP 주소입니다.

요청 객체

request 객체는 viewer-to-CloudFront HTTP 요청의 표현을 포함합니다. 함수에 전달된 event 객체에서 request 객체는 CloudFront가 뷰어에게 받은 실제 요청을 나타냅니다.

함수 코드가 CloudFront에 request 객체를 반환하는 경우 동일한 구조를 사용해야 합니다.

request 객체는 다음 필드를 포함합니다.

method

요청의 HTTP 메서드. 함수 코드가 request를 반환하면 이 필드를 수정할 수 없습니다. 이 필드는 request 객체에서 유일한 읽기 전용 필드입니다.

uri

요청된 객체의 상대 경로입니다.

참고

함수가 uri 값을 수정하는 경우 다음 사항이 적용됩니다.

  • uri 값은 슬래시(/)로 시작해야 합니다.

  • 함수가 uri 값을 변경하는 경우 이로 인해 최종 사용자가 요청 중인 객체가 변경됩니다.

  • 함수가 uri 값을 변경하는 경우 이로 인해 요청 또는 요청이 전송되는 오리진에 대한 캐시 동작이 변경되지 않습니다.

querystring

요청의 쿼리 문자열을 나타내는 객체입니다. 요청에 쿼리 문자열이 포함되지 않더라도 request 객체에는 여전히 빈 querystring 객체가 포함됩니다.

querystring 객체는 요청의 각 쿼리 문자열 파라미터에 대해 하나의 필드를 포함합니다.

headers

요청의 HTTP 헤더를 나타내는 객체입니다. 요청에 Cookie 헤더가 포함되어 있으면 해당 헤더는 headers 객체의 일부가 아닙니다. 쿠키는 cookies 객체에서 별도로 표시됩니다.

headers 객체는 요청의 각 헤더에 대해 하나의 필드를 포함합니다. 헤더 이름은 이벤트 객체에서 소문자로 변환되므로, 헤더 이름은 함수 코드에 의해 추가될 때 소문자여야 합니다. CloudFront 함수가 이벤트 객체를 HTTP 요청으로 다시 변환하는 경우 헤더 이름에 있는 각 단어의 첫 글자가 대문자로 표시됩니다. 단어는 하이픈(-)으로 구분됩니다. 예를 들어 함수 코드가 example-header-name이라는 이름의 헤더를 추가하는 경우, CloudFront는 이것을 HTTP 요청에서 Example-Header-Name으로 변환합니다.

cookies

요청(Cookie 헤더)의 쿠키를 나타내는 객체입니다.

cookies 객체는 요청의 각 쿠키에 대해 하나의 필드를 포함합니다.

쿼리 문자열, 헤더 및 쿠키의 구조에 대한 자세한 내용은 쿼리 문자열, 헤더 및 쿠키 구조 단원을 참조하세요.

예제 event 객체에 대해서는 예시 이벤트 객체 단원을 참조하세요.

응답 객체

response 객체는 CloudFront-to-Viewer HTTP 응답의 표현을 포함합니다. 함수에 전달된 event 객체에서 response 객체는 뷰어 요청에 대한 CloudFront의 실제 응답을 나타냅니다.

함수 코드가 response 객체를 반환하는 경우 이 동일한 구조를 사용해야 합니다.

response 객체는 다음 필드를 포함합니다.

statusCode

응답의 HTTP 상태 코드입니다. 이 값은 문자열이 아닌 정수입니다.

함수는 statusCode를 생성하거나 수정할 수 있습니다.

statusDescription

응답의 HTTP 상태 설명입니다. 함수 코드에서 응답을 생성하는 경우 이 필드는 선택 사항입니다.

headers

응답에서 HTTP 헤더를 나타내는 객체입니다. 응답에 Set-Cookie 헤더가 포함되어 있으면 해당 헤더는 headers 객체의 일부가 아닙니다. 쿠키는 cookies 객체에서 별도로 표시됩니다.

headers 객체는 응답의 각 헤더에 대해 하나의 필드를 포함합니다. 헤더 이름은 이벤트 객체에서 소문자로 변환되므로, 헤더 이름은 함수 코드에 의해 추가될 때 소문자여야 합니다. CloudFront 함수가 이벤트 객체를 HTTP 응답으로 다시 변환하는 경우 헤더 이름에 있는 각 단어의 첫 글자가 대문자로 표시됩니다. 단어는 하이픈(-)으로 구분됩니다. 예를 들어 함수 코드가 example-header-name이라는 이름의 헤더를 추가하는 경우, CloudFront는 이것을 HTTP 응답에서 Example-Header-Name으로 변환합니다.

cookies

응답(Set-Cookie 헤더)에서 쿠키를 나타내는 객체입니다.

cookies 객체는 응답의 각 쿠키에 대해 하나의 필드를 포함합니다.

body

body 필드 추가는 선택 사항이며 함수에서 지정하지 않는 한 response 객체에 표시되지 않습니다. 함수는 CloudFront 캐시 또는 오리진에서 반환된 원래 본문에 액세스할 수 없습니다. 뷰어 응답 함수에서 body 필드를 지정하지 않으면 CloudFront 캐시 또는 오리진에서 반환되는 원래 본문이 뷰어에게 반환됩니다.

CloudFront에서 뷰어에게 사용자 지정 본문을 반환하도록 하려면 data 필드에 본문 콘텐츠를 지정하고 encoding 필드에 본문 인코딩을 지정하세요. 인코딩을 일반 텍스트("encoding": "text") 또는 Base64로 인코딩된 콘텐츠("encoding": "base64")로 지정할 수 있습니다.

단축키로 body 필드("body": "<specify the body content here>")에서 직접 본문 콘텐츠를 지정할 수도 있습니다. 이 작업을 수행할 때는 dataencoding 필드를 생략하세요. 이 경우 CloudFront는 본문을 일반 텍스트로 취급합니다.

encoding

body 콘텐츠(data필드)의 인코딩입니다. 유일하게 유효한 인코딩은 textbase64입니다.

encodingbase64로 지정하지만 본문이 유효한 base64가 아닌 경우 CloudFront는 오류를 반환합니다.

data

body 콘텐츠입니다.

수정된 상태 코드 및 본문 콘텐츠에 대한 자세한 내용은 상태 코드 및 본문를 참조하세요.

헤더 및 쿠키의 구조에 대한 자세한 내용은 쿼리 문자열, 헤더 및 쿠키 구조 단원을 참조하세요.

예제 response 객체에 대해서는 예시 응답 객체 단원을 참조하세요.

상태 코드 및 본문

CloudFront Functions를 사용하여 뷰어 응답 상태 코드를 업데이트하고 응답 본문 전체를 새것으로 바꾸거나 제거할 수 있습니다. CloudFront 캐시 또는 오리진에서 응답의 여러 측면을 평가한 후 뷰어 응답을 업데이트하는 일반적인 시나리오는 다음과 같습니다.

  • 상태를 변경하여 HTTP 200 상태 코드를 설정하고 정적 본문 콘텐츠를 생성하여 뷰어에게 반환합니다.

  • 상태를 변경하여 HTTP 301 또는 302 상태 코드를 설정하고 사용자를 다른 웹 페이지로 리디렉션합니다.

  • 뷰어 응답의 본문을 제공할지 아니면 삭제할지 결정합니다.

참고

오리진에서 400 이상의 HTTP 오류를 반환하는 경우 CloudFront Function이 실행되지 않습니다. 자세한 정보는 모든 엣지 함수에 대한 제한 사항 섹션을 참조하세요.

HTTP 응답 본문을 사용하여 작업 중일 때 CloudFront Functions가 응답 본문에 액세스하지 못합니다. 원하는 값으로 설정하여 본문 콘텐츠를 바꾸거나 값을 비어 있음으로 설정하여 본문을 제거할 수 있습니다. 함수의 본문 필드를 업데이트하지 않은 경우 CloudFront 캐시 또는 오리진에서 반환된 원래 본문이 뷰어에게 반환됩니다.

작은 정보

CloudFront Functions를 사용하여 본문을 교체하는 경우content-encoding, content-type 또는 content-length 등의 해당 헤더를 새 본문 콘텐츠에 맞게 정렬해야 합니다.

예를 들어 CloudFront 오리진 또는 캐시가 content-encoding: gzip을 반환하지만 뷰어 응답 함수가 일반 텍스트인 본문을 설정하는 경우 함수는 content-encodingcontent-type 헤더도 그에 따라 변경해야 합니다.

CloudFront Function이 400 이상의 HTTP 오류를 반환하도록 구성된 경우 동일한 상태 코드에 대해 지정한 사용자 지정 오류 페이지가 뷰어에게 표시되지 않습니다.

쿼리 문자열, 헤더 및 쿠키는 동일한 구조를 공유합니다. 쿼리 문자열은 요청에 표시될 수 있습니다. 헤더는 요청 및 응답에 표시됩니다. 쿠키는 요청 및 응답에 표시됩니다.

각 쿼리 문자열, 헤더 또는 쿠키는 상위 querystring, headers 또는 cookies 객체 내에서 고유한 필드입니다. 필드 이름은 쿼리 문자열, 헤더 또는 쿠키의 이름입니다. 각 필드에는 쿼리 문자열, 헤더 또는 쿠키의 값이 있는 value 속성이 포함됩니다.

쿼리 문자열 값 또는 쿼리 문자열 객체

함수는 쿼리 문자열 객체 외에도 쿼리 문자열 값을 반환할 수 있습니다. 쿼리 문자열 값을 사용하여 쿼리 문자열 파라미터를 사용자 지정 순서로 정렬할 수 있습니다.

함수 코드에서 쿼리 문자열을 수정하려면 다음과 같은 코드를 사용합니다.

var request = event.request; request.querystring = 'ID=42&Exp=1619740800&TTL=1440&NoValue=&querymv=val1&querymv=val2,val3';

헤더에 대한 특별 고려 사항

헤더의 경우, 헤더 이름은 이벤트 객체에서 소문자로 변환되므로, 헤더 이름은 함수 코드에 의해 추가될 때 소문자여야 합니다. CloudFront 함수가 이벤트 객체를 HTTP 요청 또는 응답으로 다시 변환하는 경우 헤더 이름에 있는 각 단어의 첫 글자가 대문자로 표시됩니다. 단어는 하이픈(-)으로 구분됩니다. 예를 들어 함수 코드가 example-header-name이라는 이름의 헤더를 추가하는 경우, CloudFront는 이것을 HTTP 요청 또는 응답에서 Example-Header-Name으로 변환합니다.

HTTP 요청에서 다음 Host 헤더를 고려합니다.

Host: video.example.com

이 헤더는 request 객체에서 다음과 같이 표시됩니다.

"headers": { "host": { "value": "video.example.com" } }

함수 코드의 Host 헤더에 액세스하려면 다음과 같은 코드를 사용합니다.

var request = event.request; var host = request.headers.host.value;

함수 코드에서 헤더를 추가하거나 수정하려면 다음과 같은 코드를 사용합니다(이 코드는 X-Custom-Header 값이 있는 example value(이)라는 이름의 헤더를 추가함).

var request = event.request; request.headers['x-custom-header'] = {value: 'example value'};

중복 쿼리 문자열, 헤더 및 쿠키(multiValue 배열)

HTTP 요청 또는 응답은 동일한 이름의 하나 이상의 쿼리 문자열, 헤더 또는 쿠키를 포함할 수 있습니다. 이 경우 중복 쿼리 문자열, 헤더 또는 쿠키가 request 또는 response 객체의 한 필드로 축소되지만 이 필드에는 multiValue(이)라는 추가 속성이 포함되어 있습니다. multiValue 속성에는 중복 쿼리 문자열, 헤더 또는 쿠키의 각 값이 포함된 배열이 포함됩니다.

예를 들어 다음 Accept 헤더가 있는 HTTP 요청을 고려합니다.

Accept: application/json Accept: application/xml Accept: text/html

이러한 헤더는 request 객체에 다음과 같이 표시됩니다.

"headers": { "accept": { "value": "application/json", "multiValue": [ { "value": "application/json" }, { "value": "application/xml" }, { "value": "text/html" } ] } }
참고

첫 번째 헤더 값(이 경우 application/json)은 valuemultiValue 속성 모두에서 반복됩니다. 이렇게 하면 multiValue 배열을 반복하여 모든 값에 액세스할 수 있습니다.

함수 코드가 multiValue 배열이 있는 쿼리 문자열, 헤더 또는 쿠키를 수정하는 경우 CloudFront 함수는 다음 규칙을 사용하여 변경 사항을 적용합니다.

  1. multiValue 배열이 존재하고 수정이 있으면 해당 수정이 적용됩니다. value 속성의 첫 번째 요소는 무시됩니다.

  2. 그렇지 않으면 value 속성에 대한 수정 사항이 적용되고 후속 값(있는 경우)은 변경되지 않습니다.

multiValue 속성은 앞의 예제와 같이 HTTP 요청 또는 응답에 동일한 이름의 중복 쿼리 문자열, 헤더 또는 쿠키가 포함된 경우에만 사용됩니다. 그러나 단일 쿼리 문자열, 헤더 또는 쿠키에 값이 여러 개 있으면 multiValue 속성이 사용되지 않습니다.

예를 들어 세 개의 값을 포함하는 하나의 Accept 헤더가 있는 요청을 고려합니다.

Accept: application/json, application/xml, text/html

이 헤더는 request 객체에서 다음과 같이 표시됩니다.

"headers": { "accept": { "value": "application/json, application/xml, text/html" } }

HTTP 응답의 Set-Cookie 헤더에서 헤더에는 쿠키의 이름-값 쌍과 세미콜론으로 구분된 속성 집합이 포함됩니다.

Set-Cookie: cookie1=val1; Secure; Path=/; Domain=example.com; Expires=Wed, 05 Apr 2021 07:28:00 GMT

response 객체에서 이러한 속성은 쿠키 필드의 attributes 속성에 표시됩니다. 예를 들어, 앞의 Set-Cookie 헤더는 다음과 같이 표시됩니다.

"cookie1": { "value": "val1", "attributes": "Secure; Path=/; Domain=example.com; Expires=Wed, 05 Apr 2021 07:28:00 GMT" }

예시 응답 객체

다음 예시는 본문이 뷰어 응답 함수로 대체된 response 객체(뷰어 응답 함수의 출력)를 보여줍니다.

{ "response": { "statusCode": 200, "statusDescription": "OK", "headers": { "date": { "value": "Mon, 04 Apr 2021 18:57:56 GMT" }, "server": { "value": "gunicorn/19.9.0" }, "access-control-allow-origin": { "value": "*" }, "access-control-allow-credentials": { "value": "true" }, "content-type": { "value": "text/html" }, "content-length": { "value": "86" } }, "cookies": { "ID": { "value": "id1234", "attributes": "Expires=Wed, 05 Apr 2021 07:28:00 GMT" }, "Cookie1": { "value": "val1", "attributes": "Secure; Path=/; Domain=example.com; Expires=Wed, 05 Apr 2021 07:28:00 GMT", "multiValue": [ { "value": "val1", "attributes": "Secure; Path=/; Domain=example.com; Expires=Wed, 05 Apr 2021 07:28:00 GMT" }, { "value": "val2", "attributes": "Path=/cat; Domain=example.com; Expires=Wed, 10 Jan 2021 07:28:00 GMT" } ] } }, // Adding the body field is optional and it will not be present in the response object // unless you specify it in your function. // Your function does not have access to the original body returned by the CloudFront // cache or origin. // If you don't specify the body field in your viewer response function, the original // body returned by the CloudFront cache or origin is returned to viewer. "body": { "encoding": "text", "data": "<!DOCTYPE html><html><body><p>Here is your custom content.</p></body></html>" } } }

예시 이벤트 객체

다음 예는 완전한 event 객체를 보여줍니다.

참고

event 객체는 함수에 대한 입력입니다. 함수는 request 또는 response 객체만 반환하고 전체 event 객체는 반환하지 않습니다.

{ "version": "1.0", "context": { "distributionDomainName": "d111111abcdef8.cloudfront.net", "distributionId": "EDFDVBD6EXAMPLE", "eventType": "viewer-response", "requestId": "EXAMPLEntjQpEXAMPLE_SG5Z-EXAMPLEPmPfEXAMPLEu3EqEXAMPLE==" }, "viewer": {"ip": "198.51.100.11"}, "request": { "method": "GET", "uri": "/media/index.mpd", "querystring": { "ID": {"value": "42"}, "Exp": {"value": "1619740800"}, "TTL": {"value": "1440"}, "NoValue": {"value": ""}, "querymv": { "value": "val1", "multiValue": [ {"value": "val1"}, {"value": "val2,val3"} ] } }, "headers": { "host": {"value": "video.example.com"}, "user-agent": {"value": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:83.0) Gecko/20100101 Firefox/83.0"}, "accept": { "value": "application/json", "multiValue": [ {"value": "application/json"}, {"value": "application/xml"}, {"value": "text/html"} ] }, "accept-language": {"value": "en-GB,en;q=0.5"}, "accept-encoding": {"value": "gzip, deflate, br"}, "origin": {"value": "https://website.example.com"}, "referer": {"value": "https://website.example.com/videos/12345678?action=play"}, "cloudfront-viewer-country": {"value": "GB"} }, "cookies": { "Cookie1": {"value": "value1"}, "Cookie2": {"value": "value2"}, "cookie_consent": {"value": "true"}, "cookiemv": { "value": "value3", "multiValue": [ {"value": "value3"}, {"value": "value4"} ] } } }, "response": { "statusCode": 200, "statusDescription": "OK", "headers": { "date": {"value": "Mon, 04 Apr 2021 18:57:56 GMT"}, "server": {"value": "gunicorn/19.9.0"}, "access-control-allow-origin": {"value": "*"}, "access-control-allow-credentials": {"value": "true"}, "content-type": {"value": "application/json"}, "content-length": {"value": "701"} }, "cookies": { "ID": { "value": "id1234", "attributes": "Expires=Wed, 05 Apr 2021 07:28:00 GMT" }, "Cookie1": { "value": "val1", "attributes": "Secure; Path=/; Domain=example.com; Expires=Wed, 05 Apr 2021 07:28:00 GMT", "multiValue": [ { "value": "val1", "attributes": "Secure; Path=/; Domain=example.com; Expires=Wed, 05 Apr 2021 07:28:00 GMT" }, { "value": "val2", "attributes": "Path=/cat; Domain=example.com; Expires=Wed, 10 Jan 2021 07:28:00 GMT" } ] } } } }