Pro edycja
Webview
W skrócie
Dział zatytułowany „W skrócie”Webview dostarcza zlinearyzowany (Fast Web View) plik PDF przez HTTP, więc klient może zacząć renderować stronę 1 z niewielkiego wiodącego prefiksu, podczas gdy reszta pliku jest jeszcze w drodze. Opakowuje surowe bajty jako LinearizedDocument, odpowiada na żądania Range odpowiedziami partial-content zgodnymi z RFC 9110 przez ByteRangeResponder w PSR-7 i potrafi udowodnić (przez FirstPageProber), że pierwsza strona jest samowystarczalna w prefiksie.
Dostępność i licencjonowanie
Dział zatytułowany „Dostępność i licencjonowanie”Ta funkcja jest dostarczana w NextPDF Pro (nextpdf/pro) i aktywuje się z kopertą licencyjną poziomu Pro. Wdrożenie bez tego uprawnienia nie ładuje klas tej funkcji. Porównaj edycje i uzyskaj licencję.
Nie istnieje osobna flaga licencji na poziomie pojedynczej funkcji. Responder jest podłączany do Twoich własnych fabryk PSR-17 w czasie działania — ResponseFactoryInterface i StreamFactoryInterface — a typ media domyślnie wynosi application/pdf jako argument konstruktora, a nie przełącznik licencji.
Instalacja
Dział zatytułowany „Instalacja”composer require nextpdf/proKod znajduje się w przestrzeni nazw NextPDF\Pro\Webview.
Przegląd koncepcyjny
Dział zatytułowany „Przegląd koncepcyjny”Zlinearyzowany PDF jest rozplanowany tak, aby pierwsza strona dokumentu — słownik parametrów linearyzacji, główny strumień podpowiedzi (hint stream) oraz obiekty strony 1 — znalazła się w wiodącej sekcji kończącej się na przesunięciu /E. Webview zamienia ten układ w dostarczanie progresywne.
LinearizedDocument::fromBytes() parsuje bajty przez odczytową LinearizationView z Core (Pro nigdy nie reimplementuje parsowania linearyzacji) i odrzuca wszystko, co nie jest użytecznym zlinearyzowanym dokumentem: w ogóle niezlinearyzowanym, z zadeklarowaną długością /L, która nie pasuje do rzeczywistej długości bajtów, lub z przesunięciem końca pierwszej strony /E, które nie jest dodatnim przesunięciem wewnątrz pliku. Konstrukcja jest zatem całkowita — gdy już dysponujesz LinearizedDocument, każde udostępniane przez niego przesunięcie jest wiarygodne.
ByteRangeResponder następnie odpowiada na żądanie HTTP. Jest zaimplementowany wyłącznie względem PSR-7 / PSR-17, bez powiązania z frameworkiem. Zawsze ogłasza Accept-Ranges: bytes oraz silny, deterministyczny ETag SHA-256, parsuje nagłówek Range klienta zgodnie z RFC 9110 §14 i zwraca albo pełne 200 OK, albo pojedynczy zakres 206 Partial Content, albo odpowiedź 206 multipart/byteranges dla kilku zakresów, albo 416 Range Not Satisfiable.
FirstPageProber to strona dowodu strukturalnego: kwantyfikuje prefiks pierwszej strony, ułamek całego pliku, który ten prefiks reprezentuje, oraz to, czy główny strumień podpowiedzi leży w całości wewnątrz niego — właściwość, która pozwala czytnikowi zlokalizować obiekty strony 1 z samego prefiksu.
Dlaczego działa w ten sposób
Dział zatytułowany „Dlaczego działa w ten sposób”Webview nigdy sam nie parsuje ponownie linearyzacji. Zapożycza odczytową LinearizationView z Core, więc warstwa dostarczania dziedziczy jeden audytowany parser zamiast drugiej, rozjeżdżającej się kopii. Konstrukcja jest celowo całkowita. LinearizedDocument::fromBytes() z góry odrzuca nieprawidłowy układ, więc każde przesunięcie, któremu ufa odpowiedź Range, zostało najpierw zwalidowane. Responder mówi wyłącznie w PSR-7 i PSR-17, więc ten sam kod serwuje zlinearyzowany PDF z dowolnego stosu HTTP. To właśnie ta dyscyplina sprawia, że progresywne dostarczanie zakresów można bezpiecznie udostępniać niezaufanym klientom na dużą skalę.
Kontekst projektowy: Generowanie dokumentów o dużej objętości.
Jak działa progresywne serwowanie zakresów bajtów
Dział zatytułowany „Jak działa progresywne serwowanie zakresów bajtów”- Zbuduj
LinearizedDocumentz wyrenderowanych bajtów PDF. Nieprawidłowe dane wejściowe od razu zgłaszająUnsupportedDocumentException. - Przekaż dokument oraz przychodzące
ServerRequestInterfacePSR-7 doByteRangeResponder::respond(). Responder odczytujeRange(oraz opcjonalny warunek wstępnyIf-Range) i produkuje poprawneResponseInterfacePSR-7. - Klient najpierw żąda wiodącego prefiksu (lub wypychasz go za pomocą
firstPageResponse()), renderuje stronę 1, a następnie żąda pozostałych zakresów w miarę przewijania przez użytkownika.
Model zakresów bajtów używa przesunięć inkluzywnych zgodnie z RFC 9110 §14.1.2: ByteRange to firstByte–lastByte w reprezentacji o contentLength, a jego pole Content-Range to bytes first-last/length.
Kontrakt zachowania
Dział zatytułowany „Kontrakt zachowania”LinearizedDocument::fromBytes()jest całkowite: dokument niezlinearyzowany, niezgodność/Llub niedodatnie / wykraczające poza plik przesunięcie/Ezgłaszają każdeUnsupportedDocumentException, zamiast wytworzyć niebezpieczny dokument.ETagto silny entity-tag SHA-256 nad dokładnymi bajtami, memoizowany raz przy konstrukcji. Identyczne dane wejściowe renderowania dają identyczne bajty, a więc identycznyETag, więc pamięci podręczne orazIf-Rangezachowują się przewidywalnie.- Żądanie bez stosowalnego
Rangezwraca200 OKz pełnym ciałem.If-Range, który nie pasuje do bieżącego silnegoETag, powoduje zignorowanieRangei zwrócenie pełnego200(RFC 9110 §13.1.5). Honorowana jest wyłącznie forma silnego entity-tag dlaIf-Range;If-Rangew postaci daty HTTP jest traktowany jako brak dopasowania. - Nierozpoznana jednostka zakresu lub składniowo nieprawidłowy
Rangejest ignorowany i zwracane jest pełne200(RFC 9110 §14.2). - Jeden spełnialny zakres zwraca
206 Partial ContentzContent-Range; wiele spełnialnych zakresów zwraca206multipart/byteranges. Prawidłowe zakresy bajtów, z których żaden nie jest spełnialny, zwracają416zContent-Range: bytes */length(RFC 9110 §15.3.7). firstPageResponse()emituje206niosące dokładnie zakres bajtów pierwszej strony[0, /E - 1]— forma server-push „pierwsza strona przed pełnym pobraniem”.
Przykład kodu — Szybki start
Dział zatytułowany „Przykład kodu — Szybki start”Poniższe odzwierciedla udokumentowane publiczne API. Repozytorium nie dostarcza uruchamialnego przykładu dla tego modułu.
use NextPDF\Pro\Webview\LinearizedDocument;use NextPDF\Pro\Webview\ByteRangeResponder;
$document = LinearizedDocument::fromBytes($pdfBytes);$responder = new ByteRangeResponder($responseFactory, $streamFactory);
$response = $responder->respond($document, $request);Przykład kodu — Wypychanie i sondowanie pierwszej strony
Dział zatytułowany „Przykład kodu — Wypychanie i sondowanie pierwszej strony”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);}Przypadki brzegowe i pułapki
Dział zatytułowany „Przypadki brzegowe i pułapki”- Webview wymaga prawdziwie zlinearyzowanego PDF. Jeśli wyrenderowany dokument nie jest zlinearyzowany, włącz linearyzację w czasie renderowania lub serwuj go zwykłym pełnym dostarczaniem —
respondToBytes()nadal potrafi serwować zakresy nad dowolnymi (niezlinearyzowanymi) bajtami, gdy potrzebujesz tylko obsługi zakresów, a nie semantyki pierwszej strony. - Aktualizacje przyrostowe mają znaczenie: dokument, do którego dopisano dane poza jego zadeklarowanym
/L, jest odrzucany jako niezgodność długości, ponieważ przesunięcia zakresów bajtów przestałyby być wiarygodne. - Responder ogranicza liczbę odrębnych zakresów, które honoruje na żądanie. Żądanie o więcej scalonych zakresów niż limit, lub o więcej łącznych bajtów niż cała reprezentacja, ma swój
Rangezignorowany i jest obsługiwane pełnym200.
Wydajność
Dział zatytułowany „Wydajność”Prefiks pierwszej strony to przesunięcie końca pierwszej strony /E przycięte do długości pliku, więc FirstPageProber::prefixFraction() raportuje, jak małe jest początkowe pobranie względem całego pliku — dla dokumentu wielostronicowego to cały sens Fast Web View. Budowanie odpowiedzi wycina łańcuch bajtów z pamięci; koszt jest proporcjonalny do wybranych bajtów. ETag jest obliczany raz na dokument. Mierz na reprezentatywnych dokumentach.
Uwagi dotyczące bezpieczeństwa
Dział zatytułowany „Uwagi dotyczące bezpieczeństwa”Traktuj dane wejściowe jako niezaufane. LinearizedDocument::fromBytes() waliduje niezmienniki linearyzacji przed użyciem jakiegokolwiek przesunięcia. Responder odrzuca contentType zawierający znaki sterujące, aby zapobiec wstrzyknięciu nagłówka, wyprowadza granicę multipart, która z gwarancją nie wystąpi wewnątrz ciała, oraz scala nakładające się zakresy i ogranicza ich liczbę i łączny rozmiar, aby bronić się przed klasą ataków odmowy usługi typu multipart range-amplification (Apache HTTPD CVE-2011-3192). Ten moduł nie loguje żadnej treści dokumentu.
Zgodność
Dział zatytułowany „Zgodność”Dostarczanie zakresów bajtów jest zgodne z RFC 9110 (HTTP Semantics) — §14 dla żądań zakresów, §13.1.5 dla If-Range oraz §15.3.7 dla 416. Model zlinearyzowanego dokumentu to układ Fast Web View opisany w ISO 32000-2 Annex F. Moduł nie deklaruje żadnych dalszych zewnętrznych identyfikatorów klauzul poza zachowaniem zweryfikowanym jego testami.
Uwaga o granicy Enterprise
Dział zatytułowany „Uwaga o granicy Enterprise”Enterprise nie zmienia zachowania Webview. Enterprise dodaje funkcje zgodności i archiwizacji wyższego poziomu, udokumentowane osobno; nie są one wymagane do serwowania zlinearyzowanego PDF przez zakresy bajtów.
Granica publikacji
Dział zatytułowany „Granica publikacji”Ta strona dokumentuje wyłącznie zewnętrznie obserwowalne zachowanie oraz wspieraną publiczną powierzchnię API. Wewnętrzne ścieżki przestrzeni nazw, klasy pomocnicze, tabele mechanizmów, nazwy plików runbooków oraz prefiksy zgłoszeń są poza zakresem.