

# Personalización en la periferia con funciones
<a name="edge-functions"></a>

Con Amazon CloudFront, puede escribir su propio código para personalizar la forma en que sus distribuciones de CloudFront procesan las solicitudes y respuestas HTTP. El código se ejecuta cerca de los lectores (usuarios) para minimizar la latencia y no es necesario administrar servidores u otra infraestructura. Puede escribir código para manipular las solicitudes y respuestas que atraviesan CloudFront, realizar autenticación y autorización básicas, generar respuestas HTTP en el borde y mucho más.

El código que escribe y asocia a su distribución de CloudFront se denomina *función de borde*. CloudFront ofrece dos formas de escribir y administrar funciones de borde:

**CloudFront Functions**  
Puede escribir funciones ligeras en JavaScript para personalizaciones de CDN sensibles a la latencia a gran escala. El entorno de tiempo de ejecución de CloudFront Functions ofrece tiempos de arranque de submilisegundos, se escala inmediatamente para gestionar millones de solicitudes por segundo y es altamente seguro. CloudFront Functions es una característica nativa de CloudFront, lo que significa que puede compilar, probar e implementar su código completamente dentro de CloudFront.

**Lambda@Edge**  
Lambda@Edge: es una extensión de [AWS Lambda](https://aws.amazon.com/lambda/) que ofrece computación potente y flexible para funciones complejas y lógica completa de aplicaciones más cerca de sus lectores y es altamente segura. Las funciones de Lambda@Edge se ejecutan en un entorno de tiempo de ejecución Node.js o Python. Usted publica las funciones en una sola Región de AWS y, cuando asocia la función a una distribución de CloudFront, Lambda@Edge replica el código en todo el mundo de forma automática.

Si ejecuta AWS WAF en CloudFront, puede usar encabezados AWS WAF incrustados para CloudFront Functions y Lambda @Edge. Esto funciona para solicitudes y respuestas de lectores y de origen.

**Topics**
+ [

# Diferencias entre CloudFront Functions y Lambda@Edge
](edge-functions-choosing.md)
+ [

# Personalización en la periferia con CloudFront Functions
](cloudfront-functions.md)
+ [

# Personalización con funciones de conexión de CloudFront
](customize-connections-validation-with-connection-functions.md)
+ [

# Personalización en la periferia con Lambda@Edge
](lambda-at-the-edge.md)
+ [

# Restricciones en funciones de borde
](edge-functions-restrictions.md)

# Diferencias entre CloudFront Functions y Lambda@Edge
<a name="edge-functions-choosing"></a>

CloudFront Functions y Lambda@Edge proporcionan una forma de ejecutar código en respuesta a eventos de CloudFront. 

CloudFront Functions es ideal para funciones ligeras y de corta duración para los siguientes casos de uso:
+ **Normalización de la clave de caché**: transforme los atributos de la solicitud HTTP (encabezados, cadenas de consulta, cookies o hasta la ruta de la URL) para crear una [clave de caché](understanding-the-cache-key.md) óptima, lo que puede mejorar la tasa de aciertos de la caché.
+ **Manipulación de encabezados**: inserte, modifique o elimine encabezados HTTP en la solicitud o la respuesta. Por ejemplo, puede agregar un encabezado `True-Client-IP` a cada solicitud.
+ **Redireccionamientos o reescrituras de URL**: redirija a los lectores a otras páginas en función de la información de la solicitud o puede redirigir todas las solicitudes de una ruta a otra.
+ **Autorización de solicitudes**: valide los tokens de autorización con hash, como los tokens web JSON (JWT) mediante la inspección de los encabezados de autorización u otros metadatos de solicitud.

Para empezar a utilizar CloudFront Functions, consulte [Personalización en la periferia con CloudFront Functions](cloudfront-functions.md).

Lambda@Edge es ideal para los siguientes casos de uso:
+ Funciones que tardan varios milisegundos o más en completarse
+ Funciones que requieren CPU o memoria ajustable
+ Funciones que dependen de bibliotecas de terceros (incluido el SDK de AWS, para la integración con otros Servicios de AWS)
+ Funciones que requieren acceso a la red para utilizar servicios externos para el procesamiento
+ Funciones que requieren acceso al sistema de archivos o acceso al cuerpo de las solicitudes HTTP

Para comenzar con Lambda@Edge, consulte [Personalización en la periferia con Lambda@Edge](lambda-at-the-edge.md).

Para ayudarle a elegir la opción para su caso de uso, utilice la siguiente tabla con el fin de entender las diferencias entre CloudFront Functions y Lambda@Edge. Para obtener información sobre las diferencias que se aplican a los métodos auxiliares para la modificación del origen, consulte [Elección entre CloudFront Functions y Lambda@Edge](helper-functions-origin-modification.md#origin-modification-considerations).


|  | CloudFront Functions | Lambda@Edge | 
| --- | --- | --- | 
| Lenguajes de programación | JavaScript (compatible con ECMAScript 5.1) | Node.js y Python | 
| Orígenes de eventos |  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/es_es/AmazonCloudFront/latest/DeveloperGuide/edge-functions-choosing.html)  |  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/es_es/AmazonCloudFront/latest/DeveloperGuide/edge-functions-choosing.html)  | 
|  Admite [Amazon CloudFront KeyValueStore](kvs-with-functions.md)  |  Sí CloudFront KeyValueStore solo admite [JavaScript runtime 2.0](functions-javascript-runtime-20.md)  |  No  | 
| Escalado | Hasta millones de solicitudes por segundo | Hasta 10 000 solicitudes por segundo por región | 
| Duración de función | Submilisegundo |  Hasta 30 segundos (solicitud del lector y respuesta del lector) Hasta 30 segundos (solicitud de origen y respuesta de origen)  | 
|  Tamaño de memoria de función máxima  | 2 MB |  128 MB (solicitud del lector y respuesta del lector) 10 240 MB (10 GB) (solicitud de origen y respuesta de origen) Para obtener más información, consulte [Cuotas de Lambda@Edge](cloudfront-limits.md#limits-lambda-at-edge).  | 
| Tamaño máximo del código de función y bibliotecas incluidas | 10 KB |  50 MB (solicitud del espectador y respuesta del espectador) 50 MB (solicitud de origen y respuesta de origen)  | 
| Acceso a la red | No | Sí | 
| Acceso al sistema de archivos | No | Sí | 
| Acceso al cuerpo de solicitud | No | Sí | 
| Acceso a datos de geolocalización y dispositivos | Sí |  No (solicitud del lector y respuesta del lector) Sí (solicitud de origen y respuesta de origen)  | 
| Se puede compilar y probar completamente dentro de CloudFront | Sí | No | 
| Registro y métricas de funciones | Sí | Sí | 

# Personalización en la periferia con CloudFront Functions
<a name="cloudfront-functions"></a>

Con CloudFront Functions, puede escribir funciones ligeras en JavaScript para personalizaciones de CDN sensibles a la latencia a gran escala. Sus funciones pueden manipular las solicitudes y respuestas que atraviesan CloudFront, realizar autenticaciones y autorizaciones básicas, generar respuestas HTTP en el borde y mucho más. El entorno de tiempo de ejecución de CloudFront Functions ofrece tiempos de arranque de submilisegundos, se escala inmediatamente para gestionar millones de solicitudes por segundo y es altamente seguro. CloudFront Functions es una característica nativa de CloudFront, lo que significa que puede compilar, probar e implementar su código completamente dentro de CloudFront.

Cuando asocia una distribución de CloudFront con una función de CloudFront, CloudFront intercepta solicitudes y respuestas en ubicaciones de borde de CloudFront y ejecuta la función. Puede invocar CloudFront Functions cuando se producen los siguientes eventos:
+ Cuando CloudFront reciba una solicitud de un espectador (solicitud del espectador)
+ Antes de que CloudFront devuelva la respuesta al espectador (respuesta al espectador)
+ Durante el establecimiento de la conexión de TLS (solicitud de conexión): actualmente disponible para conexiones de TLS mutuas (mTLS)

Para obtener más información sobre CloudFront Functions, consulte los siguientes temas:

**Topics**
+ [

# Tutorial: creación de una función simple con CloudFront Functions
](functions-tutorial.md)
+ [

# Tutorial: creación de una función de CloudFront que incluya pares clave-valor
](functions-tutorial-kvs.md)
+ [

# Escritura de código de función
](writing-function-code.md)
+ [

# Creación de funciones
](create-function.md)
+ [

# Prueba de funciones
](test-function.md)
+ [

# Actualización de funciones
](update-function.md)
+ [

# Publicación de funciones
](publish-function.md)
+ [

# Asociación de funciones con distribuciones
](associate-function.md)
+ [

# Amazon CloudFront KeyValueStore
](kvs-with-functions.md)

# Tutorial: creación de una función simple con CloudFront Functions
<a name="functions-tutorial"></a>

En este tutorial se muestra cómo familiarizarse con CloudFront Functions. Puede crear una función simple que redirige el lector a una URL diferente y también devuelve un encabezado de respuesta personalizado.

**Contents**
+ [

## Requisitos previos
](#functions-tutorial-prerequisites)
+ [

## Creación de la función
](#functions-tutorial-create)
+ [

## Verificación de la función
](#functions-tutorial-verify)

## Requisitos previos
<a name="functions-tutorial-prerequisites"></a>

Para utilizar CloudFront Functions, necesita una distribución de CloudFront. Si no dispone de una, consulte [Introducción a una distribución estándar de CloudFront](GettingStarted.SimpleDistribution.md).

## Creación de la función
<a name="functions-tutorial-create"></a>

Puede utilizar la consola de CloudFront para crear una función simple que redirige el lector a una URL diferente y también devuelve un encabezado de respuesta personalizado. 

**Creación de una función de CloudFront**

1. Inicie sesión en la Consola de administración de AWS y abra la consola de CloudFront en [https://console.aws.amazon.com/cloudfront/v4/home](https://console.aws.amazon.com/cloudfront/v4/home).

1. En el panel de navegación, seleccione **Funciones** y, a continuación, **Crear una función**. 

1. En la página **Crear función**, en **Nombre**, introduzca un nombre de función como *MyFunctionName*.

1. (Opcional) En **Descripción**, escriba una descripción de la función, como **Simple test function**.

1. Para **Tiempo de ejecución**, mantenga la versión de JavaScript seleccionada de forma predeterminada.

1. Seleccione **Creación de función**.

1. Copie el siguiente código de función. Este código de función redirige al lector a una URL diferente y también devuelve un encabezado de respuesta personalizado.

   ```
   function handler(event) {
       // NOTE: This example function is for a viewer request event trigger. 
       // Choose viewer request for event trigger when you associate this function with a distribution. 
       var response = {
           statusCode: 302,
           statusDescription: 'Found',
           headers: {
               'cloudfront-functions': { value: 'generated-by-CloudFront-Functions' },
               'location': { value: 'https://aws.amazon.com/cloudfront/' }
           }
       };
       return response;
   }
   ```

1. En **Código de función**, pegue el código en el editor de código para reemplazar el código predeterminado.

1. Seleccione **Save changes (Guardar cambios)**.

1. (Opcional) Puede probar la función antes de publicarla. En este tutorial no se describe cómo probar una función. Para obtener más información, consulte [Prueba de funciones](test-function.md).

1. Elija la pestaña **Publicar** y, a continuación, la **función Publicar**. *Debe* publicar la función para poder asociarla a la distribución de CloudFront.

1. A continuación, puede asociar la función a un comportamiento de distribución o caché. En la página *MyFunctionName*, elija la pestaña **Publicar**. 
**aviso**  
En los pasos siguientes, seleccione un comportamiento de distribución o caché que se use para las pruebas. No asocie esta función de prueba a un comportamiento de distribución o caché que se use en producción.

1. Elija **Add association**. 

1. En el cuadro de diálogo **Asociar**, elija un comportamiento de distribución o caché. En **Tipo de evento**, mantenga el valor predeterminado.

1. Elija **Add association**.

   También verá la distribución asociada en la tabla **Distribuciones asociadas**. 

1. Espere unos minutos para que la distribución asociada termine de implementarse. Para comprobar el estado de la distribución, selecciónela en la tabla **Distribuciones asociadas** y elija **Ver distribución**.

   Cuando el estado de la distribución es **Implementada**, está lista para verificar el funcionamiento de la función.

## Verificación de la función
<a name="functions-tutorial-verify"></a>

Tras implementar la función, puede comprobar que funciona para su distribución.

**Verificación de la función**

1. En el navegador web, vaya al nombre de dominio de la distribución (por ejemplo, `https://d111111abcdef8.cloudfront.net`).

   La función devuelve un redireccionamiento al navegador, por lo que el navegador se dirige automáticamente a `https://aws.amazon.com/cloudfront/`.

1. En una ventana de línea de comandos, puede usar una herramienta como **curl** para enviar una solicitud al nombre de dominio de su distribución.

   ```
   curl -v https://d111111abcdef8.cloudfront.net/
   ```

   En la respuesta, verá la respuesta de redireccionamiento (`302 Found`) y los encabezados de respuesta personalizados que agregó la función. La respuesta podría tener un aspecto similar al siguiente.  
**Example**  

   ```
   curl -v https://d111111abcdef8.cloudfront.net/
   > GET / HTTP/1.1
   > Host: d111111abcdef8.cloudfront.net
   > User-Agent: curl/7.64.1
   > Accept: */*
   >
   < HTTP/1.1 302 Found
   < Server: CloudFront
   < Date: Tue, 16 Mar 2021 18:50:48 GMT
   < Content-Length: 0
   < Connection: keep-alive
   < Location: https://aws.amazon.com/cloudfront/
   < Cloudfront-Functions: generated-by-CloudFront-Functions
   < X-Cache: FunctionGeneratedResponse from cloudfront
   < Via: 1.1 3035b31bddaf14eded329f8d22cf188c.cloudfront.net (CloudFront)
   < X-Amz-Cf-Pop: PHX50-C2
   < X-Amz-Cf-Id: ULZdIz6j43uGBlXyob_JctF9x7CCbwpNniiMlmNbmwzH1YWP9FsEHg==
   ```

# Tutorial: creación de una función de CloudFront que incluya pares clave-valor
<a name="functions-tutorial-kvs"></a>

En este tutorial, se muestra cómo incluir pares clave-valor con una función de CloudFront. Los valores y las claves forman parte de un par clave-valor. Debe incluir el nombre (del par clave-valor) en el código de la función. Cuando se ejecute la función, CloudFront reemplaza el nombre por el valor. 

Los pares clave-valor son variables que se almacenan en un almacén de clave-valor. Cuando se utiliza una clave en la función (en lugar de valores con codificación rígida), la función es más flexible. Puede cambiar el valor de la clave sin tener que implementar cambios en el código. Los pares clave-valor también pueden reducir el tamaño de la función. Para obtener más información, consulte [Amazon CloudFront KeyValueStore](kvs-with-functions.md).

**Contents**
+ [

## Requisitos previos
](#functions-kvs-tutorial-prerequisites)
+ [

## Creación del almacén de clave-valor
](#functions-kvs-tutorial-kvs-step)
+ [

## Añadido de pares clave-valor al almacén
](#add-key-value-pairs-to-store)
+ [

## Asociación del almacén de clave-valor a la función
](#functions-kvs-tutorial-functions-step)
+ [

## Prueba y publicación del código de la función
](#test-and-publish-function-code)

## Requisitos previos
<a name="functions-kvs-tutorial-prerequisites"></a>

Si no conoce las funciones de CloudFront Functions ni el almacén de clave-valor, le recomendamos que siga el tutorial que aparece en [Tutorial: creación de una función simple con CloudFront Functions](functions-tutorial.md).

Después de completar ese tutorial, puede seguir este tutorial para ampliar la función que ha creado. En este tutorial, le recomendamos que primero cree el almacén de clave-valor. 

## Creación del almacén de clave-valor
<a name="functions-kvs-tutorial-kvs-step"></a>

En primer lugar, cree el almacén de clave-valor para usarlo en su función.

**Creación del almacén clave-valor**

1. Planifique los pares clave-valor que desee incluir en la función. Anote los nombres de las claves. Los pares clave-valor que desee utilizar en una función deben estar en un único almacén de clave-valor. 

1. Decida el orden de trabajo. Hay dos formas de proceder:
   + Cree un almacén de clave-valor y añada pares clave-valor al almacén. A continuación, cree (o modifique) la función e incorpore los nombres de las claves.
   + O bien, puede crear (o modificar) la función e incorporar los nombres de las claves que quiera usar. A continuación, cree un almacén de clave-valor y añada los pares clave-valor.

1. Inicie sesión en la Consola de administración de AWS y abra la consola de CloudFront en [https://console.aws.amazon.com/cloudfront/v4/home](https://console.aws.amazon.com/cloudfront/v4/home).

1. En el panel de navegación, elija **Funciones** y, a continuación, elija la pestaña **KeyValueStores.**

1. Elija **Crear KeyValueStore** e introduzca los siguientes campos:
   + Introduzca un nombre y una descripción (opcional) para el almacén. 
   + Deje el **URI de S3** en blanco. En este tutorial, introducirá los pares clave-valor de forma manual. 

1. Seleccione **Crear**. Aparece la página de detalles del nuevo almacén de clave-valor. Esta página incluye una sección de **pares clave-valor** que actualmente está vacía.

## Añadido de pares clave-valor al almacén
<a name="add-key-value-pairs-to-store"></a>

A continuación, añada manualmente una lista de pares clave-valor al almacén de clave-valor que creó anteriormente.

**Añadido de pares clave-valor al almacén de clave-valor**

1. En la sección de **Pares clave-valor**, seleccione el botón **Agregar pares clave-valor**. 

1. Elija **Agregar etiqueta** y, a continuación, introduzca un par clave-valor. Elija la marca de verificación para confirmar los cambios y repita este paso para añadir más.

1. Cuando haya terminado, seleccione **Guardar cambios** para guardar todos los pares del almacén de clave-valor. En el cuadro de diálogo de confirmación, elija **Listo**.

Ahora tiene un almacén que contiene un grupo de pares clave-valor. 



## Asociación del almacén de clave-valor a la función
<a name="functions-kvs-tutorial-functions-step"></a>

Ahora ha creado el almacén de clave-valor. Y ha creado o modificado una función que incluye los nombres de las claves del almacén de clave-valor. Ahora puede asociar el almacén de clave-valor y la función. La asociación se crea desde dentro de la función. 

**Asociación del almacén de clave-valor a la función**

1. Seleccione **Funciones** en el panel de navegación. La pestaña **Funciones** aparece en la parte superior de forma predeterminada. 

1. Elija el nombre de la función y, en la sección **KeyValueStore asociado**, elija **Asociar KeyValueStore existente**.

1. Seleccione el almacén de clave-valor y elija **Asociar KeyValueStore**. 

**nota**  
Solo puede asociar un almacén de clave-valor a cada función.

## Prueba y publicación del código de la función
<a name="test-and-publish-function-code"></a>

Tras asociar el almacén de clave-valor a la función, puede probar y publicar el código de la función. Siempre debe probar el código de la función cada vez que lo modifique, incluso cuando haga lo siguiente:
+ Asociar un almacén de clave-valor a la función.
+ Modificar la función y su almacén de clave-valor para incluir un nuevo par de clave-valor.
+ Cambiar el valor de un par clave-valor.

**Prueba y publicación del código de la función**

1. Para obtener más información sobre cómo probar una función, consulte [Prueba de funciones](test-function.md). Asegúrese de elegir probar la función en la etapa de `DEVELOPMENT`.

1. Publique la función cuando esté preparado para utilizarla (con los pares clave-valor nuevos o revisados) en un entorno `LIVE`. 

   Al publicar, CloudFront copia la versión de la función de la etapa de `DEVELOPMENT` a la etapa de producción en vivo. La función tiene el código nuevo y está asociada al almacén de clave-valor. (No es necesario volver a realizar la asociación en la etapa de producción en vivo).

   Para obtener más información sobre cómo publicar la función, consulte [Publicación de funciones](publish-function.md). 

# Escritura de código de función
<a name="writing-function-code"></a>

Puede utilizar CloudFront Functions para escribir funciones ligeras en JavaScript para personalizaciones de CDN sensibles a la latencia a gran escala. Su código de función puede manipular las solicitudes y respuestas que atraviesan CloudFront, realizar autenticaciones y autorizaciones básicas, generar respuestas HTTP en el borde y mucho más.

Como ayuda para escribir código de función de CloudFront Functions, consulte los siguientes temas. Para ver ejemplos de código, consulte [Ejemplos de CloudFront Functions para CloudFront](service_code_examples_cloudfront_functions_examples.md) y el [repositorio amazon-cloudfront-functions](https://github.com/aws-samples/amazon-cloudfront-functions) en GitHub.

**Topics**
+ [

# Determinación del propósito de la función
](function-code-choose-purpose.md)
+ [Estructura de evento](functions-event-structure.md)
+ [Características del tiempo de ejecución de JavaScript](functions-javascript-runtime-features.md)
+ [

# Métodos auxiliares para almacenes de clave-valor
](functions-custom-methods.md)
+ [

# Métodos auxiliares para la modificación del origen
](helper-functions-origin-modification.md)
+ [

# Métodos auxiliares para las propiedades de CloudFront SaaS Manager
](saas-specific-logic-function-code.md)
+ [

# Utilice async y await
](async-await-syntax.md)
+ [

# Compatibilidad con CWT para CloudFront Functions
](cwt-support-cloudfront-functions.md)
+ [

# Métodos de ayuda generales
](general-helper-methods.md)

# Determinación del propósito de la función
<a name="function-code-choose-purpose"></a>

Antes de escribir el código de su función, determine su propósito. La mayoría de las funciones de CloudFront Functions cumplen uno de los siguientes propósitos.

**Topics**
+ [

## Modificar la solicitud HTTP en un tipo de evento de solicitud de lector
](#function-code-modify-request)
+ [

## Generar una respuesta HTTP en un tipo de evento de solicitud de lector
](#function-code-generate-response)
+ [

## Modificar la respuesta HTTP en un tipo de evento de respuesta de lector
](#function-code-modify-response)
+ [

## Validación de las conexiones de mTLS en un tipo de evento de solicitud de conexión
](#function-code-connection-request)
+ [

## Información relacionada
](#related-information-cloudfront-functions-purpose)

Independientemente del propósito de la función, el `handler` es el punto de entrada para cualquier función. Toma un solo argumento llamado `event`, que se pasa a la función mediante CloudFront. El `event` es un objeto JSON que contiene una representación de la solicitud HTTP (y la respuesta, si su función modifica la respuesta HTTP). 

## Modificar la solicitud HTTP en un tipo de evento de solicitud de lector
<a name="function-code-modify-request"></a>

Su función puede modificar la solicitud HTTP que CloudFront recibe del lector (cliente) y devolver la solicitud modificada a CloudFront para su procesamiento continuo. Por ejemplo, el código de función podría normalizar la [clave de caché](understanding-the-cache-key.md) o modificar los encabezados de solicitud.

Cuando crea y publica una función que modifica la solicitud HTTP, asegúrese de agregar una asociación para el tipo de evento *solicitud del lector*. Para obtener más información, consulte [Creación de la función](functions-tutorial.md#functions-tutorial-create). Esto hace que la función se ejecute cada vez que CloudFront recibe una solicitud de un lector, antes de comprobar si el objeto solicitado está en la caché de CloudFront.

**Example Ejemplo**  
El siguiente pseudocódigo muestra la estructura de una función que modifica la solicitud HTTP.  

```
function handler(event) {
    var request = event.request;

    // Modify the request object here.

    return request;
}
```
La función devuelve el objeto modificado `request` a CloudFront. CloudFront continúa procesando la solicitud devuelta comprobando la caché de CloudFront en busca de un acierto de caché y enviando la solicitud al origen si es necesario.

## Generar una respuesta HTTP en un tipo de evento de solicitud de lector
<a name="function-code-generate-response"></a>

Su función puede generar una respuesta HTTP en el borde y devolverla directamente al lector (cliente) sin buscar una respuesta almacenada en la caché o cualquier otro procesamiento por parte de CloudFront. Por ejemplo, el código de función podría redirigir la solicitud a una nueva URL, o comprobar la autorización y devolver una respuesta `401` o `403` a solicitudes no autorizadas.

Cuando crea una función que genera una respuesta HTTP, asegúrese de elegir el tipo de evento *viewer request (solicitud del lector)*. Esto significa que la función se ejecuta cada vez que CloudFront recibe una solicitud de un lector, antes de que CloudFront siga procesando la solicitud.

**Example Ejemplo**  
El siguiente pseudocódigo muestra la estructura de una función que genera una respuesta HTTP.  

```
function handler(event) {
    var request = event.request;

    var response = ...; // Create the response object here,
                        // using the request properties if needed.

    return response;
}
```
La función devuelve un objeto `response` a CloudFront, que CloudFront devuelve inmediatamente al lector sin comprobar la caché de CloudFront ni enviar una solicitud al origen.

## Modificar la respuesta HTTP en un tipo de evento de respuesta de lector
<a name="function-code-modify-response"></a>

Su función puede modificar la respuesta HTTP antes de que CloudFront la envíe al lector (cliente), independientemente de si la respuesta proviene de la caché de CloudFront o del origen. Por ejemplo, es posible que el código de función agregue o modifique encabezados de respuesta, códigos de estado y contenido del cuerpo.

Cuando crea una función que modifica la respuesta HTTP, asegúrese de elegir el tipo de evento *viewer response (respuesta al lector)*. Esto significa que la función se ejecuta antes de que CloudFront devuelva una respuesta al lector, independientemente de si la respuesta proviene de la caché de CloudFront o del origen.

**Example Ejemplo**  
El siguiente pseudocódigo muestra la estructura de una función que modifica la respuesta HTTP.  

```
function handler(event) {
    var request = event.request;
    var response = event.response;

    // Modify the response object here,
    // using the request properties if needed.

    return response;
}
```
La función devuelve el objeto `response` modificado a CloudFront, que CloudFront devuelve inmediatamente al lector.

## Validación de las conexiones de mTLS en un tipo de evento de solicitud de conexión
<a name="function-code-connection-request"></a>

Las funciones de conexión son un tipo de CloudFront Functions que se ejecutan durante las conexiones TLS para proporcionar una lógica de validación y autenticación personalizada. Las funciones de conexión están disponibles actualmente para las conexiones TLS mutuas (mTLS), con las que puede validar los certificados de los clientes e implementar una lógica de autenticación personalizada más allá de la validación de certificados estándar. Las funciones de conexión se ejecutan durante el proceso de establecimiento de comunicación de TLS y pueden permitir o denegar las conexiones en función de las propiedades de los certificados, las direcciones IP de los clientes u otros criterios.

Cuando crea y publica una función de conexión, asegúrese de agregar una asociación para el tipo de evento *solicitud de conexión* con una distribución con mTLS. Esto hace que la función se ejecute cada vez que un cliente intenta establecer una conexión de mTLS con CloudFront.

**Example**  
El siguiente pseudocódigo muestra la estructura de una función de conexión:  

```
function connectionHandler(connection) {
    // Validate certificate and connection properties here.
    
    if (/* validation passes */) {
        connection.allow();
    } else {
        connection.deny();
    }
}
```
La función utiliza métodos de ayuda para determinar si se debe permitir o denegar la conexión. A diferencia de las funciones de solicitud y respuesta del espectador, las funciones de conexión no pueden modificar las solicitudes o respuestas HTTP.

## Información relacionada
<a name="related-information-cloudfront-functions-purpose"></a>

Para obtener más información sobre cómo trabajar con CloudFront Functions, consulte los siguientes:
+ [Estructura de evento](functions-event-structure.md)
+ [Características del tiempo de ejecución de JavaScript](functions-javascript-runtime-features.md)
+ [Ejemplos de CloudFront Functions ](service_code_examples_cloudfront_functions_examples.md)
+ [Restricciones en funciones de borde](edge-functions-restrictions.md)

# Estructura de eventos de CloudFront Functions
<a name="functions-event-structure"></a>

CloudFront Functions pasa un objeto `event` al código de función como entrada cuando ejecuta la función. Cuando [prueba una función](test-function.md), crea el objeto `event` y lo pasa a la función. Al crear un objeto `event` para probar una función, puede omitir los campos `distributionDomainName`,`distributionId` y`requestId` en el objeto `context`. Asegúrese de que los nombres de encabezados estén en minúsculas, esto siempre sucede en el objeto de `event` que CloudFront Functions pasa a la función en producción.

A continuación, se muestra la información general de la estructura de este objeto de evento. 

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

Para obtener más información, consulte los temas siguientes:

**Topics**
+ [

## Campo Versión
](#functions-event-structure-version)
+ [

## Objeto Context (Contexto)
](#functions-event-structure-context)
+ [

## Estructura de eventos de conexión
](#functions-event-structure-connection)
+ [

## Objeto viewer (lector)
](#functions-event-structure-viewer)
+ [

## Objeto Request (solicitud)
](#functions-event-structure-request)
+ [

## Objeto de respuesta
](#functions-event-structure-response)
+ [

## Código de estado y cuerpo
](#functions-event-structure-status-body)
+ [

## Estructura para una cadena de consulta, encabezado o cookie
](#functions-event-structure-query-header-cookie)
+ [

## Objeto de respuesta de ejemplo
](#functions-response-structure-example)
+ [

## Objeto de evento de ejemplo
](#functions-event-structure-example)

## Campo Versión
<a name="functions-event-structure-version"></a>

El campo `version` contiene una cadena que especifica la versión del objeto de evento de CloudFront Functions. La versión actual es `1.0`.

## Objeto Context (Contexto)
<a name="functions-event-structure-context"></a>

El objeto `context` contiene información contextual sobre el evento. Contiene los campos siguientes:

**`distributionDomainName`**  
El nombre de dominio de CloudFront (por ejemplo, d111111abcdef8.cloudfront.net) de la distribución que está asociada al evento.  
El campo `distributionDomainName` solo aparece cuando se invoca la función para distribuciones estándar.

**`endpoint`**  
El nombre de dominio de CloudFront (por ejemplo, d111111abcdef8.cloudfront.net) del grupo de conexión asociado al evento.  
El campo `endpoint` solo aparece cuando se invoca la función para distribuciones de varios inquilinos.

**`distributionId`**  
El identificador de la distribución (por ejemplo, EDFDVBD6EXAMPLE) que está asociada al evento.

**`eventType`**  
El tipo de evento, `viewer-request` o `viewer-response`.

**`requestId`**  
Cadena que identifica de forma única una solicitud de CloudFront (y su respuesta asociada).

## Estructura de eventos de conexión
<a name="functions-event-structure-connection"></a>

Las funciones de conexión reciben una estructura de eventos diferente a la de las funciones del espectador. Para obtener información detallada sobre la estructura de eventos de conexión y el formato de respuesta, consulte [Asociación de una función de conexión de CloudFront](connection-functions.md).

## Objeto viewer (lector)
<a name="functions-event-structure-viewer"></a>

El objeto `viewer` contiene un campo `ip` cuyo valor es la dirección IP del lector (cliente) que envió la solicitud. Si el lector utiliza un proxy HTTP o un balanceador de carga para enviar la solicitud, el valor es la dirección IP del proxy o del balanceador de carga.

## Objeto Request (solicitud)
<a name="functions-event-structure-request"></a>

El objeto `request` contiene una representación de una solicitud HTTP de lector-a-CloudFront. En el objeto `event` que se pasa a la función, el objeto `request` representa la solicitud real que CloudFront recibió del lector.

Si su código de función devuelve un objeto `request` a CloudFront, debe usar esta misma estructura.

El objeto `request` contiene los siguientes campos:

**`method`**  
El método HTTP de la solicitud. Si su código de función devuelve una `request`, no puede modificar este campo. Este es el único campo de solo lectura en el objeto `request`.

**`uri`**  
La ruta relativa del objeto solicitado.   
Si la función modifica el valor `uri`, se aplica lo siguiente:  
+ El nuevo valor `uri` debe comenzar con una barra diagonal (`/`).
+ Si una función cambia el valor de `uri`, esta cambia el objeto que el lector solicita.
+ Si una función cambia el valor de `uri`, *no* cambia el comportamiento de la caché de la solicitud ni del origen al que se envía la solicitud.

**`querystring`**  
Objeto que representa la cadena de consulta en la solicitud. Si la solicitud no incluye una cadena de consulta, el objeto `request` del evento incluye un valor `querystring` vacío.  
El objeto `querystring` contiene un campo para cada parámetro de cadena de consulta de la solicitud.

**`headers`**  
Objeto que representa el encabezado HTTP en la solicitud. Si la solicitud contiene algún encabezado `Cookie`, esos encabezados no forman parte del objeto `headers`. Las cookies se representan por separado en el objeto `cookies`.  
El objeto `headers` contiene un campo para cada encabezado de la solicitud. Los nombres de encabezados se convierten a ASCII minúsculas en el objeto de evento; deben estar en ASCII minúsculas cuando se agregan según el código de función. Cuando CloudFront Functions convierte el objeto de evento de nuevo en una solicitud HTTP, la primera letra de cada palabra en los nombres de encabezados se escribe en mayúsculas, si es una letra ASCII. CloudFront Functions no aplica ningún cambio a los símbolos que no sean ASCII en los nombres de los encabezados. Por ejemplo, `TÈst-header` se convertirá en `tÈst-header` dentro de la función. El símbolo que no es ASCII `È` permanece inalterado.  
Las palabras están separadas por un guión (`-`). Por ejemplo, si el código de la función agrega un encabezado llamado `example-header-name`, CloudFront lo convierte en `Example-Header-Name` en la solicitud HTTP.

**`cookies`**  
Objeto que representa las cookies en la solicitud (encabezados `Cookie`).  
El objeto `cookies` contiene un campo para cada cookie de la solicitud.

Para obtener más información sobre la estructura de cadenas de consulta, encabezados y cookies, consulte [Estructura para una cadena de consulta, encabezado o cookie](#functions-event-structure-query-header-cookie).

Para obtener un objeto de ejemplo `event`, consulte [Objeto de evento de ejemplo](#functions-event-structure-example).

## Objeto de respuesta
<a name="functions-event-structure-response"></a>

El objeto `response` contiene una representación de una respuesta HTTP CloudFront-to-viewer. En el objeto `event` que se pasa a la función, el objeto `response` representa la respuesta real de CloudFront a una solicitud del lector.

Si su código de función devuelve un objeto `response`, debe usar esta misma estructura.

El objeto `response` contiene los siguientes campos:

**`statusCode`**  
Código de estado HTTP de la respuesta. Este valor es un número entero, no una cadena.  
La función puede generar o modificar el `statusCode`.

**`statusDescription`**  
La descripción del estado HTTP de la respuesta. Si su código de función genera una respuesta, este campo es opcional.

**`headers`**  
Un objeto que representa los encabezados HTTP en la solicitud. Si la respuesta contiene algún encabezado `Set-Cookie`, esos encabezados no forman parte del objeto `headers`. Las cookies se representan por separado en el objeto `cookies`.  
El objeto `headers` contiene un campo para cada encabezado de la respuesta. Los nombres de encabezados se convierten a minúsculas en el objeto de evento; deben estar en minúsculas cuando se agregan con el código de función. Cuando CloudFront Functions convierte el objeto de evento de nuevo en una respuesta HTTP, la primera letra de cada palabra en los nombres de encabezados se escribe en mayúsculas. Las palabras están separadas por un guión (`-`). Por ejemplo, si el código de la función agrega un encabezado llamado `example-header-name`, CloudFront lo convierte en `Example-Header-Name` en la respuesta HTTP.

**`cookies`**  
Objeto que representa las cookies en la respuesta (encabezados `Set-Cookie`).  
El objeto `cookies` contiene un campo para cada cookie en la respuesta.

**`body`**  
Agregar el campo `body` es opcional y no estará presente en el objeto de `response` a menos que lo especifique en la función. La función no tiene acceso al cuerpo original devuelto por la caché o el origen de CloudFront. Si no especifica el campo `body` en la función de respuesta del lector, el cuerpo original devuelto por la memoria caché o el origen de CloudFront se devuelve al lector.  
Si desea que CloudFront devuelva un cuerpo personalizado al lector, especifique el contenido del cuerpo en el campo `data` y la codificación del cuerpo en el campo `encoding`. Puede especificar la codificación como texto sin formato (`"encoding": "text"`) o como contenido cifrado en Base64 (`"encoding": "base64"`).  
Como método abreviado, también puede especificar el contenido del cuerpo directamente en el campo `body` (`"body": "<specify the body content here>"`). Al hacer esto, omita los campos `data` y `encoding`. CloudFront trata el cuerpo como texto sin formato en este caso.    
`encoding`  
La codificación del contenido de `body` (campo `data`). Las únicas codificaciones válidas son `text` y `base64`.  
Si especifica `encoding` como `base64` pero el cuerpo no tiene una codificación base64 válida, CloudFront devuelve un error.  
`data`  
El contenido de `body`.

Para obtener más información sobre los códigos de estado y el contenido del cuerpo modificados, consulte [Código de estado y cuerpo](#functions-event-structure-status-body).

Para obtener más información sobre la estructura de los encabezados y las cookies, consulte [Estructura para una cadena de consulta, encabezado o cookie](#functions-event-structure-query-header-cookie).

Para obtener un objeto de ejemplo `response`, consulte [Objeto de respuesta de ejemplo](#functions-response-structure-example).

## Código de estado y cuerpo
<a name="functions-event-structure-status-body"></a>

Con CloudFront Functions, puede actualizar el código de estado de la respuesta del lector, sustituir todo el cuerpo de la respuesta por uno nuevo o eliminar el cuerpo de la respuesta. Algunos escenarios comunes para actualizar la respuesta del lector después de evaluar aspectos de la respuesta de la caché o el origen de CloudFront son los siguientes:
+ Cambiar el estado para establecer un código de estado HTTP 200 y crear un cuerpo con contenido estático para devolverlo al lector.
+ Cambiar el estado para establecer un código de estado HTTP 301 o 302 para redirigir al usuario a otro sitio web.
+ Decidir si mostrar o dejar el cuerpo de la respuesta del lector.

**nota**  
Si el origen devuelve un error HTTP igual o superior a 400, CloudFront Function no se ejecutará. Para obtener más información consulte () [Restricciones en todas las funciones de borde](edge-function-restrictions-all.md).

Cuando trabaja con la respuesta HTTP, CloudFront Functions no tiene acceso al cuerpo de la respuesta. Puede sustituir el contenido del cuerpo estableciéndolo en el valor deseado o puede eliminar el cuerpo estableciendo un valor vacío. Si no actualiza el campo cuerpo de la función, el cuerpo original devuelto por la caché o el origen de CloudFront se devuelve al lector.

**sugerencia**  
Cuando utilice CloudFront Functions para sustituir un cuerpo, asegúrese de alinear los encabezados correspondientes, como `content-encoding`, `content-type` o `content-length` con el nuevo contenido del cuerpo.   
Por ejemplo, si el origen o la caché de CloudFront devuelve `content-encoding: gzip` pero la función de respuesta del lector establece un cuerpo que es texto sin formato, la función también debe cambiar los encabezados `content-encoding` y `content-type` en consecuencia.

Si CloudFront Function está configurada para devolver un error HTTP igual o superior a 400, el visor no verá una [página de error personalizada](creating-custom-error-pages.md) que haya especificado para el mismo código de estado.

## Estructura para una cadena de consulta, encabezado o cookie
<a name="functions-event-structure-query-header-cookie"></a>

Las cadenas de consulta, los encabezados y las cookies comparten la misma estructura. Las cadenas de consulta pueden aparecer en las solicitudes. Los encabezados aparecen en las solicitudes y las respuestas. Las cookies aparecen en las solicitudes y las respuestas.

Cada cadena de consulta, encabezado o cookie es un campo único dentro del objeto principal `querystring`,`headers` o `cookies`. El nombre del campo es el nombre de la cadena de consulta, el encabezado o la cookie. Cada campo contiene una propiedad `value` con el valor de la cadena de consulta, el encabezado o la cookie.

**Contents**
+ [

### Valores de cadenas de consulta u objetos de cadenas de consulta
](#functions-event-structure-query)
+ [

### Consideraciones especiales sobre el uso de los encabezados
](#functions-event-structure-headers)
+ [

### Cadenas de consulta, encabezados y cookies duplicados (matriz `multiValue`)
](#functions-event-structure-multivalue)
+ [

### Atributos de cookie
](#functions-event-structure-cookie-attributes)

### Valores de cadenas de consulta u objetos de cadenas de consulta
<a name="functions-event-structure-query"></a>

Una función puede devolver un valor de cadena de consulta además de un objeto de cadena de consulta. El valor de la cadena de consulta se puede utilizar para organizar los parámetros de la cadena de consulta en cualquier orden personalizado. 

**Example Ejemplo**  
Para modificar una cadena de consulta en el código de función, use código como el siguiente.  

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

### Consideraciones especiales sobre el uso de los encabezados
<a name="functions-event-structure-headers"></a>

Solo en el caso de encabezados, los nombres de encabezados se convierten a minúsculas en el objeto de evento; deben estar en minúsculas cuando se agregan con el código de función. Cuando CloudFront Functions convierte el objeto de evento de nuevo en una solicitud o respuesta HTTP, la primera letra de cada palabra en los nombres de encabezados se escribe en mayúsculas. Las palabras están separadas por un guión (`-`). Por ejemplo, si el código de la función agrega un encabezado llamado `example-header-name`, CloudFront lo convierte en `Example-Header-Name` en la solicitud o respuesta HTTP.

**Example Ejemplo**  
Considere el siguiente encabezado `Host` en una solicitud HTTP.  

```
Host: video.example.com
```
Este encabezado se representa de la siguiente manera en el objeto `request`:  

```
"headers": {
    "host": {
        "value": "video.example.com"
    }
}
```
Para acceder al encabezado `Host` en su código de función, use código como el siguiente:  

```
var request = event.request;
var host = request.headers.host.value;
```
Para agregar o modificar un encabezado en su código de función, use código como el siguiente (este código agrega un encabezado llamado `X-Custom-Header` con el valor `example value`):  

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

### Cadenas de consulta, encabezados y cookies duplicados (matriz `multiValue`)
<a name="functions-event-structure-multivalue"></a>

Una solicitud o respuesta HTTP puede contener más de una cadena de consulta, encabezado o cookie con el mismo nombre. En este caso, las cadenas de consulta duplicadas, encabezados o cookies se contraen en un campo del objeto `request` o `response`, pero este campo contiene una propiedad adicional denominada `multiValue`. La propiedad `multiValue` contiene una matriz con los valores de cada una de las cadenas de consulta duplicadas, encabezados o cookies.

**Example Ejemplo**  
Considere una solicitud HTTP con los siguientes encabezados `Accept`.  

```
Accept: application/json
Accept: application/xml
Accept: text/html
```
Estos encabezados se representan de la siguiente manera en el objeto `request`.  

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

**nota**  
El primer valor de encabezado (en este caso, `application/json`) se repite en las propiedades `value` y `multiValue`. Esto le permite acceder a *todos * los valores al recorrer la matriz `multiValue`.

Si el código de función modifica una cadena de consulta, encabezado o cookie que tiene una matriz `multiValue`, CloudFront Functions utiliza las siguientes reglas para aplicar los cambios:

1. Si la matriz `multiValue` existe y tiene alguna modificación, entonces esa modificación se aplica. El primer elemento de la propiedad `value` se ignora.

1. De lo contrario, se aplicará cualquier modificación a la propiedad `value` y los valores subsiguientes (si existen) permanecen sin cambios.

La propiedad `multiValue` se utiliza solo cuando la solicitud o respuesta HTTP contiene cadenas de consulta, encabezados o cookies duplicados con el mismo nombre, como se muestra en el ejemplo anterior. Sin embargo, si hay varios valores en una sola cadena de consulta, encabezado o cookie, la propiedad `multiValue` no se utiliza.

**Example Ejemplo**  
Considere una solicitud con un encabezado `Accept` que contenga tres valores.  

```
Accept: application/json, application/xml, text/html
```
Este encabezado se representa de la siguiente manera en el objeto `request`.  

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

### Atributos de cookie
<a name="functions-event-structure-cookie-attributes"></a>

En un encabezado `Set-Cookie` de una respuesta HTTP, el encabezado contiene el par nombre-valor para la cookie y opcionalmente un conjunto de atributos separados por punto y coma. 

**Example Ejemplo**  

```
Set-Cookie: cookie1=val1; Secure; Path=/; Domain=example.com; Expires=Wed, 05 Apr 2021 07:28:00 GMT
```
En el objeto `response`, estos atributos se representan en la propiedad `attributes` del campo cookie. Por ejemplo, el encabezado `Set-Cookie` anterior se representa de la siguiente manera:  

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

## Objeto de respuesta de ejemplo
<a name="functions-response-structure-example"></a>

En el siguiente ejemplo se muestra un objeto `response` (el resultado de una función de respuesta del lector) en el que el cuerpo se ha sustituido por una función de respuesta del lector.

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

     "body": {
      "encoding": "text",
      "data": "<!DOCTYPE html><html><body><p>Here is your custom content.</p></body></html>"
    }
  }
}
```

## Objeto de evento de ejemplo
<a name="functions-event-structure-example"></a>

En el siguiente ejemplo se muestra un objeto `event` completo. Este es un ejemplo de invocación para una distribución estándar y no para una distribución de varios inquilinos. Para distribuciones de varios inquilinos, se utiliza el campo `endpoint` en lugar de `distributionDomainName`. El valor de `endpoint` es el nombre de dominio de CloudFront (por ejemplo, d111111abcdef8.cloudfront.net) del grupo de conexiones asociado al evento.

**nota**  
El objeto `event` es la entrada a su función. Su función devuelve solo el objeto `request` o `response`, no el objeto `event` completo.

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

# Características del tiempo de ejecución de JavaScript para CloudFront Functions
<a name="functions-javascript-runtime-features"></a>

El entorno de tiempo de ejecución JavaScript de CloudFront Functions es compatible con la [versión 5.1 de ECMAScript (ES)](https://www.ecma-international.org/ecma-262/5.1/) y también admite algunas características de las versiones 6 a 12 de ES.

Para obtener las características más actualizadas, le recomendamos que utilice el tiempo de ejecución 2.0 de JavaScript. 

Las características del tiempo de ejecución 2.0 de JavaScript presentan los siguientes cambios en comparación con la versión 1.0:
+ Están disponibles los métodos del módulo de búfer
+ No están disponibles los siguientes métodos de prototipos de cadenas no estándares:
  + `String.prototype.bytesFrom()`
  + `String.prototype.fromBytes()`
  + `String.prototype.fromUTF8()`
  + `String.prototype.toBytes()`
  + `String.prototype.toUTF8()`
+ El módulo criptográfico presenta los siguientes cambios:
  + `hash.digest()`: el tipo de retorno se cambia a `Buffer` si no se proporciona ninguna codificación
  + `hmac.digest()`: el tipo de retorno se cambia a `Buffer` si no se proporciona ninguna codificación
+ Para obtener más información sobre nuevas características adicionales, consulte [Características del tiempo de ejecución 2.0 de JavaScript para CloudFront Functions](functions-javascript-runtime-20.md).

**Topics**
+ [Características del tiempo de ejecución 1.0 de JavaScript](functions-javascript-runtime-10.md)
+ [Características del tiempo de ejecución 2.0 de JavaScript](functions-javascript-runtime-20.md)

# Características del tiempo de ejecución 1.0 de JavaScript para CloudFront Functions
<a name="functions-javascript-runtime-10"></a>

El entorno de tiempo de ejecución JavaScript de CloudFront Functions es compatible con [la versión 5.1 de ECMAScript (ES)](https://262.ecma-international.org/5.1/) y también admite algunas características de las versiones 6 a 9 de ES. También proporciona algunos métodos no estándar que no forman parte de las especificaciones de ES. 

En los siguientes temas se mencionan todas las características de lenguaje admitidas.

**Topics**
+ [

## Características principales
](#writing-functions-javascript-features-core)
+ [

## Objetos primitivos
](#writing-functions-javascript-features-primitive-objects)
+ [

## Objetos integrados
](#writing-functions-javascript-features-builtin-objects)
+ [

## Tipos de error
](#writing-functions-javascript-features-error-types)
+ [

## Globals
](#writing-functions-javascript-features-globals)
+ [

## Módulos integrados
](#writing-functions-javascript-features-builtin-modules)
+ [

## Características restringidas
](#writing-functions-javascript-features-restricted-features)

## Características principales
<a name="writing-functions-javascript-features-core"></a>

Se admiten las siguientes características principales de ES.

**Types**  
Se admiten todos los tipos de ES 5.1. Esto incluye valores booleanos, números, cadenas, objetos, matrices, funciones, constructores de funciones y expresiones regulares.

**Operadores**  
Se admiten todos los operadores de ES 5.1.  
Se admite el operador de exponenciación ES 7 (`**`).

**Instrucciones**  
No se admiten las instrucciones `const` ni `let`.
Se admiten las siguientes instrucciones de ES 5.1:  
+ `break`
+ `catch`
+ `continue`
+ `do-while`
+ `else`
+ `finally`
+ `for`
+ `for-in`
+ `if`
+ `return`
+ `switch`
+ `throw`
+ `try`
+ `var`
+ `while`
+ Instrucciones etiquetadas

**Literales**  
Se admiten literales de plantilla de ES 6: cadenas de líneas múltiples, interpolación de expresiones y plantillas de anidamiento.

**Funciones**  
Se admiten todas las características de función de ES 5.1.  
Se admiten las funciones flecha de ES 6 así como la sintaxis del parámetro rest de ES 6.

**Unicode**  
El texto de origen y los literales de cadena pueden contener caracteres codificados en Unicode. También se admiten secuencias de escape de punto de código Unicode de seis caracteres (por ejemplo, `\uXXXX`).

**Modo estricto**  
Las funciones operan en modo estricto de forma predeterminada, por lo que no necesita agregar una instrucción `use strict` en su código de función. Esto no se puede cambiar.

## Objetos primitivos
<a name="writing-functions-javascript-features-primitive-objects"></a>

Se admiten los siguientes objetos primitivos de ES.

**Objeto**  
Se admiten los siguientes métodos de ES 5.1 en objetos:  
+ `create` (sin lista de propiedades)
+ `defineProperties`
+ `defineProperty`
+ `freeze`
+ `getOwnPropertyDescriptor`
+ `getOwnPropertyNames`
+ `getPrototypeOf`
+ `hasOwnProperty`
+ `isExtensible`
+ `isFrozen`
+ `prototype.isPrototypeOf`
+ `isSealed`
+ `keys`
+ `preventExtensions`
+ `prototype.propertyIsEnumerable`
+ `seal`
+ `prototype.toString`
+ `prototype.valueOf`
Se admiten los siguientes métodos de ES 6 en objetos:  
+ `assign`
+ `is`
+ `prototype.setPrototypeOf`
Se admiten los siguientes métodos de ES 8 en objetos:  
+ `entries`
+ `values`

**Cadena**  
Se admiten los siguientes métodos de ES 5.1 en cadenas:  
+ `fromCharCode`
+ `prototype.charAt`
+ `prototype.concat`
+ `prototype.indexOf`
+ `prototype.lastIndexOf`
+ `prototype.match`
+ `prototype.replace`
+ `prototype.search`
+ `prototype.slice`
+ `prototype.split`
+ `prototype.substr`
+ `prototype.substring`
+ `prototype.toLowerCase`
+ `prototype.trim`
+ `prototype.toUpperCase`
Se admiten los siguientes métodos de ES 6 en cadenas:  
+ `fromCodePoint`
+ `prototype.codePointAt`
+ `prototype.endsWith`
+ `prototype.includes`
+ `prototype.repeat`
+ `prototype.startsWith`
Se admiten los siguientes métodos de ES 8 en cadenas:  
+ `prototype.padStart`
+ `prototype.padEnd`
Se admiten los siguientes métodos de ES 9 en cadenas:  
+ `prototype.trimStart`
+ `prototype.trimEnd`
Se admiten los siguientes métodos no estándar en cadenas:  
+ `prototype.bytesFrom(array | string, encoding)`

  Crea una cadena de bytes a partir de una matriz de octetos o una cadena codificada. Las opciones de codificación de cadenas son `hex`, `base64` y `base64url`.
+ `prototype.fromBytes(start[, end])`

  Crea una cadena Unicode a partir de una cadena de bytes donde cada byte se reemplaza con el punto de código Unicode correspondiente.
+ `prototype.fromUTF8(start[, end])`

  Crea una cadena Unicode a partir de una cadena de bytes codificada en UTF-8. Si la codificación es incorrecta, devuelve `null`.
+ `prototype.toBytes(start[, end])`

  Crea una cadena de bytes a partir de una cadena Unicode. Todos los caracteres deben estar comprendidos en el rango [0-255]. De lo contrario, devuelve `null`.
+ `prototype.toUTF8(start[, end])`

  Crea una cadena de bytes codificada en UTF-8 a partir de una cadena Unicode.

**Número**  
Se admiten todos los métodos de ES 5.1 en números.  
Se admiten los siguientes métodos de ES 6 en números:  
+ `isFinite`
+ `isInteger`
+ `isNaN`
+ `isSafeInteger`
+ `parseFloat`
+ `parseInt`
+ `prototype.toExponential`
+ `prototype.toFixed`
+ `prototype.toPrecision`
+ `EPSILON`
+ `MAX_SAFE_INTEGER`
+ `MAX_VALUE`
+ `MIN_SAFE_INTEGER`
+ `MIN_VALUE`
+ `NEGATIVE_INFINITY`
+ `NaN`
+ `POSITIVE_INFINITY`

## Objetos integrados
<a name="writing-functions-javascript-features-builtin-objects"></a>

Se admiten los siguientes objetos integrados de ES.

**Math**  
Se admiten todos los métodos matemáticos de ES 5.1.  
En el entorno de tiempo de ejecución de CloudFront Functions, la implementación de `Math.random()` utiliza `arc4random` de OpenBSD predefinido con la marca de tiempo de cuándo se ejecuta la función.
Se admiten los siguientes métodos matemáticos de ES 6:  
+ `acosh`
+ `asinh`
+ `atanh`
+ `cbrt`
+ `clz32`
+ `cosh`
+ `expm1`
+ `fround`
+ `hypot`
+ `imul`
+ `log10`
+ `log1p`
+ `log2`
+ `sign`
+ `sinh`
+ `tanh`
+ `trunc`
+ `E`
+ `LN10`
+ `LN2`
+ `LOG10E`
+ `LOG2E`
+ `PI`
+ `SQRT1_2`
+ `SQRT2`

**Fecha**  
Se admiten todas las características `Date` de ES 5.1.  
Por razones de seguridad, `Date` siempre devuelve el mismo valor (la hora de inicio de la función) durante la vida útil de la ejecución de una sola función. Para obtener más información, consulte [Características restringidas](#writing-functions-javascript-features-restricted-features).

**Función**  
Se admiten los métodos `apply`, `bind` y `call`.  
Los constructores de funciones no son compatibles.

**Expresiones regulares**  
Se admiten todas las características de expresión regular de ES 5.1. El lenguaje de expresión regular es compatible con Perl. Se admiten grupos de captura con nombre de ES 9.

**JSON**  
Se admiten todas las características JSON de ES 5.1, incluidas `parse` y `stringify`.

**Matriz**  
Se admiten los siguientes métodos de ES 5.1 en matrices:  
+ `isArray`
+ `prototype.concat`
+ `prototype.every`
+ `prototype.filter`
+ `prototype.forEach`
+ `prototype.indexOf`
+ `prototype.join`
+ `prototype.lastIndexOf`
+ `prototype.map`
+ `prototype.pop`
+ `prototype.push`
+ `prototype.reduce`
+ `prototype.reduceRight`
+ `prototype.reverse`
+ `prototype.shift`
+ `prototype.slice`
+ `prototype.some`
+ `prototype.sort`
+ `prototype.splice`
+ `prototype.unshift`
Se admiten los siguientes métodos de ES 6 en matrices:  
+ `of`
+ `prototype.copyWithin`
+ `prototype.fill`
+ `prototype.find`
+ `prototype.findIndex`
Se admiten los siguientes métodos de ES 7 en matrices:  
+ `prototype.includes`

**Matrices con tipo**  
Se admiten las siguientes matrices con tipo de ES 6:  
+ `Int8Array`
+ `Uint8Array`
+ `Uint8ClampedArray`
+ `Int16Array`
+ `Uint16Array`
+ `Int32Array`
+ `Uint32Array`
+ `Float32Array`
+ `Float64Array`
+ `prototype.copyWithin`
+ `prototype.fill`
+ `prototype.join`
+ `prototype.set`
+ `prototype.slice`
+ `prototype.subarray`
+ `prototype.toString`

**ArrayBuffer**  
Se admiten los siguientes métodos en `ArrayBuffer`:  
+ `prototype.isView`
+ `prototype.slice`

**Promesa**  
Se admiten los siguientes métodos en promesas:  
+ `reject`
+ `resolve`
+ `prototype.catch`
+ `prototype.finally`
+ `prototype.then`

**Cripto**  
El módulo criptográfico proporciona ayudantes de código de autenticación de mensajes (HMAC) estándar hashing y basado en hash. Puede cargar el módulo mediante `require('crypto')`. El módulo expone los siguientes métodos que se comportan exactamente como sus homólogos Node.js:  
+ `createHash(algorithm)`
+ `hash.update(data)`
+ `hash.digest([encoding])`
+ `createHmac(algorithm, secret key)`
+ `hmac.update(data)`
+ `hmac.digest([encoding])`
Para obtener más información, consulte [Cripto (hash y HMAC)](#writing-functions-javascript-features-builtin-modules-crypto) en la sección módulos integrados.

**Consola**  
Este es un objeto ayudante para la depuración. Solo admite el método `log()` para registrar mensajes de registro.  
CloudFront Functions no admite la sintaxis con comas, como `console.log('a', 'b')`. En su lugar, utilice el formato `console.log('a' + ' ' + 'b')`.

## Tipos de error
<a name="writing-functions-javascript-features-error-types"></a>

Se admiten los siguientes objetos de error:
+ `Error`
+ `EvalError`
+ `InternalError`
+ `MemoryError`
+ `RangeError`
+ `ReferenceError`
+ `SyntaxError`
+ `TypeError`
+ `URIError`

## Globals
<a name="writing-functions-javascript-features-globals"></a>

Se admite el objeto `globalThis`.

Se admiten las siguientes características globales de ES 5.1:
+ `decodeURI`
+ `decodeURIComponent`
+ `encodeURI`
+ `encodeURIComponent`
+ `isFinite`
+ `isNaN`
+ `parseFloat`
+ `parseInt`

Se admiten las siguientes constantes globales:
+ `NaN`
+ `Infinity`
+ `undefined`

## Módulos integrados
<a name="writing-functions-javascript-features-builtin-modules"></a>

Se admiten los siguientes módulos integrados:

**Topics**
+ [

### Cripto (hash y HMAC)
](#writing-functions-javascript-features-builtin-modules-crypto)
+ [

### Cadena de consulta
](#writing-functions-javascript-features-builtin-modules-query-string)

### Cripto (hash y HMAC)
<a name="writing-functions-javascript-features-builtin-modules-crypto"></a>

El módulo criptográfico (`crypto`) proporciona ayudantes de código de autenticación de mensajes basado en hash (HMAC) y hashing estándar. Puede cargar el módulo mediante `require('crypto')`. El módulo proporciona los siguientes métodos que se comportan exactamente como sus homólogos Node.js.

**Métodos de hashing**

`crypto.createHash(algorithm)`  
Crea y devuelve un objeto hash que puede utilizar para generar resúmenes hash mediante el algoritmo dado: `md5`, `sha1` o `sha256`.

`hash.update(data)`  
Actualiza el contenido hash con los dado `data`.

`hash.digest([encoding])`  
Calcula el resumen de todos los datos pasados con `hash.update()`. La codificación puede ser `hex`, `base64` o `base64url`.

**Métodos HMAC**

`crypto.createHmac(algorithm, secret key)`  
Crea y devuelve un objeto HMAC que utiliza el `algorithm` y `secret key` dados. El algoritmo puede ser `md5`, `sha1` o `sha256`.

`hmac.update(data)`  
Actualiza el contenido de HMAC con los dado `data`.

`hmac.digest([encoding])`  
Calcula el resumen de todos los datos pasados con `hmac.update()`. La codificación puede ser `hex`, `base64` o `base64url`.

### Cadena de consulta
<a name="writing-functions-javascript-features-builtin-modules-query-string"></a>

**nota**  
El objeto [ de evento de CloudFront Functions ](functions-event-structure.md) analiza automáticamente las cadenas de consulta de URL. Eso significa que en la mayoría de los casos no necesita usar este módulo.

El módulo de cadena de consulta (`querystring`) proporciona métodos para analizar y dar formato a las cadenas de consulta de URL. Puede cargar el módulo mediante `require('querystring')`. El módulo proporciona los siguientes métodos.

`querystring.escape(string)`  
La URL codifica la `string` dada y devuelve una cadena de consulta escapada. El método es utilizado por `querystring.stringify()` y no debe utilizarse directamente.

`querystring.parse(string[, separator[, equal[, options]]])`  
Analiza una cadena de consulta (`string`) y devuelve un objeto.  
El parámetro `separator` es una subcadena para delimitar pares de claves y valores en la cadena de consulta. De forma predeterminada, es `&`.  
El parámetro `equal` es una subcadena para delimitar claves y valores en la cadena de consulta. De forma predeterminada, es `=`.  
El parámetro `options` es un objeto con las siguientes claves:    
`decodeURIComponent function`  
Una función para decodificar caracteres codificados por porcentaje en la cadena de consulta. De forma predeterminada, es `querystring.unescape()`.  
`maxKeys number`  
El número máximo de claves que se analizan. De forma predeterminada, es `1000`. Utilice un valor de `0` para eliminar las limitaciones del recuento de claves.
De forma predeterminada, se supone que los caracteres codificados con porcentaje dentro de la cadena de consulta utilizan la codificación UTF-8. Las secuencias UTF-8 no válidas se reemplazan por el carácter de reemplazo `U+FFFD`.  
Por ejemplo, para la siguiente cadena de consulta:  

```
'name=value&abc=xyz&abc=123'
```
El valor de retorno de `querystring.parse()` es:  

```
{
name: 'value',
abc: ['xyz', '123']
}
```
`querystring.decode()` es un alias de `querystring.parse()`.

`querystring.stringify(object[, separator[, equal[, options]]])`  
Serializa un `object` y devuelve una cadena de consulta.  
El parámetro `separator` es una subcadena para delimitar pares de claves y valores en la cadena de consulta. De forma predeterminada, es `&`.  
El parámetro `equal` es una subcadena para delimitar claves y valores en la cadena de consulta. De forma predeterminada, es `=`.  
El parámetro `options` es un objeto con las siguientes claves:    
`encodeURIComponent function`  
La función que se va a utilizar para convertir caracteres no seguros de URL a codificación porcentual en la cadena de consulta. De forma predeterminada, es `querystring.escape()`.
De forma predeterminada, los caracteres que requieren codificación porcentual dentro de la cadena de consulta se codifican como UTF-8. Para utilizar una codificación diferente, especifique la opción `encodeURIComponent`.  
Por ejemplo, el siguiente código:  

```
querystring.stringify({ name: 'value', abc: ['xyz', '123'], anotherName: '' });
```
El valor de retorno es:  

```
'name=value&abc=xyz&abc=123&anotherName='
```
`querystring.encode()` es un alias de `querystring.stringify()`.

`querystring.unescape(string)`  
Decodifica caracteres codificados con porcentaje de URL en la `string` dada y devuelve una cadena de consulta sin escapar. Este método es utilizado por `querystring.parse()` y no debe utilizarse directamente.

## Características restringidas
<a name="writing-functions-javascript-features-restricted-features"></a>

Las siguientes características de lenguaje JavaScript no se admiten o están restringidas debido a cuestiones de seguridad.

**Evaluación dinámica de código**  
No se admite la evaluación dinámica de código. Si se intenta, los constructores `eval()` y `Function` arrojan un error. Por ejemplo, `const sum = new Function('a', 'b', 'return a + b')` arroja un error.

**Temporizadores**  
No se admiten las funciones `setTimeout()`, `setImmediate()` y `clearTimeout()`. No hay nada para posponer o producir dentro de una ejecución de función. La función debe ejecutarse de manera sincrónica hasta finalizar.

**Fecha y marcas temporales**  
Por razones de seguridad, no hay acceso a temporizadores de alta resolución. Todos los métodos `Date` para consultar la hora actual siempre devuelven el mismo valor durante la vida útil de una sola función ejecutada. La marca temporal devuelta es la hora en que la función comenzó a ejecutarse. Por eso, no puede medir el tiempo transcurrido en la función.

**Acceso al sistema de archivos**  
No hay acceso al sistema de archivos. Por ejemplo, no hay ningún módulo `fs` para el acceso al sistema de archivos como lo hay en Node.js.

**Acceso al proceso**  
No hay acceso al proceso. Por ejemplo, no hay ningún objeto global `process` para procesar el acceso a la información como lo hay en Node.js.

**Variables de entorno**  
No hay acceso a las variables de entorno.   
En su lugar, puede utilizar CloudFront KeyValueStore para crear un almacén de datos centralizado de pares clave-valor para las CloudFront Functions. CloudFront KeyValueStore habilita las actualizaciones dinámicas de los datos de configuración sin necesidad de implementar cambios en el código. Debe utilizar el [tiempo de ejecución de JavaScript 2.0](functions-javascript-runtime-20.md) para utilizar CloudFront KeyValueStore. Para obtener más información, consulte [Amazon CloudFront KeyValueStore](kvs-with-functions.md).

**Acceso a la red**  
No se admiten las llamadas de red. Por ejemplo, no se admite XHR, HTTP (S) ni socket.

# Características del tiempo de ejecución 2.0 de JavaScript para CloudFront Functions
<a name="functions-javascript-runtime-20"></a>

El entorno de tiempo de ejecución JavaScript de CloudFront Functions es compatible con la [versión 5.1 de ECMAScript (ES)](https://262.ecma-international.org/5.1/) y también admite algunas características de las versiones 6 a 12 de ES. También proporciona algunos métodos no estándar que no forman parte de las especificaciones de ES. En los siguientes temas se enumeran todas las características admitidas en este tiempo de ejecución.

**Topics**
+ [

## Características principales
](#writing-functions-javascript-features-core-20)
+ [

## Objetos primitivos
](#writing-functions-javascript-features-primitive-objects-20)
+ [

## Objetos integrados
](#writing-functions-javascript-features-builtin-objects-20)
+ [

## Tipos de error
](#writing-functions-javascript-features-error-types-20)
+ [

## Globals
](#writing-functions-javascript-features-globals-20)
+ [

## Módulos integrados
](#writing-functions-javascript-features-builtin-modules-20)
+ [

## Características restringidas
](#writing-functions-javascript-features-restricted-features-20)

## Características principales
<a name="writing-functions-javascript-features-core-20"></a>

Se admiten las siguientes características principales de ES.

**Types**  
Se admiten todos los tipos de ES 5.1. Esto incluye valores booleanos, números, cadenas, objetos, matrices, funciones y expresiones regulares.

**Operadores**  
Se admiten todos los operadores de ES 5.1.  
Se admite el operador de exponenciación ES 7 (`**`).

**Instrucciones**  
Se admiten las siguientes instrucciones de ES 5.1:  
+ `break`
+ `catch`
+ `continue`
+ `do-while`
+ `else`
+ `finally`
+ `for`
+ `for-in`
+ `if`
+ `label`
+ `return`
+ `switch`
+ `throw`
+ `try`
+ `var`
+ `while`
Se admiten las siguientes instrucciones de ES 6:  
+ `const`
+ `let`
Se admiten las siguientes instrucciones de ES 8:  
+ `async`
+ `await`
El tiempo de ejecución 2.0 de JavaScript admite `async`, `await`, `const` y `let`.  
`await` solo se puede usar dentro de funciones `async`. No se admiten argumentos ni cierres de `async`.

**Literales**  
Se admiten literales de plantilla de ES 6: cadenas de líneas múltiples, interpolación de expresiones y plantillas de anidamiento.

**Funciones**  
Se admiten todas las características de función de ES 5.1.  
Se admiten las funciones flecha de ES 6 así como la sintaxis del parámetro rest de ES 6.

**Unicode**  
El texto de origen y los literales de cadena pueden contener caracteres codificados en Unicode. También se admiten secuencias de escape de punto de código Unicode de seis caracteres (por ejemplo, `\uXXXX`).

**Modo estricto**  
Las funciones operan en modo estricto de forma predeterminada, por lo que no necesita agregar una instrucción `use strict` en su código de función. Esto no se puede cambiar.

## Objetos primitivos
<a name="writing-functions-javascript-features-primitive-objects-20"></a>

Se admiten los siguientes objetos primitivos de ES.

**Objeto**  
Se admiten los siguientes métodos de ES 5.1 en objetos:  
+ `Object.create()` (sin lista de propiedades)
+ `Object.defineProperties()`
+ `Object.defineProperty()`
+ `Object.freeze()`
+ `Object.getOwnPropertyDescriptor()`
+ `Object.getOwnPropertyDescriptors()`
+ `Object.getOwnPropertyNames()`
+ `Object.getPrototypeOf()`
+ `Object.isExtensible()`
+ `Object.isFrozen()`
+ `Object.isSealed()`
+ `Object.keys()`
+ `Object.preventExtensions()`
+ `Object.seal()`
Se admiten los siguientes métodos de ES 6 en objetos:  
+ `Object.assign()`
Se admiten los siguientes métodos de ES 8 en objetos:  
+ `Object.entries()`
+ `Object.values()`
Se admiten los siguientes métodos prototipo de ES 5.1 en objetos:  
+ `Object.prototype.hasOwnProperty()`
+ `Object.prototype.isPrototypeOf()`
+ `Object.prototype.propertyIsEnumerable()`
+ `Object.prototype.toString()`
+ `Object.prototype.valueOf()`
Se admiten los siguientes métodos prototipo de ES 6 en objetos:  
+ `Object.prototype.is()`
+ `Object.prototype.setPrototypeOf()`

**Cadena**  
Se admiten los siguientes métodos de ES 5.1 en cadenas:  
+ `String.fromCharCode()`
Se admiten los siguientes métodos de ES 6 en cadenas:  
+ `String.fromCodePoint()`
Se admiten los siguientes métodos prototipo de ES 5.1 en cadenas:  
+ `String.prototype.charAt()`
+ `String.prototype.concat()`
+ `String.prototype.indexOf()`
+ `String.prototype.lastIndexOf()`
+ `String.prototype.match()`
+ `String.prototype.replace()`
+ `String.prototype.search()`
+ `String.prototype.slice()`
+ `String.prototype.split()`
+ `String.prototype.substr()`
+ `String.prototype.substring()`
+ `String.prototype.toLowerCase()`
+ `String.prototype.trim()`
+ `String.prototype.toUpperCase()`
Se admiten los siguientes métodos prototipo de ES 6 en cadenas:  
+ `String.prototype.codePointAt()`
+ `String.prototype.endsWith()`
+ `String.prototype.includes()`
+ `String.prototype.repeat()`
+ `String.prototype.startsWith()`
Se admiten los siguientes métodos prototipo de ES 8 en cadenas:  
+ `String.prototype.padStart()`
+ `String.prototype.padEnd()`
Se admiten los siguientes métodos prototipo de ES 9 en cadenas:  
+ `String.prototype.trimStart()`
+ `String.prototype.trimEnd()`
Se admiten los siguientes métodos prototipo de ES 12 en cadenas:  
+ `String.prototype.replaceAll()`
**nota**  
`String.prototype.replaceAll()` es una novedad en el tiempo de ejecución 2.0 de JavaScript.

**Número**  
Se admiten TODOS los números de ES 5.  
Se admiten las siguientes propiedades de ES 6 en números:  
+ `Number.EPSILON`
+ `Number.MAX_SAFE_INTEGER`
+ `Number.MIN_SAFE_INTEGER`
+ `Number.MAX_VALUE`
+ `Number.MIN_VALUE`
+ `Number.NaN`
+ `Number.NEGATIVE_INFINITY`
+ `Number.POSITIVE_INFINITY`
Se admiten los siguientes métodos de ES 6 en números:  
+ `Number.isFinite()`
+ `Number.isInteger()`
+ `Number.isNaN()`
+ `Number.isSafeInteger()`
+ `Number.parseInt()`
+ `Number.parseFloat()`
Se admiten los siguientes métodos prototipo de ES 5.1 en números:  
+ `Number.prototype.toExponential()`
+ `Number.prototype.toFixed()`
+ `Number.prototype.toPrecision()`
Se admiten los separadores numéricos ES 12.  
Los separadores numéricos ES 12 son nuevos en el tiempo de ejecución 2.0 de JavaScript.

## Objetos integrados
<a name="writing-functions-javascript-features-builtin-objects-20"></a>

Se admiten los siguientes objetos integrados de ES.

**Math**  
Se admiten todos los métodos matemáticos de ES 5.1.  
En el entorno de tiempo de ejecución de CloudFront Functions, la implementación de `Math.random()` utiliza `arc4random` de OpenBSD predefinido con la marca de tiempo de cuándo se ejecuta la función.
Se admiten las siguientes propiedades matemáticas de ES 6:  
+ `Math.E`
+ `Math.LN10`
+ `Math.LN2`
+ `Math.LOG10E`
+ `Math.LOG2E`
+ `Math.PI`
+ `Math.SQRT1_2`
+ `Math.SQRT2`
Se admiten los siguientes métodos matemáticos de ES 6:  
+ `Math.abs()`
+ `Math.acos()`
+ `Math.acosh()`
+ `Math.asin()`
+ `Math.asinh()`
+ `Math.atan()`
+ `Math.atan2()`
+ `Math.atanh()`
+ `Math.cbrt()`
+ `Math.ceil()`
+ `Math.clz32()`
+ `Math.cos()`
+ `Math.cosh()`
+ `Math.exp()`
+ `Math.expm1()`
+ `Math.floor()`
+ `Math.fround()`
+ `Math.hypot()`
+ `Math.imul()`
+ `Math.log()`
+ `Math.log1p()`
+ `Math.log2()`
+ `Math.log10()`
+ `Math.max()`
+ `Math.min()`
+ `Math.pow()`
+ `Math.random()`
+ `Math.round()`
+ `Math.sign()`
+ `Math.sinh()`
+ `Math.sin()`
+ `Math.sqrt()`
+ `Math.tan()`
+ `Math.tanh()`
+ `Math.trunc()`

**Fecha**  
Se admiten todas las características `Date` de ES 5.1.  
Por razones de seguridad, `Date` siempre devuelve el mismo valor (la hora de inicio de la función) durante la vida útil de la ejecución de una sola función. Para obtener más información, consulte [Características restringidas](functions-javascript-runtime-10.md#writing-functions-javascript-features-restricted-features).

**Función**  
Se admiten los siguientes métodos prototipo de ES 5.1:  
+ `Function.prototype.apply()`
+ `Function.prototype.bind()`
+ `Function.prototype.call()`
Los constructores de funciones no son compatibles.

**Expresiones regulares**  
Se admiten todas las características de expresión regular de ES 5.1. El lenguaje de expresión regular es compatible con Perl.  
Se admiten las siguientes características de acceso prototipo de ES 5.1:  
+ `RegExp.prototype.global`
+ `RegExp.prototype.ignoreCase`
+ `RegExp.protoype.multiline`
+ `RegExp.protoype.source`
+ `RegExp.prototype.sticky`
+ `RegExp.prototype.flags`
**nota**  
`RegExp.prototype.sticky` y `RegExp.prototype.flags` son novedades en el tiempo de ejecución 2.0 de JavaScript.
Se admiten los siguientes métodos prototipo de ES 5.1:  
+ `RegExp.prototype.exec()`
+ `RegExp.prototype.test()`
+ `RegExp.prototype.toString()`
+ `RegExp.prototype[@@replace]()`
+ `RegExp.prototype[@@split]()`
**nota**  
`RegExp.prototype[@@split]()` es una novedad en el tiempo de ejecución 2.0 de JavaScript.
Se admiten las siguientes propiedades de instancia de ES 5.1:  
+ `lastIndex`
Se admiten grupos de captura con nombre de ES 9.

**JSON**  
Se admiten los siguientes métodos matemáticos de ES 5.1:  
+ `JSON.parse()`
+ `JSON.stringify()`

**Matriz**  
Se admiten los siguientes métodos de ES 5.1 en matrices:  
+ `Array.isArray()`
Se admiten los siguientes métodos de ES 6 en matrices:  
+ `Array.of()`
Se admiten los siguientes métodos prototipo de ES 5.1:  
+ `Array.prototype.concat()`
+ `Array.prototype.every()`
+ `Array.prototype.filter()`
+ `Array.prototype.forEach()`
+ `Array.prototype.indexOf()`
+ `Array.prototype.join()`
+ `Array.prototype.lastIndexOf()`
+ `Array.prototype.map()`
+ `Array.prototype.pop()`
+ `Array.prototype.push()`
+ `Array.prototype.reduce()`
+ `Array.prototype.reduceRight()`
+ `Array.prototype.reverse()`
+ `Array.prototype.shift()`
+ `Array.prototype.slice()`
+ `Array.prototype.some()`
+ `Array.prototype.sort()`
+ `Array.prototype.splice()`
+ `Array.prototype.unshift()`
Se admiten los siguientes métodos prototipo de ES 6  
+ `Array.prototype.copyWithin()`
+ `Array.prototype.fill()`
+ `Array.prototype.find()`
+ `Array.prototype.findIndex()`
Se admiten los siguientes métodos prototipo de ES 7:  
+ `Array.prototype.includes()`

**Matrices con tipo**  
Se admiten los siguientes constructores de matrices con tipo de ES 6:  
+ `Float32Array`
+ `Float64Array`
+ `Int8Array`
+ `Int16Array`
+ `Int32Array`
+ `Uint8Array`
+ `Uint8ClampedArray`
+ `Uint16Array`
+ `Uint32Array`
Se admiten los siguientes métodos matemáticos de ES 6:  
+ `TypedArray.from()`
+ `TypedArray.of()`
**nota**  
`TypedArray.from()` y `TypedArray.of()` son novedades en el tiempo de ejecución 2.0 de JavaScript.
Se admiten los siguientes métodos prototipo de ES 6:  
+ `TypedArray.prototype.copyWithin()`
+ `TypedArray.prototype.every()`
+ `TypedArray.prototype.fill()`
+ `TypedArray.prototype.filter()`
+ `TypedArray.prototype.find()`
+ `TypedArray.prototype.findIndex()`
+ `TypedArray.prototype.forEach()`
+ `TypedArray.prototype.includes()`
+ `TypedArray.prototype.indexOf()`
+ `TypedArray.prototype.join()`
+ `TypedArray.prototype.lastIndexOf()`
+ `TypedArray.prototype.map()`
+ `TypedArray.prototype.reduce()`
+ `TypedArray.prototype.reduceRight()`
+ `TypedArray.prototype.reverse()`
+ `TypedArray.prototype.some()`
+ `TypedArray.prototype.set()`
+ `TypedArray.prototype.slice()`
+ `TypedArray.prototype.sort()`
+ `TypedArray.prototype.subarray()`
+ `TypedArray.prototype.toString()`
**nota**  
`TypedArray.prototype.every()`, `TypedArray.prototype.fill()`, `TypedArray.prototype.filter()`, `TypedArray.prototype.find()`, `TypedArray.prototype.findIndex()`, `TypedArray.prototype.forEach()`, `TypedArray.prototype.includes()`, `TypedArray.prototype.indexOf()`, `TypedArray.prototype.join()`, `TypedArray.prototype.lastIndexOf()`,`TypedArray.prototype.map()`, `TypedArray.prototype.reduce()`, `TypedArray.prototype.reduceRight()`, `TypedArray.prototype.reverse()` y `TypedArray.prototype.some()` son novedades en el tiempo de ejecución 2.0 de JavaScript.

**ArrayBuffer**  
Se admiten los siguientes métodos de ES 6 en ArrayBuffer:  
+ `isView()`
Se admiten los siguientes métodos prototipo de ES 6 en ArrayBuffer:  
+ `ArrayBuffer.prototype.slice()`

**Promesa**  
Se admiten los siguientes métodos de ES 6 en promesas:  
+ `Promise.all()`
+ `Promise.allSettled()`
+ `Promise.any()`
+ `Promise.reject()`
+ `Promise.resolve()`
+ `Promise.race()`
**nota**  
`Promise.all()`, `Promise.allSettled()`, `Promise.any()` y `Promise.race()` son novedades en el tiempo de ejecución 2.0 de JavaScript.
Se admiten los siguientes métodos prototipos de ES 6 en promesas:  
+ `Promise.prototype.catch()`
+ `Promise.prototype.finally()`
+ `Promise.prototype.then()`

**DataView**  
Se admiten los siguientes métodos prototipo de ES 6:  
+ `DataView.prototype.getFloat32()`
+ `DataView.prototype.getFloat64()`
+ `DataView.prototype.getInt16()`
+ `DataView.prototype.getInt32()`
+ `DataView.prototype.getInt8()`
+ `DataView.prototype.getUint16()`
+ `DataView.prototype.getUint32()`
+ `DataView.prototype.getUint8()`
+ `DataView.prototype.setFloat32()`
+ `DataView.prototype.setFloat64()`
+ `DataView.prototype.setInt16()`
+ `DataView.prototype.setInt32()`
+ `DataView.prototype.setInt8()`
+ `DataView.prototype.setUint16()`
+ `DataView.prototype.setUint32()`
+ `DataView.prototype.setUint8()`
**nota**  
Todos los métodos prototipo de DataView ES 6 son nuevos en el tiempo de ejecución 2.0 de JavaScript.

**Símbolo**  
Se admiten los siguientes métodos matemáticos de ES 6:  
+ `Symbol.for()`
+ `Symbol.keyfor()`
**nota**  
Todos los métodos de ES 6 de símbolos son nuevos en el tiempo de ejecución 2.0 de JavaScript.

**Descodificador de texto**  
Se admiten los siguientes métodos prototipo:  
+ `TextDecoder.prototype.decode()`
Se admiten las siguientes propiedades de acceso prototipo:  
+ `TextDecoder.prototype.encoding`
+ `TextDecoder.prototype.fatal`
+ `TextDecoder.prototype.ignoreBOM`

**Codificador de texto**  
Se admiten los siguientes métodos prototipo:  
+ `TextEncoder.prototype.encode()`
+ `TextEncoder.prototype.encodeInto()`

## Tipos de error
<a name="writing-functions-javascript-features-error-types-20"></a>

Se admiten los siguientes objetos de error:
+ `Error`
+ `EvalError`
+ `InternalError`
+ `RangeError`
+ `ReferenceError`
+ `SyntaxError`
+ `TypeError`
+ `URIError`

## Globals
<a name="writing-functions-javascript-features-globals-20"></a>

Se admite el objeto `globalThis`.

Se admiten las siguientes características globales de ES 5.1:
+ `decodeURI()`
+ `decodeURIComponent()`
+ `encodeURI()`
+ `encodeURIComponent()`
+ `isFinite()`
+ `isNaN()`
+ `parseFloat()`
+ `parseInt()`

Se admiten las siguientes características globales de ES 6:
+ `atob()`
+ `btoa()`
**nota**  
`atob()` y `btoa()` son novedades en el tiempo de ejecución 2.0 de JavaScript.

Se admiten las siguientes constantes globales:
+ `NaN`
+ `Infinity`
+ `undefined`
+ `arguments`

## Módulos integrados
<a name="writing-functions-javascript-features-builtin-modules-20"></a>

Se admiten los siguientes módulos integrados:

**Topics**
+ [

### Búfer
](#writing-functions-javascript-features-builtin-modules-buffer-20)
+ [

### Cadena de consulta
](#writing-functions-javascript-features-builtin-modules-query-string-20)
+ [

### Cripto
](#writing-functions-javascript-features-builtin-modules-crypto-20)

### Búfer
<a name="writing-functions-javascript-features-builtin-modules-buffer-20"></a>

El módulo proporciona los siguientes métodos:
+ `Buffer.alloc(size[, fill[, encoding]])`

  Asignación de un `Buffer`.
  + `size`: tamaño del búfer. Introduzca un número entero.
  + `fill`: opcional. Introduzca una cadena, `Buffer`, Uint8Array o entero. El valor predeterminado es `0`. 
  + `encoding`: opcional. Si `fill` es una cadena, introduzca una de las siguientes opciones: `utf8`, `hex`, `base64` o `base64url`. El valor predeterminado es `utf8`.
+ `Buffer.allocUnsafe(size)`

  Asigne un valor no inicializado `Buffer`.
  + `size`: introduzca un número entero.
+ `Buffer.byteLength(value[, encoding])`

  Devuelve la longitud de un valor, en bytes.
  + `value`: una cadena, `Buffer`, TypedArray, Dataview o Arraybuffer.
  + `encoding`: opcional. Si `value` es una cadena, introduzca una de las siguientes opciones: `utf8`, `hex`, `base64` o `base64url`. El valor predeterminado es `utf8`.
+ `Buffer.compare(buffer1, buffer2)`

  Compare dos `Buffer` para ayudar a ordenar las matrices. Devuelve `0` si son iguales, `-1` si `buffer1` aparece primero o `1` si `buffer2` aparece primero.
  + `buffer1`: introduzca un `Buffer`.
  + `buffer2`: introduzca un `Buffer` diferente.
+ `Buffer.concat(list[, totalLength])`

  Concatenar varios `Buffer`. Devuelve `0` si no hay ninguno. Devuelve hasta `totalLength`.
  + `list`: introduzca una lista de `Buffer`. Tenga en cuenta que esto se truncará a `totalLength`.
  + `totalLength`: opcional. Introduzca un número entero sin signo. Utilice la suma de las instancias de `Buffer` de la lista si está en blanco.
+ `Buffer.from(array)`

  Cree un `Buffer` a partir de una matriz.
  + `array`: introduzca una matriz de bytes de `0` a `255`. 
+ `Buffer.from(arrayBuffer, byteOffset[, length]))`

  Cree una vista desde `arrayBuffer`, empezando por el desfase `byteOffset` con la longitud `length`.
  + `arrayBuffer`: introduzca una matriz de `Buffer`.
  + `byteOffset`: introduzca un número entero.
  + `length`: opcional. Introduzca un número entero.
+ `Buffer.from(buffer)`

  Cree una copia del `Buffer`.
  + `buffer`: introduzca un `Buffer`.
+ `Buffer.from(object[, offsetOrEncoding[, length]])`

  Cree un `Buffer` a partir de un objeto. Devuelve `Buffer.from(object.valueOf(), offsetOrEncoding, length)` si `valueOf()` no es igual al objeto.
  + `object`: introduzca un objeto.
  + `offsetOrEncoding`: opcional. Introduzca un número entero o una cadena de codificación.
  + `length`: opcional. Introduzca un número entero.
+ `Buffer.from(string[, encoding])`

  Cree un `Buffer` a partir de una cadena.
  + `string`: introduzca una cadena.
  + `encoding`: opcional. Introduzca una de las siguientes opciones: `utf8`, `hex`, `base64` o `base64url`. El valor predeterminado es `utf8`.
+ `Buffer.isBuffer(object)`

  Compruebe si `object` es un búfer. Devuelve `true` o `false`.
  + `object`: introduzca un objeto.
+ `Buffer.isEncoding(encoding)`

  Compruebe si `encoding` es compatible. Devuelve `true` o `false`.
  + `encoding`: opcional. Introduzca una de las siguientes opciones: `utf8`, `hex`, `base64` o `base64url`. El valor predeterminado es `utf8`.

El módulo proporciona los siguientes métodos de prototipo de búfer.
+ `Buffer.prototype.compare(target[, targetStart[, targetEnd[, sourceStart[, sourceEnd]]]])`

  Compare `Buffer` con el objetivo. Devuelve `0` si son iguales, `1` si `buffer` aparece primero o `-1` si `target` aparece primero.
  + `target`: introduzca un `Buffer`.
  + `targetStart`: opcional. Introduzca un número entero. El valor predeterminado es 0.
  + `targetEnd`: opcional. Introduzca un número entero. El valor predeterminado es la longitud del `target`.
  + `sourceStart`: opcional. Introduzca un número entero. El valor predeterminado es 0.
  + `sourceEnd`: opcional. Introduzca un número entero. El valor predeterminado es la longitud del `Buffer`.
+ `Buffer.prototype.copy(target[, targetStart[, sourceStart[, sourceEnd]]])`

  Copie el búfer a `target`.
  + `target`: introduzca un `Buffer` o una `Uint8Array`.
  + `targetStart`: opcional. Introduzca un número entero. El valor predeterminado es 0.
  + `sourceStart`: opcional. Introduzca un número entero. El valor predeterminado es 0.
  + `sourceEnd`: opcional. Introduzca un número entero. El valor predeterminado es la longitud del `Buffer`.
+ `Buffer.prototype.equals(otherBuffer)`

  Compare `Buffer` con `otherBuffer`. Devuelve `true` o `false`.
  + `otherBuffer`: introduzca una cadena.
+ `Buffer.prototype.fill(value[, offset[, end][, encoding])`

  Rellene `Buffer` con `value`.
  + `value`: introduzca una cadena, un `Buffer` o un número entero.
  + `offset`: opcional. Introduzca un número entero.
  + `end`: opcional. Introduzca un número entero.
  + `encoding`: opcional. Introduzca una de las siguientes opciones: `utf8`, `hex`, `base64` o `base64url`. El valor predeterminado es `utf8`.
+ `Buffer.prototype.includes(value[, byteOffset][, encoding])`

  Busque `value` en `Buffer`. Devuelve `true` o `false`.
  + `value`: introduzca una cadena, `Buffer`, `Uint8Array` o un número entero.
  + `byteOffset`: opcional. Introduzca un número entero.
  + `encoding`: opcional. Introduzca una de las siguientes opciones: `utf8`, `hex`, `base64` o `base64url`. El valor predeterminado es `utf8`.
+ `Buffer.prototype.indexOf(value[, byteOffset][, encoding])`

  Busque el primer `value` en el `Buffer`. Devuelve `index` si se encuentra; devuelve `-1` si no se encuentra.
  + `value`: introduzca una cadena, `Buffer`, Unit8Array o un número entero comprendido entre 0 y 255. 
  + `byteOffset`: opcional. Introduzca un número entero.
  + `encoding`: opcional. Introduzca una de las siguientes opciones si `value` es una cadena: `utf8`, `hex`, `base64`, `base64url`. El valor predeterminado es `utf8`.
+ `Buffer.prototype.lastIndexOf(value[, byteOffset][, encoding])`

  Busque el último `value` en el `Buffer`. Devuelve `index` si se encuentra; devuelve `-1` si no se encuentra.
  + `value`: introduzca una cadena, `Buffer`, Unit8Array o un número entero comprendido entre 0 y 255. 
  + `byteOffset`: opcional. Introduzca un número entero.
  + `encoding`: opcional. Introduzca una de las siguientes opciones si `value` es una cadena: `utf8`, `hex`, `base64`, `base64url`. El valor predeterminado es `utf8`.
+ `Buffer.prototype.readInt8(offset)`

  Lea `Int8` en `offset` desde `Buffer`.
  + `offset`: introduzca un número entero.
+ `Buffer.prototype.readIntBE(offset, byteLength)`

  Lea el `Int` como big-endian en `offset` desde `Buffer`.
  + `offset`: introduzca un número entero.
  + `byteLength`: opcional. Introduzca un número entero comprendido entre `1` y `6`.
+ `Buffer.prototype.readInt16BE(offset)`

  Lea el `Int16` como big-endian en `offset` desde `Buffer`.
  + `offset`: introduzca un número entero.
+ `Buffer.prototype.readInt32BE(offset)`

  Lea el `Int32` como big-endian en `offset` desde `Buffer`.
  + `offset`: introduzca un número entero.
+ `Buffer.prototype.readIntLE(offset, byteLength)`

  Lea el `Int` como little-endian en `offset` desde `Buffer`.
  + `offset`: introduzca un número entero.
  + `byteLength`: introduzca un número entero entre `1` y `6`.
+ `Buffer.prototype.readInt16LE(offset)`

  Lea el `Int16` como little-endian en `offset` desde `Buffer`.
  + `offset`: introduzca un número entero.
+ `Buffer.prototype.readInt32LE(offset)`

  Lea el `Int32` como little-endian en `offset` desde `Buffer`.
  + `offset`: introduzca un número entero.
+ `Buffer.prototype.readUInt8(offset)`

  Lea `UInt8` en `offset` desde `Buffer`.
  + `offset`: introduzca un número entero.
+ `Buffer.prototype.readUIntBE(offset, byteLength)`

  Lea el `UInt` como big-endian en `offset` desde `Buffer`.
  + `offset`: introduzca un número entero.
  + `byteLength`: introduzca un número entero entre `1` y `6`.
+ `Buffer.prototype.readUInt16BE(offset)`

  Lea el `UInt16` como big-endian en `offset` desde `Buffer`.
+ 
  + `offset`: introduzca un número entero.
+ `Buffer.prototype.readUInt32BE(offset)`

  Lea el `UInt32` como big-endian en `offset` desde `Buffer`.
  + `offset`: introduzca un número entero.
+ `Buffer.prototype.readUIntLE(offset, byteLength)`

  Lea el `UInt` como little-endian en `offset` desde `Buffer`.
  + `offset`: introduzca un número entero.
  + `byteLength`: introduzca un número entero entre `1` y `6`.
+ `Buffer.prototype.readUInt16LE(offset)`

  Lea el `UInt16` como little-endian en `offset` desde `Buffer`.
  + `offset`: introduzca un número entero.
+ `Buffer.prototype.readUInt32LE(offset)`

  Lea el `UInt32` como little-endian en `offset` desde `Buffer`.
  + `offset`: introduzca un número entero.
+ `Buffer.prototype.readDoubleBE([offset])`

  Lea un doble de 64 bits como big-endian en `offset` desde `Buffer`.
  + `offset`: opcional. Introduzca un número entero.
+ `Buffer.prototype.readDoubleLE([offset])`

  Lea un doble de 64 bits como little-endian en `offset` desde `Buffer`.
  + `offset`: opcional. Introduzca un número entero.
+ `Buffer.prototype.readFloatBE([offset])`

  Lea un flotante de 32 bits como big-endian en `offset` desde `Buffer`.
  + `offset`: opcional. Introduzca un número entero.
+ `Buffer.prototype.readFloatLE([offset])`

  Lea un flotante de 32 bits como little-endian en `offset` desde `Buffer`.
  + `offset`: opcional. Introduzca un número entero.
+ `Buffer.prototype.subarray([start[, end]])`

  Devuelve una copia de `Buffer` desplazada y recortada con un nuevo `start` y `end`.
  + `start`: opcional. Introduzca un número entero. El valor predeterminado es 0.
  + `end`: opcional. Introduzca un número entero. El valor predeterminado es la longitud del búfer.
+ `Buffer.prototype.swap16()`

  Cambie el orden de los bytes de la matriz del `Buffer`, tratándolo como una matriz de números de 16 bits. La longitud de `Buffer` debe ser divisible entre 2 o recibirá un error.
+ `Buffer.prototype.swap32()`

  Cambie el orden de los bytes de la matriz del `Buffer`, tratándolo como una matriz de números de 32 bits. La longitud de `Buffer` debe ser divisible entre 4 o recibirá un error.
+ `Buffer.prototype.swap64()`

  Cambie el orden de los bytes de la matriz del `Buffer`, tratándolo como una matriz de números de 64 bits. La longitud de `Buffer` debe ser divisible entre 8 o recibirá un error.
+ `Buffer.prototype.toJSON()`

  Devuelve `Buffer` como JSON. 
+ `Buffer.prototype.toString([encoding[, start[, end]]])`

  Convierte `Buffer`, de `start` a `end`, en una cadena codificada.
  + `encoding`: opcional. Introduzca una de las siguientes opciones: `utf8`, `hex`, `base64` o `base64url`. El valor predeterminado es `utf8`.
  + `start`: opcional. Introduzca un número entero. El valor predeterminado es 0.
  + `end`: opcional. Introduzca un número entero. El valor predeterminado es la longitud del búfer.
+ `Buffer.prototype.write(string[, offset[, length]][, encoding])`

  Escribe codificada la `string` en el `Buffer` si hay espacio, o una `string` truncada si no hay suficiente espacio.
  + `string`: introduzca una cadena.
  + `offset`: opcional. Introduzca un número entero. El valor predeterminado es 0.
  + `length`: opcional. Introduzca un número entero. El valor predeterminado es la longitud de la cadena.
  + `encoding`: opcional. Si lo desea, introduzca una de las siguientes opciones: `utf8`, `hex`, `base64` o `base64url`. El valor predeterminado es `utf8`.
+ `Buffer.prototype.writeInt8(value, offset, byteLength)`

  Escriba el `Int8` `value` de la `byteLength` en `offset` en `Buffer`.
  + `value`: introduzca un número entero.
  + `offset`: introduzca un número entero
  + `byteLength`: introduzca un número entero entre `1` y `6`.
+ `Buffer.prototype.writeIntBE(value, offset, byteLength)`

  Escriba un `value` en `offset` para el `Buffer`, usando big-endian.
  + `value`: introduzca un número entero.
  + `offset`: introduzca un número entero
  + `byteLength`: introduzca un número entero entre `1` y `6`.
+ `Buffer.prototype.writeInt16BE(value, offset, byteLength)`

  Escriba un `value` en `offset` para el `Buffer`, usando big-endian.
  + `value`: introduzca un número entero.
  + `offset`: introduzca un número entero
  + `byteLength`: introduzca un número entero entre `1` y `6`.
+ `Buffer.prototype.writeInt32BE(value, offset, byteLength)`

  Escriba un `value` en `offset` para el `Buffer`, usando big-endian.
  + `value`: introduzca un número entero.
  + `offset`: introduzca un número entero
  + `byteLength`: introduzca un número entero entre `1` y `6`.
+ `Buffer.prototype.writeIntLE(offset, byteLength)`

  Escriba un `value` en `offset` para el `Buffer`, usando little-endian.
  + `offset`: introduzca un número entero.
  + `byteLength`: introduzca un número entero entre `1` y `6`.
+ `Buffer.prototype.writeInt16LE(offset, byteLength)`

  Escriba un `value` en `offset` para el `Buffer`, usando little-endian.
  + `offset`: introduzca un número entero.
  + `byteLength`: introduzca un número entero entre `1` y `6`.
+ `Buffer.prototype.writeInt32LE(offset, byteLength)`

  Escriba un `value` en `offset` para el `Buffer`, usando little-endian.
  + `offset`: introduzca un número entero.
  + `byteLength`: introduzca un número entero entre `1` y `6`.
+ `Buffer.prototype.writeUInt8(value, offset, byteLength)`

  Escriba el `UInt8` `value` de la `byteLength` en `offset` en `Buffer`.
  + `value`: introduzca un número entero.
  + `offset`: introduzca un número entero
  + `byteLength`: introduzca un número entero entre `1` y `6`.
+ `Buffer.prototype.writeUIntBE(value, offset, byteLength)`

  Escriba un `value` en `offset` para el `Buffer`, usando big-endian.
  + `value`: introduzca un número entero.
  + `offset`: introduzca un número entero
  + `byteLength`: introduzca un número entero entre `1` y `6`.
+ `Buffer.prototype.writeUInt16BE(value, offset, byteLength)`

  Escriba un `value` en `offset` para el `Buffer`, usando big-endian.
  + `value`: introduzca un número entero.
  + `offset`: introduzca un número entero
  + `byteLength`: introduzca un número entero entre `1` y `6`.
+ `Buffer.prototype.writeUInt32BE(value, offset, byteLength)`

  Escriba un `value` en `offset` para el `Buffer`, usando big-endian.
  + `value`: introduzca un número entero.
  + `offset`: introduzca un número entero
  + `byteLength`: introduzca un número entero entre `1` y `6`.
+ `Buffer.prototype.writeUIntLE(value, offset, byteLength)`

  Escriba un `value` en `offset` para el `Buffer`, usando little-endian.
  + `value`: introduzca un número entero.
  + `offset`: introduzca un número entero
  + `byteLength`: introduzca un número entero entre `1` y `6`.
+ `Buffer.prototype.writeUInt16LE(value, offset, byteLength)`

  Escriba un `value` en `offset` para el `Buffer`, usando little-endian.
  + `value`: introduzca un número entero.
  + `offset`: introduzca un número entero
  + `byteLength`: introduzca un número entero entre `1` y `6`.
+ `Buffer.prototype.writeUInt32LE(value, offset, byteLength)`

  Escriba un `value` en `offset` para el `Buffer`, usando little-endian.
  + `value`: introduzca un número entero.
  + `offset`: introduzca un número entero
  + `byteLength`: introduzca un número entero entre `1` y `6`.
+ `Buffer.prototype.writeDoubleBE(value, [offset])`

  Escriba un `value` en `offset` para el `Buffer`, usando big-endian.
  + `value`: introduzca un número entero.
  + `offset`: opcional. Introduzca un número entero. El valor predeterminado es 0.
+ `Buffer.prototype.writeDoubleLE(value, [offset])`

  Escriba un `value` en `offset` para el `Buffer`, usando little-endian.
  + `value`: introduzca un número entero.
  + `offset`: opcional. Introduzca un número entero. El valor predeterminado es 0.
+ `Buffer.prototype.writeFloatBE(value, [offset])`

  Escriba un `value` en `offset` para el `Buffer`, usando big-endian.
  + `value`: introduzca un número entero.
  + `offset`: opcional. Introduzca un número entero. El valor predeterminado es 0.
+ `Buffer.prototype.writeFloatLE(value, [offset])`

  Escriba un `value` en `offset` para el `Buffer`, usando little-endian.
  + `value`: introduzca un número entero.
  + `offset`: opcional. Introduzca un número entero. El valor predeterminado es 0.

Se admiten los siguientes métodos de instancia:
+ `buffer[index]`

  Obtenga y establezca el octeto (byte) en `index` en `Buffer`. 
  + Obtenga un número de `0` a `255`. O establezca un número de `0` a `255`.

Se admiten las siguientes propiedades de instancia:
+ `buffer`

  Obtenga el objeto `ArrayBuffer` para el búfer. 
+ `byteOffset`

  Obtenga el `byteOffset` del objeto `Arraybuffer` del búfer.
+ `length`

  Obtenga el recuento de bytes del búfer.

**nota**  
Todos los métodos del módulo del búfer son nuevos en el tiempo de ejecución 2.0 de JavaScript.

### Cadena de consulta
<a name="writing-functions-javascript-features-builtin-modules-query-string-20"></a>

**nota**  
El objeto [ de evento de CloudFront Functions ](functions-event-structure.md) analiza automáticamente las cadenas de consulta de URL. Eso significa que en la mayoría de los casos no necesita usar este módulo.

El módulo de cadena de consulta (`querystring`) proporciona métodos para analizar y dar formato a las cadenas de consulta de URL. Puede cargar el módulo mediante `require('querystring')`. El módulo proporciona los siguientes métodos.

`querystring.escape(string)`  
La URL codifica la `string` dada y devuelve una cadena de consulta escapada. El método es utilizado por `querystring.stringify()` y no debe utilizarse directamente.

`querystring.parse(string[, separator[, equal[, options]]])`  
Analiza una cadena de consulta (`string`) y devuelve un objeto.  
El parámetro `separator` es una subcadena para delimitar pares de claves y valores en la cadena de consulta. De forma predeterminada, es `&`.  
El parámetro `equal` es una subcadena para delimitar claves y valores en la cadena de consulta. De forma predeterminada, es `=`.  
El parámetro `options` es un objeto con las siguientes claves:    
`decodeURIComponent function`  
Una función para decodificar caracteres codificados por porcentaje en la cadena de consulta. De forma predeterminada, es `querystring.unescape()`.  
`maxKeys number`  
El número máximo de claves que se analizan. De forma predeterminada, es `1000`. Utilice un valor de `0` para eliminar las limitaciones del recuento de claves.
De forma predeterminada, se supone que los caracteres codificados con porcentaje dentro de la cadena de consulta utilizan la codificación UTF-8. Las secuencias UTF-8 no válidas se reemplazan por el carácter de reemplazo `U+FFFD`.  
Por ejemplo, para la siguiente cadena de consulta:  

```
'name=value&abc=xyz&abc=123'
```
El valor de retorno de `querystring.parse()` es:  

```
{
name: 'value',
abc: ['xyz', '123']
}
```
`querystring.decode()` es un alias de `querystring.parse()`.

`querystring.stringify(object[, separator[, equal[, options]]])`  
Serializa un `object` y devuelve una cadena de consulta.  
El parámetro `separator` es una subcadena para delimitar pares de claves y valores en la cadena de consulta. De forma predeterminada, es `&`.  
El parámetro `equal` es una subcadena para delimitar claves y valores en la cadena de consulta. De forma predeterminada, es `=`.  
El parámetro `options` es un objeto con las siguientes claves:    
`encodeURIComponent function`  
La función que se va a utilizar para convertir caracteres no seguros de URL a codificación porcentual en la cadena de consulta. De forma predeterminada, es `querystring.escape()`.
De forma predeterminada, los caracteres que requieren codificación porcentual dentro de la cadena de consulta se codifican como UTF-8. Para utilizar una codificación diferente, especifique la opción `encodeURIComponent`.  
Por ejemplo, el siguiente código:  

```
querystring.stringify({ name: 'value', abc: ['xyz', '123'], anotherName: '' });
```
El valor de retorno es:  

```
'name=value&abc=xyz&abc=123&anotherName='
```
`querystring.encode()` es un alias de `querystring.stringify()`.

`querystring.unescape(string)`  
Decodifica caracteres codificados con porcentaje de URL en la `string` dada y devuelve una cadena de consulta sin escapar. Este método es utilizado por `querystring.parse()` y no debe utilizarse directamente.

### Cripto
<a name="writing-functions-javascript-features-builtin-modules-crypto-20"></a>

El módulo criptográfico (`crypto`) proporciona ayudantes de código de autenticación de mensajes basado en hash (HMAC) y hashing estándar. Puede cargar el módulo mediante `require('crypto')`.

**Métodos de hashing**

`crypto.createHash(algorithm)`  
Crea y devuelve un objeto hash que puede utilizar para generar resúmenes hash mediante el algoritmo dado: `md5`, `sha1` o `sha256`.

`hash.update(data)`  
Actualiza el contenido hash con los dado `data`.

`hash.digest([encoding])`  
Calcula el resumen de todos los datos pasados con `hash.update()`. La codificación puede ser `hex`, `base64` o `base64url`.

**Métodos HMAC**

`crypto.createHmac(algorithm, secret key)`  
Crea y devuelve un objeto HMAC que utiliza el `algorithm` y `secret key` dados. El algoritmo puede ser `md5`, `sha1` o `sha256`.

`hmac.update(data)`  
Actualiza el contenido de HMAC con los dado `data`.

`hmac.digest([encoding])`  
Calcula el resumen de todos los datos pasados con `hmac.update()`. La codificación puede ser `hex`, `base64` o `base64url`.

## Características restringidas
<a name="writing-functions-javascript-features-restricted-features-20"></a>

Las siguientes características de lenguaje JavaScript no se admiten o están restringidas debido a cuestiones de seguridad.

**Evaluación dinámica de código**  
No se admite la evaluación dinámica de código. Si se intenta, los constructores `eval()` y `Function` arrojan un error. Por ejemplo, `const sum = new Function('a', 'b', 'return a + b')` arroja un error.

**Temporizadores**  
No se admiten las funciones `setTimeout()`, `setImmediate()` y `clearTimeout()`. No hay nada para posponer o producir dentro de una ejecución de función. La función debe ejecutarse de manera sincrónica hasta finalizar.

**Fecha y marcas temporales**  
Por razones de seguridad, no hay acceso a temporizadores de alta resolución. Todos los métodos `Date` para consultar la hora actual siempre devuelven el mismo valor durante la vida útil de una sola función ejecutada. La marca temporal devuelta es la hora en que la función comenzó a ejecutarse. Por eso, no puede medir el tiempo transcurrido en la función.

**Acceso al sistema de archivos**  
No hay acceso al sistema de archivos. Por ejemplo, no hay ningún módulo `fs` para el acceso al sistema de archivos como lo hay en Node.js.

**Acceso al proceso**  
No hay acceso al proceso. Por ejemplo, no hay ningún objeto global `process` para procesar el acceso a la información como lo hay en Node.js.

**Variables de entorno**  
No hay acceso a las variables de entorno. En su lugar, puede utilizar CloudFront KeyValueStore para crear un almacén de datos centralizado de pares clave-valor para las CloudFront Functions. CloudFront KeyValueStore habilita las actualizaciones dinámicas de los datos de configuración sin necesidad de implementar cambios en el código. Para obtener más información, consulte [Amazon CloudFront KeyValueStore](kvs-with-functions.md).

**Acceso a la red**  
No se admiten las llamadas de red. Por ejemplo, no se admite XHR, HTTP (S) ni socket.

# Métodos auxiliares para almacenes de clave-valor
<a name="functions-custom-methods"></a>

**nota**  
Las llamadas de métodos auxiliares del almacén de valores de claves desde CloudFront Functions no desencadenan un evento de datos de AWS CloudTrail. Estos eventos no se registran en el historial de eventos de CloudTrail. Para obtener más información, consulte [Registro de llamadas a la API de Amazon CloudFront con AWS CloudTrail](logging_using_cloudtrail.md).

Esta sección se aplica si utiliza el [Almacén de clave-valor de CloudFront](kvs-with-functions.md) para incluir claves-valores en la función que cree. CloudFront Functions tiene un módulo que proporciona tres métodos auxiliares para leer valores del almacén de clave-valor.

Para utilizar este módulo en el código de la función, asegúrese de haber [asociado un almacén de clave-valor](kvs-with-functions-associate.md) a la función. 

A continuación, incluya las siguientes instrucciones en las primeras líneas del código de la función:

```
import cf from 'cloudfront';
const kvsHandle = cf.kvs();
```



## `get()`Método de
<a name="functions-custom-methods-get"></a>

Utilice este método para devolver el valor de clave del nombre de clave que especifique. 

**Solicitud**

```
get("key", options);
```
+ `key`: el nombre de la clave cuyo valor desea recuperar
+ `options`: hay una opción, `format`. Garantiza que la función analice correctamente los datos. Valores posibles:
  + `string`: (predeterminado) codificado en UTF8
  + `json` 
  + `bytes`: búfer de datos binarios sin procesar

**Ejemplo de solicitud**

```
const value = await kvsHandle.get("myFunctionKey", { format: "string"});
```

**Respuesta**

La respuesta es una `promise` que se resuelve en un valor en el formato solicitado mediante el uso de `options`. De forma predeterminada, el valor se devuelve como una cadena.

### Gestión de errores
<a name="error-handling-exists-method"></a>

El método `get()` devolverá un error cuando la clave que ha solicitado no exista en el almacén de clave-valor asociado. Para administrar este caso de uso, puede agregar un bloque `try` y `catch` al código.

**aviso**  
El uso de combinadores de promesas (por ejemplo, `Promise.all`, `Promise.any`) y métodos de cadena de promesas (por ejemplo, `then` y `catch`) puede requerir un uso elevado de la memoria de la función. Si la función supera la cuota de [memoria máxima de la función](cloudfront-limits.md#limits-functions), no se ejecutará. Para evitar este error, le recomendamos que utilice la sintaxis `await` de forma secuencial o en bucles para solicitar varios valores.  
**Ejemplo**  

```
var value1 = await kvs.get('key1');
var value2 = await kvs.get('key2');
```
Actualmente, el uso de combinadores de promesas para obtener varios valores no mejorará el rendimiento, como en el siguiente ejemplo.  

```
var values = await Promise.all([kvs.get('key1'), kvs.get('key2'),]);
```

## `exists()`Método de
<a name="functions-custom-methods-exists"></a>

Utilice este método para identificar si la clave existe o no en el almacén de clave-valor.

**Solicitud**

```
exists("key");
```

**Ejemplo de solicitud**

```
const exist = await kvsHandle.exists("myFunctionkey");
```

**Respuesta**

La respuesta es una `promise` que devuelve un valor booleano (`true` o `false`). Este valor especifica si la clave existe o no en el almacén de clave-valor.

## `meta()`Método de
<a name="functions-custom-methods-meta"></a>

Utilice este método para devolver metadatos sobre el almacén de clave-valor.

**Solicitud**

```
meta();
```

**Ejemplo de solicitud**

```
const meta = await kvsHandle.meta();
```

**Respuesta**

La respuesta es una `promise` que se resuelve en un objeto con las siguientes propiedades:
+ `creationDateTime`: la fecha y hora en formato ISO 8601 de creación del almacén de clave-valor.
+ `lastUpdatedDateTime`: la fecha y hora en formato ISO 8601 de última sincronización del almacén de clave-valor desde el origen. El valor no incluye el tiempo de propagación hasta la periferia.
+ `keyCount`: el número total de claves del KVS tras la última sincronización desde el origen.

**Ejemplo de respuesta**

```
{keyCount:3,creationDateTime:2023-11-30T23:07:55.765Z,lastUpdatedDateTime:2023-12-15T03:57:52.411Z}
```

# Métodos auxiliares para la modificación del origen
<a name="helper-functions-origin-modification"></a>

Esta sección se aplica si actualiza o cambia dinámicamente el origen utilizado en la solicitud dentro del código de CloudFront Functions. Solo puede actualizar el origen cuando el *espectador solicite* CloudFront Functions. CloudFront Functions tiene un módulo que proporciona métodos auxiliares para actualizar o cambiar el origen de forma dinámica.

Para usar este módulo, cree una función de CloudFront con tiempo de ejecución 2.0 de JavaScript e incluya la siguiente instrucción en la primera línea del código de la función:

```
import cf from 'cloudfront';
```

Para obtener más información, consulte [Características del tiempo de ejecución 2.0 de JavaScript para CloudFront Functions](functions-javascript-runtime-20.md).

**nota**  
Las páginas de la API de pruebas y la consola de pruebas no comprueban si se ha producido una modificación del origen. Sin embargo, las pruebas garantizan que el código de la función se ejecute sin errores.

## Elección entre CloudFront Functions y Lambda@Edge
<a name="origin-modification-considerations"></a>

Puede actualizar sus orígenes mediante CloudFront Functions o Lambda@Edge.

Cuando se utiliza CloudFront Functions para actualizar los orígenes, se utiliza el desencadenador de eventos de *solicitud del espectador*, lo que significa que esta lógica se ejecutará en todas las solicitudes cuando se utilice esta función. Cuando se utiliza Lambda@Edge, las funciones de actualización del origen se encuentran en el desencadenador de eventos de *solicitud de origen*, lo que significa que esta lógica solo se ejecuta cuando se pierde memoria caché.

La elección depende en gran medida de la carga de trabajo y del uso actual de CloudFront Functions y Lambda@Edge en sus distribuciones. Las siguientes consideraciones pueden ayudarlo a decidir si debe utilizar CloudFront Functions o Lambda@Edge para actualizar sus orígenes.

CloudFront Functions es más útil en las siguientes situaciones:
+ Cuando sus solicitudes son dinámicas (es decir, no se pueden almacenar en caché) y siempre van al origen. CloudFront Functions ofrece un mejor rendimiento y un coste total más bajo.
+ Si tiene una función de CloudFront de solicitud de espectador existente que se ejecutará en cada solicitud, puede añadir la lógica de actualización del origen a la función existente.

Para usar CloudFront Functions para actualizar los orígenes, consulte los métodos auxiliares en los temas siguientes.

Lambda@Edge es más útil en las siguientes situaciones:
+ Cuando tiene contenido que se puede almacenar en caché con gran frecuencia, Lambda@Edge puede ser más rentable, ya que solo se ejecuta cuando se pierde memoria caché, mientras que CloudFront Functions se ejecuta en todas las solicitudes.
+ Si tiene una función de Lambda@Edge de solicitud de origen existente, puede añadir la lógica de actualización del origen a la función existente.
+ Cuando la lógica de actualización de origen requiere obtener datos de orígenes de datos de terceros, como Amazon DynamoDB o Amazon S3.

Para obtener más información sobre Lambda@Edge, consulte [Personalización en la periferia con Lambda@Edge](lambda-at-the-edge.md).

## Método updateRequestOrigin()
<a name="update-request-origin-helper-function"></a>

Use el método `updateRequestOrigin()` para actualizar la configuración de origen de una solicitud. Puede usar este método para actualizar las propiedades de origen existentes para los orígenes que ya están definidos en su distribución o para definir un nuevo origen para la solicitud. Para ello, especifique las propiedades que desea cambiar.

**importante**  
Cualquier configuración que no especifique en `updateRequestOrigin()` heredará la *misma configuración* de la configuración del origen existente.

El origen establecido por el método `updateRequestOrigin()` puede ser cualquier punto de conexión HTTP y no es necesario que sea un origen existente en la distribución de CloudFront.

**Notas**  
Si está actualizando un origen que forma parte de un grupo de origen, solo se actualiza el *origen principal* del grupo de origen. El origen secundario no cambia. Cualquier código de respuesta del origen modificado que coincida con los criterios de conmutación por error desencadenará una conmutación por error al origen secundario.
Si va a cambiar el tipo de origen y tiene habilitado el OAC, asegúrese de que el tipo de origen en `originAccessControlConfig` coincida con el nuevo tipo de origen.
No puede usar el método `updateRequestOrigin()` para actualizar los [orígenes de la VPC](private-content-vpc-origins.md). Se producirá un error en la solicitud.

**Solicitud**

```
updateRequestOrigin({origin properties})
```

Las `origin properties` pueden incluir lo siguiente:

**domainName (opcional)**  
El nombre de dominio del origen. Si no se proporciona, se utiliza en su lugar el nombre de dominio del origen asignado.    
**Para orígenes personalizados**  
Especifique un nombre de dominio DNS, como `www.example.com`. El nombre de dominio no puede incluir dos puntos (`:`) ni puede ser una dirección IP. El nombre de dominio puede tener una longitud de hasta 253 caracteres.  
**Para orígenes de S3**  
Especifique el nombre de dominio DNS del bucket de Amazon S3, como `amzn-s3-demo-bucket.s3.eu-west-1.amazonaws.com`. El nombre puede tener una longitud de hasta 128 caracteres y debe escribirse en letras minúsculas.

**hostHeader (opcional, para orígenes personalizados que no sean de S3)**  
El encabezado del host que se utilizará al realizar la solicitud al origen. Si no se proporciona, se utiliza el valor del parámetro domainName. Si no se proporciona ningún parámetro de encabezado de host ni de nombre de dominio, se utiliza el nombre de dominio del origen asignado o el encabezado de host de la solicitud entrante si la política de reenvío al origen (FTO) incluye el host. El encabezado del host no puede incluir dos puntos (`:`) ni puede ser una dirección IP. El encabezado del host puede tener una longitud de hasta 253 caracteres.

**originPath (opcional)**  
La ruta de directorio del servidor donde la solicitud debería encontrar el contenido. La ruta debe comenzar con una barra diagonal (/), pero no debe terminar con una. Por ejemplo, no debería terminar con `example-path/`. Si no se proporciona, se utiliza la ruta de origen del origen asignado.    
**Para orígenes personalizados**  
La ruta debe estar codificada en URL y tener una longitud máxima de 255 caracteres.

**customHeaders (opcional)**  
Si desea incluir encabezados personalizados con la solicitud, especifique un nombre de encabezado y un par de valores para cada uno de ellos. El formato es diferente al de los encabezados de solicitud y respuesta de la estructura de eventos. Use la siguiente sintaxis de pares clave-valor:  

```
{"key1": "value1", "key2": "value2", ...}
```
No puede agregar encabezados que no estén permitidos y un encabezado con el mismo nombre tampoco puede estar presente en la solicitud entrante `headers`. El nombre del encabezado debe estar en minúsculas en el código de la función. Cuando CloudFront Functions convierte el objeto de evento de nuevo en una solicitud HTTP, la primera letra de cada palabra en los nombres de encabezados se escribe en mayúsculas, y las palabras se separan con guiones.  
Por ejemplo, si el código de la función agrega un encabezado llamado `example-header-name`, CloudFront lo convierte en `Example-Header-Name` en la solicitud HTTP. Para obtener más información, consulte [Encabezados personalizados que CloudFront no puede agregar a solicitudes de origen](add-origin-custom-headers.md#add-origin-custom-headers-denylist) y [Restricciones en funciones de borde](edge-functions-restrictions.md).  
Si no se proporciona, se utilizará cualquier encabezado personalizado del origen asignado.

**connectionAttempts (opcional)**  
El número de veces que CloudFront intenta conectarse al origen. El valor mínimo es 1 y el máximo, 3. Si no se proporciona, se utilizarán los intentos de conexión del origen asignado.

**originShield (opcional)**  
Esto habilita o actualiza Origin Shield de CloudFront. El uso de Origin Shield puede ayudar a reducir la carga en el origen. Para obtener más información, consulte [Uso de Amazon CloudFront Origin Shield](origin-shield.md). Si no se proporciona, se utiliza la configuración de Origin Shield del origen asignado.    
**enabled (obligatorio)**  
Expresión booleana para activar o desactivar Origin Shield. Acepta un valor `true` o `false`.  
**region (obligatorio cuando está habilitado)**  
La Región de AWS para Origin Shield. Especifique la Región de AWS que tiene la latencia más baja en su origen. Use el código de la región, no el nombre de la región. Por ejemplo, use `us-east-2` para especificar la región Este de EE. UU. (Ohio).  
Cuando habilite Origin Shield de CloudFront, debe especificar la Región de AWS para Origin Shield. Para ver una lista de las Regiones de AWS disponibles y ayudarlo a elegir la mejor región para su origen, consulte [Elección de la región de AWS para Origin Shield](origin-shield.md#choose-origin-shield-region).

**originAccessControlConfig (opcional)**  
El identificador único de un control de acceso de origen (OAC) para este origen. Esto solo se usa cuando el origen admite un OAC de CloudFront, como Amazon S3, las URL de funciones de Lambda, MediaStore y MediaPackage V2. Si no se proporciona, se utiliza la configuración de OAC del origen asignado.  
Esto no admite la identidad de acceso de origen (OAI) heredada. Para obtener más información, consulte [Restricción del acceso a un origen de AWS](private-content-restricting-access-to-origin.md).    
**enabled (obligatorio)**  
Expresión booleana para activar o desactivar OAC. Acepta un valor `true` o `false`.  
**signingBehavior (obligatorio cuando está habilitado)**  
Especifica qué solicitudes firma CloudFront (agrega información de autenticación). Especifique `always` para el caso de uso más común. Para obtener más información, consulte [Configuración avanzada para el control de acceso de origen](private-content-restricting-access-to-s3.md#oac-advanced-settings-s3).   
Este campo puede tener uno de los siguientes valores:  
+ `always`: CloudFront firma todas las solicitudes de origen y sobrescribe el encabezado `Authorization` de la solicitud del lector, si existe.
+ `never`: CloudFront no firma ninguna solicitud de origen. Este valor desactiva el control de acceso de origen para el origen.
+ `no-override`: si la solicitud del espectador no contiene el encabezado `Authorization`, CloudFront firma la solicitud de origen. Si la solicitud del espectador contiene el encabezado `Authorization`, CloudFront no firma la solicitud de origen y, en cambio, pasa el encabezado `Authorization` de la solicitud del espectador.
**aviso**  
Para pasar el encabezado `Authorization` de la solicitud del espectador, debe agregarlo a una política de solicitud de origen para todos los comportamientos de caché que utilizan los orígenes asociados a este control de acceso de origen. Para obtener más información, consulte [Control de las solicitudes de origen con una política](controlling-origin-requests.md).  
**signingProtocol (obligatorio cuando está habilitado)**  
El protocolo de firma del OAC, que determina cómo CloudFront firma (autentica) las solicitudes. El único valor válido es `sigv4`.  
**originType (obligatorio cuando está habilitado)**  
El tipo de origen de este OAC. Los valores válidos son `s3`, `mediapackagev2`, `mediastore` y `lambda`. 

**timeouts (opcional)**  
Tiempos de espera en los que puede especificar durante cuánto tiempo CloudFront debe intentar esperar a que los orígenes respondan o envíen datos. Si no se proporciona, se utiliza la configuración de tiempo de espera del origen asignado.   
A menos que se especifique lo contrario, estos tiempos de espera son compatibles tanto con orígenes personalizados como con orígenes de Amazon S3.   
**readTimeout (opcional)**  
`readTimeout` se aplica a los dos valores siguientes:  
+ Tiempo (en segundos) que CloudFront espera una respuesta después de enviar una solicitud al origen.
+ Tiempo (en segundos) que CloudFront espera después de recibir el paquete de una respuesta desde el origen y antes de recibir el paquete siguiente. 
El tiempo de espera mínimo es 1 segundo; el máximo es 120 segundos. Para obtener más información, consulte [Tiempo de espera de respuesta](DownloadDistValuesOrigin.md#DownloadDistValuesOriginResponseTimeout).  
**responseCompletionTimeout (opcional)**  
El tiempo (en segundos) que una solicitud de CloudFront al origen puede permanecer abierta y esperar una respuesta. Si en ese tiempo no se recibe la respuesta completa del origen, CloudFront finaliza la conexión.  
El valor de `responseCompletionTimeout` debe ser igual o mayor que el valor para `readTimeout`. Para obtener más información, consulte [Tiempo de espera de finalización de la respuesta](DownloadDistValuesOrigin.md#response-completion-timeout).  
**keepAliveTimeout (opcional)**  
Este tiempo de espera solo se aplica a los orígenes personalizados, no a los orígenes de Amazon S3. (Las configuraciones de origen S3 omitirán esta configuración).   
`keepAliveTimeout` especifica el tiempo que CloudFront debería intentar mantener la conexión con el origen después de recibir el último paquete de la respuesta. El tiempo de espera mínimo es 1 segundo; el máximo es 120 segundos. Para obtener más información, consulte [Tiempo de espera de keep-alive (solo orígenes personalizados y de VPC)](DownloadDistValuesOrigin.md#DownloadDistValuesOriginKeepaliveTimeout).  
**connectionTimeout (opcional)**  
Número de segundos que espera CloudFront al intentar establecer una conexión con el origen. El tiempo de espera mínimo es 1 segundo; el máximo es 10 segundos. Para obtener más información, consulte [Tiempo de espera de conexión](DownloadDistValuesOrigin.md#origin-connection-timeout).

**customOriginConfig (opcional)**  
Se utiliza `customOriginConfig` para especificar la configuración de conexión para los orígenes que *no* son un bucket de Amazon S3. Hay una excepción: puede especificar esta configuración si el bucket de S3 está configurado con alojamiento de sitios web estáticos. (Otros tipos de configuraciones de bucket de S3 ignorarán esta configuración). Si no se proporciona `customOriginConfig`, se utiliza la configuración del origen asignado.    
**port (obligatorio)**  
El puerto HTTP que CloudFront utiliza para conectarse al origen. Especifique el puerto HTTP que escucha el origen.   
**protocol (obligatorio)**  
Especifica el protocolo (HTTP o HTTPS) que CloudFront utiliza para conectarse al origen. Los valores válidos son los siguientes:  
+ `http`: CloudFront utiliza siempre HTTP para conectarse al origen
+ `https`: CloudFront utiliza siempre HTTPS para conectarse al origen  
**sslProtocols (obligatorio)**  
Una lista que especifica el protocolo SSL/TLS mínimo que CloudFront utiliza al conectarse a su origen a través de HTTPS. Los valores válidos son `SSLv3`, `TLSv1`, `TLSv1.1` y `TLSv1.2`. Para obtener más información, consulte [Protocolo SSL mínimo del origen](DownloadDistValuesOrigin.md#DownloadDistValuesOriginSSLProtocols).  
**ipAddressType (opcional)**  
Especifica el tipo de dirección IP que CloudFront utiliza para conectarse al origen. Los valores válidos son `ipv4`, `ipv6` y `dualstack`. Los cambios de `ipAddressType` solo se admiten cuando también se está cambiando la propiedad de `domainName`.

**sni (opcional, para orígenes personalizados que no sean de S3)**  
La indicación de nombre de servidor (SNI) es una extensión del protocolo seguridad de la capa de transporte (TLS) mediante el cual un cliente indica el nombre de host al que intenta conectarse al inicio del proceso de establecimiento de comunicación de TLS. Este valor debe coincidir con un nombre común de un certificado TLS del servidor de origen. De lo contrario, el servidor de origen puede generar un error.   
Si no se proporciona, se utiliza el valor del parámetro `hostHeader`. Si no se proporciona el encabezado del host, se utiliza el valor del parámetro `domainName`.  
Si no se proporciona ningún parámetro de encabezado de host ni de nombre de dominio, se utiliza el nombre de dominio del origen asignado o el encabezado de host de la solicitud entrante si la política de reenvío al origen (FTO) incluye el host. La SNI no puede incluir dos puntos (`:`) ni puede ser una dirección IP. La SNI puede tener hasta 253 caracteres.

**allowedCertificateNames (opcional, para orígenes personalizados que no sean de S3)**  
Puede incluir una lista de nombres de certificados válidos que CloudFront utilizará para validar la coincidencia del dominio con el certificado TLS del servidor de origen durante el establecimiento de comunicación de TLS con el servidor de origen. Este campo espera una matriz de nombres de dominio válidos y puede incluir dominios comodín, como `*.example.com`.   
Puede especificar hasta 20 nombres de certificado permitidos. Cada nombre de certificado puede tener hasta 64 caracteres.

**Example : actualización al origen de la solicitud de Amazon S3**  
El siguiente ejemplo cambia el origen de la solicitud del espectador a un bucket de S3, activa el OAC y restablece los encabezados personalizados enviados al origen.  

```
cf.updateRequestOrigin({
    "domainName" : "amzn-s3-demo-bucket-in-us-east-1.s3.us-east-1.amazonaws.com",
    "originAccessControlConfig": {
        "enabled": true,
        "signingBehavior": "always",
        "signingProtocol": "sigv4",
        "originType": "s3"
    },
    // Empty object resets any header configured on the assigned origin
    "customHeaders": {}
});
```

**Example : actualización al origen de la solicitud del equilibrador de carga de aplicación**  
El siguiente ejemplo cambia el origen de la solicitud del espectador a un origen de equilibrador de carga de aplicación y establece un encabezado personalizado y tiempos de espera.  

```
cf.updateRequestOrigin({
    "domainName" : "example-1234567890.us-east-1.elb.amazonaws.com",
    "timeouts": {
        "readTimeout": 30,
        "connectionTimeout": 5
    },
    "customHeaders": {
        "x-stage": "production",
        "x-region": "us-east-1"
    }
});
```

**Example : actualización al origen con Origin Shield activado**  
En el siguiente ejemplo, el origen de la distribución tiene Origin Shield activado. El código de función actualiza solo el nombre de dominio utilizado para el origen y omite todos los demás parámetros opcionales. En este caso, Origin Shield seguirá utilizándose con el nombre de dominio del origen modificado porque los parámetros de Origin Shield no se actualizaron.  

```
cf.updateRequestOrigin({
    "domainName" : "www.example.com"
});
```

**Example - Actualización del encabezado del host, la SNI y los nombres de los certificados permitidos**  
En la mayoría de los casos de uso, no necesitará usar este tipo de modificación en las solicitudes que se dirijan al origen. Estos parámetros no deberían usarse a menos que entienda el impacto de cambiar estos valores. 
En el siguiente ejemplo, se cambia al origen el nombre de dominio, el encabezado del host, la SNI y los certificados permitidos en la solicitud.   

```
cf.updateRequestOrigin({ 
    "domainName": "www.example.com", 
    "hostHeader": "test.example.com", 
    "sni": "test.example.net", 
    "allowedCertificateNames": ["*.example.com", "*.example.net"],
});
```

## Método selectRequestOriginById()
<a name="select-request-origin-id-helper-function"></a>

Utilice `selectRequestOriginById()` para actualizar un origen existente mediante la selección un origen diferente que ya esté configurado en la distribución. Este método utiliza toda la configuración definida por el origen actualizado.

Este método solo acepta orígenes que ya estén definidos en la misma distribución utilizada al ejecutar la función. Se hace referencia a los orígenes por el ID de origen, que es el nombre del origen que se ha definido al configurar el origen.

Si tiene un origen de VPC configurado en la distribución, puede utilizar este método para actualizar el origen al origen de VPC. Para obtener más información, consulte [Restricción del acceso con orígenes de la VPC](private-content-vpc-origins.md).

**Notas**  
La función `selectRequestOriginById()` no puede seleccionar un origen que tenga habilitado TLS mutua (origen). Si se intenta seleccionar un origen habilitado de TLS mutua (origen) mediante esta función, se producirá un error de validación.
Si su caso de uso requiere una selección de origen dinámica con TLS mutua (origen), utilice `updateRequestOrigin()` en su lugar, asegurándose de que todos los orígenes de destino utilicen el mismo certificado de cliente.

**Solicitud**

```
cf.selectRequestOriginById(origin_id, {origin_overrides})
```

En el ejemplo anterior, `origin_id` es una cadena que apunta al nombre de un origen en la distribución que está ejecutando la función. El parámetro `origin_overrides ` puede contener lo siguiente:

**hostHeader (opcional, para orígenes personalizados que no sean de S3)**  
El encabezado del host que se utilizará al realizar la solicitud al origen. Si no se proporciona, se utiliza el valor del parámetro `domainName`.   
Si no se proporciona ningún parámetro de encabezado de host ni de nombre de dominio, se utiliza el nombre de dominio del origen asignado o el encabezado de host de la solicitud entrante si la política de reenvío al origen (FTO) incluye el host. El encabezado del host no puede incluir dos puntos (`:`) ni puede ser una dirección IP. El encabezado del host puede tener una longitud de hasta 253 caracteres.

**sni (opcional, para orígenes personalizados que no sean de S3)**  
La indicación de nombre de servidor (SNI) es una extensión del protocolo seguridad de la capa de transporte (TLS) mediante el cual un cliente indica el nombre de host al que intenta conectarse al inicio del proceso de establecimiento de comunicación de TLS. Este valor debe coincidir con un nombre común de un certificado TLS del servidor de origen. De lo contrario, el servidor de origen puede generar un error.   
Si no se proporciona, se utiliza el valor del parámetro `hostHeader`. Si no se proporciona el encabezado del host, se utiliza el valor del parámetro `domainName`.   
Si no se proporciona ningún parámetro de encabezado de host ni de nombre de dominio, se utiliza el nombre de dominio del origen asignado o el encabezado de host de la solicitud entrante si la política de reenvío al origen (FTO) incluye el host. La SNI no puede incluir dos puntos (`:`) ni puede ser una dirección IP. La SNI puede tener hasta 253 caracteres.

**allowedCertificateNames (opcional, para orígenes personalizados que no sean de S3)**  
Puede incluir una lista de nombres de certificados válidos que CloudFront utilizará para validar la coincidencia del dominio con el certificado TLS del servidor de origen durante el establecimiento de comunicación de TLS con el servidor de origen. Este campo espera una matriz de nombres de dominio válidos y puede incluir dominios comodín, como `*.example.com`.   
Puede especificar hasta 20 nombres de certificado permitidos. Cada nombre de certificado puede tener hasta 64 caracteres.

**Solicitud**

```
selectRequestOriginById(origin_id)
```

En el ejemplo anterior, `origin_id` es una cadena que apunta al nombre de un origen en la distribución que está ejecutando la función.

**Example : selección del origen de solicitud de Amazon S3**  
El siguiente ejemplo selecciona el origen denominado `amzn-s3-demo-bucket-in-us-east-1` de la lista de orígenes asociados a la distribución y aplica los ajustes de configuración del origen `amzn-s3-demo-bucket-in-us-east-1` a la solicitud.  

```
cf.selectRequestOriginById("amzn-s3-demo-bucket-in-us-east-1");
```

**Example : selección del origen de la solicitud del equilibrador de carga de aplicación**  
El siguiente ejemplo selecciona un origen del equilibrador de carga de aplicación denominado `myALB-prod` de la lista de orígenes asociada a la distribución y aplica los ajustes de configuración de `myALB-prod` a la solicitud.  

```
cf.selectRequestOriginById("myALB-prod");
```

**Example - Selección del origen de la solicitud del equilibrador de carga de aplicación e invalidación del encabezado del host**  
Como en el ejemplo anterior, el siguiente ejemplo selecciona un origen del equilibrador de carga de aplicación denominado `myALB-prod` de la lista de orígenes asociada a la distribución y aplica los ajustes de configuración de `myALB-prod` a la solicitud. Sin embargo, este ejemplo invalida el valor del encabezado del host mediante `origin_overrides`.  

```
cf.overrideRequestOrigin("myALB-prod",{ 
        "hostHeader" : "test.example.com"
});
```

## Método createRequestOriginGroup()
<a name="create-request-origin-group-helper-function"></a>

Utilice `createRequestOriginGroup()` para definir dos orígenes que se utilizarán como [grupo de orígenes](high_availability_origin_failover.md#concept_origin_groups.creating) para la conmutación por error en escenarios que requieren alta disponibilidad.

Un grupo de orígenes incluye dos orígenes (uno principal y otro secundario) y un criterio de conmutación por error especificado. Cree un grupo de origen para admitir la conmutación por error de origen en CloudFront. Cuando cree o actualice un grupo de orígenes mediante este método, puede especificar el grupo de orígenes en lugar de un único origen. CloudFront realizará la conmutación por error del origen principal al secundario, mediante los criterios de conmutación por error.

Si tiene un origen de VPC configurado en la distribución, puede utilizar este método para crear un grupo de orígenes utilizando un origen de VPC. Para obtener más información, consulte [Restricción del acceso con orígenes de la VPC](private-content-vpc-origins.md).

**Notas**  
La función `createRequestOriginGroup()` no admite la creación de grupos de orígenes que incluyan orígenes habilitados de TLS mutua (origen). Los grupos de origen con orígenes de TLS mutua (origen) no se pueden crear dinámicamente mediante CloudFront Functions.
Si necesita capacidades de conmutación por error de origen con TLS mutua (origen), configure los grupos de origen directamente en la configuración de distribución de CloudFront, en lugar de crearlos de forma dinámica en funciones.

### Solicitud
<a name="create-origin-group-request"></a>

```
createRequestOriginGroup({origin_group_properties})
```

En el ejemplo anterior, el archivo `origin_group_properties` contiene lo siguiente:

**originIds (obligatorio)**  
Matriz de `origin_ids`, donde `origin_id` es una cadena que apunta al nombre de un origen en la distribución que ejecuta la función. Debe proporcionar dos orígenes como parte de la matriz. El primer origen de la lista es el origen principal y el segundo sirve como segundo origen a efectos de conmutación por error. 

**originOverrides (opcional)**  
 Se pueden sobrescribir algunos ajustes avanzados mediante el parámetro `{origin_overrides}`. Las `origin overrides` pueden incluir lo siguiente:     
**hostHeader (opcional, para orígenes personalizados que no sean de S3)**  
El encabezado del host que se utilizará al realizar la solicitud al origen. Si no se proporciona, se utiliza el valor del parámetro `domainName`.   
Si no se proporciona ningún parámetro de encabezado de host ni de nombre de dominio, se utiliza el nombre de dominio del origen asignado o el encabezado de host de la solicitud entrante si la política de reenvío al origen (FTO) incluye el host. El encabezado del host no puede incluir dos puntos (`:`) ni puede ser una dirección IP. El encabezado del host puede tener una longitud de hasta 253 caracteres.  
**sni (opcional, para orígenes personalizados que no sean de S3)**  
La indicación de nombre de servidor (SNI) es una extensión del protocolo seguridad de la capa de transporte (TLS) mediante el cual un cliente indica el nombre de host al que intenta conectarse al inicio del proceso de establecimiento de comunicación de TLS. Este valor debe coincidir con un nombre común de un certificado TLS del servidor de origen, de lo contrario, el servidor de origen puede generar un error.   
Si no se proporciona, se utiliza el valor del parámetro `hostHeader`. Si no se proporciona el encabezado del host, se utiliza el valor del parámetro `domainName`.  
Si no se proporciona ningún parámetro de encabezado de host ni de nombre de dominio, se utiliza el nombre de dominio del origen asignado o el encabezado de host de la solicitud entrante si la política de reenvío al origen (FTO) incluye el host. La SNI no puede incluir dos puntos (`:`) ni puede ser una dirección IP. La SNI puede tener hasta 253 caracteres.  
**allowedCertificateNames (opcional, para orígenes personalizados que no sean de S3)**  
Puede incluir una lista de nombres de certificados válidos que CloudFront utilizará para validar la coincidencia del dominio con el certificado TLS del servidor de origen durante el establecimiento de comunicación de TLS con el servidor de origen. Este campo espera una matriz de nombres de dominio válidos y puede incluir dominios comodín, como `*.example.com`.   
Puede especificar hasta 20 nombres de certificado permitidos. Cada nombre de certificado puede tener hasta 64 caracteres.

**selectionCriteria (opcional)**  
Seleccione si desea utilizar los criterios de conmutación por error del origen `default` o utilizar la lógica de conmutación por error basada en `media-quality-score`. Los valores válidos son los siguientes:  
+ `default` utiliza los criterios de conmutación por error basados en los códigos de estado que se especifican en `failoverCriteria`. Si no configura `selectionCriteria` en la función, se utilizará `default`.
+ `media-quality-score` se utiliza cuando se emplea la capacidad de enrutamiento con reconocimiento multimedia.

**failoverCriteria (obligatorio)**  
Una matriz de códigos de estado que, cuando se devuelven desde el origen principal, desencadenarán que CloudFront conmute por error al origen secundario. Si sobrescribe un grupo de orígenes existente, esta matriz sobrescribirá todos los códigos de estado de conmutación por error establecidos en la configuración original del grupo de orígenes.  
Cuando utilice `media-quality-score` `selectionCriteria`, CloudFront intentará enrutar las solicitudes basándose en la puntuación de calidad de los medios. Si el origen seleccionado devuelve un código de error establecido en esta matriz, CloudFront realizará la conmutación por error al otro origen.

**Example : creación del grupo de orígenes de solicitudes**  
En el siguiente ejemplo se crea un grupo de orígenes para una solicitud mediante los ID de origen. Estos ID de origen proceden de la configuración del grupo de orígenes para la distribución utilizada para ejecutar esta función.  
Si lo desea, puede usar `originOverrides` para invalidar las configuraciones del grupo de origen para `sni`, `hostHeader` y `allowedCertificateNames`.  

```
import cf from 'cloudfront';

function handler(event) {
    cf.createRequestOriginGroup({
        "originIds": [
            {
                "originId": "origin-1",
                "originOverrides": {
                    "hostHeader": "hostHeader.example.com",
                    "sni": "sni.example.com",
                    "allowedCertificateNames": ["cert1.example.com", "cert2.example.com", "cert3.example.com"]
                }
            },
            {
                "originId": "origin-2",
                "originOverrides": {
                    "hostHeader": "hostHeader2.example.com",
                    "sni": "sni2.example.com",
                    "allowedCertificateNames": ["cert4.example.com", "cert5.example.com"]
                }
            }
        ],
        "failoverCriteria": {
            "statusCodes": [500]
        }
    });
    
    event.request.headers['x-hookx'] = { value: 'origin-overrides' };
    return event.request;
}
```

# Métodos auxiliares para las propiedades de CloudFront SaaS Manager
<a name="saas-specific-logic-function-code"></a>

Utilice las siguientes funciones auxiliares de CloudFront SaaS Manager para recuperar los valores de las distribuciones de varios inquilinos en la función que cree. Para utilizar los ejemplos de esta página, primero debe crear una función de CloudFront utilizando el tiempo de ejecución 2.0 de JavaScript. Para obtener más información, [Características del tiempo de ejecución 2.0 de JavaScript para CloudFront Functions](functions-javascript-runtime-20.md).

**Topics**
+ [

## Grupos de conexiones
](#connection-groups-helper-function)
+ [

## Inquilinos de distribución
](#distribution-tenants-helper-functions)

## Grupos de conexiones
<a name="connection-groups-helper-function"></a>

El grupo de conexiones que está asociado a los inquilinos de distribución tiene un nombre de dominio.

Para obtener este valor, utilice el campo `endpoint` del subobjeto `context` del objeto de evento. 

**Solicitud**

```
const value = event.context.endpoint;
```

**Respuesta**

La respuesta es una `string` que contiene el nombre de dominio del grupo de conexiones, como d111111abcdef8.cloudfront.net. El campo `endpoint` solo aparece cuando se invoca la función para una distribución de varios inquilinos con un grupo de conexiones asociado. Para obtener más información, consulte [Objeto Context (Contexto)](functions-event-structure.md#functions-event-structure-context).

## Inquilinos de distribución
<a name="distribution-tenants-helper-functions"></a>

CloudFront Functions tiene un módulo que proporciona acceso a valores específicos de inquilinos de distribución.

Para usar este módulo, incluya la siguiente instrucción en la primera línea del código de la función:

```
import cf from 'cloudfront';
```

Puede usar los siguientes ejemplos solo en la función `handler`, ya sea directamente o mediante cualquier función de llamada anidada.

### `distributionTenant.id`Campo de
<a name="distribution-tenants-field"></a>

Utilice este campo para obtener el valor del ID del inquilino de distribución.

**Solicitud**

```
const value = cf.distributionTenant.id;
```

**Respuesta**

La respuesta es una `string` que contiene el ID del inquilino de distribución, por ejemplo, `dt_1a2b3c4d5e6f7`.

**Gestión de errores**

Si se invoca la función para una distribución estándar, al especificar el campo `distributionTenant.id` se devolverá el error de tipo `distributionTenant module is not available`. Para gestionar este caso de uso, puede agregar un bloque `try` y `catch` al código.

### `distributionTenant.parameters.get()`Método de
<a name="distribution-tenant-parameters-get-method"></a>

Utilice este método para devolver el valor de los nombres de parámetro de inquilino de distribución que especifique.

```
distributionTenant.parameters.get("key");
```

`key`: el nombre del parámetro del inquilino de distribución cuyo valor desea obtener.

**Solicitud **

```
const value = distributionTenant.parameters.get("key");
```

**Respuesta**

La respuesta es una `string` que contiene el valor del parámetro del inquilino de distribución. Por ejemplo, si el nombre de la clave es `TenantPath`, entonces el valor de este parámetro podría ser `tenant1`.

**Gestión de errores**

Es posible que reciba los errores siguientes:
+ Si se invoca la función para una distribución estándar, el método `distributionTenant.parameters.get()` devolverá el error de tipo `distributionTenant module is not available`. 
+ El error `DistributionTenantParameterKeyNotFound` se devuelve cuando el parámetro de inquilino de distribución que especificó no existe. 

Para administrar estos casos de uso, puede agregar un bloque `try` y `catch` al código.

# Utilice async y await
<a name="async-await-syntax"></a>

Las funciones de tiempo de ejecución 2.0 de JavaScript de CloudFront Functions proporcionan una sintaxis `async` y `await` para gestionar los objetos `Promise`. Las promesas representan resultados retrasados a los que se puede acceder mediante la palabra clave `await` en las funciones marcadas como `async`. Varias funciones nuevas de WebCrypto utilizan promesas.

Para obtener más información sobre los objetos `Promise`, consulte [Promesa](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise).

**nota**  
Debe usar el tiempo de ejecución de JavaScript 2.0 para las siguientes muestras de código.  
`await` solo se puede usar dentro de funciones `async`. No se admiten argumentos ni cierres de `async`.

```
async function answer() {
    return 42;
}

// Note: async, await can be used only inside an async function. async arguments and closures are not supported.

async function handler(event) {
    // var answer_value = answer(); // returns Promise, not a 42 value
    let answer_value = await answer(); // resolves Promise, 42
    console.log("Answer"+answer_value);
    event.request.headers['answer'] = { value : ""+answer_value };
    return event.request;
}
```

El siguiente ejemplo de código JavaScript muestra cómo ver las promesas con el método en cadena `then`. Se puede utilizar `catch` para ver los errores.

**aviso**  
El uso de combinadores de promesas (por ejemplo, `Promise.all`, `Promise.any`) y métodos de cadena de promesas (por ejemplo, `then` y `catch`) puede requerir un uso elevado de la memoria de la función. Si la función supera la cuota de [memoria máxima de la función](cloudfront-limits.md#limits-functions), no se ejecutará. Para evitar este error, recomendamos que utilice la sintaxis `await` en lugar de los métodos `promise`.

```
async function answer() {
    return 42;
}

async function squared_answer() {
   return answer().then(value => value * value)
} 
// Note: async, await can be used only inside an async function. async arguments and closures are not supported.
async function handler(event) {
    // var answer_value = answer(); // returns Promise, not a 42 value
    let answer_value = await squared_answer(); // resolves Promise, 42
    console.log("Answer"+answer_value);
    event.request.headers['answer'] = { value : ""+answer_value };
    return event.request;
}
```

# Compatibilidad con CWT para CloudFront Functions
<a name="cwt-support-cloudfront-functions"></a>

En esta sección, se proporcionan detalles sobre la compatibilidad con los tókenes web CBOR (CWT) en las CloudFront Functions, lo que permite la autenticación y la autorización seguras basadas en tókenes en las ubicaciones periféricas de CloudFront. Esta compatibilidad se proporciona como un módulo, al que se puede acceder desde CloudFront Functions. 

Para usar este módulo, cree una función de CloudFront con tiempo de ejecución 2.0 de JavaScript e incluya la siguiente instrucción en la primera línea del código de la función: 

```
import cf from 'cloudfront';
```

Los métodos asociados a este módulo son accesibles mediante (donde \$1 es un comodín que representa las diferentes funciones presentes en el módulo):

```
cf.cwt.*
```

Para obtener más información, consulte [Características del tiempo de ejecución 2.0 de JavaScript para CloudFront Functions](functions-javascript-runtime-20.md).

Actualmente, el módulo solo admite la estructura MAC0 con el algoritmo HS256 (HMAC-SHA256) con un límite de 1 KB para el tamaño máximo del token.

## Estructura de token
<a name="token-structure"></a>

En esta sección se describe la estructura de token que espera el módulo de CWT. El módulo espera que el token esté correctamente etiquetado y sea identificable (por ejemplo, COSE MAC0). Además, en cuanto a la estructura del token, el módulo sigue los estándares establecidos por [Firma y cifrado de objetos CBOR (COSE) [RFC 8152]](https://datatracker.ietf.org/doc/html/rfc8152).

```
( // CWT Tag (Tag value: 61) --- optional    
    ( // COSE MAC0 Structure Tag (Tag value: 17) --- required        
        [            
            protectedHeaders,            
            unprotectedHeaders,            
            payload,            
            tag,        
        ]    
    )
)
```

**Example : CWT utiliza la estructura COSE MAC0**  

```
61( // CWT tag     
    17( // COSE_MAC0 tag       
        [         
            { // Protected Headers           
                1: 4  // algorithm : HMAC-256-64         
            },         
            { // Unprotected Headers           
                4: h'53796d6d6574726963323536' // kid : Symmetric key id          
            },         
            { // Payload           
                1: "https://iss.example.com", // iss           
                2: "exampleUser", // sub           
                3: "https://aud.example.com", // aud           
                4: 1444064944, // exp           
                5: 1443944944, // nbf           
                6: 1443944944, // iat         
            },         
            h'093101ef6d789200' // tag       
        ]     
    )   
)
```
La etiqueta de CWT es opcional a la hora de generar los tókenes. Sin embargo, se requiere la etiqueta de estructura COSE.

## método validateToken()
<a name="validatetoken-method"></a>

La función decodifica y valida un token de CWT con la clave especificada. Si la validación es exitosa, devuelve el token de CWT decodificado. De lo contrario, emite un error. Tenga en cuenta que esta función no valida el conjunto de reclamaciones.

### Solicitud
<a name="validatetoken-request"></a>

```
cf.cwt.validateToken(token, handlerContext{key})
```Parameters

**token (obligatorio)**  
Token codificado para la validación. Debe ser un búfer de JavaScript.

**handlerContext (obligatorio)**  
Un objeto de JavaScript que almacena el contexto de la llamada a validateToken. Por el momento, solo se admite la propiedad de la clave.

**clave (obligatorio)**  
Clave secreta para el cálculo del resumen del mensaje. Se puede proporcionar como cadena o búfer de JavaScript.

### Respuesta
<a name="validatetoken-response"></a>

Cuando el método `validateToken()` devuelve un token validado correctamente, la respuesta de la función es un `CWTObject` en el siguiente formato. Una vez decodificadas, todas las claves de reclamación se representan como cadenas.

```
CWTObject {    
    protectedHeaders,    
    unprotectedHeaders,    
    payload
}
```

### Ejemplo: Validación del token con el identificador enviado como parte del token
<a name="validatetoken-example"></a>

En este ejemplo, se muestra la validación del token de CWT, en la que se extrae el identificador del encabezado. A continuación, el identificador pasa a KeyValueStore de CloudFront Functions para obtener la clave secreta utilizada para validar el token.

```
import cf from 'cloudfront'

const CwtClaims = {
   iss: 1,
   aud: 3,
   exp: 4
}

async function handler(event) {
    try {
        let request = event.request;
        let encodedToken = request.headers['x-cwt-token'].value;
        let kid = request.headers['x-cwt-kid'].value;
                
        // Retrieve the secret key from the kvs
        let secretKey = await cf.kvs().get(kid);
                 
        // Now you can use the secretKey to decode & validate the token.
        let tokenBuffer = Buffer.from(encodedToken, 'base64url');
                
        let handlerContext = {
           key: secretKey,
        }
                
        try {
            let cwtObj = cf.cwt.validateToken(tokenBuffer, handlerContext);
                        
            // Check if token is expired
            const currentTime = Math.floor(Date.now() / 1000); // Current time in seconds
            if (cwtObj[CwtClaims.exp] && cwtObj[CwtClaims.exp] < currentTime) {
                return {
                    statusCode: 401,
                    statusDescription: 'Token expired'
                };
            }
        } catch (error) {
            return {
               statusCode: 401,
               statusDescription: 'Invalid token'
            };
         }
    } catch (error) {
        return {
            statusCode: 402,
            statusDescription: 'Token processing failed'
        };
     }
    return request;
}
```

## método generateToken()
<a name="generatetoken-method"></a>

Esta función genera un nuevo token de CWT mediante la carga útil y la configuración de contexto proporcionados.

### Solicitud
<a name="generatetoken-request"></a>

```
cf.cwt.generateToken(generatorContext, payload)
```Parameters

**generatorContext (obligatorio)**  
Se trata de un objeto de JavaScript que se utiliza como contexto para generar el token y contiene los siguientes pares de valores clave:    
**cwTag (opcional)**  
Este valor es un booleano que, si `true` lo especifica, `cwtTag` se debe agregar.  
**coseTag (obligatorio)**  
Especifica el tipo de etiqueta de COSE. Actualmente, solo admite `MAC0`.  
**clave (obligatorio)**  
Clave secreta para el cálculo del resumen del mensaje. Este valor puede ser una cadena o JavaScript `Buffer`.

**carga útil (obligatorio)**  
Carga útil del token para la codificación. La carga útil debe estar en formato `CWTObject`.

### Respuesta
<a name="generatetoken-response"></a>

Devuelve un búfer de JavaScript que contiene el token codificado.

**Example : genera un token de CWT**  

```
import cf from 'cloudfront';

const CwtClaims = {
    iss: 1,
    sub: 2,
    exp: 4
};

const CatClaims = {
    catu: 401,
    catnip: 402,
    catm: 403,
    catr: 404
};

const Catu = {
    host: 1,
    path: 2,
    ext: 3
};

const CatuMatchTypes = {
    prefix_match: 1,
    suffix_match: 2,
    exact_match: 3
};

const Catr = {
    renewal_method: 1,
    next_renewal_time: 2,
    max_uses: 3
};

async function handler(event) {
    try {
        const response = {
            statusCode: 200,
            statusDescription: 'OK',
            headers: {}
        };
        
        const commonAccessToken = {
            protected: {
                1: "5",
            },
            unprotected: {},
            payload: {
                [CwtClaims.iss]: "cloudfront-documentation",
                [CwtClaims.sub]: "cwt-support-on-cloudfront-functions",
                [CwtClaims.exp]: 1740000000,
                [CatClaims.catu]: {
                    [Catu.host]: {
                        [CatuMatchTypes.suffix_match]: ".cloudfront.net"
                    },
                    [Catu.path]: {
                        [CatuMatchTypes.prefix_match]: "/media/live-stream/cf-4k/"
                    },
                    [Catu.ext]: {
                        [CatuMatchTypes.exact_match]: [
                            ".m3u8",
                            ".ts",
                            ".mpd"
                        ]
                    }
                },
                [CatClaims.catnip]: [
                    "[IP_ADDRESS]",
                    "[IP_ADDRESS]"
                ],
                [CatClaims.catm]: [
                    "GET",
                    "HEAD"
                ],
                [CatClaims.catr]: {
                    [Catr.renewal_method]: "header_renewal",
                    [Catr.next_renewal_time]: 1750000000,
                    [Catr.max_uses]: 5
                }
            }
        };
        
        if (!request.headers['x-cwt-kid']) {
            throw new Error('Missing x-cwt-kid header');
        }
        
        const kid = request.headers['x-cwt-kid'].value;
        const secretKey = await cf.kvs().get(kid);
        
        if (!secretKey) {
            throw new Error('Secret key not found for provided kid');
        }
        
        try {
            const genContext = {
                cwtTag: true,
                coseTag: "MAC0",
                key: secretKey
            };
            
            const tokenBuffer = cf.cwt.generateToken(commonAccessToken, genContext);
            response.headers['x-generated-cwt-token'] = { value: tokenBuffer.toString('base64url') };
                        
            return response;
        } catch (tokenError) {
            return {
                statusCode: 401,
                statusDescription: 'Could not generate the token'
            };
        }
    } catch (error) {
        return {
            statusCode: 402,
            statusDescription: 'Token processing failed'
        };
    }
}
```

**Example : actualice el token según alguna lógica**  

```
import cf from 'cloudfront'

const CwtClaims = {
   iss: 1,
   aud: 3,
   exp: 4
}

async function handler(event) {
    try {
        let request = event.request;
        let encodedToken = request.headers['x-cwt-token'].value;
        let kid = request.headers['x-cwt-kid'].value;
        let secretKey = await cf.kvs().get(kid); // Retrieve the secret key from the kvs
                
        // Now you can use the secretKey to decode & validate the token.
        let tokenBuffer = Buffer.from(encodedToken, 'base64url');
                
        let handlerContext = {
           key: secretKey,
        }
                
        try {
            let cwtJSON = cf.cwt.validateToken(tokenBuffer, handlerContext);
                        
            // Check if token is expired
            const currentTime = Math.floor(Date.now() / 1000); // Current time in seconds
            if (cwtJSON[CwtClaims.exp] && cwtJSON[CwtClaims.exp] < currentTime) {
                // We can regnerate the token and add 8 hours to the expiry time
                cwtJSON[CwtClaims.exp] = Math.floor(Date.now() / 1000) + (8 * 60 * 60);
                                
                let genContext = {
                  coseTag: "MAC0",
                  key: secretKey
                }
                                
                let newTokenBuffer = cf.cwt.generateToken(cwtJSON, genContext);
                 request.headers['x-cwt-regenerated-token'] = newTokenBuffer.toString('base64url');
            }
        } catch (error) {
            return {
               statusCode: 401,
               statusDescription: 'Invalid token'
            };
         }
    }
    catch (error) {
        return {
            statusCode: 402,
            statusDescription: 'Token processing failed'
        };
     }
    return request;
}
```

# Métodos de ayuda generales
<a name="general-helper-methods"></a>

Esta página proporciona métodos de ayuda adicionales en CloudFront Functions. Para usar estos métodos, cree una función de CloudFront con tiempo de ejecución 2.0 de JavaScript.

```
import cf from 'cloudfront';
```

Para obtener más información, consulte [Características del tiempo de ejecución 2.0 de JavaScript para CloudFront Functions](functions-javascript-runtime-20.md).

## `edgeLocation`Metadatos de
<a name="edge-location-metadata"></a>

Este método requiere el uso del modulo `cloudfront`.

**nota**  
Solo puede utilizar este método para las funciones de solicitud del espectador. Para las funciones de respuesta del espectador, este método está vacío.

Utilice este objeto de JavaScript para obtener el código del aeropuerto de ubicación periférica, la región de [Caché periférica regional](HowCloudFrontWorks.md#CloudFrontRegionaledgecaches) prevista o la dirección IP del servidor de CloudFront utilizada para gestionar la solicitud. Estos metadatos solo están disponibles cuando el espectador solicita desencadenar el evento.

```
cf.edgeLocation = {
    name: SEA
    serverIp: 1.2.3.4
    region: us-west-2
}
```

El objeto `cf.edgeLocation` puede incluir lo siguiente:

**name**  
El [código IATA](https://en.wikipedia.org/wiki/IATA_airport_code) de tres letras de la ubicación periférica que gestionó la solicitud.

**serverIp**  
Dirección IPv4 o IPv6 del servidor que gestionó la solicitud.

**region**  
La caché periférica regional (REC) de CloudFront que se *espera* que utilice la solicitud en caso de falta de memoria caché. Este valor no se actualiza en caso de que el REC esperado no esté disponible y se utilice un REC de copia de seguridad para la solicitud. Esto no incluye la ubicación de Origin Shield que se utilice, excepto en los casos en que el REC principal y el Origin Shield estén en la misma ubicación.

**nota**  
CloudFront Functions no se invoca por segunda vez cuando CloudFront está configurado para usar la conmutación por error de origen. Para obtener más información, consulte [Optimización de alta disponibilidad con conmutación por error de origen de CloudFront](high_availability_origin_failover.md).

## `rawQueryString()`Método de
<a name="raw-query-string-method"></a>

Este método no requiere el módulo `cloudFront`.

Utilice el método `rawQueryString()` para recuperar la cadena de consulta no analizada y no modificada como una cadena.

**Solicitud**

```
function handler(event) {
    var request = event.request;
    const qs = request.rawQueryString();
}
```

**Respuesta**

Devuelve la cadena de consulta completa de la solicitud entrante como un valor de cadena sin `?` al principio. 
+ Si no hay una cadena de consulta, pero `?` está presente, la función devuelve una cadena vacía. 
+ Si no hay una cadena de consulta y `?` no está presente, la función devuelve `undefined`.

**Caso 1: se devuelve la cadena de consulta completa (sin `?` al principio)**  
URL de solicitud entrante: `https://example.com/page?name=John&age=25&city=Boston`  
`rawQueryString()` devuelve: `"name=John&age=25&city=Boston"`

**Caso 2: se devuelve una cadena vacía (cuando `?` está presente pero sin parámetros)**  
URL de solicitud entrante: `https://example.com/page?`  
`rawQueryString()` devuelve: `""`

**Caso 3: se devuelve `undefined` (sin cadena de consulta ni `?`)**  
URL de solicitud entrante: `https://example.com/page`  
`rawQueryString()` devuelve: `undefined`

# Creación de funciones
<a name="create-function"></a>

La función se crea en dos etapas: 

1. Crear el código de función como JavaScript. Puede utilizar el ejemplo predeterminado de la consola de CloudFront o escribir el suyo propio. Para obtener más información, consulte los temas siguientes:
   + [Escritura de código de función](writing-function-code.md)
   + [Estructura de eventos de CloudFront Functions](functions-event-structure.md)
   + [Ejemplos de CloudFront Functions para CloudFront](service_code_examples_cloudfront_functions_examples.md)

1. Utilice CloudFront para crear la función e incluir el código. El código existe dentro de la función (no como referencia).

------
#### [ Console ]

**Para crear una función**

1. Inicie sesión en la consola de CloudFront en [https://console.aws.amazon.com/cloudfront/v4/home#/functions](https://console.aws.amazon.com/cloudfront/v4/home#/functions) y elija la página **Funciones**.

1. Seleccione **Creación de función**.

1. Introduzca un nombre de función que sea único en la Cuenta de AWS, elija la versión de Java Script y, a continuación, elija **Continuar**. Aparece la página de detalles de la nueva función.
**nota**  
Para utilizar [pares clave-valor](kvs-with-functions.md) en la función, debe elegir tiempo de ejecución 2.0 de Java Script.

1. En la sección **Código de función**, seleccione la pestaña **Compilación** e introduzca el código de función. El código de ejemplo que se incluye en la pestaña **Compilación** ilustra la sintaxis básica del código de la función.

1. Elija **Guardar cambios**.

1. Si el código de la función utiliza pares clave-valor, debe asociar un almacén de clave-valor. 

   Puede asociar el almacén de clave-valor cuando crea en primer lugar la función. O bien, puede asociarlo más adelante, [actualizando la función](update-function.md). 

   Para asociar un almacén clave-valor ahora, siga estos pasos:
   + Vaya a la sección **Asociar KeyValueStore** y elija **Asociar KeyValueStore existente**.
   + Seleccione el almacén de clave-valor que contiene los pares clave-valor de la función y, a continuación, elija **Asociar KeyValueStore**.

   CloudFront asocia inmediatamente el almacén a la función. No necesita guardar la función.

------
#### [ CLI ]

Si utiliza la CLI, normalmente crea primero el código de la función en un archivo y, a continuación, crea la función con la AWS CLI.

**Para crear una función**

1. Cree el código de la función en un archivo y guárdelo en un directorio al que se pueda conectar el equipo. 

1. Ejecute el comando como se muestra en el ejemplo. En este ejemplo, se utiliza la notación `fileb://` para transmitir el archivo. También incluye saltos de línea para que el comando sea más legible. 

   ```
   aws cloudfront create-function \
       --name MaxAge \
       --function-config '{"Comment":"Max Age 2 years","Runtime":"cloudfront-js-2.0","KeyValueStoreAssociations":{"Quantity":1,"Items":[{"KeyValueStoreARN":"arn:aws:cloudfront::111122223333:key-value-store/a1b2c3d4-5678-90ab-cdef-EXAMPLE11111"}]}}' \
       --function-code fileb://function-max-age-v1.js
   ```
**Notas**  
`Runtime`: la versión de Java Script. Para utilizar [pares clave-valor](kvs-with-functions.md) en la función, debe especificar la versión 2.0.
`KeyValueStoreAssociations`: si la función usa pares clave-valor, puede asociar el almacén de clave-valor en la creación inicial de la función. O bien, puede asociarlo más adelante, utilizando `update-function`. La `Quantity` siempre es `1`, porque cada función solo puede tener asociado un almacén de clave-valor.

   Si el comando se ejecuta correctamente, verá un resultado parecido al siguiente.

   ```
   ETag: ETVABCEXAMPLE
   FunctionSummary:
     FunctionConfig:
       Comment: Max Age 2 years
       Runtime: cloudfront-js-2.0
       KeyValueStoreAssociations= \
         {Quantity=1, \
         Items=[{KeyValueStoreARN='arn:aws:cloudfront::111122223333:key-value-store/a1b2c3d4-5678-90ab-cdef-EXAMPLE11111'}]} \
     FunctionMetadata:
       CreatedTime: '2021-04-18T20:38:56.915000+00:00'
       FunctionARN: arn:aws:cloudfront::111122223333:function/MaxAge
       LastModifiedTime: '2023-11-19T20:38:56.915000+00:00'
       Stage: DEVELOPMENT
     Name: MaxAge
     Status: UNPUBLISHED
   Location: https://cloudfront.amazonaws.com/2020-05-31/function/arn:aws:cloudfront:::function/MaxAge
   ```

   La mayor parte de la información se repite desde la solicitud. CloudFront agrega el resto de información.
**Notas**  
`ETag`: este valor cambia cada vez que se modifica el almacén de clave-valor. Utilice este valor y el nombre de la función para hacer referencia a la función en el futuro. Asegúrese de utilizar siempre la `ETag` actual.
`FunctionARN`: el ARN de la función CloudFront.
111122223333: la Cuenta de AWS.
`Stage`: la fase de la función (`LIVE` o `DEVELOPMENT`). 
`Status`: el estado de la función (`PUBLISHED` o `UNPUBLISHED`).

------

Después de crear la función, se agrega a la fase `DEVELOPMENT`. Le recomendamos que [pruebe la función](test-function.md) antes de [publicarla](publish-function.md). Tras publicar la función, la función cambia a la fase `LIVE`.

# Prueba de funciones
<a name="test-function"></a>

Antes de implementar función en la etapa activa (producción), puede probarla para verificar que funciona según lo previsto. Para probar una función, especifica un *objeto de evento* que representa una solicitud o respuesta HTTP que su distribución de CloudFront podría recibir en producción. 

CloudFront Functions realiza lo siguiente:

1. Ejecuta la función con el objeto de evento proporcionado como entrada.

1. Devuelve el resultado de la función (el objeto de evento modificado) junto con los registros de función o mensajes de error y la *utilización de cómputo*de la función. Para obtener más información acerca del uso de cómputo, consulte [Descripción del uso de cómputo](#compute-utilization).

**nota**  
Al probar una función, CloudFront solo la valida en función de los errores de ejecución de la función. CloudFront no valida si la solicitud se tramitará correctamente una vez publicada. Por ejemplo, si su función elimina un encabezado obligatorio, la prueba se realizará correctamente porque no hay ningún problema con el código. Sin embargo, si publica la función y la asocia a una distribución, la función fallará cuando se realice una solicitud a través de CloudFront.

**Contents**
+ [

## Configuración del objeto del evento
](#test-function-create-event)
+ [

## Prueba de la función
](#test-function-step-test)
+ [

## Descripción del uso de cómputo
](#compute-utilization)

## Configuración del objeto del evento
<a name="test-function-create-event"></a>

Antes de probar una función, debe configurar el objeto de evento con el cual la probará. Hay varias opciones para hacerlo.

**Opción 1: Configurar un objeto de evento sin guardarlo**  
Puede configurar un objeto de evento en el editor visual de la consola de CloudFront y no guardarlo.   
Puede usar este objeto de evento para probar la función desde la consola de CloudFront, aunque no esté guardado.

**Opción 2: Crear un objeto de evento en el editor visual**  
Puede configurar un objeto de evento en el editor visual de la consola de CloudFront y no guardarlo. Puede crear 10 objetos de eventos para cada función para, por ejemplo, probar diferentes entradas posibles.  
Al crear el objeto de evento de esta manera, puede usarlo para probar la función en la consola de CloudFront. No puede usarlo para probar la función mediante una API o un SDK de AWS. 

**Opción 3: Crear un objeto de evento mediante un editor de texto**  
Puede usar un editor de texto para crear un objeto de evento a mano en formato JSON. Para obtener información sobre la estructura de un objeto de evento, consulte [Estructura de evento](functions-event-structure.md).   
Puede usar este objeto de evento para probar la función mediante la CLI. Sin embargo, no se puede utilizar para probar la función en la consola de CloudFront.

**Para crear un objeto de evento (opción 1 o 2)**

1. Inicie sesión en la consola de CloudFront en [https://console.aws.amazon.com/cloudfront/v4/home#/functions](https://console.aws.amazon.com/cloudfront/v4/home#/functions) y elija la página **Funciones**.

   Elija la función que desea probar.

1. En la página de detalles de la función, seleccione la pestaña **Probar**. 

1. En **Tipo de evento**, elija una de las siguientes opciones:
   + Elija **Solicitud del lector** si la función modifica una solicitud HTTP o genera una respuesta basada en la solicitud. Aparece la sección **Solicitud**.
   + O bien, seleccione **Respuesta del lector**. Aparecen las secciones **Solicitud** y **Respuesta**. 

1. Complete los campos que desee incluir en el evento. Puede elegir **Editar JSON** para ver el JSON sin procesar.

1. (Opcional) Para guardar el evento, elija **Guardar** y, en **Save test event**, introduzca un nombre y, a continuación, seleccione **Guardar**.

   También puede elegir **Editar JSON**, copiar el JSON sin procesar y guardarlo en su propio archivo, fuera de CloudFront. 

**Para crear un objeto de evento (opción 3)**

Cree el objeto de evento mediante un editor de texto. Guarde el archivo en un directorio al que se pueda conectar su equipo. 

Asegúrese de seguir estas directrices:
+ Omita los campos `distributionDomainName`, `distributionId` y `requestId`. 
+ Los nombres de encabezados, cookies y cadenas de consulta deben estar en minúsculas.

Una opción para crear un objeto de evento de esta manera es crear una muestra mediante el editor visual. Puede estar seguro de que la muestra tiene el formato correcto. A continuación, puede copiar el JSON sin procesar, pegarlo en un editor de texto y guardar el archivo.

Para obtener más información sobre la estructura de un evento, consulte [Estructura de evento](functions-event-structure.md). 

## Prueba de la función
<a name="test-function-step-test"></a>

Puede probar una función en la consola de CloudFront o con la AWS Command Line Interface (AWS CLI).

------
#### [ Console ]

**Para probar la función**

1. Inicie sesión en la consola de CloudFront en [https://console.aws.amazon.com/cloudfront/v4/home#/functions](https://console.aws.amazon.com/cloudfront/v4/home#/functions) y elija la página **Funciones**.

1. Elija la función que desea probar.

1. Elija la pestaña **Prueba**. 

1. Asegúrese de que se muestre el evento correcto. Si desea cambiar desde el evento que se muestra actualmente, elija otro evento en el campo **Seleccionar evento de prueba**.

1. Seleccione **Probar función**. La consola muestra el resultado de la función, incluidos los registros de funciones y el uso del cómputo. 

------
#### [ CLI ]

Puede probar una función mediante el comando **aws cloudfront test-function**. 

**Para probar la función**

1. Abra una ventana de línea de comandos.

1. Ejecute el siguiente comando desde el directorio que contiene el archivo especificado.

   En este ejemplo, se utiliza la notación `fileb://` para transmitir el archivo del objeto de evento. También incluye saltos de línea para que el comando sea más legible. 

   ```
   aws cloudfront test-function \
       --name MaxAge \
       --if-match ETVABCEXAMPLE \
       --event-object fileb://event-maxage-test01.json \
       --stage DEVELOPMENT
   ```
**Notas**  
Se hace referencia a la función por su nombre y por la ETag (en el parámetro `if-match`). Se hace referencia al objeto de evento por su ubicación en el sistema de archivos.
El estado puede ser `DEVELOPMENT` o `LIVE`.

   Si el comando se ejecuta correctamente, verá un resultado parecido al siguiente.

   ```
   TestResult:
     ComputeUtilization: '21'
     FunctionErrorMessage: ''
     FunctionExecutionLogs: []
     FunctionOutput: '{"response":{"headers":{"cloudfront-functions":{"value":"generated-by-CloudFront-Functions"},"location":{"value":"https://aws.amazon.com/cloudfront/"}},"statusDescription":"Found","cookies":{},"statusCode":302}}'
     FunctionSummary:
       FunctionConfig:
         Comment: MaxAge function
         Runtime: cloudfront-js-2.0
         KeyValueStoreAssociations= \
         {Quantity=1, \
         Items=[{KeyValueStoreARN='arn:aws:cloudfront::111122223333:key-value-store/a1b2c3d4-5678-90ab-cdef-EXAMPLE11111'}]} \
       FunctionMetadata:
         CreatedTime: '2021-04-18T20:38:56.915000+00:00'
         FunctionARN: arn:aws:cloudfront::111122223333:function/MaxAge
         LastModifiedTime: '2023-17-20T10:38:57.057000+00:00'
         Stage: DEVELOPMENT
       Name: MaxAge
       Status: UNPUBLISHED
   ```

------

**Notas**  
`FunctionExecutionLogs` contiene una lista de líneas de registro que la función escribió en instrucciones `console.log()` (si las hay).
`ComputeUtilization` contiene información sobre la ejecución de la función. Consulte [Descripción del uso de cómputo](#compute-utilization).
`FunctionOutput` contiene el objeto de evento que devolvió la función. 

## Descripción del uso de cómputo
<a name="compute-utilization"></a>

**Utilización de cómputo** es la cantidad de tiempo que la función tardó en ejecutarse como un porcentaje del tiempo máximo permitido. Por ejemplo, un valor de 35 significa que la función se completó en el 35 % del tiempo máximo permitido.

Si una función supera continuamente el tiempo máximo permitido, CloudFront la limita. En la siguiente lista se explica la probabilidad de que una función se limite en función del valor de utilización de cómputo.

**Valor de utilización de cómputo:**
+ **1 – 50** – la función está cómodamente por debajo del tiempo máximo permitido y debe ejecutarse sin limitación.
+ **51 – 70** – la función se acerca al tiempo máximo permitido. Considere optimizar el código de la función.
+ **71 – 100** – la función está muy cerca o supera el tiempo máximo permitido. Es probable que CloudFront limite esta función si la asocia a una distribución.

# Actualización de funciones
<a name="update-function"></a>

Puede actualizar una función en cualquier momento. Los cambios se realizan únicamente en la versión de la función que se encuentra en la etapa `DEVELOPMENT`. Para copiar los cambios de la etapa `DEVELOPMENT` a `LIVE`, debe [publicar la función](publish-function.md). 

Puede actualizar el código de una función en la consola de CloudFront o con la AWS Command Line Interface (AWS CLI).

------
#### [ Console ]

**Actualización del código de la función**

1. Inicie sesión en la consola de CloudFront en [https://console.aws.amazon.com/cloudfront/v4/home#/functions](https://console.aws.amazon.com/cloudfront/v4/home#/functions) y elija la página **Funciones**.

   Elija la función que desea actualizar.

1. Elija **Editar** y realice los siguientes cambios:
   + Actualice todos los campos de la sección **Detalles**.
   + Cambie o elimine el almacén de clave-valor asociado. Para obtener más información sobre los almacenes de clave-valor, consulte [Amazon CloudFront KeyValueStore](kvs-with-functions.md).
   + Cambie el código de la función. Seleccione la pestaña **Compilación**, realice los cambios y, a continuación, seleccione **Guardar cambios** para guardar los cambios en el código.

------
#### [ CLI ]

**Para actualizar el código de la función**

1. Abra una ventana de línea de comandos.

1. Ejecute el siguiente comando.

   En este ejemplo, se utiliza la notación `fileb://` para transmitir el archivo. También incluye saltos de línea para que el comando sea más legible. 

   ```
   aws cloudfront update-function \
       --name MaxAge \
       --function-config '{"Comment":"Max Age 2 years","Runtime":"cloudfront-js-2.0","KeyValueStoreAssociations":{"Quantity":1,"Items":[{"KeyValueStoreARN":"arn:aws:cloudfront::111122223333:key-value-store/a1b2c3d4-5678-90ab-cdef-EXAMPLE11111"}]}}' \
       --function-code fileb://function-max-age-v1.js \
       --if-match ETVABCEXAMPLE
   ```
**Notas**  
Puede identificar la función por su nombre y ETag (en el parámetro `if-match`). Asegúrese de utilizar siempre la ETag actual. Puede obtener este valor de la operación de la API [DescribeFunction](https://docs.aws.amazon.com/cloudfront/latest/APIReference/API_DescribeFunction.html).
Debe incluir el `function-code`, incluso aunque no desee cambiarlo.
Tenga cuidado con la `function-config`. Debe transmitir todo lo que quiera conservar en la configuración. En concreto, gestione el almacén de clave-valor de la siguiente manera:   
Para retener la asociación de almacenes de clave-valor existentes (si existen), especifique el nombre del almacén *existente*.
Para cambiar la asociación, especifique el nombre del *nuevo* almacén de clave-valor.
Para eliminar la asociación, omita el parámetro `KeyValueStoreAssociations`. 

   Si el comando se ejecuta correctamente, verá un resultado parecido al siguiente. 

   ```
   ETag: ETVXYZEXAMPLE
   FunctionSummary:
     FunctionConfig:
       Comment: Max Age 2 years \
       Runtime: cloudfront-js-2.0 \
       KeyValueStoreAssociations= \
         {Quantity=1, \
         Items=[{KeyValueStoreARN='arn:aws:cloudfront::111122223333:key-value-store/a1b2c3d4-5678-90ab-cdef-EXAMPLE11111'}]} \
     FunctionMetadata: \
       CreatedTime: '2021-04-18T20:38:56.915000+00:00' \
       FunctionARN: arn:aws:cloudfront::111122223333:function/MaxAge \
       LastModifiedTime: '2023-12-19T23:41:15.389000+00:00' \
       Stage: DEVELOPMENT \
     Name: MaxAge \
     Status: UNPUBLISHED
   ```

------

La mayor parte de la información se repite desde la solicitud. CloudFront agrega el resto de información.

**Notas**  
`ETag`: este valor cambia cada vez que se modifica el almacén de clave-valor.
`FunctionARN`: el ARN de la función CloudFront.
`Stage`: la fase de la función (`LIVE` o `DEVELOPMENT`). 
`Status`: el estado de la función (`PUBLISHED` o `UNPUBLISHED`).

# Publicación de funciones
<a name="publish-function"></a>

Al publicar la función, se copia la función de la fase `DEVELOPMENT` a la fase `LIVE`.

Si no hay ningún comportamiento de la caché asociado a la función, publicarla permite asociarla a un comportamiento de la caché. Solo se pueden asociar comportamientos de la caché a funciones que se encuentran en la etapa `LIVE`.

**importante**  
Antes de la publicación, le recomendamos que [pruebe la función](test-function.md).
Después de publicar la función, todos los comportamientos de la caché asociados a la función comienzan automáticamente a usar la copia recién publicada, tan pronto como las distribuciones terminen de implementarse.

Puede publicar una función en la consola de CloudFront o con la AWS CLI.

------
#### [ Console ]

**Publicación de una función**

1. Inicie sesión en la consola de CloudFront en [https://console.aws.amazon.com/cloudfront/v4/home#/functions](https://console.aws.amazon.com/cloudfront/v4/home#/functions) y elija la página **Funciones**.

1. Elija la función que desea actualizar.

1. Elija la pestaña **Publicar** y, a continuación, elija **Publicar**. Si la función ya está asociada a uno o varios comportamientos de la caché, elija **Publish and update**.

1. (Opcional) Para ver las distribuciones asociadas a la función, seleccione **Associated CloudFront distributions (Distribuciones de CloudFront asociadas)** a fin de expandir esa sección.

Cuando se guarda correctamente, aparece un banner en la parte superior de la página que dice ***Function name* published successfully**. También puede seleccionar la pestaña **Compilación** y, a continuación, **Activa** para ver la versión activa del código de función.

------
#### [ CLI ]

**Publicación de una función**

1. Abra una ventana de línea de comandos.

1. Ejecute el siguiente comando de la **aws cloudfront publish-function**. En el ejemplo, se proporcionan saltos de línea para que el ejemplo sea más legible.

   ```
   aws cloudfront publish-function \
       --name MaxAge \
       --if-match ETVXYZEXAMPLE
   ```

   Si el comando se ejecuta correctamente, verá un resultado parecido al siguiente.

   ```
   FunctionSummary:
     FunctionConfig:
       Comment: Max Age 2 years
       Runtime: cloudfront-js-2.0
     FunctionMetadata:
       CreatedTime: '2021-04-18T21:24:21.314000+00:00'
       FunctionARN: arn:aws:cloudfront::111122223333:function/ExampleFunction
       LastModifiedTime: '2023-12-19T23:41:15.389000+00:00'
       Stage: LIVE
     Name: MaxAge
     Status: UNASSOCIATED
   ```

------

# Asociación de funciones con distribuciones
<a name="associate-function"></a>

Para utilizar una función con una distribución, asocie la función a uno o varios comportamientos de caché en la distribución. Puede asociar una función a varios comportamientos de la caché en varias distribuciones.

Puede asociar una función con cualquiera de los siguientes elementos:
+ Un comportamiento de la caché existente
+ Un nuevo comportamiento de la caché en una distribución existente
+ Un nuevo comportamiento de la caché en una distribución nueva.

Cuando asocia una función a un comportamiento de la caché, debe selecciona un *tipo de evento*. El tipo de evento determina cuándo CloudFront ejecuta la función. 

Puede elegir los siguientes tipos de evento:
+ **Solicitud del lector**: la función se ejecuta cuando CloudFront recibe una solicitud de un lector.
+ **Viewer Response (Respuesta al lector)**: la función se ejecuta antes de que CloudFront devuelva una respuesta al lector.

No se pueden utilizar tipos de eventos orientados al origen (*solicitud de origen* y *respuesta de origen*) con CloudFront Functions. En su lugar, puede utilizar Lambda@Edge. Para obtener más información, consulte [Eventos de CloudFront que pueden desencadenar una función de Lambda@Edge](lambda-cloudfront-trigger-events.md). 

**nota**  
Antes de asociar una función, debe [publicarla](publish-function.md) en la etapa `LIVE`.

Puede asociar una función a una distribución en la consola de CloudFront o con la AWS Command Line Interface (AWS CLI). En el siguiente procedimiento, se muestra cómo asociar una función a un comportamiento existente de la caché. 

------
#### [ Console ]

**Asociación de una función a un comportamiento existente de la caché**

1. Inicie sesión en la consola de CloudFront en [https://console.aws.amazon.com/cloudfront/v4/home#/functions](https://console.aws.amazon.com/cloudfront/v4/home#/functions) y elija la página **Funciones**.

1. Elija la función que desee asociar.

1. En la página **Función**, seleccione la pestaña **Publicar**.

1. Elija la **función Publicar**.

1. Elija **Add association**. En el cuadro de diálogo que aparece, elija una distribución, un tipo de evento o un comportamiento de caché. 

   Para el tipo de evento, seleccione cuándo desea que se ejecute esta función:
   + **Solicitud del lector**: ejecute la función cada vez que CloudFront reciba una solicitud.
   + **Respuesta al lector**: ejecute la función cada vez que CloudFront devuelve una respuesta.

1. Para guardar la configuración, elija **Agregar asociación**.

CloudFront asocia la distribución a la función. Espere unos minutos para que la distribución asociada termine de implementarse. Puede seleccionar **Ver distribución** en la página de detalles de la función para comprobar el progreso.

------
#### [ CLI ]

**Asociación de una función a un comportamiento existente de la caché**

1. Abra una ventana de línea de comandos.

1. Introduzca el siguiente comando para guardar la configuración de la distribución cuyo comportamiento de la caché desea asociar a una función. Este comando guarda la configuración de distribución en un archivo llamado `dist-config.yaml`. Para utilizar este comando, haga lo siguiente:
   + Reemplace *`DistributionID`* por el ID de la distribución.
   + Ejecute el comando en una línea. En el ejemplo, se proporcionan saltos de línea para que el ejemplo sea más legible.

   ```
   aws cloudfront get-distribution-config \
       --id DistributionID \
       --output yaml > dist-config.yaml
   ```

   Si el comando se ejecuta correctamente, la AWS CLI no devuelve ninguna salida.

1. Abra el archivo llamado `dist-config.yaml` que ha creado. Edite el archivo para realizar los siguientes cambios.

   1. Cambie el nombre del campo `ETag` a `IfMatch`, pero no cambie el valor del campo.

   1. En el comportamiento de la caché, busque el objeto llamado `FunctionAssociations`. Actualice este objeto para agregar una asociación de función. La sintaxis YAML para una asociación de función se parece al siguiente ejemplo.
      + En el siguiente ejemplo, se muestra un tipo de evento de solicitud del lector (disparador). Para utilizar un tipo de evento de respuesta al lector, reemplace `viewer-request` por `viewer-response`.
      + Reemplace *`arn:aws:cloudfront::111122223333:function/ExampleFunction`* por el nombre de recurso de Amazon (ARN) de la función que está asociando a este comportamiento de la caché. Para obtener el ARN de la función, puede usar el comando **aws cloudfront list-functions**.

      ```
      FunctionAssociations:
        Items:
          - EventType: viewer-request
            FunctionARN: arn:aws:cloudfront::111122223333:function/ExampleFunction
        Quantity: 1
      ```

   1. Después de realizar estos cambios, guarde el archivo.

1. Utilice el siguiente comando para actualizar la distribución y agregue la asociación de función. Para utilizar este comando, haga lo siguiente:
   + Reemplace *`DistributionID`* por el ID de la distribución.
   + Ejecute el comando en una línea. En el ejemplo, se proporcionan saltos de línea para que el ejemplo sea más legible.

   ```
   aws cloudfront update-distribution \
       --id DistributionID \
       --cli-input-yaml file://dist-config.yaml
   ```

   Cuando el comando se realiza correctamente verá una salida como la siguiente, que describe la distribución que se acaba de actualizar con la asociación de función. La siguiente salida de ejemplo se trunca para que sea más legible.

   ```
   Distribution:
     ARN: arn:aws:cloudfront::111122223333:distribution/EBEDLT3BGRBBW
     ... truncated ...
     DistributionConfig:
       ... truncated ...
       DefaultCacheBehavior:
         ... truncated ...
         FunctionAssociations:
           Items:
           - EventType: viewer-request
             FunctionARN: arn:aws:cloudfront::111122223333:function/ExampleFunction
           Quantity: 1
         ... truncated ...
     DomainName: d111111abcdef8.cloudfront.net
     Id: EDFDVBD6EXAMPLE
     LastModifiedTime: '2021-04-19T22:39:09.158000+00:00'
     Status: InProgress
   ETag: E2VJGGQEG1JT8S
   ```

------

El `Status` de la distribución cambia a `InProgress` mientras la distribución se vuelve a implementar. Cuando la nueva configuración de distribución llega a una ubicación periférica de CloudFront, esa ubicación periférica comienza a utilizar la función asociada. Cuando la distribución esté completamente implementada, `Status` volverá a `Deployed`. Esto indica que la CloudFront Function asociada está activa en todas las ubicaciones periféricas de CloudFront en todo el mundo. Esto normalmente dura unos minutos.

# Amazon CloudFront KeyValueStore
<a name="kvs-with-functions"></a>

CloudFront KeyValueStore es un almacén de datos clave-valor seguro, global y de baja latencia que permite el acceso de lectura desde [CloudFront Functions](cloudfront-functions.md), lo que permite una lógica personalizable avanzada en las ubicaciones periféricas de CloudFront. 

Con CloudFront KeyValueStore, puede actualizar el código de la función y los datos asociados a una función de forma independiente. Esta separación simplifica el código de la función y facilita la actualización de los datos sin necesidad de implementar cambios en el código. 

**nota**  
Para usar CloudFront KeyValueStore, la función de CloudFront debe usar el [tiempo de ejecución 2.0 de JavaScript](functions-javascript-runtime-20.md).

A continuación, se muestra el procedimiento general para usar pares clave-valor: 
+ Cree almacenes de clave-valor y llénelos con un conjunto de pares clave-valor. Puede agregar los almacenes de clave-valor a un bucket de Amazon S3 o introducirlos manualmente.
+ Asocie los almacenes de clave-valor a la función de CloudFront.
+ En el código de la función, utilice el nombre de la clave para recuperar el valor asociado a la clave o para evaluar si existe una clave. Para obtener más información sobre el uso de pares clave-valor en el código de la función y sobre los métodos auxiliares, consulte [Métodos auxiliares para almacenes de clave-valor](functions-custom-methods.md).

## Casos de uso
<a name="key-value-store-use-cases"></a>

Puede utilizar pares clave-valor para los siguientes ejemplos:
+ **Reescrituras o redirecciones de URL**: el par clave-valor puede contener las URL reescritas o las URL redirigidas.
+ **Pruebas A/B y marcadores de características**: puede crear una función para realizar experimentos asignando un porcentaje del tráfico a una versión específica del sitio web. 
+ **Autorización de acceso**: puede implementar el control de acceso para permitir o denegar las solicitudes en función de los criterios que haya definido y de los datos almacenados en un almacén de clave-valor.

## Formatos de valores compatibles
<a name="key-value-store-supported-formats"></a>

Puede almacenar el valor en un par clave-valor en cualquiera de los siguientes formatos:
+ Cadena
+ Cadena codificada en bytes
+ JSON 

## Seguridad
<a name="key-value-store-security"></a>

La función de CloudFront y todos los datos de los almacenes de clave-valor se gestionan de forma segura, de la siguiente manera:
+ CloudFront cifra cada almacén de clave-valor en reposo y durante el tránsito (al leer o escribir en los almacenes de clave-valor) cuando llame a las operaciones de la API [CloudFront KeyValueStore](https://docs.aws.amazon.com/cloudfront/latest/APIReference/API_Operations_Amazon_CloudFront_KeyValueStore.html).
+ Cuando se ejecuta la función, CloudFront descifra cada par clave-valor de la memoria en las ubicaciones periféricas de CloudFront. 

Para comenzar a utilizar CloudFront KeyValueStore, consulte los siguientes temas. 

**Topics**
+ [

## Casos de uso
](#key-value-store-use-cases)
+ [

## Formatos de valores compatibles
](#key-value-store-supported-formats)
+ [

## Seguridad
](#key-value-store-security)
+ [

# Trabajo con un almacén de clave-valor
](kvs-with-functions-kvs.md)
+ [

# Trabajo con datos de clave-valor
](kvs-with-functions-kvp.md)
+ Para obtener más información sobre la introducción a CloudFront KeyValueStore, consulte la entrada de blog de AWS [Introducing Amazon CloudFront KeyValueStore](https://aws.amazon.com/blogs/aws/introducing-amazon-cloudfront-keyvaluestore-a-low-latency-datastore-for-cloudfront-functions/).

# Trabajo con un almacén de clave-valor
<a name="kvs-with-functions-kvs"></a>

Debe crear un almacén de clave-valor para almacenar los pares clave-valor que desee utilizar en CloudFront Functions. 

Una vez que cree los almacenes de clave-valor y los pares clave-valor agregados, puede usar las claves-valores en el código de la función de CloudFront. 

Para comenzar, consulte los siguientes temas: 

**Topics**
+ [

# Creación de un almacén de clave-valor
](kvs-with-functions-create.md)
+ [

# Asociación de un almacén de clave-valor a una función
](kvs-with-functions-associate.md)
+ [

# Actualización de un almacén de clave-valor
](kvs-with-functions-edit.md)
+ [

# Obtención de una referencia a un almacén de clave-valor
](kvs-with-functions-get-reference.md)
+ [

# Eliminación de un almacén de clave-valor
](kvs-with-functions-delete.md)
+ [

# Formato de archivo para pares clave-valor
](kvs-with-functions-create-s3-kvp.md)

**nota**  
El tiempo de ejecución 2.0 de JavaScript incluye algunos métodos auxiliares para trabajar con claves-valor en el código de la función. Para obtener más información, consulte [Métodos auxiliares para almacenes de clave-valor](functions-custom-methods.md).

# Creación de un almacén de clave-valor
<a name="kvs-with-functions-create"></a>



Puede crear un almacén de clave-valor y los pares clave-valor al mismo tiempo. Puede crear también un almacén de clave-valor vacío ahora y luego agregar pares clave-valor. 

**nota**  
Si especifica el origen de datos de un bucket de Amazon S3, debe tener los permisos `s3:GetObject` y `s3:GetBucketLocation` de ese bucket. Si no tiene estos permisos, CloudFront no podrá crear correctamente el almacén de clave-valor.

Decida si quiere agregar pares clave-valor al mismo tiempo cuando crea el almacén de clave-valor. Puede importar los pares clave-valor mediante la consola de CloudFront, la API de CloudFront o los AWS SDK. Sin embargo, solo puede importar el archivo de pares clave-valor cuando *inicialmente* crea el almacén de clave-valor. 

Para crear un archivo de pares clave-valor, consulte [Formato de archivo para pares clave-valor](kvs-with-functions-create-s3-kvp.md). 

------
#### [ Console ]

**Creación de un almacén de clave-valor**

1. Inicie sesión en Consola de administración de AWS y abra la página **Funciones** en la consola de CloudFront en [https://console.aws.amazon.com/cloudfront/v4/home#/functions](https://console.aws.amazon.com/cloudfront/v4/home#/functions).

1. Elija la pestaña **KeyValueStores** y, a continuación, elija **Crear KeyValueStore**.

1. Introduzca un nombre y una descripción opcional para el almacén de clave-valor. 

1. Complete **URI de S3**: 
   + Si tiene un archivo de pares clave-valor, ingrese la ruta al bucket de Amazon S3 donde ha almacenado el archivo. 
   + Deje este campo en blanco si piensa ingresar los pares clave-valor manualmente. 

1. Seleccione **Crear**. El almacén de clave-valor ya existe.

   Aparece la página de detalles del nuevo almacén de clave-valor. La información de la página incluye el ID y el ARN del almacén de clave-valor. 
   + El ID es una cadena aleatoria de caracteres que es única en la Cuenta de AWS. 
   + El ARN tiene la siguiente sintaxis:

     *Cuenta de AWS*`:key-value-store/`*el ID del almacén de clave-valor*

1. Consulte la sección de **Pares clave-valor**. Si ha importado un archivo, en esta sección se muestran algunos pares clave-valor. Se puede hacer lo siguiente:
   + Si ha importado un archivo, también puede agregar más valores manualmente. 
   + Si no ha importado un archivo desde un bucket de Amazon S3 y desea agregar pares clave-valor ahora, puede completar el siguiente paso.
   + Puede omitir este paso y agregar los pares clave-valor más adelante. 

1. Para agregar los pares ahora:

   1. Elija **Agregar pares clave-valor**. 

   1. Seleccione **Agregar par** e introduzca un nombre y un valor. Repita este paso para agregar más pares.

   1. Cuando haya terminado, elija **Guardar cambios** para guardar todos los pares clave-valor del almacén de clave-valor. En el cuadro de diálogo que aparece, elija **Listo**.

1. Para asociar ahora el almacén de clave-valor a una función, complete la sección **Funciones asociadas**. Para obtener más información, consulte [Creación de funciones](create-function.md) o [Actualización de funciones](update-function.md). 

   También puede asociar la función más adelante, ya sea desde esta página de detalles del almacén de clave-valor o desde la página de detalles de la función.

------
#### [ AWS CLI ]

**Creación de un almacén de clave-valor**
+ Ejecute el siguiente comando para crear un almacén clave-valor e importar los pares clave-valor de un bucket de Amazon S3.

  ```
  aws cloudfront create-key-value-store \
      --name=keyvaluestore1 \
      --comment="This is my key value store file" \
      --import-source=SourceType=S3,SourceARN=arn:aws:s3:::amzn-s3-demo-bucket1/kvs-input.json
  ```

  **Respuesta**

  ```
  {
      "ETag": "ETVABCEXAMPLE",
      "Location": "https://cloudfront.amazonaws.com/2020-05-31/key-value-store/arn:aws:cloudfront::123456789012:key-value-store/8aa76c93-3198-462c-aaf6-example",
      "KeyValueStore": {
          "Name": "keyvaluestore1",
          "Id": "8aa76c93-3198-462c-aaf6-example",
          "Comment": "This is my key value store file",
          "ARN": "arn:aws:cloudfront::123456789012:key-value-store/8aa76c93-3198-462c-aaf6-example",
          "Status": "PROVISIONING",
          "LastModifiedTime": "2024-08-06T22:19:10.813000+00:00"
      }
  }
  ```

------
#### [ API ]

**Creación de un almacén de clave-valor**

1. Utilice la operación [CreateKeyValueStore de CloudFront](https://docs.aws.amazon.com/cloudfront/latest/APIReference/API_CreateKeyValueStore.html). La operación requiere varios parámetros:
   + Un `name` del almacén de clave-valor.
   + Un parámetro `comment` que incluye un comentario.
   + Un parámetro `import-source` que permite importar pares clave-valor desde un archivo almacenado en un bucket de Amazon S3. Solo podrá importar desde un archivo cuando cree por primera vez el almacén clave-valor. Para obtener información sobre la estructura de archivos, consulte [Formato de archivo para pares clave-valor](kvs-with-functions-create-s3-kvp.md).

La respuesta de la operación incluye la siguiente información:
+ Los valores transferidos en la solicitud, incluido el nombre que asignó.
+ Datos como la hora de creación.
+ Una `ETag` (por ejemplo, `ETVABCEXAMPLE`), el ARN que incluye el nombre del almacén de clave-valor (por ejemplo, `arn:aws:cloudfront::123456789012:key-value-store/keyvaluestore1`). 

  Utilizará alguna combinación de la `ETag`, el ARN y el nombre para trabajar con el almacén de clave-valor mediante programación.

------

## Estados del almacén de clave-valor
<a name="key-value-store-status"></a>

Al crear un almacén de clave-valor, el almacén de datos puede tener los siguientes valores de estado.


****  

| Valor | Descripción | 
| --- | --- | 
|  **Aprovisionando**  |  Se ha creado el almacén de clave-valor y CloudFront está procesando el origen de datos que usted ha especificado.  | 
|  **Ready**  |  Se ha creado el almacén de clave-valor y CloudFront ha procesado correctamente el origen de datos que usted ha especificado.  | 
|  **Error al importar**  |  CloudFront no ha podido procesar el origen de datos que usted ha especificado. Este estado puede aparecer si el formato de archivo no es válido o si supera el límite de tamaño. Para obtener más información, consulte [Formato de archivo para pares clave-valor](kvs-with-functions-create-s3-kvp.md).  | 

# Asociación de un almacén de clave-valor a una función
<a name="kvs-with-functions-associate"></a>

Después de crear el almacén de clave-valor, puede actualizar la función para asociarla al almacén de clave-valor. Debe realizar esta asociación para utilizar los pares clave-valor de ese almacén en esa función. Se aplican las siguientes reglas:
+ Una función solo puede tener un almacén de clave-valor
+ Puede asociar el mismo almacén de clave-valor a varias funciones

------
#### [ Console ]

**Asociación de un almacén de clave-valor a una función**

1. Inicie sesión en la consola de CloudFront en [https://console.aws.amazon.com/cloudfront/v4/home#/functions](https://console.aws.amazon.com/cloudfront/v4/home#/functions) y elija la página **Funciones**.

1. Elija el nombre de la función.

1. Vaya a la sección **Asociar KeyValueStore** y elija **Asociar KeyValueStore existente**.

1. Seleccione el almacén de clave-valor que contiene los pares clave-valor de la función y, a continuación, elija **Asociar KeyValueStore**.

   CloudFront asocia inmediatamente el almacén a la función. No necesita guardar la función.

1. Para especificar un almacén de clave-valor diferente, elija **Actualizar KeyValueStore asociado**, seleccione otro nombre de almacén de clave-valor y, a continuación, elija **Asociar KeyValueStore**.

Para obtener más información, consulte [Actualización de funciones](update-function.md).

------
#### [ AWS CLI ]

**Asociación de un almacén de clave-valor a una función**
+ Ejecute el siguiente comando para actualizar la función `MaxAge` y asociar un recurso de almacén de clave-valor.

  ```
  aws cloudfront update-function \
      --name MaxAge \
      --function-config '{"Comment":"Max Age 2 years","Runtime":"cloudfront-js-2.0","KeyValueStoreAssociations":{"Quantity":1,"Items":[{"KeyValueStoreARN":"arn:aws:cloudfront::123456789012:key-value-store/8aa76c93-3198-462c-aaf6-example"}]}}' \
      --function-code fileb://function-max-age-v1.js \
      --if-match ETVABCEXAMPLE
  ```
+ Para asociar un almacén de clave-valor a una función, especifique el parámetro `KeyValueStoreAssociations` y el ARN del almacén de clave-valor. 
+ Para cambiar la asociación, especifique otro ARN de almacén de clave-valor. 
+ Para eliminar la asociación, quite el parámetro `KeyValueStoreAssociations`. 

Para obtener más información, consulte [Actualización de funciones](update-function.md).

------
#### [ API ]

**Asociación de un almacén de clave-valor a una función**
+ Utilice la operación de la API [UpdateFunction](https://docs.aws.amazon.com/cloudfront/latest/APIReference/API_UpdateFunction.html). Para obtener más información, consulte [Actualización de funciones](update-function.md).

------

**Notas**  
Si modifica un almacén de clave-valor sin cambiar los pares clave-valor o si solo modifica los pares clave-valor sin cambiar el almacén de clave-valor, no necesita volver a asociarlo. Tampoco necesita volver a publicar la función.  
Sin embargo, le recomendamos que pruebe la función para comprobar que funciona según lo previsto. Para obtener más información, consulte [Prueba de funciones](test-function.md).
Puede ver todas las funciones que utilizan determinados almacenes de clave-valor. En la consola de CloudFront, elija la página de detalles del almacén de clave-valor. 

# Actualización de un almacén de clave-valor
<a name="kvs-with-functions-edit"></a>

Al actualizar un almacén de clave-valor, puede cambiar los pares clave-valor o cambiar la asociación entre el almacén de clave-valor y la función.

------
#### [ Console ]

**Actualización de un almacén de clave-valor**

1. Inicie sesión en Consola de administración de AWS y abra la página **Funciones** en la consola de CloudFront en [https://console.aws.amazon.com/cloudfront/v4/home#/functions](https://console.aws.amazon.com/cloudfront/v4/home#/functions).

1. Elija la pestaña **KeyValueStores**.

1.  Seleccione el almacén de clave-valor que desee actualizar. 
   + Para actualizar los pares clave-valor, elija **Editar** en la sección **Pares clave-valor**. Puede agregar o eliminar cualquier par clave-valor. También puede cambiar el valor de un par clave-valor existente. Cuando haya finalizado, elija **Save changes** (Guardar cambios).
   + Para actualizar la asociación de este almacén de clave-valor, elija **Ir a las funciones**. Para obtener más información, consulte [Asociación de un almacén de clave-valor a una función](kvs-with-functions-associate.md).

------
#### [ AWS CLI ]

**Actualización de un almacén de clave-valor**

1. **Cambiar los pares clave-valor**: puede agregar más pares clave-valor, eliminar uno o varios pares clave-valor y cambiar el valor de un par clave-valor existente. Para obtener más información, consulte [Trabajo con datos de clave-valor](kvs-with-functions-kvp.md).

1. **Cambiar la asociación de funciones para el almacén de clave-valor**: para actualizar la asociación de funciones para el almacén de clave-valor, consulte [Asociación de un almacén de clave-valor a una función](kvs-with-functions-associate.md). 
**sugerencia**  
Necesitará el ARN del almacén de clave-valor. Para obtener más información, consulte [Obtención de una referencia a un almacén de clave-valor](kvs-with-functions-get-reference.md).

------
#### [ API ]

**Actualización de un almacén de clave-valor**

1. **Cambiar los pares clave-valor**: puede agregar más pares clave-valor, eliminar uno o varios pares clave-valor y cambiar el valor de un par clave-valor existente. Para obtener más información, consulte [Trabajo con datos de clave-valor](kvs-with-functions-kvp.md).

1. **Cambiar la asociación de funciones para el almacén de clave-valor**: para actualizar la asociación de funciones para el almacén de clave-valor, utilice la operación de la API [UpdateFunction](https://docs.aws.amazon.com/cloudfront/latest/APIReference/API_UpdateFunction.html). Para obtener más información, consulte [Actualización de funciones](update-function.md). 
**sugerencia**  
Necesitará el ARN del almacén de clave-valor. Para obtener más información, consulte [Obtención de una referencia a un almacén de clave-valor](kvs-with-functions-get-reference.md).

------

# Obtención de una referencia a un almacén de clave-valor
<a name="kvs-with-functions-get-reference"></a>

Para trabajar con los almacenes de clave-valor mediante programación, necesita la `ETag` y el nombre del almacén de clave-valor. 

Para obtener ambos valores, puede usar la AWS Command Line Interface (AWS CLI) o la API de CloudFront.

------
#### [ AWS CLI ]

**Obtención de la referencia del almacén de clave-valor**

1. Para obtener una lista de almacenes de clave-valor, ejecute el siguiente comando. Busque el nombre del almacén de clave-valor que desea modificar.

   ```
   aws cloudfront list-key-value-stores
   ```

1. A partir de la respuesta, busque el nombre del almacén de clave-valor que desee.

   **Respuesta**

   ```
   {
       "KeyValueStoreList": {
           "Items": [
               {
                   "Name": "keyvaluestore3",
                   "Id": "37435e19-c205-4271-9e5c-example3",
                   "ARN": "arn:aws:cloudfront::123456789012:key-value-store/37435e19-c205-4271-9e5c-example3",
                   "Status": "READY",
                   "LastModifiedTime": "2024-05-08T14:50:18.876000+00:00"
               },
               {
                   "Name": "keyvaluestore2",
                   "Id": "47970d59-6408-474d-b850-example2",
                   "ARN": "arn:aws:cloudfront::123456789012:key-value-store/47970d59-6408-474d-b850-example2",
                   "Status": "READY",
                   "LastModifiedTime": "2024-05-30T21:06:22.113000+00:00"
               },
               {
                   "Name": "keyvaluestore1",
                   "Id": "8aa76c93-3198-462c-aaf6-example",
                   "ARN": "arn:aws:cloudfront::123456789012:key-value-store/8aa76c93-3198-462c-aaf6-example",
                   "Status": "READY",
                   "LastModifiedTime": "2024-08-06T22:19:30.510000+00:00"
               }
           ]
       }
   }
   ```

1. Ejecute el siguiente comando para devolver la `ETag` para el almacén de clave-valor especificado.

   ```
   aws cloudfront describe-key-value-store \
       --name=keyvaluestore1
   ```

   **Respuesta**

   ```
   {
       "ETag": "E3UN6WX5RRO2AG",
       "KeyValueStore": {
           "Name": "keyvaluestore1",
           "Id": "8aa76c93-3198-462c-aaf6-example",
           "Comment": "This is an example KVS",
           "ARN": "arn:aws:cloudfront::123456789012:key-value-store/8aa76c93-3198-462c-aaf6-example",
           "Status": "READY",
           "LastModifiedTime": "2024-08-06T22:19:30.510000+00:00"
       }
   }
   ```

------
#### [ API ]

**Obtención de la referencia del almacén de clave-valor**

1. Utilice la operación de la API [https://docs.aws.amazon.com/cloudfront/latest/APIReference/API_ListKeyValueStores.html](https://docs.aws.amazon.com/cloudfront/latest/APIReference/API_ListKeyValueStores.html) para obtener una lista de almacenes de clave-valor. Busque el nombre del almacén de clave-valor que desee cambiar. 

1. Utilice la operación de la API [https://docs.aws.amazon.com/cloudfront/latest/APIReference/API_DescribeKeyValueStore.html](https://docs.aws.amazon.com/cloudfront/latest/APIReference/API_DescribeKeyValueStore.html) y especifique el nombre del almacén de clave-valor que devolvió en el paso anterior. 

------

La respuesta incluye un UUID, el ARN del almacén de clave-valor y la `ETag` del almacén de clave-valor.
+ Una `ETag`, como `E3UN6WX5RRO2AG`
+ El UUID es de 128 bits, como `8aa76c93-3198-462c-aaf6-example`
+ El ARN incluye el número de Cuenta de AWS, el `key-value-store` constante y el UUID, como en el siguiente ejemplo:

  `arn:aws:cloudfront::123456789012:key-value-store/8aa76c93-3198-462c-aaf6-example`

Para obtener más información acerca de la operación `DescribeKeyValueStore`, consulte [Acerca de CloudFront KeyValueStore](kvs-with-functions-kvp.md#kvs-with-functions-api-describe).

# Eliminación de un almacén de clave-valor
<a name="kvs-with-functions-delete"></a>

Puede eliminar el almacén de clave-valor mediante la consola de Amazon CloudFront o la API.

------
#### [ Console ]

**Eliminación de un almacén de clave-valor**

1. Inicie sesión en Consola de administración de AWS y abra la página **Funciones** en la consola de CloudFront en [https://console.aws.amazon.com/cloudfront/v4/home#/functions](https://console.aws.amazon.com/cloudfront/v4/home#/functions).

1. Elija el nombre de la función.

1. En la sección **KeyValueStore asociado**, compruebe si hay un almacén de clave-valor asociado a la función. Si es así, elimine la asociación eligiendo **Desasociar KeyValueStore** y, a continuación, elija **Eliminar asociación**.

1. En el panel de navegación, elija la página **Funciones** y, a continuación, elija la pestaña **KeyValueStores**. 

1. Seleccione el almacén de clave-valor que desea eliminar y, a continuación, elija **Eliminar**.

------
#### [ AWS CLI ]

**Eliminación de un almacén de clave-valor**

1. Obtenga la `ETag` y el nombre de los almacenes de clave-valor. Para obtener más información, consulte [Obtención de una referencia a un almacén de clave-valor](kvs-with-functions-get-reference.md).

1. Compruebe si los almacenes de clave-valor están asociados a una función. Si lo está, elimine la asociación. Para obtener más información sobre los dos pasos, consulte [Actualización de funciones](update-function.md).

1. Cuando tenga el nombre y la `ETag` del almacén de clave-valor y ya no esté asociado a una función, podrá eliminarlo.

   Ejecute el siguiente comando para eliminar el almacén de clave-valor especificado.

   ```
   aws cloudfront delete-key-value-store \
       --name=keyvaluestore1 \
       --if-match=E3UN6WX5RRO2AG
   ```

------
#### [ API ]

**Eliminación de un almacén de clave-valor**

1. Obtenga la `ETag` y el nombre de los almacenes de clave-valor. Para obtener más información, consulte [Obtención de una referencia a un almacén de clave-valor](kvs-with-functions-get-reference.md).

1. Compruebe si los almacenes de clave-valor están asociados a una función. Si lo está, elimine la asociación. Para obtener más información sobre los dos pasos, consulte [Actualización de funciones](update-function.md).

1. Para eliminar el almacén de clave-valor, utilice la operación de la API [https://docs.aws.amazon.com/cloudfront/latest/APIReference/API_DeleteKeyValueStore.html](https://docs.aws.amazon.com/cloudfront/latest/APIReference/API_DeleteKeyValueStore.html) de CloudFront.

------

# Formato de archivo para pares clave-valor
<a name="kvs-with-functions-create-s3-kvp"></a>

Al crear un archivo codificado con UTF-8, utilice el siguiente formato JSON:

```
{
  "data":[
    {
      "key":"key1",
      "value":"value"
    },
    {
      "key":"key2",
      "value":"value"
    }
  ]
}
```

El archivo no puede incluir claves duplicadas. Si especificó un archivo no válido en el bucket de Amazon S3, puede actualizar el archivo para eliminar cualquier duplicado y, a continuación, intentar crear de nuevo el almacén de clave-valor.

Para obtener más información, consulte [Creación de un almacén de clave-valor](kvs-with-functions-create.md).

**nota**  
El archivo de su origen de datos y sus pares clave-valor tienen los siguientes límites:  
Tamaño del archivo: 5 MB
Tamaño de la clave: 512 caracteres
Tamaño del valor: 1024 caracteres

# Trabajo con datos de clave-valor
<a name="kvs-with-functions-kvp"></a>

Este tema describe cómo agregar pares clave-valor a un almacén de clave-valor existente. Para incluir pares clave-valor al crear inicialmente los almacenes de clave-valor, consulte [Creación de un almacén de clave-valor](kvs-with-functions-create.md).

**Topics**
+ [

## Uso de pares clave-valor (consola)
](#kvs-with-functions-kvp-using-console)
+ [

## Acerca de CloudFront KeyValueStore
](#kvs-with-functions-api-describe)
+ [

## Uso de pares clave-valor (AWS CLI)
](#work-with-kvs-cli-keys)
+ [

## Uso de pares clave-valor (API)
](#kvs-with-functions-kvp-using-api)

## Uso de pares clave-valor (consola)
<a name="kvs-with-functions-kvp-using-console"></a>

Puede utilizar la consola de CloudFront para trabajar con los pares clave-valor.

**Trabajo con pares clave-valor**

1. Inicie sesión en Consola de administración de AWS y abra la página **Funciones** en la consola de CloudFront en [https://console.aws.amazon.com/cloudfront/v4/home#/functions](https://console.aws.amazon.com/cloudfront/v4/home#/functions).

1. Elija la pestaña **KeyValueStores**. 

1. Seleccione el almacén de clave-valor que desee cambiar.

1. En la sección **Pares clave-valor**, elija **Editar**. 

1. Puede agregar un par clave-valor, eliminar cualquier par clave-valor o cambiar el valor de un par clave-valor existente. 

1. Cuando haya finalizado, elija **Save changes** (Guardar cambios).

## Acerca de CloudFront KeyValueStore
<a name="kvs-with-functions-api-describe"></a>

**sugerencia**  
La API KeyValueStore de CloudFront es un servicio global que utiliza Signature Version 4A (SigV4A) para la autenticación. Utilizar credenciales temporales con SigV4A requiere tokens de sesión de la versión 2. Para obtener más información, consulte [Uso de credenciales temporales con la API KeyValueStore de CloudFront](cloudfront-function-restrictions.md#regional-endpoint-for-key-value-store).

Si utiliza la AWS Command Line Interface (AWS CLI) o el código propio para llamar a la API KeyValueStore de CloudFront, consulte las secciones siguientes. 

Cuando trabaja con un almacén de clave-valor y sus pares clave-valor, el servicio al que llame depende del caso de uso:
+ Para trabajar con pares clave-valor en un almacén de clave-valor *existente*, utilice el servicio KeyValueStore de CloudFront. 
+ Para incluir pares clave-valor en el almacén de clave-valor al crear *inicialmente* el almacén de clave-valor, utilice el servicio de CloudFront.

Tanto la API de CloudFront como la API de CloudFront KeyValueStore tienen una operación `DescribeKeyValueStore`. Las llama por diferentes motivos. Para entender las diferencias, consulte la siguiente tabla.


|  | API de CloudFront DescribeKeyValueStore | API de CloudFront KeyValueStore DescribeKeyValueStore | 
| --- | --- | --- | 
| Datos sobre el almacén de clave-valor |  Devuelve datos, como el estado y la fecha en que se modificó por última vez el propio almacén de clave-valor.  |  Devuelve datos sobre el *contenido* del recurso de almacenamiento: los pares clave-valor del almacén y el tamaño del contenido.  | 
| Datos que identifican el almacén de clave-valor |  Devuelve una `ETag`, el UUID y el ARN del almacén de clave-valor.  |  Devuelve una `ETag` y el ARN del almacén de clave-valor.  | 

**Notas**  
Cada operación DescribeKeyValueStore devuelve una `ETag` *diferente*. Las `ETags` no son intercambiables.
Al llamar a una operación de la API para completar una acción, debe especificar la `ETag` de la API correspondiente. Por ejemplo, en la operación [DeleteKey](https://docs.aws.amazon.com/cloudfront/latest/APIReference/API_kvs_DeleteKey.html) de KeyValueStore de CloudFront, especifique la `ETag` que devolvió de la operación [https://docs.aws.amazon.com/cloudfront/latest/APIReference/API_kvs_DescribeKeyValueStore.html](https://docs.aws.amazon.com/cloudfront/latest/APIReference/API_kvs_DescribeKeyValueStore.html) de KeyValueStore de CloudFront.
Cuando invoca CloudFront Functions mediante CloudFront KeyValueStore, los valores del almacén de valores clave no se actualizan ni cambian durante la invocación de la función. Las actualizaciones se procesan entre las invocaciones de una función.

## Uso de pares clave-valor (AWS CLI)
<a name="work-with-kvs-cli-keys"></a>

Puede ejecutar los siguientes comandos de la AWS Command Line Interface para KeyValueStore de CloudFront.

**Contents**
+ [

### Enumeración de pares clave-valor
](#kvs-cli-list-keys)
+ [

### Obtención de pares clave-valor
](#kvs-cli-get-keys)
+ [

### Descripción de un almacén de clave-valor
](#kvs-cli-describe-keys)
+ [

### Creación de un par clave-valor
](#kvs-cli-create-keys)
+ [

### Eliminación de un par clave-valor
](#kvs-cli-delete-keys)
+ [

### Actualización de pares clave-valor
](#kvs-cli-update-key)

### Enumeración de pares clave-valor
<a name="kvs-cli-list-keys"></a>

Para enumerar los pares clave-valor del almacén de clave-valor, ejecute el siguiente comando.

```
aws cloudfront-keyvaluestore list-keys \
    --kvs-arn=arn:aws:cloudfront::123456789012:key-value-store/37435e19-c205-4271-9e5c-example
```

**Respuesta**

```
{
    "Items": [
        {
            "Key": "key1",
            "Value": "value1"
        }
    ]
}
```

### Obtención de pares clave-valor
<a name="kvs-cli-get-keys"></a>

Para obtener un par clave-valor del almacén de clave-valor, ejecute el siguiente comando.

```
aws cloudfront-keyvaluestore get-key \
    --key=key1 \
    --kvs-arn=arn:aws:cloudfront::123456789012:key-value-store/37435e19-c205-4271-9e5c-example
```

**Respuesta**

```
{
    "Key": "key1",
    "Value": "value1",
    "ItemCount": 1,
    "TotalSizeInBytes": 11
}
```

### Descripción de un almacén de clave-valor
<a name="kvs-cli-describe-keys"></a>

Para describir un almacén de clave-valor, ejecute el siguiente comando.

```
aws cloudfront-keyvaluestore describe-key-value-store \
    --kvs-arn=arn:aws:cloudfront::123456789012:key-value-store/37435e19-c205-4271-9e5c-example
```

**Respuesta**

```
{
    "ETag": "KV1F83G8C2ARO7P",
    "ItemCount": 1,
    "TotalSizeInBytes": 11,
    "KvsARN": "arn:aws:cloudfront::123456789012:key-value-store/37435e19-c205-4271-9e5c-example",
    "Created": "2024-05-08T07:48:45.381000-07:00",
    "LastModified": "2024-08-05T13:50:58.843000-07:00",
    "Status": "READY"
}
```

### Creación de un par clave-valor
<a name="kvs-cli-create-keys"></a>

Para crear un par clave-valor en el almacén de clave-valor, ejecute el siguiente comando.

```
aws cloudfront-keyvaluestore put-key \
    --if-match=KV1PA6795UKMFR9 \
    --key=key2 \
    --value=value2 \
    --kvs-arn=arn:aws:cloudfront::123456789012:key-value-store/37435e19-c205-4271-9e5c-example
```

**Respuesta**

```
{
    "ETag": "KV13V1IB3VIYZZH",
    "ItemCount": 3,
    "TotalSizeInBytes": 31
}
```

### Eliminación de un par clave-valor
<a name="kvs-cli-delete-keys"></a>

Para eliminar un par clave-valor, ejecute el siguiente comando.

```
aws cloudfront-keyvaluestore delete-key \
    --if-match=KV13V1IB3VIYZZH \
    --key=key1 \
    --kvs-arn=arn:aws:cloudfront::123456789012:key-value-store/37435e19-c205-4271-9e5c-example
```

**Output**

```
{
    "ETag": "KV1VC38T7YXB528",
    "ItemCount": 2,
    "TotalSizeInBytes": 22
}
```

### Actualización de pares clave-valor
<a name="kvs-cli-update-key"></a>

Puede utilizar el comando `update-keys` para actualizar más de un par clave-valor. Por ejemplo, para eliminar un par clave-valor existente y crear otro, ejecute el siguiente comando.

```
aws cloudfront-keyvaluestore update-keys \
    --if-match=KV2EUQ1WTGCTBG2 \
    --kvs-arn=arn:aws:cloudfront::123456789012:key-value-store/37435e19-c205-4271-9e5c-example \
    --deletes '[{"Key":"key2"}]' \
    --puts '[{"Key":"key3","Value":"value3"}]'
```

**Respuesta**

```
{
    "ETag": "KV3AEGXETSR30VB",
    "ItemCount": 3,
    "TotalSizeInBytes": 28
}
```

## Uso de pares clave-valor (API)
<a name="kvs-with-functions-kvp-using-api"></a>

Siga esta sección para trabajar con los pares clave-valor mediante programación. 

**Contents**
+ [

### Obtención de una referencia a un almacén de clave-valor
](#kvs-with-functions-api-ref)
+ [

### Cambio de los pares clave-valor en un almacén de clave-valor
](#kvs-with-functions-api-actions)
+ [

### Código de ejemplo para CloudFront KeyValueStore
](#example-code-key-value-store)

### Obtención de una referencia a un almacén de clave-valor
<a name="kvs-with-functions-api-ref"></a>

Cuando utilice la API KeyValueStore de CloudFront para llamar a una operación de escritura, debe especificar el ARN y la `ETag` del almacén de clave-valor. Para obtener estos datos, haga lo siguiente:

**Obtención de una referencia a un almacén de clave-valor**

1. Utilice la operación de la API [https://docs.aws.amazon.com/cloudfront/latest/APIReference/API_ListKeyValueStores.html](https://docs.aws.amazon.com/cloudfront/latest/APIReference/API_ListKeyValueStores.html) para obtener una lista de almacenes de clave-valor. Busque el almacén de clave-valor que desee cambiar. 

1. Utilice la [operación de la API CloudFrontKeyValueStore DescribeKeyValueStore](https://docs.aws.amazon.com/cloudfront/latest/APIReference/API_kvs_DescribeKeyValueStore.html) y especifique el almacén de clave-valor del paso anterior.

   La respuesta incluye el ARN y la `ETag` del almacén de clave-valor. 
   + El ARN incluye el número de Cuenta de AWS, el `key-value-store` constante y el UUID, como en el siguiente ejemplo:

     `arn:aws:cloudfront::123456789012:key-value-store/a1b2c3d4-5678-90ab-cdef-EXAMPLE11111`
   + Una `ETag` como la del siguiente ejemplo: 

     `ETVABCEXAMPLE2`

### Cambio de los pares clave-valor en un almacén de clave-valor
<a name="kvs-with-functions-api-actions"></a>

Puede especificar el almacén de clave-valor que contiene el par clave-valor que desea actualizar. 

Consulte las siguientes operaciones de la API de CloudFront KeyValueStore:
+ [CloudFrontKeyValueStore DeleteKey](https://docs.aws.amazon.com/cloudfront/latest/APIReference/API_kvs_DeleteKey.html): elimina un par clave-valor
+ [CloudFrontKeyValueStore GetKey](https://docs.aws.amazon.com/cloudfront/latest/APIReference/API_kvs_GetKey.html): devuelve un par clave-valor
+ [CloudFrontKeyValueStore ListKeys](https://docs.aws.amazon.com/cloudfront/latest/APIReference/API_kvs_ListKeys.html): devuelve una lista de pares clave-valor 
+ [CloudFrontKeyValueStore PutKey](https://docs.aws.amazon.com/cloudfront/latest/APIReference/API_kvs_PutKey.html): puede realizar las siguientes tareas:
  + Cree un par clave-valor en un almacén de clave-valor especificando un nombre y un valor de clave nuevos.
  + Establezca un valor diferente en un par clave-valor existente especificando un nombre de clave existente y un valor de clave nuevo.
+ [CloudFrontKeyValueStore UpdateKeys](https://docs.aws.amazon.com/cloudfront/latest/APIReference/API_kvs_UpdateKeys.html): puede realizar una o más de las siguientes acciones en una operación de todo o nada:
  + Eliminación de uno o varios pares clave-valor
  + Creación de uno o varios pares clave-valor nuevos
  + Establecimiento de un valor diferente en uno o varios pares clave-valor existentes

### Código de ejemplo para CloudFront KeyValueStore
<a name="example-code-key-value-store"></a>

**Example**  
En el siguiente código, se muestra cómo llamar a la operación de la API `DescribeKeyValueStore` de un almacén de clave-valor.  

```
const {
  CloudFrontKeyValueStoreClient,
  DescribeKeyValueStoreCommand,
} = require("@aws-sdk/client-cloudfront-keyvaluestore");

require("@aws-sdk/signature-v4-crt");

(async () => {
  try {
    const client = new CloudFrontKeyValueStoreClient({
      region: "us-east-1"
    });
    const input = {
      KvsARN: "arn:aws:cloudfront::123456789012:key-value-store/a1b2c3d4-5678-90ab-cdef-EXAMPLE11111",
    };
    const command = new DescribeKeyValueStoreCommand(input);

    const response = await client.send(command);
  } catch (e) {
    console.log(e);
  }
})();
```

# Personalización con funciones de conexión de CloudFront
<a name="customize-connections-validation-with-connection-functions"></a>

Las funciones de conexión de CloudFront permiten escribir funciones de JavaScript sencillas para la validación de certificados mTLS y la lógica de autenticación personalizada. Las funciones de conexión se ejecutan durante el establecimiento de la conexión de mTLS para validar los certificados de los clientes, implementar reglas de autenticación específicas del dispositivo y gestionar los escenarios de revocación de certificados. El entorno de tiempo de ejecución de funciones de conexión ofrece tiempos de arranque de submilisegundos, se escala inmediatamente para gestionar millones de solicitudes por segundo y es altamente seguro. Las funciones de conexión son características nativas de CloudFront, lo que significa que puede compilar, probar e implementar el código completamente dentro de CloudFront.

Cuando asocia una función de conexión con una distribución de CloudFront habilitada para mTLS, CloudFront intercepta solicitudes de conexión de TLS en ubicaciones periféricas de CloudFront y pasa la información de certificado a la función. Puede invocar funciones de conexión cuando se produce el siguiente evento:
+ Durante el establecimiento de la conexión de TLS (solicitud de conexión): para conexiones de TLS mutuas (mTLS)

Para obtener más información sobre las funciones de conexión, consulte los siguientes temas.

**Topics**
+ [

# Información general y flujo de trabajo
](connection-functions-overview.md)
+ [

# Configuración y límites
](connection-function-configuration-limits.md)
+ [

# Creación de funciones de conexión de CloudFront para la validación de TLS mutua (espectador)
](create-connection-functions.md)
+ [

# Escritura de código de función de conexión de CloudFront para la validación de TLS mutua (espectador)
](write-connection-function-code.md)
+ [

# Prueba de las funciones de conexión de CloudFront antes de la implementación
](test-connection-functions.md)
+ [

# Asociación de funciones de conexión con distribuciones
](associate-connection-functions.md)
+ [

# Implementación de la revocación de certificados para TLS mutua (espectador) con CloudFront Functions y KeyValueStore
](implement-certificate-revocation.md)

# Información general y flujo de trabajo
<a name="connection-functions-overview"></a>

Las funciones de conexión de CloudFront son un tipo especializado de CloudFront Functions que se ejecutan durante el establecimiento de comunicación de TLS cuando un cliente intenta establecer una conexión de mTLS. La función de conexión puede acceder a la información de los certificados del cliente, a los parámetros de configuración de mTLS, a los resultados de las comprobaciones de revocación de certificados y a la dirección IP del cliente.

Las funciones de conexión se invocan después de que CloudFront lleve a cabo la validación estándar del certificado (cadena de confianza, caducidad, verificación de firma), pero pueden ejecutarse incluso si las comprobaciones de revocación de certificados producen un error. Esto permite implementar una lógica personalizada para gestionar los certificados revocados o agregar criterios de validación adicionales.

Cuando crea y publica una función de conexión, asegúrese de agregar una asociación para el tipo de evento solicitud de conexión con una distribución con mTLS. Esto hace que la función se ejecute cada vez que un cliente intenta establecer una conexión de mTLS con CloudFront.

Las funciones de conexión de CloudFront siguen un ciclo de vida de dos etapas que permite desarrollar y probar funciones antes de implementarlas en producción. Este flujo de trabajo garantiza que las funciones de conexión funcionen correctamente antes de que afecten al tráfico en directo.

**Topics**
+ [

## Etapas de la función
](#connection-function-stages)
+ [

## Flujo de trabajo de desarrollo
](#connection-function-development-workflow)
+ [

## Diferencias con otros tipos de funciones
](#connection-function-differences)

## Etapas de la función
<a name="connection-function-stages"></a>

Las funciones de conexión existen en una de estas dos etapas:
+ **DESARROLLO**: las funciones de esta etapa se pueden modificar, probar y actualizar. Utilice esta etapa para escribir y depurar el código de la función.
+ **ACTIVA**: las funciones de esta etapa son de solo lectura y gestionan el tráfico de producción. No se pueden modificar las funciones directamente en la etapa ACTIVA.

Cuando se crea una nueva función de conexión, esta comienza en la etapa de **DESARROLLO**. Tras la prueba y la validación, se publica la función para pasarla a la etapa **ACTIVA**.

## Flujo de trabajo de desarrollo
<a name="connection-function-development-workflow"></a>

Siga este flujo de trabajo para desarrollar e implementar las funciones de conexión:

1. **Crear**: cree una nueva función de conexión en la etapa de DESARROLLO con el código y la configuración iniciales.

1. **Probar**: utilice la funcionalidad de prueba para validar la función con ejemplos de eventos de conexión antes de la implementación.

1. **Actualizar**: modifique el código y la configuración de la función según sea necesario en función de los resultados de las pruebas.

1. **Publicar**: cuando esté lista para la producción, publique la función para pasarla de la etapa de DESARROLLO a la etapa ACTIVA.

1. **Asociar**: asocie la función publicada a la distribución compatible con mTLS para gestionar las conexiones en directo.

Para realizar cambios en una función ACTIVA, debe actualizar la versión de DESARROLLO y volver a publicarla. Así se creará una versión nueva en la etapa ACTIVA.

## Diferencias con otros tipos de funciones
<a name="connection-function-differences"></a>

Las funciones de conexión se diferencian de las funciones de solicitud y respuesta del espectador en varios aspectos importantes:
+ Las funciones de conexión se ejecutan después del establecimiento de comunicación de mTLS, antes de que se produzca cualquier procesamiento HTTP.
+ Las funciones de conexión tienen acceso a la información del certificado TLS en lugar de a los datos de solicitud/respuesta HTTP.
+ Las funciones de conexión solo pueden permitir o denegar las conexiones, no modificar los datos HTTP.
+ Las funciones de conexión solo se invocan para las nuevas conexiones TLS, no para su reutilización.
+ mTLS no admite la reanudación de la sesión TLS para garantizar que la validación del certificado se realice en todas las conexiones.
+ Las funciones de conexión se ejecutan de forma adicional a las funciones de solicitud del espectador y respuesta del espectador.
+ Las funciones de conexión se asocian por distribución, en lugar de por comportamiento de la caché.
+ Las funciones de conexión solo admiten tiempo de ejecución 2.0 de JavaScript.

# Configuración y límites
<a name="connection-function-configuration-limits"></a>

Las funciones de conexión de CloudFront tienen requisitos de configuración y límites de servicio específicos debido al rol especializado en la validación de la conexión TLS y a los requisitos de rendimiento de la computación de periferia.

**Topics**
+ [

## Requisitos del código de función
](#connection-function-code-requirements)
+ [

## Límites de los servicios
](#connection-function-service-limits)
+ [

## Opciones de filtrado de funciones
](#connection-function-filtering-options)

## Requisitos del código de función
<a name="connection-function-code-requirements"></a>

Las funciones de conexión requieren un código JavaScript que procese los eventos de conexión de TLS. El código de la función debe:
+ Estar escrito en JavaScript
+ Procesar los eventos de conexión y tomar decisiones de permitir/denegar
+ Realizar una ejecución completa dentro de los límites de tiempo
+ Gestionar la lógica de validación de certificados y conexiones

## Límites de los servicios
<a name="connection-function-service-limits"></a>

Las funciones de conexión están sujetas a los siguientes límites:
+ **Tamaño de la función**: el código de función y la configuración tienen un tamaño limitado
+ **Tiempo de ejecución**: las funciones tienen límites de tiempo de ejecución estrictos para el procesamiento de la conexión TLS
+ **Límites de asociación**: cada distribución solo puede tener asociada una función de conexión
+ **Restricciones de etapa**: solo las funciones de la etapa ACTIVA se pueden asociar a las distribuciones

## Opciones de filtrado de funciones
<a name="connection-function-filtering-options"></a>

Cuando se muestran funciones de conexión, puede usar los siguientes filtros:
+ **Filtro de etapa**: filtre por etapa de DESARROLLO o ACTIVA
+ **Filtro de asociación**: filtre por ID de distribución o asociaciones de ID de almacén de clave-valor

Estos filtros lo ayudan a organizar y administrar las funciones de conexión en diferentes entornos y casos de uso.

# Creación de funciones de conexión de CloudFront para la validación de TLS mutua (espectador)
<a name="create-connection-functions"></a>

Se crea una función de conexión de CloudFront en dos etapas:

1. Crear el código de función como JavaScript. Puede utilizar el ejemplo predeterminado de la consola de CloudFront o escribir el suyo propio. Para obtener más información, consulte los temas siguientes:
   + Escritura de código de la función de conexión de CloudFront para la validación de mTLS
   + Estructura de eventos y formato de respuesta de la función de conexión de CloudFront
   + Ejemplos de código de función de conexión

1. Utilice CloudFront para crear la función de conexión e incluir el código. El código existe dentro de la función (no como referencia).

**Topics**
+ [

## Consola de CloudFront
](#create-connection-function-console)
+ [

## AWS CLI
](#create-connection-function-cli)

## Consola de CloudFront
<a name="create-connection-function-console"></a>

**Creación de una función de conexión**

1. Inicie sesión en la Consola de administración de AWS y abra la consola de CloudFront en [https://console.aws.amazon.com/cloudfront/v4/home](https://console.aws.amazon.com/cloudfront/v4/home).

1. Seleccione **Creación de función**.

1. Ingrese un nombre de función que sea único en la Cuenta de AWS, elija **Función de conexión** como tipo de función y, a continuación, elija **Continuar**.

1. Aparece la página de detalles de la nueva función de conexión.
**nota**  
Las funciones de conexión solo admiten tiempo de ejecución 2.0 de JavaScript. Para utilizar la integración de KeyValueStore de la función de conexión de CloudFront en la función, debe utilizar esta versión de tiempo de ejecución.

1. En la sección **Código de función**, elija la pestaña **Compilación** e ingrese el código de función de conexión. El código de ejemplo que se incluye en la pestaña Compilación ilustra la sintaxis básica del código de la función de conexión.

1. Seleccione **Save changes (Guardar cambios)**.

1. Si el código de la función de conexión utiliza KeyValueStore para comprobar la revocación de certificados o la validación de dispositivos, debe asociar un KeyValueStore.

   Puede asociar KeyValueStore cuando crea en primer lugar la función. O bien, puede asociarlo más adelante, mediante la asociación de funciones de conexión.

   Para asociar un KeyValueStore ahora, siga estos pasos:
   + Vaya a la sección **Asociar KeyValueStore** y elija **Asociar KeyValueStore existente**.
   + Seleccione el KeyValueStore que contiene los datos del certificado para la función de conexión y, a continuación, elija **Asociar KeyValueStore**.

   CloudFront asocia inmediatamente el almacén a la función. No necesita guardar la función.

## AWS CLI
<a name="create-connection-function-cli"></a>

Si utiliza la AWS CLI, normalmente crea primero el código de la función de conexión en un archivo y, a continuación, crea la función con la AWS CLI.

**Creación de una función de conexión**

1. Cree el código de la función de conexión en un archivo y guárdelo en un directorio al que se pueda conectar el equipo.

1. Ejecute el comando como se muestra en el ejemplo. En este ejemplo, se utiliza la notación `fileb://` para transmitir el archivo. También incluye saltos de línea para que el comando sea más legible.

   ```
   aws cloudfront create-connection-function \
       --name CertificateValidator \
       --connection-function-config '{
           "Comment":"Device certificate validation",
           "Runtime":"cloudfront-js-2.0",
           "KeyValueStoreAssociations":{
               "Quantity":1,
               "Items":[{
                   "KeyValueStoreARN":"arn:aws:cloudfront::111122223333:key-value-store/a1b2c3d4-5678-90ab-cdef-EXAMPLE11111"
               }]
           }
       }' \
       --connection-function-code fileb://certificate-validator.js
   ```
**nota**  
**Tiempo de ejecución**: las funciones de conexión solo admiten el tiempo de ejecución 2.0 de JavaScript (cloudfront-js-2.0).
**KeyValueStoreAssociations**: si la función de conexión usa KeyValueStore para la validación de certificados, puede asociar KeyValueStore en la creación inicial de la función. O bien, puede asociarlo más adelante, mediante update-connection-function. La cantidad siempre es 1, porque cada función de conexión solo puede tener asociado un KeyValueStore.

1. Si el comando se ejecuta correctamente, verá un resultado parecido al siguiente.

   ```
   ETag: ETVABCEXAMPLE
   ConnectionFunctionSummary:
     ConnectionFunctionConfig:
       Comment: Device certificate validation
       Runtime: cloudfront-js-2.0
       KeyValueStoreAssociations:
         Quantity: 1
         Items:
           - KeyValueStoreARN: arn:aws:cloudfront::111122223333:key-value-store/a1b2c3d4-5678-90ab-cdef-EXAMPLE11111
     ConnectionFunctionMetadata:
       CreatedTime: '2024-09-04T16:32:54.292000+00:00'
       ConnectionFunctionARN: arn:aws:cloudfront::111122223333:connection-function/CertificateValidator
       LastModifiedTime: '2024-09-04T16:32:54.292000+00:00'
       Stage: DEVELOPMENT
     Name: CertificateValidator
     Status: UNPUBLISHED
   Location: https://cloudfront.amazonaws.com/2020-05-31/connection-function/arn:aws:cloudfront:::connection-function/CertificateValidator
   ```

   La mayor parte de la información se repite desde la solicitud. CloudFront agrega el resto de información.
**nota**  
**ETag**: este valor cambia cada vez que se modifica la función de conexión. Necesitará este valor para actualizar o publicar la función.
**Etapa**: las nuevas funciones de conexión comienzan en la etapa de DESARROLLO. Debe publicar la función para moverla al escenario ACTIVA antes de asociarla a una distribución.
**Estado**: el estado de la función es NO PUBLICADA hasta que la publique en la etapa ACTIVA.

# Escritura de código de función de conexión de CloudFront para la validación de TLS mutua (espectador)
<a name="write-connection-function-code"></a>

Las funciones de conexión de CloudFront permiten escribir funciones de JavaScript sencillas para la validación de certificados de mTLS y la lógica de autenticación personalizada. El código de la función de conexión puede validar los certificados de los clientes, implementar reglas de autenticación específicas del dispositivo, gestionar escenarios de revocación de certificados y tomar decisiones de permitir o denegar las conexiones TLS en las ubicaciones periféricas de CloudFront de todo el mundo.

Las funciones de conexión proporcionan una forma eficaz de ampliar la validación de certificados integrada en CloudFront con su propia lógica empresarial. A diferencia de las funciones de solicitud y respuesta del espectador que procesan datos HTTP, las funciones de conexión funcionan en la capa de TLS y tienen acceso a la información del certificado, a las direcciones IP del cliente y a los detalles de la conexión de TLS. Esto las hace ideales para implementar modelos de seguridad de confianza cero, sistemas de autenticación de dispositivos y políticas de validación de certificados personalizadas que van más allá de la validación estándar de PKI.

El código de la función de conexión se ejecuta en un entorno seguro y aislado con tiempos de inicio de submilisegundos y se puede escalar para gestionar millones de conexiones por segundo. El tiempo de ejecución está optimizado para las cargas de trabajo de validación de certificados y proporciona una integración integrada con CloudFront KeyValueStore para operaciones de búsqueda de datos en tiempo real, lo que permite escenarios de autenticación sofisticados, como la comprobación de la lista de revocación de certificados y la validación de la lista de dispositivos permitidos.

Como ayuda para escribir código de la función de conexión eficaz, consulte los siguientes temas. Para ver ejemplos de código completos y tutoriales paso a paso, consulte las secciones de tutoriales de esta guía y explore los ejemplos de funciones de conexión disponibles en la consola de CloudFront.

**Topics**
+ [

## Casos de uso y finalidades de la función de conexión de CloudFront
](#connection-function-use-cases)
+ [

## Estructura de eventos y formato de respuesta de la función de conexión de CloudFront
](#connection-function-event-structure)
+ [

## Características del tiempo de ejecución de JavaScript de funciones de conexión de CloudFront
](#connection-function-javascript-runtime)
+ [

## API y métodos auxiliares de la función de conexión de CloudFront
](#connection-function-helper-methods)
+ [

## Integración de KeyValueStore con la función de conexión de CloudFront
](#connection-function-kvs-integration)
+ [

## Uso de async y await
](#connection-function-async-await)
+ [

## Ejemplos de código de función de conexión
](#connection-function-code-examples)

## Casos de uso y finalidades de la función de conexión de CloudFront
<a name="connection-function-use-cases"></a>

Antes de escribir la función de conexión de CloudFront, determine cuidadosamente qué tipo de lógica de autenticación o validación de certificados debe implementar. Las funciones de conexión están diseñadas para casos de uso específicos que requieren una validación personalizada más allá de la comprobación estándar de los certificados de PKI. La comprensión del caso de uso lo ayuda a diseñar un código eficiente que cumpla con los requisitos de seguridad y, al mismo tiempo, mantenga un rendimiento óptimo.

Los casos de uso comunes de la función de conexión incluyen:
+ **Gestión de la revocación de certificados**: implemente políticas personalizadas para gestionar los certificados revocados, incluidos los periodos de gracia para la rotación de los certificados, las excepciones de redes de confianza para los dispositivos internos o los escenarios de acceso de emergencia en los que los certificados revocados podrían necesitar un acceso temporal.
+ **Compatibilidad con mTLS opcional**: gestione las conexiones de mTLS y las que no lo son con políticas de autenticación diferentes, lo que permite ofrecer una mayor seguridad a los clientes que admiten certificados y, al mismo tiempo, mantener la compatibilidad con los clientes antiguos.
+ **Autenticación basada en IP**: combine la validación de los certificados con las comprobaciones de las direcciones IP de los clientes para mejorar la seguridad, por ejemplo, restringiendo el acceso desde regiones geográficas específicas, redes corporativas o rangos de IP maliciosos conocidos.
+ **Validación de certificados multiusuario**: implemente reglas de validación específicas para cada inquilino en las que se apliquen diferentes autoridades de certificación o criterios de validación en función del emisor del certificado del cliente o de los atributos del sujeto.
+ **Control de acceso basado en el tiempo**: aplique restricciones basadas en el tiempo para que los certificados solo sean válidos durante horas, periodos de mantenimiento o periodos laborables específicos, incluso si el certificado en sí no ha caducado.

Las funciones de conexión se ejecutan después de que CloudFront lleve a cabo la validación estándar del certificado (verificación de la cadena de confianza, comprobaciones de caducidad y validación de firmas), pero antes de que se establezca la conexión de TLS. Este tiempo brinda la flexibilidad de agregar criterios de validación personalizados y, al mismo tiempo, beneficiarse de la validación de certificados integrada de CloudFront. La función recibe los resultados de la validación estándar y puede tomar decisiones fundamentadas sobre si permitir o denegar la conexión en función de criterios estándar y personalizados.

Al diseñar la función de conexión, tenga en cuenta las implicaciones de rendimiento de la lógica de validación. Las funciones tienen un límite de ejecución de 5 milisegundos, por lo que las operaciones complejas deben optimizarse para aumentar su velocidad. Utilice KeyValueStore para realizar búsquedas rápidas de datos en lugar de realizar cálculos complejos y estructure su lógica de validación para que los certificados no válidos respondan rápido a los errores.

## Estructura de eventos y formato de respuesta de la función de conexión de CloudFront
<a name="connection-function-event-structure"></a>

Las funciones de conexión de CloudFront reciben una estructura de eventos diferente a la de las funciones de solicitud y respuesta del espectador. En lugar de datos de solicitud/respuesta HTTP, las funciones de conexión reciben información sobre certificados y conexiones que puede utilizar para tomar decisiones de autenticación.

**Topics**
+ [

### Estructura de eventos para las funciones de conexión
](#connection-function-event-structure-details)
+ [

### Formato de respuesta de funciones de conexión
](#connection-function-response-format)

### Estructura de eventos para las funciones de conexión
<a name="connection-function-event-structure-details"></a>

Las funciones de conexión reciben un objeto de eventos que contiene el certificado y la información de conexión. La estructura de eventos de la función se muestra a continuación:

```
{
  "clientCertificate": {
    "certificates": {
      "leaf": {
        "serialNumber": "string",
        "issuer": "string",
        "subject": "string",
        "validity": {
          "notBefore": "string",
          "notAfter": "string",
        },
        "sha256Fingerprint": "string"
      }
    }
  },
  "clientIp": "string",
  "endpoint": "string",
  "distributionId": "string",
  "connectionId": "string"
}
```

A continuación, se muestra un ejemplo de la estructura del objeto de eventos:

```
{
  "clientCertificate": {
    "certificates": {
      "leaf": {
        "serialNumber": "00:9e:2a:af:16:56:e5:47:25:7d:2e:38:c3:f9:9d:57:fa",
        "issuer": "C=US, O=Ram, OU=Edge, ST=WA, CN=mTLS-CA, L=Snoqualmie",
        "subject": "C=US, O=Ram, OU=Edge, ST=WA, CN=mTLS-CA, L=Snoqualmie",
        "validity": {
          "notBefore": "2025-09-10T23:43:10Z",
          "notAfter": "2055-09-11T00:43:02Z"
        },
        "sha256Fingerprint": "_w6bJ7aOAlGOj7NUhJxTfsfee-ONg_xop3_PTgTJpqs="
      }
    }
  },
  "clientIp": "127.0.0.1",
  "endpoint": "d3lch071jze0cb.cloudfront.net",
  "distributionId": "E1NXS4MQZH501R",
  "connectionId": "NpvTe1925xfj24a67sPQr7ae42BIq03FGhJJKfrQYWZcWZFp96SIIg=="
}
```

### Formato de respuesta de funciones de conexión
<a name="connection-function-response-format"></a>

La función de conexión debe devolver un objeto de respuesta que indique si se va a permitir o denegar la conexión. Utilice los métodos auxiliares para tomar decisiones de conexión:

```
function connectionHandler(connection) {
    // Helper methods to allow or deny connections
    if (/* some logic to determine if function should allow connection */) {
        connection.allow();
    } else {
        connection.deny();
    }
}
```

A diferencia de las funciones de solicitud y respuesta del espectador, las funciones de conexión no pueden modificar las solicitudes o respuestas HTTP. Solo pueden permitir o denegar la conexión de TLS.

## Características del tiempo de ejecución de JavaScript de funciones de conexión de CloudFront
<a name="connection-function-javascript-runtime"></a>

Las funciones de conexión de CloudFront utilizan el tiempo de ejecución de JavaScript 2.0 de CloudFront Functions, que proporciona un entorno seguro y de alto rendimiento optimizado específicamente para las cargas de trabajo de validación de certificados. El tiempo de ejecución está diseñado para comenzar en submilisegundos y gestionar millones de ejecuciones simultáneas en la red de periferia global de CloudFront.

El entorno de tiempo de ejecución incluye una amplia compatibilidad con el lenguaje de JavaScript:
+ **Compatibilidad con ECMAScript 2020 (ES11)**: características modernas de JavaScript que incluyen el encadenamiento opcional (?.), la fusión de NULL (??), y BigInt para gestionar números de serie de certificados de gran tamaño.
+ **Objetos integrados**: objetos de JavaScript estándar como Object, Array, JSON, Math y Date.
+ **Registro de consola**: utilice console.log() para depurar y supervisar las decisiones de validación de certificados. Los registros están disponibles en tiempo real durante las pruebas y pueden ayudar a solucionar los problemas de la lógica de validación durante el desarrollo.
+ **Integración con KeyValueStore**: acceso nativo a CloudFront KeyValueStore para operaciones de búsqueda de datos ultrarrápidas, lo que permite comprobar la revocación de certificados en tiempo real, validar las listas de dispositivos permitidos y recuperar la configuración específica del inquilino.

Las funciones de conexión están optimizadas para ofrecer un alto rendimiento en los escenarios de validación de certificados. El tiempo de ejecución gestiona automáticamente la administración de la memoria, la recopilación de elementos no utilizados y la limpieza de recursos para garantizar un rendimiento coherente en millones de conexiones simultáneas. Todas las operaciones están diseñadas para ser deterministas y rápidas, y las búsquedas de KeyValueStore suelen completarse en microsegundos.

El entorno de tiempo de ejecución está completamente aislado entre las ejecuciones de las funciones, lo que garantiza que no se filtren datos entre las diferentes conexiones de los clientes. La ejecución de cada función comienza con un estado limpio y no tiene acceso a los resultados de la ejecución anterior ni a los datos del cliente desde otras conexiones.

## API y métodos auxiliares de la función de conexión de CloudFront
<a name="connection-function-helper-methods"></a>

Las funciones de conexión de CloudFront proporcionan métodos auxiliares especializados diseñados para simplificar las decisiones de validación de certificados y mejorar la observabilidad. Estos métodos están optimizados para el flujo de trabajo de validación de conexiones y se integran perfectamente con los sistemas de registro y supervisión de conexiones de CloudFront.
+ **connection.allow()**: permita que continúe la conexión de TLS. Este método indica a CloudFront que complete el establecimiento de comunicación de TLS y permita al cliente establecer la conexión. Úselo cuando se apruebe la validación del certificado y se cumpla cualquier lógica de autenticación personalizada.
+ **connection.deny()**: deniegue la conexión de TLS y finalice el establecimiento de comunicación. Este método cierra inmediatamente la conexión e impide que fluya el tráfico HTTP. El cliente recibirá un error de conexión de TLS. Úselo para los certificados no válidos, los errores de autenticación o las infracciones de las políticas.
+ **connection.logCustomData()**: agregue datos personalizados a los registros de conexión (hasta 800 bytes de texto UTF-8). Este método permite incluir los resultados de la validación, los detalles del certificado o el fundamento de la decisión en los registros de conexión de CloudFront para la supervisión de la seguridad, la auditoría de conformidad y la solución de problemas.

Estos métodos proporcionan una interfaz clara y declarativa para tomar decisiones de conexión y registrar la información relevante para la supervisión y la depuración. El patrón de permitir/denegar garantiza que la intención de la función sea clara y que CloudFront pueda optimizar la gestión de la conexión en función de la decisión. Los datos de registro personalizados están disponibles inmediatamente en los registros de conexión de CloudFront y se pueden utilizar con herramientas de análisis de registros para supervisar la seguridad y obtener información operativa.

Llame siempre a connection.allow() o connection.deny() antes de que finalice la función. Si no se llama a ninguno de los dos métodos, CloudFront denegará la conexión de forma predeterminada como medida de seguridad.

## Integración de KeyValueStore con la función de conexión de CloudFront
<a name="connection-function-kvs-integration"></a>

Las funciones de conexión de CloudFront pueden usar KeyValueStore de CloudFront para realizar búsquedas de datos ultrarrápidas para escenarios de validación de certificados. KeyValueStore es especialmente eficaz para las funciones de conexión, ya que proporciona un acceso a los datos global y, en última instancia, coherente con tiempos de búsqueda de microsegundos en todas las ubicaciones periféricas de CloudFront. Esto lo hace ideal para mantener listas de revocación de certificados, listas de dispositivos permitidos, configuraciones de inquilinos y otros datos de validación a los que es necesario acceder durante los establecimientos de comunicación de TLS.

La integración de KeyValueStore está diseñada específicamente para flujos de trabajo de validación de conexiones de alto rendimiento:
+ **kvsHandle.exists(clave)**: compruebe si existe una clave en el KeyValueStore sin recuperar el valor. Este es el método más eficaz para los escenarios de validación binaria, como la comprobación de la revocación de certificados, en los que solo necesita saber si el número de serie de un certificado está en una lista de revocaciones.
+ **kvsHandle.get(clave)**: recupere un valor del KeyValueStore para escenarios de validación más complejos. Úselo cuando necesite acceder a los datos de configuración, las reglas de validación o los metadatos asociados a un certificado o identificador de dispositivo.

Las operaciones de KeyValueStore son asíncronas y deben usarse con la sintaxis async/await. El KeyValueStore tiene un límite de tamaño total de 10 MB y admite hasta 10 millones de pares clave-valor. Con el tiempo, los datos de KeyValueStore son coherentes en todas las ubicaciones periféricas y, por lo general, las actualizaciones se propagan en cuestión de segundos.

Para obtener un rendimiento óptimo, estructure las claves de KeyValueStore para minimizar las operaciones de búsqueda. Utilice los números de serie de los certificados como claves para comprobar las revocaciones de forma sencilla o cree claves compuestas que combinen el hash del emisor y el número de serie para entornos con varias autoridades de certificación. Tenga en cuenta las ventajas y desventajas entre la complejidad de las claves y la capacidad de KeyValueStore al diseñar la estructura de datos.

## Uso de async y await
<a name="connection-function-async-await"></a>

Las funciones de conexión admiten operaciones asíncronas mediante la sintaxis de async/await, que es esencial cuando se trabaja con operaciones de KeyValueStore u otras tareas asincrónicas. El patrón async/await garantiza que la función espere a que se completen las búsquedas en KeyValueStore antes de tomar decisiones de conexión, a la vez que mantiene las características de alto rendimiento necesarias para el procesamiento del establecimiento de comunicación de TLS.

El uso adecuado de la función async/await es fundamental para las funciones de conexión, ya que las operaciones de KeyValueStore, si bien son muy rápidas, siguen siendo operaciones de red que requieren la coordinación de toda la infraestructura distribuida de CloudFront. El tiempo de ejecución gestiona automáticamente la resolución prometida y garantiza que la función se complete dentro del límite de ejecución de 5 milisegundos.

**Example : función de conexión asíncrona con KeyValueStore**  

```
import cf from 'cloudfront';

async function connectionHandler(connection) {
    const kvsHandle = cf.kvs();
    
    // Async operation to check KeyValueStore for certificate revocation
    const isRevoked = await kvsHandle.exists(connection.clientCertificate.certificates.leaf.serialNumber);
    
    if (isRevoked) {
        // Log the revocation decision with certificate details
        connection.logCustomData(`REVOKED_CERT:${connection.clientCertificate.certificates.leaf.serialNumber}:${connection.clientCertificate.certificates.leaf.issuer}`);
        console.log(`Denying connection for revoked certificate: ${connection.clientCertificate.certificates.leaf.serialNumber}`);
        return connection.deny();
    }
    
    // Log successful validation for monitoring
    connection.logCustomData(`VALID_CERT:${connection.clientCertificate.certificates.leaf.serialNumber}`);
    console.log(`Allowing connection for valid certificate: ${connection.clientCertificate.certificates.leaf.serialNumber}`);
    return connection.allow();
}
```

Utilice siempre async/await al llamar a los métodos de KeyValueStore u otras operaciones asincrónicas. El tiempo de ejecución de la función de conexión gestiona automáticamente la resolución de las promesas y garantiza un flujo de ejecución adecuado dentro de las estrictas restricciones temporales del procesamiento de establecimiento de comunicación de TLS. Evite utilizar los patrones .then() o callback, ya que async/await permite gestionar los errores de forma más limpia y ofrece un mejor rendimiento en el entorno de la función de conexión.

Al diseñar funciones de conexión asíncronas, estructure el código para minimizar el número de operaciones de KeyValueStore y realícelas lo antes posible en su lógica de validación. Esto garantiza el máximo rendimiento y reduce el riesgo de problemas de tiempo de espera durante los periodos de tráfico alto. Considere agrupar las comprobaciones de validación relacionadas con los lotes y utilizar el método KeyValueStore más eficiente (exists() frente a get()) para el caso de uso.

## Ejemplos de código de función de conexión
<a name="connection-function-code-examples"></a>

Los siguientes ejemplos muestran patrones de funciones de conexión comunes para diferentes escenarios comunes. Utilice estos ejemplos como puntos de partida para las propias implementaciones de funciones de conexión.

**Example : validación de certificados de dispositivo**  
Este ejemplo valida los números de serie de los dispositivos y los campos de asunto de los certificados para dispositivos IoT, consolas de juegos y otros escenarios de autenticación de clientes:  

```
async function connectionHandler(connection) {
    // Custom validation: check device serial number format
    const serialNumber = connection.clientCertificate.certificates.leaf.serialNumber;
    if (!serialNumber.startsWith("DEV")) {
        connection.logCustomData(`INVALID_SERIAL:${serialNumber}`);
        return connection.deny();
    }
    
    // Validate certificate subject contains required organizational unit
    const subject = connection.clientCertificate.certificates.leaf.subject;
    if (!subject.includes("OU=AuthorizedDevices")) {
        connection.logCustomData(`INVALID_OU:${subject}`);
        return connection.deny();
    }
    
    // Allow connection for valid devices
    connection.logCustomData(`VALID_DEVICE:${serialNumber}`);
    return connection.allow();
}
```
Esta función realiza varias comprobaciones de validación además de la validación estándar del certificado, como el formato del número de serie del dispositivo y la verificación de la unidad organizativa.

**Example : mTLS opcionales con autenticación mixta**  
Este ejemplo gestiona las conexiones de mTLS y las que no lo son con políticas de autenticación diferentes:  

```
async function connectionHandler(connection) {
    if (connection.clientCertificate) {
        // mTLS connection - enhanced validation for certificate holders
        const subject = connection.clientCertificate.certificates.leaf.subject;
        connection.logCustomData(`MTLS_SUCCESS:${subject}:${connection.clientIp}`);
        console.log(`mTLS connection from: ${subject}`);
        return connection.allow();
    } else {
        // Non-mTLS connection - apply IP-based restrictions
        const clientIp = connection.clientIp;
        
        // Only allow non-mTLS from specific IP ranges
        if (clientIp.startsWith("203.0.113.") || clientIp.startsWith("198.51.100.")) {
            connection.logCustomData(`NON_MTLS_ALLOWED:${clientIp}`);
            console.log(`Non-mTLS connection allowed from: ${clientIp}`);
            return connection.allow();
        }
        
        connection.logCustomData(`NON_MTLS_DENIED:${clientIp}`);
        return connection.deny();
    }
}
```
Esta función proporciona una seguridad mejorada para los clientes con certificados y, al mismo tiempo, mantiene la compatibilidad con los clientes antiguos de rangos de IP fiables.

# Prueba de las funciones de conexión de CloudFront antes de la implementación
<a name="test-connection-functions"></a>

Puede probar las funciones de conexión de CloudFront en la etapa de DESARROLLO mediante la operación de la API TestConnectionFunction. Las pruebas permiten validar la lógica de la función con ejemplos de eventos de conexión antes de publicarlos en la etapa ACTIVA.

**Topics**
+ [

## Proceso de prueba
](#connection-function-testing-process)
+ [

## Resultados de la prueba
](#connection-function-test-results)
+ [

## Objeto de prueba de conexión
](#connection-test-object)

## Proceso de prueba
<a name="connection-function-testing-process"></a>

Para probar una función de conexión:

1. Cree una función de conexión en la etapa de DESARROLLO.

1. Prepare un objeto de conexión de prueba que represente el evento de conexión de TLS.

1. Utilice la operación de la API TestConnectionFunction para ejecutar la función con los datos de prueba.

1. Revise los resultados de la prueba, incluidos los resultados de las funciones, los registros de ejecución y cualquier mensaje de error.

1. Actualice el código de función según sea necesario y repita el proceso de prueba.

## Resultados de la prueba
<a name="connection-function-test-results"></a>

Al probar una función de conexión, los resultados incluyen:
+ **Resumen de la función**: metadatos sobre la función que se probó
+ **Utilización del cómputo**: métricas de rendimiento que muestran el uso de los recursos
+ **Registros de ejecución**: resultados de la consola de la función, incluidas las instrucciones de registro
+ **Resultado de la función**: el resultado devuelto por la función
+ **Mensajes de error**: cualquier error o excepción de tiempo de ejecución que se haya producido durante la ejecución

## Objeto de prueba de conexión
<a name="connection-test-object"></a>

El objeto de prueba de conexión es un blob binario (hasta 40 KB) que representa el evento de conexión de TLS que procesará la función. Este objeto contiene el certificado y la información de conexión que la función utiliza para tomar decisiones de autenticación.

**nota**  
El tiempo de ejecución de funciones de conexión de CloudFront define la estructura y el formato específicos del objeto de prueba de conexión. Consulte la documentación de CloudFront Functions o contacte con AWS Support para obtener información sobre cómo crear los objetos de prueba adecuados para el caso de uso.

Tras crear la función de conexión, puede:
+ **Probar la función**: utilice la funcionalidad de prueba de la consola o la CLI para validar la función con ejemplos de eventos de conexión. Para obtener más información, consulte Pruebas de funciones de conexión.
+ **Actualizar la función**: modifique el código y la configuración de la función según sea necesario. Las funciones de conexión en la etapa de DESARROLLO se pueden actualizar en cualquier momento.
+ **Publicar la función**: cuando esté lista para la producción, publique la función para pasarla de la etapa de DESARROLLO a la etapa ACTIVA. Para obtener más información, consulte asociación de funciones de conexión.
+ **Asociar con una distribución**: asocie la función publicada con la distribución compatible con MTLS para gestionar las conexiones en directo. Para obtener más información, consulte asociación de funciones de conexión.

# Asociación de funciones de conexión con distribuciones
<a name="associate-connection-functions"></a>

Tras publicar una función de conexión en la etapa ACTIVA, debe asociarla a una distribución compatible con mTLS para gestionar las conexiones en directo. Las funciones de conexión se asocian por distribución, a diferencia de las funciones de solicitud y respuesta del espectador, que están asociadas a los comportamientos de la memoria caché.

**Topics**
+ [

## Requisitos de asociación
](#connection-function-association-requirements)
+ [

## Organización de funciones con filtros
](#connection-function-organizing-filters)
+ [

## Consideraciones sobre la implementación
](#connection-function-deployment-considerations)

## Requisitos de asociación
<a name="connection-function-association-requirements"></a>

Asociación de una función de conexión con una distribución:
+ La función debe estar en la etapa ACTIVA
+ La distribución debe tener habilitado mTLS
+ La distribución debe tener un almacén de confianza válido configurado
+ Solo puede asociar una función de conexión por distribución

## Organización de funciones con filtros
<a name="connection-function-organizing-filters"></a>

CloudFront proporciona funciones de filtrado para ayudarlo a organizar y administrar funciones de conexión:
+ **Filtro de ID de distribución**: busque funciones asociadas a distribuciones específicas
+ **Filtro de almacén de valores clave**: busque funciones que utilicen almacenes de valores clave específicos para la búsqueda de datos
+ **Filtro de etapas**: muestre las funciones en las etapas DESARROLLO o ACTIVA

Utilice estos filtros cuando se administren múltiples funciones de conexión en diferentes distribuciones o entornos de desarrollo.

## Consideraciones sobre la implementación
<a name="connection-function-deployment-considerations"></a>

Tenga en cuenta estos factores al implementar las funciones de conexión:
+ **Implementación global**: las funciones de conexión se implementan en todas las ubicaciones periféricas de CloudFront del mundo, lo que puede tardar varios minutos
+ **Administración de versiones**: cada versión publicada crea una nueva función ACTIVA que reemplaza a la versión anterior
+ **Estrategia de reversión**: planifique la reversión conservando las versiones anteriores del código de la función que funcionaban
+ **Pruebas en producción**: considere la posibilidad de utilizar distribuciones independientes para los entornos de ensayo y producción

# Implementación de la revocación de certificados para TLS mutua (espectador) con CloudFront Functions y KeyValueStore
<a name="implement-certificate-revocation"></a>

Puede utilizar funciones de conexión de CloudFront con KeyValueStore para implementar la comprobación de revocación de certificados. Esto permite mantener una lista de números de serie de los certificados revocados y comparar los certificados de los clientes con esta lista durante el establecimiento de comunicación de TLS.

Para implementar la revocación de certificados, necesita estos componentes:
+ Una distribución configurada con un mTLS de espectador
+ Un KeyValueStore que contenga números de serie de certificados revocados
+ Una función de conexión que consulta el KeyValueStore para comprobar el estado del certificado

Cuando un cliente se conecta, CloudFront valida el certificado con el almacén de confianza y, a continuación, ejecuta la función de conexión. La función compara el número de serie del certificado con el KeyValueStore y permite o deniega la conexión.

**Topics**
+ [

# Paso 1: crear un KeyValueStore para los certificados revocados
](create-kvs-revoked-certificates.md)
+ [

# Paso 2: crear la función de conexión de revocación
](create-revocation-connection-function.md)
+ [

# Paso 3: probar la función de revocación
](test-revocation-function.md)
+ [

# Paso 4: asocie la función a la distribución
](associate-function-distribution.md)
+ [

# Escenarios de revocación avanzada
](advanced-revocation-scenarios.md)

# Paso 1: crear un KeyValueStore para los certificados revocados
<a name="create-kvs-revoked-certificates"></a>

Cree un KeyValueStore para almacenar los números de serie de los certificados revocados que la función de conexión pueda comprobar durante las conexiones de mTLS.

En primer lugar, prepare los números de serie de los certificados revocados en formato JSON:

```
{
  "data": [
    {
      "key": "ABC123DEF456",
      "value": ""
    },
    {
      "key": "789XYZ012GHI", 
      "value": ""
    }
  ]
}
```

Cargue este archivo JSON en un bucket de S3 y, a continuación, cree el KeyValueStore:

```
aws s3 cp revoked-serials.json s3://your-bucket-name/revoked-serials.json
aws cloudfront create-key-value-store \
  --name revoked-serials-kvs \
  --import-source '{
    "SourceType": "S3",
    "SourceARN": "arn:aws:s3:::your-bucket-name/revoked-serials.json"
  }'
```

Espere a que el KeyValueStore termine de aprovisionarse. Compruebe el estado con:

```
aws cloudfront get-key-value-store --name "revoked-serials-kvs"
```

# Paso 2: crear la función de conexión de revocación
<a name="create-revocation-connection-function"></a>

Cree una función de conexión que compruebe los números de serie de los certificados con los de KeyValueStore para determinar si los certificados se revocan.

Cree una función de conexión que compruebe los números de serie de los certificados con el KeyValueStore:

```
aws cloudfront create-connection-function \
  --name "revocation-control" \
  --connection-function-config file://connection-function-config.json \
  --connection-function-code file://connection-function-code.txt
```

El archivo de configuración especifica la asociación de KeyValueStore:

```
{
  "Runtime": "cloudfront-js-2.0",
  "Comment": "A function that implements revocation control via KVS",
  "KeyValueStoreAssociations": {
    "Quantity": 1,
    "Items": [
      {
        "KeyValueStoreArn": "arn:aws:cloudfront::account-id:key-value-store/kvs-id"
      }
    ]
  }
}
```

El código de la función de conexión comprueba KeyValueStore por si hay certificados revocados:

```
import cf from 'cloudfront';

async function connectionHandler(connection) {
    const kvsHandle = cf.kvs();
    
    // Get parsed client serial number from client certificate
    const clientSerialNumber = connection.clientCertInfo.serialNumber;
    
    // Check KVS to see if serial number exists as a key
    const serialNumberExistsInKvs = await kvsHandle.exists(clientSerialNumber);
    
    // Deny connection if serial number exists in KVS
    if (serialNumberExistsInKvs) {
        console.log("Connection denied - certificate revoked");
        return connection.deny();
    }
    
    // Allow connections that don't exist in kvs
    console.log("Connection allowed");
    return connection.allow();
}
```

# Paso 3: probar la función de revocación
<a name="test-revocation-function"></a>

Utilice la consola de CloudFront para probar la función de conexión con certificados de ejemplo. Navegue hasta la función de conexión en la consola y utilice la pestaña Probar.

**Prueba con certificados de ejemplo**

1. Pegue un certificado de ejemplo en formato PEM en la interfaz de prueba.

1. Si lo desea, especifique una dirección IP de cliente para probar la lógica basada en IP.

1. Elija **Función de prueba** para consultar los resultados de ejecución.

1. Revise los registros de ejecución para verificar la lógica de la función.

Realice pruebas con certificados válidos y revocados para asegurarse de que la función gestiona ambos escenarios correctamente. Los registros de ejecución muestran el resultado de console.log y cualquier error que se produzca durante la ejecución de la función.

# Paso 4: asocie la función a la distribución
<a name="associate-function-distribution"></a>

Una vez que publique la función de conexión, asóciela a la distribución compatible con mTLS para activar la comprobación de revocación de certificados.

Puede asociar la función desde la página de configuración de distribución o desde la tabla de distribuciones asociadas a la función de conexión. Vaya a la configuración de distribución, vaya a la sección **Autenticación mutua del espectador (mTLS)**, seleccione la función de conexión y guarde los cambios.

# Escenarios de revocación avanzada
<a name="advanced-revocation-scenarios"></a>

Para requisitos de revocación de certificados más complejos, considere estas configuraciones adicionales:

**Topics**
+ [

## Convierta las listas de revocación de certificados (CRL) al formato KeyValueStore.
](#convert-crl-kvs-format)
+ [

## Gestión de varias autoridades de certificación
](#handle-multiple-cas)
+ [

## Agregación de datos personalizados a los registros de conexión
](#add-custom-data-logs)
+ [

## Actualizaciones de CRL administradas
](#manage-crl-updates)
+ [

## Planificación de la capacidad de KeyValueStore
](#plan-kvs-capacity)

## Convierta las listas de revocación de certificados (CRL) al formato KeyValueStore.
<a name="convert-crl-kvs-format"></a>

Si tiene un archivo de lista de revocación de certificados (CRL), puede convertirlo al formato JSON de KeyValueStore mediante OpenSSL y jq:

**Convierta el CRL al formato KeyValueStore**

Extraiga los números de serie del archivo CRL:

```
openssl crl -text -noout -in rfc5280_CRL.crl | \
  awk '/Serial Number:/ {print $3}' | \
  cut -d'=' -f2 | \
  sed 's/../&:/g;s/:$//' >> serialnumbers.txt
```

Convierta los números de serie al formato JSON de KeyValueStore:

```
jq -R -s 'split("\n") | map(select(length > 0)) | {data: map({"key": ., "value": ""})}' \
  serialnumbers.txt >> serialnumbers_kvs.json
```

Cargue el archivo formateado en S3 y cree el KeyValueStore tal y como se describe en el paso 1.

## Gestión de varias autoridades de certificación
<a name="handle-multiple-cas"></a>

Si su TrustStore contiene varias autoridades de certificación (CA), incluya la información del emisor en las claves de KeyValueStore para evitar conflictos entre certificados de distintas autoridades de certificación que puedan tener el mismo número de serie.

En escenarios con varias autoridades de certificación, utilice como clave una combinación del hash SHA1 del emisor y el número de serie:

```
import cf from 'cloudfront';

async function connectionHandler(connection) {
    const kvsHandle = cf.kvs();
    const clientCert = connection.clientCertInfo;
    
    // Create composite key with issuer hash and serial number
    const issuer = clientCert.issuer.replace(/[^a-zA-Z0-9]/g, '').substring(0, 20);
    const serialno = clientCert.serialNumber;
    const compositeKey = `${issuer}_${serialno}`;
    
    const cert_revoked = await kvsHandle.exists(compositeKey);
    
    if (cert_revoked) {
        console.log(`Blocking revoked cert: ${serialno} from issuer: ${issuer}`);
        connection.deny();
    } else {
        connection.allow();
    }
}
```

**nota**  
Al utilizar el identificador del emisor y el número de serie, se crean claves más largas, lo que puede reducir el número total de entradas que puede almacenar en KeyValueStore.

## Agregación de datos personalizados a los registros de conexión
<a name="add-custom-data-logs"></a>

Las funciones de conexión pueden agregar datos personalizados a los registros de conexión de CloudFront mediante el método logCustomData. Esto permite incluir los resultados de las comprobaciones de revocación, la información sobre los certificados u otros datos relevantes en los registros.

```
async function connectionHandler(connection) {
    const kvsHandle = cf.kvs();
    const clientSerialNumber = connection.clientCertInfo.serialNumber;
    const serialNumberExistsInKvs = await kvsHandle.exists(clientSerialNumber);
    
    if (serialNumberExistsInKvs) {
        // Log revocation details to connection logs
        connection.logCustomData(`REVOKED:${clientSerialNumber}:DENIED`);
        console.log("Connection denied - certificate revoked");
        return connection.deny();
    }
    
    // Log successful validation
    connection.logCustomData(`VALID:${clientSerialNumber}:ALLOWED`);
    console.log("Connection allowed");
    return connection.allow();
}
```

Los datos personalizados están limitados a 800 bytes de texto UTF-8 válido. Si supera este límite, CloudFront trunca los datos hasta el límite UTF-8 válido más cercano.

**nota**  
El registro de datos personalizado solo funciona cuando los registros de conexión están habilitados para la distribución. Si los registros de conexión no están configurados, el método logCustomData no es operativo.

## Actualizaciones de CRL administradas
<a name="manage-crl-updates"></a>

Las autoridades de certificación pueden emitir dos tipos de CRL:
+ **CRL completas**: contienen una lista completa de todos los certificados revocados
+ **CRL de Delta**: solo se muestran los certificados revocados desde la última CRL completa

Para obtener actualizaciones completas de la CRL, cree un KeyValueStore nuevo con los datos actualizados y redirija la asociación de la función de conexión al nuevo KeyValueStore. Este enfoque es más sencillo que calcular las diferencias y realizar actualizaciones incrementales.

Para las actualizaciones de CRL delta, utilice el comando update-keys para agregar nuevos certificados revocados al KeyValueStore existente:

```
aws cloudfront update-key-value-store \
  --name "revoked-serials-kvs" \
  --if-match "current-etag" \
  --put file://delta-revoked-serials.json
```

## Planificación de la capacidad de KeyValueStore
<a name="plan-kvs-capacity"></a>

KeyValueStore tiene un límite de tamaño total de 5 MB y admite hasta 10 millones de pares clave-valor. Planifique la capacidad de la lista de revocación en función del formato de la clave y del tamaño de los datos:
+ **Solo número de serie**: almacenamiento eficiente para una comprobación sencilla de las revocaciones
+ **Identificador del emisor \$1 número de serie**: claves más largas para entornos con varias autoridades de certificación

En el caso de listas de revocación de gran tamaño, considere la posibilidad de implementar un enfoque escalonado en el que mantenga almacenes KeyValueStores independientes para diferentes categorías de certificados o periodos de tiempo.

# Personalización en la periferia con Lambda@Edge
<a name="lambda-at-the-edge"></a>

Lambda@Edge es una extensión de AWS Lambda. Lambda@Edge es un servicio informático que le permite ejecutar funciones que personalizan el contenido que entrega Amazon CloudFront. Puede crear funciones de Node.js o Python en la consola de Lambda en una sola Región de AWS, Este de EE. UU. (Norte de Virginia).

Después de crear la función, puede agregar desencadenadores con la consola de Lambda o la de CloudFront que hacen que las funciones se ejecuten en ubicaciones de AWS que están más cerca del espectador, sin necesidad de aprovisionar ni administrar servidores. Si lo desea, puede utilizar las operaciones de las API de Lambda y CloudFront para configurar las funciones y los desencadenadores mediante programación.

Lambda@Edge se escala automáticamente, desde unas pocas solicitudes al día a miles de solicitudes por segundo. Procesar solicitudes en ubicaciones de AWS más cercanas al espectador en lugar de en servidores de origen reduce significativamente la latencia y mejora la experiencia del usuario.

**nota**  
Lambda@Edge no es compatible con las solicitudes de gRPC. Para obtener más información, consulte [Uso de gRPC con distribuciones de CloudFront](distribution-using-grpc.md).

**Topics**
+ [

# Cómo funciona Lambda@Edge con las solicitudes y las respuestas
](lambda-edge-event-request-response.md)
+ [

# Formas de utilizar Lambda@Edge
](lambda-edge-ways-to-use.md)
+ [

# Introducción a las funciones de Lambda@Edge (consola)
](lambda-edge-how-it-works.md)
+ [

# Configuración de permisos y roles de IAM para Lambda@Edge
](lambda-edge-permissions.md)
+ [

# Escritura y creación de una función de Lambda@Edge
](lambda-edge-create-function.md)
+ [

# Adición de desencadenadores para una función de Lambda@Edge
](lambda-edge-add-triggers.md)
+ [

# Prueba y depuración de funciones de Lambda@Edge
](lambda-edge-testing-debugging.md)
+ [

# Eliminación de réplicas y funciones de Lambda@Edge
](lambda-edge-delete-replicas.md)
+ [

# Estructura de eventos de Lambda@Edge
](lambda-event-structure.md)
+ [

# Trabajo con solicitudes y respuestas
](lambda-generating-http-responses.md)
+ [

# Funciones de ejemplo de Lambda@Edge
](lambda-examples.md)

# Cómo funciona Lambda@Edge con las solicitudes y las respuestas
<a name="lambda-edge-event-request-response"></a>

Cuando asocia una distribución de CloudFront con una función de Lambda@Edge, CloudFront intercepta solicitudes y respuestas en ubicaciones de borde de CloudFront. Puede ejecutar funciones de Lambda cuando se producen los siguientes eventos de CloudFront:
+ Cuando CloudFront reciba una solicitud de un espectador (solicitud del espectador)
+ Antes de que CloudFront reenvíe una solicitud al origen (solicitud al origen)
+ Cuando CloudFront reciba una respuesta del origen (respuesta del origen)
+ Antes de que CloudFront devuelva la respuesta al espectador (respuesta al espectador)

Si utiliza AWS WAF, la solicitud del espectador de Lambda@Edge se ejecuta después de aplicar cualquier regla de AWS WAF.

Para obtener más información, consulte [Trabajo con solicitudes y respuestas](lambda-generating-http-responses.md) y [Estructura de eventos de Lambda@Edge](lambda-event-structure.md).

# Formas de utilizar Lambda@Edge
<a name="lambda-edge-ways-to-use"></a>

Existe una gran variedad de usos para el procesamiento con Lambda@Edge con su distribución de Amazon CloudFront, como en los siguientes ejemplos:
+ Una función de Lambda puede inspeccionar las cookies y reescribir URL, a fin de que los usuarios vean distintas versiones de un sitio para pruebas A/B.
+ CloudFront puede devolver diferentes objetos a lectores en función del dispositivo que estén utilizando comprobando el encabezado `User-Agent`, que incluye información acerca de los dispositivos. Por ejemplo, CloudFront puede devolver imágenes diferentes en función del tamaño de las pantallas de su dispositivo. Del mismo modo, la función podría tener en cuenta el valor del encabezado `Referer` y hacer que CloudFront devuelva a bots las imágenes con la menor resolución disponible. 
+ O bien, podría comprobar las cookies para otros criterios. Por ejemplo, en un sitio web minorista que vende ropa, si utiliza cookies para indicar el color de chaqueta que eligió un usuario, la función de Lambda puede cambiar la solicitud para que CloudFront devuelva la imagen de una chaqueta del color seleccionado.
+ Una función de Lambda puede generar respuestas HTTP cuando ocurran eventos de solicitudes al origen o del lector de CloudFront.
+ Una función puede inspeccionar encabezados o tokens de autorización e insertar un encabezado para controlar el acceso a su contenido antes de que CloudFront reenvíe una solicitud a su origen.
+ Una función de Lambda también puede realizar llamadas de red a recursos externos para confirmar credenciales de usuarios o buscar contenido adicional para personalizar una respuesta.

Para obtener más información, incluido código de ejemplo, consulte [Funciones de ejemplo de Lambda@Edge](lambda-examples.md).

Para obtener más información acerca de cómo configurar Lambda@Edge en la consola, consulte [Tutorial: Creación de una función de Lambda@Edge básica (consola)](lambda-edge-how-it-works-tutorial.md).

# Introducción a las funciones de Lambda@Edge (consola)
<a name="lambda-edge-how-it-works"></a>

Con Lambda@Edge, puede utilizar desencadenadores de CloudFront para invocar una función de Lambda. Cuando asocia una distribución de CloudFront con una función de Lambda, CloudFront [intercepta solicitudes y respuestas](https://docs.aws.amazon.com/lambda/latest/dg/lambda-edge.html) en ubicaciones de borde de CloudFront y ejecuta la función. Las funciones de Lambda pueden mejorar la seguridad o personalizar la información según la ubicación de los lectores, para mejorar el rendimiento.

En la siguiente lista se ofrece información general básica sobre cómo crear y utilizar funciones de Lambda con CloudFront.

**Información general: Creación y uso de funciones de Lambda con CloudFront**

1. Cree una función de Lambda en la región Este de EE. UU. (Norte de Virginia).

1. Guarde y publique una versión numerada de la función.

   Si desea cambiar la función, debe editar la versión \$1LATEST de la función en la región EE. UU. Este (Norte de Virginia). A continuación, antes de configurarla para usarla con CloudFront, publique una nueva versión numerada.

1. Asocie la función a un comportamiento de distribución y caché de CloudFront. A continuación, especifique uno o varios eventos de CloudFront (*desencadenadores*) que provoquen la ejecución de la función. Por ejemplo, puede crear un desencadenador para que la función se ejecute cuando CloudFront reciba una solicitud de un lector.

1. Cuando crea un desencadenador, Lambda crea réplicas de la función en ubicaciones de AWS de todo el mundo.

**sugerencia**  
Para obtener más información, consulte [creación y actualización de funciones](lambda-edge-create-function.md), [la estructura de los eventos](lambda-event-structure.md) y la [agregación de desencadenadores de CloudFront](lambda-edge-add-triggers.md). También puede encontrar más ideas y obtener ejemplos de código en [Funciones de ejemplo de Lambda@Edge](lambda-examples.md).

Para ver un tutorial paso a paso, consulte el tema siguiente:

**Topics**
+ [

# Tutorial: Creación de una función de Lambda@Edge básica (consola)
](lambda-edge-how-it-works-tutorial.md)

# Tutorial: Creación de una función de Lambda@Edge básica (consola)
<a name="lambda-edge-how-it-works-tutorial"></a>

En este tutorial, se muestra cómo comenzar a utilizar Lambda@Edge mediante la creación y configuración de una función de Node.js de ejemplo que se ejecuta en CloudFront. En el ejemplo se agregan encabezados HTTP de seguridad a una respuesta cuando CloudFront recupera un archivo. (Esto puede mejorar la seguridad y la privacidad de un sitio web).

No necesita su propio sitio web para este tutorial. Sin embargo, si decide crear su propia solución de Lambda@Edge, seguirá pasos similares y elegirá entre las mismas opciones.

**Topics**
+ [

## Paso 1: Regístrese para obtener una Cuenta de AWS
](#lambda-edge-how-it-works-tutorial-AWS)
+ [

## Paso 2: Cree una distribución de CloudFront
](#lambda-edge-how-it-works-tutorial-cloudfront)
+ [

## Paso 3: Cree su función
](#lambda-edge-how-it-works-tutorial-create-function)
+ [

## Paso 4: Agregue un desencadenador de CloudFront para ejecutar la función
](#lambda-edge-how-it-works-tutorial-add-trigger)
+ [

## Paso 5: Verifique que la función se ejecuta
](#lambda-edge-how-it-works-tutorial-verify)
+ [

## Paso 6: Solucione problemas
](#lambda-edge-how-it-works-tutorial-troubleshoot)
+ [

## Paso 7: Elimine los recursos del ejemplo
](#lambda-edge-how-it-works-tutorial-cleanup-resources)
+ [

## Información relacionada
](#lambda-edge-how-it-works-tutorial-resources)

## Paso 1: Regístrese para obtener una Cuenta de AWS
<a name="lambda-edge-how-it-works-tutorial-AWS"></a>

Si aún no lo ha hecho, regístrese para conseguir una Cuenta de AWS. Para obtener más información, consulte [Cómo crear una Cuenta de AWS](setting-up-cloudfront.md#sign-up-for-aws).

## Paso 2: Cree una distribución de CloudFront
<a name="lambda-edge-how-it-works-tutorial-cloudfront"></a>

Antes de crear la función de Lambda@Edge de ejemplo, debe tener un entorno de CloudFront con el que trabajar que incluya un origen para distribuir contenido.

En este ejemplo, creará una distribución de CloudFront que utilice un bucket de Amazon S3 como origen de la distribución. Si ya dispone de un entorno, puede omitir este paso.<a name="lambda-edge-how-it-works-tutorial-cf-proc"></a>

**Para crear una distribución de CloudFront con un origen de Amazon S3**

1. Cree un bucket de Amazon S3 con un archivo o dos, como, por ejemplo, archivos de imágenes para usarlos como contenido de muestra. Puede seguir los pasos que se detallan en [Cargar su contenido en Amazon S3](https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/GettingStarted.html#GettingStartedUploadContent). Asegúrese de que establece permisos para conceder acceso de lectura público a los objetos del bucket.

1. Cree una distribución de CloudFront y agregue el bucket de S3 como un origen, siguiendo los pasos que se describen [Crear una distribución web de CloudFront](https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/GettingStarted.html#GettingStartedCreateDistribution). Si ya tiene una distribución, solo es necesario que añada el bucket como origen para esa distribución.
**sugerencia**  
Tome nota del ID de distribución. Más adelante en este tutorial, al agregar un desencadenador de CloudFront para la función, debe elegir el ID de la distribución en una lista desplegable, por ejemplo, `E653W22221KDDL`.

## Paso 3: Cree su función
<a name="lambda-edge-how-it-works-tutorial-create-function"></a>

En este paso, se crea una función de Lambda a partir de una plantilla de esquema en la consola de Lambda. La función agrega código para actualizar los encabezados de seguridad de su distribución de CloudFront. <a name="lambda-edge-how-it-works-tutorial-create-function-blueprint-proc"></a>

**Para crear una función Lambda, realice el siguiente procedimiento:**

1. Inicie sesión en la Consola de administración de AWS y abra la consola de AWS Lambda en [https://console.aws.amazon.com/lambda/](https://console.aws.amazon.com/lambda/).
**importante**  
Asegúrese de que está en la Región de AWS **Este de EE. UU.-1 (Norte de Virginia)** (**us-east-1**). Debe estar en esta región para crear funciones de Lambda@Edge.

1. Elija **Create function (Crear función)**.

1. En la página **Create function (Crear función)**, elija **Use a blueprint (Usar un proyecto)** y, a continuación, filtre los proyectos de CloudFront especificando **cloudfront** en el campo de búsqueda.
**nota**  
Los proyectos de CloudFront solo están disponibles en la región **US-East-1 (N. Virginia) (EE. UU. Este (Norte de Virginia)** (**us-east-1**).

1. Elija el esquema **Modificar encabezado de respuesta HTTP** como la plantilla para la función.

1. Escriba la siguiente información sobre su función:
   + **Nombre de la función**: ingrese un nombre para la función.
   + **Rol de ejecución**: elija cómo se deben establecer los permisos para la función. Para utilizar la plantilla de política de permisos de Lambda@Edge básica recomendada, elija **Create a new role from policy templates (Crear un nuevo rol a partir de plantillas de política de AWS)**.
   + **Nombre de rol**: ingrese un nombre para el rol que crea la plantilla de política.
   + **Plantillas de política**: Lambda agrega automáticamente la plantilla de política **Permisos básicos de Lambda@Edge** porque ha elegido un esquema de CloudFront como base de la función. Esta plantilla de política agrega permisos de rol de ejecución que permiten a CloudFront ejecutar su función de Lambda en ubicaciones de CloudFront en todo el mundo. Para obtener más información, consulte [Configuración de permisos y roles de IAM para Lambda@Edge](lambda-edge-permissions.md).

1. Elija **Crear función** en la parte inferior de la página.

1. En el panel **Implementar en Lambda@Edge** que aparece, elija **Cancelar**. (Para este tutorial, debe modificar el código de la función antes de implementarla en Lambda@Edge).

1. Desplácese hacia abajo hasta la sección **Código fuente**.

1. Reemplace el código de la plantilla por una función que modifique los encabezados de seguridad que devuelve el origen. Por ejemplo, puede utilizar código similar al siguiente:

   ```
   '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. Elija **Archivo**, **Guardar** para guardar el código actualizado.

1. Elija **Implementar**.

Continúe con la siguiente sección para agregar un desencadenador de CloudFront para ejecutar la función.

## Paso 4: Agregue un desencadenador de CloudFront para ejecutar la función
<a name="lambda-edge-how-it-works-tutorial-add-trigger"></a>

Ahora que tiene una función de Lambda para actualizar los encabezados de seguridad, configure el desencadenador de CloudFront para ejecutar la función que va a agregar los encabezados a cualquier respuesta que CloudFront reciba desde el origen de la distribución.<a name="lambda-edge-how-it-works-tutorial-add-trigger-proc"></a>

**Para configurar el desencadenador CloudFront para su función**

1. En la consola de Lambda, en la página **Información general de la función** de la función, seleccione **Agregar desencadenador**.

1. En **Configuración del desencadenador**, elija **CloudFront**.

1. Elija **Implementar en Lambda @Edge**.

1. En el panel **Implementar en Lambda@Edge**, en **Configurar desencadenador de CloudFront**, escriba lo siguiente:
   + **Distribución**: el ID de distribución de CloudFront que se debe asociar a la función. En la lista desplegable, elija el ID de distribución.
   + **Comportamiento de la caché**: el comportamiento de la caché que se debe utilizar con el desencadenador. En este ejemplo, deje el valor establecido en **\$1**, es decir, el comportamiento de caché predeterminado de la distribución. Para obtener más información, consulte [Configuración del comportamiento de la caché](DownloadDistValuesCacheBehavior.md) en el tema [Referencia de toda la configuración de distribución](distribution-web-values-specify.md).
   + **Evento de CloudFront**: el desencadenador que especifica cuándo se ejecutará la función. Queremos que la función de encabezados de seguridad se ejecute siempre que CloudFront devuelva una respuesta desde el origen. En la lista desplegable, elija **Respuesta de origen**. Para obtener más información, consulte [Adición de desencadenadores para una función de Lambda@Edge](lambda-edge-add-triggers.md).

1. Seleccione la casilla de verificación **Confirmar implementación en Lambda @Edge**.

1. Seleccione **Deploy (Implementar)** para añadir el desencadenador y replicar la función a ubicaciones de AWS en todo el mundo.

1. Espere a que la función se replique. Esta operación suele tardar varios minutos.

    Para comprobar si la replicación ha terminado, [vaya a la consola de CloudFront](https://console.aws.amazon.com/cloudfront/v4/home) y consulte la distribución. Espere a que el estado de la distribución cambie de **Implementando** a una fecha y hora, lo que significa que la función se ha replicado. Para comprobar que la función es correcta, realice los pasos de la siguiente sección.

## Paso 5: Verifique que la función se ejecuta
<a name="lambda-edge-how-it-works-tutorial-verify"></a>

Ahora que ha creado la función de Lambda y que ha configurado un desencadenador para que la ejecute en una distribución de CloudFront, asegúrese de que la función se comporta según lo previsto. En este ejemplo, comprobamos los encabezados HTTP que devuelve CloudFront, para asegurarnos de que se agregan los encabezados de seguridad.<a name="lambda-edge-how-it-works-tutorial-verify-proc"></a>

**Para verificar que la función de Lambda@Edge añade los encabezados de seguridad**

1. En un navegador, escriba la dirección URL de un archivo de su bucket de S3. Por ejemplo, puede utilizar una URL similar a `https://d111111abcdef8.cloudfront.net/image.jpg`.

   Para obtener más información sobre el nombre de dominio de CloudFront que se debe utilizar en la URL del archivo, consulte [Personalización del formato de URL para archivos en CloudFront](LinkFormat.md).

1. Abra la barra de herramientas para desarrolladores web del navegador. Por ejemplo, en la ventana del navegador Chrome, abra el menú contextual (haga clic con el botón derecho) y, a continuación, elija **Inspeccionar**.

1. Elija la pestaña **Network (Red)**.

1. Vuelva a cargar la página para ver la imagen y, a continuación, elija una solicitud HTTP en el panel izquierdo. Verá que los encabezados HTTP se muestran en un panel independiente.

1. Examine la lista de encabezados HTTP para verificar que incluye los encabezados de seguridad esperados. Por ejemplo, es posible que vea encabezados similares a los que se muestran en la siguiente captura de pantalla.  
![\[Lista de encabezados HTTP con los encabezados de seguridad esperados resaltados.\]](http://docs.aws.amazon.com/es_es/AmazonCloudFront/latest/DeveloperGuide/images/lambda-at-edge-security-headers-list.png)

Si los encabezados de seguridad se incluyen en la lista de encabezados, ¡estupendo\$1 Significa que ha creado correctamente su primera función de Lambda@Edge. Si CloudFront devuelve algún error o hay otros problemas, continúe con el paso siguiente para solucionar los problemas.

## Paso 6: Solucione problemas
<a name="lambda-edge-how-it-works-tutorial-troubleshoot"></a>

Si CloudFront devuelve errores o no agrega los encabezados de seguridad según lo previsto, puede investigar la ejecución de la función consultando los CloudWatch Logs. Asegúrese de utilizar los registros almacenados en la ubicación de AWS más cercana a la ubicación en que se ejecuta la función.

Por ejemplo, si ve el archivo desde Londres, pruebe a cambiar la región en la consola de CloudWatch a UE (Londres).<a name="lambda-edge-how-it-works-tutorial-cloudwatch-proc"></a>

**Para examinar los registros de CloudWatch para su función de Lambda@Edge**

1. Inicie sesión en la Consola de administración de AWS y abra la consola de CloudWatch en [https://console.aws.amazon.com/cloudwatch/](https://console.aws.amazon.com/cloudwatch/).

1. Cambie **Región (Región)** a la ubicación que se muestra al ver el archivo en el navegador. Aquí es donde se está ejecutando la función.

1. En el panel izquierdo, elija **Logs** para ver los logs de la distribución. 

Para obtener más información, consulte [Supervisión de métricas de CloudFront con Amazon CloudWatch](monitoring-using-cloudwatch.md).

## Paso 7: Elimine los recursos del ejemplo
<a name="lambda-edge-how-it-works-tutorial-cleanup-resources"></a>

Si ha creado un bucket de Amazon S3 y una distribución de CloudFront solo para este tutorial, elimine los recursos de AWS asignados para que no se le apliquen cargos. Después de eliminar los recursos de AWS, el contenido que haya añadido dejará de estar disponible.

**Tareas**
+ [Elimine el bucket de S3](#lambda-edge-how-it-works-tutorial-delete-bucket) 
+ [Para eliminar la función de Lambda](#lambda-edge-how-it-works-tutorial-delete-function)
+ [Eliminar la distribución de CloudFront](#lambda-edge-how-it-works-tutorial-delete-distribution)

### Elimine el bucket de S3
<a name="lambda-edge-how-it-works-tutorial-delete-bucket"></a>

Antes de eliminar su bucket de Amazon S3, asegúrese de que la función de registro esté desactivada para el bucket. De lo contrario, AWS seguirá escribiendo logs en el bucket mientras lo elimina.<a name="lambda-edge-how-it-works-tutorial-delete-bucket-proc"></a>

**Para deshabilitar el registro en el bucket**

1. Abra la consola de Amazon S3 en [https://console.aws.amazon.com/s3](https://console.aws.amazon.com/s3/).

1. Seleccione el bucket y, luego, seleccione **Properties (Propiedades)**.

1. En **Properties (Propiedades)**, elija **Logging (Registro)**.

1. Elimine la selección del recuadro **Enabled (Habilitado)**.

1. Seleccione **Guardar**.

Ahora ya puede eliminar el bucket. Para obtener más información, consulte [Eliminación de un bucket](https://docs.aws.amazon.com/AmazonS3/latest/userguide/delete-bucket.html) en la *Guía del usuario de la consola de Amazon Simple Storage Service*.

### Para eliminar la función de Lambda
<a name="lambda-edge-how-it-works-tutorial-delete-function"></a>

Para obtener instrucciones sobre cómo eliminar la asociación de función de Lambda y, opcionalmente, la propia función, consulte [Eliminación de réplicas y funciones de Lambda@Edge](lambda-edge-delete-replicas.md).

### Eliminar la distribución de CloudFront
<a name="lambda-edge-how-it-works-tutorial-delete-distribution"></a>

Antes de eliminar una distribución de CloudFront, debe desactivarla. Una distribución deshabilitada ya no es funcional y no acumula cargos. Puede habilitar una distribución deshabilitada en cualquier momento. Después de eliminar una distribución deshabilitada, esta deja de estar disponible.<a name="lambda-edge-how-it-works-tutorial-delete-distribution-proc"></a>

**Para desactivar y eliminar una distribución de CloudFront, realice las siguientes acciones:**

1. Abra la consola de CloudFront en [https://console.aws.amazon.com/cloudfront/v4/home](https://console.aws.amazon.com/cloudfront/v4/home).

1. Seleccione la distribución que desea deshabilitar y elija **Disable** (Deshabilitar).

1. Cuando se le indique que confirme, seleccione **Yes, Disable (Sí, deshabilitar)**.

1. Seleccione la distribución desactivada y después **Delete (Eliminar)**.

1. Cuando se le indique que confirme, seleccione **Yes, Delete**.

## Información relacionada
<a name="lambda-edge-how-it-works-tutorial-resources"></a>

Ahora que tiene una idea básica de cómo funcionan las funciones de Lambda@Edge, puede obtener más información leyendo los temas siguientes:
+ [Funciones de ejemplo de Lambda@Edge](lambda-examples.md)
+ [Prácticas recomendadas de diseño de Lambda@Edge](https://aws.amazon.com/blogs/networking-and-content-delivery/lambdaedge-design-best-practices/)
+ [Reducción de la latencia y traslado de cómputo al borde con Lambda@Edge](https://aws.amazon.com/blogs/networking-and-content-delivery/reducing-latency-and-shifting-compute-to-the-edge-with-lambdaedge/)

# Configuración de permisos y roles de IAM para Lambda@Edge
<a name="lambda-edge-permissions"></a>

Para configurar Lambda@Edge, debe tener los siguientes permisos y roles de IAM para AWS Lambda: 
+ [Permisos de IAM](#lambda-edge-permissions-required): estos permisos le permiten crear la función de Lambda y asociarla a la distribución de CloudFront.
+ [Un rol de ejecución de una función de Lambda](#lambda-edge-permissions-function-execution) (rol de IAM): las entidades principales de servicio de Lambda asumen este rol para ejecutar la función.
+ [Roles vinculados a servicios para Lambda@Edge](#using-service-linked-roles-lambda-edge): los roles vinculados a servicios permiten a Servicios de AWS específicos replicar funciones de Lambda en Regiones de AWS y permitir que CloudWatch utilice archivos de registro de CloudFront.

## Permisos de IAM necesarios para asociar funciones de Lambda@Edge con distribuciones de CloudFront
<a name="lambda-edge-permissions-required"></a>

Además de los permisos de IAM necesarios para Lambda, necesita los siguientes permisos para asociar funciones de Lambda a las distribuciones de CloudFront:
+ `lambda:GetFunction`: concede permisos para obtener información de configuración para la función de Lambda y una URL prefirmada para descargar un archivo `.zip` que contiene la función.
+ `lambda:EnableReplication*`: concede permisos a la política de recursos de modo que el servicio de replicación de Lambda pueda obtener una configuración y un código de función.
+ `lambda:DisableReplication*`: concede permisos a la política de recursos de modo que el servicio de replicación de Lambda pueda eliminar la función.
**importante**  
Debe agregar el asterisco (`*`) al final de las acciones `lambda:EnableReplication*` y `lambda:DisableReplication*`.
+ Para el recurso, especifique el ARN de la versión de la función que desea ejecutar cuando se produzca un evento de CloudFront, como en el ejemplo siguiente:

  `arn:aws:lambda:us-east-1:123456789012:function:TestFunction:2`
+ `iam:CreateServiceLinkedRole`: concede permiso para crear un rol vinculado a un servicio que utiliza Lambda@Edge para replicar funciones de Lambda en CloudFront. Después de configurar Lambda@Edge por primera vez, el rol vinculado a un servicio se crea automáticamente. No es necesario agregar este permiso a otras distribuciones que utilizan Lambda@Edge.

  
+ `cloudfront:UpdateDistribution` o `cloudfront:CreateDistribution`: concede permiso para actualizar o crear una distribución.

Para obtener más información, consulte los temas siguientes:
+ [Identity and Access Management para Amazon CloudFront](security-iam.md)
+ [Permisos de acceso a recursos de Lambda](https://docs.aws.amazon.com/lambda/latest/dg/intro-permission-model.html#lambda-intro-execution-role) en la *Guía para desarrolladores de AWS Lambda*

## Rol de ejecución de funciones para las entidades principales del servicio
<a name="lambda-edge-permissions-function-execution"></a>

Debe crear un rol de IAM que las entidades principales de servicio `lambda.amazonaws.com` y `edgelambda.amazonaws.com` puedan asumir cuando ejecuten su función. 

**sugerencia**  
Cuando crea la función en la consola de Lambda, puede elegir crear un nuevo rol de ejecución utilizando una plantilla de políticas de AWS. En este paso, se agregan *automáticamente* los permisos de Lambda@Edge necesarios para ejecutar la función. Consulte el [Paso 5 del tutorial: creación de una función de Lambda@Edge sencilla](lambda-edge-how-it-works-tutorial.md#lambda-edge-how-it-works-tutorial-create-function).

Para obtener más información sobre cómo crear un rol de IAM manualmente, consulte [Creación de roles y asociación de políticas (consola)](https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_job-functions_create-policies.html) en la *Guía del usuario de IAM*.

**Example Ejemplo: Política de confianza de rol**  
Puede agregar este rol en la pestaña **Relación de confianza** en la consola de IAM. No agregue esta política en la pestaña **Permisos**.    
****  

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

Para obtener más información sobre los permisos que debe conceder al rol de ejecución, consulte [Permisos de acceso a recursos de Lambda](https://docs.aws.amazon.com/lambda/latest/dg/intro-permission-model.html#lambda-intro-execution-role) en la *Guía para desarrolladores de AWS Lambda*.

**Notas**  
De forma predeterminada, siempre que un evento de CloudFront desencadene una función de Lambda, los datos se escriben en CloudWatch Logs. Si desea utilizar estos registros, el rol de ejecución necesita permiso para escribir datos en CloudWatch Logs. Puede utilizar la política predefinida AWSLambdaBasicExecutionRole para conceder permisos al rol de ejecución.  
Para obtener más información acerca de Registros de CloudWatch, consulte [Registros de funciones perimetrales](edge-functions-logs.md).
Si el código de la función de Lambda tiene acceso a otros recursos de AWS, como, por ejemplo, la lectura de un objeto de un bucket de S3, el rol de ejecución necesita permiso para realizar esa acción. 

## Roles vinculados a servicios para Lambda@Edge
<a name="using-service-linked-roles-lambda-edge"></a>

Lambda@Edge utiliza [roles vinculados a servicios](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_terms-and-concepts.html#iam-term-service-linked-role) de IAM. Un rol vinculado a un servicio es un tipo único de rol de IAM que está vinculado directamente a un servicio. Los roles vinculados a servicios están predefinidos por el servicio e incluyen todos los permisos que el servicio requiere para llamar a otros servicios de AWS en su nombre.

Lambda@Edge usa los siguientes roles vinculados a servicios de IAM:
+ **AWSServiceRoleForLambdaReplicator** – Lambda@Edge utiliza este rol para permitir que Lambda@Edge replique funciones en Regiones de AWS.

  Cuando se agrega un desencadenador de Lambda@Edge por primera vez en CloudFront, se crea automáticamente un rol denominado AWSServiceRoleForLambdaReplicator para permitir que Lambda@Edge replique funciones en Regiones de AWS. Este rol es necesario para utilizar las funciones de Lambda@Edge. El ARN del rol AWSServiceRoleForLambdaReplicator tiene el aspecto del siguiente ejemplo:

  `arn:aws:iam::123456789012:role/aws-service-role/replicator.lambda.amazonaws.com/AWSServiceRoleForLambdaReplicator`
+ **AWSServiceRoleForCloudFrontLogger** – CloudFront utiliza este rol para insertar archivos de registro en CloudWatch. Puede usar archivos de registro para depurar los errores de validación de Lambda@Edge.

  El rol AWSServiceRoleForCloudFrontLogger se crea automáticamente al agregar una asociación de función de Lambda@Edge para permitir que CloudFront envíe archivos de registro de errores de Lambda@Edge a CloudWatch. El ARN del rol AWSServiceRoleForCloudFrontLogger tiene este aspecto:

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

Los roles vinculados a servicios simplifican la configuración y el uso de Lambda@Edge porque no será necesario añadir manualmente los permisos necesarios. Lambda@Edge define los permisos de sus roles vinculados a servicios y solo Lambda@Edge puede asumir estos roles. Los permisos definidos incluyen la política de confianza y la política de permisos. No se puede adjuntar la política de permisos a ninguna otra entidad de IAM.

Debe eliminar los recursos de CloudFront o de Lambda@Edge asociados para poder eliminar un rol vinculado a servicio. Esto ayuda a proteger sus recursos de Lambda@Edge de modo que no elimine un rol vinculado a un servicio que sigue siendo necesario para obtener acceso a los recursos activos.

Para obtener más información acerca de los roles vinculados a servicios, consulte [Roles vinculados a servicios para CloudFront](security_iam_service-with-iam.md#security_iam_service-with-iam-roles-service-linked). 

### Permisos de roles vinculados a servicios para Lambda@Edge
<a name="slr-permissions-lambda-edge"></a>

Lambda@Edge utiliza dos roles vinculados a servicios, denominados **AWSServiceRoleForLambdaReplicator** y **AWSServiceRoleForCloudFrontLogger**. En las siguientes secciones se describen los permisos de cada uno de estos roles.

**Contents**
+ [

#### Permisos del rol vinculado a servicio para el replicador de Lambda
](#slr-permissions-lambda-replicator)
+ [

#### Permisos de rol vinculado a servicio para el registrador de CloudFront
](#slr-permissions-cloudfront-logger)

#### Permisos del rol vinculado a servicio para el replicador de Lambda
<a name="slr-permissions-lambda-replicator"></a>

Este rol vinculado a servicio permite que Lambda replique las funciones de Lambda@Edge en Regiones de AWS.

El rol vinculado a servicios AWSServiceRoleForLambdaReplicator confía en el servicio `replicator.lambda.amazonaws.com` para asumir el rol.

La política de permisos del rol permite que Lambda@Edge realice las siguientes acciones en los recursos especificados:
+ `lambda:CreateFunction` en `arn:aws:lambda:*:*:function:*`
+ `lambda:DeleteFunction` en `arn:aws:lambda:*:*:function:*`
+ `lambda:DisableReplication` en `arn:aws:lambda:*:*:function:*`
+ `iam:PassRole` en `all AWS resources`
+  `cloudfront:ListDistributionsByLambdaFunction` en `all AWS resources`

#### Permisos de rol vinculado a servicio para el registrador de CloudFront
<a name="slr-permissions-cloudfront-logger"></a>

Este rol vinculado a un servicio permite que CloudFront envíe archivos de registro a CloudWatch de modo que pueda depurar errores de validación de Lambda@Edge.

El rol vinculado a servicios AWSServiceRoleForCloudFrontLogger confía en el servicio `logger.cloudfront.amazonaws.com` para asumir el rol.

La política de permisos de rol permite que Lambda@Edge realice las siguientes acciones en el recurso de `arn:aws:logs:*:*:log-group:/aws/cloudfront/*` especificado:
+ `logs:CreateLogGroup` ``
+ `logs:CreateLogStream`
+ `logs:PutLogEvents`

Debe configurar permisos para permitir que una entidad de IAM (como un usuario, grupo o rol) elimine los roles vinculados a servicios de Lambda@Edge. Para obtener más información, consulte [Permisos de roles vinculados a servicios](https://docs.aws.amazon.com/IAM/latest/UserGuide/using-service-linked-roles.html#service-linked-role-permissions) en la *Guía del usuario de IAM*.

### Creación de roles vinculados a servicios para Lambda@Edge
<a name="create-slr-lambda-edge"></a>

Normalmente no es necesario crear manualmente los roles vinculados a servicios para Lambda@Edge. El servicio crea los roles automáticamente en los siguientes casos:
+ Cuando se crea un desencadenador por primera vez, el servicio crea el rol AWSServiceRoleForLambdaReplicator (si aún no existe). Este rol permite que Lambda replique las funciones de Lambda@Edge en Regiones de AWS.

  Si elimina el rol vinculado a servicio, el rol se creará de nuevo al añadir un nuevo disparador para Lambda@Edge en una distribución.
+ Cuando se actualiza o se crea una distribución de CloudFront que tiene una asociación de Lambda@Edge, el servicio crea un rol AWSServiceRoleForCloudFrontLogger (si no existe ya). Este rol permite a CloudFront insertar sus archivos de registro en CloudWatch.

  Si elimina el rol vinculado al servicio, el rol se creará de nuevo al actualizar o crear una distribución de CloudFront que tiene una asociación de Lambda@Edge.

Para crear manualmente estos roles vinculados a servicios, ejecute los siguientes comandos de la AWS Command Line Interface (AWS CLI):

**Para crear el rol de AWSServiceRoleForLambdaReplicator**
+ Ejecute el siguiente comando.

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

**Para crear el rol de AWSServiceRoleForCloudFrontLogger**
+ Ejecute el siguiente comando.

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

### Edición de roles vinculados a servicios de Lambda@Edge
<a name="edit-slr-lambda-edge"></a>

Lambda@Edge no permite editar los roles vinculados a servicios AWSServiceRoleForLambdaReplicator o AWSServiceRoleForCloudFrontLogger. Una vez que el servicio ha creado un rol vinculado a un servicio, no puede cambiarle el nombre, ya que varias entidades pueden hacer referencia a él. Sin embargo, puede utilizar IAM para editar la descripción del rol. Para obtener más información, consulte [Editar un rol vinculado a servicios](https://docs.aws.amazon.com/IAM/latest/UserGuide/using-service-linked-roles.html#edit-service-linked-role) en la *Guía del usuario de IAM*.

### Regiones de AWS compatibles con roles vinculados a servicios de Lambda@Edge
<a name="slr-regions-lambda-edge"></a>

CloudFront admite el uso de roles vinculados a servicios para Lambda@Edge en las siguientes Regiones de AWS:
+ Este de EE. UU. (Norte de Virginia) – `us-east-1`
+ Este de EE. UU. (Ohio) – `us-east-2`
+ Oeste de EE. UU. (Norte de California) – `us-west-1`
+ Oeste de EE. UU. (Oregón) – `us-west-2`
+ Asia-Pacífico (Bombay) – `ap-south-1`
+ Asia-Pacífico (Seúl) – (`ap-northeast-2`)
+ Asia Pacífico (Singapur) – `ap-southeast-1`
+ Asia-Pacífico (Sídney) – `ap-southeast-2`
+ Asia-Pacífico (Tokio) – `ap-northeast-1`
+ Europa (Fráncfort) – `eu-central-1`
+ Europa (Irlanda) – `eu-west-1`
+ Europa (Londres) – `eu-west-2`
+ América del Sur (São Paulo) – `sa-east-1`

# Escritura y creación de una función de Lambda@Edge
<a name="lambda-edge-create-function"></a>

Para usar Lambda@Edge, debe *escribir* el código de la función de AWS Lambda. Para ayudarle a escribir funciones de Lambda@Edge, consulte los siguientes recursos:
+  [Estructura de eventos de Lambda@Edge](lambda-event-structure.md): comprensión de la estructura de eventos que se va a utilizar con Lambda@Edge.
+ [Funciones de ejemplo de Lambda@Edge](lambda-examples.md): funciones de ejemplo, como pruebas A/B y generación de un redireccionamiento HTTP.

El modelo de programación para utilizar Node.js o Python con Lambda@Edge es el mismo que para utilizar Lambda en una Región de AWS. Para obtener más información, consulte [Creación de funciones de Lambda con Node.js](https://docs.aws.amazon.com/lambda/latest/dg/lambda-nodejs.html) o [Creación de funciones de Lambda con Python](https://docs.aws.amazon.com/lambda/latest/dg/lambda-python.html) en la *Guía del desarrollador de AWS Lambda*.

En su función de Lambda@Edge, incluya el parámetro `callback` y devuelva el objeto correspondiente para eventos de solicitud o de respuesta:
+ **Eventos de solicitud**: incluya el objeto `cf.request` en la respuesta.

  Si está generando una respuesta, incluya el objeto `cf.response` en ella. Para obtener más información, consulte [Generación de respuestas HTTP en los desencadenadores de solicitud](lambda-generating-http-responses.md#lambda-generating-http-responses-in-requests). 
+ **Eventos de respuesta**: incluya el objeto `cf.response` en la respuesta.

Tras escribir su propio código o utilizar uno de los ejemplos, cree la función en Lambda. Para crear una función o editar una ya existente, consulte los temas siguientes:

**Topics**
+ [

# Creación de una función de Lambda@Edge
](lambda-edge-create-in-lambda-console.md)
+ [

# Edición de una función de Lambda
](lambda-edge-edit-function.md)

 Después de crear la función en Lambda, se configura Lambda para ejecutar la función según los eventos de CloudFront específicos, que se denominan *desencadenadores*. Para obtener más información, consulte [Adición de desencadenadores para una función de Lambda@Edge](lambda-edge-add-triggers.md).

# Creación de una función de Lambda@Edge
<a name="lambda-edge-create-in-lambda-console"></a>

Para configurar AWS Lambda para que ejecute funciones Lambda basadas en eventos de CloudFront, siga este procedimiento.<a name="lambda-edge-create-function-procedure"></a>

**Para crear una función de Lambda@Edge**

1. Inicie sesión en la Consola de administración de AWS y abra la consola de AWS Lambda en [https://console.aws.amazon.com/lambda/](https://console.aws.amazon.com/lambda/).

1. Si ya tiene una o varias funciones de Lambda, elija **Create function (Crear función)**.

   Si no tiene ninguna función, elija **Get Started Now (Comenzar ahora)**.

1. En la lista Región de la parte superior de la página, elija **US East (N. Virginia) (EE. UU. Este (Norte de Virginia))**.

1. Cree una función mediante su propio código o cree una función a partir de un proyecto de CloudFront.
   + Para crear una función utilizando su propio código, elija **Author from scratch (Crear desde cero)**. 
   + Para mostrar una lista de esquemas de CloudFront, ingrese **cloudfront** en el campo de filtro y, a continuación, elija **Intro**.

     Si encuentra un proyecto que desee utilizar, elija el nombre del proyecto.

1. En la sección **Basic information (Información básica)**, especifique los siguientes valores:

   1. **Nombre**: escriba un nombre para la función.

   1. **Rol**: para empezar rápidamente, seleccione **Crear un rol nuevo desde las plantillas**. También puede seleccionar **Elegir un rol existente** o **Crear un rol personalizado** y, a continuación, seguir las indicaciones para completar la información de esta sección.

   1. **Nombre del rol**: escriba un nombre para el rol.

   1. **Plantillas de políticas**: elija **Permisos básicos de Edge Lambda**.

1. Si eligió **Author from scratch (Crear desde cero)** en el paso 4, vaya al paso 7.

   Si eligió un proyecto en el paso 4, la sección **cloudfront** le permite crear un desencadenador, que asocia esta función con una memoria caché en una distribución de CloudFront y un evento de CloudFront. Le recomendamos que elija **Remove (Eliminar)** en este punto, por lo que no habrá un disparador para la función cuando esta se cree. Podrá añadir disparadores más adelante. 
**sugerencia**  
Le recomendamos que pruebe y depure la función antes de agregar desencadenadores. Si agrega un desencadenador ahora, la función se ejecutará en cuanto la cree y terminará de replicarse en las ubicaciones de AWS en todo el mundo; además, se implementará la distribución correspondiente.

1. Elija **Create function (Crear función)**.

   Lambda crea dos versiones de su función: \$1LATEST y Version 1. Solo puede editar la versión \$1LATEST, pero la consola muestra inicialmente Version 1.

1. Para editar la función, elija **Version 1 (Versión 1)** cerca de la parte superior de la página, bajo el ARN de la función. A continuación, en la pestaña **Versions (Versiones)**, elija **\$1LATEST**. (Si abandona la función y vuelve a ella más tarde, el botón de etiqueta será **Qualifiers (Cualificadores)**).

1. En la pestaña **Configuration (Configuración)**, elija el valor correspondiente para **Code entry type (Tipo de entrada de código)**. A continuación, siga las instrucciones para editar o cargar el código.

1. En **Runtime (Tiempo de ejecución)**, elija el valor según el código de la función.

1. En la sección **Tags (Etiquetas)**, añada todas las etiquetas aplicables.

1. Elija **Actions (Acciones)** y, a continuación, **Publish new version (Publicar nueva versión)**.

1. Ingrese una descripción para la nueva versión de la función.

1. Elija **Publish**.

1. Pruebe y depure la función. Para obtener más información sobre las pruebas en la consola de Lambda, consulte [Invocar una función de Lambda con la consola](https://docs.aws.amazon.com/lambda/latest/dg/getting-started.html#get-started-invoke-manually) en la *Guía para desarrolladores de AWS Lambda*.

1. Cuando esté listo para que la función se ejecute para eventos de CloudFront, publique otra versión y edite la función para agregar desencadenadores. Para obtener más información, consulte [Adición de desencadenadores para una función de Lambda@Edge](lambda-edge-add-triggers.md).

# Edición de una función de Lambda
<a name="lambda-edge-edit-function"></a>

Después de crear una función de Lambda@Edge, puede utilizar la consola de Lambda para editarla.

**Notas**  
La versión original se denomina \$1LATEST.
Solo puede editar la versión \$1LATEST.
Cada vez que edite la versión \$1LATEST, debe publicar una nueva versión numerada.
No puede crear disparadores para \$1LATEST.
Cuando se publica una nueva versión de una función, Lambda no copia automáticamente los desencadenadores de la versión anterior a la nueva. Debe reproducir los disparadores para la nueva versión. 
Cuando se agrega un desencadenador para un evento de CloudFront a una función, si ya existe un desencadenador para la misma distribución, comportamiento de la caché y evento para una versión anterior de la misma función, Lambda lo elimina de esta versión anterior.
Después de realizar actualizaciones a una distribución de CloudFront, como agregar desencadenadores, debe esperar que los cambios se propaguen a ubicaciones de borde antes de que las funciones que ha especificado en los desencadenadores funcionen.<a name="lambda-edge-edit-function-procedure"></a>

**Para editar una función de Lambda**

1. Inicie sesión en la Consola de administración de AWS y abra la consola de AWS Lambda en [https://console.aws.amazon.com/lambda/](https://console.aws.amazon.com/lambda/).

1. En la lista Región de la parte superior de la página, elija **US East (N. Virginia) (EE. UU. Este (Norte de Virginia))**.

1. En la lista de funciones, elija el nombre de la función.

   De forma predeterminada, la consola muestra la versión \$1LATEST. Puede ver las versiones anteriores (elija **Qualifiers (Cualificadores)**), pero solo puede editar \$1LATEST.

1. En la pestaña **Code (Código)**, en **Code entry type (Tipo de entrada de código)**, elija si desea editar el código en el navegador, cargar un archivo .zip o cargar un archivo desde Amazon S3.

1. Elija **Save (Guardar)** o **Save and test (Guardar y probar)**.

1. Elija **Actions (Acciones)** y, a continuación, **Publish new version (Publicar nueva versión)**. 

1. En el cuadro de diálogo **Publish new version from \$1LATEST (Publicar una nueva versión desde \$1LATEST)**, introduzca una descripción de la nueva versión. Esta descripción aparece en la lista de versiones, junto con un número de versión generado de forma automática. 

1. Elija **Publish**.

   La nueva versión se convierte automáticamente la versión más reciente. El número de versión aparece en **Versión** en la esquina superior izquierda de la página.
**nota**  
Si no ha agregado aún desencadenadores para la función, consulte [Adición de desencadenadores para una función de Lambda@Edge](lambda-edge-add-triggers.md). 

1. Elija la pestaña **Desencadenadores**.

1. Elija **Add trigger (Añadir disparador)**.

1. En el cuadro de diálogo **Add trigger (Agregar desencadenador)**, elija el cuadro con puntos y, a continuación, **CloudFront**.
**nota**  
Si ya ha creado uno o varios desencadenadores para una función, CloudFront es el servicio predeterminado.

1. Especifique los siguientes valores para indicar cuándo desea que se ejecute la función de Lambda.

   1. **ID de distribución**: elija el ID de la distribución donde desea añadir el desencadenador.

   1. **Comportamiento de caché**: elija el comportamiento de la caché que especifica los objetos en los que desea ejecutar la función.

   1. **Evento de CloudFront**: elija el evento de CloudFront que provoca la ejecución de la función.

   1. **Activar desencadenador y replicar**: seleccione esta casilla para que Lambda replique la función en las Regiones de AWS en todo el mundo.

1. Elija **Submit**.

1. Para añadir más disparadores para esta función, repita los pasos del 10 al 13.

Para obtener más información sobre las pruebas y la depuración de la función en la consola de Lambda, consulte [Invocar una función de Lambda con la consola](https://docs.aws.amazon.com/lambda/latest/dg/getting-started.html#get-started-invoke-manually) en la *Guía para desarrolladores de AWS Lambda*.

Cuando esté listo para que la función se ejecute para eventos de CloudFront, publique otra versión y edite la función para agregar desencadenadores. Para obtener más información, consulte [Adición de desencadenadores para una función de Lambda@Edge](lambda-edge-add-triggers.md).

# Adición de desencadenadores para una función de Lambda@Edge
<a name="lambda-edge-add-triggers"></a>

Un desencadenador de Lambda@Edge es una combinación de una distribución de CloudFront, un comportamiento de la caché y un evento que provoca la ejecución de una función. Por ejemplo, puede crear un desencadenador que provoque la ejecución de la función cuando CloudFront reciba una solicitud de un lector para un comportamiento de la caché específico que haya configurado para la distribución. Puede especificar uno o más desencadenadores de CloudFront. 

**sugerencia**  
Al crear una distribución de CloudFront, debe especificar la configuración que indica a CloudFront cómo responder al recibir distintas solicitudes. La configuración predeterminada se denomina *comportamiento de la caché predeterminado* para la distribución. Puede configurar más comportamientos de la caché que definen cómo responde CloudFront en circunstancias específicas, por ejemplo, cuando recibe una solicitud para un tipo de archivo específico. Para obtener más información, consulte [Configuración del comportamiento de la caché](DownloadDistValuesCacheBehavior.md).

Cuando crea por primera vez una función de Lambda, solo puede especificar un *desencadenador*. Pero se pueden agregar más desencadenadores a la misma función más adelante con la consola de Lambda o editando la distribución en la consola de CloudFront.
+ La consola de Lambda funciona bien si desea agregar más desencadenadores a una función para la misma distribución de CloudFront.
+ La consola de CloudFront puede ser mejor si desea agregar desencadenadores para varias distribuciones, ya que es más sencillo encontrar la distribución que desea actualizar. También puede actualizar otros ajustes de CloudFront simultáneamente.

**Topics**
+ [

# Eventos de CloudFront que pueden desencadenar una función de Lambda@Edge
](lambda-cloudfront-trigger-events.md)
+ [

# Elección del evento para desencadenar la función
](lambda-how-to-choose-event.md)
+ [

# Adición de desencadenadores a una función de Lambda@Edge
](lambda-edge-add-triggers-console.md)

# Eventos de CloudFront que pueden desencadenar una función de Lambda@Edge
<a name="lambda-cloudfront-trigger-events"></a>

Para cada comportamiento de la caché de una distribución de Amazon CloudFront, puede agregar hasta cuatro desencadenadores (asociaciones) que harán que se ejecute una función de Lambda cuando se produzcan determinados eventos de CloudFront. Los desencadenadores de CloudFront pueden basarse en uno de los cuatro eventos de CloudFront que se muestran en el siguiente diagrama.

![\[Gráfico conceptual que muestra cómo se integran con CloudFront los eventos desencadenadores de CloudFront para las funciones de Lambda.\]](http://docs.aws.amazon.com/es_es/AmazonCloudFront/latest/DeveloperGuide/images/cloudfront-events-that-trigger-lambda-functions.png)


El eventos de CloudFront que pueden utilizarse para activar funciones de Lambda@Edge son los siguientes:

**Solicitud del lector**  
La función se ejecuta cuando CloudFront recibe una solicitud de un lector y antes de comprobar si el objeto solicitado está en la caché de CloudFront.  
La función no se ejecuta en los casos siguientes:  
+ Cuando se devuelve una página de error personalizada.
+ Cuando CloudFront redirige automáticamente una solicitud HTTP a HTTPS (cuando el valor de [Política de protocolo para lectores](DownloadDistValuesCacheBehavior.md#DownloadDistValuesViewerProtocolPolicy) es **Redirigir HTTP a HTTPS**).

**Solicitud del origen**  
La función se ejecuta *solo* cuando CloudFront reenvía una solicitud a su origen. Cuando el objeto solicitado está en la caché de CloudFront, la función no se ejecuta.

**Respuesta del origen**  
La función se ejecuta después de que CloudFront recibe una respuesta del origen y antes de almacenar el objeto en caché en la respuesta. Tenga en cuenta que la función se ejecuta aunque el origen devuelva un error.  
La función no se ejecuta en los casos siguientes:  
+ Cuando el archivo solicitado está en la caché de CloudFront y no ha caducado.
+ Cuando la respuesta se genera a partir de una función activada por un evento de solicitud al origen.

**Respuesta del lector**  
La función se ejecuta antes de devolver el archivo solicitado al espectador. Tenga en cuenta que la función se ejecuta independientemente de si el archivo ya está en la caché de CloudFront.  
La función no se ejecuta en los casos siguientes:  
+ Cuando el origen devuelve un código de estado HTTP 400 o superior.
+ Cuando se devuelve una página de error personalizada.
+ Cuando la respuesta se genera a partir de una función activada por un evento de solicitud del espectador.
+ Cuando CloudFront redirige automáticamente una solicitud HTTP a HTTPS (cuando el valor de [Política de protocolo para lectores](DownloadDistValuesCacheBehavior.md#DownloadDistValuesViewerProtocolPolicy) es **Redirigir HTTP a HTTPS**).

Si añade varios disparadores al mismo comportamiento de la caché, puede utilizarlos para ejecutar la misma función o distintas funciones para cada disparador. También puede asociar la misma función a más de una distribución.

**nota**  
Cuando un evento de CloudFront desencadena la ejecución de una función de Lambda, la función debe finalizar *antes* de que CloudFront pueda continuar.   
Por ejemplo, si una función Lambda se activa por medio de un evento de solicitud del espectador de CloudFront, CloudFront no devolverá una respuesta al lector ni reenviará la solicitud al origen hasta que la función Lambda termine de ejecutarse.   
Esto significa que cada solicitud que desencadena una función de Lambda aumenta la latencia de la solicitud, por lo que es conveniente que la función se ejecute con la mayor rapidez posible.

# Elección del evento para desencadenar la función
<a name="lambda-how-to-choose-event"></a>

A la hora de decidir qué evento de CloudFront utilizar para desencadenar una función de Lambda, tenga en cuenta lo siguiente:

**Quiero que CloudFront almacene en caché los objetos modificados por una función de Lambda**  
Para almacenar en caché un objeto modificado por una función de Lambda para que CloudFront pueda enviarlo desde la ubicación periférica la próxima vez que se solicite, utilice el evento de *solicitud de origen* o *respuesta de origen*.   
Esto reduce la carga en el origen, la latencia de las solicitudes posteriores y los costos de invocación de Lambda@Edge en las solicitudes posteriores.  
Por ejemplo, si desea agregar, eliminar o cambiar los encabezados de los objetos devueltos por el origen y que CloudFront almacene el resultado en caché, utilice el evento de respuesta del origen.

**Deseo que la función se ejecute por cada solicitud**  
Para ejecutar la función para cada solicitud que CloudFront reciba para la distribución, utilice los eventos de *solicitud del lector* o de *respuesta del lector*.   
Los eventos de solicitud al origen y respuesta del origen ocurren solo cuando un objeto solicitado no se almacena en caché en una ubicación de borde y CloudFront reenvía una solicitud al origen.

**Quiero que la función cambie la clave de caché**  
Para cambiar un valor que está utilizando como base para el almacenamiento en caché, utilice el evento de *solicitud del lector*.   
Por ejemplo, si una función cambia la URL para incluir una abreviatura de idioma en la ruta (por ejemplo, porque el usuario había elegido su idioma en una lista desplegable), utilice el evento de solicitud del espectador:  
+ **URL en la solicitud del lector**: https://example.com/en/index.html
+ **URL si la solicitud viene de una dirección IP en Alemania**: https://example.com/de/index.html
También puede utilizar el evento de solicitud del espectador si está almacenando en caché en función de cookies o encabezados de solicitudes.  
Si la función cambia cookies o encabezados, configure CloudFront para reenviar la parte aplicable de la solicitud al origen. Para obtener más información, consulte los temas siguientes:  
+ [Almacenamiento en caché de contenido en función de cookies](Cookies.md)
+ [Almacenamiento en caché de contenido en función de encabezados de solicitud](header-caching.md)

**La función afecta a la respuesta del origen**  
Para cambiar la solicitud para que afecte a la respuesta del origen, utilice el evento de *solicitud de origen*.   
Normalmente, la mayoría de los eventos de solicitud de lectores no se reenvían al origen. CloudFront responde a una solicitud con un objeto que ya está en la caché periférica. Si la función modifica la solicitud basándose en un evento de solicitud al origen, CloudFront almacena en caché la respuesta a la solicitud al origen modificada.

# Adición de desencadenadores a una función de Lambda@Edge
<a name="lambda-edge-add-triggers-console"></a>

Puede utilizar la consola de AWS Lambda o la consola de Amazon CloudFront para agregar un desencadenador a su función de Lambda@Edge.

**importante**  
Solo puede crear desencadenadores para las versiones numeradas de su función (no para las **\$1LATEST**).

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

**Agregación de desencadenadores para eventos de CloudFront a una función de Lambda@Edge**

1. Inicie sesión en la Consola de administración de AWS y abra la consola de AWS Lambda en [https://console.aws.amazon.com/lambda/](https://console.aws.amazon.com/lambda/).

1. En la lista Región de la parte superior de la página, elija **US East (N. Virginia) (EE. UU. Este (Norte de Virginia))**.

1. En la página **Functions (Funciones)**, elija el nombre de la función a la que desee añadir disparadores.

1. En la página **Información general de la función**, elija la pestaña **Versiones**.

1. Elija la versión a la que desea añadir disparadores.

   Una vez elegida una versión, el nombre del botón cambia a **Version: \$1LATEST (Versión: \$1LATEST)** o **Version:** *número de versión*.

1. Elija la pestaña **Desencadenadores**.

1. Elija **Add trigger (Añadir disparador)**.

1. En **Configuración del desencadenador**, elija **Seleccionar un origen**, introduzca **cloudfront** y, a continuación, elija **CloudFront**.
**nota**  
Si ya ha creado uno o varios desencadenadores, CloudFront es el servicio predeterminado.

1. Especifique los siguientes valores para indicar cuándo desea que se ejecute la función de Lambda.

   1. **Distribución**: elija la distribución a la que desee agregar el desencadenador.

   1. **Comportamiento de caché**: elija el comportamiento de la caché que especifica los objetos en los que desea ejecutar la función.
**nota**  
Si especifica `*` como comportamiento de la caché, la función de Lambda se implementa con el comportamiento predeterminado de la caché.

   1. **Evento de CloudFront**: elija el evento de CloudFront que provoca la ejecución de la función.

   1. **Incluir cuerpo**: marque esta casilla si desea obtener acceso al cuerpo de la solicitud en la función. 

   1. **Confirmación de la implementación en Lambda@Edge**: seleccione esta casilla para que AWS Lambda replique la función en las Regiones de AWS de forma global.

1. Elija **Agregar**.

   La función comienza a procesar solicitudes de los eventos de CloudFront especificados cuando se implementa la distribución de CloudFront actualizada. Para determinar si una distribución se ha implementado, elija **Distribuciones** en el panel de navegación. Cuando una distribución se implementa, el valor de la columna **Estado** de la distribución cambia de **Implementando** a la fecha y hora de la implementación.

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

**Agregación de desencadenadores para eventos de CloudFront a una función de Lambda@Edge**

1. Identifique el ARN de la función de Lambda para la que desee añadir disparadores:

   1. Inicie sesión en la Consola de administración de AWS y abra la consola de AWS Lambda en [https://console.aws.amazon.com/lambda/](https://console.aws.amazon.com/lambda/).

   1. En la lista de regiones de la parte superior de la página, elija **US East (N. Virginia) (EE. UU. Este (Norte de Virginia))**.

   1. En la lista de funciones, seleccione el nombre de la función a la que desee añadir disparadores.

   1. En la página **Información general de la función**, elija la pestaña **Versiones** y seleccione la versión numerada a la que desea agregar desencadenadores.

   1. Elija el botón **Copiar ARN** para copiar el ARN en el portapapeles. El ARN de la función de Lambda tiene un aspecto similar al siguiente:

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

      El número del final (en este ejemplo es **2**) es el número de versión de la función.

1. Abra la consola de CloudFront en [https://console.aws.amazon.com/cloudfront/v4/home](https://console.aws.amazon.com/cloudfront/v4/home).

1. En la lista de distribuciones, seleccione el ID de la distribución a la que desee añadir disparadores.

1. Elija la pestaña **Behaviors (Comportamientos)**.

1. Seleccione comportamiento de caché al que desee agregar desencadenadores y, a continuación, elija **Editar**.

1. En **Asociaciones de función**, en la lista **Tipo de función**, elija **Lambda@Edge** para cuando desee que se ejecute la función: para solicitudes de lector, respuestas de lector, solicitudes de origen o respuestas de origen. 

   Para obtener más información, consulte [Elección del evento para desencadenar la función](lambda-how-to-choose-event.md).

1. En el cuadro de texto **ARN/nombre de la función**, pegue el ARN de la función de Lambda que desea ejecutar cuando se produzca el evento elegido. Este es el valor que ha copiado de la consola de Lambda.

1. Seleccione **Incluir cuerpo** si desea obtener acceso al cuerpo de la solicitud en la función.

   Si simplemente desea reemplazar el cuerpo de la solicitud, no necesita seleccionar esta opción.

1. Para ejecutar la misma función con más tipos de eventos, repita los pasos 6 y 7.

1. Seleccione **Save changes (Guardar cambios)**.

1. Para agregar desencadenadores a más comportamientos de caché para esa distribución, repita los pasos del 5 al 10.

   La función comienza a procesar solicitudes de los eventos de CloudFront especificados cuando se implementa la distribución de CloudFront actualizada. Para determinar si una distribución se ha implementado, elija **Distribuciones** en el panel de navegación. Cuando una distribución se implementa, el valor de la columna **Estado** de la distribución cambia de **Implementando** a la hora y fecha de la implementación.

------

# Prueba y depuración de funciones de Lambda@Edge
<a name="lambda-edge-testing-debugging"></a>

Es importante probar el código de la función de Lambda@Edge de forma independiente, para asegurarse de que completa la tarea prevista, y realizar pruebas de integración, para asegurarse de que la funciona correctamente con CloudFront. 

Durante las pruebas de integración o una vez implementada su función, es posible que deba depurar errores de CloudFront, como errores HTTP 5xx. Los errores pueden ser una respuesta no válida que devuelve la función de Lambda, errores de ejecución cuando se desencadena la función o errores debido a limitación controlada de ejecución por parte del servicio de Lambda. En las secciones de este tema se explican estrategias para determinar qué tipo de error es la causa del problema y, a continuación, se ofrecen pasos que puede seguir para corregir el problema.

**nota**  
Al examinar las métricas o los archivos de registro de CloudWatch durante la solución de problemas, tenga en cuenta que se muestran o almacenan en la Región de AWS más cercana a la ubicación donde se ejecutó la función. Por lo tanto, si tiene un sitio web o una aplicación web con usuarios en el Reino Unido y tiene una función de Lambda asociada a su distribución, por ejemplo, debe cambiar la región para ver las métricas o los archivos de registro de CloudWatch para la Región de AWS de Londres. Para obtener más información, consulte [Determinación de la región de Lambda@Edge](#lambda-edge-testing-debugging-determine-region).

**Topics**
+ [

## Prueba de funciones de Lambda@Edge
](#lambda-edge-testing-debugging-test-function)
+ [

## Identificación de errores de funciones de Lambda@Edge en CloudFront
](#lambda-edge-identifying-function-errors)
+ [

## Solución de problemas de respuestas no válidas de funciones de Lambda@Edge (errores de validación)
](#lambda-edge-testing-debugging-troubleshooting-invalid-responses)
+ [

## Solución de problemas de errores de ejecución de funciones de Lambda@Edge
](#lambda-edge-testing-debugging-execution-errors)
+ [

## Determinación de la región de Lambda@Edge
](#lambda-edge-testing-debugging-determine-region)
+ [

## Determinación de si la cuenta inserta registros en CloudWatch
](#lambda-edge-testing-debugging-cloudwatch-logs-enabled)

## Prueba de funciones de Lambda@Edge
<a name="lambda-edge-testing-debugging-test-function"></a>

Hay dos pasos para probar la función de Lambda: pruebas independientes y pruebas de integración.

**Probar la funcionalidad independiente**  
Antes de agregar su función de Lambda a CloudFront, asegúrese de probar primero la funcionalidad mediante las capacidades de prueba de la consola de Lambda o mediante otros métodos. Para obtener más información sobre las pruebas en la consola de Lambda, consulte [Invocar una función de Lambda con la consola](https://docs.aws.amazon.com/lambda/latest/dg/getting-started.html#get-started-invoke-manually) en la *Guía para desarrolladores de AWS Lambda*.

**Probar la operación de la función en CloudFront**  
Es importante realizar pruebas de integración, donde la función está asociada a una distribución y se ejecuta en función de un evento de CloudFront. Asegúrese de que la función se activa para el evento adecuado y devuelve una respuesta que es válida y correcta para CloudFront. Por ejemplo, asegúrese de que la estructura del evento es correcta, que solo se incluyen encabezados válidos, etc.  
Mientras realiza la iteración en las pruebas de integración con la función en la consola de Lambda, consulte los pasos que se indican en el tutorial de Lambda@Edge a medida que modifica el código o cambia el desencadenador de CloudFront que llama a su función. Por ejemplo, asegúrese de que está trabajando en una versión numerada de su función, tal y como se describe en este paso del tutorial: [Paso 4: Agregue un desencadenador de CloudFront para ejecutar la función](lambda-edge-how-it-works-tutorial.md#lambda-edge-how-it-works-tutorial-add-trigger).   
A medida que realiza cambios y los implementa, tenga en cuenta que pasarán varios minutos hasta que su función actualizada y los desencadenadores de CloudFront se repliquen en todas las regiones. Esto suele hacerse en unos minutos, pero puede tardar hasta 15 minutos.  
Para comprobar si la replicación ha terminado, vaya a la consola de CloudFront y consulte la distribución.  

**Comprobación de la finalización de la implementación de la replicación**

1. Abra la consola de CloudFront en [https://console.aws.amazon.com/cloudfront/v4/home](https://console.aws.amazon.com/cloudfront/v4/home).

1. Elija el nombre de la distribución.

1. Compruebe que el estado de la distribución cambia de **En curso** a **Implementada**, lo que significa que la función se ha replicado. A continuación, siga los pasos de la sección siguiente para verificar el funcionamiento de la función.
Tenga en cuenta que las pruebas en la consola solo validan la lógica de la función, pero no aplican cuotas (antes denominadas límites) de servicio específicas de Lambda@Edge.

## Identificación de errores de funciones de Lambda@Edge en CloudFront
<a name="lambda-edge-identifying-function-errors"></a>

Una vez que haya verificado que la lógica de la función funciona correctamente, es posible que sigan apareciendo errores HTTP 5xx cuando la función se ejecuta en CloudFront. Los errores HTTP 5xx se pueden devolver por diversas razones, que puede incluir errores de las funciones de Lambda u otros problemas en CloudFront.
+ Si utiliza las funciones de Lambda@Edge, puede utilizar gráficos en la consola de CloudFront para ayudar a localizar lo que está provocando el error y, a continuación, trabajar para solucionarlo. Por ejemplo, puede ver si los errores HTTP 5xx están provocados por CloudFront o funciones de Lambda y, a continuación, en el caso de funciones específicas, puede ver los archivos de registro relacionados para investigar el problema.
+ Para solucionar los errores HTTP en general en CloudFront, consulte los pasos de solución de problemas en el siguiente tema: [Solución de problemas de códigos de estado de respuesta a errores en CloudFront](troubleshooting-response-errors.md).

### Causa de los errores de función de Lambda@Edge en CloudFront
<a name="lambda-edge-testing-debugging-function-errors"></a>

Existen varias razones por las que una función de Lambda puede provocar un error HTTP 5xx y los pasos de solución de problemas que lleve a cabo dependerán del tipo de error. Los errores pueden clasificarse como los siguientes:

**Un error de ejecución de la función de Lambda**  
Un error de ejecución se produce cuando CloudFront no obtiene ninguna respuesta de Lambda porque hay excepciones no controladas en la función o hay un error en el código. Por ejemplo, si el código incluye callback(Error).

**Se devuelve a CloudFront una respuesta de función de Lambda no válida**  
Después de ejecutar la función, CloudFront recibe una respuesta de Lambda. Se devuelve un error si la estructura de objetos de la respuesta no se ajusta a la [Estructura de eventos de Lambda@Edge](lambda-event-structure.md) o si la respuesta contiene encabezados no válidos u otros campos no válidos.

**La ejecución en CloudFront se limita debido a las cuotas de servicio de Lambda (anteriormente conocidas como límites)**  
El servicio de Lambda limita las ejecuciones en cada región y devuelve un error si se supera la cuota. Para obtener más información, consulte [Cuotas de Lambda@Edge](cloudfront-limits.md#limits-lambda-at-edge).

### Cómo determinar el tipo de error
<a name="lambda-edge-testing-debugging-failure-type"></a>

Para ayudarle a decidir dónde centrarse a medida que depura y trabaja para resolver errores que devuelve CloudFront, es útil identificar por qué CloudFront devuelve un error HTTP. Para empezar, puede usar los gráficos proporcionados en la sección **Monitoring (Monitoreo)** de la consola de CloudFront en la Consola de administración de AWS. Para empezar, puede usar los gráficos proporcionada en la sección **Monitoring (Monitoreo)** de la consola de CloudFront, consulte [Supervisión de métricas de CloudFront con Amazon CloudWatch](monitoring-using-cloudwatch.md).

Los siguientes gráficos pueden resultar especialmente útiles cuando desea realizar un seguimiento de los errores devueltos por orígenes o por una función de Lambda y para acotar el tipo de problema cuando se trata de un error de una función de Lambda.

**Gráfico de índices de error**  
Uno de los gráficos que puede ver en la pestaña **Overview (Descripción general)** de cada una de las distribuciones es un gráfico de **Error rates (Índices de error)**. Este gráfico muestra la tasa de errores como porcentaje de las solicitudes totales próximas a su distribución. El gráfico se muestra la tasa de error total, errores 4xx totales, errores 5xx totales y errores 5xx totales de funciones Lambda. En función del tipo de error y del volumen, puede seguir los pasos para investigar y solucionar la causa.  

![\[Gráfico de índices de error para una distribución de CloudFront\]](http://docs.aws.amazon.com/es_es/AmazonCloudFront/latest/DeveloperGuide/images/Distribution-error-rate-pct-full.png)

+ Si ve errores de Lambda, puede seguir investigando mirando los tipos de error específicos que devuelve la función. La pestaña **Lambda@Edge errors (Errores de Lambda@Edge)** incluye gráficos que clasifican los errores de función por tipo para ayudar a identificar el problema para una función específica.
+ Si ve errores de CloudFront, puede solucionar el problema y trabajar para corregir los errores de origen o cambiar la configuración de CloudFront. Para obtener más información, consulte [Solución de problemas de códigos de estado de respuesta a errores en CloudFront](troubleshooting-response-errors.md).

**Gráficos de respuestas de función no válida y errores de ejecución**  
La pestaña **Lambda@Edge errors (Errores de Lambda@Edge)** incluye gráficos que clasifican los errores de Lambda@Edge de una distribución específica, por tipo. Por ejemplo, un gráfico muestra todos los errores de ejecución por Región de AWS.  
Para facilitar la resolución de problemas, puede buscar problemas específicos abriendo y examinando los archivos de registro de funciones específicas por región.   

**Visualización de los archivos de registro de una función específica por región**

1. En la pestaña **Errores de Lambda@Edge**, en **Funciones de Lambda@Edge asociadas**, elija el nombre de la función y, a continuación, **Ver métricas**. 

1. A continuación, en la página con el nombre de la función, en la esquina superior derecha, seleccione **Ver registros de funciones** y, a continuación, elija una región. 

   Por ejemplo, si ve problemas en el gráfico **Errores** de la región Oeste de EE. UU. (Oregón), elija esa región en la lista desplegable. Se abrirá la consola de Amazon CloudWatch.

1. En la consola de CloudWatch de esa región, en **Flujos de registro**, seleccione un flujo de registro para ver los eventos de la función.
Además, lea las siguientes secciones de este capítulo para obtener más recomendaciones acerca de la solución de problemas y la corrección de errores.

**Gráfico de limitaciones**  
La pestaña **Lambda@Edge errors (Errores de Lambda@Edge)** incluye además un gráfico **Throttles (Limitaciones)**. A veces, el servicio de Lambda limita las invocaciones de la función por región, si se alcanza la cuota (antes denominada límite) de simultaneidad regional. Si aparece un error limit exceeded (límite superado), su función ha alcanzado una cuota que el servicio Lambda impone a las ejecuciones en una región. Para obtener más información, incluido cómo solicitar un aumento de la cuota, consulte [Cuotas de Lambda@Edge](cloudfront-limits.md#limits-lambda-at-edge).  

![\[Gráfico de limitación para la ejecución de la función Lambda@Edge.\]](http://docs.aws.amazon.com/es_es/AmazonCloudFront/latest/DeveloperGuide/images/Lambda-throttles-page.png)


Para ver un ejemplo sobre cómo utilizar esta información en la solución de problemas de errores HTTP, consulte [Cuatro pasos para depurar la entrega de contenido en AWS](https://aws.amazon.com/blogs/networking-and-content-delivery/four-steps-for-debugging-your-content-delivery-on-aws/).

## Solución de problemas de respuestas no válidas de funciones de Lambda@Edge (errores de validación)
<a name="lambda-edge-testing-debugging-troubleshooting-invalid-responses"></a>

Si identifica que el problema es un error de validación de Lambda, significa que su función de Lambda devuelve una respuesta no válida a CloudFront. Siga las indicaciones de esta sección para realizar los pasos que permiten revisar la función y asegurarse de que su respuesta se ajusta a los requisitos de CloudFront. 

CloudFront valida la respuesta de una función de Lambda de dos maneras:
+ **La respuesta de Lambda debe ajustarse a la estructura de objetos necesaria.** Estos son algunos ejemplos de estructura de objetos incorrecta: JSON que no se puede analizar, campos obligatorios que faltan y un objeto no válido en la respuesta. Para obtener más información, consulte [Estructura de eventos de Lambda@Edge](lambda-event-structure.md).
+ **La respuesta solo debe incluir valores de objetos válidos.** Se producirá un error si la respuesta incluye un objeto válido pero tiene valores que no se admiten. Por ejemplo: añadir o actualizar encabezados que están en la lista negra o son de solo lectura (consulte [Restricciones en funciones de borde](edge-functions-restrictions.md) en el tema Requisitos y restricciones en funciones Lambda), superar el tamaño máximo del cuerpo (consulte *Restricciones en el tamaño de la respuesta generada* en el tema [Errores](lambda-generating-http-responses.md#lambda-generating-http-responses-errors) de respuesta de Lambda@Edge) y caracteres o valores no válidos (consulte [Estructura de eventos de Lambda@Edge](lambda-event-structure.md)).

Cuando Lambda devuelve una respuesta no válida a CloudFront, los mensajes de error se escriben en los archivos de registro que CloudFront envía a CloudWatch en la región donde se ejecutó la función de Lambda. El comportamiento predeterminado es enviar los archivos de registro a CloudWatch cuando hay una respuesta no válida. Sin embargo, si asoció una función de Lambda con CloudFront antes de que se lanzara la funcionalidad, es posible que no esté habilitada para la función. Para obtener más información, consulte *Determinación de si su cuenta inserta registros en CloudWatch* más adelante en este tema.

CloudFront envía los archivos de registro a la región correspondiente donde se ejecutó la función, al grupo de registros asociado a la distribución. Los grupos de registros tienen el siguiente formato: `/aws/cloudfront/LambdaEdge/DistributionId`, donde *DistributionId* es el ID de la distribución. Para determinar la región donde se encuentran los archivos de registro de CloudWatch, consulte *Determinación de la región de Lambda@Edge* más adelante en este tema.

Si el error es reproducible, puede crear una nueva solicitud que produzca el error y, a continuación, buscar el ID de solicitud en una respuesta fallida de CloudFront (encabezado `X-Amz-Cf-Id`) para encontrar un error en los archivos de registro. La entrada del archivo de registro incluye información que puede ayudarle a identificar por qué se devuelve el error, y también muestra el ID de solicitud de Lambda correspondiente para que pueda analizar la causa raíz en el contexto de una única solicitud.

Si se trata de un error intermitente, puede utilizar los registros de acceso de CloudFront para encontrar el ID de una solicitud que ha generado un error y, a continuación, buscar en los registros de CloudWatch los mensajes de error correspondientes. Para obtener más información, consulte la sección anterior, *Determinación del tipo de error*.

## Solución de problemas de errores de ejecución de funciones de Lambda@Edge
<a name="lambda-edge-testing-debugging-execution-errors"></a>

Si se trata de un error de ejecución de Lambda, puede ser útil crear declaraciones de registros para las funciones de Lambda, escribir mensajes en los archivos de registro de CloudWatch que monitorean la ejecución de la función en CloudFront y determinar si funciona según lo previsto. A continuación, puede buscar esas instrucciones en los archivos de registro de CloudWatch para verificar que la función está funcionando.

**nota**  
Aunque no haya cambiado la función de Lambda@Edge, las actualizaciones del entorno de ejecución de la función de Lambda podrían afectar a esa función y devolver un error de ejecución. Para obtener más información sobre cómo probar y migrar a una versión posterior, consulte [Próximas actualizaciones del entorno de ejecución de AWS Lambda y AWS Lambda@Edge.](https://aws.amazon.com/blogs/compute/upcoming-updates-to-the-aws-lambda-execution-environment/)

## Determinación de la región de Lambda@Edge
<a name="lambda-edge-testing-debugging-determine-region"></a>

Para ver las regiones donde la función Lambda@Edge recibe tráfico, consulte las métricas de la función en la consola de CloudFront en la Consola de administración de AWS. Las métricas se muestran para cada región de AWS. En la misma página, puede elegir una región y ver los archivos de registro para dicha región a fin de poder investigar problemas. Debe revisar los archivos de registro de CloudWatch en la región correcta de AWS para ver los archivos de registro creados cuando CloudFront ejecutó su función de Lambda.

Para empezar, puede usar los gráficos proporcionada en la sección **Monitoring (Monitoreo)** de la consola de CloudFront, consulte [Supervisión de métricas de CloudFront con Amazon CloudWatch](monitoring-using-cloudwatch.md).

## Determinación de si la cuenta inserta registros en CloudWatch
<a name="lambda-edge-testing-debugging-cloudwatch-logs-enabled"></a>

De forma predeterminada, CloudFront habilita el registro de respuestas de la función de Lambda no válidas y envía los archivos de registro a CloudWatch mediante uno de los [Roles vinculados a servicios para Lambda@Edge](lambda-edge-permissions.md#using-service-linked-roles-lambda-edge). Si ha agregado funciones de Lambda@Edge a CloudFront antes de que se lanzara la característica de registro de respuestas de funciones de Lambda, el registro estará habilitado la próxima vez que actualice la configuración de Lambda@Edge, por ejemplo, agregando un desencadenador de CloudFront.

Haga lo siguiente para verificar que el envío de los archivos de registro a CloudWatch está habilitado para su cuenta:
+ **Compruebe si los registros aparecen en CloudWatch**: asegúrese de mirar en la región donde se ejecutó la función de Lambda@Edge. Para obtener más información, consulte [Determinación de la región de Lambda@Edge](#lambda-edge-testing-debugging-determine-region).
+ **Determine si el rol vinculado al servicio relacionado existe en la cuenta en IAM:** debe tener el rol de IAM `AWSServiceRoleForCloudFrontLogger` en la cuenta. Para obtener más información acerca de este rol, consulte [Roles vinculados a servicios para Lambda@Edge](lambda-edge-permissions.md#using-service-linked-roles-lambda-edge).

# Eliminación de réplicas y funciones de Lambda@Edge
<a name="lambda-edge-delete-replicas"></a>

Puede eliminar una función de Lambda@Edge solo cuando CloudFront haya eliminado las réplicas de la función. Las réplicas de una función de Lambda se eliminan automáticamente en las siguientes situaciones:
+ Una vez que elimine la última asociación de la función desde todas sus distribuciones de CloudFront. Si más de una distribución utiliza una función, las réplicas se eliminan solo después de que elimine la asociación de la función desde la última distribución.
+ Después de eliminar la última distribución a la que se asoció una función.

Las réplicas suelen eliminarse al cabo de unas horas. No puede eliminar manualmente las réplicas de las funciones Lambda@Edge. Esto contribuye a evitar una situación en la que se elimina una réplica que todavía está en uso, lo que daría lugar a un error.

**aviso**  
No cree aplicaciones que utilicen réplicas de funciones de Lambda@Edge fuera de CloudFront. Estas réplicas se eliminan cuando se eliminan sus asociaciones con distribuciones o cuando se eliminan las propias distribuciones. La réplica de la que depende una aplicación externa puede eliminarse sin ningún tipo de advertencia, lo que provocaría un error.

**Para eliminar una asociación de las funciones de Lambda@Edge de una distribución de CloudFront**

1. Inicie sesión en la Consola de administración de AWS y abra la consola de CloudFront en [https://console.aws.amazon.com/cloudfront/v4/home](https://console.aws.amazon.com/cloudfront/v4/home).

1. Elija el ID de la distribución con la asociación de las funciones de Lambda@Edge que desea eliminar.

1. Elija la pestaña **Comportamientos**.

1. Seleccione el comportamiento de caché que tiene la asociación de la función de Lambda@Edge que desea eliminar y, a continuación, elija **Editar**.

1. En **Asociaciones de funciones**, **Tipo de función**, elija **Sin asociación** para eliminar la asociación de función de Lambda@Edge.

1. Seleccione **Save changes (Guardar cambios)**.

Después de eliminar una asociación de la función Lambda@Edge de una distribución de CloudFront, si lo desea puede eliminar la función Lambda o la versión de la función de AWS Lambda. Espere unas horas después de eliminar la asociación de funciones para poder limpiar las réplicas de la función de Lambda @Edge. Después, puede eliminar la función mediante la consola de Lambda, la AWS CLI, la API de Lambda o un SDK de AWS.

También puede eliminar una *versión* específica de una función de Lambda si la versión no tiene ninguna distribución de CloudFront asociada. Cuando haya eliminado todas las asociaciones correspondientes a una versión de función de Lambda, espere unas horas. Después, puede eliminar la versión de la función.

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

En los temas siguientes se describen los objetos de evento de solicitud y respuesta que CloudFront pasa a una función de Lambda@Edge cuando se activa.

**Topics**
+ [

## Selección dinámica del origen
](#lambda-event-content-based-routing)
+ [

## Eventos de solicitud
](#lambda-event-structure-request)
+ [

## Eventos de respuesta
](#lambda-event-structure-response)

## Selección dinámica del origen
<a name="lambda-event-content-based-routing"></a>

Puede utilizar [el patrón de ruta de un comportamiento de la caché](DownloadDistValuesCacheBehavior.md#DownloadDistValuesPathPattern) para enviar las solicitudes a un origen, en función de la ruta y el nombre del objeto solicitado, como `images/*.jpg`. Lambda@Edge también le permite direccionar las solicitudes a un origen en función de otras características, como los valores de los encabezados de solicitudes. 

Esta selección dinámica del origen puede resultar útil en varios casos. Por ejemplo, puede distribuir solicitudes entre orígenes de diferentes zonas geográficas para facilitar el balanceo de carga global. También puede direccionar solicitudes selectivamente a varios orígenes, cada uno de ellos con un propósito distinto: control de bots, optimización SEO, autenticación, etc. Para obtener ejemplos de código que muestran cómo utilizar esta característica, consulte [Selección de origen dinámico basada en contenido: ejemplos](lambda-examples.md#lambda-examples-content-based-routing-examples).

En el evento de solicitud de origen de CloudFront, el objeto `origin` de la estructura de eventos contiene información sobre el origen al que se enviaría la solicitud, en función del patrón de ruta. Puede actualizar los valores del objeto `origin` para enviar una solicitud a otro origen. Al actualizar el objeto de `origin`, no es necesario definir el origen en la distribución. También puede reemplazar un objeto de origen de Amazon S3 por un objeto de origen personalizado y viceversa. Sin embargo, solo se puede especificar un único origen por solicitud, ya sea un origen personalizado o un origen de Amazon S3, pero no ambos.

## Eventos de solicitud
<a name="lambda-event-structure-request"></a>

En los temas siguientes se muestra la estructura del objeto que CloudFront pasa a una función de Lambda para los [eventos de solicitud de lector y de origen](lambda-cloudfront-trigger-events.md). Estos ejemplos muestran una solicitud `GET` sin cuerpo. Después de los ejemplos, se muestra una lista de todos los campos posibles en eventos de solicitud de lector y de origen.

**Topics**
+ [

### Ejemplo de solicitud de lector
](#example-viewer-request)
+ [

### Ejemplo de solicitud de origen
](#example-origin-request)
+ [

### Campos de eventos de solicitud
](#request-event-fields)

### Ejemplo de solicitud de lector
<a name="example-viewer-request"></a>

En el ejemplo siguiente se muestra un objeto de evento de solicitud de lector.

```
{
  "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": "/"
        }
      }
    }
  ]
}
```

### Ejemplo de solicitud de origen
<a name="example-origin-request"></a>

En el ejemplo siguiente se muestra un objeto de evento de solicitud de origen.

```
{
  "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 solicitud
<a name="request-event-fields"></a>

Los datos del objeto de evento de solicitud se incluyen en dos subobjetos: `config` (`Records.cf.config`) y `request` (`Records.cf.request`). En las listas siguientes se describen los campos de cada subobjeto.

#### Campos del objeto config
<a name="request-event-fields-config"></a>

En la siguiente lista se describen los campos del objeto `config` (`Records.cf.config`).

**`distributionDomainName` (solo lectura)**  
El nombre de dominio de la distribución asociada a la solicitud.

**`distributionID` (solo lectura)**  
El ID de la distribución asociada a la solicitud.

**`eventType` (solo lectura)**  
El tipo de desencadenador asociado a la solicitud: `viewer-request` u `origin-request`.

**`requestId` (solo lectura)**  
Una cadena cifrada que identifica de forma inequívoca una solicitud de lector a CloudFront. El valor `requestId` también aparece en los registros de acceso de CloudFront como `x-edge-request-id`. Para obtener más información, consulte [Registros de acceso (registros estándar)](AccessLogs.md) y [Campos de un archivo de registro](standard-logs-reference.md#BasicDistributionFileFormat).

#### Campos del objeto de solicitud
<a name="request-event-fields-request"></a>

En la siguiente lista se describen los campos del objeto `request` (`Records.cf.request`).

**`clientIp` (solo lectura)**  
La dirección IP del espectador que ha realizado la solicitud. Si el espectador utiliza un proxy HTTP o un equilibrador de carga para enviar la solicitud, el valor es la dirección IP del proxy o del equilibrador de carga.

**headers (lectura y escritura)**  
Los encabezados de la solicitud. Tenga en cuenta lo siguiente:  
+ Las claves del objeto `headers` son nombres de encabezado HTTP estándar en minúsculas. El uso de claves en minúsculas le proporciona acceso a los valores del encabezado sin diferenciar mayúsculas de minúsculas.
+ Cada objeto header (por ejemplo, `headers["accept"]` o `headers["host"]`) es una matriz de pares de clave-valor. Para un encabezado determinado, la matriz contiene un par de clave-valor para cada valor de la solicitud.
+ `key` contiene el nombre con distinción de mayúsculas y minúsculas del encabezado tal como aparecía en la solicitud HTTP; por ejemplo, `Host`, `User-Agent`, `X-Forwarded-For`, `Cookie`, etc.
+ `value` contiene el valor del encabezado tal como aparecía en la solicitud HTTP.
+ Cuando la función Lambda agrega o modifica encabezados de solicitud y no incluye el campo `key` del encabezado, Lambda@Edge inserta automáticamente un encabezado `key` usando el nombre de encabezado que proporcione. Independientemente de cómo haya formateado el nombre del encabezado, la clave de encabezado que se inserta automáticamente se formatea con mayúscula inicial para cada parte, separada por guiones (-).

  Por ejemplo, puede agregar un encabezado como el siguiente, sin la clave de encabezado `key`:

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

  En este ejemplo, Lambda @Edge inserta automáticamente `"key": "User-Agent"`.
Para obtener más información acerca de restricciones de uso de encabezados, consulte [Restricciones en funciones de borde](edge-functions-restrictions.md).

**`method` (solo lectura)**  
El método HTTP de la solicitud.

**`querystring` (lectura y escritura)**  
La cadena de consulta, si hay alguna, de la solicitud. Si la solicitud no incluye una cadena de consulta, el objeto del evento incluye igualmente `querystring` con un valor vacío. Para obtener más información acerca de cadenas de consulta, consulte [Almacenamiento en caché de contenido en función de parámetros de cadenas de consulta](QueryStringParameters.md).

**`uri` (lectura y escritura)**  
La ruta relativa del objeto solicitado. Si su función de Lambda modifica el valor `uri`, tenga en cuenta lo siguiente:  
+ El nuevo valor `uri` debe comenzar con una barra diagonal (/).
+ Si una función cambia el valor de `uri`, se cambia el objeto que el lector solicita.
+ Si una función cambia el valor de `uri`, *no* cambia el comportamiento de la caché de la solicitud ni del origen al que se envía la solicitud.

**`body` (lectura y escritura)**  
El cuerpo de la solicitud HTTP. La estructura `body` puede contener los siguientes campos:    
**`inputTruncated` (solo lectura)**  
Un indicador booleano que indica si Lambda@Edge truncó el cuerpo. Para obtener más información, consulte [Restricciones para el cuerpo de la solicitud con la opción Incluir cuerpo](lambda-at-edge-function-restrictions.md#lambda-at-edge-restrictions-request-body).  
**`action` (lectura y escritura)**  
La acción que va a realizar con el cuerpo. Las opciones de `action` son las siguientes:  
+ `read-only:` Esta es la opción predeterminada. Cuando se devuelve la respuesta de la función de Lambda, si `action` es solo lectura, Lambda@Edge omite los cambios realizados en `encoding` o `data`.
+ `replace:` Especifique este valor cuando desee reemplazar el cuerpo enviado al origen.  
**`encoding` (lectura y escritura)**  
La codificación del cuerpo. Cuando Lambda@Edge expone el cuerpo a la función de Lambda, primero lo convierte a base64-encoding. Si elige `replace` en `action` para reemplazar el cuerpo, puede elegir usar la codificación `base64` o `text` (el valor predeterminado). Si especifica `encoding` como `base64` pero el cuerpo no tiene una codificación base64 válida, CloudFront devuelve un error.  
**`data` (lectura y escritura)**  
El contenido del cuerpo de la solicitud. 

**`origin` (lectura y escritura) (solo eventos de origen)**  
El origen al que se envía la solicitud. La estructura del `origin` debe contener *exactamente un origen*, que puede ser un origen personalizado o un origen de Amazon S3.  
Según el tipo de origen que especifique (orígenes personalizados o de Amazon S3), debe especificar los siguientes campos en su solicitud:    
**`customHeaders` (lectura/escritura) (orígenes personalizados y de Amazon S3)**  
(Opcional) Si desea incluir encabezados personalizados con la solicitud, especifique un nombre de encabezado y un par de valores para cada uno de ellos. No puede agregar encabezados que no estén permitidos y un encabezado con el mismo nombre no puede estar presente en `Records.cf.request.headers`. Las [notas sobre encabezados de solicitud](#request-event-fields-request-headers) también se aplican a los encabezados personalizados. Para obtener más información, consulte [Encabezados personalizados que CloudFront no puede agregar a solicitudes de origen](add-origin-custom-headers.md#add-origin-custom-headers-denylist) y [Restricciones en funciones de borde](edge-functions-restrictions.md).  
**`domainName` (lectura/escritura) (orígenes personalizados y de Amazon S3)**  
El nombre de dominio del origen. El nombre de dominio no puede estar vacío.  
+ **Para orígenes personalizados**: especifique un nombre de dominio DNS, como `www.example.com`. El nombre de dominio no puede incluir dos puntos (:) y no puede ser una dirección IP. El nombre de dominio puede tener una longitud de hasta 253 caracteres.
+ **Para orígenes de Amazon S3**: especifique el nombre de dominio DNS del bucket de Amazon S3, como `amzn-s3-demo-bucket.s3.eu-west-1.amazonaws.com`. El nombre puede tener una longitud de hasta 128 caracteres y debe escribirse en letras minúsculas.  
**`path` (lectura/escritura) (orígenes personalizados y de Amazon S3)**  
La ruta de directorio del servidor donde la solicitud debería encontrar el contenido. La ruta debe comenzar con una barra diagonal (/), pero no debe terminar con una (por ejemplo, no debería terminar con `example-path/`). Solo para los orígenes personalizados: la ruta debe estar codificada como una URL y tener una longitud máxima de 255 caracteres.  
**`keepaliveTimeout` (lectura y escritura) (solo orígenes personalizados)**  
El periodo de tiempo, en segundos, que CloudFront debería intentar mantener la conexión con el origen después de recibir el último paquete de la respuesta. El valor debe ser un número del 1 al 120, ambos inclusive.  
**`port` (lectura y escritura) (solo orígenes personalizados)**  
El puerto al que CloudFront debe conectarse en el origen personalizado. Este valor debe ser 80, 443 o un número comprendido entre 1024 y 65535, ambos inclusive.  
**`protocol` (lectura y escritura) (solo orígenes personalizados)**  
El protocolo de conexión que CloudFront debe usar al conectarse a su origen. El valor puede ser `http` o `https`.  
**`readTimeout` (lectura/escritura) (orígenes personalizados y de Amazon S3)**  
El tiempo, en segundos, que CloudFront debe esperar una respuesta después de enviar una solicitud a su origen. También especifica cuánto tiempo debe esperar CloudFront después de recibir un paquete de una respuesta antes de recibir el siguiente paquete. El valor debe ser un número del 1 al 120, ambos inclusive.  
Si necesita una cuota mayor, consulte [Tiempo de espera de respuesta por origen](cloudfront-limits.md#limits-web-distributions).  
**`responseCompletionTimeout` (lectura/escritura) (orígenes personalizados y de Amazon S3)**  
El tiempo (en segundos) que una solicitud de CloudFront al origen puede permanecer abierta y esperar una respuesta. Si en ese tiempo no se recibe la respuesta completa del origen, CloudFront finaliza la conexión.  
El valor de `responseCompletionTimeout` debe ser igual o mayor que el valor para `readTimeout`. Si establece este valor en 0, elimina cualquier valor anterior que haya establecido y vuelve al valor predeterminado. También puede conseguirlo si elimina el campo `responseCompletionTimeout` de la solicitud del evento.   
**`sslProtocols` (lectura y escritura) (solo orígenes personalizados)**  
El protocolo SSL/TLS mínimo que CloudFront puede utilizar al establecer una conexión HTTPS con su origen. Los valores pueden ser alguno de los siguientes: `TLSv1.2`, `TLSv1.1`, `TLSv1` o `SSLv3`.  
**`authMethod` (lectura/escritura) (solo orígenes de Amazon S3)**  
Si utiliza una [identidad de acceso de origen (OAI)](private-content-restricting-access-to-s3.md#private-content-restricting-access-to-s3-oai), establezca este campo a `origin-access-identity`. Si no usa una OAI, establézcala a `none`. Si establece `authMethod` en `origin-access-identity`, se aplican varios requisitos:   
+ Debe especificar el elemento `region` (consulte el siguiente campo).
+ Debe utilizar la misma OAI cuando cambie la solicitud de un origen de Amazon S3 a otro.
+ No se puede utilizar una OAI cuando se cambia la solicitud de un origen personalizado a un origen de Amazon S3.
Este campo no admite el [control de acceso de origen (OAC)](private-content-restricting-access-to-s3.md).  
**`region` (lectura/escritura) (solo orígenes de Amazon S3)**  
La región de AWS de su bucket de Amazon S3. Esto solo es necesario cuando se establece `authMethod` en `origin-access-identity`.

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

En los temas siguientes se muestra la estructura del objeto que CloudFront pasa a una función Lambda para los [eventos de respuesta de lector y de origen](lambda-cloudfront-trigger-events.md). Después de los ejemplos, se muestra una lista de todos los campos posibles en eventos de respuesta de lector y de origen.

**Topics**
+ [

### Respuesta de origen de ejemplo
](#lambda-event-structure-response-origin)
+ [

### Respuesta de lector de ejemplo
](#lambda-event-structure-response-viewer)
+ [

### Campos del evento de respuesta
](#response-event-fields)

### Respuesta de origen de ejemplo
<a name="lambda-event-structure-response-origin"></a>

En el ejemplo siguiente se muestra un objeto de evento de respuesta de origen.

```
{
  "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"
        }
      }
    }
  ]
}
```

### Respuesta de lector de ejemplo
<a name="lambda-event-structure-response-viewer"></a>

En el ejemplo siguiente se muestra un objeto de evento de respuesta de lector.

```
{
  "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 del evento de respuesta
<a name="response-event-fields"></a>

Los datos del objeto de evento de respuesta se incluyen en tres subobjetos: `config` (`Records.cf.config`), `request` (`Records.cf.request`) y `response` (`Records.cf.response`). Para obtener más información acerca de los campos del objeto de solicitud, consulte [Campos del objeto de solicitud](#request-event-fields-request). En las listas siguientes se describen los campos de los subobjetos `config` y `response`.

#### Campos del objeto config
<a name="response-event-fields-config"></a>

En la siguiente lista se describen los campos del objeto `config` (`Records.cf.config`).

**`distributionDomainName` (solo lectura)**  
El nombre de dominio de la distribución asociada a la respuesta.

**`distributionID` (solo lectura)**  
El ID de la distribución asociada a la respuesta.

**`eventType` (solo lectura)**  
El tipo de desencadenador asociado a la respuesta: `origin-response` o `viewer-response`.

**`requestId` (solo lectura)**  
Una cadena cifrada que identifica de forma inequívoca la solicitud del lector a CloudFront a la que está asociada esta respuesta. El valor `requestId` también aparece en los registros de acceso de CloudFront como `x-edge-request-id`. Para obtener más información, consulte [Registros de acceso (registros estándar)](AccessLogs.md) y [Campos de un archivo de registro](standard-logs-reference.md#BasicDistributionFileFormat).

#### Campos del objeto de respuesta
<a name="response-event-fields-response"></a>

En la siguiente lista se describen los campos del objeto `response` (`Records.cf.response`). Para obtener información sobre el uso de una función de Lambda @Edge para generar una respuesta HTTP, consulte [Generación de respuestas HTTP en los desencadenadores de solicitud](lambda-generating-http-responses.md#lambda-generating-http-responses-in-requests).

**`headers` (lectura y escritura)**  
Los encabezados de la respuesta. Tenga en cuenta lo siguiente:  
+ Las claves del objeto `headers` son nombres de encabezado HTTP estándar en minúsculas. El uso de claves en minúsculas le proporciona acceso a los valores del encabezado sin diferenciar mayúsculas de minúsculas.
+ Cada objeto header (por ejemplo, `headers["content-type"]` o `headers["content-length"]`) es una matriz de pares de clave-valor. Para un encabezado determinado, la matriz contiene un par de clave-valor para cada valor de la respuesta.
+ `key` contiene el nombre con distinción de mayúsculas y minúsculas del encabezado tal como aparece en la respuesta HTTP; por ejemplo `Content-Type`, `Content-Length`, `Cookie`, etc.
+ `value` contiene el valor del encabezado tal como aparece en la respuesta HTTP.
+ Cuando la función Lambda agrega o modifica encabezados de respuesta y no incluye el campo `key` del encabezado, Lambda@Edge inserta automáticamente un encabezado `key` usando el nombre de encabezado que proporcione. Independientemente de cómo haya formateado el nombre del encabezado, la clave de encabezado que se inserta automáticamente se formatea con mayúscula inicial para cada parte, separada por guiones (-).

  Por ejemplo, puede agregar un encabezado como el siguiente, sin la clave de encabezado `key`:

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

  En este ejemplo, Lambda @Edge inserta automáticamente `"key": "Content-Type"`.
Para obtener más información acerca de restricciones de uso de encabezados, consulte [Restricciones en funciones de borde](edge-functions-restrictions.md).

**`status`**  
Código de estado HTTP de la respuesta.

**`statusDescription`**  
La descripción del estado HTTP de la respuesta.

# Trabajo con solicitudes y respuestas
<a name="lambda-generating-http-responses"></a>

Para utilizar las solicitudes y respuestas de Lambda@Edge, consulte los temas siguientes:

**Topics**
+ [

## Uso de funciones de Lambda@Edge con conmutación por error de origen
](#lambda-and-origin-failover)
+ [

## Generación de respuestas HTTP en los desencadenadores de solicitud
](#lambda-generating-http-responses-in-requests)
+ [

## Actualización de respuestas HTTP en desencadenadores de respuesta de origen
](#lambda-updating-http-responses)
+ [

## Acceso al cuerpo de la solicitud con la opción Incluir cuerpo
](#lambda-include-body-access)

## Uso de funciones de Lambda@Edge con conmutación por error de origen
<a name="lambda-and-origin-failover"></a>

Puede utilizar las funciones de Lambda@Edge con distribuciones de CloudFront que ha configurado con grupos de origen, por ejemplo, para conmutación por error de origen que configure para ayudar a garantizar una alta disponibilidad. Para utilizar una función de Lambda con un grupo de origen, especifique la función en una solicitud de origen o un desencadenador de respuesta de origen para un grupo de origen al crear el comportamiento de la caché.

Para obtener más información, consulte los siguientes temas:
+ **Creación de grupos de origen:** [Creación de un grupo de origen](high_availability_origin_failover.md#concept_origin_groups.creating)
+ **Cómo utilizar la conmutación por error de origen con Lambda@Edge:** [Utilizar la conmutación por error de origen con funciones de Lambda@Edge](high_availability_origin_failover.md#concept_origin_groups.lambda)

## Generación de respuestas HTTP en los desencadenadores de solicitud
<a name="lambda-generating-http-responses-in-requests"></a>

Cuando CloudFront recibe una solicitud, es posible utilizar una función de Lambda para generar una respuesta HTTP que CloudFront devuelve directamente al lector sin enviarla al origen. La generación de respuestas HTTP reduce la carga en el origen, y normalmente también reduce la latencia para el espectador.

Entre las situaciones más comunes para generar respuestas HTTP se incluyen las siguientes:
+ Devolver una pequeña página web al lector
+ Devolver un código de estado HTTP 301 o 302 para redirigir al usuario a otra página web
+ Devolución de un código de estado HTTP 401 al espectador si el usuario no se ha autenticado

Una función de Lambda@Edge puede generar una respuesta HTTP cuando ocurren los siguientes eventos de CloudFront:

**Eventos de solicitud del espectador**  
Cuando un evento de solicitud del lector activa una función, CloudFront devuelve la respuesta al lector y no la almacena en caché.

**Eventos de solicitud al origen**  
Cuando un evento de solicitud al origen activa una función, CloudFront busca en la caché de borde una respuesta generada previamente por la función.   
+ Si la respuesta está en la caché, la función no se ejecuta y CloudFront devuelve al lector la respuesta almacenada en la caché.
+ Si la respuesta no está en la caché, la función se ejecuta, CloudFront devuelve la respuesta al lector y también la almacena en la caché.

Para ver algunos ejemplos de código para generar respuestas HTTP, consulte [Funciones de ejemplo de Lambda@Edge](lambda-examples.md). También puede sustituir las respuestas HTTP en disparadores de respuesta. Para obtener más información, consulte [Actualización de respuestas HTTP en desencadenadores de respuesta de origen](#lambda-updating-http-responses).

### Modelo de programación
<a name="lambda-generating-http-responses-programming-model"></a>

En esta sección se describe el modelo de programación a seguir para usar Lambda@Edge con el fin de generar respuestas HTTP.

**Topics**
+ [

#### Objeto de respuesta
](#lambda-generating-http-responses-object)
+ [

#### Errores
](#lambda-generating-http-responses-errors)
+ [

#### Campos obligatorios
](#lambda-generating-http-responses-required-fields)

#### Objeto de respuesta
<a name="lambda-generating-http-responses-object"></a>

La respuesta que devuelva como parámetro `result` del método `callback` debe tener la siguiente estructura (tenga en cuenta que solo es obligatorio el campo `status`).

```
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'
};
```

El objeto de respuesta puede incluir los siguientes valores:

**`body`**  
El cuerpo, si lo hay, que desea que CloudFront devuelva en la respuesta generada.

**`bodyEncoding`**  
La codificación del valor especificado en `body`. Las únicas codificaciones válidas son `text` y `base64`. Si incluye `body` en el objeto `response` pero omite `bodyEncoding`, CloudFront trata el cuerpo como texto.  
Si especifica `bodyEncoding` como `base64` pero el cuerpo no tiene una codificación base64 válida, CloudFront devuelve un error.

**`headers`**  
Los encabezados que desea que devuelva CloudFront en la respuesta generada. Tenga en cuenta lo siguiente:  
+ Las claves del objeto `headers` son nombres de encabezado HTTP estándar en minúsculas. El uso de claves en minúsculas le proporciona acceso a los valores del encabezado sin diferenciar mayúsculas de minúsculas.
+ Cada encabezado (por ejemplo, `headers["accept"]` or `headers["host"]`) es una matriz de pares clave-valor. Para un encabezado determinado, la matriz contiene un par de clave-valor para cada valor de la respuesta generada.
+ `key` (opcional) es el nombre del encabezado que diferencia mayúsculas de minúsculas tal como aparece en una solicitud HTTP; por ejemplo, `accept` u `host`.
+ Especifique `value` como un valor de encabezado.
+ Si no incluye la parte de clave de encabezado del par de clave-valor, Lambda@Edge insertará automáticamente una clave de encabezado utilizando el nombre de encabezado que proporcione. Independientemente de cómo haya formateado el nombre del encabezado, la clave de encabezado que se inserta automáticamente se formatea con mayúscula inicial para cada parte, separada por guiones (-).

  Por ejemplo, puede añadir un encabezado como el siguiente, sin una clave de encabezado: `'content-type': [{ value: 'text/html;charset=UTF-8' }]`

  En este ejemplo, Lambda@Edge crea la siguiente clave de encabezado: `Content-Type`.
Para obtener más información acerca de restricciones de uso de encabezados, consulte [Restricciones en funciones de borde](edge-functions-restrictions.md).

**`status`**  
El código de estado HTTP. Proporcione el código de estado como una cadena. CloudFront utiliza el código de estado proporcionado para lo siguiente:  
+ Devolverlo en la respuesta
+ Almacenarlo en la caché de borde de CloudFront cuando la respuesta la generó una función activada por un evento de solicitud al origen
+ Inicie sesión en CloudFront [Registros de acceso (registros estándar)](AccessLogs.md)
Si el valor `status` no está comprendido entre 200 y 599, CloudFront devuelve un error al lector.

**`statusDescription`**  
La descripción que desea que CloudFront devuelva en la respuesta, y que acompañará al código de estado HTTP. No es obligatorio utilizar descripciones estándar, como `OK` en un código de estado HTTP 200.

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

Los siguientes son posibles errores de respuestas HTTP generadas.

**La respuesta contiene un cuerpo y especifica un código de estado 204 (Sin contenido**  
Cuando una solicitud del lector activa una función, CloudFront devuelve un código de estado HTTP 502 (Gateway incorrecta) al lector cuando se cumplen las dos condiciones siguientes:  
+ El valor de `status` es 204 (Sin contenido)
+ La respuesta incluye un valor para `body`
Esto se debe a que Lambda@Edge impone la restricción opcional de RFC 2616 que establece que una respuesta `HTTP 204` no necesita contener cuerpo de mensaje.

**Restricciones en el tamaño de la respuesta generada**  
El tamaño máximo de una respuesta generada por una función de Lambda depende del evento que desencadenó la función:  
+ **Eventos de solicitud del lector**: 40 KB
+ **Eventos de solicitud al origen**: 1 MB
Si la respuesta supera el tamaño permitido, CloudFront devuelve un código de estado HTTP 502 (Gateway incorrecta) al lector.

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

El campo `status` es obligatorio. 

Todos los demás campos son opcionales.

## Actualización de respuestas HTTP en desencadenadores de respuesta de origen
<a name="lambda-updating-http-responses"></a>

Cuando CloudFront recibe una respuesta HTTP desde el servidor de origen, si existe un desencadenador de respuesta del origen asociado al comportamiento de la caché, es posible modificar la respuesta HTTP para anular lo que ha devuelto el origen.

Entre las situaciones más comunes para actualizar respuestas HTTP se incluyen las siguientes:
+ Cambiar el estado para establecer un código de estado HTTP 200 y crear un cuerpo con contenido estático para devolverlo al espectador cuando un origen devuelva un código de estado de error (4xx o 5xx). Para ver código de muestra, consulte [Ejemplo: Uso de un desencadenador de respuesta de origen para actualizar el código de estado de error a 200](lambda-examples.md#lambda-examples-custom-error-static-body).
+ Cambiar el estado para establecer un código de estado HTTP 301 o 302, con objeto de redirigir al usuario a otro sitio web cuando un origen devuelve un código de estado de error (4xx o 5xx). Para ver código de muestra, consulte [Ejemplo: Uso de un desencadenador de respuesta de origen para actualizar el código de estado de error a 302](lambda-examples.md#lambda-examples-custom-error-new-site).

**nota**  
La función debe devolver un valor de estado entre `200` y `599` (incluidos); de lo contrario, CloudFront devuelve un error al espectador.

También puede sustituir las respuestas HTTP en eventos de solicitud al origen y del espectador. Para obtener más información, consulte [Generación de respuestas HTTP en los desencadenadores de solicitud](#lambda-generating-http-responses-in-requests).

Cuando trabaja con la respuesta HTTP, Lambda@Edge no expone el cuerpo que devuelve el servidor de origen al desencadenador de respuesta del origen. Puede generar un cuerpo con contenido estático estableciéndolo en el valor deseado, o eliminar el cuerpo dentro de la función estableciendo un valor vacío. Si no actualiza el campo de cuerpo de la función, se devolverá al espectador el cuerpo original devuelto por el servidor de origen.

## Acceso al cuerpo de la solicitud con la opción Incluir cuerpo
<a name="lambda-include-body-access"></a>

A partir de ahora, puede hacer que Lambda@Edge exponga el cuerpo de una solicitud en los métodos HTTP que permiten la escritura (POST, PUT, DELETE, etc.) para que puede tener acceso a él en la función de Lambda. Puede elegir acceso de solo lectura o puede especificar que sustituirá el cuerpo.

Para habilitar esta opción, elija **Incluir cuerpo** al crear un desencadenador de CloudFront para la función que corresponde a un evento de solicitud al origen o del lector. Para obtener más información, consulte [Adición de desencadenadores para una función de Lambda@Edge](lambda-edge-add-triggers.md); para obtener información acerca de cómo utilizar **Incluir cuerpo** con su función, consulte [Estructura de eventos de Lambda@Edge](lambda-event-structure.md).

Entre los escenarios en los que es conveniente utilizar esta característica se incluyen los siguientes:
+ Procesamiento de formularios web, como formularios de tipo "póngase en contacto con nosotros", sin devolver los datos de entrada de los clientes a los servidores de origen.
+ Recopilación de datos de balizas web enviados por los navegadores de los espectadores y que se procesan en el borde.

Para ver código de muestra, consulte [Funciones de ejemplo de Lambda@Edge](lambda-examples.md).

**nota**  
Si el cuerpo de la solicitud es grande, Lambda@Edge lo trunca. Para obtener información detallada sobre el tamaño máximo y el truncamiento, consulte [Restricciones para el cuerpo de la solicitud con la opción Incluir cuerpo](lambda-at-edge-function-restrictions.md#lambda-at-edge-restrictions-request-body).

# Funciones de ejemplo de Lambda@Edge
<a name="lambda-examples"></a>

Consulte los ejemplos siguientes para usar funciones de Lambda con Amazon CloudFront.

**nota**  
Si elige el tiempo de ejecución Node.js 18 o una versión posterior para la función Lambda@Edge, se creará automáticamente un archivo `index.mjs`. Para usar los siguientes ejemplos de código, cambie el nombre del archivo `index.mjs` a `index.js`.

**Topics**
+ [

## Ejemplos generales
](#lambda-examples-general-examples)
+ [

## Generación de respuestas: ejemplos
](#lambda-examples-generated-response-examples)
+ [

## Cadenas de consulta: ejemplos
](#lambda-examples-query-string-examples)
+ [

## Personalización de contenido por encabezados de tipo de dispositivo o país: ejemplos
](#lambda-examples-redirecting-examples)
+ [

## Selección de origen dinámico basada en contenido: ejemplos
](#lambda-examples-content-based-routing-examples)
+ [

## Actualización de estados de error: ejemplos
](#lambda-examples-update-error-status-examples)
+ [

## Acceso al cuerpo de la solicitud: ejemplos
](#lambda-examples-access-request-body-examples)

## Ejemplos generales
<a name="lambda-examples-general-examples"></a>

Los ejemplos siguientes muestran formas habituales de usar Lambda@Edge en CloudFront.

**Topics**
+ [

### Ejemplo: prueba A/B
](#lambda-examples-a-b-testing)
+ [

### Ejemplo: Sobrescritura de un encabezado de respuesta
](#lambda-examples-overriding-response-header)

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

Puede utilizar el siguiente ejemplo para probar dos versiones diferentes de una imagen sin crear redirecciones ni cambiar la dirección URL. En este ejemplo se leen las cookies de la solicitud del lector y se modifica la URL de la solicitud en consecuencia. Si el espectador no envía una cookie con uno de los valores esperados, el ejemplo asigna aleatoriamente al espectador una de las URL.

------
#### [ 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
```

------

### Ejemplo: Sobrescritura de un encabezado de respuesta
<a name="lambda-examples-overriding-response-header"></a>

En el ejemplo siguiente, se muestra cómo cambiar el valor de un encabezado de respuesta según el valor de otro encabezado.

------
#### [ 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
```

------

## Generación de respuestas: ejemplos
<a name="lambda-examples-generated-response-examples"></a>

En los ejemplos siguientes se muestra cómo puede usar Lambda@Edge para generar respuestas.

**Topics**
+ [

### Ejemplo: Envío de contenido estático (respuesta generada)
](#lambda-examples-static-web-server)
+ [

### Ejemplo: Generación de un redireccionamiento HTTP (respuesta generada)
](#lambda-examples-http-redirect)

### Ejemplo: Envío de contenido estático (respuesta generada)
<a name="lambda-examples-static-web-server"></a>

En el siguiente ejemplo se muestra cómo utilizar una función de Lambda para enviar contenido de sitio web estático, lo que reduce la carga en el servidor de origen y la latencia total. 

**nota**  
Puede generar respuestas HTTP para los eventos de solicitud del espectador y al origen. Para obtener más información, consulte [Generación de respuestas HTTP en los desencadenadores de solicitud](lambda-generating-http-responses.md#lambda-generating-http-responses-in-requests).  
También puede sustituir o quitar el cuerpo de la respuesta HTTP en eventos de respuesta de origen. Para obtener más información, consulte [Actualización de respuestas HTTP en desencadenadores de respuesta de origen](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
```

------

### Ejemplo: Generación de un redireccionamiento HTTP (respuesta generada)
<a name="lambda-examples-http-redirect"></a>

En el siguiente ejemplo se muestra cómo generar una redirección HTTP.

**nota**  
Puede generar respuestas HTTP para los eventos de solicitud del espectador y al origen. Para obtener más información, consulte [Generación de respuestas HTTP en los desencadenadores de solicitud](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
```

------

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

En los ejemplos siguientes se muestran formas de usar Lambda@Edge con cadenas de consulta.

**Topics**
+ [

### Ejemplo: Adición de un encabezado en función de un parámetro de la cadena de consulta
](#lambda-examples-header-based-on-query-string)
+ [

### Ejemplo: Normalización de parámetros de cadenas de consulta para mejorar la tasa de aciertos de caché
](#lambda-examples-normalize-query-string-parameters)
+ [

### Ejemplo: Redireccionamiento de los usuarios no autenticados a una página de inicio de sesión
](#lambda-examples-redirect-to-signin-page)

### Ejemplo: Adición de un encabezado en función de un parámetro de la cadena de consulta
<a name="lambda-examples-header-based-on-query-string"></a>

El siguiente ejemplo muestra cómo obtener el par clave-valor de un parámetro de la cadena de consulta y, a continuación, añadir un encabezado en función de dichos 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
```

------

### Ejemplo: Normalización de parámetros de cadenas de consulta para mejorar la tasa de aciertos de caché
<a name="lambda-examples-normalize-query-string-parameters"></a>

El siguiente ejemplo muestra cómo mejorar la tasa de acceso a la caché haciendo los siguientes cambios en las cadenas de consulta antes de que CloudFront reenvíe las solicitudes a su origen:
+ Alfabetizar los pares de clave-valor por el nombre del parámetro.
+ Cambiar a minúsculas el modelo de mayúsculas y minúsculas de los pares de clave-valor.

Para obtener más información, consulte [Almacenamiento en caché de contenido en función de parámetros de cadenas 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
```

------

### Ejemplo: Redireccionamiento de los usuarios no autenticados a una página de inicio de sesión
<a name="lambda-examples-redirect-to-signin-page"></a>

El siguiente ejemplo muestra cómo redirigir a los usuarios una página de inicio de sesión si no ha introducido sus credenciales.

------
#### [ 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
```

------

## Personalización de contenido por encabezados de tipo de dispositivo o país: ejemplos
<a name="lambda-examples-redirecting-examples"></a>

En los ejemplos siguientes se muestra cómo puede usar Lambda@Edge para personalizar el comportamiento en función de la ubicación o el tipo de dispositivo que usa el lector.

**Topics**
+ [

### Ejemplo: Redireccionamiento de solicitudes de espectadores a una URL específica de un país
](#lambda-examples-redirect-based-on-country)
+ [

### Ejemplo: Envío de distintas versiones de un objeto en función del dispositivo
](#lambda-examples-vary-on-device-type)

### Ejemplo: Redireccionamiento de solicitudes de espectadores a una URL específica de un país
<a name="lambda-examples-redirect-based-on-country"></a>

El siguiente ejemplo muestra cómo generar una respuesta de redireccionamiento HTTP con una URL específica del país y devolver la respuesta al espectador. Esto resulta útil cuando se quiere proporcionar respuestas específicas del país. Por ejemplo:
+ Si tiene subdominios específicos de un país, como us.ejemplo.com y tw.ejemplo.com, puede generar una respuesta de redireccionamiento cuando un espectador solicite ejemplo.com.
+ Si está haciendo streaming de video, pero no tiene derechos para transmitir el contenido en un país determinado, puede redirigir a los usuarios de dicho país a una página en la que se explica por qué no pueden ver el video. 

Tenga en cuenta lo siguiente:
+ Debe configurar la distribución para almacenar en la caché en función del encabezado `CloudFront-Viewer-Country`. Para obtener más información, consulte [Caché en función de encabezados de solicitud seleccionados](DownloadDistValuesCacheBehavior.md#DownloadDistValuesForwardHeaders).
+ CloudFront agrega el encabezado `CloudFront-Viewer-Country` después del evento de solicitud del lector. Para utilizar este ejemplo, debe crear un activador para el evento de solicitud al origen.

------
#### [ 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
```

------

### Ejemplo: Envío de distintas versiones de un objeto en función del dispositivo
<a name="lambda-examples-vary-on-device-type"></a>

El siguiente ejemplo muestra cómo ofrecer distintas versiones de un objeto en función del tipo de dispositivo que el usuario está utilizando; por ejemplo, un dispositivo móvil o una tablet. Tenga en cuenta lo siguiente:
+ Debe configurar la distribución para almacenar en la caché en función de los encabezados `CloudFront-Is-*-Viewer`. Para obtener más información, consulte [Caché en función de encabezados de solicitud seleccionados](DownloadDistValuesCacheBehavior.md#DownloadDistValuesForwardHeaders).
+ CloudFront agrega los encabezados `CloudFront-Is-*-Viewer` después del evento de solicitud del lector. Para utilizar este ejemplo, debe crear un activador para el evento de solicitud al origen.

------
#### [ 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
```

------

## Selección de origen dinámico basada en contenido: ejemplos
<a name="lambda-examples-content-based-routing-examples"></a>

En los ejemplos siguientes se muestra cómo puede usar Lambda@Edge para el direccionamiento a diferentes orígenes en función de la información de la solicitud.

**Topics**
+ [

### Ejemplo: Uso de un desencadenador de solicitud de origen para cambiar desde un origen personalizado a un origen de Amazon S3
](#lambda-examples-content-based-S3-origin-based-on-query)
+ [

### Ejemplo: Uso de un desencadenador de solicitud de origen para cambiar la región de origen de Amazon S3
](#lambda-examples-content-based-S3-origin-request-trigger)
+ [

### Ejemplo: Uso de un desencadenador de solicitud de origen para cambiar desde un origen de Amazon S3 a un origen personalizado
](#lambda-examples-content-based-custom-origin-request-trigger)
+ [

### Ejemplo: Uso de un desencadenador de solicitud al origen para transferir gradualmente el tráfico desde un bucket de Amazon S3 a otro
](#lambda-examples-content-based-gradual-traffic-transfer)
+ [

### Ejemplo: Uso de un desencadenador de solicitud de origen para cambiar el nombre del dominio de origen en función del encabezado de país
](#lambda-examples-content-based-geo-header)

### Ejemplo: Uso de un desencadenador de solicitud de origen para cambiar desde un origen personalizado a un origen de Amazon S3
<a name="lambda-examples-content-based-S3-origin-based-on-query"></a>

Esta función demuestra cómo utilizar un desencadenador de solicitud al origen para cambiar desde un origen personalizado a un origen de Amazon S3 desde el que recuperar el contenido, en función de las propiedades de la solicitud.

------
#### [ 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
```

------

### Ejemplo: Uso de un desencadenador de solicitud de origen para cambiar la región de origen de Amazon S3
<a name="lambda-examples-content-based-S3-origin-request-trigger"></a>

Esta función demuestra cómo utilizar un desencadenador de solicitud al origen para cambiar el origen de Amazon S3 desde el que se recupera el contenido, en función de las propiedades de la solicitud.

En este ejemplo, utilizamos el valor del encabezado `CloudFront-Viewer-Country` para actualizar el nombre de dominio del bucket de S3 por un bucket de una región que está más cerca del lector. Esto puede resultar útil de varias maneras:
+ Reduce las latencias cuando la región especificada está más cerca del país del lector.
+ Proporciona soberanía de los datos, al asegurarse de que los datos se distribuyen desde un origen que está en el país del que provino la solicitud.

Para utilizar este ejemplo, debe hacer lo siguiente:
+ Configure la distribución para almacenar en la caché en función del encabezado `CloudFront-Viewer-Country`. Para obtener más información, consulte [Caché en función de encabezados de solicitud seleccionados](DownloadDistValuesCacheBehavior.md#DownloadDistValuesForwardHeaders). 
+ Crear un disparador para esta función en el evento de solicitud al origen. CloudFront agrega el encabezado `CloudFront-Viewer-Country` después del evento de solicitud del lector; por lo tanto, para utilizar este ejemplo, debe asegurarse de que la función ejecuta una solicitud de origen.

**nota**  
El siguiente código de ejemplo usa la misma identidad de acceso de origen (OAI) para todos los buckets de S3 que usa para el origen. Para obtener más información, consulte [Identidad de acceso de origen](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
```

------

### Ejemplo: Uso de un desencadenador de solicitud de origen para cambiar desde un origen de Amazon S3 a un origen personalizado
<a name="lambda-examples-content-based-custom-origin-request-trigger"></a>

Esta función demuestra cómo utilizar un disparador de solicitud al origen para cambiar el origen personalizado desde el que se recupera el contenido, en función de las propiedades de la solicitud.

------
#### [ 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
```

------

### Ejemplo: Uso de un desencadenador de solicitud al origen para transferir gradualmente el tráfico desde un bucket de Amazon S3 a otro
<a name="lambda-examples-content-based-gradual-traffic-transfer"></a>

Esta función demuestra cómo transferir gradualmente el tráfico desde un bucket de Amazon S3 a otro de forma 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
```

------

### Ejemplo: Uso de un desencadenador de solicitud de origen para cambiar el nombre del dominio de origen en función del encabezado de país
<a name="lambda-examples-content-based-geo-header"></a>

Esta función demuestra cómo cambiar el nombre del dominio de origen en función del encabezado `CloudFront-Viewer-Country`, de forma que el contenido se distribuya desde un origen más cercano al país del lector.

La implementación de esta funcionalidad para su distribución puede tener ventajas como las siguientes:
+ Reducir las latencias cuando la región especificada está más cerca del país del lector
+ Proporcionar soberanía de los datos, al asegurarse de que los datos se distribuyen desde un origen que está en el país del que provino la solicitud

Tenga en cuenta que para habilitar esta funcionalidad, debe configurar su distribución para almacenar en la caché en función del encabezado `CloudFront-Viewer-Country`. Para obtener más información, consulte [Caché en función de encabezados de solicitud seleccionados](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
```

------

## Actualización de estados de error: ejemplos
<a name="lambda-examples-update-error-status-examples"></a>

En los ejemplos siguientes se proporciona orientación acerca de cómo puede usar Lambda@Edge para cambiar el estado de error que se devuelve a los usuarios.

**Topics**
+ [

### Ejemplo: Uso de un desencadenador de respuesta de origen para actualizar el código de estado de error a 200
](#lambda-examples-custom-error-static-body)
+ [

### Ejemplo: Uso de un desencadenador de respuesta de origen para actualizar el código de estado de error a 302
](#lambda-examples-custom-error-new-site)

### Ejemplo: Uso de un desencadenador de respuesta de origen para actualizar el código de estado de error a 200
<a name="lambda-examples-custom-error-static-body"></a>

Esta función demuestra cómo actualizar el estado de la respuesta a 200 y generar un cuerpo con contenido estático para devolverlo al espectador en la siguiente situación:
+ La función se desencadena en una respuesta del origen.
+ El estado de la respuesta del servidor de origen es un código de estado de error (4xx o 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
```

------

### Ejemplo: Uso de un desencadenador de respuesta de origen para actualizar el código de estado de error a 302
<a name="lambda-examples-custom-error-new-site"></a>

Esta función demuestra cómo actualizar el código de estado HTTP a 302 para la redirección a otra ruta (comportamiento de la caché) en la que se ha configurado un origen diferente. Tenga en cuenta lo siguiente:
+ La función se desencadena en una respuesta del origen.
+ El estado de la respuesta del servidor de origen es un código de estado de error (4xx o 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
```

------

## Acceso al cuerpo de la solicitud: ejemplos
<a name="lambda-examples-access-request-body-examples"></a>

En los ejemplos siguientes se muestra cómo puede usar Lambda@Edge para trabajar con las solicitudes POST.

**nota**  
Para utilizar estos ejemplos, debe habilitar la opción *incluir cuerpo* en la asociación de funciones Lambda de la distribución. No está habilitada de forma predeterminada.  
Para habilitar esta configuración en la consola de CloudFront, seleccione la casilla de verificación **Incluir cuerpo** en la **Asociación de funciones Lambda**.
Para habilitar esta configuración en la API de CloudFront o con CloudFormation, establezca el campo `IncludeBody` en `true` en `LambdaFunctionAssociation`.

**Topics**
+ [

### Ejemplo: Uso de un desencadenador de solicitud para leer un formulario HTML
](#lambda-examples-access-request-body-examples-read)
+ [

### Ejemplo: Uso de un desencadenador de solicitud para modificar un formulario HTML
](#lambda-examples-access-request-body-examples-replace)

### Ejemplo: Uso de un desencadenador de solicitud para leer un formulario HTML
<a name="lambda-examples-access-request-body-examples-read"></a>

Esta función ilustra cómo puede procesar el cuerpo de una solicitud POST generada por un formulario HTML (formulario web), como por ejemplo un formulario tipo "póngase en contacto con nosotros". Por ejemplo, es posible que tenga un formulario HTML como el siguiente:

```
<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>
```

Para la función de ejemplo que se indica a continuación, la función se debe desencadenar en una solicitud al origen o del lector de 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
```

------

### Ejemplo: Uso de un desencadenador de solicitud para modificar un formulario HTML
<a name="lambda-examples-access-request-body-examples-replace"></a>

Esta función ilustra cómo puede modificar el cuerpo de una solicitud POST generada por un formulario HTML (formulario web). La función se activa en una solicitud al origen o del lector de 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)
```

------

# Restricciones en funciones de borde
<a name="edge-functions-restrictions"></a>

En los temas siguientes se describen las restricciones que se aplican a CloudFront Functions y Lambda @Edge. Algunas restricciones se aplican a todas las funciones de borde y otras solo se aplican a CloudFront Functions o Lambda @Edge.

En este tema se proporciona información detallada sobre las limitaciones y las restricciones que debe tener en cuenta al desarrollar e implementar funciones periféricas con CloudFront. 

Comprender estas restricciones lo ayuda a asegurarse de que las funciones periféricas funcionan según lo previsto y cumplen las características admitidas.

**Topics**
+ [

# Restricciones en todas las funciones de borde
](edge-function-restrictions-all.md)
+ [

# Restricciones en CloudFront Functions
](cloudfront-function-restrictions.md)
+ [

# Restricciones de Lambda @Edge
](lambda-at-edge-function-restrictions.md)

Para obtener información acerca de las cuotas (anteriormente denominadas límites), consulte [Cuotas en CloudFront Functions](cloudfront-limits.md#limits-functions) y [Cuotas de Lambda@Edge](cloudfront-limits.md#limits-lambda-at-edge).

# Restricciones en todas las funciones de borde
<a name="edge-function-restrictions-all"></a>

Las siguientes restricciones se aplican a todas las funciones periféricas, tanto de CloudFront Functions como de Lambda @Edge.

**Topics**
+ [

## Propiedad de Cuenta de AWS
](#function-restrictions-account-ownership)
+ [

## Combinación de funciones de CloudFront con Lambda @Edge
](#function-restrictions-combining-functions)
+ [

## HTTP status codes
](#function-restrictions-status-codes)
+ [

## Encabezados HTTP
](#function-restrictions-headers)
+ [

## Cadenas de consulta
](#function-restrictions-query-strings)
+ [

## URI
](#function-restrictions-uri)
+ [

## Codificación de URI, cadena de consulta y encabezados
](#function-restrictions-encoding)
+ [

## Microsoft Smooth Streaming
](#function-restrictions-microsoft-smooth-streaming)
+ [

## Etiquetado
](#function-restrictions-tagging)

## Propiedad de Cuenta de AWS
<a name="function-restrictions-account-ownership"></a>

Para asociar una función de borde con una distribución de CloudFront, la función y la distribución deben pertenecer al mismo propietario Cuenta de AWS.

## Combinación de funciones de CloudFront con Lambda @Edge
<a name="function-restrictions-combining-functions"></a>

Para un determinado comportamiento de caché, se aplican las siguientes restricciones:
+ Cada tipo de evento (solicitud de lector, solicitud de origen, respuesta de origen y respuesta de lector) solo puede tener una asociación de función de borde.
+ No se puede combinar CloudFront Functions y Lambda@Edge en eventos de lector (solicitud y respuesta).

Todas las demás combinaciones de funciones de borde están permitidas. En la tabla siguiente se explican las combinaciones permitidas.

[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/es_es/AmazonCloudFront/latest/DeveloperGuide/edge-function-restrictions-all.html)

## HTTP status codes
<a name="function-restrictions-status-codes"></a>

CloudFront no invoca funciones periféricas para eventos de respuesta al lector si el origen devuelve el código de estado HTTP 400 o un número superior.

Las funciones de Lambda @Edge para eventos de respuesta de origen se invocan para *All (Todos)*, incluso si el origen devuelve el código de estado HTTP 400 o un número superior. Para obtener más información, consulte [Actualización de respuestas HTTP en desencadenadores de respuesta de origen](lambda-generating-http-responses.md#lambda-updating-http-responses).

## Encabezados HTTP
<a name="function-restrictions-headers"></a>

Determinados encabezados HTTP no están permitidos, lo que significa que no están expuestos a funciones perimetrales y las funciones no pueden agregarlos. Otros encabezados son de solo lectura, lo que significa que las funciones pueden leerlos pero no pueden agregarlos, modificarlos ni eliminarlos.

**Topics**
+ [

### Encabezados no permitidos
](#function-restrictions-disallowed-headers)
+ [

### Encabezados de solo lectura
](#function-restrictions-read-only-headers)

### Encabezados no permitidos
<a name="function-restrictions-disallowed-headers"></a>

Los siguientes encabezados HTTP no están expuestos a funciones perimetrales y las funciones no pueden agregarlos. Si su función agrega uno de estos encabezados, no supera la validación de CloudFront y CloudFront devuelve el código de estado HTTP 502 (Gateway incorrecta) al lector.
+ `Connection` 
+ `Expect`
+ `Keep-Alive`
+ `Proxy-Authenticate`
+ `Proxy-Authorization`
+ `Proxy-Connection`
+ `Trailer`
+ `Upgrade`
+ `X-Accel-Buffering`
+ `X-Accel-Charset`
+ `X-Accel-Limit-Rate`
+ `X-Accel-Redirect`
+ `X-Amz-Cf-*`
+ `X-Amzn-Auth`
+ `X-Amzn-Cf-Billing`
+ `X-Amzn-Cf-Id`
+ `X-Amzn-Cf-Xff`
+ `X-Amzn-Errortype`
+ `X-Amzn-Fle-Profile`
+ `X-Amzn-Header-Count`
+ `X-Amzn-Header-Order`
+ `X-Amzn-Lambda-Integration-Tag`
+ `X-Amzn-RequestId`
+ `X-Cache`
+ `X-Edge-*`
+ `X-Forwarded-Proto`
+ `X-Real-IP`

### Encabezados de solo lectura
<a name="function-restrictions-read-only-headers"></a>

Los siguientes encabezados son de solo lectura. La función puede leerlos y utilizarlos como entrada para la lógica de la función, pero no puede cambiar los valores. Si su función añade o edita un encabezado de solo lectura, la solicitud no supera la validación de CloudFront y CloudFront devuelve el código de estado HTTP 502 (Gateway incorrecta) al lector.

#### Encabezados de solo lectura en eventos de solicitud de lector
<a name="function-restrictions-read-only-headers-viewer-request"></a>

Los siguientes encabezados son de solo lectura en los eventos de solicitud de lector.
+ `Content-Length`
+ `Host`
+ `Transfer-Encoding`
+ `Via`

#### Encabezados de solo lectura en eventos de solicitud de origen (solo Lambda @Edge)
<a name="function-restrictions-read-only-headers-origin-request"></a>

Los siguientes encabezados son de solo lectura en eventos de solicitud de origen, que solo existen en Lambda @Edge.
+ `Accept-Encoding`
+ `Content-Length`
+ `If-Modified-Since`
+ `If-None-Match`
+ `If-Range`
+ `If-Unmodified-Since`
+ `Transfer-Encoding`
+ `Via`

#### Encabezados de solo lectura en eventos de respuesta de origen (solo Lambda @Edge)
<a name="function-restrictions-read-only-headers-origin-response"></a>

Los siguientes encabezados son de solo lectura en eventos de respuesta de origen, que solo existen en Lambda @Edge.
+ `Transfer-Encoding`
+ `Via`

#### Encabezados de solo lectura en eventos de respuesta de lector
<a name="function-restrictions-read-only-headers-viewer-response"></a>

Los siguientes encabezados son de solo lectura en eventos de respuesta de lector para CloudFront Functions y Lambda@Edge.
+ `Warning`
+ `Via`

Los siguientes encabezados son de solo lectura en los eventos de respuesta de lector para Lambda@Edge.
+ `Content-Length`
+ `Content-Encoding`
+ `Transfer-Encoding`

## Cadenas de consulta
<a name="function-restrictions-query-strings"></a>

Las siguientes restricciones se aplican a las funciones que leen, actualizan o crean una cadena de consulta en un URI de solicitud.
+ (Solo Lambda @Edge) Para acceder a la cadena de consulta en una solicitud de origen o función de respuesta de origen, la política de caché o la política de solicitud de origen debe establecerse en**All (Todos)**: para**Cadenas de consulta**.
+ Una función puede crear o actualizar una cadena de consulta para eventos de solicitud de lector y solicitud de origen (los eventos de solicitud de origen solo existen en Lambda @Edge).
+ Una función puede leer una cadena de consulta, pero no puede crear o actualizar una, para eventos de respuesta de origen y respuesta de lector (los eventos de respuesta de origen solo existen en Lambda @Edge).
+ Las siguientes restricciones se aplica si una función crea o actualiza una cadena de consulta:
  + La cadena de consulta no puede incluir espacios, caracteres de control ni el identificador de fragmento (`#`).
  + El tamaño total del URI () y la cadena de consulta () debe ser inferior a 8 192 caracteres.
  + Le recomendamos que utilice la codificación de porcentaje para el URI y la cadena de consulta. Para obtener más información, consulte [Codificación de URI, cadena de consulta y encabezados](#function-restrictions-encoding).

## URI
<a name="function-restrictions-uri"></a>

Si una función cambia la URI de una solicitud, eso no cambia el comportamiento de la caché frente a la solicitud ni el origen al que se reenvía la solicitud.

El tamaño total del URI y la cadena de consulta debe ser inferior a 8192 caracteres.

## Codificación de URI, cadena de consulta y encabezados
<a name="function-restrictions-encoding"></a>

Los valores de URI, cadena de consulta y encabezados que se pasan a funciones periféricas tienen la codificación UTF-8. La función debe usar la codificación UTF-8 para los valores de URI, cadena de consulta y encabezado que devuelve. La codificación de porcentaje es compatible con la codificación UTF-8.

La siguiente lista explica cómo CloudFront maneja la codificación del URI, la cadena de consulta y los encabezados:
+ Cuando los valores de la solicitud tienen la codificación UTF-8, CloudFront reenvía los valores a la función de sin cambiarlos.
+ Cuando los valores en la solicitud tienen [codificación de caracteres ISO 8859-1](https://en.wikipedia.org/wiki/ISO/IEC_8859-1), CloudFront convierte los valores a la codificación UTF-8 antes de reenviarlos a su función.
+ Si los valores en la solicitud están codificados mediante alguna otra codificación de caracteres, CloudFront supone que tienen la codificación ISO-8859-1 e intenta convertir esa codificación de ISO-8859-1 a UTF-8.
**importante**  
Los caracteres convertidos podrían ser una interpretación inexacta de los valores de la solicitud original. Esto podría hacer que su función o su origen produzcan un resultado no deseado.

Los valores del URI, la cadena de consulta y los encabezados que CloudFront reenvía al origen dependen de si una función cambia los valores:
+ Si una función no cambia el URI, la cadena de consulta o el encabezado, CloudFront reenvía los valores que recibió en la solicitud al origen.
+ Si la función cambia el URI, la cadena de consulta o el encabezado, CloudFront reenvía los valores con codificación UTF-8.

## Microsoft Smooth Streaming
<a name="function-restrictions-microsoft-smooth-streaming"></a>

No puede utilizar funciones periféricas con una distribución de CloudFront que esté utilizando para streaming de archivos multimedia que haya transcodificado en formato Microsoft Smooth Streaming.

## Etiquetado
<a name="function-restrictions-tagging"></a>

No se pueden agregar etiquetas a funciones periféricas. Para obtener más información sobre el etiquetado en CloudFront, consulte [Etiquetado de una distribución](tagging.md).

# Restricciones en CloudFront Functions
<a name="cloudfront-function-restrictions"></a>

Las siguientes restricciones se aplican solo a CloudFront Functions.

**Contents**
+ [

## Registros
](#cloudfront-function-restrictions-logs)
+ [

## Cuerpo de la solicitud
](#cloudfront-function-restrictions-request-body)
+ [

## Uso de credenciales temporales con la API KeyValueStore de CloudFront
](#regional-endpoint-for-key-value-store)
+ [

## Tiempo de ejecución
](#cloudfront-function-runtime-restrictions)
+ [

## Utilización de cómputo
](#cloudfront-function-restrictions-compute-utilization)

Para obtener información acerca de las cuotas (anteriormente denominadas límites), consulte [Cuotas en CloudFront Functions](cloudfront-limits.md#limits-functions).

## Registros
<a name="cloudfront-function-restrictions-logs"></a>

Los registros de funciones en CloudFront Functions están limitados a 10 KB.

## Cuerpo de la solicitud
<a name="cloudfront-function-restrictions-request-body"></a>

CloudFront Functions no tiene acceso al cuerpo de la solicitud HTTP.

## Uso de credenciales temporales con la API KeyValueStore de CloudFront
<a name="regional-endpoint-for-key-value-store"></a>

Puede utilizar AWS Security Token Service (AWS STS) para generar credenciales de seguridad temporales (también conocidas como *tokens de sesión*). Gracias a los tokens de sesión, podrá asumir temporalmente un rol de AWS Identity and Access Management (IAM) para poder acceder a Servicios de AWS.

Para llamar a la [API KeyValueStore de CloudFront](https://docs.aws.amazon.com/cloudfront/latest/APIReference/API_Operations_Amazon_CloudFront_KeyValueStore.html), utilice un punto de conexión *regional* en AWS STS para devolver un token de sesión de la *versión 2*. Si utiliza el punto de conexión *global* para AWS STS (`sts.amazonaws.com`), AWS STS generará un token de sesión de la *versión 1*, que no es compatible con Signature Version 4A (SigV4A). Como resultado, se producirá un error de autenticación.

Para llamar a la API KeyValueStore de CloudFront, puede utilizar las siguientes opciones: 

**SDK de AWS CLI y AWS**  
Puede configurar la AWS CLI o un SDK de AWS para utilizar puntos de conexión de AWS STS regionales. Para obtener más información, consulte [Puntos de conexión regionalizados de AWS STS](https://docs.aws.amazon.com/sdkref/latest/guide/feature-sts-regionalized-endpoints.html) en la *Guía de referencia de AWS SDK y las herramientas*.  
Para obtener más información sobre los puntos de conexión de AWS STS disponibles, consulte [Regiones y puntos de conexión](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_enable-regions.html#id_credentials_region-endpoints) en la *Guía del usuario de IAM*.

**SAML**  
Puede configurar SAML para utilizar puntos de conexión de AWS STS regionales. Para obtener más información, consulte la entrada de blog [How to use regional SAML endpoints for failover](https://aws.amazon.com/blogs/security/how-to-use-regional-saml-endpoints-for-failover/).

**`SetSecurityTokenServicePreferences`API **  
En lugar de utilizar un punto de conexión de AWS STS regional, puede configurar el punto de conexión global para que AWS STS devuelva tokens de sesión de la versión 2. Para ello, utilice la operación de la API [SetSecurityTokenServicePreferences](https://docs.aws.amazon.com/IAM/latest/APIReference/API_SetSecurityTokenServicePreferences.html) para configurar la Cuenta de AWS.   

**Example Ejemplo: Comando de la CLI de IAM**  

```
aws iam set-security-token-service-preferences --global-endpoint-token-version v2Token
```
Le recomendamos que utilice los puntos de conexión regionales de AWS STS en lugar de esta opción. Los puntos de conexión regionales proporcionan una mayor disponibilidad y escenarios de conmutación por error.

**Proveedor de identidades personalizado**  
Si está utilizando un proveedor de identidades personalizado que realiza la federación y asume el rol, utilice una de las opciones anteriores para el sistema del proveedor de identidades principal que es responsable de generar el token de sesión.

## Tiempo de ejecución
<a name="cloudfront-function-runtime-restrictions"></a>

El entorno de tiempo de ejecución de CloudFront Functions no admite la evaluación dinámica del código y restringe el acceso a la red, al sistema de archivos, a las variables de entorno y a los temporizadores. Para obtener más información, consulte [Características restringidas](functions-javascript-runtime-10.md#writing-functions-javascript-features-restricted-features).

**nota**  
Para usar CloudFront KeyValueStore, la función de CloudFront debe usar el [tiempo de ejecución 2.0 de JavaScript](functions-javascript-runtime-20.md).

## Utilización de cómputo
<a name="cloudfront-function-restrictions-compute-utilization"></a>

CloudFront Functions tiene un límite en el tiempo que pueden tardar en ejecutarse, que se mide como *Utilización de cómputo*. La utilización de cómputo es un número entre 0 y 100 que indica la cantidad de tiempo que la función tardó en ejecutarse como porcentaje del tiempo máximo permitido. Por ejemplo, una utilización de cómputo de 35 significa que la función se completó en 35 % del tiempo máximo permitido.

Cuando [prueba una función](test-function.md), puede ver el valor de utilización de cómputo en la salida del evento de prueba. Para las funciones de producción, puede ver la [Métrica de utilización de cómputo](viewing-cloudfront-metrics.md#monitoring-console.cloudfront-functions) en la [página de Monitoring (Monitorización) de la consola de CloudFront](https://console.aws.amazon.com/cloudfront/v4/home?#/monitoring) o en CloudWatch.

# Restricciones de Lambda @Edge
<a name="lambda-at-edge-function-restrictions"></a>

Las siguientes restricciones se aplican solo a Lambda @Edge.

**Contents**
+ [

## Resolución de los DNS
](#lambda-at-edge-restrictions-dns)
+ [

## HTTP status codes
](#lambda-at-edge-restrictions-status-codes)
+ [

## Versión de función de Lambda
](#lambda-at-edge-restrictions-version)
+ [

## Región de Lambda
](#lambda-at-edge-restrictions-region)
+ [

## Permisos de rol de Lambda
](#lambda-at-edge-restrictions-role-permissions)
+ [

## Características de Lambda
](#lambda-at-edge-restrictions-features)
+ [

## Tiempos de ejecución admitidos
](#lambda-at-edge-restrictions-runtime)
+ [

## Encabezados CloudFront
](#lambda-at-edge-restrictions-cloudfront-headers)
+ [

## Restricciones para el cuerpo de la solicitud con la opción Incluir cuerpo
](#lambda-at-edge-restrictions-request-body)
+ [

## Tiempo de espera de respuesta y tiempo de espera de keep-alive (solo orígenes personalizados)
](#timeout-for-lambda-edge-functions)

Para obtener información sobre cuotas de , consulte [Cuotas de Lambda@Edge](cloudfront-limits.md#limits-lambda-at-edge).

## Resolución de los DNS
<a name="lambda-at-edge-restrictions-dns"></a>

CloudFront realiza una resolución DNS en el nombre de dominio de origen *antes* de ejecutar la función de Lambda@Edge de solicitud de origen. Si el servicio DNS del dominio tiene problemas y CloudFront no puede resolver el nombre de dominio para obtener la dirección IP, la función de Lambda@Edge no se invocará. CloudFront devolverá un [código de estado HTTP 502 (puerta de enlace incorrecta)](http-502-bad-gateway.md) al cliente. Para obtener más información, consulte [Error de DNS (`NonS3OriginDnsError`)](http-502-bad-gateway.md#http-502-dns-error).

Si la lógica de la función modifica el nombre de dominio de origen, CloudFront realizará otra resolución de DNS en el nombre de dominio actualizado después de que la función haya terminado de ejecutarse.

Para obtener más información sobre la administración de la conmutación por error de DNS, consulte [Configuring DNS failover](https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/dns-failover-configuring.html) en la *Guía para desarrolladores de Amazon Route 53*.

## HTTP status codes
<a name="lambda-at-edge-restrictions-status-codes"></a>

Las funciones de Lambda@Edge para eventos de respuesta de lector no pueden modificar el código de estado HTTP de la respuesta, independientemente de si la respuesta proviene del origen o de la caché de CloudFront.

## Versión de función de Lambda
<a name="lambda-at-edge-restrictions-version"></a>

Debe usar una versión numerada de la función de Lambda, no `$LATEST` o alias.

## Región de Lambda
<a name="lambda-at-edge-restrictions-region"></a>

La función de Lambda debe estar en la región EE. UU. Este (Norte de Virginia).

## Permisos de rol de Lambda
<a name="lambda-at-edge-restrictions-role-permissions"></a>

El rol de la ejecución de IAM asociado a la función de Lambda debe permitir que lo asuman las entidades principales del servicio `lambda.amazonaws.com` y `edgelambda.amazonaws.com`. Para obtener más información, consulte [Configuración de permisos y roles de IAM para Lambda@Edge](lambda-edge-permissions.md).

## Características de Lambda
<a name="lambda-at-edge-restrictions-features"></a>

Lambda @Edge no admite las siguientes características de Lambda:
+ [Configuraciones de administración del tiempo de ejecución de Lambda](https://docs.aws.amazon.com/lambda/latest/dg/runtimes-update.html#runtime-management-controls) distintas de **Auto** (predeterminada)
+ Configuración de la función de Lambda para obtener acceso a recursos en la VPC
+ [Colas de mensajes fallidos de la función de Lambda](https://docs.aws.amazon.com/lambda/latest/dg/invocation-async.html#dlq)
+ [Variables de entorno de Lambda](https://docs.aws.amazon.com/lambda/latest/dg/configuration-envvars.html) (excepto las variables de entorno reservadas, que se admiten automáticamente)
+ Lambda funciona con [Administración de dependencias de AWS Lambda con capas](https://docs.aws.amazon.com/lambda/latest/dg/chapter-layers.html)
+ [Uso de AWS X-Ray](https://docs.aws.amazon.com/lambda/latest/dg/lambda-x-ray.html)
+ Simultaneidad aprovisionada de Lambda
**nota**  
Las funciones de Lambda@Edge comparten las mismas capacidades de [simultaneidad regional](https://docs.aws.amazon.com/lambda/latest/dg/configuration-concurrency.html) que todas las funciones de Lambda. Para obtener más información, consulte [Cuotas de Lambda@Edge](cloudfront-limits.md#limits-lambda-at-edge).
+ [Creación de una función de Lambda con una imagen de contenedor](https://docs.aws.amazon.com/lambda/latest/dg/images-create.html)
+ [Funciones de Lambda que utilizan la arquitectura arm](https://docs.aws.amazon.com/lambda/latest/dg/foundation-arch.html)
+ Funciones de Lambda con más de 512 MB de almacenamiento efímero
+ Uso de una [clave administrada por el cliente para cifrar los paquetes de implementación .zip](https://docs.aws.amazon.com/lambda/latest/dg/encrypt-zip-package.html)

## Tiempos de ejecución admitidos
<a name="lambda-at-edge-restrictions-runtime"></a>

Lambda@Edge admite las versiones más recientes de los tiempos de ejecución de Node.js y Python. Para obtener una lista de las versiones compatibles y sus futuras fechas de obsolescencia, consulte [Tiempos de ejecución compatibles](https://docs.aws.amazon.com/lambda/latest/dg/lambda-runtimes.html#runtimes-supported) en la *Guía para desarrolladores de AWS Lambda*.

**sugerencia**  
Como práctica recomendada, utilice las últimas versiones de los tiempos de ejecución proporcionados para obtener mejoras en el rendimiento y nuevas características.
No puede crear ni actualizar funciones con las versiones obsoletas de Node.js. Solo puede asociar las funciones existentes a estas versiones con las distribuciones de CloudFront. Las funciones con estas versiones que están asociadas a las distribuciones continúan ejecutándose. Sin embargo, le recomendamos que traslade la función a versiones más recientes de Node.js. Para obtener más información, consulte [Política de obsolescencia del tiempo de ejecución](https://docs.aws.amazon.com/lambda/latest/dg/runtime-support-policy.html) en la *Guía para desarrolladores de AWS Lambda* y la [programación de versiones de Node.js](https://github.com/nodejs/Release#release-schedule) en GitHub.

## Encabezados CloudFront
<a name="lambda-at-edge-restrictions-cloudfront-headers"></a>

Las funciones de Lambda@Edge pueden leer, editar, eliminar o agregar cualquiera de los siguientes encabezados de CloudFront enumerados en [Añadido de encabezados de solicitudes de CloudFront](adding-cloudfront-headers.md).

**Notas**  
Si desea que CloudFront agregue estos encabezados, debe configurar CloudFront para que los agregue mediante una [política de caché](controlling-the-cache-key.md) o una [política de solicitud de origen](controlling-origin-requests.md).
CloudFront agrega los encabezados *después* del evento de solicitud de lector, lo que significa que los encabezados no están disponibles para las funciones de Lambda @Edge en una solicitud de lector. Los encabezados solo están disponibles para las funciones de Lambda @Edge en una solicitud de origen y una respuesta de origen.
Si la solicitud de lector incluye encabezados que tienen estos nombres y configuró CloudFront para que agregue estos encabezados mediante una [Política de caché](controlling-the-cache-key.md) o una [Política de solicitud de origen](controlling-origin-requests.md), CloudFront sobrescribe los valores de los encabezados que estaban en la solicitud de lector. Las funciones orientadas al lector ven el valor del encabezado de la solicitud de lector, mientras que las funciones orientadas al origen ven el valor de encabezado que CloudFront agregó.
Si una función de solicitud de lector agrega el encabezado `CloudFront-Viewer-Country`, la solicitud no supera la validación de CloudFront y devuelve el código de estado HTTP 502 (puerta de enlace incorrecta) al lector.

## Restricciones para el cuerpo de la solicitud con la opción Incluir cuerpo
<a name="lambda-at-edge-restrictions-request-body"></a>

Cuando elija la opción **Incluir cuerpo** para exponer el cuerpo de la solicitud a la función de Lambda@Edge, se aplican la siguiente información y los siguientes límites de tamaño para las partes del cuerpo que se exponen o reemplazan.
+ CloudFront siempre codifica con base64 el cuerpo de la solicitud antes de exponerlo a Lambda @Edge.
+ Si el cuerpo de la solicitud es grande, CloudFront lo limita antes de exponerlo a Lambda@Edge, del siguiente modo:
  + Para los eventos de solicitudes de lector, el cuerpo está limitado a 40 KB.
  + Para las solicitudes de origen, el cuerpo está limitado a 1 MB.
+ Si tiene acceso al cuerpo de la solicitud como de solo lectura, CloudFront devuelve el cuerpo completo de la solicitud original al origen.
+ Si la función de Lambda @Edge reemplaza el cuerpo de la solicitud, se aplican los siguientes límites de tamaño al cuerpo que devuelve la función:
  + Si la función Lambda @Edge devuelve el cuerpo como texto sin formato:
    + Para los eventos de solicitudes de lector, el límite del cuerpo es 40 KB.
    + Para los eventos de solicitudes de origen, el límite del cuerpo es 1 MB.
  + Si la función Lambda @Edge devuelve el cuerpo como texto codificado con base64:
    + Para los eventos de solicitudes de lector, el límite del cuerpo es 53,2 KB.
    + Para los eventos de solicitudes de origen, el límite del cuerpo es 1,33 MB.

**nota**  
Si la función de Lambda@Edge devuelve un cuerpo que supera estos límites, la solicitud producirá un error con un código de estado HTTP 502 ([Error de validación de Lambda](http-502-bad-gateway.md#http-502-lambda-validation-error)). Le recomendamos que actualice la función Lambda@Edge para que el cuerpo no supere estos límites.

## Tiempo de espera de respuesta y tiempo de espera de keep-alive (solo orígenes personalizados)
<a name="timeout-for-lambda-edge-functions"></a>

Si utiliza las funciones de Lambda@Edge para establecer el tiempo de espera de respuesta o el tiempo de espera de keep-alive para sus orígenes de distribución, compruebe que está especificando un valor que su origen pueda admitir. Para obtener más información, consulte [Cuotas de tiempo de espera de respuesta y de keep-alive](DownloadDistValuesOrigin.md#response-keep-alive-timeout-quota).