Konfigurasi bridge Cloudflare NextPDF
Sekilas
Bagian berjudul “Sekilas”Paket ini diatur oleh tiga objek konfigurasi immutable. Setiap nilai standar di halaman ini dibaca dari signature konstruktor yang sesuai di src/Cloudflare/. Nilai tersebut tidak berasal dari spesifikasi atau perkiraan. Jika halaman ini menyebutkan suatu nilai maksimum, nilai maksimum itu adalah batas yang diberlakukan oleh paket ini. Itu bukan klaim tentang kapasitas platform Cloudflare.
CloudflareRendererConfig
Bagian berjudul “CloudflareRendererConfig”Konfigurasi untuk renderer. final readonly. Buat langsung atau melalui CloudflareRendererConfig::fromArray().
| Kolom | Tipe | Standar | Arti |
|---|---|---|---|
workerUrl | string | — (wajib) | URL endpoint Worker. Harus HTTPS. |
apiToken | string | — (wajib) | Bearer token. Ditandai #[SensitiveParameter]. |
renderTimeout | int | 30 | Batas waktu transfer dalam detik, diterapkan oleh transport cURL yang di-pin. |
defaultCss | string | '' | CSS yang disisipkan ke dalam payload sebelum HTML Anda. |
maxHtmlSize | int | 5000000 | Ukuran maksimum input HTML, dalam byte, diberlakukan sebelum permintaan dikirim. |
r2FontBucket | ?string | null | Nama bucket R2 untuk paket fon kustom. |
fallbackToLocal | bool | true | Apakah proses beralih ke renderer lokal saat Worker tidak dapat dijangkau. |
pinnedPublicKeys | list<string> | [] | Sidik jari SPKI SHA-256, dengan format sha256/<base64>. |
backupPublicKeys | list<string> | [] | Pin SPKI cadangan yang disimpan terpisah agar rotasi divalidasi secara independen. |
isValid() mengembalikan true hanya jika workerUrl !== '' dan apiToken !== ''. allPublicKeyPins() mengembalikan gabungan tanpa duplikat dari pinnedPublicKeys dan backupPublicKeys. Lapisan TLS menerima sertifikat jika hash SPKI-nya ada di salah satu anggota gabungan tersebut. Hal ini sesuai dengan RFC 7469 §2.6, yang memvalidasi koneksi yang di-pin saat himpunan sidik jari SPKI yang disajikan memiliki irisan dengan himpunan yang di-pin. RFC 7469 §2.5 menjelaskan pin cadangan sebagai mekanisme pemulihan utama jika validasi pin gagal secara tidak disengaja. Simpan setidaknya satu pin cadangan agar rotasi sertifikat tidak merusak endpoint — lihat /integrations/cloudflare/security-and-operations/.
Pemetaan kunci fromArray()
Bagian berjudul “Pemetaan kunci fromArray()”CloudflareRendererConfig::fromArray() membaca kunci snake_case dan menerapkan nilai standar yang sama jika kunci tidak ada atau tipenya salah:
| Kunci array | Dipetakan ke |
|---|---|
worker_url | workerUrl |
api_token | apiToken |
render_timeout | renderTimeout (standar 30) |
default_css | defaultCss |
max_html_size | maxHtmlSize (standar 5000000) |
r2_font_bucket | r2FontBucket |
fallback_to_local | fallbackToLocal (standar true) |
pinned_public_keys | pinnedPublicKeys (anggota non-string dibuang) |
backup_public_keys | backupPublicKeys (anggota non-string dibuang) |
<?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='],]);Batas ukuran input yang diberlakukan paket
Bagian berjudul “Batas ukuran input yang diberlakukan paket”Batas ini diberlakukan oleh CloudflareSecurityPolicy::validate() sebelum permintaan apa pun keluar dari proses. Angkanya dibaca dari kode sumber:
| Batas | Nilai | Lokasi |
|---|---|---|
| Input HTML maksimum | maxHtmlSize (standar 5000000 byte) | CloudflareSecurityPolicy::validate() |
| Ukuran maksimum data-URI base64 setelah didekode | 13631488 byte (≈13 MB) | CloudflareSecurityPolicy::MAX_DATA_URI_BYTES |
Jika salah satunya terlampaui, RuntimeException akan muncul dengan pesan yang menyebut ukuran yang melanggar dan batasnya. Batas atas base64 berfungsi sebagai pelindung terhadap decompression bomb. Kebijakan ini memperkirakan ukuran hasil dekode dari panjang base64, lalu menolak input pada atau di atas batas atas tersebut. Tag <meta http-equiv="refresh"> juga ditolak tanpa membedakan huruf besar/kecil, karena dapat memicu pengalihan dari dalam halaman yang dirender.
Paket ini hanya menyatakan batas yang diberlakukannya sendiri. Paket ini tidak membuat klaim apa pun tentang batas permintaan, CPU, atau memori milik Worker itu sendiri. Rujuk dokumentasi resmi Cloudflare dan implementasi Worker Anda untuk hal tersebut.
ApiProtectionConfig
Bagian berjudul “ApiProtectionConfig”Konfigurasi untuk lapisan proteksi permintaan opsional yang diterapkan oleh Worker — atau gateway PHP di depannya — pada permintaan render yang masuk. final readonly.
| Kolom | Tipe | Standar | Arti |
|---|---|---|---|
maxRequestsPerMinute | int | 60 | Batas atas permintaan per klien per menit. |
maxRequestsPerHour | int | 1000 | Batas atas permintaan per klien per jam. |
maxPayloadSizeBytes | int | 10485760 | Payload masuk maksimum (≈10 MB). |
allowedOrigins | list<string> | [] | Daftar origin yang diizinkan untuk CORS. Kosong berarti tidak ada pembatasan origin yang dinyatakan di sini. |
requireApiKey | bool | true | Apakah kunci API diperlukan. |
apiKeyHeader | string | 'X-Api-Key' | Header yang membawa kunci API. |
rateLimitWindowSeconds | int | 60 | Durasi jendela per menit, dalam detik. |
fromArray() membaca max_requests_per_minute, max_requests_per_hour, max_payload_size_bytes, allowed_origins, require_api_key, api_key_header, dan rate_limit_window_seconds. isValid() mengharuskan semua kolom numerik bernilai positif dan apiKeyHeader tidak boleh kosong.
R2ArchiveConfig
Bagian berjudul “R2ArchiveConfig”Konfigurasi untuk mengarsipkan PDF yang telah dirender ke Cloudflare R2 melalui API yang kompatibel dengan S3. final readonly.
| Kolom | Tipe | Standar | Arti |
|---|---|---|---|
bucketName | string | — (wajib) | Bucket R2. Divalidasi terhadap aturan penamaan S3. |
accountId | string | — (wajib) | ID akun Cloudflare, dipakai untuk membangun endpoint standar. |
accessKeyId | string | — (wajib) | ID kunci akses R2. #[SensitiveParameter]. |
secretAccessKey | string | — (wajib) | Kunci akses rahasia R2. #[SensitiveParameter]. |
endpoint | string | '' | Endpoint S3 kustom. Kosong membangun nilai standar dari accountId. |
pathPrefix | string | 'pdfs/' | Prefiks kunci untuk objek yang diunggah. |
maxFileSizeBytes | int | 104857600 | Ukuran unggahan maksimum (≈100 MB), diberlakukan sebelum unggahan. |
Konstruktor menolak bucketName yang tidak kosong tetapi tidak sesuai dengan aturan yang kompatibel dengan S3. Aturan tersebut adalah: 3–63 karakter, karakter alfanumerik huruf kecil dan tanda hubung, dimulai dan diakhiri dengan karakter alfanumerik. Pelanggaran akan memunculkan InvalidArgumentException. isValid() mengharuskan bucketName, accountId, accessKeyId, dan secretAccessKey tidak boleh kosong. Saat endpoint kosong, getEndpoint() mengembalikan https://<accountId>.r2.cloudflarestorage.com.
Penanganan rahasia
Bagian berjudul “Penanganan rahasia”apiToken, accessKeyId, dan secretAccessKey memiliki atribut #[SensitiveParameter], sehingga PHP meredaksi nilainya dari stack trace. Berikan nilainya dari variabel lingkungan atau secrets manager. Jangan pernah commit nilainya. Objek konfigurasi bersifat immutable, sehingga nilai yang sudah disetel tidak dapat diubah lagi setelah konstruksi.
Lihat juga
Bagian berjudul “Lihat juga”- /integrations/cloudflare/quickstart/ — gunakan konfigurasi ini pada render pertama.
- /integrations/cloudflare/production-usage/ — fallback, pengarsipan R2, dan proteksi API yang dirangkai bersama.
- /integrations/cloudflare/security-and-operations/ — pinning, pertahanan SSRF, dan rotasi rahasia.