Pro Edition
Webview
Auf einen Blick
Abschnitt betitelt „Auf einen Blick“Webview liefert ein linearisiertes (Fast Web View) PDF über HTTP aus, sodass ein Client das Rendern von Seite 1 aus einem kleinen führenden Präfix beginnen kann, während der Rest der Datei noch im Transfer ist. Es umhüllt die rohen Bytes als ein LinearizedDocument, beantwortet Range-Anfragen mit RFC-9110-Partial-Content-Antworten über einen PSR-7-ByteRangeResponder und kann (über FirstPageProber) beweisen, dass die erste Seite im Präfix in sich abgeschlossen ist.
Verfügbarkeit & Lizenzierung
Abschnitt betitelt „Verfügbarkeit & Lizenzierung“Diese Funktion ist in NextPDF Pro (nextpdf/pro) enthalten und wird mit einem Lizenz-Envelope der Pro-Stufe aktiviert. Ein Deployment ohne diese Berechtigung lädt die Klassen der Funktion nicht. Editionen vergleichen und Lizenz erwerben.
Es gibt kein separates per-Feature-Lizenz-Flag. Der Responder wird zur Laufzeit an Ihre eigenen PSR-17-Factories angebunden — ein ResponseFactoryInterface und ein StreamFactoryInterface — und der Media-Type ist standardmäßig application/pdf als Konstruktorargument, kein Lizenzschalter.
Installation
Abschnitt betitelt „Installation“composer require nextpdf/proDer Code liegt unter dem Namespace NextPDF\Pro\Webview.
Konzeptioneller Überblick
Abschnitt betitelt „Konzeptioneller Überblick“Ein linearisiertes PDF ist so angeordnet, dass die erste Seite des Dokuments — das Linearisierungs-Parameter-Dictionary, der primäre Hint-Stream und die Objekte von Seite 1 — in einem führenden Abschnitt liegt, der am /E-Offset endet. Webview verwandelt dieses Layout in eine progressive Auslieferung.
LinearizedDocument::fromBytes() parst die Bytes über die Lese-seitige LinearizationView von Core (Pro implementiert das Parsen der Linearisierung niemals neu) und weist alles zurück, was kein verwendbares linearisiertes Dokument ist: gar nicht linearisiert, eine deklarierte /L-Länge, die nicht der tatsächlichen Byte-Länge entspricht, oder ein /E-End-of-First-Page-Offset, der kein positiver Offset innerhalb der Datei ist. Die Konstruktion ist daher total — sobald Sie ein LinearizedDocument halten, ist jeder Offset, den es offenlegt, vertrauenswürdig.
ByteRangeResponder beantwortet anschließend eine HTTP-Anfrage. Er ist ausschließlich gegen PSR-7 / PSR-17 implementiert, ohne Framework-Kopplung. Er kündigt stets Accept-Ranges: bytes und einen starken, deterministischen SHA-256-ETag an, parst den Range-Header des Clients gemäß RFC 9110 §14 und gibt entweder ein vollständiges 200 OK, einen 206 Partial Content Single Range, eine 206-multipart/byteranges-Antwort für mehrere Ranges oder ein 416 Range Not Satisfiable zurück.
FirstPageProber ist die Seite des strukturellen Nachweises: Er quantifiziert das First-Page-Präfix, den Anteil der gesamten Datei, den dieses Präfix darstellt, und ob der primäre Hint-Stream vollständig darin liegt — die Eigenschaft, die es einem Reader erlaubt, die Objekte von Seite 1 allein aus dem Präfix zu lokalisieren.
Warum es so funktioniert
Abschnitt betitelt „Warum es so funktioniert“Webview parst die Linearisierung niemals selbst neu. Es leiht sich die Lese-seitige LinearizationView von Core, sodass die Auslieferungsschicht einen einzigen auditierten Parser erbt statt einer zweiten, driftenden Kopie. Die Konstruktion ist bewusst total. LinearizedDocument::fromBytes() weist ein fehlerhaftes Layout vorab zurück, sodass jeder Offset, dem eine Range-Antwort vertraut, zuerst validiert wurde. Der Responder spricht ausschließlich PSR-7 und PSR-17, sodass derselbe Code ein linearisiertes PDF aus jedem HTTP-Stack ausliefert. Genau diese Disziplin macht die progressive Range-Auslieferung sicher genug, um sie in großem Umfang nicht vertrauenswürdigen Clients auszusetzen.
Design-Hintergrund: Hochvolumige Dokumentenerzeugung.
Wie das progressive Byte-Range-Serving funktioniert
Abschnitt betitelt „Wie das progressive Byte-Range-Serving funktioniert“- Bauen Sie ein
LinearizedDocumentaus den gerenderten PDF-Bytes. Ungültige Eingaben lösen vorab eineUnsupportedDocumentExceptionaus. - Übergeben Sie das Dokument und das eingehende PSR-7-
ServerRequestInterfaceanByteRangeResponder::respond(). Der Responder liestRange(und die optionaleIf-Range-Precondition) und erzeugt das korrekte PSR-7-ResponseInterface. - Der Client fordert zuerst das führende Präfix an (oder Sie pushen es mit
firstPageResponse()), rendert Seite 1 und fordert dann die übrigen Ranges an, während der Benutzer scrollt.
Das Byte-Range-Modell verwendet inklusive Offsets gemäß RFC 9110 §14.1.2: Ein ByteRange ist firstByte–lastByte über eine Repräsentation von contentLength, und sein Content-Range-Feld ist bytes first-last/length.
Verhaltensvertrag
Abschnitt betitelt „Verhaltensvertrag“LinearizedDocument::fromBytes()ist total: Ein nicht-linearisiertes Dokument, eine/L-Abweichung oder ein nicht-positiver / außerhalb der Datei liegender/E-Offset lösen jeweils eineUnsupportedDocumentExceptionaus, statt ein unsicheres Dokument zu erzeugen.- Der
ETagist ein starker SHA-256-Entity-Tag über die exakten Bytes, einmalig bei der Konstruktion memoisiert. Identische Render-Eingaben ergeben identische Bytes und daher einen identischenETag, sodass Caches undIf-Rangesich vorhersehbar verhalten. - Eine Anfrage ohne anwendbares
Rangegibt200 OKmit dem vollständigen Body zurück. EinIf-Range, das nicht zum aktuellen starkenETagpasst, bewirkt, dass dasRangeignoriert und ein vollständiges200zurückgegeben wird (RFC 9110 §13.1.5). Nur die starke Entity-Tag-Form vonIf-Rangewird honoriert; ein HTTP-Date-If-Rangewird als Nicht-Treffer behandelt. - Eine nicht erkannte Range-Unit oder ein syntaktisch ungültiges
Rangewird ignoriert, und ein vollständiges200wird zurückgegeben (RFC 9110 §14.2). - Ein erfüllbares Range gibt
206 Partial ContentmitContent-Rangezurück; mehrere erfüllbare Ranges geben206multipart/byterangeszurück. Gültige Byte-Ranges, von denen keines erfüllbar ist, geben416mitContent-Range: bytes */lengthzurück (RFC 9110 §15.3.7). firstPageResponse()emittiert ein206, das genau das Byte-Range der ersten Seite[0, /E - 1]trägt — die Server-Push-Form von „erste Seite vor dem vollständigen Download“.
Codebeispiel — Schnellstart
Abschnitt betitelt „Codebeispiel — Schnellstart“Das Folgende spiegelt die dokumentierte öffentliche API wider. Das Repository liefert für dieses Modul kein lauffähiges Beispiel aus.
use NextPDF\Pro\Webview\LinearizedDocument;use NextPDF\Pro\Webview\ByteRangeResponder;
$document = LinearizedDocument::fromBytes($pdfBytes);$responder = new ByteRangeResponder($responseFactory, $streamFactory);
$response = $responder->respond($document, $request);Codebeispiel — First-Page-Push und Probing
Abschnitt betitelt „Codebeispiel — First-Page-Push und Probing“use NextPDF\Pro\Webview\LinearizedDocument;use NextPDF\Pro\Webview\ByteRangeResponder;use NextPDF\Pro\Webview\FirstPageProber;use NextPDF\Pro\Webview\Exception\UnsupportedDocumentException;
try { $document = LinearizedDocument::fromBytes($pdfBytes);} catch (UnsupportedDocumentException $e) { // Not a usable linearized document — fall back to plain full delivery. // ... return;}
$prober = new FirstPageProber($document);if ($prober->isFirstPageSelfContained()) { // Push exactly the first page's bytes for an instant render. $response = (new ByteRangeResponder($responseFactory, $streamFactory)) ->firstPageResponse($document);}Sonderfälle & Fallstricke
Abschnitt betitelt „Sonderfälle & Fallstricke“- Webview erfordert ein echt linearisiertes PDF. Wenn das gerenderte Dokument nicht linearisiert ist, aktivieren Sie die Linearisierung zur Render-Zeit oder liefern Sie es mit einer einfachen vollständigen Auslieferung aus —
respondToBytes()kann weiterhin Ranges über beliebige (nicht-linearisierte) Bytes ausliefern, wenn Sie nur Range-Unterstützung benötigen, keine First-Page-Semantik. - Inkrementelle Updates sind relevant: Ein Dokument, das über seine deklarierte
/Lhinaus angehängt wurde, wird als Längenabweichung zurückgewiesen, weil Byte-Range-Offsets dann nicht mehr vertrauenswürdig wären. - Der Responder deckelt die Anzahl der distinkten Ranges, die er pro Anfrage honoriert. Eine Anfrage, die mehr zusammengeführte Ranges als die Obergrenze oder mehr Gesamt-Bytes als die gesamte Repräsentation verlangt, lässt ihr
Rangeignorieren und wird mit einem vollständigen200bedient.
Performance
Abschnitt betitelt „Performance“Das First-Page-Präfix ist der /E-End-of-First-Page-Offset, auf die Dateilänge geklemmt, sodass FirstPageProber::prefixFraction() meldet, wie klein der initiale Abruf relativ zur gesamten Datei ist — für ein mehrseitiges Dokument ist genau das der Sinn von Fast Web View. Der Antwortaufbau schneidet aus dem In-Memory-Byte-String; die Kosten sind proportional zu den ausgewählten Bytes. Der ETag wird einmal pro Dokument berechnet. Messen Sie mit repräsentativen Dokumenten.
Sicherheitshinweise
Abschnitt betitelt „Sicherheitshinweise“Behandeln Sie die Eingabe als nicht vertrauenswürdig. LinearizedDocument::fromBytes() validiert die Linearisierungs-Invarianten, bevor irgendein Offset verwendet wird. Der Responder weist einen contentType mit Steuerzeichen zurück, um Header-Injection zu verhindern, leitet eine Multipart-Boundary ab, die garantiert nicht innerhalb des Bodys auftritt, und führt überlappende Ranges zusammen und begrenzt deren Anzahl und Gesamtgröße, um sich gegen die Multipart-Range-Amplification-Klasse von Denial-of-Service zu verteidigen (Apache HTTPD CVE-2011-3192). Dieses Modul protokolliert keinen Dokumentinhalt.
Konformität
Abschnitt betitelt „Konformität“Die Byte-Range-Auslieferung folgt RFC 9110 (HTTP Semantics) — §14 für Range-Anfragen, §13.1.5 für If-Range und §15.3.7 für 416. Das Linearisiertes-Dokument-Modell ist das in ISO 32000-2 Annex F beschriebene Fast-Web-View-Layout. Das Modul behauptet keine weiteren externen Klausel-Identifikatoren über das durch seine Tests verifizierte Verhalten hinaus.
Hinweis zur Enterprise-Grenze
Abschnitt betitelt „Hinweis zur Enterprise-Grenze“Enterprise ändert das Verhalten von Webview nicht. Enterprise ergänzt höherstufige Compliance- und Archivierungsfunktionen, die separat dokumentiert sind; sie sind nicht erforderlich, um ein linearisiertes PDF über Byte-Ranges auszuliefern.
Veröffentlichungsgrenze
Abschnitt betitelt „Veröffentlichungsgrenze“Diese Seite dokumentiert ausschließlich extern beobachtbares Verhalten und die unterstützte öffentliche API-Oberfläche. Interne Namespace-Pfade, Hilfsklassen, Mechanismus-Tabellen, Runbook-Dateinamen und Ticket-Präfixe liegen außerhalb des Geltungsbereichs.