Enterprise sürüm
Webhook — Derin referans
Bir bakışta
“Bir bakışta” başlıklı bölümNextPDF\Enterprise\Webhook ad alanı, iş olayları için kiracı kapsamlı webhook teslimi sunar. Genel yüzey altı simgeden oluşur: WebhookManager, WebhookRegistration, WebhookPayload, WebhookDelivery, WebhookRetryPolicy ve DeadLetterEntry. Yönetici, uç noktaları kiracı başına kaydeder ve iş olaylarını abone olan kayıtlara gönderir. Teslim motoru, HMAC-SHA256 ile imzalanmış bir JSON yükünü POST eder, her hedefi Core SSRF çıkış geçidine karşı doğrular, üstel geri çekilme ile yeniden dener ve kalıcı başarısızlıkları bellek içi bir ölü-mektup kuyruğuna kaydeder. 3.1.0 itibarıyla imza, X-NextPDF-Timestamp başlığını MAC temel dizesine bağlar; böylece alıcılar tazeliği ve bütünlüğü birlikte doğrular. İş akışı düzeyindeki kılavuz için Webhook sayfasına bakın.
Kullanılabilirlik ve lisanslama
“Kullanılabilirlik ve lisanslama” başlıklı bölümBu yetenek NextPDF Enterprise (nextpdf/enterprise) içinde sunulur ve Enterprise katmanlı bir lisans zarfıyla etkinleşir. Bu yetkiye sahip olmayan bir dağıtım, yeteneğin sınıflarını yüklemez. Sürümleri karşılaştırın ve lisans alın.
Webhook yüzeyi, Enterprise paketi kurulduğunda kullanılabilen temel bir Enterprise yeteneğidir; özellik başına ayrı bir bayrak yoktur. NextPDF Core (Apache-2.0) ve NextPDF Pro hiçbir webhook kaydı veya teslim yüzeyine sahip değildir; yönetici, kayıt, yük, teslim motoru, yeniden deneme politikası ve ölü-mektup girişi yalnızca nextpdf/enterprise içinde sunulur.
Genel API yüzeyi
“Genel API yüzeyi” başlıklı bölüm| Simge | Parametreler | Varsayılan davranış | Döndürür | Fırlatır veya şununla başarısız olur | Notlar |
|---|---|---|---|---|---|
WebhookManager::__construct | WebhookDelivery $delivery, ?LoggerInterface $logger = null | Boş bir bellek içi kayıt dizini olan bir yönetici oluşturur | Yeni WebhookManager | Fırlatmaz | Kayıtlar kiracı başına dizinlenir |
WebhookManager::register | TenantContext $tenant, WebhookRegistration $registration | Kaydı, çağıran kiracının dizinine ekler | void | Kayıt kiracısı bağlam kiracısıyla eşleşmediğinde InvalidArgumentException | Kiracılar arası kayıt, depolamadan önce reddedilir |
WebhookManager::unregister | TenantContext $tenant, string $registrationId | Eşleşen kaydı devre dışı bırakılmış bir kopyayla değiştirir | bool | Fırlatmaz; kimlik bulunmadığında false döndürür | Yumuşak devre dışı bırakma; geçmiş korunur |
WebhookManager::activeRegistrations | TenantContext $tenant | Kiracının kayıtlarını etkin olanlara filtreler | list<WebhookRegistration> | Fırlatmaz | Yalnızca çağıran kiracının kayıtları görünür |
WebhookManager::dispatch | TenantContext $tenant, JobEvent $event | Olayı, olay türüne abone olan her etkin kayda teslim eder | int (başarılı teslimler) | Olay verisi JSON ile kodlanamadığında JsonException yayar; teslim başarısızlıkları fırlatmaz | Her kayıt teslimi için yeni bir 32 haneli onaltılık teslim kimliği üretilir |
WebhookRegistration::__construct | string $id, string $tenantId, string $url, array $events, string $secret, bool $active = true, ?string $description = null | Verilen değerleri olduğu gibi saklar | Yeni WebhookRegistration | Bildirilmiş @throws yok; strict_types altında uyumsuz argüman türlerinde PHP TypeError fırlatır | final readonly; boş $events tümüne-abone-ol anlamına gelir |
WebhookRegistration::subscribesTo | JobEventType $eventType | $events boş olduğunda veya türü içerdiğinde true | bool | Fırlatmaz | Katı özdeşlik karşılaştırması |
WebhookRegistration::deactivate | — | Etkin olmayan bir kopya döndürür | self | Fırlatmaz | Orijinal örnek değişmez |
WebhookPayload::fromJobEvent | JobEvent $event, string $tenantId, string $deliveryId | İş kimliğini, olay türünü, veriyi ve zaman damgasını olaydan kopyalar | self | Fırlatmaz | dispatch tarafından kullanılan statik fabrika |
WebhookPayload::toJson | — | Altı alanlı gövdeyi kaçışsız eğik çizgilerle serileştirir | non-empty-string | Olay verisi JSON ile kodlanamadığında JsonException | JSON_THROW_ON_ERROR | JSON_UNESCAPED_SLASHES |
WebhookPayload::toArray | — | Gövdeyi ilişkisel bir dizi olarak döndürür | array<string, mixed> | Fırlatmaz | Zaman damgası RFC 3339 genişletilmiş olarak biçimlendirilir |
WebhookPayload::signedTimestamp | — | Sıfıra veya daha büyüğe sabitlenmiş Unix saniye cinsinden olay zamanı | int<0, max> | Fırlatmaz | X-NextPDF-Timestamp olarak yayılır ve MAC’e bağlanır |
WebhookPayload::sign | string $secret | {signedTimestamp}.{jsonBody} temel dizesi üzerinde HMAC-SHA256 | non-empty-string (onaltılık) | Gövde kodlanamadığında toJson() yoluyla JsonException | Zaman damgası başlığını gövdeye kriptografik olarak bağlar |
WebhookDelivery::__construct | ClientInterface $httpClient, RequestFactoryInterface $requestFactory, StreamFactoryInterface $streamFactory, WebhookRetryPolicy $retryPolicy = new WebhookRetryPolicy(), ?LoggerInterface $logger = null | Boş bir ölü-mektup kuyruğuna sahip PSR-18/PSR-17 teslim motoru | Yeni WebhookDelivery | Fırlatmaz | Varsayılan politika: 5 deneme, 1 sn temel, 300 sn sınır |
WebhookDelivery::deliver | WebhookRegistration $registration, WebhookPayload $payload | İmzalı yükü, deneme başına SSRF çıkış doğrulaması ve üstel geri çekilme ile POST eder | bool | Gövde kodlanamadığında ilk denemeden önce JsonException; aksi hâlde fırlatmaz — false, yükün ölü-mektup kuyruğuna yönlendirildiği anlamına gelir | Yalnızca 2xx yanıtında true |
WebhookDelivery::deadLetters | — | Kaydedilen tüm girişleri döndürür | list<DeadLetterEntry> | Fırlatmaz | Bellek içi, süreç kapsamlı |
WebhookDelivery::clearDeadLetters | — | Ölü-mektup kuyruğunu boşaltır | void | Fırlatmaz | Geri alınamaz; yeniden oynatma gerekiyorsa önce girişleri dışa aktarın |
WebhookRetryPolicy::__construct | int $maxRetries = 5, int $baseDelaySeconds = 1, int $maxDelaySeconds = 300 | Politika değerlerini saklar | Yeni WebhookRetryPolicy | Bildirilmiş @throws yok; parametreler positive-int olarak belgelenmiştir | $maxRetries, toplam deneme sayısını sayar |
WebhookRetryPolicy::delayForAttempt | int $attempt | maxDelaySeconds değerinde sınırlanmış baseDelaySeconds × 2^(attempt − 1) | positive-int | Fırlatmaz | Deneme numaraları 1 tabanlıdır |
WebhookRetryPolicy::shouldRetry | int $currentAttempt | Geçerli deneme maksimumun altındayken true | bool | Fırlatmaz | Son denemeden sonra bekleme atlanır |
WebhookRetryPolicy::default | — | 5 deneme, 1 sn temel, 300 sn sınır | self | Fırlatmaz | Statik fabrika; üretim varsayılanı |
WebhookRetryPolicy::aggressive | — | 10 deneme, 2 sn temel, 600 sn sınır | self | Fırlatmaz | Kritik uç noktalar için statik fabrika |
DeadLetterEntry::__construct | string $id, string $registrationId, WebhookPayload $payload, int $attempts, string $lastError, ?int $lastHttpStatus, DateTimeImmutable $failedAt, bool $replayed = false | Başarısızlık kaydını olduğu gibi saklar | Yeni DeadLetterEntry | Bildirilmiş @throws yok; strict_types altında TypeError | final readonly; null $lastHttpStatus taşıma başarısızlığı anlamına gelir |
DeadLetterEntry::markReplayed | — | replayed = true olan bir kopya döndürür | self | Fırlatmaz | Aynı kimlik; orijinal giriş değişmez |
public function __construct( private readonly WebhookDelivery $delivery, private readonly ?LoggerInterface $logger = null,) {}
public function register(TenantContext $tenant, WebhookRegistration $registration): void
public function unregister(TenantContext $tenant, string $registrationId): bool
public function activeRegistrations(TenantContext $tenant): array
public function dispatch(TenantContext $tenant, JobEvent $event): intpublic function __construct( public string $id, public string $tenantId, public string $url, public array $events, public string $secret, public bool $active = true, public ?string $description = null,) {}
public function subscribesTo(JobEventType $eventType): bool
public function deactivate(): selfpublic static function fromJobEvent( JobEvent $event, string $tenantId, string $deliveryId,): self
public function toJson(): string
public function toArray(): array
public function signedTimestamp(): int
public function sign(string $secret): stringpublic function __construct( private readonly ClientInterface $httpClient, private readonly RequestFactoryInterface $requestFactory, private readonly StreamFactoryInterface $streamFactory, private readonly WebhookRetryPolicy $retryPolicy = new WebhookRetryPolicy(), private readonly ?LoggerInterface $logger = null,) {}
public function deliver(WebhookRegistration $registration, WebhookPayload $payload): bool
public function deadLetters(): array
public function clearDeadLetters(): voidpublic function __construct( public int $maxRetries = 5, public int $baseDelaySeconds = 1, public int $maxDelaySeconds = 300,) {}
public function delayForAttempt(int $attempt): int
public function shouldRetry(int $currentAttempt): bool
public static function default(): self
public static function aggressive(): selfpublic function __construct( public string $id, public string $registrationId, public WebhookPayload $payload, public int $attempts, public string $lastError, public ?int $lastHttpStatus, public DateTimeImmutable $failedAt, public bool $replayed = false,) {}
public function markReplayed(): selfDavranış sözleşmesi
“Davranış sözleşmesi” başlıklı bölüm- Kayıtlar kiracı başına dizinlenir.
register(), kiracı tanımlayıcısı çağıran bağlamla eşleşmeyen bir kaydı reddeder.unregister()yumuşak bir devre dışı bırakmadır: kayıt, etkin olmayan bir kopyayla değiştirilir; böylece geçmiş korunurken gelecekteki gönderimlerden çıkarılır. dispatch(), yalnızca gönderilen olay türüne abone olan çağıran kiracının etkin kayıtlarında yinelenir. Boş bir abone-olunan-olay listesi, tümüne-abone-ol anlamına gelir. Dönüş değeri, başarılı teslimleri sayar.- Her teslim, bir JSON gövdesi ve beş başlığa sahip bir HTTP POST’tur:
Content-Type: application/json,X-NextPDF-Signature(sha256=<hex>),X-NextPDF-Timestamp(unix saniye),X-NextPDF-Delivery-IdveX-NextPDF-Event. - JSON gövde alanları
delivery_id,job_id,event_type,data,timestamp(RFC 3339 genişletilmiş) vetenant_idolup kaçışsız eğik çizgilerle serileştirilir. Olay türü değerlerinextpdf/coreiçindekiJobEventType’tan gelir:progress,completed,failed,cancelled. - İmza şeması (3.1.0’da değişti, kırıcı). HMAC-SHA256 temel dizesi, kayıt gizli anahtarıyla anahtarlanmış
{signedTimestamp}.{jsonBody}olup yalnızca gövde değildir.X-NextPDF-Timestampdeğeri, MAC’in zaman damgası bileşenidir; böylece kurcalanmış veya yeniden oynatılmış bir zaman damgası başlığı imzayı geçersiz kılar. - Alıcı doğrulaması:
X-NextPDF-TimestampbaşlığıT’yi okuyun;Tkabul edilebilir bir tazelik penceresinin (örneğin 300 sn) dışındaysa reddedin; ham alınan baytlar üzerindehash_hmac('sha256', T . '.' . rawBody, secret)’i yeniden hesaplayın;sha256=önekini çıkardıktan sonra başlık değeriyle sabit zamanda karşılaştırın. - Gövde, imza ve teslim kimliği, teslim başına bir kez hesaplanır ve yeniden deneme denemeleri boyunca sabit kalır.
- SSRF çıkış geçidi. Her denemeden önce hedef URL, Core
UrlValidator::validateExternalUrl()geçidinden geçer: yalnızca HTTPS şeması; loopback, özel, ayrılmış, taşıyıcı düzeyli NAT, bulut meta verisi ve IPv4 gömülü IPv6 geçiş aralıkları engellenir; ana makine adları DNS ile çözümlenir (A ve AAAA) ve çözümlenemeyen ana makineler başarısız-kapalı olarak reddedilir. Engellenen bir URL asla gönderilmez: deneme döngüsü iptal edilir ve yük,Blocked SSRF destination:son hatası ve null HTTP durumuyla doğrudan ölü-mektup kuyruğuna yönlendirilir. - Deneme başına sonuç sınıflandırması: 2xx başarıdır ve hemen döner; 429 dışındaki bir 4xx nihaidir ve doğrudan ölü-mektuba gider; diğer her sonuç — 3xx, 429, 5xx veya bir taşıma istisnası — politikanın toplam deneme sayısına kadar yeniden denenebilir.
- Geri çekilme üsteldir: bir sonraki denemeden önceki bekleme,
maxDelaySecondsdeğerinde sınırlanmışbaseDelaySeconds × 2^(attempt − 1)’dir. Son denemeden sonra bekleme atlanır. - Hiçbir deneme başarılı olmadığında, bir
DeadLetterEntryşunları kaydeder: benzersiz bir kimlik, kayıt kimliği, orijinal yük, deneme sayısı (politika maksimumuna sabitlenmiş), son hata mesajı, son HTTP durumu (taşıma başarısızlığında veya SSRF engellemesinde null) ve başarısızlık zaman damgası. - Ölü-mektup kuyruğu bellek içidir ve süreç ömrüyle kapsamlıdır.
markReplayed(), işaretlenmiş bir kopya üretir; yeniden göndermez ve kuyruk orijinal girişi korur.
Uç durumlar ve başarısızlık modları
“Uç durumlar ve başarısızlık modları” başlıklı bölüm- Boş olay listesi. Kayıt her olay türünü alır. Alıcı tüm olayları görmemeliyse listeyi açıkça kapsamlandırın.
- Nihai 4xx’e karşı taşıma başarısızlığı. Bir 4xx reddi, doldurulmuş bir
lastHttpStatuskaydeder; bir bağlantı başarısızlığı null kaydeder. Alıcı reddini taşıma başarısızlığından ayırmak için null’ı kullanın. - SSRF ile engellenen hedef. Bir HTTP, özel, loopback veya meta veri adresini işaret eden bir kayıt, ilk denemede
Blocked SSRF destination:hatası ve null durumla ölü-mektuba düşer. Hiçbir giden istek yapılmaz. URL’yi düzeltin ve yeniden kaydedin. - Yükseltmeden sonra eski alıcılar. 3.1.0 öncesi yalnızca-gövde HMAC’ini hâlâ doğrulayan bir alıcı, 3.1.0 teslimlerine karşı başarısız-kapalı olur. Alıcıyı
{timestamp}.{body}temel dizesine geçirin veX-NextPDF-Timestamp’ı tüketin. - Kodlanamayan olay verisi.
toJson()vesign(), herhangi bir deneme yapılmadan öncedeliver()vedispatch()dışına yayılanJsonExceptionfırlatır. - Eşzamanlı engelleme.
deliver(), denemeler arasında satır içinde uyur. Kümülatif geri çekilme, varsayılan politikada 15 sn’ye ve aggressive politikada yaklaşık 17 dakikaya ulaşır. Alıcı gecikmesi güvenilmezse bir kuyruk çalışanından gönderin. - Deneme sayısı sabitlemesi. Dahilî döngü sayacı tükenmede onun ötesine ilerlese de, kaydedilen deneme sayısı asla politika maksimumunu aşmaz.
- Kuyruk büyümesi ve kalıcılık. Ölü-mektup kuyruğu süreç içinde sınırsız büyür ve yeniden başlatmada kaybolur. Kalıcı yeniden oynatma gerektiğinde,
clearDeadLetters()çağrılmadan önce girişlerideadLetters()yoluyla dışa aktarın ve haricî olarak kalıcılaştırın. - Yeniden oynatma operatör güdümlüdür. Yeniden teslim,
deliver()’ı girişin yüküyle yeniden çağırmak anlamına gelir;markReplayed()yalnızca bu olguyu bir kopyada kaydeder. - DNS yeniden bağlama kalıntısı. URL her denemede yeniden doğrulanır; bu, yeniden bağlama penceresini daraltır ama kapatmaz: PSR-18 soyutlaması bağlantıyı doğrulanmış IP’ye sabitleyemez. Bu kalıntının önem taşıdığı yerlerde ağ katmanı çıkış denetimleri ekleyin.
- Gizli anahtar işleme. Kayıt gizli anahtarı bir kimlik bilgisidir. HMAC yalnızca bütünlüğü ve kökeni doğrular — gizlilik değildir. Alıcının görmemesi gereken veriyi olay yüküne koymayın.
FIPS modu davranışı
“FIPS modu davranışı” başlıklı bölümYük imzalama, PHP’nin hash_hmac()’i aracılığıyla HMAC-SHA256’dır; bu nedenle ana makine kripto sağlayıcısına dayanır. FIPS kısıtlamalı bir derlemede, onaylanmamış bir ilkel, düşürmek yerine kriptografik sınırda başarısız olur. Webhook katmanı, kendine ait hiçbir kriptografik politika eklemez.
Uygunluk
“Uygunluk” başlıklı bölüm- Yük kimlik doğrulaması, SHA-256 ile örneklenmiş, FIPS PUB 198-1 §1’in anahtarlı-karma mesaj kimlik doğrulama kodu olan HMAC’i uygular.
- Yeniden oynatma koruması, OWASP Cheat Sheet Series webhook güvenliği yönergesini izler: olay zaman damgası özel bir başlıkta taşınır ve imza hesaplamasına tohumlanır; böylece kurcalanmış bir zaman damgası doğrulamada başarısız olur.
- Gövde zaman damgaları, RFC 3339 genişletilmiş tarih-saat biçimini kullanır. Kodda bildirilmiş: RFC 3339 bu sayfa için RAG bütüncesinden alınmamıştır.
- Bunlar, ürün kaynağına ve alıntılanan hükümlere dayanan yetenek beyanlarıdır. NextPDF, bu yüzey için hiçbir uygunluk veya sertifikasyon iddiasında bulunmaz.
Geliştirme notları
“Geliştirme notları” başlıklı bölüm- Tüm sınıflar
strict_types=1bildirir vefinal’dir;WebhookRegistration,WebhookPayload,WebhookRetryPolicyveDeadLetterEntry, yükseltilmiş genel özelliklere sahipfinal readonly’dir. - Modül,
2.2.0olan bir@sinceaçıklaması taşır; zaman damgasına bağlı imza şeması, 3.1.0’da belgelenmiş bir kırıcı değişikliktir. - Teslim motoru, PSR-18/PSR-17 soyutlamalarını alır; böylece sahte bir HTTP istemcisi, tam gönderme, yeniden deneme ve ölü-mektup yolunu çevrimdışı çalıştırır. Günlükleyici varsayılan olarak null’dur; üretimde bir PSR-3 günlükleyici enjekte edin, yoksa başarısızlıklar yalnızca dönüş değerleri aracılığıyla ortaya çıkar.
- Alıcı uygulamaları, imza karşılaştırması için
hash_equals()kullanmalı veX-NextPDF-Timestampüzerinde bir tazelik penceresi uygulamalıdır. - Önerilen sınır testleri: kiracı uyumsuz kayıt, boş-olay-listesi dağıtımı, nihai 4xx, yeniden deneme tükenmesi, SSRF ile engellenen URL, sabit bir vektöre karşı zaman damgası kurcalanmış imza reddi ve ölü-mektup deneme sayısı sabitlemesi.
Yayımlama sınırı
“Yayımlama sınırı” başlıklı bölümBu sayfa yalnızca dışarıdan gözlemlenebilir davranışı ve desteklenen genel API yüzeyini belgeler. Dahilî ad alanı yolları, yardımcı sınıflar, mekanizma tabloları, runbook dosya adları ve bilet önekleri kapsam dışıdır.
Ayrıca bakınız
“Ayrıca bakınız” başlıklı bölüm- Webhook — NextPDF Enterprise — yetenek sayfası: iş akışı, yapılandırma ve işlenmiş kayıt örnekleri.
- SaaS — Derinlemesine başvuru — kiracı kimliği, API anahtarları ve kotalar;
TenantContext’in kaynağı. - Metering — Derin referans — aynı PSR-18 teslim disipliniyle kullanım ölçümü dağıtımı.