콘텐츠로 이동

NextPDF Cloudflare 브리지 구성

세 개의 불변 구성 객체가 패키지 동작을 제어합니다. 이 페이지의 모든 기본값은 src/Cloudflare/의 해당 생성자 시그니처에서 가져온 것이며, 명세나 추정값을 기준으로 하지 않습니다. 이 페이지에서 최댓값을 명시하는 경우, 그 최댓값은 이 패키지가 적용하는 제한입니다. Cloudflare 플랫폼 용량에 대한 진술이 아닙니다.

렌더러 구성입니다. final readonly이며, 직접 생성하거나 CloudflareRendererConfig::fromArray()로 생성합니다.

필드타입기본값의미
workerUrlstring— (필수)Worker 엔드포인트 URL입니다. HTTPS여야 합니다.
apiTokenstring— (필수)Bearer 토큰입니다. #[SensitiveParameter]로 표시됩니다.
renderTimeoutint30고정된 cURL 전송에서 적용하는 전송 타임아웃(초)입니다.
defaultCssstring''페이로드에서 HTML 앞에 주입되는 CSS입니다.
maxHtmlSizeint5000000요청 전송 전에 적용되는 최대 HTML 입력 크기(바이트)입니다.
r2FontBucket?stringnull사용자 정의 폰트 패키지용 R2 버킷 이름입니다.
fallbackToLocalbooltrue연결할 수 없는 Worker가 로컬 렌더러로 폴백할지 여부입니다.
pinnedPublicKeyslist<string>[]SHA-256 SPKI 지문이며, 형식은 sha256/<base64>입니다.
backupPublicKeyslist<string>[]백업 SPKI 핀이며, 회전이 독립적으로 검증되도록 별도로 유지됩니다.

isValid()workerUrl !== ''이고 apiToken !== ''일 때만 true를 반환합니다. allPublicKeyPins()pinnedPublicKeysbackupPublicKeys의 중복 제거된 합집합을 반환합니다. TLS 계층은 인증서의 SPKI 해시가 그 합집합의 구성원 중 하나와 일치할 때 인증서를 수락합니다. 이는 제시된 SPKI 지문 집합이 고정된 집합과 교차할 때 고정된 연결을 검증하는 RFC 7469 §2.6과 일치합니다. 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()에 의해 적용됩니다. 이 수치는 소스에서 가져왔습니다:

제한위치
최대 HTML 입력maxHtmlSize (기본값 5000000 바이트)CloudflareSecurityPolicy::validate()
최대 디코딩된 base64 데이터 URI 크기13631488 바이트 (≈13 MB)CloudflareSecurityPolicy::MAX_DATA_URI_BYTES

둘 중 하나라도 초과하면 위반한 크기와 제한을 명시하는 메시지와 함께 RuntimeException이 발생합니다. base64 상한은 압축 폭탄 방어 장치입니다. 정책은 base64 길이로부터 디코딩된 크기를 추정하여 상한 이상이면 거부합니다. <meta http-equiv="refresh"> 태그도 대소문자를 구분하지 않고 거부되는데, 렌더링된 페이지 안에서 리디렉션을 유발할 수 있기 때문입니다.

패키지는 자신이 직접 적용하는 제한만 명시합니다. Worker 자체의 요청, CPU, 메모리 상한에 대해서는 어떤 주장도 하지 않습니다. 해당 내용은 Cloudflare 공식 문서와 사용자의 Worker 구현을 참조하십시오.

Worker 또는 그 앞단의 PHP 게이트웨이가 인바운드 렌더 요청에 적용하는 선택적 요청 보호 계층 구성입니다. final readonly.

필드타입기본값의미
maxRequestsPerMinuteint60클라이언트별 분당 요청 상한입니다.
maxRequestsPerHourint1000클라이언트별 시간당 요청 상한입니다.
maxPayloadSizeBytesint10485760최대 인바운드 페이로드(≈10 MB)입니다.
allowedOriginslist<string>[]CORS 허용 목록입니다. 비어 있으면 여기서는 출처 제한을 표현하지 않습니다.
requireApiKeybooltrueAPI 키가 필요한지 여부입니다.
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가 비어 있지 않아야 합니다.

S3 호환 API를 통해 렌더링된 PDF를 Cloudflare R2에 아카이브하기 위한 구성입니다. final readonly.

필드타입기본값의미
bucketNamestring— (필수)R2 버킷입니다. S3 명명 규칙에 대해 검증됩니다.
accountIdstring— (필수)기본 엔드포인트를 구성하는 데 사용되는 Cloudflare 계정 ID입니다.
accessKeyIdstring— (필수)R2 액세스 키 ID입니다. #[SensitiveParameter].
secretAccessKeystring— (필수)R2 비밀 액세스 키입니다. #[SensitiveParameter].
endpointstring''사용자 정의 S3 엔드포인트입니다. 비어 있으면 accountId로부터 기본값을 구성합니다.
pathPrefixstring'pdfs/'업로드된 객체의 키 접두사입니다.
maxFileSizeBytesint104857600업로드 전에 적용되는 최대 업로드 크기(≈100 MB)입니다.

생성자는 비어 있지 않지만 S3 호환 규칙에 맞지 않는 bucketName을 거부합니다. 그 규칙은 다음과 같습니다: 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 방어, 비밀 정보 회전.