Ir al contenido

Configuración del puente de Cloudflare de NextPDF

Tres objetos de configuración inmutables rigen el paquete. Cada valor predeterminado de esta página se toma de la firma del constructor correspondiente en src/Cloudflare/. No procede de una especificación ni de una estimación. Cuando esta página indica un máximo, ese máximo es un límite que este paquete aplica. No es una afirmación sobre la capacidad de la plataforma Cloudflare.

Configuración del renderizador. final readonly. Se puede construir directamente o con CloudflareRendererConfig::fromArray().

CampoTipoPredeterminadoSignificado
workerUrlstring— (obligatorio)URL del endpoint del Worker. Debe ser HTTPS.
apiTokenstring— (obligatorio)Token Bearer. Marcado con #[SensitiveParameter].
renderTimeoutint30Tiempo de espera de transferencia en segundos, aplicado por el transporte cURL con pines fijados.
defaultCssstring''CSS inyectado en el payload antes del HTML proporcionado.
maxHtmlSizeint5000000Tamaño máximo de entrada HTML, en bytes, aplicado antes de enviar la solicitud.
r2FontBucket?stringnullNombre del bucket de R2 para paquetes de fuentes personalizadas.
fallbackToLocalbooltrueIndica si un Worker inalcanzable recurre a un renderizador local.
pinnedPublicKeyslist<string>[]Huellas digitales SPKI SHA-256, con formato sha256/<base64>.
backupPublicKeyslist<string>[]Pines SPKI de respaldo, mantenidos por separado para que la rotación se valide de forma independiente.

isValid() devuelve true solo cuando workerUrl !== '' y apiToken !== ''. allPublicKeyPins() devuelve la unión sin duplicados de pinnedPublicKeys y backupPublicKeys. La capa TLS acepta un certificado cuyo hash SPKI figure en cualquier miembro de esa unión. Esto coincide con RFC 7469 §2.6, que valida una conexión fijada cuando el conjunto de huellas digitales SPKI presentadas tiene intersección con el conjunto fijado. RFC 7469 §2.5 describe el pin de respaldo como el mecanismo principal de recuperación frente a un fallo inadvertido de validación de pines. Conviene mantener al menos un pin de respaldo para evitar que una rotación de certificado rompa el endpoint; ver /integrations/cloudflare/security-and-operations/.

CloudflareRendererConfig::fromArray() lee claves en snake_case y aplica los mismos valores predeterminados cuando una clave está ausente o tiene un tipo incorrecto:

Clave del arraySe asigna a
worker_urlworkerUrl
api_tokenapiToken
render_timeoutrenderTimeout (predeterminado 30)
default_cssdefaultCss
max_html_sizemaxHtmlSize (predeterminado 5000000)
r2_font_bucketr2FontBucket
fallback_to_localfallbackToLocal (predeterminado true)
pinned_public_keyspinnedPublicKeys (los miembros que no son cadenas se descartan)
backup_public_keysbackupPublicKeys (los miembros que no son cadenas se descartan)
<?php
declare(strict_types=1);
use NextPDF\Cloudflare\CloudflareRendererConfig;
$config = CloudflareRendererConfig::fromArray([
'worker_url' => 'https://pdf-renderer.example.workers.dev/render',
'api_token' => getenv('CF_PDF_TOKEN') ?: '',
'render_timeout' => 60,
'r2_font_bucket' => 'pdf-fonts',
'pinned_public_keys' => ['sha256/YLh1dUR9y6Kja30RrAn7JKnbQG/uEtLMkBgFF2Fuihg='],
'backup_public_keys' => ['sha256/Vjs8r4z+80wjNcr1YKepWQboSIRi63WsWXhIMN+eWys='],
]);

Límites de tamaño de entrada aplicados por el paquete

Sección titulada «Límites de tamaño de entrada aplicados por el paquete»

CloudflareSecurityPolicy::validate() aplica estos límites antes de que cualquier solicitud salga del proceso. Los números se toman del código fuente:

