Pular para o conteúdo

Configurar a ponte Cloudflare no NextPDF

O pacote é governado por três objetos de configuração imutáveis. Cada padrão nesta página é lido da assinatura do construtor correspondente em src/Cloudflare/. Ele não vem de uma especificação nem de uma estimativa. Quando esta página informa um máximo, esse máximo é um limite que este pacote impõe. Não é uma afirmação sobre a capacidade da plataforma Cloudflare.

A configuração do renderizador. final readonly. Instancie-a diretamente ou com CloudflareRendererConfig::fromArray().

CampoTipoPadrãoSignificado
workerUrlstring— (obrigatório)URL do endpoint do Worker. Deve ser HTTPS.
apiTokenstring— (obrigatório)Token Bearer. Marcado com #[SensitiveParameter].
renderTimeoutint30Timeout de transferência em segundos, aplicado pelo transporte cURL fixado.
defaultCssstring''CSS injetado no payload antes do HTML.
maxHtmlSizeint5000000Tamanho máximo da entrada HTML, em bytes, imposto antes do envio da requisição.
r2FontBucket?stringnullNome do bucket R2 para pacotes de fontes personalizadas.
fallbackToLocalbooltrueSe um Worker inacessível deve recorrer a um renderizador local.
pinnedPublicKeyslist<string>[]Fingerprints SPKI SHA-256, formato sha256/<base64>.
backupPublicKeyslist<string>[]Pins SPKI de backup, mantidos separados para que a rotação seja validada de forma independente.

isValid() retorna true somente quando workerUrl !== '' e apiToken !== ''. allPublicKeyPins() retorna a união desduplicada de pinnedPublicKeys e backupPublicKeys. A camada TLS aceita um certificado cujo hash SPKI apareça em qualquer membro dessa união. Isso corresponde ao RFC 7469 §2.6, que valida uma conexão fixada quando o conjunto de fingerprints SPKI apresentados faz interseção com o conjunto fixado. O RFC 7469 §2.5 descreve o pin de backup como o principal mecanismo de recuperação contra falhas acidentais na validação de pin. Mantenha pelo menos um pin de backup para que uma rotação de certificado não quebre o endpoint — consulte /integrations/cloudflare/security-and-operations/.

CloudflareRendererConfig::fromArray() lê chaves snake_case e aplica os mesmos padrões quando uma chave está ausente ou é do tipo errado:

Chave do arrayMapeia para
worker_urlworkerUrl
api_tokenapiToken
render_timeoutrenderTimeout (padrão 30)
default_cssdefaultCss
max_html_sizemaxHtmlSize (padrão 5000000)
r2_font_bucketr2FontBucket
fallback_to_localfallbackToLocal (padrão true)
pinned_public_keyspinnedPublicKeys (membros que não são string são descartados)
backup_public_keysbackupPublicKeys (membros que não são string são descartados)
<?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='],
]);

Esses limites são impostos por CloudflareSecurityPolicy::validate() antes que qualquer requisição saia do processo. Os números são lidos do código-fonte:

LimiteValorOnde
Entrada HTML máximamaxHtmlSize (padrão 5000000 bytes)CloudflareSecurityPolicy::validate()
Tamanho máximo do data-URI base64 decodificado13631488 bytes (≈13 MB)CloudflareSecurityPolicy::MAX_DATA_URI_BYTES

Exceder qualquer um deles gera uma RuntimeException com uma mensagem que informa o tamanho infrator e o limite. O teto de base64 é uma proteção contra bombas de descompressão. A política estima o tamanho decodificado a partir do comprimento do base64 e rejeita a entrada ao atingir ou ultrapassar o teto. Uma tag <meta http-equiv="refresh"> também é rejeitada, sem diferenciar maiúsculas de minúsculas, porque pode acionar um redirecionamento de dentro da página renderizada.

O pacote informa apenas os limites que ele próprio impõe. Ele não faz nenhuma afirmação sobre os tetos de requisição, CPU ou memória do próprio Worker. Consulte a documentação oficial da Cloudflare e a implementação do seu Worker para esses limites.

Configuração da camada opcional de proteção de requisições que um Worker — ou um gateway PHP à frente dele — aplica às requisições de renderização recebidas. final readonly.

CampoTipoPadrãoSignificado
maxRequestsPerMinuteint60Teto de requisições por cliente por minuto.
maxRequestsPerHourint1000Teto de requisições por cliente por hora.
maxPayloadSizeBytesint10485760Carga útil máxima de entrada (≈10 MB).
allowedOriginslist<string>[]Lista de permissões CORS. Quando vazia, nenhuma restrição de origem é expressa aqui.
requireApiKeybooltrueSe uma chave de API é obrigatória.
apiKeyHeaderstring'X-Api-Key'Cabeçalho que transporta a chave de API.
rateLimitWindowSecondsint60Duração da janela por minuto, em segundos.

fromArray()max_requests_per_minute, max_requests_per_hour, max_payload_size_bytes, allowed_origins, require_api_key, api_key_header e rate_limit_window_seconds. isValid() exige que todos os campos numéricos sejam positivos e que apiKeyHeader não seja vazio.

Configuração para arquivar PDFs renderizados no Cloudflare R2 via API compatível com S3. final readonly.

CampoTipoPadrãoSignificado
bucketNamestring— (obrigatório)Bucket R2. Validado conforme a regra de nomenclatura do S3.
accountIdstring— (obrigatório)ID da conta Cloudflare, usado para construir o endpoint padrão.
accessKeyIdstring— (obrigatório)ID da chave de acesso R2. #[SensitiveParameter].
secretAccessKeystring— (obrigatório)Chave de acesso secreta R2. #[SensitiveParameter].
endpointstring''Endpoint S3 personalizado. Vazio constrói o padrão a partir de accountId.
pathPrefixstring'pdfs/'Prefixo de chave dos objetos enviados.
maxFileSizeBytesint104857600Tamanho máximo de upload (≈100 MB), imposto antes do upload.

O construtor rejeita um bucketName não vazio que não corresponda à regra compatível com S3. A regra exige: 3 a 63 caracteres, alfanuméricos minúsculos e hifens, começando e terminando com um alfanumérico. Uma violação gera InvalidArgumentException. isValid() exige que bucketName, accountId, accessKeyId e secretAccessKey não sejam vazios. Quando endpoint está vazio, getEndpoint() retorna https://<accountId>.r2.cloudflarestorage.com.

apiToken, accessKeyId e secretAccessKey carregam o atributo #[SensitiveParameter], de modo que o PHP os oculta dos stack traces. Forneça esses valores por variáveis de ambiente ou por um gerenciador de segredos. Nunca faça commit deles. Os objetos de configuração são imutáveis, portanto um valor definido uma vez não pode ser alterado após a construção.

  • /integrations/cloudflare/quickstart/ — aplique esta configuração na primeira renderização.
  • /integrations/cloudflare/production-usage/ — fallback, arquivamento em R2 e proteção de API integrados.
  • /integrations/cloudflare/security-and-operations/ — pinning, defesa contra SSRF e rotação de segredos.