Перейти к содержимому

Настройка моста NextPDF для Cloudflare

Работой пакета управляют три неизменяемых объекта конфигурации. Каждое значение по умолчанию на этой странице взято из соответствующей сигнатуры конструктора в src/Cloudflare/. Оно не взято из спецификации и не является оценкой. Если на этой странице указан максимум, это предел, который применяет данный пакет. Это не утверждение о возможностях платформы Cloudflare.

Конфигурация отрисовщика. final readonly. Создайте её напрямую или через CloudflareRendererConfig::fromArray().

ПолеТипПо умолчаниюЗначение
workerUrlstring— (обязательно)URL конечной точки Worker. Должен использовать HTTPS.
apiTokenstring— (обязательно)Bearer-токен. Помечен #[SensitiveParameter].
renderTimeoutint30Таймаут передачи в секундах, который применяет закреплённый транспорт cURL.
defaultCssstring''CSS, внедряемый в полезную нагрузку перед вашим HTML.
maxHtmlSizeint5000000Максимальный размер входного HTML в байтах, проверяемый до отправки запроса.
r2FontBucket?stringnullИмя бакета R2 для пользовательских наборов шрифтов.
fallbackToLocalbooltrueПереключается ли недоступный Worker на локальный отрисовщик.
pinnedPublicKeyslist<string>[]Отпечатки SPKI по SHA-256 в формате sha256/<base64>.
backupPublicKeyslist<string>[]Резервные SPKI-пины, которые хранятся отдельно, чтобы ротация проверялась независимо.

isValid() возвращает true только когда workerUrl !== '' и apiToken !== ''. allPublicKeyPins() возвращает объединение pinnedPublicKeys и backupPublicKeys без дубликатов. Уровень TLS принимает сертификат, если его хеш SPKI есть в любом элементе этого объединения. Это соответствует RFC 7469 §2.6: закреплённое соединение считается корректным, когда множество предъявленных отпечатков SPKI пересекается с закреплённым множеством. RFC 7469 §2.5 описывает резервный пин как основной механизм восстановления при непреднамеренном сбое проверки пина. Сохраняйте хотя бы один резервный пин, чтобы ротация сертификата не нарушила работу конечной точки — см. /integrations/cloudflare/security-and-operations/.

CloudflareRendererConfig::fromArray() считывает ключи в snake_case и применяет те же значения по умолчанию, если ключ отсутствует или у него неверный тип:

Ключ массиваСопоставляется с
worker_urlworkerUrl
api_tokenapiToken
render_timeoutrenderTimeout (по умолчанию 30)
default_cssdefaultCss
max_html_sizemaxHtmlSize (по умолчанию 5000000)
r2_font_bucketr2FontBucket
fallback_to_localfallbackToLocal (по умолчанию true)
pinned_public_keyspinnedPublicKeys (нестроковые элементы отбрасываются)
backup_public_keysbackupPublicKeys (нестроковые элементы отбрасываются)
<?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='],
]);

Ограничения размера входных данных, применяемые пакетом

Заголовок раздела «Ограничения размера входных данных, применяемые пакетом»

Эти ограничения применяются методом CloudflareSecurityPolicy::validate() до того, как любой запрос покинет процесс. Числа взяты из исходного кода:

ОграничениеЗначениеГде
Максимальный входной HTMLmaxHtmlSize (по умолчанию 5000000 байт)CloudflareSecurityPolicy::validate()
Максимальный размер декодированного data-URI в base6413631488 байт (≈13 MB)CloudflareSecurityPolicy::MAX_DATA_URI_BYTES

Превышение любого ограничения приводит к RuntimeException с сообщением, где указаны превышенный размер и предел. Порог base64 защищает от декомпрессионной бомбы. Политика оценивает декодированный размер по длине base64 и отклоняет данные на этом пороге или выше него. Тег <meta http-equiv="refresh"> также отклоняется без учёта регистра, поскольку может вызвать перенаправление изнутри отрисованной страницы.

Пакет указывает только те ограничения, которые применяет сам. Он не делает никаких утверждений о собственных пределах Worker по запросам, ЦП или памяти. За ними обратитесь к официальной документации Cloudflare и реализации вашего Worker.

Конфигурация необязательного уровня защиты запросов, который Worker — или PHP-шлюз перед ним — применяет к входящим запросам на отрисовку. final readonly.

ПолеТипПо умолчаниюЗначение
maxRequestsPerMinuteint60Лимит запросов на клиента в минуту.
maxRequestsPerHourint1000Лимит запросов на клиента в час.
maxPayloadSizeBytesint10485760Максимальная входящая полезная нагрузка (≈10 MB).
allowedOriginslist<string>[]Список разрешённых источников для CORS. Пустое значение означает, что здесь не выражено никакого ограничения по источнику.
requireApiKeybooltrueТребуется ли ключ API.
apiKeyHeaderstring'X-Api-Key'Заголовок, в котором передаётся ключ API.
rateLimitWindowSecondsint60Длина минутного окна, в секундах.

fromArray() считывает max_requests_per_minute, max_requests_per_hour, max_payload_size_bytes, allowed_origins, require_api_key, api_key_header и rate_limit_window_seconds. isValid() требует, чтобы каждое числовое поле было положительным, а apiKeyHeader — непустым.

Конфигурация для архивирования отрисованных PDF в Cloudflare R2 через S3-совместимый API. final readonly.

ПолеТипПо умолчаниюЗначение
bucketNamestring— (обязательно)Бакет R2. Проверяется по правилу именования S3.
accountIdstring— (обязательно)Идентификатор аккаунта Cloudflare, используемый для построения конечной точки по умолчанию.
accessKeyIdstring— (обязательно)Идентификатор ключа доступа R2. #[SensitiveParameter].
secretAccessKeystring— (обязательно)Секретный ключ доступа R2. #[SensitiveParameter].
endpointstring''Пользовательская конечная точка S3. Пустое значение строит конечную точку по умолчанию из accountId.
pathPrefixstring'pdfs/'Префикс ключа для загружаемых объектов.
maxFileSizeBytesint104857600Максимальный размер загрузки (≈100 MB), проверяемый до загрузки.

Конструктор отклоняет непустой bucketName, если он не соответствует S3-совместимому правилу: от 3 до 63 символов, строчные буквенно-цифровые символы и дефисы, начало и конец — буквенно-цифровой символ. Нарушение приводит к InvalidArgumentException. isValid() требует, чтобы bucketName, accountId, accessKeyId и secretAccessKey были непустыми. Когда endpoint пуст, getEndpoint() возвращает https://<accountId>.r2.cloudflarestorage.com.

apiToken, accessKeyId и secretAccessKey имеют атрибут #[SensitiveParameter], поэтому PHP скрывает их в трассировках стека. Передавайте их из переменных окружения или менеджера секретов. Никогда не фиксируйте их в репозитории. Объекты конфигурации неизменяемы: заданное при создании значение нельзя изменить позже.

  • /integrations/cloudflare/quickstart/ — применение этой конфигурации при первой отрисовке.
  • /integrations/cloudflare/production-usage/ — резервный режим, архивирование в R2 и защита API в одной связке.
  • /integrations/cloudflare/security-and-operations/ — закрепление, защита от SSRF и ротация секретов.