Riferimento alle API Cloudflare
In breve
Sezione intitolata “In breve”Il package NextPDF\Cloudflare è un ponte per il rendering edge: il processo PHP gestisce l’HTML, mentre un Cloudflare Worker gestisce il browser headless. Il package espone un renderer HTML basato su Worker (CloudflareHtmlRenderer) e i value object che restituisce, uno strato di protezione delle richieste per mettere in sicurezza gli endpoint di rendering (ApiProtection), un servizio di archiviazione R2 per memorizzare i PDF generati (R2ArchiveManager) e helper di trasporto con pinning per l’hardening di TLS/DNS. La configurazione risiede in tre oggetti immutabili (CloudflareRendererConfig, ApiProtectionConfig, R2ArchiveConfig).
Da dove iniziare: se si usa il package per la prima volta, creare un CloudflareRendererConfig, collegarlo a CloudflareHtmlRenderer e chiamare render(). Questa singola chiamata invia l’HTML al Worker e restituisce un CloudflareRenderResult con i byte del PDF. Tutto il resto (protezione, archiviazione, pinning) ruota attorno a quella chiamata.
Attività comuni
Sezione intitolata “Attività comuni”Gli snippet seguenti rappresentano i flussi di lavoro reali più frequenti per questo package. Ciascuno è autonomo, verificato rispetto al codice sorgente in src/Cloudflare/ e legge i segreti dall’ambiente.
Eseguire il rendering di una stringa HTML in un PDF all’edge: la sola chiamata di rendering canonica:
<?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);}Cosa fa: invia l’HTML al Worker tramite HTTPS e scrive su disco i byte del PDF A4 restituito, dopo che isValid() ha confermato che si tratta di un PDF reale.
Archiviare un PDF generato in R2 e restituire un link a breve durata:
<?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;Cosa fa: carica i byte del PDF in una chiave R2 partizionata per data e, in caso di esito positivo, genera un URL prefirmato valido 10 minuti per il download temporaneo.
Proteggere un endpoint di rendering prima di eseguire operazioni Worker onerose:
<?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];}Cosa fa: convalida la chiave API, la dimensione del payload e poi il limite di frequenza per client, restituendo una singola decisione insieme alle intestazioni di risposta da allegare quando la richiesta viene rifiutata.
Renderer
Sezione intitolata “Renderer”La tabella Renderer descrive la superficie principale. Usarla quando si costruisce la configurazione, si crea il renderer o si eseguono chiamate di rendering e di raggiungibilità.
| Simbolo | Parametri | Comportamento predefinito | Valore restituito | Eccezioni o errori | Note |
|---|---|---|---|---|---|
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, bearer token, timeout, CSS, limite di dimensione, bucket di font R2 facoltativo, flag di fallback, set di pin. | Il fallback locale è abilitato; il pinning è disabilitato quando gli array di pin sono vuoti. | CloudflareRendererConfig | nessuna prevista. | Mantenere segreto il token API; preferire URL HTTPS del Worker. |
CloudflareRendererConfig::fromArray(array $config) | worker_url, api_token, render_timeout, default_css, max_html_size, r2_font_bucket, fallback_to_local, array di pin. | Le chiavi facoltative mancanti usano i valori predefiniti del costruttore. | CloudflareRendererConfig | nessuna prevista. | Corrisponde agli array di configurazione in stile framework. |
CloudflareRendererConfig::isValid() | nessuna. | Richiede un URL del Worker e un token API non vuoti. | bool | nessuna prevista. | Una configurazione non valida attiva il fallback o un errore nel renderer. |
CloudflareRendererConfig::allPublicKeyPins() | nessuna. | Combina i pin della chiave pubblica primaria e di backup. | list<string> | nessuna prevista. | Un elenco vuoto disabilita il pinning. |
new CloudflareHtmlRenderer(CloudflareRendererConfig $config, ClientInterface $httpClient, RequestFactoryInterface $requestFactory, StreamFactoryInterface $streamFactory, ?LoggerInterface $logger = null, ?LocalRendererFactoryInterface $localRendererFactory = null, ?HtmlSecurityPolicyInterface $htmlSecurityPolicy = null, ?ResponseFactoryInterface $responseFactory = null) | Configurazione, dipendenze HTTP PSR, logger facoltativo, factory di fallback locale facoltativa, policy HTML facoltativa, factory di risposta facoltativa. | Usa DefaultHtmlSecurityPolicy quando non viene fornita alcuna policy HTML. | CloudflareHtmlRenderer | Errori di wiring del container. | La factory di risposta abilita il trasporto cURL con pinning quando richiesto. |
CloudflareHtmlRenderer::render(string $html, float $widthPt = 595.28, float $heightPt = 0, array $fontFiles = []) | HTML, larghezza pagina, altezza pagina, file di font in R2. | Larghezza A4; altezza automatica; nessun file di font. | CloudflareRenderResult | CloudflareNotAvailableException, CloudflareRenderException, validation failures. | Convalida la dimensione dell’HTML e l’URL del Worker prima dell’I/O di rete. |
CloudflareHtmlRenderer::getHtmlSecurityPolicy() | nessuna. | Restituisce la policy configurata a livello di parsing. | HtmlSecurityPolicyInterface | nessuna prevista. | Usare insieme alla protezione degli endpoint e alla convalida dell’URL del Worker. |
CloudflareHtmlRenderer::isAvailable() | nessuna. | Richiesta HEAD al Worker quando la configurazione è valida. | bool | Restituisce false in caso di errori. | Usare per i controlli di prontezza, non come unica protezione a runtime. |
Value object del renderer e sicurezza
Sezione intitolata “Value object del renderer e sicurezza”Usare questa tabella quando servono i value object request/result (CloudflareRenderResult, CloudflareRenderPayload) o i controlli statici a livello di trasporto che convalidano l’HTML, l’URL del Worker e i pin DNS prima di qualsiasi I/O di rete.
| Simbolo | Parametri | Comportamento predefinito | Valore restituito | Eccezioni o errori | Note |
|---|---|---|---|---|---|
new CloudflareRenderResult(string $pdfData, float $widthPt, float $heightPt, float $contentHeightPx = 0.0, string $renderLocation = '', float $renderTimeMs = 0.0) | Byte del PDF, larghezza, altezza, altezza del contenuto misurata, posizione edge, tempo di rendering. | Metadati vuoti quando il Worker non li riporta. | CloudflareRenderResult | nessuna prevista. | Solitamente restituito da CloudflareResponseParser::parse(). |
CloudflareRenderResult::isValid() | nessuna. | Verifica la presenza di byte PDF non vuoti che iniziano con un’intestazione PDF. | bool | nessuna prevista. | Usare prima di archiviare o passare i byte a un altro livello. |
CloudflareRenderResult::size() | nessuna. | Conta i byte del PDF generato. | int | nessuna prevista. | Inserire questo valore nella logica di quota e audit. |
new CloudflareRenderPayload(string $html, float $widthPt, float $heightPt = 0, string $defaultCss = '', ?string $r2FontBucket = null, array $fontFiles = []) | HTML, dimensione, CSS, bucket di font R2 facoltativo, elenco di file di font. | Altezza automatica, nessun CSS predefinito, nessun bucket di font R2, nessun file di font. | CloudflareRenderPayload | nessuna prevista. | Value object del payload di richiesta. |
CloudflareRenderPayload::toJson() | nessuna. | Serializza HTML, dimensione, CSS e riferimenti ai font per il Worker. | string | Errori di codifica JSON. | API di basso livello per il payload di richiesta. |
CloudflareResponseParser::parse(ResponseInterface $response, float $requestedWidthPt) | Risposta del Worker e larghezza richiesta. | Accetta risposte PDF binarie e risposte JSON strutturate. | CloudflareRenderResult | CloudflareRenderException per output del Worker non riuscito o non valido. | Parser centrale utilizzato dal renderer. |
CloudflareSecurityPolicy::validate(string $html, int $maxSize) | Input HTML e limite di dimensione. | Applica la policy di input HTML del package. | void | Eccezione di convalida. | Mantenere i controlli sull’input non attendibile fuori dal confine del Worker. |
CloudflareSecurityPolicy::validateWorkerUrl(string $url) | URL del Worker. | Analizza e convalida la destinazione. | array | Eccezione di convalida. | Blocca le forme di endpoint non sicure prima dell’I/O di rete. |
CloudflareSecurityPolicy::assertPinsStillValid(string $host, array $pinnedIps) | Host ed elenco di IP con pinning. | Verifica le aspettative dei pin DNS. | void | Eccezione di convalida quando i pin sono obsoleti o non validi. | Usare durante i controlli operativi per i deployment con pinning. |
Protezione API
Sezione intitolata “Protezione API”Usare questa tabella per proteggere un endpoint di rendering: convalida della chiave API, controlli sulla dimensione del payload e sul limite di frequenza, e gli oggetti result/header prodotti.
| Simbolo | Parametri | Comportamento predefinito | Valore restituito | Eccezioni o errori | Note |
|---|---|---|---|---|---|
new ApiProtection(ApiProtectionConfig $config, ?ApiKeyValidator $keyValidator = null, ?Closure $clock = null) | Configurazione di protezione, validatore di chiavi facoltativo, clock facoltativo. | Utilizza l’ora di sistema quando non viene fornito alcun clock. | ApiProtection | nessuna prevista. | Iniettare un clock deterministico nei test. |
ApiProtection::checkRequest(string $clientId, int $payloadSize, string $apiKey = '') | Identificatore client, dimensione del payload, chiave API facoltativa. | Una chiave API vuota è consentita solo quando la configurazione non richiede chiavi. | ApiProtectionResult | nessuna prevista. | Controlla la chiave API, la dimensione e quindi i limiti di frequenza. |
ApiProtection::getRateLimit(string $clientId) | Identificatore client. | Non registra una richiesta. | RateLimitResult | nessuna prevista. | Usare per aggiungere le intestazioni del limite di frequenza. |
new ApiKeyValidator(array $validKeys = []) | Elenco di chiavi valide in testo non cifrato. | Un elenco vuoto rifiuta tutte le chiavi. | ApiKeyValidator | nessuna prevista. | Memorizzare i segreti al di fuori del codice e idratarli tramite la configurazione. |
ApiKeyValidator::validate(string $key) | Chiave non elaborata. | Confronto timing-safe rispetto alle chiavi in testo non cifrato configurate. | bool | nessuna prevista. | Parametro sensibile; non registrare chiavi non elaborate. |
ApiKeyValidator::addKey(string $key) | Chiave non elaborata. | Aggiunge una chiave con hash a una nuova istanza del validatore. | self | nessuna prevista. | Considerare l’istanza restituita come il validatore aggiornato. |
ApiKeyValidator::revokeKey(string $key) | Chiave non elaborata. | Rimuove l’hash corrispondente da una nuova istanza del validatore. | self | nessuna prevista. | Considerare l’istanza restituita come il validatore aggiornato. |
ApiKeyValidator::hashKey(string $key) | Chiave non elaborata. | Produce la rappresentazione hash memorizzata. | string | nessuna prevista. | Non esporre gli hash nei log o nelle risposte al client. |
ApiKeyValidator::validateHashed(string $key, array $hashedKeys) | Chiave non elaborata e hash candidati. | Confronto a tempo costante rispetto agli hash forniti. | bool | nessuna prevista. | Helper di basso livello per archivi di chiavi personalizzati. |
new ApiProtectionConfig(int $maxRequestsPerMinute = 60, int $maxRequestsPerHour = 1000, int $maxPayloadSizeBytes = 10485760, array $allowedOrigins = [], bool $requireApiKey = true, string $apiKeyHeader = 'X-Api-Key', int $rateLimitWindowSeconds = 60) | Limiti di richieste, limite del payload, origini consentite, requisito della chiave API, nome dell’intestazione, lunghezza della finestra. | 60/minute, 1000/hour, payload da 10 MiB, chiave API richiesta. | ApiProtectionConfig | nessuna prevista. | Costruire direttamente nei test o idratare tramite 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. | Le chiavi mancanti usano i valori predefiniti del costruttore. | ApiProtectionConfig | nessuna prevista. | Usare per idratare la configurazione del framework. |
ApiProtectionConfig::isValid() | nessuna. | Richiede limiti positivi e valori size/window coerenti. | bool | nessuna prevista. | Convalidare prima di esporre un endpoint. |
new ApiProtectionResult(bool $allowed, string $denialReason = '', ?RateLimitResult $rateLimit = null) | Decisione, motivo del rifiuto, risultato del limite di frequenza facoltativo. | Motivo del rifiuto vuoto e nessun risultato del limite di frequenza. | ApiProtectionResult | nessuna prevista. | Restituito da ApiProtection::checkRequest(). |
ApiProtectionResult::toHeaders() | nessuna. | Emette le intestazioni del limite di frequenza quando sono presenti dati sulla frequenza. | array<string, string> | nessuna prevista. | Allegare alle risposte del Worker o del framework. |
new RateLimitResult(bool $allowed, int $remainingRequests, int $retryAfterSeconds, string $clientId) | Decisione, conteggio rimanente, ritardo per il nuovo tentativo, ID client. | Nessun valore predefinito. | RateLimitResult | nessuna prevista. | Risultato immutabile per un singolo controllo. |
RateLimitResult::toHeaders() | nessuna. | Emette le intestazioni del limite rimanente e di reset. | array<string, string> | nessuna prevista. | Usare per l’osservabilità e il backoff del client. |
new RateLimitEntry(string $clientId, int $requestCount = 0, int $windowStart = 0, int $hourlyCount = 0, int $hourlyWindowStart = 0) | ID client e contatori modificabili. | I contatori iniziano da zero. | RateLimitEntry | nessuna prevista. | Oggetto di tracciamento in memoria. |
RateLimitEntry::increment() | nessuna. | Incrementa il contatore in memoria per un singolo client/window. | void | nessuna prevista. | Helper di basso livello usato da ApiProtection. |
RateLimitEntry::isExpired(int $windowSeconds) | Lunghezza della finestra in secondi. | Confronta rispetto all’ora corrente. | bool | nessuna prevista. | Helper di scadenza a runtime. |
RateLimitEntry::isExpiredAt(int $now, int $windowSeconds) | Valore del clock e lunghezza della finestra. | Confronta rispetto al valore del clock fornito. | bool | nessuna prevista. | Helper di test deterministico. |
RateLimitEntry::reset() | nessuna. | Reimposta il conteggio e l’ora di inizio della finestra. | void | nessuna prevista. | Usato all’inizio di una nuova finestra. |
Archivio R2
Sezione intitolata “Archivio R2”Usare questa tabella per memorizzare i PDF generati in Cloudflare R2: il servizio di archiviazione, i relativi tipi di configurazione e chiave dell’oggetto, e il risultato del caricamento da esaminare prima di esporre un URL.
| Simbolo | Parametri | Comportamento predefinito | Valore restituito | Eccezioni o errori | Note |
|---|---|---|---|---|---|
new R2ArchiveManager(R2ArchiveConfig $config, ClientInterface $httpClient, RequestFactoryInterface $requestFactory, StreamFactoryInterface $streamFactory) | Configurazione R2 e factory/client HTTP PSR. | Nessuna chiamata di rete durante la costruzione. | R2ArchiveManager | Errori di wiring del container. | Servizio di archiviazione principale. |
R2ArchiveManager::upload(string $pdfData, string $filename, array $metadata = []) | Byte del PDF non elaborati, nome file originale, metadati stringa. | Metadati vuoti; chiave partizionata per data. | R2UploadResult | Restituisce un risultato non riuscito in caso di errore di configurazione, dimensione, HTTP o trasporto. | Non genera eccezioni per un normale errore di caricamento. |
R2ArchiveManager::generateSignedUrl(string $key, int $expiresInSeconds = 3600) | Chiave dell’oggetto e TTL dell’URL. | URL firmato di un’ora. | string | Errori di firma derivanti da una configurazione non valida. | Mantenere TTL brevi per i PDF sensibili. |
R2ArchiveManager::buildObjectKey(string $filename) | Nome file originale. | Usa il prefisso del percorso configurato e la data corrente. | R2ObjectKey | nessuna prevista. | Usare per un partizionamento prevedibile dell’archivio. |
R2ArchiveManager::createPutRequest(R2ObjectKey $key, string $data, array $metadata = []) | Chiave dell’oggetto, byte non elaborati, metadati. | Firma una richiesta PUT. | RequestInterface | Errori di costruzione della richiesta. | API di basso livello per trasporti personalizzati. |
new R2ArchiveConfig(string $bucketName, string $accountId, string $accessKeyId, string $secretAccessKey, string $endpoint = '', string $pathPrefix = 'pdfs/', int $maxFileSizeBytes = 104857600) | Bucket, ID account, credenziali, override dell’endpoint, prefisso della chiave, dimensione massima dell’oggetto. | Endpoint derivato, prefisso pdfs/, dimensione massima dell’oggetto di 100 MiB. | R2ArchiveConfig | InvalidArgumentException per nomi di bucket non validi. | Considerare le credenziali come configurazione contenente segreti. |
R2ArchiveConfig::fromArray(array $data) | ID account, bucket, credenziali, prefisso del percorso, override dell’endpoint, dimensione massima. | I valori mancanti usano i valori predefiniti del costruttore. | R2ArchiveConfig | Nome di bucket non valido quando fornito. | Usare per idratare la configurazione dell’applicazione. |
R2ArchiveConfig::isValid() | nessuna. | Richiede account, bucket, access key e secret key non vuoti. | bool | nessuna prevista. | Una configurazione non valida fa fallire i caricamenti con risultati strutturati. |
R2ArchiveConfig::getEndpoint() | nessuna. | Usa l’endpoint esplicito o deriva l’endpoint Cloudflare R2 dall’ID account. | string | nessuna prevista. | Usato per costruire le richieste firmate. |
new R2ObjectKey(string $key, string $bucket) | Chiave completa dell’oggetto e bucket. | Nessuna normalizzazione. | R2ObjectKey | nessuna prevista. | Solitamente creato da R2ObjectKey::generate(). |
R2ObjectKey::generate(string $prefix, string $filename, ?DateTimeInterface $date = null) | Prefisso, nome file originale, data facoltativa. | Chiave dell’oggetto partizionata per data e sanificata. | R2ObjectKey | nessuna prevista. | Iniettare la data nei test per ottenere chiavi deterministiche. |
R2ObjectKey::fullPath() | nessuna. | Unisce il percorso di partizione e il nome file dell’oggetto. | string | nessuna prevista. | Memorizzare questo valore come chiave dell’oggetto. |
new R2UploadResult(bool $success, string $key, string $etag = '', int $size = 0, string $error = '') | Flag di esito positivo, chiave dell’oggetto, ETag, dimensione in byte, messaggio di errore. | ETag vuoto, dimensione zero, errore vuoto. | R2UploadResult | nessuna prevista. | Restituito da R2ArchiveManager::upload(). |
R2UploadResult::isValid() | nessuna. | Valido quando il caricamento è riuscito e sono presenti sia la chiave sia l’ETag. | bool | nessuna prevista. | Verificare prima di esporre URL. |
R2UploadResult::publicUrl(string $customDomain = '') | Dominio pubblico personalizzato facoltativo. | Restituisce la sola chiave dell’oggetto quando non viene fornito alcun dominio personalizzato. | string | nessuna prevista. | Evitare URL pubblici per i documenti sensibili, a meno che la policy non lo consenta. |
Helper di trasporto
Sezione intitolata “Helper di trasporto”Usare questa tabella solo per il wiring di basso livello: pinning IP/SPKI a livello di cURL e contratti del renderer locale usati come percorso di fallback quando il Worker non è raggiungibile.
| Simbolo | Parametri | Comportamento predefinito | Valore restituito | Eccezioni o errori | Note |
|---|---|---|---|---|---|
new PinnedCurlTransport(ResponseFactoryInterface $responseFactory, StreamFactoryInterface $streamFactory, array $pinnedIps = [], array $pinnedPublicKeys = [], int $timeoutSeconds = 30) | Factory PSR-17, IP con pinning, chiavi pubbliche con pinning, timeout. | Nessun pin e timeout di 30 secondi. | PinnedCurlTransport | nessuna prevista. | Utilizzare solo quando è richiesto il pinning a livello di cURL. |
PinnedCurlTransport::sendRequest(RequestInterface $request) | Richiesta PSR-7. | Invia tramite cURL con il timeout configurato e i controlli di pinning. | ResponseInterface | Eccezioni di trasporto PSR-18. | Usare solo quando i client HTTP del framework non possono applicare la stessa policy di pinning. |
PinnedCurlTransport::buildCurlOptions(RequestInterface $request, string $host, int $port) | Richiesta, host di destinazione, porta di destinazione. | Costruisce l’array di opzioni cURL utilizzato da sendRequest(). | array | Errori di richiesta non valida o di configurazione dei pin. | Hook di basso livello per test e diagnostica. |
LocalRendererInterface::render(string $html, array $options = []) | HTML e opzioni del renderer. | Solo contratto; l’implementazione decide i valori predefiniti. | string | Errori di rendering specifici dell’implementazione. | Usato come fallback locale quando il rendering del Worker non è disponibile. |
LocalRendererFactoryInterface::create() | nessuna. | Crea un’implementazione del renderer locale. | LocalRendererInterface | Errori di factory o di dipendenza. | Mantiene la costruzione del renderer di fallback al di fuori di CloudflareHtmlRenderer. |
Note di sviluppo
Sezione intitolata “Note di sviluppo”- Considerare l’URL del Worker come un confine di rete. Convalidare destinazione, dimensione e autenticazione prima del rendering.
- Usare i risultati della protezione API come output di policy, non come flusso di controllo delle eccezioni.
- I caricamenti R2 restituiscono risultati strutturati di esito positivo o di errore; gestire entrambi i percorsi.