

# Personalização na borda com o Lambda@Edge
<a name="lambda-at-the-edge"></a>

O Lambda@Edge é uma extensão do AWS Lambda. O Lambda@Edge é um serviço de computação que permite executar funções que personalizam o conteúdo fornecido pelo Amazon CloudFront. É possível criar funções do Node.js ou Python no console do Lambda em uma Região da AWS, Leste dos EUA (Norte da Virgínia).

Depois de criar a função, é possível adicionar acionadores usando o console do Lambda ou do CloudFront para que as funções sejam executadas nos locais da AWS mais próximos do visualizador, sem provisionar ou gerenciar servidores. Se desejar, você poderá usar as operações de API do Lambda e do CloudFront para configurar as funções e os acionadores de forma programática.

O Lambda@Edge é automaticamente dimensionado, desde algumas solicitações por dia até milhares por segundo. O processamento de solicitações em locais da AWS mais próximos do visualizador, em vez de servidores de origem, reduz significativamente a latência e melhora a experiência do usuário.

**nota**  
O Lambda@Edge não é compatível com solicitações gRPC. Para ter mais informações, consulte [Usar gRPC com distribuições do CloudFront](distribution-using-grpc.md).

**Topics**
+ [Como o Lambda@Edge funciona com solicitações e respostas](lambda-edge-event-request-response.md)
+ [Maneiras de usar o Lambda@Edge](lambda-edge-ways-to-use.md)
+ [Começar a usar funções do Lambda@Edge (console)](lambda-edge-how-it-works.md)
+ [Configurar permissões e perfis do IAM para o Lambda@Edge](lambda-edge-permissions.md)
+ [Escrever e criar uma função do Lambda@Edge](lambda-edge-create-function.md)
+ [Adicionar acionadores para uma função do Lambda@Edge](lambda-edge-add-triggers.md)
+ [Testar e depurar as funções do Lambda@Edge](lambda-edge-testing-debugging.md)
+ [Excluir funções e réplicas do Lambda@Edge](lambda-edge-delete-replicas.md)
+ [Estrutura de eventos do Lambda@Edge](lambda-event-structure.md)
+ [Trabalho com solicitações e respostas](lambda-generating-http-responses.md)
+ [Funções de exemplo do Lambda@Edge](lambda-examples.md)

# Como o Lambda@Edge funciona com solicitações e respostas
<a name="lambda-edge-event-request-response"></a>

Ao associar uma distribuição do CloudFront a uma função do Lambda@Edge, o CloudFront intercepta solicitações e respostas nos pontos de presença do CloudFront. É possível executar funções do Lambda quando ocorrem os seguintes eventos do CloudFront:
+ Quando o CloudFront receber uma solicitação de um visualizador (solicitação do visualizador)
+ Antes do CloudFront encaminhar uma solicitação para a origem (solicitação da origem)
+ Quando o CloudFront receber uma resposta da origem (resposta da origem)
+ Antes de o CloudFront exibir a resposta para o visualizador (resposta ao visualizador).

Se você estiver usando o AWS WAF, a solicitação do visualizador do Lambda@Edge será executada após a aplicação de qualquer regra do AWS WAF.

Para obter mais informações, consulte [Trabalho com solicitações e respostas](lambda-generating-http-responses.md) e [Estrutura de eventos do Lambda@Edge](lambda-event-structure.md).

# Maneiras de usar o Lambda@Edge
<a name="lambda-edge-ways-to-use"></a>

Há diversos usos para o processamento do Lambda@Edge com sua distribuição do Amazon CloudFront, como os seguintes exemplos:
+ Uma função do Lambda pode inspecionar cookies e reescrever URLs para que os usuários vejam diferentes versões de um site para testes A/B.
+ O CloudFront pode retornar objetos diferentes aos visualizadores dependendo do dispositivo que estão usando, verificando o cabeçalho `User-Agent`, que inclui informações sobre os dispositivos. Por exemplo, o CloudFront pode retornar imagens diferentes com base no tamanho da tela do seu dispositivo. Da mesma forma, a função pode considerar o valor do cabeçalho `Referer` e fazer com que o CloudFront retorne imagens com a menor resolução disponível a bots. 
+ Ou você pode verificar cookies para outros critérios. Por exemplo, em um site de varejo que vende roupas, se você usar cookies para indicar a cor de uma jaqueta escolhida por um usuário, a função do Lambda poderá alterar a solicitação para que o CloudFront retorne a imagem de uma jaqueta na cor selecionada.
+ Uma função do Lambda pode gerar respostas HTTP quando ocorrerem os eventos da solicitação de origem ou do visualizador do CloudFront.
+ Uma função pode inspecionar cabeçalhos ou tokens de autorização e inserir um cabeçalho para controlar o acesso ao seu conteúdo antes de o CloudFront encaminhar uma solicitação para a origem.
+ Uma função do Lambda também pode fazer chamadas de rede para recursos externos a fim de confirmar as credenciais do usuário ou obter conteúdo adicional para personalizar uma resposta.

Consulte mais informações, incluindo exemplos de código em [Funções de exemplo do Lambda@Edge](lambda-examples.md).

Consulte mais informações sobre como configurar o Lambda@Edge no console em [Tutorial: criar uma função básica do Lambda@Edge (console)](lambda-edge-how-it-works-tutorial.md).

# Começar a usar funções do Lambda@Edge (console)
<a name="lambda-edge-how-it-works"></a>

