Referencia de API de Cloudflare
De un vistazo
Sección titulada «De un vistazo»El paquete NextPDF\Cloudflare es un puente de renderizado en el edge: el proceso PHP conserva el HTML y un Worker de Cloudflare mantiene el navegador headless. El paquete expone un renderer de HTML respaldado por un Worker (CloudflareHtmlRenderer), junto con los objetos de valor que devuelve, una capa de protección de solicitudes para proteger los endpoints de renderizado (ApiProtection), un servicio de archivado en R2 para almacenar los PDF renderizados (R2ArchiveManager) y utilidades de transporte con pinning para reforzar TLS/DNS. La configuración reside en tres objetos inmutables (CloudflareRendererConfig, ApiProtectionConfig, R2ArchiveConfig).
Para empezar: cuando se usa el paquete por primera vez, el punto de partida es construir un CloudflareRendererConfig, conectarlo a CloudflareHtmlRenderer y llamar a render(). Esa única llamada envía el HTML al Worker y devuelve un CloudflareRenderResult con los bytes del PDF. Todo lo demás (protección, archivado, pinning) se construye alrededor de esa llamada.
Tareas habituales
Sección titulada «Tareas habituales»Los fragmentos de código siguientes muestran los flujos de trabajo reales más frecuentes de este paquete. Cada uno es autónomo, está verificado contra el código fuente en src/Cloudflare/ y lee los secretos desde el entorno.
Renderizar una cadena de HTML a PDF en el edge: la única llamada canónica de renderizado:
<?php
declare(strict_types=1);
use GuzzleHttp\Client;use GuzzleHttp\Psr7\HttpFactory;use NextPDF\Cloudflare\CloudflareHtmlRenderer;use NextPDF\Cloudflare\CloudflareRendererConfig;
$httpFactory = new HttpFactory();
$renderer = new CloudflareHtmlRenderer( config: new CloudflareRendererConfig( workerUrl: 'https://pdf-renderer.example.workers.dev/render', apiToken: getenv('CF_PDF_TOKEN') ?: throw new RuntimeException('CF_PDF_TOKEN not set'), ), httpClient: new Client(), requestFactory: $httpFactory, streamFactory: $httpFactory, responseFactory: $httpFactory,);
$result = $renderer->render('<h1>Hello from the edge</h1>', widthPt: 595.28);
if ($result->isValid()) { file_put_contents('output.pdf', $result->pdfData);}Qué hace: envía el HTML al Worker por HTTPS y escribe en disco los bytes del PDF A4 devuelto una vez que isValid() confirma que es un PDF real.
Archivar un PDF renderizado en R2 y devolver un enlace de corta duración:
<?php
declare(strict_types=1);
use NextPDF\Cloudflare\R2ArchiveConfig;use NextPDF\Cloudflare\R2ArchiveManager;
$archive = new R2ArchiveManager( config: R2ArchiveConfig::fromArray([ 'bucket_name' => 'pdf-archive', 'account_id' => getenv('CF_ACCOUNT_ID') ?: '', 'access_key_id' => getenv('R2_ACCESS_KEY_ID') ?: '', 'secret_access_key' => getenv('R2_SECRET_ACCESS_KEY') ?: '', ]), httpClient: $httpClient, // PSR-18 ClientInterface requestFactory: $requestFactory, // PSR-17 RequestFactoryInterface streamFactory: $streamFactory, // PSR-17 StreamFactoryInterface);
$upload = $archive->upload($result->pdfData, 'invoice-1234.pdf');
$signedUrl = $upload->isValid() ? $archive->generateSignedUrl($upload->key, expiresInSeconds: 600) : null;Qué hace: sube los bytes del PDF a una clave de R2 particionada por fecha y, si tiene éxito, emite una URL prefirmada de 10 minutos para la descarga temporal.
Proteger un endpoint de renderizado antes de realizar trabajo costoso en el Worker:
<?php
declare(strict_types=1);
use NextPDF\Cloudflare\ApiKeyValidator;use NextPDF\Cloudflare\ApiProtection;use NextPDF\Cloudflare\ApiProtectionConfig;
$protection = new ApiProtection( config: new ApiProtectionConfig(maxRequestsPerMinute: 30), keyValidator: new ApiKeyValidator([getenv('RENDER_API_KEY') ?: '']),);
$decision = $protection->checkRequest( clientId: $clientIp, payloadSize: strlen($html), apiKey: $presentedApiKey,);
if (!$decision->allowed) { // Reject with 429 and rate-limit headers before any render call. return [429, $decision->toHeaders(), $decision->denialReason];}Qué hace: valida la clave de API, el tamaño del payload y, después, el límite de tasa por cliente; devuelve una única decisión junto con las cabeceras de respuesta que se adjuntan cuando la solicitud se deniega.
Renderer
Sección titulada «Renderer»La tabla del renderer describe la superficie principal. Usarla al construir la configuración, crear el renderer o hacer las llamadas de renderizado y de comprobación de disponibilidad.
| Símbolo | Parámetros | Comportamiento predeterminado | Devuelve | Lanza o falla con | Notas |
|---|---|---|---|---|---|
new CloudflareRendererConfig(string $workerUrl, string $apiToken, int $renderTimeout = 30, string $defaultCss = '', int $maxHtmlSize = 5000000, ?string $r2FontBucket = null, bool $fallbackToLocal = true, array $pinnedPublicKeys = [], array $backupPublicKeys = []) | URL del Worker, token bearer, timeout, CSS, límite de tamaño, bucket de fuentes en R2 opcional, indicador de fallback, conjuntos de pins. | El fallback local está habilitado; el pinning se deshabilita cuando los arrays de pins están vacíos. | CloudflareRendererConfig | No se espera ninguno. | Mantener en secreto el token de API; preferir URLs del Worker con HTTPS. |
CloudflareRendererConfig::fromArray(array $config) | worker_url, api_token, render_timeout, default_css, max_html_size, r2_font_bucket, fallback_to_local, arrays de pins. | Las claves opcionales ausentes usan los valores predeterminados del constructor. | CloudflareRendererConfig | No se espera ninguno. | Coincide con los arrays de configuración al estilo de los frameworks. |
CloudflareRendererConfig::isValid() | ninguno. | Requiere una URL del Worker y un token de API no vacíos. | bool | No se espera ninguno. | Una configuración no válida provoca el fallback o un fallo en el renderer. |
CloudflareRendererConfig::allPublicKeyPins() | ninguno. | Combina los pins de clave pública primarios y de respaldo. | list<string> | No se espera ninguno. | Una lista vacía deshabilita el pinning. |
new CloudflareHtmlRenderer(CloudflareRendererConfig $config, ClientInterface $httpClient, RequestFactoryInterface $requestFactory, StreamFactoryInterface $streamFactory, ?LoggerInterface $logger = null, ?LocalRendererFactoryInterface $localRendererFactory = null, ?HtmlSecurityPolicyInterface $htmlSecurityPolicy = null, ?ResponseFactoryInterface $responseFactory = null) | Configuración, dependencias HTTP de PSR, logger opcional, factory de fallback local opcional, política de HTML opcional, factory de respuestas opcional. | Usa DefaultHtmlSecurityPolicy cuando no se proporciona ninguna política de HTML. | CloudflareHtmlRenderer | Errores de cableado del contenedor. | La factory de respuestas habilita el transporte cURL con pinning cuando es necesario. |
CloudflareHtmlRenderer::render(string $html, float $widthPt = 595.28, float $heightPt = 0, array $fontFiles = []) | HTML, ancho de página, alto de página, archivos de fuente en R2. | Ancho A4; alto automático; sin archivos de fuente. | CloudflareRenderResult | CloudflareNotAvailableException, CloudflareRenderException, fallos de validación. | Valida el tamaño del HTML y la URL del Worker antes de la E/S de red. |
CloudflareHtmlRenderer::getHtmlSecurityPolicy() | ninguno. | Devuelve la política de la capa de análisis configurada. | HtmlSecurityPolicyInterface | No se espera ninguno. | Usarla junto con la protección de endpoints y la validación de la URL del Worker. |
CloudflareHtmlRenderer::isAvailable() | ninguno. | Solicitud HEAD al Worker cuando la configuración es válida. | bool | Devuelve false ante errores. | Usarla para comprobaciones de disponibilidad, no como la única salvaguarda en tiempo de ejecución. |
Objetos de valor del renderer y seguridad
Sección titulada «Objetos de valor del renderer y seguridad»Usar esta tabla cuando se necesiten los objetos de valor de request/result (CloudflareRenderResult, CloudflareRenderPayload) o las comprobaciones estáticas de la capa de transporte que validan el HTML, la URL del Worker y los pins de DNS antes de cualquier E/S de red.
| Símbolo | Parámetros | Comportamiento predeterminado | Devuelve | Lanza o falla con | Notas |
|---|---|---|---|---|---|
new CloudflareRenderResult(string $pdfData, float $widthPt, float $heightPt, float $contentHeightPx = 0.0, string $renderLocation = '', float $renderTimeMs = 0.0) | Bytes del PDF, ancho, alto, alto del contenido medido, ubicación en el edge, tiempo de renderizado. | Metadatos vacíos cuando el Worker no los informa. | CloudflareRenderResult | No se espera ninguno. | Suele devolverlo CloudflareResponseParser::parse(). |
CloudflareRenderResult::isValid() | ninguno. | Comprueba que los bytes del PDF no estén vacíos y comiencen con una cabecera de PDF. | bool | No se espera ninguno. | Usarlo antes de archivar o de pasar los bytes a otra capa. |
CloudflareRenderResult::size() | ninguno. | Cuenta los bytes del PDF renderizado. | int | No se espera ninguno. | Pasarlo a la lógica de cuotas y de auditoría. |
new CloudflareRenderPayload(string $html, float $widthPt, float $heightPt = 0, string $defaultCss = '', ?string $r2FontBucket = null, array $fontFiles = []) | HTML, tamaño, CSS, bucket de fuentes en R2 opcional, lista de archivos de fuente. | Alto automático, sin CSS predeterminado, sin bucket de fuentes en R2, sin archivos de fuente. | CloudflareRenderPayload | No se espera ninguno. | Objeto de valor del payload de la solicitud. |
CloudflareRenderPayload::toJson() | ninguno. | Serializa el HTML, el tamaño, el CSS y las referencias de fuentes para el Worker. | string | Errores de codificación JSON. | API de bajo nivel del payload de la solicitud. |
CloudflareResponseParser::parse(ResponseInterface $response, float $requestedWidthPt) | Respuesta del Worker y ancho solicitado. | Acepta respuestas de PDF binario y respuestas de JSON estructurado. | CloudflareRenderResult | CloudflareRenderException ante una salida del Worker fallida o no válida. | Parser central que usa el renderer. |
CloudflareSecurityPolicy::validate(string $html, int $maxSize) | Entrada de HTML y límite de tamaño. | Aplica la política de entrada de HTML del paquete. | void | Excepción de validación. | Mantener las comprobaciones de entrada no confiable fuera del límite del Worker. |
CloudflareSecurityPolicy::validateWorkerUrl(string $url) | URL del Worker. | Analiza y valida el destino. | array | Excepción de validación. | Bloquea las formas de endpoint no seguras antes de la E/S de red. |
CloudflareSecurityPolicy::assertPinsStillValid(string $host, array $pinnedIps) | Host y lista de IP fijadas con pin. | Verifica las expectativas de los pins de DNS. | void | Excepción de validación cuando los pins están obsoletos o no son válidos. | Usarlo durante las comprobaciones operativas de los despliegues con pinning. |
Protección de API
Sección titulada «Protección de API»Usar esta tabla al proteger un endpoint de renderizado: validación de la clave de API, comprobaciones del tamaño del payload y del límite de tasa, y los objetos de result/header que producen.
| Símbolo | Parámetros | Comportamiento predeterminado | Devuelve | Lanza o falla con | Notas |
|---|---|---|---|---|---|
new ApiProtection(ApiProtectionConfig $config, ?ApiKeyValidator $keyValidator = null, ?Closure $clock = null) | Configuración de protección, validador de claves opcional, reloj opcional. | Usa la hora del sistema cuando no se proporciona ningún reloj. | ApiProtection | No se espera ninguno. | Inyectar un reloj determinista en las pruebas. |
ApiProtection::checkRequest(string $clientId, int $payloadSize, string $apiKey = '') | Identificador del cliente, tamaño del payload, clave de API opcional. | Una clave de API vacía solo se permite cuando la configuración no exige claves. | ApiProtectionResult | No se espera ninguno. | Comprueba la clave de API, el tamaño y, después, los límites de tasa. |
ApiProtection::getRateLimit(string $clientId) | Identificador del cliente. | No registra una solicitud. | RateLimitResult | No se espera ninguno. | Usarlo para añadir cabeceras de límite de tasa. |
new ApiKeyValidator(array $validKeys = []) | Lista de claves válidas en texto plano. | Una lista vacía rechaza todas las claves. | ApiKeyValidator | No se espera ninguno. | Almacenar los secretos fuera del código e hidratarlos a través de la configuración. |
ApiKeyValidator::validate(string $key) | Clave en bruto. | Comparación segura frente a ataques de temporización contra las claves en texto plano configuradas. | bool | No se espera ninguno. | Parámetro sensible; no registrar las claves en bruto. |
ApiKeyValidator::addKey(string $key) | Clave en bruto. | Añade una clave hasheada a una nueva instancia del validador. | self | No se espera ninguno. | Tratar la instancia devuelta como el validador actualizado. |
ApiKeyValidator::revokeKey(string $key) | Clave en bruto. | Elimina el hash coincidente de una nueva instancia del validador. | self | No se espera ninguno. | Tratar la instancia devuelta como el validador actualizado. |
ApiKeyValidator::hashKey(string $key) | Clave en bruto. | Produce la representación hash almacenada. | string | No se espera ninguno. | No exponer los hashes en los logs ni en las respuestas al cliente. |
ApiKeyValidator::validateHashed(string $key, array $hashedKeys) | Clave en bruto y hashes candidatos. | Comparación en tiempo constante contra los hashes proporcionados. | bool | No se espera ninguno. | Utilidad de bajo nivel para almacenes de claves personalizados. |
new ApiProtectionConfig(int $maxRequestsPerMinute = 60, int $maxRequestsPerHour = 1000, int $maxPayloadSizeBytes = 10485760, array $allowedOrigins = [], bool $requireApiKey = true, string $apiKeyHeader = 'X-Api-Key', int $rateLimitWindowSeconds = 60) | Límites de solicitudes, límite del payload, orígenes permitidos, requisito de clave de API, nombre de la cabecera, longitud de la ventana. | 60/minute, 1000/hour, payload de 10 MiB, clave de API requerida. | ApiProtectionConfig | No se espera ninguno. | Construirlo directamente en las pruebas o hidratarlo con fromArray(). |
ApiProtectionConfig::fromArray(array $data) | max_requests_per_minute, max_requests_per_hour, max_payload_size_bytes, allowed_origins, require_api_key, api_key_header, rate_limit_window_seconds. | Las claves ausentes usan los valores predeterminados del constructor. | ApiProtectionConfig | No se espera ninguno. | Usarlo para la hidratación de la configuración del framework. |
ApiProtectionConfig::isValid() | ninguno. | Requiere límites positivos y valores coherentes de size/window. | bool | No se espera ninguno. | Validarlo antes de exponer un endpoint. |
new ApiProtectionResult(bool $allowed, string $denialReason = '', ?RateLimitResult $rateLimit = null) | Decisión, motivo de la denegación, resultado del límite de tasa opcional. | Motivo de la denegación vacío y sin resultado del límite de tasa. | ApiProtectionResult | No se espera ninguno. | Lo devuelve ApiProtection::checkRequest(). |
ApiProtectionResult::toHeaders() | ninguno. | Emite cabeceras de límite de tasa cuando existen datos de tasa. | array<string, string> | No se espera ninguno. | Adjuntarlas a las respuestas del Worker o del framework. |
new RateLimitResult(bool $allowed, int $remainingRequests, int $retryAfterSeconds, string $clientId) | Decisión, recuento restante, retardo de reintento, ID del cliente. | Sin valores predeterminados. | RateLimitResult | No se espera ninguno. | Resultado inmutable de una comprobación. |
RateLimitResult::toHeaders() | ninguno. | Emite las cabeceras de límite restante y de reinicio. | array<string, string> | No se espera ninguno. | Usarlo para la observabilidad y el backoff del cliente. |
new RateLimitEntry(string $clientId, int $requestCount = 0, int $windowStart = 0, int $hourlyCount = 0, int $hourlyWindowStart = 0) | ID del cliente y contadores mutables. | Los contadores empiezan en cero. | RateLimitEntry | No se espera ninguno. | Objeto de seguimiento en memoria. |
RateLimitEntry::increment() | ninguno. | Incrementa el contador en memoria de un client/window. | void | No se espera ninguno. | Utilidad de bajo nivel que usa ApiProtection. |
RateLimitEntry::isExpired(int $windowSeconds) | Longitud de la ventana en segundos. | Compara contra la hora actual. | bool | No se espera ninguno. | Utilidad de expiración en tiempo de ejecución. |
RateLimitEntry::isExpiredAt(int $now, int $windowSeconds) | Valor del reloj y longitud de la ventana. | Compara contra el valor del reloj proporcionado. | bool | No se espera ninguno. | Utilidad de pruebas determinista. |
RateLimitEntry::reset() | ninguno. | Reinicia el recuento y la hora de inicio de la ventana. | void | No se espera ninguno. | Se usa cuando comienza una nueva ventana. |
Archivo R2
Sección titulada «Archivo R2»Usar esta tabla al almacenar PDF renderizados en Cloudflare R2: el servicio de archivado, sus tipos de configuración y de clave de objeto, y el resultado de la subida que se inspecciona antes de exponer una URL.
| Símbolo | Parámetros | Comportamiento predeterminado | Devuelve | Lanza o falla con | Notas |
|---|---|---|---|---|---|
new R2ArchiveManager(R2ArchiveConfig $config, ClientInterface $httpClient, RequestFactoryInterface $requestFactory, StreamFactoryInterface $streamFactory) | Configuración de R2 y factories/client HTTP de PSR. | Sin llamadas de red durante la construcción. | R2ArchiveManager | Errores de cableado del contenedor. | Servicio de archivado principal. |
R2ArchiveManager::upload(string $pdfData, string $filename, array $metadata = []) | Bytes del PDF en bruto, nombre de archivo original, metadatos de cadena. | Metadatos vacíos; clave particionada por fecha. | R2UploadResult | Devuelve un resultado sin éxito ante un fallo de configuración, de tamaño, de HTTP o de transporte. | No lanza excepciones por fallos normales de subida. |
R2ArchiveManager::generateSignedUrl(string $key, int $expiresInSeconds = 3600) | Clave de objeto y TTL de la URL. | URL firmada de una hora. | string | Errores de firma por una configuración no válida. | Mantener los TTL cortos para los PDF sensibles. |
R2ArchiveManager::buildObjectKey(string $filename) | Nombre de archivo original. | Usa el prefijo de ruta configurado y la fecha actual. | R2ObjectKey | No se espera ninguno. | Usarlo para una partición predecible del archivo. |
R2ArchiveManager::createPutRequest(R2ObjectKey $key, string $data, array $metadata = []) | Clave de objeto, bytes en bruto, metadatos. | Firma una solicitud PUT. | RequestInterface | Errores de construcción de la solicitud. | API de bajo nivel para transportes personalizados. |
new R2ArchiveConfig(string $bucketName, string $accountId, string $accessKeyId, string $secretAccessKey, string $endpoint = '', string $pathPrefix = 'pdfs/', int $maxFileSizeBytes = 104857600) | Bucket, ID de cuenta, credenciales, sobrescritura del endpoint, prefijo de clave, tamaño máximo de objeto. | Endpoint derivado, prefijo pdfs/, tamaño máximo de objeto de 100 MiB. | R2ArchiveConfig | InvalidArgumentException ante nombres de bucket no válidos. | Tratar las credenciales como configuración que contiene secretos. |
R2ArchiveConfig::fromArray(array $data) | ID de cuenta, bucket, credenciales, prefijo de ruta, sobrescritura del endpoint, tamaño máximo. | Los valores ausentes usan los valores predeterminados del constructor. | R2ArchiveConfig | Nombre de bucket no válido cuando se proporciona. | Usarlo para la hidratación de la configuración de la aplicación. |
R2ArchiveConfig::isValid() | ninguno. | Requiere una cuenta, un bucket, una clave de acceso y una clave secreta no vacías. | bool | No se espera ninguno. | Una configuración no válida hace que las subidas fallen con resultados estructurados. |
R2ArchiveConfig::getEndpoint() | ninguno. | Usa el endpoint explícito o deriva el endpoint de Cloudflare R2 a partir del ID de cuenta. | string | No se espera ninguno. | Se usa para la construcción de solicitudes firmadas. |
new R2ObjectKey(string $key, string $bucket) | Clave de objeto completa y bucket. | Sin normalización. | R2ObjectKey | No se espera ninguno. | Suele crearlo R2ObjectKey::generate(). |
R2ObjectKey::generate(string $prefix, string $filename, ?DateTimeInterface $date = null) | Prefijo, nombre de archivo original, fecha opcional. | Clave de objeto particionada por fecha y saneada. | R2ObjectKey | No se espera ninguno. | Inyectar la fecha en las pruebas para obtener claves deterministas. |
R2ObjectKey::fullPath() | ninguno. | Une la ruta de partición y el nombre de archivo del objeto. | string | No se espera ninguno. | Almacenar este valor como la clave de objeto. |
new R2UploadResult(bool $success, string $key, string $etag = '', int $size = 0, string $error = '') | Indicador de éxito, clave de objeto, ETag, tamaño en bytes, mensaje de error. | ETag vacío, tamaño cero, error vacío. | R2UploadResult | No se espera ninguno. | Lo devuelve R2ArchiveManager::upload(). |
R2UploadResult::isValid() | ninguno. | Es válido cuando la subida tuvo éxito y tanto la clave como el ETag están presentes. | bool | No se espera ninguno. | Comprobarlo antes de exponer las URL. |
R2UploadResult::publicUrl(string $customDomain = '') | Dominio público personalizado opcional. | Devuelve solo la clave de objeto cuando no se proporciona ningún dominio personalizado. | string | No se espera ninguno. | Evitar las URL públicas para documentos sensibles a menos que la política lo permita. |
Utilidades de transporte
Sección titulada «Utilidades de transporte»Usar esta tabla solo para el cableado de bajo nivel: el pinning de IP/SPKI a nivel de cURL y los contratos del renderer local que se emplean como ruta de fallback cuando el Worker es inalcanzable.
| Símbolo | Parámetros | Comportamiento predeterminado | Devuelve | Lanza o falla con | Notas |
|---|---|---|---|---|---|
new PinnedCurlTransport(ResponseFactoryInterface $responseFactory, StreamFactoryInterface $streamFactory, array $pinnedIps = [], array $pinnedPublicKeys = [], int $timeoutSeconds = 30) | Factories de PSR-17, IP fijadas con pin, claves públicas fijadas con pin, timeout. | Sin pins y timeout de 30 segundos. | PinnedCurlTransport | No se espera ninguno. | Usarlo solo cuando se requiere pinning a nivel de cURL. |
PinnedCurlTransport::sendRequest(RequestInterface $request) | Solicitud de PSR-7. | Envía a través de cURL con el timeout configurado y los controles de pinning. | ResponseInterface | Excepciones de transporte de PSR-18. | Usarlo solo cuando los clientes HTTP del framework no pueden aplicar la misma política de pinning. |
PinnedCurlTransport::buildCurlOptions(RequestInterface $request, string $host, int $port) | Solicitud, host de destino, puerto de destino. | Construye el array de opciones de cURL que usa sendRequest(). | array | Errores de solicitud no válida o de configuración de pins. | Hook de bajo nivel para pruebas y diagnósticos. |
LocalRendererInterface::render(string $html, array $options = []) | HTML y opciones del renderer. | Solo contrato; la implementación decide los valores predeterminados. | string | Errores de renderizado específicos de la implementación. | Se usa como fallback local cuando el renderizado en el Worker no está disponible. |
LocalRendererFactoryInterface::create() | ninguno. | Crea una implementación de renderer local. | LocalRendererInterface | Errores de la factory o de dependencias. | Mantiene la construcción del renderer de fallback fuera de CloudflareHtmlRenderer. |
Notas de desarrollo
Sección titulada «Notas de desarrollo»- Tratar la URL del Worker como un límite de red. Validar el destino, el tamaño y la autenticación antes de renderizar.
- Usar los resultados de la protección de API como salidas de política, no como flujo de control de excepciones.
- Las subidas a R2 devuelven resultados estructurados de éxito o de error; gestionar ambas rutas.