# Reglas de caché

> Omite la caché o haz elegibles más peticiones por ruta, extensión, cookie o parámetro de consulta, con TTL del borde y del navegador por regla.

Las reglas de caché cambian el [comportamiento por defecto](https://developers.openwaf.dev/es/cache/default-behavior/) para las peticiones que casan con ellas. Úsalas para dejar fuera de la caché las páginas de administración y los visitantes con sesión, o para cachear el HTML.

## Cómo se evalúan

- Una zona (y cada nombre con lista propia) tiene hasta **25 reglas**, que se evalúan en orden para las peticiones `GET` y `HEAD`.
- Si casan varias, **la última que casa gana en cada ajuste**. Pon primero las reglas `cache` amplias y después las `bypass` que siempre deben ganar.
- Un nombre hereda las reglas de la zona que le aplican o tiene su propia lista, que sustituye a la de la zona para ese nombre.

## Condiciones

Deben cumplirse todas las listas que rellenes (Y); dentro de una lista basta con un valor (O). Una regla sin condiciones casa con todas las peticiones. Cada lista admite hasta 32 valores.

| Campo | Panel | Casa cuando |
|---|---|---|
| `match.path_prefix` | La ruta empieza por | La ruta empieza por uno de los valores (cada uno empieza por `/`). |
| `match.path_exact` | La ruta es exactamente | La ruta es exactamente uno de los valores. |
| `match.extensions` | Extensión de fichero | La extensión del último segmento es uno de los valores, sin el punto; `""` = sin extensión (`/`, `/contacto`). |
| `match.cookie_present` | La petición trae la cookie | La petición trae una de estas cookies; un `*` final casa por prefijo (`wordpress_logged_in_*`). |
| `match.query_present` | La URL lleva el parámetro | La URL lleva este parámetro de consulta, con o sin valor; un `*` final casa por prefijo. |
| `hosts` | Nombres | Solo en las reglas de la zona: los nombres a los que se aplica; vacío = todos. |

Como las listas de una regla se combinan con Y, pon las rutas exactas y los prefijos en reglas distintas cuando baste con cualquiera de ellos.

## Acciones

| `action` | Panel | Efecto |
|---|---|---|
| `bypass` | Omitir caché | Ni se busca ni se guarda (`DYNAMIC`). No lleva parámetros. |
| `cache` | Elegible para caché | Elegible aunque la extensión no esté en la lista por defecto (HTML, JSON…), con los parámetros opcionales de abajo. |

### Parámetros de una regla cache

| Parámetro | Valores | Efecto |
|---|---|---|
| `edge_ttl.mode` | `respect_origin` | Las cabeceras del origen; sin ellas, los [TTL por defecto](https://developers.openwaf.dev/es/cache/default-behavior/#default-ttls) (solo en las extensiones por defecto). |
| | `bypass_by_default` | Las cabeceras del origen; sin ellas, no se guarda. |
| | `override` (con `ttl_s`) | Ignora la `Cache-Control` del origen y guarda la respuesta `ttl_s` segundos. Quita `Set-Cookie` de la copia guardada y desactiva la armadura anti-engaño para estas peticiones. |
| `edge_ttl.status` | `[{"from": 200, "to": 299, "ttl_s": 300}]` | TTL por rango de códigos de estado, en cualquier modo: `-1` = no guardar, `0` = guardar y revalidar siempre. Hasta 10 rangos. |
| `browser_ttl` | `{"mode": "respect_origin"}` o `{"mode": "override", "ttl_s": N}` | `override` sube el `max-age` del navegador hasta al menos `N`. |
| `query` | `{"mode": …, "sort": …, "params": […]}` | Política de consulta en la clave para estas peticiones. Consulta [Claves de caché](https://developers.openwaf.dev/es/cache/cache-keys/#query-string). |
| `serve_stale` | `{"while_revalidate": …, "on_error_max_s": …}` | Contenido caducado para estas peticiones. |
| `vary_bypass_if_present` | Nombres de cabecera de petición en minúsculas | Consulta [más abajo](#vary-bypass). |

Los TTL van de 1 segundo a 1 año; `on_error_max_s`, hasta 30 días.

> **Atención**
>
> `override` guarda las respuestas aunque pongan cookies. Úsalo solo con páginas iguales para todos los visitantes y añade después una regla `bypass` para los visitantes con sesión (sus cookies de sesión).


### Saltar la caché con ciertas cabeceras

`vary_bypass_if_present` (**Saltar la caché si la petición trae estas cabeceras**) lista cabeceras de petición, como `rsc`, `next-router-state-tree`, `next-router-prefetch` y `next-router-segment-prefetch`, las de la navegación interna de Next.js. Una petición que traiga alguna ni se busca ni se guarda (`DYNAMIC`, `detail=vary`). Las peticiones sin ellas reciben la versión cacheada normal, aunque el origen liste esas cabeceras en `Vary`. No se pueden listar `accept-encoding`, `accept` ni `origin`: ya diferencian la caché.

## Plantillas

El panel (**Caché › Reglas de caché › Empezar con una plantilla**) rellena el editor de reglas; nada cambia hasta que guardas.

| Plantilla | Reglas |
|---|---|
| WordPress | Omite `/wp-admin/` y `/wp-login.php`, y los visitantes con cookies de sesión de WordPress o WooCommerce. Opcionalmente cachea también el HTML anónimo 5 minutos. |
| Next.js | Cachea las páginas (rutas sin extensión) hasta 10 minutos, solo las respuestas `200`, ignorando en la clave los parámetros de anuncios. Nunca cachea las rutas de `/api/`, login, cuenta, carrito ni checkout, los visitantes con cookie de sesión ni la navegación interna de Next.js (cabeceras RSC, `?_rsc`). |
| Web estática | HTML 5 minutos, servido caducado mientras se actualiza o si el origen falla. |
| Solo valores por defecto | Quita todas las reglas. |
| Cachear todo | Todas las respuestas elegibles, según la `Cache-Control` del origen. |
| Omitir la caché para todo | No se cachea nada. |

> **Consejo**
>
> Con la plantilla de Next.js, ajusta los nombres de las cookies de sesión a tu sitio y purga el HTML tras cada despliegue para que las páginas no apunten a los chunks del build anterior. Un [token de solo purga](https://developers.openwaf.dev/es/cache/purge/#ci) lo hace desde tu CI.


## Añadir reglas

**Panel**

En **Caché › Reglas de caché**, pulsa **Añadir regla**, rellena **Cuando las peticiones coincidan con…** y **Entonces…**, y pulsa **Aplicar**. Reordena con las flechas y después pulsa **Guardar cambios**.

**CLI**

```sh
openwaf-cloud ctl zones set example.com 'cache.rules:=[
  {"match": {"extensions": ["html", ""]}, "action": "cache",
   "edge_ttl": {"mode": "override", "ttl_s": 300}},
  {"match": {"path_prefix": ["/wp-admin/", "/wp-login.php"]}, "action": "bypass"},
  {"match": {"cookie_present": ["wordpress_logged_in_*", "wp-postpass_*"]}, "action": "bypass"}
]' --reason "reglas de caché de WordPress"
```

**API**

```sh
curl -s -X PATCH https://dash.openwaf.dev/v1/orgs/$ORG/zones/$ZONE/edge \
  -H "Authorization: Bearer $OPENWAF_TOKEN" \
  -H "Content-Type: application/json" \
  -H "X-Change-Reason: omitir el admin" \
  -d '{"cache": {"rules": [{"match": {"path_prefix": ["/wp-admin/"]}, "action": "bypass"}]}}'
```

**MCP**

`update_settings` con `{"zone": "example.com", "settings": {"cache": {"rules": [{"match": {"path_prefix": ["/wp-admin/"]}, "action": "bypass"}]}}, "reason": "omitir el admin"}`.


`rules` siempre se sustituye entera: envía la lista completa; `[]` quita todas las reglas. Las reglas sin `id` reciben `r1`, `r2`…

## Comprobar una regla

```sh
curl -sI https://www.example.com/ | grep -i -E 'x-cache-status|cache-status'
```

Con HTML, pide dos veces: la segunda respuesta debe ser `HIT`. Una página que sigue en `MISS` o `BYPASS` no se está guardando; `Cache-Status` explica el motivo en `detail`. Consulta [Solución de problemas](https://developers.openwaf.dev/es/cache/troubleshooting/).