Com o Lambda@Edge, é possível usar acionadores do CloudFront para invocar uma função do Lambda. Quando você associa uma distribuição do CloudFront a uma função do Lambda, o CloudFront [intercepta solicitações e respostas](https://docs.aws.amazon.com/lambda/latest/dg/lambda-edge.html) nos pontos de presença do CloudFront e executa a função. As funções do Lambda podem melhorar a segurança ou personalizar informações próximas aos visualizadores para melhorar a performance.

A lista a seguir fornece uma visão geral básica de como criar e usar as funções do Lambda com o CloudFront.

**Visão geral: como criar e usar funções do Lambda com o CloudFront**

1. Crie uma função do Lambda na região Leste dos EUA (N. da Virgínia).

1. Salve e publique uma versão numerada da função.

   Para alterar a função, edite a versão \$1LATEST da função na região Leste dos EUA (Norte da Virgínia). A seguir, antes de configurá-la para funcionar com o CloudFront, publique uma nova versão numerada.

1. Associe a função a uma distribuição do CloudFront e ao comportamento de cache. Depois, especifique um ou mais eventos do CloudFront (*triggers*) que fazem com que a função seja executada. Por exemplo, você pode criar um trigger para que a função seja executada quando o CloudFront receber uma solicitação de um visualizador.

1. Quando você cria um acionador, o Lambda cria réplicas da função em locais da AWS em todo o mundo.

**dica**  
Consulte mais informações em [criar e atualizar funções](lambda-edge-create-function.md), [a estrutura de eventos](lambda-event-structure.md) e [adicionar acionadores do CloudFront](lambda-edge-add-triggers.md). Você também pode encontrar mais ideias e obter amostras de código em [Funções de exemplo do Lambda@Edge](lambda-examples.md).

Consulte um tutorial detalhado no seguinte tópico:

**Topics**
+ [Tutorial: criar uma função básica do Lambda@Edge (console)](lambda-edge-how-it-works-tutorial.md)

# Tutorial: criar uma função básica do Lambda@Edge (console)
<a name="lambda-edge-how-it-works-tutorial"></a>

Esse tutorial mostra como começar a usar o Lambda@Edge criando e configurando um exemplo de função do Node.js que é executado no CloudFront. Este exemplo adiciona cabeçalhos de segurança HTTP a uma resposta quando o CloudFront recupera um arquivo. (Isso pode melhorar a segurança e a privacidade de um site.)

Você não precisa de seu próprio site para esse tutorial. No entanto, ao optar por criar sua própria solução do Lambda@Edge, você segue etapas semelhantes e escolhe entre as mesmas opções.

**Topics**
+ [Etapa 1: cadastrar-se com uma Conta da AWS](#lambda-edge-how-it-works-tutorial-AWS)
+ [Etapa 2: Criar uma distribuição do CloudFront](#lambda-edge-how-it-works-tutorial-cloudfront)
+ [Etapa 3: criar sua função](#lambda-edge-how-it-works-tutorial-create-function)
+ [Etapa 4: adicionar um acionador do CloudFront para executar a função](#lambda-edge-how-it-works-tutorial-add-trigger)
+ [Etapa 5: verificar se a função é executada](#lambda-edge-how-it-works-tutorial-verify)
+ [Etapa 6: solução de problemas](#lambda-edge-how-it-works-tutorial-troubleshoot)
+ [Etapa 7: apagar recursos de exemplo](#lambda-edge-how-it-works-tutorial-cleanup-resources)
+ [Informações relacionadas](#lambda-edge-how-it-works-tutorial-resources)

## Etapa 1: cadastrar-se com uma Conta da AWS
<a name="lambda-edge-how-it-works-tutorial-AWS"></a>

Se ainda não tiver feito isso, cadastre-se para uma Conta da AWS. Para obter mais informações, consulte [Inscrever-se para uma Conta da AWS](setting-up-cloudfront.md#sign-up-for-aws).

## Etapa 2: Criar uma distribuição do CloudFront
<a name="lambda-edge-how-it-works-tutorial-cloudfront"></a>

Antes de criar o exemplo de função do Lambda@Edge, você deve ter um ambiente do CloudFront para trabalhar com o que inclui uma origem para servir conteúdo.

Para este exemplo, crie uma distribuição do CloudFront que use um bucket do Amazon S3 como a origem da distribuição. Se já tiver um ambiente para usar, você pode ignorar esta etapa.<a name="lambda-edge-how-it-works-tutorial-cf-proc"></a>

**Como criar uma distribuição do CloudFront com uma origem do Amazon S3**

1. Crie um bucket do Amazon S3 com um ou dois arquivos, como arquivos de imagem, para exemplo de conteúdo. Para obter ajuda, siga as etapas em [Fazer upload do conteúdo no Amazon S3](https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/GettingStarted.html#GettingStartedUploadContent). Certifique-se de ter definido permissões para conceder acesso público de leitura aos objetos do seu bucket.

1. Crie uma distribuição do CloudFront e adicione o bucket do S3 como uma origem, seguindo as etapas em [Criar uma distribuição na Web do CloudFront](https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/GettingStarted.html#GettingStartedCreateDistribution). Se você já tiver uma distribuição, pode adicionar o bucket como origem para essa distribuição.
**dica**  
Anote seu ID de distribuição. Posteriormente neste tutorial, ao adicionar um acionador do CloudFront para a função, você deve escolher o ID da distribuição em uma lista suspensa; por exemplo, `E653W22221KDDL`.

## Etapa 3: criar sua função
<a name="lambda-edge-how-it-works-tutorial-create-function"></a>

Nesta etapa, você cria uma função do Lambda, começando com um modelo de esquema no console do Lambda. A função adiciona o código para atualizar os cabeçalhos de segurança na distribuição do CloudFront. <a name="lambda-edge-how-it-works-tutorial-create-function-blueprint-proc"></a>

**Como criar uma função do Lambda**

1. Faça login no Console de gerenciamento da AWS e abra o console do AWS Lambda em [https://console.aws.amazon.com/lambda/](https://console.aws.amazon.com/lambda/).
**Importante**  
Verifique se você está na Região da AWS **US-East-1 (Norte da Virgínia)** (**us-east-1**). Você deve estar nessa região para criar as funções do Lambda@Edge.

1. Escolha **Create function**.

1. Na página **Create function (Criar função)**, escolha **Use a blueprint (Usar um esquema)** e filtre os esquemas do CloudFront inserindo **cloudfront** no campo de pesquisa.
**nota**  
Os esquemas do CloudFront estão disponíveis somente na região **US-East-1 (N. Virgínia) (Leste dos EUA-1 (Norte da Virgínia))** (**us-east-1**).

1. Escolha o esquema **Modify HTTP response header** (Modificar cabeçalho de resposta HTTP) como modelo para sua função.

1. Insira as seguintes informações sobre sua função:
   + **Nome da função**: insira um nome para a função.
   + **Perfil de execução**: escolha como definir as permissões para a função. Para usar o modelo básico de política de permissões recomendado do Lambda@Edge, selecione **Criar uma função de modelos de política da AWS**.
   + **Nome do perfil**: insira um nome para o perfil que o modelo de política cria.
   + **Modelos de política**: o Lambda adiciona automaticamente o modelo de política **Permissões básicas do Lambda@Edge** porque você escolheu um esquema do CloudFront como a base da função. Esse modelo de política adiciona permissões de função de execução que permitem que o CloudFront execute sua função do Lambda para você em locais do CloudFront em todo o mundo. Para obter mais informações, consulte [Configurar permissões e perfis do IAM para o Lambda@Edge](lambda-edge-permissions.md).

1. Selecione **Criar função** na parte inferior da página.

1. No painel **Implantar no Lambda@Edge** exibido, escolha **Cancelar**. (Para este tutorial, você deve modificar o código da função antes de implantá-la no Lambda@Edge.)

1. Role para baixo até a seção **Code source** (Origem do código) da página.

1. Substitua o código do modelo por uma função que modifica os cabeçalhos de segurança que sua origem retorna. Por exemplo, você pode usar um código semelhante ao seguinte:

   ```
   'use strict';
   export const handler = (event, context, callback) => {
   
       //Get contents of response
       const response = event.Records[0].cf.response;
       const headers = response.headers;
   
       //Set new headers
       headers['strict-transport-security'] = [{key: 'Strict-Transport-Security', value: 'max-age= 63072000; includeSubdomains; preload'}];
       headers['content-security-policy'] = [{key: 'Content-Security-Policy', value: "default-src 'none'; img-src 'self'; script-src 'self'; style-src 'self'; object-src 'none'"}];
       headers['x-content-type-options'] = [{key: 'X-Content-Type-Options', value: 'nosniff'}];
       headers['x-frame-options'] = [{key: 'X-Frame-Options', value: 'DENY'}];
       headers['x-xss-protection'] = [{key: 'X-XSS-Protection', value: '1; mode=block'}];
       headers['referrer-policy'] = [{key: 'Referrer-Policy', value: 'same-origin'}];
   
       //Return modified response
       callback(null, response);
   };
   ```

1. Selecione **File** (Arquivo), **Save** (Salvar) para salvar o código atualizado.

1. Escolha **Implantar**.

Prossiga para a próxima seção para adicionar um trigger do CloudFront para executar a função.

## Etapa 4: adicionar um acionador do CloudFront para executar a função
<a name="lambda-edge-how-it-works-tutorial-add-trigger"></a>

Agora que você tem uma função do Lambda para atualizar os cabeçalhos de segurança, configure o trigger do CloudFront que executa a função para adicionar cabeçalhos em qualquer resposta recebida pelo CloudFront da origem para sua distribuição.<a name="lambda-edge-how-it-works-tutorial-add-trigger-proc"></a>

**Como configurar o trigger do CloudFront para sua função**

1. No console do Lambda, na página de **Function overview** (Visão geral da função) da função, escolha **Add trigger** (Adicionar acionador).

1. Em **Trigger configuration** (Configuração do acionador), escolha **CloudFront**.

1. Escolha **Implantar no Lambda@Edge**.

1. No painel **Implantar no Lambda@Edge**, em **Configurar acionador do CloudFront**, insira as seguintes informações:
   + **Distribuição**: o ID de distribuição do CloudFront a ser associado à função. Na lista suspensa, escolha o ID da distribuição.
   + **Comportamento de cache**: o comportamento de cache para usar com o acionador. Para este exemplo, deixe o valor definido como **\$1**, que indica o comportamento de cache padrão da distribuição. Para obter mais informações, consulte [Configurações de comportamento de cache](DownloadDistValuesCacheBehavior.md)[Referência de configurações de todas as distribuições](distribution-web-values-specify.md) no tópico.
   + **Evento do CloudFront**: o acionador que especifica quando a função é executada. Queremos que os cabeçalhos de segurança da função sejam executados sempre que o CloudFront retornar uma resposta da origem. Na lista suspensa, escolha **Resposta da origem**. Para obter mais informações, consulte [Adicionar acionadores para uma função do Lambda@Edge](lambda-edge-add-triggers.md).

1. Marque a caixa de seleção **Confirmar implantação no Lambda@Edge**.

1. Escolha **Deploy (Implantar)** para adicionar o trigger e replicar a função para os locais da AWS em todo o mundo.

1. Aguarde até que a função seja replicada. Isso normalmente demora vários minutos.

    Você pode verificar se a replicação foi concluída [acessando o console do CloudFront](https://console.aws.amazon.com/cloudfront/v4/home) e visualizando a distribuição. Aguarde o status de distribuição mudar de **Implantando** para uma data e hora, o que significa que sua função foi replicada. Para verificar se a função funciona, siga as etapas na próxima seção.

## Etapa 5: verificar se a função é executada
<a name="lambda-edge-how-it-works-tutorial-verify"></a>

Agora que você criou a função do Lambda e configurou um trigger para executá-la em uma distribuição do CloudFront, verifique se a função está realizando o que você espera. Neste exemplo, verificamos os cabeçalhos HTTP que o CloudFront retorna, para garantir que os cabeçalhos de segurança estejam adicionados.<a name="lambda-edge-how-it-works-tutorial-verify-proc"></a>

**Para verificar se a sua função do Lambda@Edge adiciona cabeçalhos de segurança**

1. Em um navegador, insira o URL para um arquivo no seu bucket do S3. Por exemplo, você pode usar um URL semelhante a `https://d111111abcdef8.cloudfront.net/image.jpg`.

   Para obter mais informações sobre o nome de domínio do CloudFront a ser usado no arquivo URL, consulte [Personalizar o formato do URL para arquivos no CloudFront](LinkFormat.md).

1. Abra a barra de ferramentas do desenvolvedor da Web do navegador. Por exemplo, em sua janela do navegador Chrome, abra o menu de contexto (clique com o botão direito do mouse) e escolha **Inspect (Inspecionar)**.

1. Escolha a guia **Network**.

1. Recarregue a página para visualizar sua imagem e, em seguida, escolha uma solicitação HTTP no painel esquerdo. Você vê os cabeçalhos HTTP exibidos em um painel separado.

1. Verifique a lista de cabeçalhos HTTP para verificar se os cabeçalhos de segurança esperados são incluídos na lista. Por exemplo, você poderá ver cabeçalhos semelhantes aos mostrados na captura de tela a seguir:  
![\[Os cabeçalhos de HTTP listam com os cabeçalhos de segurança em destaque esperados.\]](http://docs.aws.amazon.com/pt_br/AmazonCloudFront/latest/DeveloperGuide/images/lambda-at-edge-security-headers-list.png)

Se os cabeçalhos de segurança forem incluídos na sua lista de cabeçalhos, excelente\$1 Você criou com êxito sua primeira função do Lambda@Edge. Se o CloudFront retornar erros ou se houver outros problemas, continue na próxima etapa para solucionar os problemas.

## Etapa 6: solução de problemas
<a name="lambda-edge-how-it-works-tutorial-troubleshoot"></a>

Se o CloudFront retornar erros ou não adicionar os cabeçalhos de segurança conforme esperado, você poderá investigar a execução da função verificando o CloudWatch Logs. Certifique-se de usar os logs armazenados no local da AWS que estão mais próximos do local em que a função é executada.

Por exemplo, se você visualizar o arquivo de Londres, tente alterar a região no console do CloudWatch para EU (Londres).<a name="lambda-edge-how-it-works-tutorial-cloudwatch-proc"></a>

**Como examinar os CloudWatch Logs para sua função do Lambda@Edge**

1. Faça login no Console de gerenciamento da AWS e abra o console do CloudWatch em [https://console.aws.amazon.com/cloudwatch/](https://console.aws.amazon.com/cloudwatch/).

1. Altere a **Region (Região)** para o local que é mostrado quando você visualiza o arquivo no navegador. Aqui é onde a função está sendo executada.

1. No painel esquerdo, selecione **Logs** para visualizar os logs da sua distribuição. 

Para obter mais informações, consulte [Monitorar métricas do CloudFront com o Amazon CloudWatch](monitoring-using-cloudwatch.md).

## Etapa 7: apagar recursos de exemplo
<a name="lambda-edge-how-it-works-tutorial-cleanup-resources"></a>

Se você criar um bucket do Amazon S3 e a distribuição do CloudFront apenas para este tutorial, exclua os recursos da AWS alocados para não acumular mais cobranças. Depois que você excluir os recursos da AWS, qualquer conteúdo que você adicionou não ficará mais disponível.

**Tarefas**
+ [Exclua o bucket do S3](#lambda-edge-how-it-works-tutorial-delete-bucket) 
+ [Excluir a função Lambda](#lambda-edge-how-it-works-tutorial-delete-function)
+ [Exclua a distribuição do CloudFront](#lambda-edge-how-it-works-tutorial-delete-distribution)

### Exclua o bucket do S3
<a name="lambda-edge-how-it-works-tutorial-delete-bucket"></a>

Antes de excluir o bucket do Amazon S3, verifique se o log está desativado para o bucket. Caso contrário, a AWS continuará gravando logs para o bucket à medida que você o excluir.<a name="lambda-edge-how-it-works-tutorial-delete-bucket-proc"></a>

**Para desabilitar o registro em log para um bucket**

1. Abra o console do Amazon S3 em [https://console.aws.amazon.com/s3/](https://console.aws.amazon.com/s3/).

1. Selecione o bucket e escolha **Properties (Propriedades)**.

1. Em **Properties (Propriedades)**, escolha **Logging (Registro)**.

1. Desmarque a caixa de seleção **Enabled (Habilitado)**.

1. Escolha **Save (Salvar)**.

Agora, você pode excluir seu bucket. Para obter mais informações, consulte [Exclusão de um bucket ](https://docs.aws.amazon.com/AmazonS3/latest/userguide/delete-bucket.html) no *Guia do usuário do console do Amazon Simple Storage Service*.

### Excluir a função Lambda
<a name="lambda-edge-how-it-works-tutorial-delete-function"></a>

Para ter instruções sobre como excluir a associação da função do Lambda e, opcionalmente, a própria função, consulte [Excluir funções e réplicas do Lambda@Edge](lambda-edge-delete-replicas.md).

### Exclua a distribuição do CloudFront
<a name="lambda-edge-how-it-works-tutorial-delete-distribution"></a>

Antes de excluir uma distribuição do CloudFront, você deve desabilitá-la. Uma distribuição desabilitada deixa de ser funcional e não acumula encargos. É possível habilitar uma distribuição desabilitada a qualquer momento. Depois que você excluir uma distribuição desabilitada, ela deixará de estar disponível.<a name="lambda-edge-how-it-works-tutorial-delete-distribution-proc"></a>

**Como desabilitar e excluir uma distribuição do CloudFront**

1. Abra o console do CloudFront em [https://console.aws.amazon.com/cloudfront/v4/home](https://console.aws.amazon.com/cloudfront/v4/home).

1. Selecione a distribuição que você deseja desabilitar e escolha **Disable (Desabilitar)**.

1. Quando a confirmação for solicitada, escolha **Yes, Disable (Sim, desabilitar)**.

1. Selecione a distribuição desabilitada e escolha **Delete (Excluir)**.

1. Quando a confirmação for solicitada, escolha **Yes, Delete (Sim, excluir)**.

## Informações relacionadas
<a name="lambda-edge-how-it-works-tutorial-resources"></a>

Agora que você tem uma ideia básica de como as funções do Lambda@Edge funcionam, saiba mais lendo o seguinte:
+ [Funções de exemplo do Lambda@Edge](lambda-examples.md)
+ [Práticas recomendadas de design do Lambda@Edge](https://aws.amazon.com/blogs/networking-and-content-delivery/lambdaedge-design-best-practices/)
+ [Reducing Latency and Shifting Compute to the Edge with Lambda@Edge](https://aws.amazon.com/blogs/networking-and-content-delivery/reducing-latency-and-shifting-compute-to-the-edge-with-lambdaedge/)

# Configurar permissões e perfis do IAM para o Lambda@Edge
<a name="lambda-edge-permissions"></a>

Para configurar o Lambda@Edge, é necessário ter as seguintes permissões e perfis do IAM para o AWS Lambda: 
+ [Permissões do IAM](#lambda-edge-permissions-required): essas permissões autorizam você a criar a função do Lambda e a associá-la à distribuição do CloudFront.
+ [Perfil de execução da função do Lambda](#lambda-edge-permissions-function-execution) (perfil do IAM): as entidades principais do serviço do Lambda assumem esse perfil para executar a função.
+ [Perfis vinculados ao serviço para o Lambda@Edge](#using-service-linked-roles-lambda-edge): os perfis vinculados ao serviço permitem que Serviços da AWS específicos repliquem funções do Lambda para Regiões da AWS e habilitem o CloudWatch para usar arquivos de log do CloudFront.

## Permissões do IAM necessárias para associar funções do Lambda às distribuições do CloudFront
<a name="lambda-edge-permissions-required"></a>

Além das permissões do IAM necessárias para o Lambda, você precisa das seguintes permissões para associar as funções do Lambda às distribuições do CloudFront:
+ `lambda:GetFunction`: concede permissão para recebimento de informações de configuração para a função do Lambda e de um URL pré-assinado para baixar um arquivo `.zip` que contém a função.
+ `lambda:EnableReplication*`: concede permissão à política de recurso para que o serviço de replicação do Lambda possa obter o a configuração e o código da função.
+ `lambda:DisableReplication*`: concede permissão à política de recurso para que o serviço de replicação do Lambda possa excluir a função.
**Importante**  
É necessário adicionar o asterisco (`*`) ao final das ações `lambda:EnableReplication*` e `lambda:DisableReplication*`.
+ Para o recurso, especifique o ARN da versão da função que você deseja executar quando ocorrer um evento do CloudFront, conforme mostrado no seguinte exemplo:

  `arn:aws:lambda:us-east-1:123456789012:function:TestFunction:2`
+ `iam:CreateServiceLinkedRole`: concede permissão para criar um perfil vinculado ao serviço que o Lambda@Edge usa para replicar funções do Lambda no CloudFront. Depois que você configurar o Lambda@Edge pela primeira vez, o perfil vinculado ao serviço será criado automaticamente para você. Não é necessário adicionar essa permissão a outras distribuições que usam o Lambda@Edge.

  
+ `cloudfront:UpdateDistribution` ou `cloudfront:CreateDistribution`: concede permissão para atualizar ou criar uma distribuição.

Para saber mais, consulte os seguintes tópicos:
+ [Identity and Access Management para Amazon CloudFront](security-iam.md)
+ [Permissões de acesso a recursos do Lambda](https://docs.aws.amazon.com/lambda/latest/dg/intro-permission-model.html#lambda-intro-execution-role) no *Guia do desenvolvedor do AWS Lambda*

## Função de execução de função para primários de serviço
<a name="lambda-edge-permissions-function-execution"></a>

É necessário criar um perfil do IAM que as entidades principais do serviço `lambda.amazonaws.com` e `edgelambda.amazonaws.com` possam assumir ao executarem a função. 

**dica**  
Ao criar a função no console do Lambda, você pode optar por criar um perfil de execução usando um modelo de política da AWS. Essa etapa adiciona *automaticamente* as permissões necessárias do Lambda@Edge para executar a função. Consulte a [Etapa 5 do tutorial Criação de uma função do Lambda@Edge simples](lambda-edge-how-it-works-tutorial.md#lambda-edge-how-it-works-tutorial-create-function).

Consulte mais informações sobre como criar um perfil do IAM manualmente em [Criar funções e anexar políticas (console)](https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_job-functions_create-policies.html) no *Guia do usuário do IAM*.

**Example Exemplo: política de confiança do perfil**  
É possível adicionar esse perfil na guia **Relação de confiança** no console do IAM. Não adicione essa política na guia **Permissões**.    
****  

```
{
   "Version":"2012-10-17",		 	 	 
   "Statement": [
      {
         "Effect": "Allow",
         "Principal": {
            "Service": [
               "lambda.amazonaws.com",
               "edgelambda.amazonaws.com"
            ]
         },
         "Action": "sts:AssumeRole"
      }
   ]
}
```

Consulte mais informações sobre as permissões que você precisa conceder ao perfil de execução em [Permissões de acesso a recursos do Lambda](https://docs.aws.amazon.com/lambda/latest/dg/intro-permission-model.html#lambda-intro-execution-role) no *Guia do desenvolvedor do AWS Lambda*.

**Observações**  
Por padrão, sempre que um evento do CloudFront aciona uma função do Lambda, os dados são gravados no CloudWatch Logs. Se você quiser usar esses logs, a função de execução precisará de permissão para registrar dados no CloudWatch Logs. É possível usar o AWSLambdaBasicExecutionRole predefinido para conceder permissão ao perfil de execução.  
Para obter mais informações sobre o CloudWatch Logs, consulte [Logs de funções de borda](edge-functions-logs.md).
Se o código da função do Lambda acessar outros recursos da AWS, como a leitura de um objeto em um bucket do S3, o perfil de execução precisará de permissão para executar essa ação. 

## Funções vinculadas ao serviço para o Lambda@Edge
<a name="using-service-linked-roles-lambda-edge"></a>

O Lambda@Edge usa [perfis vinculados ao serviço](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_terms-and-concepts.html#iam-term-service-linked-role) do IAM. Uma função vinculada ao serviço é um tipo exclusivo de função do IAM vinculada diretamente a um serviço. As funções vinculadas a serviços são predefinidas pelo serviço e incluem todas as permissões de que ele precisa para chamar outros serviços da AWS em seu nome.

O Lambda@Edge usa os seguintes perfis vinculados ao serviço do IAM:
+ **AWSServiceRoleForLambdaReplicator** – o Lambda@Edge usa essa função para permitir que ele mesmo replique funções para Regiões da AWS.

  Quando você adiciona um acionador do Lambda@Edge ao CloudFront pela primeira vez, um perfil chamado AWSServiceRoleForLambdaReplicator é criado automaticamente para permitir que o Lambda@Edge replique funções para Regiões da AWS. Esse perfil é necessário para usar as funções do Lambda@Edge. O ARN do perfil AWSServiceRoleForLambdaReplicator é semelhante a este exemplo:

  `arn:aws:iam::123456789012:role/aws-service-role/replicator.lambda.amazonaws.com/AWSServiceRoleForLambdaReplicator`
+ **AWSServiceRoleForCloudFrontLogger** – o CloudFront usa esse perfil para enviar arquivos de log ao CloudWatch. É possível usar arquivos de log para depurar erros de validação do Lambda@Edge.

  O perfil AWSServiceRoleForCloudFrontLogger é criado automaticamente quando você adiciona a associação da função do Lambda@Edge para permitir que o CloudFront envie arquivos de log de erros do Lambda@Edge ao CloudWatch. O ARN para a função AWSServiceRoleForCloudFrontLogger é semelhante a:

  `arn:aws:iam::account_number:role/aws-service-role/logger.cloudfront.amazonaws.com/AWSServiceRoleForCloudFrontLogger`

Uma função vinculada a serviço facilita a configuração e o uso do Lambda@Edge, pois você não precisa adicionar manualmente as permissões necessárias. Lambda@Edge define as permissões de suas funções vinculadas ao serviço e apenas Lambda@Edge pode assumir as funções. As permissões definidas incluem a política de confiança e a política de permissões. Não é possível anexar a política de permissões a nenhuma outra entidade do IAM.

Você deve remover todos os recursos do CloudFront ou do Lambda@Edge associados para poder excluir a função vinculada ao serviço. Isso ajuda a proteger seus recursos do Lambda@Edge de modo que você não remova um perfil vinculado ao serviço que ainda seja necessário para acessar os recursos ativos.

Para obter mais informações sobre funções vinculadas ao serviço, consulte [Funções vinculadas ao serviço do CloudFront](security_iam_service-with-iam.md#security_iam_service-with-iam-roles-service-linked). 

### Permissões de função vinculada ao serviço para o Lambda@Edge
<a name="slr-permissions-lambda-edge"></a>

O Lambda@Edge usa duas funções vinculadas a serviços: **AWSServiceRoleForLambdaReplicator** e **AWSServiceRoleForCloudFrontLogger**. As seções a seguir descrevem as permissões para cada uma dessas funções.

**Contents**
+ [Permissões de função vinculada ao serviço para o replicador do Lambda](#slr-permissions-lambda-replicator)
+ [Permissões de função vinculada ao serviço para o CloudFront Logger](#slr-permissions-cloudfront-logger)

#### Permissões de função vinculada ao serviço para o replicador do Lambda
<a name="slr-permissions-lambda-replicator"></a>

Essa função vinculada ao serviço permite que o Lambda replique funções do Lambda@Edge para Regiões da AWS.

O perfil vinculado ao serviço AWSServiceRoleForLambdaReplicator confia no serviço `replicator.lambda.amazonaws.com` para presumir o perfil.

A política de permissões da função permite que o Lambda@Edge conclua as seguintes ações nos recursos especificados:
+ `lambda:CreateFunction` na `arn:aws:lambda:*:*:function:*`
+ `lambda:DeleteFunction` na `arn:aws:lambda:*:*:function:*`
+ `lambda:DisableReplication` na `arn:aws:lambda:*:*:function:*`
+ `iam:PassRole` na `all AWS resources`
+  `cloudfront:ListDistributionsByLambdaFunction` na `all AWS resources`

#### Permissões de função vinculada ao serviço para o CloudFront Logger
<a name="slr-permissions-cloudfront-logger"></a>

Esse perfil vinculado ao serviço permite que o CloudFront envie arquivos de log por push ao CloudWatch para que seja possível depurar erros de validação do Lambda@Edge.

O perfil vinculado ao serviço AWSServiceRoleForCloudFrontLogger confia no serviço `logger.cloudfront.amazonaws.com` para presumir o perfil.

A política de permissões do perfil permite que o Lambda@Edge conclua as seguintes ações no recurso `arn:aws:logs:*:*:log-group:/aws/cloudfront/*` especificado:
+ `logs:CreateLogGroup` ``
+ `logs:CreateLogStream`
+ `logs:PutLogEvents`

Você deve configurar permissões para permitir que uma entidade do IAM (como um usuário, grupo ou função) exclua uma função vinculada ao serviço do Lambda@Edge. Para obter mais informações, consulte [Permissões do perfil vinculado a serviço](https://docs.aws.amazon.com/IAM/latest/UserGuide/using-service-linked-roles.html#service-linked-role-permissions) no *Guia do usuário do IAM*.

### Criação de funções vinculadas ao serviço para o Lambda@Edge
<a name="create-slr-lambda-edge"></a>

Normalmente, não é necessário criar manualmente as funções vinculadas a serviços para o Lambda@Edge. O serviço cria as funções automaticamente nas seguintes situações:
+ Quando você cria um acionador pela primeira vez, o serviço cria o perfil AWSServiceRoleForLambdaReplicator (caso ele ainda não exista). Esse perfil permite que o Lambda replique funções do Lambda@Edge para Regiões da AWS.

  Se você excluir a função vinculada ao serviço, a função será criada novamente quando você adicionar um novo gatilho para o Lambda@Edge em uma distribuição.
+ Quando você atualiza ou cria uma distribuição do CloudFront que tem uma associação ao Lambda@Edge, o serviço cria o perfil AWSServiceRoleForCloudFrontLogger (caso o perfil ainda não exista). Esse perfil permite que o CloudFront envie arquivos de log ao CloudWatch.

  Se você excluir a função vinculada ao serviço, ela será criada novamente quando você atualizar ou criar uma distribuição do CloudFront que tenha uma associação ao Lambda@Edge.

Para criar manualmente esses perfis vinculados ao serviço, execute os seguintes comandos da AWS Command Line Interface (AWS CLI):

**Para criar a função AWSServiceRoleForLambdaReplicator**
+ Execute o comando a seguir.

  ```
  aws iam create-service-linked-role --aws-service-name replicator.lambda.amazonaws.com
  ```

**Para criar a função AWSServiceRoleForCloudFrontLogger**
+ Execute o comando a seguir.

  ```
  aws iam create-service-linked-role --aws-service-name logger.cloudfront.amazonaws.com
  ```

### Edição de funções vinculadas ao serviço do Lambda@Edge
<a name="edit-slr-lambda-edge"></a>

O Lambda@Edge não permite que você edite os perfis vinculados ao serviço AWSServiceRoleForLambdaReplicator ou AWSServiceRoleForCloudFrontLogger. Depois que o serviço criar um perfil vinculado ao serviço, você não poderá alterar o nome dele, pois várias entidades podem fazer referência a ele. No entanto, é possível usar o IAM para editar a descrição da função. Para saber mais, consulte [Editar um perfil vinculado ao serviço](https://docs.aws.amazon.com/IAM/latest/UserGuide/using-service-linked-roles.html#edit-service-linked-role) no *Guia do usuário do IAM*.

### Regiões da AWS compatíveis com perfis vinculados ao serviço do Lambda@Edge
<a name="slr-regions-lambda-edge"></a>

O CloudFront é compatível com as funções vinculadas ao serviço do Lambda@Edge nas seguintes Regiões da AWS:
+ Leste dos EUA (Norte da Virgínia) – `us-east-1`
+ Leste dos EUA (Ohio) – `us-east-2`
+ US West (N. California) – `us-west-1`
+ US West (Oregon) – `us-west-2`
+ Asia Pacific (Mumbai) – `ap-south-1`
+ Asia Pacific (Seoul) – `ap-northeast-2`
+ Asia Pacific (Singapore) – `ap-southeast-1`
+ Asia Pacific (Sydney) – `ap-southeast-2`
+ Asia Pacific (Tokyo) – `ap-northeast-1`
+ Europe (Frankfurt) – `eu-central-1`
+ Europe (Ireland) – `eu-west-1`
+ Europe (London) – `eu-west-2`
+ South America (São Paulo) – `sa-east-1`

# Escrever e criar uma função do Lambda@Edge
<a name="lambda-edge-create-function"></a>

Para usar o Lambda@Edge, você *escreve* o código da função do AWS Lambda. Para ajudar você a escrever funções do Lambda@Edge, consulte os seguintes recursos:
+  [Estrutura de eventos do Lambda@Edge](lambda-event-structure.md): entenda a estrutura de eventos a ser usada com o Lambda@Edge.
+ [Funções de exemplo do Lambda@Edge](lambda-examples.md): funções de exemplo, como testes A/B e geração de um redirecionamento HTTP.

O modelo de programação para usar o Node.js com o Lambda@Edge é o mesmo que para usar o Lambda em uma Região da AWS. Consulte mais informações em [Criar funções do Lambda com Node.js](https://docs.aws.amazon.com/lambda/latest/dg/lambda-nodejs.html) ou em [Criar funções do Lambda com Python](https://docs.aws.amazon.com/lambda/latest/dg/lambda-python.html) no *Guia do desenvolvedor do AWS Lambda*.

Na função do Lambda@Edge, inclua o parâmetro `callback` e retorne o objeto aplicável para eventos de solicitação ou resposta:
+ **Eventos de solicitação**: inclua o objeto `cf.request` na resposta.

  Se você estiver gerando uma resposta, inclua o objeto `cf.response` na resposta. Para obter mais informações, consulte [Gerar respostas de HTTP em acionadores da solicitação](lambda-generating-http-responses.md#lambda-generating-http-responses-in-requests). 
+ **Eventos de resposta**: inclua o objeto `cf.response` na resposta.

Depois de escrever seu próprio código ou usar um dos exemplos, você cria a função no Lambda. Para criar uma função ou editar uma existente, consulte os seguintes tópicos:

**Topics**
+ [Criar uma função do Lambda@Edge](lambda-edge-create-in-lambda-console.md)
+ [Editar uma função do Lambda](lambda-edge-edit-function.md)

 Depois de criar a função no Lambda, você configura o Lambda para executar a função com base em eventos específicos do CloudFront, chamados *acionadores*. Para obter mais informações, consulte [Adicionar acionadores para uma função do Lambda@Edge](lambda-edge-add-triggers.md).

# Criar uma função do Lambda@Edge
<a name="lambda-edge-create-in-lambda-console"></a>

Para configurar o AWS Lambda para executar funções do Lambda baseadas em eventos do CloudFront, siga este procedimento.<a name="lambda-edge-create-function-procedure"></a>

**Para criar uma função Lambda@Edge**

1. Faça login no Console de gerenciamento da AWS e abra o console AWS Lambda em [https://console.aws.amazon.com/lambda/](https://console.aws.amazon.com/lambda/).

1. Se você já tiver uma ou mais funções do Lambda, escolha **Create function (Criar função)**.

   Se você não tiver nenhuma função, escolha **Get Started Now**.

1. Na lista Region (Região) na parte superior da página, escolha **US East (N. Virginia) (Leste dos EUA (Norte da Virgínia))**.

1. Crie uma função usando seu próprio código ou crie uma função começando com um esquema do CloudFront.
   + Para criar uma função usando seu próprio código, escolha **Author from scratch**. 
   + Para exibir uma lista de esquemas do CloudFront, insira **cloudfront** no campo de filtro e selecione **Enter**.

     Se você encontrar um esquema que deseja usar, selecione o nome dele.

1. Na seção **Basic information**, especifique os seguintes valores:

   1. **Nome**: insira um nome para a função.

   1. **Função**: para começar rapidamente, escolha **Criar função com base em modelo(s)**. Também é possível selecionar **Escolher uma função existente** ou **Criar uma função personalizada** e siga as instruções para concluir as informações dessa seção.

   1. **Nome da função**: insira um nome para a função.

   1. **Modelos de política**: escolha **Permissões básicas do Edge Lambda**.

1. Se você escolheu **Author from scratch** na etapa 4, vá para a etapa 7.

   Se você escolheu um esquema na etapa 4, a seção **cloudfront** permitirá que você crie um trigger, que associa essa função a um cache em uma distribuição do CloudFront e a um evento do CloudFront. Recomendamos que você escolha **Remove (Remover)** nesse momento, para que não haja um trigger para a função quando ela for criada. Você poderá adicionar gatilhos mais tarde. 
**dica**  
Recomendamos que você teste e depure a função antes de adicionar acionadores. Se você adicionar um acionador agora, a função será executada assim que for criada e concluirá a replicação para locais da AWS em todo o mundo, e a distribuição correspondente será implantada.

1. Escolha **Create function**.

   O Lambda cria duas versões da sua função: \$1LATEST e Versão 1. Você pode editar apenas a versão \$1LATEST, mas o console inicialmente exibirá a Versão 1.

1. Para editar a função, escolha **Version 1** na parte superior da página, sob o ARN da função. Na guia **Versions**, escolha **\$1LATEST**. (Se você deixou a função e depois retornou a ela, o título do botão será **Qualifiers**.)

1. Na guia **Configuration**, escolha o **Code entry type** aplicável. Em seguida, siga as instruções para editar ou fazer upload do seu código.

1. Em **Runtime**, escolha o valor com base no código da função.

1. Na seção **Tags**, adicione todas as tags aplicáveis.

1. Escolha **Actions** e, em seguida, **Publish new version**.

1. Insira uma descrição para a nova versão da função.

1. Escolha **Publish**.

1. Teste e depure a função. Consulte mais informações sobre como testar no console do Lambda em [Invocar a função do Lambda usando o console](https://docs.aws.amazon.com/lambda/latest/dg/getting-started.html#get-started-invoke-manually) no *Guia do desenvolvedor do AWS Lambda*.

1. Quando você estiver pronto para que a função seja executada em eventos do CloudFront, publique outra versão e edite-a para adicionar triggers. Para obter mais informações, consulte [Adicionar acionadores para uma função do Lambda@Edge](lambda-edge-add-triggers.md).

# Editar uma função do Lambda
<a name="lambda-edge-edit-function"></a>

Depois de criar uma função do Lambda@Edge, você pode usar o console do Lambda para editá-la.

**Observações**  
A versão original é identificada como \$1 LATEST.
Você só pode editar a versão \$1LATEST.
Cada vez que você editar a versão \$1LATEST, deverá publicar uma nova versão numerada.
Você não pode criar triggers para \$1LATEST.
Ao publicar uma nova versão de uma função, o Lambda não copiará automaticamente os triggers da versão anterior para a nova versão. Você deve reproduzir os triggers para a nova versão. 
Quando você adiciona um trigger de um evento do CloudFront a uma função, se já houver um trigger para a mesma distribuição, comportamento de cache e evento para uma versão anterior da mesma função, o Lambda excluirá o trigger da versão anterior.
Depois de fazer atualizações em uma distribuição do CloudFront, como a adição de triggers, você precisará aguardar a propagação das alterações para os pontos de presença para que as funções especificadas nos triggers funcionem.<a name="lambda-edge-edit-function-procedure"></a>

**Para editar uma função do Lambda**

1. Faça login no Console de gerenciamento da AWS e abra o console AWS Lambda em [https://console.aws.amazon.com/lambda/](https://console.aws.amazon.com/lambda/).

1. Na lista Region (Região) na parte superior da página, escolha **US East (N. Virginia) (Leste dos EUA (Norte da Virgínia))**.

1. Na lista de funções, selecione o nome da função.

   Por padrão, o console exibirá a versão \$1LATEST. Você pode visualizar versões anteriores (escolha **Qualifiers**), mas só poderá editar \$1LATEST.

1. Na guia **Code (Código)**, em **Code entry type (Tipo de entrada de código)**, escolha editar o código no navegador, fazer upload de um arquivo .zip ou fazer upload de um arquivo do Amazon S3.

1. Selecione **Save** ou **Save and test**.

1. Escolha **Actions** e **Publish new version**. 

1. Na caixa de diálogo **Publish new version from \$1LATEST**, insira uma descrição da nova versão. Essa descrição aparece na lista de versões, junto com um número de versão gerado automaticamente. 

1. Escolha **Publish**.

   A nova versão se torna automaticamente a versão mais recente. O número da versão aparece em **Versão** no canto superior esquerdo da página.
**nota**  
Se ainda não tiver adicionado acionadores para a função, consulte [Adicionar acionadores para uma função do Lambda@Edge](lambda-edge-add-triggers.md). 

1. Selecione a guia **Triggers**.

1. Escolha **Add trigger**.

1. Na caixa de diálogo **Add trigger (Adicionar trigger)**, selecione a caixa pontilhada e escolha **CloudFront**.
**nota**  
Se você já tiver criado um ou mais triggers para uma função, o CloudFront será o serviço padrão.

1. Especifique os seguintes valores para indicar quando você deseja que a função Lambda seja executada.

   1. **ID da distribuição**: escolha o ID da distribuição à qual você deseja adicionar o acionador.

   1. **Comportamento de cache**: escolha o comportamento de cache que especifica os objetos nos quais você deseja executar a função.

   1. **Evento do CloudFront**: escolha o evento do CloudFront que faz com que a função seja executada.

   1. **Ativar o trigger e replicar**: marque essa caixa de seleção para que o Lambda replique a função para Regiões da AWS globalmente.

1. Selecione **Enviar**.

1. Para adicionar mais triggers a essa função, repita as etapas de 10 a 13.

Consulte mais informações sobre como testar e depurar a função no console do Lambda em [Invocar a função do Lambda usando o console](https://docs.aws.amazon.com/lambda/latest/dg/getting-started.html#get-started-invoke-manually) no *Guia do desenvolvedor do AWS Lambda*.

Quando você estiver pronto para que a função seja executada em eventos do CloudFront, publique outra versão e edite-a para adicionar triggers. Para obter mais informações, consulte [Adicionar acionadores para uma função do Lambda@Edge](lambda-edge-add-triggers.md).

# Adicionar acionadores para uma função do Lambda@Edge
<a name="lambda-edge-add-triggers"></a>

Gatilho do Lambda@Edge é uma combinação de distribuição do CloudFront, comportamento de cache e evento que faz com que a função seja executada. Por exemplo, você pode criar um trigger que faça com que a função seja executada quando o CloudFront receber uma solicitação de um visualizador para um determinado comportamento do cache de sua configuração da distribuição. Você pode especificar um ou mais acionadores do CloudFront. 

**dica**  
Ao criar uma distribuição do CloudFront, você especifica as configurações que informam ao CloudFront como responder ao receber diferentes solicitações. As configurações padrão são chamadas de *comportamento de cache padrão *para a distribuição. Você pode configurar comportamentos de cache adicionais que definem como o CloudFront responde em circunstâncias específicas, por exemplo, quando recebe uma solicitação para um tipo de arquivo específico. Para obter mais informações, consulte [Configurações de comportamento de cache](DownloadDistValuesCacheBehavior.md).

Ao criar uma função do Lambda pela primeira vez, é possível especificar apenas *um* acionador. É possível adicionar mais acionadores à mesma função mais tarde usando o console do Lambda ou editando a distribuição no console do CloudFront.
+ O console do Lambda funciona bem para adicionar mais acionadores a uma função da mesma distribuição do CloudFront.
+ O console do CloudFront pode ser melhor para adicionar acionadores a várias distribuições, pois é mais fácil encontrar a distribuição que você deseja atualizar. Também é possível atualizar outras configurações do CloudFront ao mesmo tempo.

**Topics**
+ [Eventos do CloudFront que podem acionar uma função do Lambda@Edge](lambda-cloudfront-trigger-events.md)
+ [Escolher o evento para acionar a função](lambda-how-to-choose-event.md)
+ [Adicionar acionadores a uma função do Lambda@Edge](lambda-edge-add-triggers-console.md)

# Eventos do CloudFront que podem acionar uma função do Lambda@Edge
<a name="lambda-cloudfront-trigger-events"></a>

Para cada comportamento do cache em uma distribuição do Amazon CloudFront, é possível adicionar até quatro acionadores (associações) que fazem com que uma função do Lambda seja executada quando ocorrem eventos específicos do CloudFront. Os triggers de CloudFront podem ser baseados em um dos quatro eventos do CloudFront, conforme mostrado no diagrama a seguir.

![\[Gráfico conceitual que mostra como eventos acionadores do CloudFront para funções do Lambda integram-se ao CloudFront.\]](http://docs.aws.amazon.com/pt_br/AmazonCloudFront/latest/DeveloperGuide/images/cloudfront-events-that-trigger-lambda-functions.png)


Os eventos do CloudFront que podem ser usados para acionar as funções do Lambda@Edge são os seguintes:

**Solicitação do visualizador**  
A função é executada quando o CloudFront recebe uma solicitação de um visualizador antes de ele verificar se o objeto solicitado está no cache do CloudFront.  
A função não é executada nos seguintes casos:  
+ Ao buscar uma página de erro personalizada.
+ Quando o CloudFront redireciona automaticamente uma solicitação HTTP para HTTPS (quando o valor de [Política de protocolo do visualizador](DownloadDistValuesCacheBehavior.md#DownloadDistValuesViewerProtocolPolicy) é **Redirecionar HTTP para HTTPS**).

**Solicitação da origem**  
A função é executada *apenas* quando o CloudFront encaminha uma solicitação para a origem. Quando o objeto solicitado está no cache do CloudFront, a função não é executada.

**Resposta da origem**  
A função é executada depois que o CloudFront recebe uma resposta da origem e antes de ele armazenar o objeto em cache na resposta. Observe que a função é executada mesmo se um erro for retornado da origem.  
A função não é executada nos seguintes casos:  
+ Quando o arquivo solicitado está no cache do CloudFront e não expirou.
+ Quando a resposta é gerada de uma função acionada por um evento de solicitação de origem.

**Resposta do visualizador**  
A função é executada antes de retornar o arquivo solicitado para o visualizador. Observe que a função é executada independentemente de o arquivo já estar no cache do CloudFront.  
A função não é executada nos seguintes casos:  
+ Quando a origem retorna um código de status HTTP 400 ou posterior.
+ Quando uma página de erro personalizada é retornada.
+ Quando a resposta é gerada de uma função acionada por um evento de solicitação do visualizador.
+ Quando o CloudFront redireciona automaticamente uma solicitação HTTP para HTTPS (quando o valor de [Política de protocolo do visualizador](DownloadDistValuesCacheBehavior.md#DownloadDistValuesViewerProtocolPolicy) é **Redirecionar HTTP para HTTPS**).

Ao adicionar vários triggers para o mesmo comportamento do cache, você pode usá-los para executar a mesma função ou executar funções diferentes para cada trigger. Você também pode associar a mesma função para mais de uma distribuição.

**nota**  
Quando um evento do CloudFront aciona a execução de uma função do Lambda, a função deve ser concluída *antes* que o CloudFront possa continuar.   
Por exemplo, se uma função do Lambda for acionada por um evento de solicitação do visualizador do CloudFront, este não retornará uma resposta ao visualizador nem encaminhará a solicitação à origem enquanto a execução da função do Lambda não for concluída.   
Isso significa que cada solicitação que aciona uma função do Lambda aumenta a latência da solicitação. Portanto, é conveniente executar a função o mais rapidamente possível.

# Escolher o evento para acionar a função
<a name="lambda-how-to-choose-event"></a>

Ao decidir qual evento do CloudFront você deseja usar para acionar uma função do Lambda, considere:

**Quero que o CloudFront armazene em cache objetos que são alterados por uma função do Lambda**  
Para armazenar em cache um objeto que foi modificado por uma função do Lambda para que o CloudFront possa fornecer o objeto no local da borda na próxima vez que ele for solicitado, use os eventos de *solicitação da origem* ou de *resposta da origem*.   
Isso reduz a carga na origem, a latência de solicitações subsequentes e o custo de chamar o Lambda@Edge em solicitações subsequentes.  
Por exemplo, para adicionar, remover ou alterar os cabeçalhos dos objetos retornados pela origem e quiser que o CloudFront armazene o resultado em cache, use o evento de resposta da origem.

**Quero que a função seja executada em todas as solicitações**  
Se quiser executar a função para todas as solicitações que o CloudFront recebe para a distribuição, use os eventos de *solicitação do visualizador* ou de *resposta do visualizador*.   
Os eventos de solicitação e de resposta da origem ocorrem somente quando um objeto solicitado não é armazenado em cache em um ponto de presença, e o CloudFront encaminha uma solicitação para a origem.

**Quero que a função altere a chave de cache**  
Para alterar um valor que está sendo usado como base para o armazenamento em cache, use o evento de *solicitação do visualizador*.   
Por exemplo, se uma função altera o URL para incluir a abreviação de um idioma no caminho (por exemplo, porque o usuário escolheu o idioma em uma lista suspensa), use o evento de solicitação do visualizador:  
+ **URL na solicitação do visualizador**: https://example.com/en/index.html
+ **URL quando a solicitação é proveniente de um endereço IP na Alemanha**: https://example.com/de/index.html
O evento de solicitação do visualizador também pode ser usada se você estiver armazenando em cache com base em cookies ou cabeçalhos de solicitação.  
Se a função alterar cookies ou cabeçalhos, configure o CloudFront para encaminhar a parte aplicável da solicitação à origem. Para saber mais, consulte os seguintes tópicos:  
+ [Conteúdo em cache com base em cookies](Cookies.md)
+ [Conteúdo em cache com base nos cabeçalhos de solicitação](header-caching.md)

**A função afeta a resposta da origem**  
Para alterar a solicitação de maneira a afetar a resposta da origem, use o evento de *solicitação de origem*.   
Normalmente, a maioria dos eventos de solicitação do visualizador não é encaminhada para a origem. O CloudFront responde a uma solicitação com um objeto que já está no cache da borda. Se a função alterar a solicitação com base em um evento de solicitação de origem, o CloudFront armazenará em cache a resposta à solicitação de origem alterada.

# Adicionar acionadores a uma função do Lambda@Edge
<a name="lambda-edge-add-triggers-console"></a>

É possível usar o console do AWS Lambda ou o console do Amazon CloudFront para adicionar um acionador à função do Lambda@Edge.

**Importante**  
É possível criar acionadores somente para versões numeradas da função (não para **\$1LATEST**).

------
#### [ Lambda console ]<a name="lambda-edge-add-triggers-procedure"></a>

**Como adicionar acionadores para eventos do CloudFront a uma função do Lambda@Edge**

1. Faça login no Console de gerenciamento da AWS e abra o console AWS Lambda em [https://console.aws.amazon.com/lambda/](https://console.aws.amazon.com/lambda/).

1. Na lista Region (Região) na parte superior da página, escolha **US East (N. Virginia) (Leste dos EUA (Norte da Virgínia))**.

1. Na página **Functions**, selecione o nome da função à qual você deseja adicionar triggers.

1. Na página de **Function overview** (Visão geral da função), escolha a guia **Versions** (Versões).

1. Escolha a versão à qual você deseja adicionar triggers.

   Depois de escolher uma versão, o nome do botão mudará para **Version: \$1LATEST** ou para **Version:** *número da versão*.

1. Selecione a guia **Triggers**.

1. Escolha **Add trigger**.

1. Em **Configuração do gatilho**, escolha **Selecione uma origem**, insira **cloudfront** e selecione **CloudFront**.
**nota**  
Se você já tiver criado um ou mais triggers, o CloudFront será o serviço padrão.

1. Especifique os seguintes valores para indicar quando você deseja que a função Lambda seja executada.

   1. **Distribuição**: escolha a distribuição à qual você deseja adicionar o acionador.

   1. **Comportamento de cache**: escolha o comportamento de cache que especifica os objetos nos quais você deseja executar a função.
**nota**  
Se você especificar `*` para o comportamento do cache, a função do Lambda será implantada no comportamento do cache padrão.

   1. **Evento do CloudFront**: escolha o evento do CloudFront que faz com que a função seja executada.

   1. **Incluir corpo**: marque essa caixa de seleção se quiser acessar o corpo da solicitação na função. 

   1. **Confirmar implantação no Lambda@Edge**: marque essa caixa de seleção para que o AWS Lambda replique a função para Regiões da AWS globalmente.

1. Escolha **Adicionar**.

   A função começará a processar solicitações para os eventos do CloudFront especificados quando a distribuição atualizada do CloudFront for implantada. Para determinar se uma distribuição foi implantada, escolha **Distributions** no painel de navegação. Quando uma distribuição estiver implantada, o valor da coluna **Status** da distribuição mudará de **Deploying** (Implantando) para a data e hora da implantação.

------
#### [ CloudFront console ]<a name="lambda-create-functions-add-triggers-cloudfront-console-procedure"></a>

**Como adicionar acionadores para eventos do CloudFront a uma função do Lambda@Edge**

1. Obtenha o Nome de região da Amazon (ARN) da função do Lambda à qual você deseja adicionar triggers:

   1. Faça login no Console de gerenciamento da AWS e abra o console AWS Lambda em [https://console.aws.amazon.com/lambda/](https://console.aws.amazon.com/lambda/).

   1. Na lista de regiões na parte superior da página, escolha **US East (N. Virginia) (Leste dos EUA (Norte da Virgínia))**.

   1. Na lista de funções, selecione o nome da função à qual você deseja adicionar triggers.

   1. Na página **Function overview** (Visão geral da função), escolha a guia **Versions** (Versões) e escolha a versão numerada à qual você deseja adicionar acionadores.

   1. Selecione **Copy ARN** (Copiar ARN) para copiar o código para a área de transferência. O ARN da função do Lambda tem a seguinte aparência:

      `arn:aws:lambda:us-east-1:123456789012:function:TestFunction:2`

      O número no final (**2**, no exemplo) é o número da versão da função.

1. Abra o console do CloudFront em [https://console.aws.amazon.com/cloudfront/v4/home](https://console.aws.amazon.com/cloudfront/v4/home).

1. Na lista de distribuição, selecione o ID da distribuição à qual você deseja adicionar triggers.

1. Escolha a guia **Behaviors**.

1. Selecione o comportamento do cache ao qual você deseja adicionar acionadores e, em seguida, escolha **Edit** (Editar).

1. Em **Function associations** (Associações da função), na lista **Function type** (Tipo da função), escolha **Lambda@Edge** para quando a função deve ser executada: para solicitações do visualizador, respostas do visualizador, solicitações da origem ou respostas da origem. 

   Para obter mais informações, consulte [Escolher o evento para acionar a função](lambda-how-to-choose-event.md).

1. Na caixa de texto **Function ARN / Name** (Função ARN/Nome), cole o ARN da função do Lambda que você deseja executar quando o evento escolhido ocorrer. Esse é o valor copiado do console do Lambda.

1. Selecione **Include body** (Incluir corpo) se quiser acessar o corpo da solicitação na sua função.

   Se deseja apenas substituir o corpo da solicitação, você não precisa selecionar essa opção.

1. Para executar a mesma função em outros tipos de evento, repita as etapas 6 e 7.

1. Escolha **Salvar alterações**.

1. Para adicionar acionadores em outros comportamentos de cache para essa distribuição, repita as etapas 5 a 10.

   A função começará a processar solicitações para os eventos do CloudFront especificados quando a distribuição atualizada do CloudFront for implantada. Para determinar se uma distribuição foi implantada, escolha **Distributions** no painel de navegação. Quando uma distribuição estiver implantada, o valor da coluna **Status** da distribuição mudará de **Deploying** (Implantando) para a data e hora da implantação.

------

# Testar e depurar as funções do Lambda@Edge
<a name="lambda-edge-testing-debugging"></a>

É importante testar o código da sua função do Lambda@Edge independentemente para ter certeza de que ele conclui a tarefa pretendida e fazer testes de integração para garantir que a função funcione corretamente com o CloudFront. 

Durante o teste de integração ou depois que a função foi implantada, talvez seja necessário depurar erros do CloudFront, como erros HTTP 5xx. Os erros podem ser uma resposta inválida retornada da função do Lambda, erros de execução quando a função é acionada ou erros devido a uma limitação de execução do serviço do Lambda. As seções neste tópico compartilham estratégias para determinar qual tipo de falha é o problema e, em seguida, as etapas que você pode realizar para corrigir o problema.

**nota**  
Ao revisar os arquivos de log ou as métricas do CloudWatch durante a solução de erros, esteja ciente de que eles são exibidos ou armazenados na Região da AWS mais próxima do local em que a função foi executada. Portanto, se você tiver um site ou aplicação web com usuários no Reino Unido e, por exemplo, tiver uma função do Lambda associada à distribuição, deverá alterar a região para visualizar as métricas ou os arquivos de log do CloudWatch para a Região da AWS Londres. Para obter mais informações, consulte [Determinar a região do Lambda@Edge](#lambda-edge-testing-debugging-determine-region).

**Topics**
+ [Testar as funções do Lambda@Edge](#lambda-edge-testing-debugging-test-function)
+ [Identificar erros de função do Lambda@Edge no CloudFront](#lambda-edge-identifying-function-errors)
+ [Solução de problemas de respostas inválidas de funções do Lambda@Edge (erros de validação)](#lambda-edge-testing-debugging-troubleshooting-invalid-responses)
+ [Solução de problemas de erros de execução de funções do Lambda@Edge](#lambda-edge-testing-debugging-execution-errors)
+ [Determinar a região do Lambda@Edge](#lambda-edge-testing-debugging-determine-region)
+ [Determinar se a sua conta envia logs ao CloudWatch](#lambda-edge-testing-debugging-cloudwatch-logs-enabled)

## Testar as funções do Lambda@Edge
<a name="lambda-edge-testing-debugging-test-function"></a>

Há duas etapas para testar a função do Lambda: teste autônomo e teste de integração.

**Testar a funcionalidade autônoma**  
Antes de adicionar a função do Lambda ao CloudFront, teste a funcionalidade primeiro usando os recursos de teste no console do Lambda ou usando outros métodos. Consulte mais informações sobre como testar no console do Lambda em [Invocar a função do Lambda usando o console](https://docs.aws.amazon.com/lambda/latest/dg/getting-started.html#get-started-invoke-manually) no *Guia do desenvolvedor do AWS Lambda*.

**Testar a operação da função no CloudFront**  
É importante concluir o teste de integração, quando a função está associada a uma distribuição e é executada com base em um evento do CloudFront. Certifique-se de que a função seja acionada para o evento correto e retorne uma resposta válida e correta para o CloudFront. Por exemplo, verifique se a estrutura do evento está correta, se apenas os cabeçalhos válidos estão incluídos e assim por diante.  
Ao iterar os testes de integração com a função no console do Lambda, consulte as etapas do tutorial do Lambda@Edge à medida que você modifica o código ou altera o trigger do CloudFront que chama a função. Por exemplo, verifique se você está trabalhando em uma versão numerada da função, conforme descrito nesta etapa do tutorial: [Etapa 4: adicionar um acionador do CloudFront para executar a função](lambda-edge-how-it-works-tutorial.md#lambda-edge-how-it-works-tutorial-add-trigger).   
Ao fazer alterações e implantá-las, lembre-se de que a função e os triggers atualizados do CloudFront levarão vários minutos para serem replicados em todas as regiões. Isso geralmente leva alguns minutos, mas pode demorar até 15 minutos.  
Você pode verificar se a replicação foi concluída acessando o console do CloudFront e visualizando a distribuição.  

**Como verificar se a implantação da replicação foi concluída**

1. Abra o console do CloudFront em [https://console.aws.amazon.com/cloudfront/v4/home](https://console.aws.amazon.com/cloudfront/v4/home).

1. Escolha o nome da distribuição.

1. Verifique o status de distribuição para mudar de **In Progress** (Em progresso) para **Deployed** (Implantado), o que significa que sua função foi replicada. Em seguida, siga as etapas na próxima seção para verificar se a função funciona.
Esteja ciente de que o teste no console valida apenas a lógica da sua função e não aplica cotas de serviço (anteriormente conhecidas como limites) específicas do Lambda@Edge.

## Identificar erros de função do Lambda@Edge no CloudFront
<a name="lambda-edge-identifying-function-errors"></a>

Depois de verificar se a lógica da função funciona corretamente, você ainda poderá ver erros HTTP 5xx quando a função for executada no CloudFront. Os erros HTTP 5xx podem ser retornados por vários motivos, que incluem erros ou outros problemas da função do Lambda no CloudFront.
+ Ao usar as funções do Lambda@Edge, é possível usar gráficos no console do CloudFront para ajudar a identificar o que está causando o erro e corrigi-lo. Por exemplo, é possível ver se os erros HTTP 5xx são causados pelo CloudFront ou pelas funções do Lambda e, no caso de funções específicas, visualizar os arquivos de log relacionados para investigar o problema.
+ Para solucionar a maioria dos erros HTTP do CloudFront, consulte as etapas de solução de problemas no seguinte tópico: [Solucionar problemas de códigos de status de resposta de erros no CloudFront](troubleshooting-response-errors.md).

### O que causa erros na função do Lambda@Edge no CloudFront
<a name="lambda-edge-testing-debugging-function-errors"></a>

Existem vários motivos pelos quais uma função do Lambda pode causar um erro HTTP 5xx, e as etapas de solução de problemas que você deve seguir dependem do tipo de erro. Os erros podem ser categorizados assim:

**Um erro de execução de função do Lambda**  
Ocorre um erro de execução quando o CloudFront não obtém uma resposta do Lambda porque existem exceções não tratadas na função ou há um erro no código. Por exemplo, se o código incluir um retorno de chamada (erro).

**Uma resposta inválida da função do Lambda é retornada ao CloudFront**  
Após a execução da função, o CloudFront recebe uma resposta do Lambda. Um erro será retornado se a estrutura do objeto da resposta não estiver em conformidade com o [Estrutura de eventos do Lambda@Edge](lambda-event-structure.md) ou se a resposta contiver cabeçalhos inválidos ou outros campos inválidos.

**A execução no CloudFront é limitada devido às cotas de serviço do Lambda (anteriormente conhecidas como limites)**  
O serviço do Lambda limita as execuções em cada região e retornará um erro se você exceder a cota. Para obter mais informações, consulte [Cotas do Lambda@Edge](cloudfront-limits.md#limits-lambda-at-edge).

### Como determinar o tipo de falha
<a name="lambda-edge-testing-debugging-failure-type"></a>

Para ajudar a decidir onde se concentrar na depuração de erros e solucionar os problemas retornados pelo CloudFront, é útil identificar por que o CloudFront está retornando um erro HTTP. Para iniciar a busca, você pode usar os gráficos fornecidos na seção **Monitoring** (Monitoramento) do console do CloudFront no Console de gerenciamento da AWS. Para obter mais informações sobre como visualizar gráficos na seção **Monitoring (Monitoramento)** no console do CloudFront, consulte [Monitorar métricas do CloudFront com o Amazon CloudWatch](monitoring-using-cloudwatch.md).

Os seguintes gráficos podem ser especialmente úteis ao verificar se os erros estão sendo retornados por origens ou por uma função do Lambda, e para restringir o tipo de problema quando se trata de um erro de função do Lambda.

**Gráfico de taxas de erro**  
Um dos gráficos que você pode visualizar na guia **Overview (Visão geral)** para cada uma das suas distribuições é um gráfico **Error rates (Taxas de erro)**. Esse gráfico exibe a taxa de erros como porcentagem do total de solicitações que chegam à sua distribuição. O gráfico mostra o total de taxa de erros, total de erros 4xx, total de erros 5xx e total de erros 5xx provenientes de funções Lambda. Com base no tipo de erro e volume, você pode executar etapas para investigar e solucionar o problema.  

![\[Gráfico de taxas de erro na distribuição do CloudFront\]](http://docs.aws.amazon.com/pt_br/AmazonCloudFront/latest/DeveloperGuide/images/Distribution-error-rate-pct-full.png)

+ Se você encontrar erros do Lambda, você poderá investigar mais detalhadamente, observando os tipos específicos de erros retornados pela função. A guia **Lambda@Edge errors (Erros do Lambda@Edge)** inclui gráficos que categorizam os erros por tipo de função para ajudar a identificar o problema em uma função específica.
+ Se encontrar erros do CloudFront, você poderá solucionar e trabalhar para corrigir os erros de origem ou alterar a configuração do CloudFront. Para obter mais informações, consulte [Solucionar problemas de códigos de status de resposta de erros no CloudFront](troubleshooting-response-errors.md).

**Gráficos de erros de execução e repostas de funções inválidas**  
A guia **Lambda@Edge errors (Erros do Lambda@Edge)** inclui gráficos que categorizam os erros do Lambda@Edge em uma distribuição específica, por tipo. Por exemplo, um grafo mostra todos os erros de execução por Região da AWS.  
Para facilitar a solução de problemas, você pode procurar problemas específicos ao abrir e examinar os arquivos de log para funções específicas por região.   

**Como visualizar os arquivos de log de uma função específica por região**

1. Na guia **Erros do Lambda@Edge**, em **Funções associadas do Lambda@Edge**, escolha o nome da função e selecione **Visualizar métricas**. 

1. Em seguida, na página com o nome da função, no canto superior direito, selecione **Visualizar logs da função** e escolha uma região. 

   Por exemplo, se você encontrar problemas no grafo **Erros** para a região Oeste dos EUA (Oregon), escolha essa região na lista suspensa. Isso abrirá o console do Amazon CloudWatch.

1. No console do CloudWatch dessa região, em **Fluxos de log**, escolha um fluxo de log para visualizar os eventos da função.
Também leia as seguintes seções neste capítulo para obter mais recomendações sobre como solucionar problemas e corrigir erros.

**Gráfico de limitações**  
A guia **Lambdga@Edge errors (Erros do Lambda@Edge)** também inclui um gráfico de **Throttles (Limitações)**. Ocasionalmente, o serviço Lambda limita as invocações de função por região quando a cota (anteriormente conhecida como limite) de simultaneidade regional é atingida. Se você encontrar um erro limit exceeded (limite excedido), isso significa que a função atingiu uma cota que o serviço Lambda impõe para execuções em uma região. Para obter mais informações, incluindo como solicitar um aumento na cota, consulte [Cotas do Lambda@Edge](cloudfront-limits.md#limits-lambda-at-edge).  

![\[Grafo de controle de utilização para a execução da função do Lambda@Edge.\]](http://docs.aws.amazon.com/pt_br/AmazonCloudFront/latest/DeveloperGuide/images/Lambda-throttles-page.png)


Para obter um exemplo de como usar essas informações para solucionar erros HTTP, consulte [Quatro etapas para depurar a entrega de conteúdo na AWS](https://aws.amazon.com/blogs/networking-and-content-delivery/four-steps-for-debugging-your-content-delivery-on-aws/).

## Solução de problemas de respostas inválidas de funções do Lambda@Edge (erros de validação)
<a name="lambda-edge-testing-debugging-troubleshooting-invalid-responses"></a>

Se você identificar que o problema é um erro de validação do Lambda, a função do Lambda poderá estar retornando uma resposta inválida ao CloudFront. Siga as orientações nesta seção para tomar medidas para analisar a função e garantir que a resposta esteja de acordo com os requisitos do CloudFront. 

O CloudFront valida a resposta de uma função do Lambda de duas maneiras:
+ **A resposta do Lambda deve estar de acordo com a estrutura de objeto necessária.** Exemplos de estruturas de objeto inválidas incluem o seguinte: JSON não analisável, campos obrigatórios ausentes e um objeto inválido na resposta. Para mais informações, consulte o [Estrutura de eventos do Lambda@Edge](lambda-event-structure.md).
+ **A resposta deve incluir apenas valores de objeto válidos.** Um erro ocorrerá se a resposta incluir um objeto válido, mas tiver valores sem suporte. Os exemplos incluem o seguinte: adicionar ou atualizar cabeçalhos permitidos ou somente leitura (consulte [Restrições das funções de borda](edge-functions-restrictions.md)), exceder o tamanho máximo do corpo (consulte *Restrições sobre o tamanho da resposta gerada* no tópico [Erros](lambda-generating-http-responses.md#lambda-generating-http-responses-errors) do Lambda@Edge) e caracteres ou valores inválidos (consulte o [Estrutura de eventos do Lambda@Edge](lambda-event-structure.md)).

Quando o Lambda retorna uma resposta inválida ao CloudFront, as mensagens de erro são gravados em arquivos de log que o CloudFront envia por push ao CloudWatch na região em que a função do Lambda foi executada. O comportamento padrão é enviar os arquivos de log ao CloudWatch quando há uma resposta inválida. No entanto, se você tiver associado uma função do Lambda ao CloudFront antes do lançamento dessa funcionalidade, talvez ela não esteja habilitada para a função. Para obter mais informações, consulte *Determinar se a conta envia logs por push ao CloudWatch*, mais adiante neste tópico.

O CloudFront envia arquivos de log à região correspondente ao local onde a função foi executada, no grupo de logs associado à sua distribuição. Os grupos de log têm o seguinte formato: `/aws/cloudfront/LambdaEdge/DistributionId`, em que *DistributionId* é o ID da distribuição. Para determinar a região na qual você pode encontrar os arquivos de log do CloudWatch, consulte *Determinar a região do Lambda@Edge* mais adiante neste tópico.

Se for possível reproduzir o erro, você poderá criar uma nova solicitação que resulte no erro e encontrar o id da solicitação em uma resposta do CloudFront com falha (cabeçalho `X-Amz-Cf-Id`) para localizar uma única falha nos arquivos de log. A entrada do arquivo de log inclui informações que podem ajudar a identificar porque o erro está sendo retornado, e também lista o id da solicitação do Lambda correspondente, para que você possa analisar a causa raiz no contexto de uma única solicitação.

Se um erro for intermitente, você poderá usar os logs de acesso do CloudFront para encontrar o id de uma solicitação que falhou e depois pesquisar as mensagens de erro correspondentes nos CloudWatch Logs. Para mais informações, consulte a seção anterior, *Determinar o tipo de falha*.

## Solução de problemas de erros de execução de funções do Lambda@Edge
<a name="lambda-edge-testing-debugging-execution-errors"></a>

Se o problema for um erro de execução do Lambda, poderá ser útil criar instruções de registro em log para funções do Lambda, gravar mensagens nos arquivos de log CloudWatch que monitoram a execução da função no CloudFront e determinar se ela está funcionando conforme o esperado. Depois, você pode pesquisar essas instruções nos arquivos de log do CloudWatch para verificar se a sua função está funcionando.

**nota**  
Mesmo que você não tenha alterado a função do Lambda@Edge, as atualizações no ambiente de execução da função do Lambda podem afetá-la e um erro de execução poderá ser retornado. Para obter informações sobre como testar e migrar para uma versão mais recente, consulte [Próximas atualizações no AWS Lambda e no ambiente de execução do AWS Lambda@Edge](https://aws.amazon.com/blogs/compute/upcoming-updates-to-the-aws-lambda-execution-environment/).

## Determinar a região do Lambda@Edge
<a name="lambda-edge-testing-debugging-determine-region"></a>

Para ver as regiões em que a função do Lambda@Edge está recebendo tráfego, visualize os gráficos das métricas da função no console do CloudFron no Console de gerenciamento da AWS. As métricas são exibidas para cada região da AWS. Na mesma página, é possível escolher uma região e visualizar os arquivos de log para essa região a fim de investigar problemas. Revise os arquivos de log do CloudWatch na região correta da AWS para ver os arquivos de log criados quando o CloudFront executou a função do Lambda.

Para obter mais informações sobre como visualizar gráficos na seção **Monitoring (Monitoramento)** no console do CloudFront, consulte [Monitorar métricas do CloudFront com o Amazon CloudWatch](monitoring-using-cloudwatch.md).

## Determinar se a sua conta envia logs ao CloudWatch
<a name="lambda-edge-testing-debugging-cloudwatch-logs-enabled"></a>

Por padrão, o CloudFront habilita o registro em log de respostas de função inválidas do Lambda e envia por push os arquivos de log para o CloudWatch usando uma das [Funções vinculadas ao serviço para o Lambda@Edge](lambda-edge-permissions.md#using-service-linked-roles-lambda-edge). Se você tiver funções do Lambda@Edge adicionadas ao CloudFront antes do lançamento do recurso de log de respostas de função inválidas do Lambda, o registro em log será habilitado quando você atualizar a configuração do Lambda@Edge, por exemplo, adicionando um trigger do CloudFront.

É possível verificar se o envio por push dos arquivos de log ao CloudWatch está habilitado para a conta, fazendo o seguinte:
+ **Verifique se os logs aparecem no CloudWatch**: examine na região em que a função do Lambda@Edge foi executada. Para obter mais informações, consulte [Determinar a região do Lambda@Edge](#lambda-edge-testing-debugging-determine-region).
+ **Determine se o perfil vinculado ao serviço relacionado existe na sua conta do IAM**: você deve ter o perfil do IAM `AWSServiceRoleForCloudFrontLogger` na sua conta. Para obter mais informações sobre esse perfil, consulte [Funções vinculadas ao serviço para o Lambda@Edge](lambda-edge-permissions.md#using-service-linked-roles-lambda-edge).

# Excluir funções e réplicas do Lambda@Edge
<a name="lambda-edge-delete-replicas"></a>

Só é possível excluir uma função do Lambda@Edge quando as réplicas da função tiverem sido excluídas pelo CloudFront. As réplicas de uma função do Lambda são excluídas automaticamente nas seguintes situações:
+ Depois de remover a última associação da função de todas as distribuições do CloudFront. Se mais de uma distribuição usar uma função, as réplicas serão excluídas somente depois que a associação da função for removida da última distribuição.
+ Depois que você excluir a última distribuição com a qual a função estava associada.

Geralmente, as réplicas são excluídas dentro de algumas horas. Não é possível excluir manualmente réplicas de função do Lambda@Edge. Isso ajuda a evitar que uma réplica ainda em uso seja excluída, o que resultaria em um erro.

**Atenção**  
Não crie aplicações que usem réplicas de função do Lambda@Edge fora do CloudFront. Essas réplicas são excluídas quando suas associações a distribuições são removidas ou quando as próprias distribuições são excluídas. A réplica da qual um aplicativo externo depende poderá ser removida sem aviso prévio, fazendo com que ele falhe.

**Como excluir uma associação de função do Lambda@Edge de uma distribuição do CloudFront**

1. Faça login no Console de gerenciamento da AWS e abra o console do CloudFront em [https://console.aws.amazon.com/cloudfront/v4/home](https://console.aws.amazon.com/cloudfront/v4/home).

1. Escolha o ID da distribuição com a associação da função do Lambda@Edge que deseja excluir.

1. Escolha a guia **Behaviors**.

1. Selecione o comportamento de cache que possui a associação de função do Lambda@Edge que deseja excluir e selecione **Edit** (Editar).

1. Em **Function associations** (Associações da função), **Function type** (Tipo da função), escolha **No association** (Nenhuma associação) para excluir a associação da função do Lambda@Edge.

1. Escolha **Salvar alterações**.

Depois de excluir uma associação de função do Lambda@Edge de uma distribuição do CloudFront, você pode, opcionalmente, excluir a função Lambda ou a versão da função do AWS Lambda. Aguarde algumas horas após excluir a associação da função para que as réplicas da função do Lambda@Edge possam ser limpas. Depois disso, é possível excluir a função usando o console do Lambda, a AWS CLI, a API do Lambda ou um AWS SDK.

Também é possível excluir uma *versão* específica de uma função do Lambda se ela não tiver nenhuma distribuição do CloudFront associada a ela. Depois de remover todas as associações de uma versão de função do Lambda, aguarde algumas horas. Depois, você pode excluir a versão da função.

# Estrutura de eventos do Lambda@Edge
<a name="lambda-event-structure"></a>

Os tópicos a seguir descrevem os objetos de eventos de solicitação e resposta que o CloudFront passa para uma função do Lambda@Edge quando ela é acionada.

**Topics**
+ [Seleção de origem dinâmica](#lambda-event-content-based-routing)
+ [Eventos de solicitação](#lambda-event-structure-request)
+ [Eventos de resposta](#lambda-event-structure-response)

## Seleção de origem dinâmica
<a name="lambda-event-content-based-routing"></a>

Você pode usar [o padrão do caminho em um comportamento de cache](DownloadDistValuesCacheBehavior.md#DownloadDistValuesPathPattern) para rotear as solicitações para uma origem, de acordo com o caminho e o nome do objeto solicitado, como `images/*.jpg`. Usando o Lambda@Edge, você também pode rotear as solicitações para uma origem com base em outras características, como os valores nos cabeçalhos de solicitação. 

Essa seleção de origem dinâmica pode ser útil de várias maneiras. Por exemplo, você pode distribuir solicitações em origens em diferentes áreas geográficas para ajudar com o balanceamento de carga global. Ou você pode seletivamente rotear solicitações para diferentes origens que cada servir uma determinada função: manuseio de bot, otimização de SEO, autenticação, e assim por diante. Para obter exemplos de código que demonstram como usar esse recurso, consulte [Seleção de origem dinâmica baseada em conteúdo: exemplos](lambda-examples.md#lambda-examples-content-based-routing-examples).

No evento de solicitação de origem do CloudFront, o objeto `origin` na estrutura do evento contém informações sobre a origem para a qual a solicitação seria roteada, de acordo com o padrão de caminho. Você pode atualizar os valores no objeto `origin` para rotear uma solicitação para outra origem. Quando você atualiza o objeto `origin`, não precisa definir a origem na distribuição. Também é possível substituir um objeto de origem do Amazon S3 por um objeto de origem personalizado e vice-versa. No entanto, só é possível especificar uma única origem por solicitação; uma origem personalizada ou uma origem do Amazon S3, mas não ambas.

## Eventos de solicitação
<a name="lambda-event-structure-request"></a>

Os tópicos a seguir mostram a estrutura do objeto que o CloudFront passa para uma função do Lambda para [eventos de solicitação do visualizador e da origem](lambda-cloudfront-trigger-events.md). Estes exemplos mostram uma solicitação `GET` sem corpo. Após os exemplos, está uma lista de todos os campos possíveis em eventos de solicitação de visualizador e origem.

**Topics**
+ [Exemplo de solicitação de visualizador](#example-viewer-request)
+ [Exemplo de solicitação de origem](#example-origin-request)
+ [Campos de eventos de solicitação](#request-event-fields)

### Exemplo de solicitação de visualizador
<a name="example-viewer-request"></a>

O exemplo a seguir mostra um objeto de evento de solicitação de visualizador.

```
{
  "Records": [
    {
      "cf": {
        "config": {
          "distributionDomainName": "d111111abcdef8.cloudfront.net",
          "distributionId": "EDFDVBD6EXAMPLE",
          "eventType": "viewer-request",
          "requestId": "4TyzHTaYWb1GX1qTfsHhEqV6HUDd_BzoBZnwfnvQc_1oF26ClkoUSEQ=="
        },
        "request": {
          "clientIp": "203.0.113.178",
          "headers": {
            "host": [
              {
                "key": "Host",
                "value": "d111111abcdef8.cloudfront.net"
              }
            ],
            "user-agent": [
              {
                "key": "User-Agent",
                "value": "curl/7.66.0"
              }
            ],
            "accept": [
              {
                "key": "accept",
                "value": "*/*"
              }
            ]
          },
          "method": "GET",
          "querystring": "",
          "uri": "/"
        }
      }
    }
  ]
}
```

### Exemplo de solicitação de origem
<a name="example-origin-request"></a>

O exemplo a seguir mostra um objeto de evento de solicitação de origem.

```
{
  "Records": [
    {
      "cf": {
        "config": {
          "distributionDomainName": "d111111abcdef8.cloudfront.net",
          "distributionId": "EDFDVBD6EXAMPLE",
          "eventType": "origin-request",
          "requestId": "4TyzHTaYWb1GX1qTfsHhEqV6HUDd_BzoBZnwfnvQc_1oF26ClkoUSEQ=="
        },
        "request": {
          "clientIp": "203.0.113.178",
          "headers": {
            "x-forwarded-for": [
              {
                "key": "X-Forwarded-For",
                "value": "203.0.113.178"
              }
            ],
            "user-agent": [
              {
                "key": "User-Agent",
                "value": "Amazon CloudFront"
              }
            ],
            "via": [
              {
                "key": "Via",
                "value": "2.0 2afae0d44e2540f472c0635ab62c232b.cloudfront.net (CloudFront)"
              }
            ],
            "host": [
              {
                "key": "Host",
                "value": "example.org"
              }
            ],
            "cache-control": [
              {
                "key": "Cache-Control",
                "value": "no-cache"
              }
            ]
          },
          "method": "GET",
          "origin": {
            "custom": {
              "customHeaders": {},
              "domainName": "example.org",
              "keepaliveTimeout": 5,
              "path": "",
              "port": 443,
              "protocol": "https",
              "readTimeout": 30,
              "responseCompletionTimeout": 30,
              "sslProtocols": [
                "TLSv1",
                "TLSv1.1",
                "TLSv1.2"
              ]
            }
          },
          "querystring": "",
          "uri": "/"
        }
      }
    }
  ]
}
```

### Campos de eventos de solicitação
<a name="request-event-fields"></a>

Os dados do objeto de evento de solicitação estão contidos em dois subobjetos: `config` (`Records.cf.config`) e `request` (`Records.cf.request`). As listas a seguir descrevem os campos de cada subobjeto.

#### Campos no objeto de configuração
<a name="request-event-fields-config"></a>

A lista a seguir descreve os campos no objeto `config` (`Records.cf.config`).

**`distributionDomainName` (somente leitura)**  
O nome de domínio da distribuição associada à solicitação.

**`distributionID` (somente leitura)**  
O ID da distribuição associada à solicitação.

**`eventType` (somente leitura)**  
O tipo de acionador associado à solicitação: `viewer-request` ou `origin-request`.

**`requestId` (somente leitura)**  
Uma string criptografada que identifica exclusivamente uma solicitação do visualizador ao CloudFront. O valor de `requestId` também aparece nos logs de acesso do CloudFront como `x-edge-request-id`. Para obter mais informações, consulte [Logs de acesso (logs padrão)](AccessLogs.md) e [Campos de arquivo de log](standard-logs-reference.md#BasicDistributionFileFormat).

#### Campos no objeto de solicitação
<a name="request-event-fields-request"></a>

A lista a seguir descreve os campos no objeto `request` (`Records.cf.request`).

**`clientIp` (somente leitura)**  
O endereço IP do visualizador que fez a solicitação. Se o visualizador usar um proxy HTTP ou um load balancer para enviar a solicitação, o valor será o endereço IP do proxy ou do load balancer.

**Cabeçalhos (leitura/gravação)**  
Os cabeçalhos na solicitação. Observe o seguinte:  
+ As chaves no objeto `headers` são versões em letras minúsculas de nomes de cabeçalho HTTP padrão. Usar chaves em letras minúsculas dá acesso sem diferenciar letras maiúsculas e minúsculas dos valores de cabeçalho.
+ Cada objeto de cabeçalho (por exemplo, `headers["accept"]` ou `headers["host"]`) é uma matriz de pares de chave-valor. Para um determinado cabeçalho, a matriz contém um par de chave-valor para cada valor na solicitação.
+ `key` contém o nome do cabeçalho com distinção entre maiúsculas e minúsculas conforme ele apareceu na solicitação HTTP; por exemplo, `Host`, `User-Agent`, `X-Forwarded-For`, `Cookie` e assim por diante.
+ `value` contém o valor do cabeçalho conforme ele apareceu na solicitação HTTP.
+ Quando a função do Lambda adicionar ou modificar cabeçalhos de solicitação e você não incluir o campo `key` do cabeçalho, o Lambda@Edge inserirá automaticamente uma `key` de cabeçalho usando o nome de cabeçalho que você fornecer. Independentemente de como você tiver formatado o nome do cabeçalho, a chave de cabeçalho inserida automaticamente será formatada com inicial maiúscula para cada parte, separada por hifens (-).

  Por exemplo, você pode adicionar um cabeçalho como o seguinte, sem um de cabeçalh `key`:

  ```
  "user-agent": [
    {
      "value": "ExampleCustomUserAgent/1.X.0"
    }
  ]
  ```

  Neste exemplo, o Lambda@Edge insere automaticamente `"key": "User-Agent"`.
Para obter informações sobre as restrições de uso do cabeçalho, consulte [Restrições das funções de borda](edge-functions-restrictions.md).

**`method` (somente leitura)**  
O método HTTP da solicitação.

**`querystring` (leitura/gravação)**  
A string de consulta, se houver, na solicitação. Se a solicitação não incluir uma string de consulta, o objeto de evento ainda incluirá `querystring` com um valor vazio. Para obter mais informações sobre query strings, consulte [Conteúdo em cache com base em parâmetros de string de consulta](QueryStringParameters.md).

**`uri` (leitura/gravação)**  
O caminho relativo do objeto solicitado. Se a função do Lambda modificar o valor `uri`, observe o seguinte:  
+ O novo valor `uri` deve começar com uma barra (/).
+ Se uma função alterar o valor `uri`, isso alterará o objeto solicitado pelo visualizador.
+ Se uma função alterar o valor `uri`, isso *não* mudará o comportamento do cache da solicitação ou da origem para a qual a solicitação é enviada.

**`body` (leitura/gravação)**  
O corpo da solicitação HTTP. A estrutura `body` pode conter os seguintes campos:    
**`inputTruncated` (somente leitura)**  
Um sinalizador booliano que indica se o corpo foi truncado pelo Lambda@Edge. Para obter mais informações, consulte [Restrições do corpo da solicitação com a opção de incluir corpo](lambda-at-edge-function-restrictions.md#lambda-at-edge-restrictions-request-body).  
**`action` (leitura/gravação)**  
A ação que você pretende realizar com o corpo. As opções para `action` são as seguintes:  
+ `read-only:` esse é o padrão. Ao retornar a resposta da função do Lambda, se `action` for somente leitura, o Lambda@Edge ignorará todas as alterações em `encoding` ou em `data`.
+ `replace:` especifique isso quando quiser substituir o corpo enviado à origem.  
**`encoding` (leitura/gravação)**  
A codificação do corpo. Ao expor o corpo à função do Lambda, o Lambda@Edge primeiro converte o corpo em base64-encoding. Se você escolher `replace` para `action` substituir o corpo, poderá optar por usar a codificação `base64` (padrão) ou `text`. Se você especificar `encoding` como `base64`, mas o corpo não for um base64 válido, o CloudFront retornará um erro.  
**`data` (leitura/gravação)**  
O conteúdo do corpo da solicitação. 

**`origin` (leitura/gravação) (somente eventos de origem)**  
A origem para a qual enviar a solicitação. A estrutura `origin` deve conter *exatamente uma origem*, que pode ser personalizada ou do Amazon S3.  
Dependendo do tipo de origem que você especificar (origens personalizadas ou do Amazon S3), será necessário especificar os seguintes campos em sua solicitação:    
**`customHeaders` (leitura/gravação) (origens personalizadas e do Amazon S3)**  
(Opcional) É possível incluir os cabeçalhos personalizados com a solicitação ao especificar o par de nome e valor para cada cabeçalho personalizado. Não é possível adicionar cabeçalhos não permitidos, e não pode haver um cabeçalho com o mesmo nome em `Records.cf.request.headers`. As [notas sobre cabeçalhos de solicitação](#request-event-fields-request-headers) também se aplicam a cabeçalhos personalizados. Para obter mais informações, consulte [Cabeçalhos personalizados que o CloudFront não pode adicionar às solicitações da origem](add-origin-custom-headers.md#add-origin-custom-headers-denylist) e [Restrições das funções de borda](edge-functions-restrictions.md).  
**`domainName` (leitura/gravação) (origens personalizadas e do Amazon S3)**  
O nome de domínio da origem. O nome de domínio não pode estar vazio.  
+ **Para origens personalizadas** — especifique um nome de domínio DNS, como `www.example.com`. O nome de domínio não pode incluir dois-pontos (:) e não pode ser um endereço IP. O nome de domínio pode ter até 253 caracteres.
+ **Para origens do Amazon S3**: especifique o nome de domínio DNS do bucket do Amazon S3, como `amzn-s3-demo-bucket.s3.eu-west-1.amazonaws.com`. O nome pode ter até 128 caracteres e deve ser todo em minúsculas.  
**`path` (leitura/gravação) (origens personalizadas e do Amazon S3)**  
O caminho do diretório na origem em que a solicitação deve localizar o conteúdo. O caminho deve começar com uma barra (/), mas não deve terminar com uma (por exemplo, não deve terminar com `example-path/`). Apenas para origens personalizadas, o caminho deve ser codificado por URL e ter um comprimento máximo de 255 caracteres.  
**`keepaliveTimeout` (leitura/gravação) (somente origens personalizadas)**  
O tempo, em segundos, durante o qual o CloudFront deve tentar manter a conexão com a origem depois de receber o último pacote da resposta. O valor deve ser um número de 1 a 120, inclusive.  
**`port` (leitura/gravação) (somente origens personalizadas)**  
A porta à qual o CloudFront deve se conectar em sua origem personalizada. A porta deve ser 80, 443 ou um número no intervalo de 1024 a 65535, inclusive.  
**`protocol` (leitura/gravação) (somente origens personalizadas)**  
O protocolo de conexão que o CloudFront deve usar ao se conectar à sua origem. O valor pode ser `http` ou `https`.  
**`readTimeout` (leitura/gravação) (origens personalizadas e do Amazon S3)**  
O tempo, em segundos, que o CloudFront deve esperar por uma resposta depois de enviar uma solicitação à origem. Isso também especifica o tempo que o CloudFront deve aguardar depois de receber um pacote de resposta antes de receber o próximo pacote. O valor deve ser um número de 1 a 120, inclusive.  
Se você precisar de uma cota maior, consulte [Tempo limite de resposta por origem.](cloudfront-limits.md#limits-web-distributions)  
**`responseCompletionTimeout` (leitura/gravação) (origens personalizadas e do Amazon S3)**  
O tempo (em segundos) em que uma solicitação do CloudFront para a origem pode permanecer aberta e aguardar uma resposta. Se a resposta completa não for recebida da origem até esse momento, o CloudFront encerrará a conexão.  
O valor para `responseCompletionTimeout` deve ser igual a ou maior que o valor para `readTimeout`. Se você definir esse valor como 0, ele removerá qualquer valor anterior definido e retornará ao padrão. Você também pode fazer isso excluindo o campo `responseCompletionTimeout` da solicitação de evento.   
**`sslProtocols` (leitura/gravação) (somente origens personalizadas)**  
O protocolo SSL/TLS mínimo que o CloudFront pode usar ao estabelecer uma conexão HTTPS com a origem. Os valores podem ser qualquer um dos seguintes: `TLSv1.2`, `TLSv1.1`, `TLSv1` ou `SSLv3`.  
**`authMethod` (leitura/gravação) (somente origens do Amazon S3)**  
Se você estiver usando uma [identidade do acesso de origem (OAI)](private-content-restricting-access-to-s3.md#private-content-restricting-access-to-s3-oai), defina esse campo como `origin-access-identity`. Se você não estiver usando uma OAI, defina-o como `none`. Se você definir `authMethod` como `origin-access-identity`, haverá vários requisitos:   
+ Você deve especificar `region` (consulte o campo a seguir).
+ Use o mesmo OAI ao alterar a solicitação de uma origem do Amazon S3 para outra.
+ Não é possível usar uma OAI ao alterar a solicitação de uma origem personalizada para uma origem do Amazon S3.
Esse campo não aceita [controle de acesso à origem (OAC)](private-content-restricting-access-to-s3.md).  
**`region` (leitura/gravação) (somente origens do Amazon S3)**  
A região da AWS do bucket do Amazon S3. Isso é necessário apenas quando você define `authMethod` como `origin-access-identity`.

## Eventos de resposta
<a name="lambda-event-structure-response"></a>

Os tópicos a seguir mostram a estrutura do objeto que o CloudFront passa para uma função do Lambda para [eventos de resposta do visualizador e da origem](lambda-cloudfront-trigger-events.md). Após os exemplos, está uma lista de todos os campos possíveis em eventos de resposta do visualizador e da origem.

**Topics**
+ [Exemplo de resposta da origem](#lambda-event-structure-response-origin)
+ [Exemplo de resposta do visualizador](#lambda-event-structure-response-viewer)
+ [Campos de evento de resposta](#response-event-fields)

### Exemplo de resposta da origem
<a name="lambda-event-structure-response-origin"></a>

O exemplo a seguir mostra um objeto de evento de resposta da origem.

```
{
  "Records": [
    {
      "cf": {
        "config": {
          "distributionDomainName": "d111111abcdef8.cloudfront.net",
          "distributionId": "EDFDVBD6EXAMPLE",
          "eventType": "origin-response",
          "requestId": "4TyzHTaYWb1GX1qTfsHhEqV6HUDd_BzoBZnwfnvQc_1oF26ClkoUSEQ=="
        },
        "request": {
          "clientIp": "203.0.113.178",
          "headers": {
            "x-forwarded-for": [
              {
                "key": "X-Forwarded-For",
                "value": "203.0.113.178"
              }
            ],
            "user-agent": [
              {
                "key": "User-Agent",
                "value": "Amazon CloudFront"
              }
            ],
            "via": [
              {
                "key": "Via",
                "value": "2.0 8f22423015641505b8c857a37450d6c0.cloudfront.net (CloudFront)"
              }
            ],
            "host": [
              {
                "key": "Host",
                "value": "example.org"
              }
            ],
            "cache-control": [
              {
                "key": "Cache-Control",
                "value": "no-cache"
              }
            ]
          },
          "method": "GET",
          "origin": {
            "custom": {
              "customHeaders": {},
              "domainName": "example.org",
              "keepaliveTimeout": 5,
              "path": "",
              "port": 443,
              "protocol": "https",
              "readTimeout": 30,
              "responseCompletionTimeout": 30,
              "sslProtocols": [
                "TLSv1",
                "TLSv1.1",
                "TLSv1.2"
              ]
            }
          },
          "querystring": "",
          "uri": "/"
        },
        "response": {
          "headers": {
            "access-control-allow-credentials": [
              {
                "key": "Access-Control-Allow-Credentials",
                "value": "true"
              }
            ],
            "access-control-allow-origin": [
              {
                "key": "Access-Control-Allow-Origin",
                "value": "*"
              }
            ],
            "date": [
              {
                "key": "Date",
                "value": "Mon, 13 Jan 2020 20:12:38 GMT"
              }
            ],
            "referrer-policy": [
              {
                "key": "Referrer-Policy",
                "value": "no-referrer-when-downgrade"
              }
            ],
            "server": [
              {
                "key": "Server",
                "value": "ExampleCustomOriginServer"
              }
            ],
            "x-content-type-options": [
              {
                "key": "X-Content-Type-Options",
                "value": "nosniff"
              }
            ],
            "x-frame-options": [
              {
                "key": "X-Frame-Options",
                "value": "DENY"
              }
            ],
            "x-xss-protection": [
              {
                "key": "X-XSS-Protection",
                "value": "1; mode=block"
              }
            ],
            "content-type": [
              {
                "key": "Content-Type",
                "value": "text/html; charset=utf-8"
              }
            ],
            "content-length": [
              {
                "key": "Content-Length",
                "value": "9593"
              }
            ]
          },
          "status": "200",
          "statusDescription": "OK"
        }
      }
    }
  ]
}
```

### Exemplo de resposta do visualizador
<a name="lambda-event-structure-response-viewer"></a>

O exemplo a seguir mostra um objeto de evento de resposta do visualizador.

```
{
  "Records": [
    {
      "cf": {
        "config": {
          "distributionDomainName": "d111111abcdef8.cloudfront.net",
          "distributionId": "EDFDVBD6EXAMPLE",
          "eventType": "viewer-response",
          "requestId": "4TyzHTaYWb1GX1qTfsHhEqV6HUDd_BzoBZnwfnvQc_1oF26ClkoUSEQ=="
        },
        "request": {
          "clientIp": "203.0.113.178",
          "headers": {
            "host": [
              {
                "key": "Host",
                "value": "d111111abcdef8.cloudfront.net"
              }
            ],
            "user-agent": [
              {
                "key": "User-Agent",
                "value": "curl/7.66.0"
              }
            ],
            "accept": [
              {
                "key": "accept",
                "value": "*/*"
              }
            ]
          },
          "method": "GET",
          "querystring": "",
          "uri": "/"
        },
        "response": {
          "headers": {
            "access-control-allow-credentials": [
              {
                "key": "Access-Control-Allow-Credentials",
                "value": "true"
              }
            ],
            "access-control-allow-origin": [
              {
                "key": "Access-Control-Allow-Origin",
                "value": "*"
              }
            ],
            "date": [
              {
                "key": "Date",
                "value": "Mon, 13 Jan 2020 20:14:56 GMT"
              }
            ],
            "referrer-policy": [
              {
                "key": "Referrer-Policy",
                "value": "no-referrer-when-downgrade"
              }
            ],
            "server": [
              {
                "key": "Server",
                "value": "ExampleCustomOriginServer"
              }
            ],
            "x-content-type-options": [
              {
                "key": "X-Content-Type-Options",
                "value": "nosniff"
              }
            ],
            "x-frame-options": [
              {
                "key": "X-Frame-Options",
                "value": "DENY"
              }
            ],
            "x-xss-protection": [
              {
                "key": "X-XSS-Protection",
                "value": "1; mode=block"
              }
            ],
            "age": [
              {
                "key": "Age",
                "value": "2402"
              }
            ],
            "content-type": [
              {
                "key": "Content-Type",
                "value": "text/html; charset=utf-8"
              }
            ],
            "content-length": [
              {
                "key": "Content-Length",
                "value": "9593"
              }
            ]
          },
          "status": "200",
          "statusDescription": "OK"
        }
      }
    }
  ]
}
```

### Campos de evento de resposta
<a name="response-event-fields"></a>

Os dados do objeto de evento de resposta estão contidos em três subobjetos: `config` (`Records.cf.config`), `request` (`Records.cf.request`) e `response` (`Records.cf.response`). Para obter mais informações sobre os campos no objeto da solicitação, consulte [Campos no objeto de solicitação](#request-event-fields-request). As listas a seguir descrevem os campos nos subobjetos `config` e `response`.

#### Campos no objeto de configuração
<a name="response-event-fields-config"></a>

A lista a seguir descreve os campos no objeto `config` (`Records.cf.config`).

**`distributionDomainName` (somente leitura)**  
O nome de domínio da distribuição associada à resposta.

**`distributionID` (somente leitura)**  
O ID da distribuição associada à resposta.

**`eventType` (somente leitura)**  
O tipo de acionador associado à resposta: `origin-response` ou `viewer-response`.

**`requestId` (somente leitura)**  
Uma string criptografada que identifica exclusivamente a solicitação do visualizador ao CloudFront à qual esta resposta está associada. O valor de `requestId` também aparece nos logs de acesso do CloudFront como `x-edge-request-id`. Para obter mais informações, consulte [Logs de acesso (logs padrão)](AccessLogs.md) e [Campos de arquivo de log](standard-logs-reference.md#BasicDistributionFileFormat).

#### Campos no objeto de resposta
<a name="response-event-fields-response"></a>

A lista a seguir descreve os campos no objeto `response` (`Records.cf.response`). Para obter informações sobre como usar uma função do Lambda@Edge para gerar uma resposta HTTP, consulte [Gerar respostas de HTTP em acionadores da solicitação](lambda-generating-http-responses.md#lambda-generating-http-responses-in-requests).

**`headers` (leitura/gravação)**  
Os cabeçalhos na resposta. Observe o seguinte:  
+ As chaves no objeto `headers` são versões em letras minúsculas de nomes de cabeçalho HTTP padrão. Usar chaves em letras minúsculas dá acesso sem diferenciar letras maiúsculas e minúsculas dos valores de cabeçalho.
+ Cada objeto de cabeçalho (por exemplo, `headers["content-type"]` ou `headers["content-length"]`) é uma matriz de pares de chave-valor. Para determinado cabeçalho, a matriz contém um par de chave-valor para cada valor na resposta.
+ `key` contém o nome do cabeçalho com distinção entre maiúsculas e minúsculas conforme aparece na resposta HTTP; por exemplo, `Content-Type`, `Content-Length`, `Cookie`, e assim por diante.
+ `value` contém o valor do cabeçalho como ele aparece na resposta HTTP.
+ Quando a função do Lambda adicionar ou modificar cabeçalhos de resposta e você não incluir o campo `key` do cabeçalho, o Lambda@Edge inserirá automaticamente uma `key` de cabeçalho usando o nome de cabeçalho que você fornecer. Independentemente de como você tiver formatado o nome do cabeçalho, a chave de cabeçalho inserida automaticamente será formatada com inicial maiúscula para cada parte, separada por hifens (-).

  Por exemplo, você pode adicionar um cabeçalho como o seguinte, sem um de cabeçalh `key`:

  ```
  "content-type": [
    {
      "value": "text/html;charset=UTF-8"
    }
  ]
  ```

  Neste exemplo, o Lambda@Edge insere automaticamente `"key": "Content-Type"`.
Para obter informações sobre as restrições de uso do cabeçalho, consulte [Restrições das funções de borda](edge-functions-restrictions.md).

**`status`**  
O código de status HTTP da resposta.

**`statusDescription`**  
A descrição do status HTTP da resposta.

# Trabalho com solicitações e respostas
<a name="lambda-generating-http-responses"></a>

Para usar as solicitações e as respostas do Lambda@Edge, consulte os seguintes tópicos:

**Topics**
+ [Usar funções do Lambda@Edge com failover de origem](#lambda-and-origin-failover)
+ [Gerar respostas de HTTP em acionadores da solicitação](#lambda-generating-http-responses-in-requests)
+ [Atualizar respostas de HTTP em acionadores de resposta da origem](#lambda-updating-http-responses)
+ [Acessar o corpo da solicitação escolhendo a opção de incluir o corpo](#lambda-include-body-access)

## Usar funções do Lambda@Edge com failover de origem
<a name="lambda-and-origin-failover"></a>

É possível usar as funções do Lambda@Edge com distribuições do CloudFront que você configurou com grupos de origens, por exemplo, para um failover de origem que você configura para ajudar a garantir a alta disponibilidade. Para usar uma função do Lambda com um grupo de origem, especifique a função em um trigger de resposta ou de solicitação de origem para um grupo de origens ao criar o comportamento de cache.

Para saber mais, consulte:
+ **Criar grupos de origens:** [Criar um grupo de origem](high_availability_origin_failover.md#concept_origin_groups.creating)
+ **Como um failover de origem funciona com o Lambda@Edge:** [Uso do failover de origem com funções do Lambda@Edge](high_availability_origin_failover.md#concept_origin_groups.lambda)

## Gerar respostas de HTTP em acionadores da solicitação
<a name="lambda-generating-http-responses-in-requests"></a>

Quando o CloudFront recebe uma solicitação, você pode usar uma função do Lambda para gerar uma resposta HTTP que o CloudFront retornará diretamente ao visualizador sem encaminhar a resposta para a origem. Gerar respostas HTTP reduz a carga na origem e geralmente também reduz a latência para o visualizador.

Alguns cenários comuns para gerar respostas HTTP incluem o seguinte:
+ Retornar uma pequena página da web ao visualizador
+ Retornar um código de status HTTP 301 ou 302 para redirecionar o usuário para outra página da web
+ Retornar um código de status HTTP 401 para o visualizador quando o usuário ainda não tiver sido autenticado

Uma função do Lambda@Edge pode gerar uma resposta HTTP quando ocorrerem os seguintes eventos do CloudFront:

**Eventos de solicitação de visualizador**  
Quando uma função for acionada por um evento de solicitação do visualizador, o CloudFront retornará a resposta ao visualizador e não a armazenará em cache.

**Eventos de solicitação de origem**  
Quando a função for acionada por um evento de solicitação de origem, o CloudFront verificará se há uma resposta gerada anteriormente pela função no cache de borda.   
+ Se a resposta estiver no cache, a função não será executada e o CloudFront retornará a resposta em cache ao visualizador.
+ Se a resposta não estiver no cache, a função será executada, o CloudFront retornará a resposta ao visualizador e também a armazenará em cache.

Para ver códigos de exemplo para gerar respostas HTTP, consulte [Funções de exemplo do Lambda@Edge](lambda-examples.md). Você também pode substituir as respostas HTTP em triggers de resposta. Para obter mais informações, consulte [Atualizar respostas de HTTP em acionadores de resposta da origem](#lambda-updating-http-responses).

### Modelo de programação
<a name="lambda-generating-http-responses-programming-model"></a>

Esta seção descreve o modelo de programação para usar o Lambda@Edge para gerar respostas HTTP.

**Topics**
+ [Objeto da resposta](#lambda-generating-http-responses-object)
+ [Erros](#lambda-generating-http-responses-errors)
+ [Campos obrigatórios](#lambda-generating-http-responses-required-fields)

#### Objeto da resposta
<a name="lambda-generating-http-responses-object"></a>

A resposta que você retornar como o parâmetro `result` do método `callback` deverá ter a seguinte estrutura (observe que apenas o campo `status` é necessário).

```
const response = {
    body: 'content',
    bodyEncoding: 'text' | 'base64',
    headers: {
        'header name in lowercase': [{
            key: 'header name in standard case',
            value: 'header value'
         }],
         ...
    },
    status: 'HTTP status code (string)',
    statusDescription: 'status description'
};
```

O objeto de resposta pode incluir os seguintes valores:

**`body`**  
O corpo, se houver, que você deseja que o CloudFront retorne na resposta gerada.

**`bodyEncoding`**  
A codificação para o valor que você especificou no `body`. As únicas codificações válidas são `text` e `base64`. Se você incluir `body` no objeto `response`, mas omitir `bodyEncoding`, o CloudFront tratará o corpo como texto.  
Se você especificar `bodyEncoding` como `base64`, mas o corpo não for um base64 válido, o CloudFront retornará um erro.

**`headers`**  
Cabeçalhos que você deseja que o CloudFront retorne na resposta gerada. Observe o seguinte:  
+ As chaves no objeto `headers` são versões em letras minúsculas de nomes de cabeçalho HTTP padrão. Usar chaves em letras minúsculas dá acesso sem diferenciar letras maiúsculas e minúsculas dos valores de cabeçalho.
+ Cada cabeçalho (por exemplo, `headers["accept"]` ou `headers["host"]`) é uma matriz de pares de chave-valor. Para determinado cabeçalho, a matriz contém um par de chave-valor para cada valor na resposta gerada.
+ `key` (opcional) é o nome com distinção entre letras maiúsculas e minúsculas do cabeçalho da forma como ele aparece em uma solicitação HTTP, por exemplo, `accept` ou `host`.
+ Especifique `value` como valor do cabeçalho.
+ Se você não incluir a parte da chave do par de chave-valor do cabeçalho, o Lambda@Edge inserirá automaticamente uma chave de cabeçalho usando o nome de cabeçalho fornecido. Independentemente de como você tiver formatado o nome do cabeçalho, a chave de cabeçalho inserida será automaticamente formatada com o uso de iniciais maiúsculas para cada parte, separada por hífen (-).

  Por exemplo, você pode adicionar um cabeçalho como o seguinte, sem uma chave de cabeçalho: `'content-type': [{ value: 'text/html;charset=UTF-8' }]`

  Neste exemplo, o Lambda@ Edge cria a seguinte chave de cabeçalho: `Content-Type`.
Para obter informações sobre as restrições de uso do cabeçalho, consulte [Restrições das funções de borda](edge-functions-restrictions.md).

**`status`**  
Código de status do HTTP. Forneça o código de status como uma string. O CloudFront usa o código de status fornecido para o seguinte:  
+ Retornar na resposta
+ Armazenar no cache de borda do CloudFront, quando a resposta tiver sido gerada por uma função acionada por um evento de solicitação de origem
+ Fazer login no CloudFront [Logs de acesso (logs padrão)](AccessLogs.md)
Se o valor de `status` não estiver entre 200 e 599, o CloudFront retornará um erro ao visualizador.

**`statusDescription`**  
A descrição que você deseja que o CloudFront retorne na resposta para acompanhar o código de status HTTP. Você não precisa usar descrições padrão, como `OK`, para um código de status HTTP de 200.

#### Erros
<a name="lambda-generating-http-responses-errors"></a>

Veja a seguir os erros possíveis das respostas HTTP geradas.

**A resposta contém um corpo e especifica 204 (sem conteúdo) como status**  
Quando uma função for acionada por uma solicitação de visualizador, o CloudFront retornará um código de status HTTP 502 (gateway inválido) ao visualizador quando ocorrer o seguinte:  
+ O valor de `status` for 204 (sem conteúdo)
+ A resposta incluir um valor para `body`
Isso ocorre porque o Lambda@Edge impõe a restrição opcional encontrada na RFC 2616: uma resposta `HTTP 204` não precisa conter um corpo de mensagem.

**Restrições ao tamanho da resposta gerada**  
O tamanho máximo de uma resposta gerada por uma função do Lambda depende do evento que acionou a função:  
+ **Eventos de solicitação de visualizador**: 40 KB
+ **Eventos de solicitação de origem**: 1 MB
Se a resposta for maior que o tamanho permitido, o CloudFront retornará um código de status HTTP 502 (gateway inválido) ao visualizador.

#### Campos obrigatórios
<a name="lambda-generating-http-responses-required-fields"></a>

O campo `status` é obrigatório. 

Todos os demais campos são opcionais.

## Atualizar respostas de HTTP em acionadores de resposta da origem
<a name="lambda-updating-http-responses"></a>

Quando o CloudFront recebe uma resposta HTTP do servidor de origem, se houver um trigger de resposta de origem associado ao comportamento de cache, você poderá modificar a resposta HTTP para substituir o que foi retornado pela origem.

Alguns cenários comuns para atualizar respostas HTTP incluem o seguinte:
+ Alterar o status para definir um código de status HTTP 200 e a criação de conteúdo estático do corpo para retornar ao visualizador quando uma origem retornar um código de status de erro (4xx ou 5xx). Para obter o código de exemplo, consulte [Exemplo: usar um acionador de resposta de origem para atualizar o código do status de erro para 200](lambda-examples.md#lambda-examples-custom-error-static-body).
+ Alterar o status para definir um código de status HTTP 301 ou 302, de forma a redirecionar o usuário para outro site quando uma origem retornar um código de status de erro (4xx ou 5xx). Para obter o código de exemplo, consulte [Exemplo: usar um acionador de resposta de origem para atualizar o código do status de erro para 302](lambda-examples.md#lambda-examples-custom-error-new-site).

**nota**  
A função deve retornar um valor de status entre `200` e `599` (inclusive); do contrário, o CloudFront retornará um erro ao visualizador.

Você também pode substituir as respostas HTTP em eventos de solicitação do visualizador e da origem. Para obter mais informações, consulte [Gerar respostas de HTTP em acionadores da solicitação](#lambda-generating-http-responses-in-requests).

Ao trabalhar com a resposta de HTTP, o Lambda@Edge não expõe o corpo retornado pelo servidor de origem ao acionador da resposta de origem. Você pode gerar um corpo de conteúdo estático definindo-o no valor desejado ou removendo o corpo de dentro da função ao definir o valor como vazio. Se você não atualizar o campo do corpo na função, o corpo original retornado pelo servidor de origem será reapresentado ao visualizador.

## Acessar o corpo da solicitação escolhendo a opção de incluir o corpo
<a name="lambda-include-body-access"></a>

Você pode optar por fazer com que o Lambda@Edge exponha o corpo em uma solicitação para métodos HTTP graváveis (POST, PUT, DELETE e assim por diante), para que seja possível acessá-lo na função do Lambda. Você pode escolher acesso somente leitura ou especificar que substituirá o corpo.

Para ativar essa opção, escolha **Include Body (Incluir corpo)** ao criar um trigger do CloudFront para sua função que seja para um evento de solicitação de visualizador ou de origem. Para obter mais informações, consulte [Adicionar acionadores para uma função do Lambda@Edge](lambda-edge-add-triggers.md) ou, para saber como usar a opção **Include Body (Incluir corpo)** com a função, consulte [Estrutura de eventos do Lambda@Edge](lambda-event-structure.md).

Os cenários em que você pode querer usar esse recurso incluem:
+ Processamento de formulários da web, como formulários "entre em contato conosco", sem enviar dados de entrada do cliente de volta aos servidores de origem.
+ Reunir dados de web beacons enviados por navegadores dos visualizadores e processá-los no ponto.

Para obter o código de exemplo, consulte [Funções de exemplo do Lambda@Edge](lambda-examples.md).

**nota**  
Se o corpo da solicitação for grande, o Lambda@Edge o truncará. Para obter informações detalhadas sobre truncamento e tamanho máximo, consulte [Restrições do corpo da solicitação com a opção de incluir corpo](lambda-at-edge-function-restrictions.md#lambda-at-edge-restrictions-request-body).

# Funções de exemplo do Lambda@Edge
<a name="lambda-examples"></a>

Veja os exemplos a seguir de como usar as funções do Lambda com o Amazon CloudFront.

**nota**  
Se você escolher o runtime Node.js 18 ou posterior para a função Lambda@Edge, um arquivo `index.mjs` será criado automaticamente para você. Para usar os exemplos de código a seguir, renomeie o arquivo `index.mjs` para `index.js`.

**Topics**
+ [Exemplos gerais](#lambda-examples-general-examples)
+ [Gerar respostas: exemplos](#lambda-examples-generated-response-examples)
+ [Strings de consulta: exemplos](#lambda-examples-query-string-examples)
+ [Personalizar o conteúdo por cabeçalhos de país ou tipo de dispositivo: exemplos](#lambda-examples-redirecting-examples)
+ [Seleção de origem dinâmica baseada em conteúdo: exemplos](#lambda-examples-content-based-routing-examples)
+ [Atualização do status de erro: exemplos](#lambda-examples-update-error-status-examples)
+ [Acesso ao corpo da solicitação: exemplos](#lambda-examples-access-request-body-examples)

## Exemplos gerais
<a name="lambda-examples-general-examples"></a>

Os exemplos a seguir mostram as maneiras comuns de usar o Lambda@Edge no CloudFront.

**Topics**
+ [Exemplo: testes A/B](#lambda-examples-a-b-testing)
+ [Exemplo: substituir um cabeçalho de resposta](#lambda-examples-overriding-response-header)

### Exemplo: testes A/B
<a name="lambda-examples-a-b-testing"></a>

Você pode usar o exemplo a seguir para testar duas versões diferentes de uma imagem sem criar redirecionamentos nem alterar a URL. Este exemplo lê os cookies na solicitação do visualizador e modifica a URL da solicitação adequadamente. Se o visualizador não enviar um cookie com um dos valores esperados, o exemplo atribuirá aleatoriamente o visualizador a um dos URLs.

------
#### [ Node.js ]

```
'use strict';

exports.handler = (event, context, callback) => {
    const request = event.Records[0].cf.request;
    const headers = request.headers;

    if (request.uri !== '/experiment-pixel.jpg') {
        // do not process if this is not an A-B test request
        callback(null, request);
        return;
    }

    const cookieExperimentA = 'X-Experiment-Name=A';
    const cookieExperimentB = 'X-Experiment-Name=B';
    const pathExperimentA = '/experiment-group/control-pixel.jpg';
    const pathExperimentB = '/experiment-group/treatment-pixel.jpg';

    /*
     * Lambda at the Edge headers are array objects.
     *
     * Client may send multiple Cookie headers, i.e.:
     * > GET /viewerRes/test HTTP/1.1
     * > User-Agent: curl/7.18.1 (x86_64-unknown-linux-gnu) libcurl/7.18.1 OpenSSL/1.0.1u zlib/1.2.3
     * > Cookie: First=1; Second=2
     * > Cookie: ClientCode=abc
     * > Host: example.com
     *
     * You can access the first Cookie header at headers["cookie"][0].value
     * and the second at headers["cookie"][1].value.
     *
     * Header values are not parsed. In the example above,
     * headers["cookie"][0].value is equal to "First=1; Second=2"
     */
    let experimentUri;
    if (headers.cookie) {
        for (let i = 0; i < headers.cookie.length; i++) {
            if (headers.cookie[i].value.indexOf(cookieExperimentA) >= 0) {
                console.log('Experiment A cookie found');
                experimentUri = pathExperimentA;
                break;
            } else if (headers.cookie[i].value.indexOf(cookieExperimentB) >= 0) {
                console.log('Experiment B cookie found');
                experimentUri = pathExperimentB;
                break;
            }
        }
    }

    if (!experimentUri) {
        console.log('Experiment cookie has not been found. Throwing dice...');
        if (Math.random() < 0.75) {
            experimentUri = pathExperimentA;
        } else {
            experimentUri = pathExperimentB;
        }
    }

    request.uri = experimentUri;
    console.log(`Request uri set to "${request.uri}"`);
    callback(null, request);
};
```

------
#### [ Python ]

```
import json
import random

def lambda_handler(event, context):
    request = event['Records'][0]['cf']['request']
    headers = request['headers']

    if request['uri'] != '/experiment-pixel.jpg':
        # Not an A/B Test
        return request

    cookieExperimentA, cookieExperimentB = 'X-Experiment-Name=A', 'X-Experiment-Name=B'
    pathExperimentA, pathExperimentB = '/experiment-group/control-pixel.jpg', '/experiment-group/treatment-pixel.jpg'

    '''
    Lambda at the Edge headers are array objects.

    Client may send multiple cookie headers. For example:
    > GET /viewerRes/test HTTP/1.1
    > User-Agent: curl/7.18.1 (x86_64-unknown-linux-gnu) libcurl/7.18.1 OpenSSL/1.0.1u zlib/1.2.3
    > Cookie: First=1; Second=2
    > Cookie: ClientCode=abc
    > Host: example.com

    You can access the first Cookie header at headers["cookie"][0].value
    and the second at headers["cookie"][1].value.

    Header values are not parsed. In the example above,
    headers["cookie"][0].value is equal to "First=1; Second=2"
    '''

    experimentUri = ""

    for cookie in headers.get('cookie', []):
        if cookieExperimentA in cookie['value']:
            print("Experiment A cookie found")
            experimentUri = pathExperimentA
            break
        elif cookieExperimentB in cookie['value']:
            print("Experiment B cookie found")
            experimentUri = pathExperimentB
            break

    if not experimentUri:
        print("Experiment cookie has not been found. Throwing dice...")
        if random.random() < 0.75:
            experimentUri = pathExperimentA
        else:
            experimentUri = pathExperimentB

    request['uri'] = experimentUri
    print(f"Request uri set to {experimentUri}")
    return request
```

------

### Exemplo: substituir um cabeçalho de resposta
<a name="lambda-examples-overriding-response-header"></a>

O exemplo abaixo mostra como alterar o valor de um cabeçalho de resposta com base no valor de outro cabeçalho.

------
#### [ Node.js ]

```
export const handler = async (event) => {
    const response = event.Records[0].cf.response;
    const headers = response.headers;

    const headerNameSrc = 'X-Amz-Meta-Last-Modified';
    const headerNameDst = 'Last-Modified';

    if (headers[headerNameSrc.toLowerCase()]) {
        headers[headerNameDst.toLowerCase()] = [{
            key: headerNameDst,
            value: headers[headerNameSrc.toLowerCase()][0].value,
        }];
        console.log(`Response header "${headerNameDst}" was set to ` +
                    `"${headers[headerNameDst.toLowerCase()][0].value}"`);
    }

    return response;
};
```

------
#### [ Python ]

```
import json 

def lambda_handler(event, context):
    response = event['Records'][0]['cf']['response']
    headers = response['headers']
    
    header_name_src = 'X-Amz-Meta-Last-Modified'
    header_name_dst = 'Last-Modified'
    
    if headers.get(header_name_src.lower()):
        headers[header_name_dst.lower()] = [{
            'key': header_name_dst,
            'value': headers[header_name_src.lower()][0]['value']
        }]
        print(f'Response header "{header_name_dst}" was set to '
              f'"{headers[header_name_dst.lower()][0]["value"]}"')
    
    return response
```

------

## Gerar respostas: exemplos
<a name="lambda-examples-generated-response-examples"></a>

Os exemplos a seguir mostram como você pode usar o Lambda@Edge para gerar respostas.

**Topics**
+ [Exemplo: fornecer conteúdo estático (resposta gerada)](#lambda-examples-static-web-server)
+ [Exemplo: gerar um redirecionamento de HTTP (resposta gerada)](#lambda-examples-http-redirect)

### Exemplo: fornecer conteúdo estático (resposta gerada)
<a name="lambda-examples-static-web-server"></a>

O exemplo a seguir mostra como usar uma função do Lambda para fornecer conteúdo estático de site. Isso reduz a carga no servidor de origem e a latência geral. 

**nota**  
Você pode gerar respostas HTTP para eventos de solicitação de visualizador e de solicitação de origem. Para obter mais informações, consulte [Gerar respostas de HTTP em acionadores da solicitação](lambda-generating-http-responses.md#lambda-generating-http-responses-in-requests).  
Você também pode substituir ou remover o corpo da resposta de HTTP em eventos de resposta de origem. Para obter mais informações, consulte [Atualizar respostas de HTTP em acionadores de resposta da origem](lambda-generating-http-responses.md#lambda-updating-http-responses).

------
#### [ Node.js ]

```
'use strict';

const content = `
<\!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <title>Simple Lambda@Edge Static Content Response</title>
  </head>
  <body>
    <p>Hello from Lambda@Edge!</p>
  </body>
</html>
`;

exports.handler = (event, context, callback) => {
    /*
     * Generate HTTP OK response using 200 status code with HTML body.
     */
    const response = {
        status: '200',
        statusDescription: 'OK',
        headers: {
            'cache-control': [{
                key: 'Cache-Control',
                value: 'max-age=100'
            }],
            'content-type': [{
                key: 'Content-Type',
                value: 'text/html'
            }]
        },
        body: content,
    };
    callback(null, response);
};
```

------
#### [ Python ]

```
import json

CONTENT = """
<\!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <title>Simple Lambda@Edge Static Content Response</title>
</head>
<body>
    <p>Hello from Lambda@Edge!</p>
</body>
</html>
"""

def lambda_handler(event, context):
    # Generate HTTP OK response using 200 status code with HTML body.
    response = {
        'status': '200',
        'statusDescription': 'OK',
        'headers': {
            'cache-control': [
                {
                    'key': 'Cache-Control',
                    'value': 'max-age=100'
                }
            ],
            "content-type": [
                {
                    'key': 'Content-Type',
                    'value': 'text/html'
                }
            ]
        },
        'body': CONTENT
    }
    return response
```

------

### Exemplo: gerar um redirecionamento de HTTP (resposta gerada)
<a name="lambda-examples-http-redirect"></a>

O exemplo abaixo mostra como gerar um redirecionamento HTTP.

**nota**  
Você pode gerar respostas HTTP para eventos de solicitação de visualizador e de solicitação de origem. Para obter mais informações, consulte [Gerar respostas de HTTP em acionadores da solicitação](lambda-generating-http-responses.md#lambda-generating-http-responses-in-requests).

------
#### [ Node.js ]

```
'use strict';

exports.handler = (event, context, callback) => {
    /*
     * Generate HTTP redirect response with 302 status code and Location header.
     */
    const response = {
        status: '302',
        statusDescription: 'Found',
        headers: {
            location: [{
                key: 'Location',
                value: 'https://docs.aws.amazon.com/lambda/latest/dg/lambda-edge.html',
            }],
        },
    };
    callback(null, response);
};
```

------
#### [ Python ]

```
def lambda_handler(event, context):

    # Generate HTTP redirect response with 302 status code and Location header.

    response = {
        'status': '302',
        'statusDescription': 'Found',
        'headers': {
            'location': [{
                'key': 'Location',
                'value': 'https://docs.aws.amazon.com/lambda/latest/dg/lambda-edge.html'
            }]
        }
    }

    return response
```

------

## Strings de consulta: exemplos
<a name="lambda-examples-query-string-examples"></a>

Os exemplos a seguir mostram maneiras de usar o Lambda@Edge com strings de consulta.

**Topics**
+ [Exemplo: adicionar um cabeçalho com base em um parâmetro de string de consulta](#lambda-examples-header-based-on-query-string)
+ [Exemplo: normalizar os parâmetros da string de consulta para melhorar a proporção de acertos no cache](#lambda-examples-normalize-query-string-parameters)
+ [Exemplo: redirecionar usuários não autenticados para uma página de login](#lambda-examples-redirect-to-signin-page)

### Exemplo: adicionar um cabeçalho com base em um parâmetro de string de consulta
<a name="lambda-examples-header-based-on-query-string"></a>

O exemplo a seguir mostra como obter o par chave-valor de um parâmetro de string de consulta e adicionar um cabeçalho com base nesses valores.

------
#### [ Node.js ]

```
'use strict';

const querystring = require('querystring');
exports.handler = (event, context, callback) => {
    const request = event.Records[0].cf.request;
    
    /* When a request contains a query string key-value pair but the origin server
     * expects the value in a header, you can use this Lambda function to
     * convert the key-value pair to a header. Here's what the function does:
     * 1. Parses the query string and gets the key-value pair.
     * 2. Adds a header to the request using the key-value pair that the function got in step 1.
     */

    /* Parse request querystring to get javascript object */
    const params = querystring.parse(request.querystring);

    /* Move auth param from querystring to headers */
    const headerName = 'Auth-Header';
    request.headers[headerName.toLowerCase()] = [{ key: headerName, value: params.auth }];
    delete params.auth;

    /* Update request querystring */
    request.querystring = querystring.stringify(params);

    callback(null, request);
};
```

------
#### [ Python ]

```
from urllib.parse import parse_qs, urlencode

def lambda_handler(event, context):
    request = event['Records'][0]['cf']['request']

    '''
    When a request contains a query string key-value pair but the origin server
    expects the value in a header, you can use this Lambda function to
    convert the key-value pair to a header. Here's what the function does:
        1. Parses the query string and gets the key-value pair.
        2. Adds a header to the request using the key-value pair that the function got in step 1.
    '''

    # Parse request querystring to get dictionary/json
    params = {k : v[0] for k, v in parse_qs(request['querystring']).items()}

    # Move auth param from querystring to headers
    headerName = 'Auth-Header'
    request['headers'][headerName.lower()] = [{'key': headerName, 'value': params['auth']}]
    del params['auth']

    # Update request querystring
    request['querystring'] = urlencode(params)

    return request
```

------

### Exemplo: normalizar os parâmetros da string de consulta para melhorar a proporção de acertos no cache
<a name="lambda-examples-normalize-query-string-parameters"></a>

O exemplo a seguir mostra como melhorar o índice de ocorrência no cache fazendo as seguintes alterações nas strings de consulta antes que o CloudFront encaminhe as solicitações para a origem:
+ Colocar os pares de chave-valor em ordem alfabética pelo nome do parâmetro.
+ Alterar os pares de chave-valor para minúsculas.

Para obter mais informações, consulte [Conteúdo em cache com base em parâmetros de string de consulta](QueryStringParameters.md).

------
#### [ Node.js ]

```
'use strict';

const querystring = require('querystring');

exports.handler = (event, context, callback) => {
    const request = event.Records[0].cf.request;
    /* When you configure a distribution to forward query strings to the origin and
     * to cache based on an allowlist of query string parameters, we recommend
     * the following to improve the cache-hit ratio:
     * - Always list parameters in the same order.
     * - Use the same case for parameter names and values.
     *
     * This function normalizes query strings so that parameter names and values
     * are lowercase and parameter names are in alphabetical order.
     *
     * For more information, see:
     * https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/QueryStringParameters.html
     */

    console.log('Query String: ', request.querystring);

    /* Parse request query string to get javascript object */
    const params = querystring.parse(request.querystring.toLowerCase());
    const sortedParams = {};

    /* Sort param keys */
    Object.keys(params).sort().forEach(key => {
        sortedParams[key] = params[key];
    });

    /* Update request querystring with normalized  */
    request.querystring = querystring.stringify(sortedParams);

    callback(null, request);
};
```

------
#### [ Python ]

```
from urllib.parse import parse_qs, urlencode

def lambda_handler(event, context):
    request = event['Records'][0]['cf']['request']
    '''
    When you configure a distribution to forward query strings to the origin and
    to cache based on an allowlist of query string parameters, we recommend
    the following to improve the cache-hit ratio:
    Always list parameters in the same order.
    - Use the same case for parameter names and values.

    This function normalizes query strings so that parameter names and values
    are lowercase and parameter names are in alphabetical order.

    For more information, see:
    https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/QueryStringParameters.html
    '''
    print("Query string: ", request["querystring"])

    # Parse request query string to get js object
    params = {k : v[0] for k, v in parse_qs(request['querystring'].lower()).items()}

    # Sort param keys
    sortedParams = sorted(params.items(), key=lambda x: x[0])

    # Update request querystring with normalized
    request['querystring'] = urlencode(sortedParams)
    
    return request
```

------

### Exemplo: redirecionar usuários não autenticados para uma página de login
<a name="lambda-examples-redirect-to-signin-page"></a>

O exemplo a seguir mostra como redirecionar os usuários para uma página de login caso não tenham inserido as credenciais.

------
#### [ Node.js ]

```
'use strict';

function parseCookies(headers) {
    const parsedCookie = {};
    if (headers.cookie) {
        headers.cookie[0].value.split(';').forEach((cookie) => {
            if (cookie) {
                const parts = cookie.split('=');
                parsedCookie[parts[0].trim()] = parts[1].trim();
            }
        });
    }
    return parsedCookie;
}

exports.handler = (event, context, callback) => {
    const request = event.Records[0].cf.request;
    const headers = request.headers;

    /* Check for session-id in request cookie in viewer-request event,
     * if session-id is absent, redirect the user to sign in page with original
     * request sent as redirect_url in query params.
     */

    /* Check for session-id in cookie, if present then proceed with request */
    const parsedCookies = parseCookies(headers);
    if (parsedCookies && parsedCookies['session-id']) {
        callback(null, request);
        return;
    }

    /* URI encode the original request to be sent as redirect_url in query params */
    const encodedRedirectUrl = encodeURIComponent(`https://${headers.host[0].value}${request.uri}?${request.querystring}`);
    const response = {
        status: '302',
        statusDescription: 'Found',
        headers: {
            location: [{
                key: 'Location',
                value: `https://www.example.com/signin?redirect_url=${encodedRedirectUrl}`,
            }],
        },
    };
    callback(null, response);
};
```

------
#### [ Python ]

```
import urllib

def parseCookies(headers):
    parsedCookie = {}
    if headers.get('cookie'):
        for cookie in headers['cookie'][0]['value'].split(';'):
            if cookie:
                parts = cookie.split('=')
                parsedCookie[parts[0].strip()] = parts[1].strip()
    return parsedCookie

def lambda_handler(event, context):
    request = event['Records'][0]['cf']['request']
    headers = request['headers']

    '''
    Check for session-id in request cookie in viewer-request event,
    if session-id is absent, redirect the user to sign in page with original
    request sent as redirect_url in query params.
    '''

    # Check for session-id in cookie, if present, then proceed with request
    parsedCookies = parseCookies(headers)

    if parsedCookies and parsedCookies['session-id']:
        return request

    # URI encode the original request to be sent as redirect_url in query params
    redirectUrl = "https://%s%s?%s" % (headers['host'][0]['value'], request['uri'], request['querystring'])
    encodedRedirectUrl = urllib.parse.quote_plus(redirectUrl.encode('utf-8'))

    response = {
        'status': '302',
        'statusDescription': 'Found',
        'headers': {
            'location': [{
                'key': 'Location',
                'value': 'https://www.example.com/signin?redirect_url=%s' % encodedRedirectUrl
            }]
        }
    }
    return response
```

------

## Personalizar o conteúdo por cabeçalhos de país ou tipo de dispositivo: exemplos
<a name="lambda-examples-redirecting-examples"></a>

Os exemplos a seguir mostram como você pode usar o Lambda@Edge para personalizar o comportamento com base no local ou no tipo de dispositivo usado pelo visualizador.

**Topics**
+ [Exemplo: redirecionar as solicitações do visualizador para um URL específico do país](#lambda-examples-redirect-based-on-country)
+ [Exemplo: fornecer diferentes versões de um objeto com base no dispositivo](#lambda-examples-vary-on-device-type)

### Exemplo: redirecionar as solicitações do visualizador para um URL específico do país
<a name="lambda-examples-redirect-based-on-country"></a>

O exemplo a seguir mostra como gerar uma resposta de redirecionamento HTTP com um URL específico do país e retornar a resposta para o visualizador. Isso é útil quando você deseja fornecer respostas específicas do país. Por exemplo:
+ Se tiver subdomínios específicos do país, como us.example.com e tw.example.com, você pode gerar uma resposta de redirecionamento quando um visualizador solicitar example.com.
+ Se estiver transmitindo um vídeo, mas não tem direitos para transmitir o conteúdo em um país específico, você pode redirecionar os usuários desse país para uma página que explica por que eles não podem visualizar o vídeo. 

Observe o seguinte:
+ É necessário configurar a distribuição para armazenar em cache com base no cabeçalho `CloudFront-Viewer-Country`. Para obter mais informações, consulte [Cache baseado em Cabeçalhos de solicitação selecionados](DownloadDistValuesCacheBehavior.md#DownloadDistValuesForwardHeaders).
+ O CloudFront adiciona o cabeçalho `CloudFront-Viewer-Country` após o evento de solicitação do visualizador. Para usar este exemplo, é necessário criar um trigger para o evento de solicitação da origem.

------
#### [ Node.js ]

```
'use strict';

/* This is an origin request function */
exports.handler = (event, context, callback) => {
    const request = event.Records[0].cf.request;
    const headers = request.headers;

    /*
     * Based on the value of the CloudFront-Viewer-Country header, generate an
     * HTTP status code 302 (Redirect) response, and return a country-specific
     * URL in the Location header.
     * NOTE: 1. You must configure your distribution to cache based on the
     *          CloudFront-Viewer-Country header. For more information, see
     *          https://docs.aws.amazon.com/console/cloudfront/cache-on-selected-headers
     *       2. CloudFront adds the CloudFront-Viewer-Country header after the viewer
     *          request event. To use this example, you must create a trigger for the
     *          origin request event.
     */

    let url = 'https://example.com/';
    if (headers['cloudfront-viewer-country']) {
        const countryCode = headers['cloudfront-viewer-country'][0].value;
        if (countryCode === 'TW') {
            url = 'https://tw.example.com/';
        } else if (countryCode === 'US') {
            url = 'https://us.example.com/';
        }
    }

    const response = {
        status: '302',
        statusDescription: 'Found',
        headers: {
            location: [{
                key: 'Location',
                value: url,
            }],
        },
    };
    callback(null, response);
};
```

------
#### [ Python ]

```
# This is an origin request function

def lambda_handler(event, context):
    request = event['Records'][0]['cf']['request']
    headers = request['headers']

    '''
    Based on the value of the CloudFront-Viewer-Country header, generate an
    HTTP status code 302 (Redirect) response, and return a country-specific
    URL in the Location header.
    NOTE: 1. You must configure your distribution to cache based on the
            CloudFront-Viewer-Country header. For more information, see
            https://docs.aws.amazon.com/console/cloudfront/cache-on-selected-headers
          2. CloudFront adds the CloudFront-Viewer-Country header after the viewer
            request event. To use this example, you must create a trigger for the
            origin request event.
    '''

    url = 'https://example.com/'
    viewerCountry = headers.get('cloudfront-viewer-country')
    if viewerCountry:
        countryCode = viewerCountry[0]['value']
        if countryCode == 'TW':
            url = 'https://tw.example.com/'
        elif countryCode == 'US':
            url = 'https://us.example.com/'

    response = {
        'status': '302',
        'statusDescription': 'Found',
        'headers': {
            'location': [{
                'key': 'Location',
                'value': url
            }]
        }
    }

    return response
```

------

### Exemplo: fornecer diferentes versões de um objeto com base no dispositivo
<a name="lambda-examples-vary-on-device-type"></a>

O exemplo a seguir mostra como servir diferentes versões de um objeto com base no tipo de dispositivo usado pelo usuário, por exemplo, um dispositivo móvel ou um tablet. Observe o seguinte:
+ É necessário configurar a distribuição para armazenar em cache com base nos cabeçalhos `CloudFront-Is-*-Viewer`. Para obter mais informações, consulte [Cache baseado em Cabeçalhos de solicitação selecionados](DownloadDistValuesCacheBehavior.md#DownloadDistValuesForwardHeaders).
+ O CloudFront adiciona os cabeçalhos `CloudFront-Is-*-Viewer` após o evento de solicitação do visualizador. Para usar este exemplo, é necessário criar um trigger para o evento de solicitação da origem.

------
#### [ Node.js ]

```
'use strict';

/* This is an origin request function */
exports.handler = (event, context, callback) => {
    const request = event.Records[0].cf.request;
    const headers = request.headers;

    /*
     * Serve different versions of an object based on the device type.
     * NOTE: 1. You must configure your distribution to cache based on the
     *          CloudFront-Is-*-Viewer headers. For more information, see
     *          the following documentation:
     *          https://docs.aws.amazon.com/console/cloudfront/cache-on-selected-headers
     *          https://docs.aws.amazon.com/console/cloudfront/cache-on-device-type
     *       2. CloudFront adds the CloudFront-Is-*-Viewer headers after the viewer
     *          request event. To use this example, you must create a trigger for the
     *          origin request event.
     */

    const desktopPath = '/desktop';
    const mobilePath = '/mobile';
    const tabletPath = '/tablet';
    const smarttvPath = '/smarttv';

    if (headers['cloudfront-is-desktop-viewer']
        && headers['cloudfront-is-desktop-viewer'][0].value === 'true') {
        request.uri = desktopPath + request.uri;
    } else if (headers['cloudfront-is-mobile-viewer']
               && headers['cloudfront-is-mobile-viewer'][0].value === 'true') {
        request.uri = mobilePath + request.uri;
    } else if (headers['cloudfront-is-tablet-viewer']
               && headers['cloudfront-is-tablet-viewer'][0].value === 'true') {
        request.uri = tabletPath + request.uri;
    } else if (headers['cloudfront-is-smarttv-viewer']
               && headers['cloudfront-is-smarttv-viewer'][0].value === 'true') {
        request.uri = smarttvPath + request.uri;
    }
    console.log(`Request uri set to "${request.uri}"`);

    callback(null, request);
};
```

------
#### [ Python ]

```
# This is an origin request function
def lambda_handler(event, context):
    request = event['Records'][0]['cf']['request']
    headers = request['headers']

    '''
    Serve different versions of an object based on the device type.
    NOTE: 1. You must configure your distribution to cache based on the
            CloudFront-Is-*-Viewer headers. For more information, see
            the following documentation:
            https://docs.aws.amazon.com/console/cloudfront/cache-on-selected-headers
            https://docs.aws.amazon.com/console/cloudfront/cache-on-device-type
          2. CloudFront adds the CloudFront-Is-*-Viewer headers after the viewer
            request event. To use this example, you must create a trigger for the
            origin request event.
    '''

    desktopPath = '/desktop';
    mobilePath = '/mobile';
    tabletPath = '/tablet';
    smarttvPath = '/smarttv';

    if 'cloudfront-is-desktop-viewer' in headers and headers['cloudfront-is-desktop-viewer'][0]['value'] == 'true':
        request['uri'] = desktopPath + request['uri']
    elif 'cloudfront-is-mobile-viewer' in headers and headers['cloudfront-is-mobile-viewer'][0]['value'] == 'true':
        request['uri'] = mobilePath + request['uri']
    elif 'cloudfront-is-tablet-viewer' in headers and headers['cloudfront-is-tablet-viewer'][0]['value'] == 'true':
        request['uri'] = tabletPath + request['uri']
    elif 'cloudfront-is-smarttv-viewer' in headers and headers['cloudfront-is-smarttv-viewer'][0]['value'] == 'true':
        request['uri'] = smarttvPath + request['uri']

    print("Request uri set to %s" % request['uri'])

    return request
```

------

## Seleção de origem dinâmica baseada em conteúdo: exemplos
<a name="lambda-examples-content-based-routing-examples"></a>

Os exemplos a seguir mostram como você pode usar o Lambda@Edge para rotear para diferentes origens com base em informações na solicitação.

**Topics**
+ [Exemplo: usar um acionador de solicitação de origem para alterar de uma origem personalizada para uma origem do Amazon S3](#lambda-examples-content-based-S3-origin-based-on-query)
+ [Exemplo: usar um acionador de solicitação de origem para alterar a região de origem do Amazon S3](#lambda-examples-content-based-S3-origin-request-trigger)
+ [Exemplo: usar um acionador de solicitação de origem para alterar de uma origem do Amazon S3 para uma origem personalizada](#lambda-examples-content-based-custom-origin-request-trigger)
+ [Exemplo: usar um acionador de solicitação de origem para transferir gradualmente o tráfego de um bucket do Amazon S3 para outro](#lambda-examples-content-based-gradual-traffic-transfer)
+ [Exemplo: usar um acionador de solicitação de origem para alterar o nome do domínio de origem com base no cabeçalho do país](#lambda-examples-content-based-geo-header)

### Exemplo: usar um acionador de solicitação de origem para alterar de uma origem personalizada para uma origem do Amazon S3
<a name="lambda-examples-content-based-S3-origin-based-on-query"></a>

Essa função demonstra como um trigger origin-request pode ser usado para alterar de uma origem personalizada para uma origem do Amazon S3 da qual o conteúdo é obtido, com base nas propriedades da solicitação.

------
#### [ Node.js ]

```
'use strict';

 const querystring = require('querystring');
 
 exports.handler = (event, context, callback) => {
     const request = event.Records[0].cf.request;
 
     /**
      * Reads query string to check if S3 origin should be used, and
      * if true, sets S3 origin properties.
      */
 
     const params = querystring.parse(request.querystring);
 
     if (params['useS3Origin']) {
         if (params['useS3Origin'] === 'true') {
             const s3DomainName = 'amzn-s3-demo-bucket.s3.amazonaws.com';
 
             /* Set S3 origin fields */
             request.origin = {
                 s3: {
                     domainName: s3DomainName,
                     region: '',
                     authMethod: 'origin-access-identity',
                     path: '',
                     customHeaders: {}
                 }
             };
             request.headers['host'] = [{ key: 'host', value: s3DomainName}];
         }
     }
     
    callback(null, request);
};
```

------
#### [ Python ]

```
from urllib.parse import parse_qs

def lambda_handler(event, context):
    request = event['Records'][0]['cf']['request']
    '''
    Reads query string to check if S3 origin should be used, and
    if true, sets S3 origin properties
    '''
    params = {k: v[0] for k, v in parse_qs(request['querystring']).items()}
    if params.get('useS3Origin') == 'true':
        s3DomainName = 'amzn-s3-demo-bucket.s3.amazonaws.com'

        # Set S3 origin fields
        request['origin'] = {
            's3': {
                'domainName': s3DomainName,
                'region': '',
                'authMethod': 'origin-access-identity',
                'path': '',
                'customHeaders': {}
            }
        }
        request['headers']['host'] = [{'key': 'host', 'value': s3DomainName}]
    return request
```

------

### Exemplo: usar um acionador de solicitação de origem para alterar a região de origem do Amazon S3
<a name="lambda-examples-content-based-S3-origin-request-trigger"></a>

Esta função demonstra como um trigger origin-request pode ser usado para alterar a origem do Amazon S3 da qual o conteúdo é obtido, com base nas propriedades da solicitação.

Neste exemplo, usamos o valor do cabeçalho `CloudFront-Viewer-Country` para atualizar o nome do domínio de bucket do S3 para um bucket em uma região mais próxima do visualizador. Isso pode ser útil de várias maneiras:
+ Reduz as latências quando a região especificada estiver mais próxima do país do visualizador.
+ Fornece soberania de dados, garantindo que os dados sejam oferecidos de uma origem que esteja no mesmo país de onde veio a solicitação.

Para usar esse exemplo, você precisa fazer o seguinte:
+ Configure sua distribuição para armazenar em cache com base no cabeçalho `CloudFront-Viewer-Country`. Para obter mais informações, consulte [Cache baseado em Cabeçalhos de solicitação selecionados](DownloadDistValuesCacheBehavior.md#DownloadDistValuesForwardHeaders). 
+ Crie um gatilho para essa função no evento de solicitação de origem. O CloudFront adiciona o cabeçalho `CloudFront-Viewer-Country` após o evento de solicitação do visualizador. Portanto, para usar este exemplo, você precisa garantir que a função seja executada para uma solicitação de origem.

**nota**  
O código de exemplo a seguir usa a mesma identidade do acesso de origem (OAI) para todos os buckets do S3 que você está usando para sua origem. Para ter mais informações, consulte [Visão geral da identidade do acesso de origem](private-content-restricting-access-to-s3.md#private-content-restricting-access-to-s3-oai).

------
#### [ Node.js ]

```
'use strict';

exports.handler = (event, context, callback) => {
    const request = event.Records[0].cf.request;

    /**
     * This blueprint demonstrates how an origin-request trigger can be used to
     * change the origin from which the content is fetched, based on request properties.
     * In this example, we use the value of the CloudFront-Viewer-Country header
     * to update the S3 bucket domain name to a bucket in a Region that is closer to
     * the viewer.
     * 
     * This can be useful in several ways:
     *      1) Reduces latencies when the Region specified is nearer to the viewer's
     *         country.
     *      2) Provides data sovereignty by making sure that data is served from an
     *         origin that's in the same country that the request came from.
     * 
     * NOTE: 1. You must configure your distribution to cache based on the
     *          CloudFront-Viewer-Country header. For more information, see
     *          https://docs.aws.amazon.com/console/cloudfront/cache-on-selected-headers
     *       2. CloudFront adds the CloudFront-Viewer-Country header after the viewer
     *          request event. To use this example, you must create a trigger for the
     *          origin request event.
     */

    const countryToRegion = {
        'DE': 'eu-central-1',
        'IE': 'eu-west-1',
        'GB': 'eu-west-2',
        'FR': 'eu-west-3',
        'JP': 'ap-northeast-1',
        'IN': 'ap-south-1'
    };

    if (request.headers['cloudfront-viewer-country']) {
        const countryCode = request.headers['cloudfront-viewer-country'][0].value;
        const region = countryToRegion[countryCode];
        
        /**
         * If the viewer's country is not in the list you specify, the request
         * goes to the default S3 bucket you've configured.
         */  
        if (region) {
            /**
             * If you've set up OAI, the bucket policy in the destination bucket
             * should allow the OAI GetObject operation, as configured by default
             * for an S3 origin with OAI. Another requirement with OAI is to provide
             * the Region so it can be used for the SIGV4 signature. Otherwise, the
             * Region is not required.
             */
            request.origin.s3.region = region;
            const domainName = `amzn-s3-demo-bucket-in-${region}.s3.${region}.amazonaws.com`;
            request.origin.s3.domainName = domainName;
            request.headers['host'] = [{ key: 'host', value: domainName }];
        }
    }

    callback(null, request);
};
```

------
#### [ Python ]

```
def lambda_handler(event, context):
    request = event['Records'][0]['cf']['request']

    '''
    This blueprint demonstrates how an origin-request trigger can be used to
    change the origin from which the content is fetched, based on request properties.
    In this example, we use the value of the CloudFront-Viewer-Country header
    to update the S3 bucket domain name to a bucket in a Region that is closer to
    the viewer.
    
    This can be useful in several ways:
        1) Reduces latencies when the Region specified is nearer to the viewer's
            country.
        2) Provides data sovereignty by making sure that data is served from an
            origin that's in the same country that the request came from.
    
    NOTE: 1. You must configure your distribution to cache based on the
            CloudFront-Viewer-Country header. For more information, see
            https://docs.aws.amazon.com/console/cloudfront/cache-on-selected-headers
          2. CloudFront adds the CloudFront-Viewer-Country header after the viewer
            request event. To use this example, you must create a trigger for the
            origin request event.
    '''

    countryToRegion = {
        'DE': 'eu-central-1',
        'IE': 'eu-west-1',
        'GB': 'eu-west-2',
        'FR': 'eu-west-3',
        'JP': 'ap-northeast-1',
        'IN': 'ap-south-1'
    }

    viewerCountry = request['headers'].get('cloudfront-viewer-country')
    if viewerCountry:
        countryCode = viewerCountry[0]['value']
        region = countryToRegion.get(countryCode)

        # If the viewer's country in not in the list you specify, the request
        # goes to the default S3 bucket you've configured
        if region:
            '''
            If you've set up OAI, the bucket policy in the destination bucket
            should allow the OAI GetObject operation, as configured by default
            for an S3 origin with OAI. Another requirement with OAI is to provide
            the Region so it can be used for the SIGV4 signature. Otherwise, the
            Region is not required.
            '''
            request['origin']['s3']['region'] = region
            domainName = 'amzn-s3-demo-bucket-in-{0}.s3.{0}.amazonaws.com'.format(region)
            request['origin']['s3']['domainName'] = domainName
            request['headers']['host'] = [{'key': 'host', 'value': domainName}]

    return request
```

------

### Exemplo: usar um acionador de solicitação de origem para alterar de uma origem do Amazon S3 para uma origem personalizada
<a name="lambda-examples-content-based-custom-origin-request-trigger"></a>

Esta função demonstra como um trigger de origem-solicitação pode ser usado para alterar a origem personalizada de onde o conteúdo é obtido, com base nas propriedades da solicitação.

------
#### [ Node.js ]

```
'use strict';

const querystring = require('querystring');
 
 exports.handler = (event, context, callback) => {
     const request = event.Records[0].cf.request;
 
     /**
      * Reads query string to check if custom origin should be used, and
      * if true, sets custom origin properties.
      */
 
     const params = querystring.parse(request.querystring);
 
     if (params['useCustomOrigin']) {
         if (params['useCustomOrigin'] === 'true') {
 
             /* Set custom origin fields*/
             request.origin = {
                 custom: {
                     domainName: 'www.example.com',
                     port: 443,
                     protocol: 'https',
                     path: '',
                     sslProtocols: ['TLSv1', 'TLSv1.1'],
                     readTimeout: 5,
                     keepaliveTimeout: 5,
                     customHeaders: {}
                 }
             };
             request.headers['host'] = [{ key: 'host', value: 'www.example.com'}];
         }
     }
    callback(null, request);
};
```

------
#### [ Python ]

```
from urllib.parse import parse_qs

def lambda_handler(event, context):
    request = event['Records'][0]['cf']['request']

    # Reads query string to check if custom origin should be used, and
    # if true, sets custom origin properties

    params = {k: v[0] for k, v in parse_qs(request['querystring']).items()}

    if params.get('useCustomOrigin') == 'true':
            # Set custom origin fields
            request['origin'] = {
                'custom': {
                    'domainName': 'www.example.com',
                    'port': 443,
                    'protocol': 'https',
                    'path': '',
                    'sslProtocols': ['TLSv1', 'TLSv1.1'],
                    'readTimeout': 5,
                    'keepaliveTimeout': 5,
                    'customHeaders': {}
                }
            }
            request['headers']['host'] = [{'key': 'host', 'value': 'www.example.com'}]

    return request
```

------

### Exemplo: usar um acionador de solicitação de origem para transferir gradualmente o tráfego de um bucket do Amazon S3 para outro
<a name="lambda-examples-content-based-gradual-traffic-transfer"></a>

Essa função demonstra como transferir o tráfego de um bucket do Amazon S3 para outro de forma gradual e controlada.

------
#### [ Node.js ]

```
'use strict';

    function getRandomInt(min, max) {
        /* Random number is inclusive of min and max*/
        return Math.floor(Math.random() * (max - min + 1)) + min;
 }

exports.handler = (event, context, callback) => {
    const request = event.Records[0].cf.request;
    const BLUE_TRAFFIC_PERCENTAGE = 80;

    /**
      * This Lambda function demonstrates how to gradually transfer traffic from
      * one S3 bucket to another in a controlled way.
      * We define a variable BLUE_TRAFFIC_PERCENTAGE which can take values from
      * 1 to 100. If the generated randomNumber less than or equal to BLUE_TRAFFIC_PERCENTAGE, traffic
      * is re-directed to blue-bucket. If not, the default bucket that we've configured
      * is used.
      */

    const randomNumber = getRandomInt(1, 100);

if (randomNumber <= BLUE_TRAFFIC_PERCENTAGE) {
         const domainName = 'blue-bucket.s3.amazonaws.com';
         request.origin.s3.domainName = domainName;
         request.headers['host'] = [{ key: 'host', value: domainName}];
     }
    callback(null, request);
};
```

------
#### [ Python ]

```
import math
import random

def getRandomInt(min, max):
    # Random number is inclusive of min and max
    return math.floor(random.random() * (max - min + 1)) + min

def lambda_handler(event, context):
    request = event['Records'][0]['cf']['request']
    BLUE_TRAFFIC_PERCENTAGE = 80

    '''
    This Lambda function demonstrates how to gradually transfer traffic from
    one S3 bucket to another in a controlled way.
    We define a variable BLUE_TRAFFIC_PERCENTAGE which can take values from
    1 to 100. If the generated randomNumber less than or equal to BLUE_TRAFFIC_PERCENTAGE, traffic
    is re-directed to blue-bucket. If not, the default bucket that we've configured
    is used.
    '''

    randomNumber = getRandomInt(1, 100)

    if randomNumber <= BLUE_TRAFFIC_PERCENTAGE:
        domainName = 'blue-bucket.s3.amazonaws.com'
        request['origin']['s3']['domainName'] = domainName
        request['headers']['host'] = [{'key': 'host', 'value': domainName}]

    return request
```

------

### Exemplo: usar um acionador de solicitação de origem para alterar o nome do domínio de origem com base no cabeçalho do país
<a name="lambda-examples-content-based-geo-header"></a>

Esta função demonstra como você pode alterar o nome de domínio de origem com base no cabeçalho `CloudFront-Viewer-Country`, de forma que o conteúdo seja fornecido de origem mais próxima do país do visualizador.

A implementação dessa funcionalidade para sua distribuição pode ter vantagens, como as seguintes:
+ Redução das latências quando a região especificada estiver mais próxima do país do visualizador
+ Fornecimento da soberania de dados garantindo que os dados sejam fornecidos de uma origem que esteja no mesmo país de onde veio a solicitação

Observe que, para habilitar essa funcionalidade, você deve configurar sua distribuição para o cache com base no cabeçalho `CloudFront-Viewer-Country`. Para obter mais informações, consulte [Cache baseado em Cabeçalhos de solicitação selecionados](DownloadDistValuesCacheBehavior.md#DownloadDistValuesForwardHeaders).

------
#### [ Node.js ]

```
'use strict';

exports.handler = (event, context, callback) => {
     const request = event.Records[0].cf.request;
     
  if (request.headers['cloudfront-viewer-country']) {
         const countryCode = request.headers['cloudfront-viewer-country'][0].value;
         if (countryCode === 'GB' || countryCode === 'DE' || countryCode === 'IE' ) {
             const domainName = 'eu.example.com';
             request.origin.custom.domainName = domainName;
             request.headers['host'] = [{key: 'host', value: domainName}];
         } 
     }
     
    callback(null, request);
};
```

------
#### [ Python ]

```
def lambda_handler(event, context):
    request = event['Records'][0]['cf']['request']

    viewerCountry = request['headers'].get('cloudfront-viewer-country')
    if viewerCountry:
        countryCode = viewerCountry[0]['value']
        if countryCode == 'GB' or countryCode == 'DE' or countryCode == 'IE':
            domainName = 'eu.example.com'
            request['origin']['custom']['domainName'] = domainName
            request['headers']['host'] = [{'key': 'host', 'value': domainName}]
    return request
```

------

## Atualização do status de erro: exemplos
<a name="lambda-examples-update-error-status-examples"></a>

Os exemplos a seguir fornecem orientações sobre como você pode usar o Lambda@Edge para alterar o status de erro retornado para os usuários.

**Topics**
+ [Exemplo: usar um acionador de resposta de origem para atualizar o código do status de erro para 200](#lambda-examples-custom-error-static-body)
+ [Exemplo: usar um acionador de resposta de origem para atualizar o código do status de erro para 302](#lambda-examples-custom-error-new-site)

### Exemplo: usar um acionador de resposta de origem para atualizar o código do status de erro para 200
<a name="lambda-examples-custom-error-static-body"></a>

Esta função demonstra como você pode atualizar o status da resposta para 200 e gerar conteúdo do corpo estático para retornar ao visualizador no cenário a seguir:
+ A função é acionada em uma resposta da origem.
+ O status da resposta do servidor de origem é um código de status de erro (4xx ou 5xx).

------
#### [ Node.js ]

```
'use strict';

exports.handler = (event, context, callback) => {
    const response = event.Records[0].cf.response;

    /**
     * This function updates the response status to 200 and generates static
     * body content to return to the viewer in the following scenario:
     * 1. The function is triggered in an origin response
     * 2. The response status from the origin server is an error status code (4xx or 5xx)
     */

    if (response.status >= 400 && response.status <= 599) {
        response.status = 200;
        response.statusDescription = 'OK';
        response.body = 'Body generation example';
    }

    callback(null, response);
};
```

------
#### [ Python ]

```
def lambda_handler(event, context):
    response = event['Records'][0]['cf']['response']

    '''
    This function updates the response status to 200 and generates static
    body content to return to the viewer in the following scenario:
    1. The function is triggered in an origin response
    2. The response status from the origin server is an error status code (4xx or 5xx)
    '''

    if int(response['status']) >= 400 and int(response['status']) <= 599:
        response['status'] = 200
        response['statusDescription'] = 'OK'
        response['body'] = 'Body generation example'
    return response
```

------

### Exemplo: usar um acionador de resposta de origem para atualizar o código do status de erro para 302
<a name="lambda-examples-custom-error-new-site"></a>

Essa função demonstra como você pode atualizar o código de status HTTP para 302, de forma a redirecionar a outro caminho (comportamento de cache) que tem uma origem diferente configurada. Observe o seguinte:
+ A função é acionada em uma resposta da origem.
+ O status da resposta do servidor de origem é um código de status de erro (4xx ou 5xx).

------
#### [ Node.js ]

```
'use strict';

exports.handler = (event, context, callback) => {
    const response = event.Records[0].cf.response;
    const request = event.Records[0].cf.request;

    /**
     * This function updates the HTTP status code in the response to 302, to redirect to another
     * path (cache behavior) that has a different origin configured. Note the following:
     * 1. The function is triggered in an origin response
     * 2. The response status from the origin server is an error status code (4xx or 5xx)
     */

    if (response.status >= 400 && response.status <= 599) {
        const redirect_path = `/plan-b/path?${request.querystring}`;

        response.status = 302;
        response.statusDescription = 'Found';

        /* Drop the body, as it is not required for redirects */
        response.body = '';
        response.headers['location'] = [{ key: 'Location', value: redirect_path }];
    }

    callback(null, response);
};
```

------
#### [ Python ]

```
def lambda_handler(event, context):
    response = event['Records'][0]['cf']['response']
    request = event['Records'][0]['cf']['request']

    '''
    This function updates the HTTP status code in the response to 302, to redirect to another
    path (cache behavior) that has a different origin configured. Note the following:
    1. The function is triggered in an origin response
    2. The response status from the origin server is an error status code (4xx or 5xx)
    '''

    if int(response['status']) >= 400 and int(response['status']) <= 599:
        redirect_path = '/plan-b/path?%s' % request['querystring']

        response['status'] = 302
        response['statusDescription'] = 'Found'

        # Drop the body as it is not required for redirects
        response['body'] = ''
        response['headers']['location'] = [{'key': 'Location', 'value': redirect_path}]

    return response
```

------

## Acesso ao corpo da solicitação: exemplos
<a name="lambda-examples-access-request-body-examples"></a>

Os exemplos a seguir mostram como você pode usar o Lambda@Edge para trabalhar com solicitações POST.

**nota**  
Para usar esses exemplos, você deve habilitar a opção *include body* (incluir corpo) na associação da função do Lambda da distribuição. Ele não é habilitado por padrão.  
Para habilitar essa configuração no console do CloudFront, marque a caixa de seleção **Include Body (Incluir corpo)** na **Lambda Function Association (Associação de função do Lambda)**.
Para habilitar essa configuração na API do CloudFront ou com o CloudFormation, defina o campo `IncludeBody` como `true` em `LambdaFunctionAssociation`.

**Topics**
+ [Exemplo: usar um acionador de solicitação para ler um formulário HTML](#lambda-examples-access-request-body-examples-read)
+ [Exemplo: usar um acionador de solicitação para modificar um formulário HTML](#lambda-examples-access-request-body-examples-replace)

### Exemplo: usar um acionador de solicitação para ler um formulário HTML
<a name="lambda-examples-access-request-body-examples-read"></a>

Essa função demonstra como você pode processar o corpo de uma solicitação POST gerada por um formulário HTML (formulário da web), como um formulário "entre em contato conosco". Por exemplo, você pode ter um formulário em HTML como o seguinte:

```
<html>
  <form action="https://example.com" method="post">
    Param 1: <input type="text" name="name1"><br>
    Param 2: <input type="text" name="name2"><br>
    input type="submit" value="Submit">
  </form>
</html>
```

No exemplo a seguir, a função deve ser acionada em uma solicitação de origem ou de um visualizador do CloudFront.

------
#### [ Node.js ]

```
'use strict';

const querystring = require('querystring');

/**
 * This function demonstrates how you can read the body of a POST request 
 * generated by an HTML form (web form). The function is triggered in a
 * CloudFront viewer request or origin request event type.
 */

exports.handler = (event, context, callback) => {
    const request = event.Records[0].cf.request;

    if (request.method === 'POST') {
        /* HTTP body is always passed as base64-encoded string. Decode it. */
        const body = Buffer.from(request.body.data, 'base64').toString();
 
        /* HTML forms send the data in query string format. Parse it. */
        const params = querystring.parse(body);
 
        /* For demonstration purposes, we only log the form fields here.
         * You can put your custom logic here. For example, you can store the 
         * fields in a database, such as Amazon DynamoDB, and generate a response
         * right from your Lambda@Edge function.
         */
        for (let param in params) {
            console.log(`For "${param}" user submitted "${params[param]}".\n`);
        }
    }
    return callback(null, request);
};
```

------
#### [ Python ]

```
import base64
from urllib.parse import parse_qs

'''
Say there is a POST request body generated by an HTML such as:

<html>
<form action="https://example.com" method="post">
    Param 1: <input type="text" name="name1"><br>
    Param 2: <input type="text" name="name2"><br>
    input type="submit" value="Submit">
</form>
</html>

'''

'''
This function demonstrates how you can read the body of a POST request 
generated by an HTML form (web form). The function is triggered in a
CloudFront viewer request or origin request event type.
'''

def lambda_handler(event, context):
    request = event['Records'][0]['cf']['request']

    if request['method'] == 'POST':
        # HTTP body is always passed as base64-encoded string. Decode it
        body = base64.b64decode(request['body']['data'])

        # HTML forms send the data in query string format. Parse it
        params = {k: v[0] for k, v in parse_qs(body).items()}

        '''
        For demonstration purposes, we only log the form fields here.
        You can put your custom logic here. For example, you can store the
        fields in a database, such as Amazon DynamoDB, and generate a response
        right from your Lambda@Edge function.
        '''
        for key, value in params.items():
            print("For %s use submitted %s" % (key, value))
            
    return request
```

------

### Exemplo: usar um acionador de solicitação para modificar um formulário HTML
<a name="lambda-examples-access-request-body-examples-replace"></a>

Essa função demonstra como você pode modificar o corpo de uma solicitação POST gerada por um formulário HTML (formulário da web). A função é acionada em uma solicitação de origem ou de visualizador do CloudFront.

------
#### [ Node.js ]

```
'use strict';
				
const querystring = require('querystring');

exports.handler = (event, context, callback) => {
    var request = event.Records[0].cf.request;
    if (request.method === 'POST') {
        /* Request body is being replaced. To do this, update the following
        /* three fields:
         *    1) body.action to 'replace'
         *    2) body.encoding to the encoding of the new data.
         *
         *       Set to one of the following values:
         *
         *           text - denotes that the generated body is in text format.
         *               Lambda@Edge will propagate this as is.
         *           base64 - denotes that the generated body is base64 encoded.
         *               Lambda@Edge will base64 decode the data before sending
         *               it to the origin.
         *    3) body.data to the new body.
         */
        request.body.action = 'replace';
        request.body.encoding = 'text';
        request.body.data = getUpdatedBody(request);
    }
    callback(null, request);
};

function getUpdatedBody(request) {
    /* HTTP body is always passed as base64-encoded string. Decode it. */
    const body = Buffer.from(request.body.data, 'base64').toString();

    /* HTML forms send data in query string format. Parse it. */
    const params = querystring.parse(body);

    /* For demonstration purposes, we're adding one more param.
     *
     * You can put your custom logic here. For example, you can truncate long
     * bodies from malicious requests.
     */
    params['new-param-name'] = 'new-param-value';
    return querystring.stringify(params);
}
```

------
#### [ Python ]

```
import base64
from urllib.parse import parse_qs, urlencode

def lambda_handler(event, context):
    request = event['Records'][0]['cf']['request']
    if request['method'] == 'POST':
        '''
        Request body is being replaced. To do this, update the following
        three fields:
            1) body.action to 'replace'
            2) body.encoding to the encoding of the new data.
        
            Set to one of the following values:
        
                text - denotes that the generated body is in text format.
                    Lambda@Edge will propagate this as is.
                base64 - denotes that the generated body is base64 encoded.
                    Lambda@Edge will base64 decode the data before sending
                    it to the origin.
            3) body.data to the new body.
        '''
        request['body']['action'] = 'replace'
        request['body']['encoding'] = 'text'
        request['body']['data'] = getUpdatedBody(request)
    return request

def getUpdatedBody(request):
    # HTTP body is always passed as base64-encoded string. Decode it
    body = base64.b64decode(request['body']['data'])

    # HTML forms send data in query string format. Parse it
    params = {k: v[0] for k, v in parse_qs(body).items()}

    # For demonstration purposes, we're adding one more param

    # You can put your custom logic here. For example, you can truncate long
    # bodies from malicious requests
    params['new-param-name'] = 'new-param-value'
    return urlencode(params)
```

------