LímiteValorDónde
Entrada HTML máximamaxHtmlSize (predeterminado 5000000 bytes)CloudflareSecurityPolicy::validate()
Tamaño máximo de URI de datos base64 decodificado13631488 bytes (≈13 MB)CloudflareSecurityPolicy::MAX_DATA_URI_BYTES

Si se supera cualquiera de los dos, se genera una RuntimeException con un mensaje que indica el tamaño infractor y el límite. El tope de base64 protege contra bombas de descompresión. La política estima el tamaño decodificado a partir de la longitud de base64 y rechaza la solicitud si se alcanza o supera el tope. Una etiqueta <meta http-equiv="refresh"> también se rechaza, sin distinguir mayúsculas y minúsculas, porque puede provocar una redirección desde dentro de la página renderizada.

El paquete declara únicamente los límites que él mismo aplica. No hace ninguna afirmación sobre los topes de solicitud, CPU o memoria del propio Worker. Consultar la documentación oficial de Cloudflare y la implementación del Worker para conocerlos.

Configuración de la capa opcional de protección de solicitudes que un Worker — o una pasarela PHP situada delante de él — aplica a las solicitudes de renderizado entrantes. final readonly.

CampoTipoPredeterminadoSignificado
maxRequestsPerMinuteint60Tope de solicitudes por minuto por cliente.
maxRequestsPerHourint1000Tope de solicitudes por hora por cliente.
maxPayloadSizeBytesint10485760Payload entrante máximo (≈10 MB).
allowedOriginslist<string>[]Lista CORS de orígenes permitidos. Vacía significa que aquí no se expresa ninguna restricción de origen.
requireApiKeybooltrueIndica si se requiere una clave de API.
apiKeyHeaderstring'X-Api-Key'Cabecera que transporta la clave de API.
rateLimitWindowSecondsint60Duración de la ventana por minuto, en segundos.

fromArray() lee max_requests_per_minute, max_requests_per_hour, max_payload_size_bytes, allowed_origins, require_api_key, api_key_header y rate_limit_window_seconds. isValid() exige que todos los campos numéricos sean positivos y que apiKeyHeader no esté vacío.

Configuración para archivar los PDF renderizados en Cloudflare R2 a través de la API compatible con S3. final readonly.

CampoTipoPredeterminadoSignificado
bucketNamestring— (obligatorio)Bucket de R2. Validado contra la regla de nomenclatura de S3.
accountIdstring— (obligatorio)ID de cuenta de Cloudflare, utilizado para construir el endpoint predeterminado.
accessKeyIdstring— (obligatorio)ID de clave de acceso de R2. #[SensitiveParameter].
secretAccessKeystring— (obligatorio)Clave de acceso secreta de R2. #[SensitiveParameter].
endpointstring''Endpoint S3 personalizado. Si está vacío, se construye el predeterminado a partir de accountId.
pathPrefixstring'pdfs/'Prefijo de clave para los objetos cargados.
maxFileSizeBytesint104857600Tamaño máximo de subida (≈100 MB), aplicado antes de subir.

El constructor rechaza un bucketName no vacío que no cumpla la regla compatible con S3. Según esa regla, debe tener de 3 a 63 caracteres, usar solo caracteres alfanuméricos en minúscula y guiones, y empezar y terminar con un carácter alfanumérico. Una infracción genera InvalidArgumentException. isValid() exige que bucketName, accountId, accessKeyId y secretAccessKey no estén vacíos. Cuando endpoint está vacío, getEndpoint() devuelve https://<accountId>.r2.cloudflarestorage.com.

apiToken, accessKeyId y secretAccessKey llevan el atributo #[SensitiveParameter], por lo que PHP los oculta en las trazas de pila. Deben proporcionarse desde variables de entorno o desde un gestor de secretos. No deben confirmarse nunca en el repositorio. Los objetos de configuración son inmutables, por lo que un valor establecido una vez no puede modificarse después de la construcción.

  • /integrations/cloudflare/quickstart/ — aplicar esta configuración en un primer renderizado.
  • /integrations/cloudflare/production-usage/ — el fallback, el archivado en R2 y la protección de la API integrados entre sí.
  • /integrations/cloudflare/security-and-operations/ — fijado de pines, defensa contra SSRF y rotación de secretos.