Pro edición
Webview
De un vistazo
Sección titulada «De un vistazo»Webview entrega un PDF linealizado (Fast Web View) por HTTP, de modo que un cliente pueda empezar a renderizar la página 1 a partir de un pequeño prefijo inicial mientras el resto del archivo todavía está en tránsito. Envuelve los bytes en bruto como un LinearizedDocument, responde a las solicitudes Range con respuestas de contenido parcial RFC 9110 a través de un ByteRangeResponder PSR-7, y puede demostrar (mediante FirstPageProber) que la primera página está contenida por completo en el prefijo.
Disponibilidad y licencias
Sección titulada «Disponibilidad y licencias»Esta capacidad se incluye en NextPDF Pro (nextpdf/pro) y se activa con un sobre de licencia de nivel Pro. Una implementación sin ese derecho no carga las clases de la capacidad. Compare ediciones y obtenga una licencia.
No hay ningún indicador de licencia por característica independiente. El responder se conecta a sus propias fábricas PSR-17 en tiempo de ejecución —una ResponseFactoryInterface y una StreamFactoryInterface— y el tipo de medio toma por defecto application/pdf como argumento del constructor, no como un interruptor de licencia.
Instalación
Sección titulada «Instalación»composer require nextpdf/proEl código reside bajo el espacio de nombres NextPDF\Pro\Webview.
Descripción conceptual
Sección titulada «Descripción conceptual»Un PDF linealizado se dispone de modo que la primera página del documento —el diccionario de parámetros de linealización, el flujo de pistas primario y los objetos de la página 1— se sitúa en una sección inicial que termina en el desplazamiento /E. Webview convierte esa disposición en entrega progresiva.
LinearizedDocument::fromBytes() analiza los bytes a través del LinearizationView del lado de lectura de Core (Pro nunca reimplementa el análisis de linealización) y rechaza cualquier cosa que no sea un documento linealizado utilizable: que no esté linealizado en absoluto, una longitud /L declarada que no coincide con la longitud real en bytes, o un desplazamiento /E de fin de primera página que no es un desplazamiento positivo dentro del archivo. Por tanto, la construcción es total: una vez que se dispone de un LinearizedDocument, todo desplazamiento que expone es confiable.
ByteRangeResponder responde entonces a una solicitud HTTP. Está implementado únicamente contra PSR-7 / PSR-17, sin acoplamiento a ningún framework. Siempre anuncia Accept-Ranges: bytes y un ETag SHA-256 fuerte y determinista, analiza la cabecera Range del cliente según RFC 9110 §14, y devuelve un 200 OK completo, un 206 Partial Content de un único rango, una respuesta 206 multipart/byteranges para varios rangos, o un 416 Range Not Satisfiable.
FirstPageProber es el lado de la prueba estructural: cuantifica el prefijo de la primera página, la fracción de todo el archivo que representa ese prefijo, y si el flujo de pistas primario se encuentra por completo dentro de él, la propiedad que permite a un lector localizar los objetos de la página 1 solo a partir del prefijo.
Por qué funciona así
Sección titulada «Por qué funciona así»Webview nunca reanaliza la linealización por sí mismo. Toma prestado el LinearizationView del lado de lectura de Core, de modo que la capa de entrega hereda un único analizador auditado en lugar de una segunda copia que va divergiendo. La construcción es deliberadamente total. LinearizedDocument::fromBytes() rechaza de entrada una disposición mal formada, de modo que todo desplazamiento en el que confía una respuesta Range fue validado primero. El responder habla únicamente PSR-7 y PSR-17, de modo que el mismo código sirve un PDF linealizado desde cualquier pila HTTP. Esa disciplina es lo que hace seguro exponer la entrega progresiva por rangos a clientes no confiables a gran volumen.
Contexto de diseño: Generación de documentos de alto volumen.
Cómo funciona el servicio progresivo por rango de bytes
Sección titulada «Cómo funciona el servicio progresivo por rango de bytes»- Construya un
LinearizedDocumenta partir de los bytes del PDF renderizado. Una entrada no válida provocaUnsupportedDocumentExceptionde entrada. - Entregue el documento y el
ServerRequestInterfacePSR-7 entrante aByteRangeResponder::respond(). El responder leeRange(y la precondición opcionalIf-Range) y produce elResponseInterfacePSR-7 correcto. - El cliente solicita primero el prefijo inicial (o usted lo envía mediante
firstPageResponse()), renderiza la página 1 y luego solicita los rangos restantes a medida que el usuario se desplaza.
El modelo de rango de bytes usa desplazamientos inclusivos según RFC 9110 §14.1.2: un ByteRange es firstByte–lastByte sobre una representación de contentLength, y su campo Content-Range es bytes first-last/length.
Contrato de comportamiento
Sección titulada «Contrato de comportamiento»LinearizedDocument::fromBytes()es total: un documento no linealizado, una discrepancia de/Lo un desplazamiento/Eno positivo / fuera del archivo provocan, cada uno,UnsupportedDocumentExceptionen lugar de producir un documento inseguro.- El
ETages una etiqueta de entidad SHA-256 fuerte sobre los bytes exactos, memoizada una sola vez en la construcción. Una entrada de renderizado idéntica produce bytes idénticos y, por tanto, unETagidéntico, de modo que las cachés yIf-Rangese comportan de forma predecible. - Una solicitud sin ningún
Rangeaplicable devuelve200 OKcon el cuerpo completo. UnIf-Rangeque no coincide con elETagfuerte actual hace que se ignore elRangey se devuelva un200completo (RFC 9110 §13.1.5). Solo se respeta la forma de etiqueta de entidad fuerte deIf-Range; unIf-Rangede fecha HTTP se trata como una no coincidencia. - Una unidad de rango no reconocida o un
Rangesintácticamente no válido se ignora y se devuelve un200completo (RFC 9110 §14.2). - Un rango satisfacible devuelve
206 Partial ContentconContent-Range; varios rangos satisfacibles devuelven206multipart/byteranges. Rangos de bytes válidos sin ninguno satisfacible devuelven416conContent-Range: bytes */length(RFC 9110 §15.3.7). firstPageResponse()emite un206que transporta exactamente el rango de bytes de la primera página[0, /E - 1]: la forma de envío por servidor de «la primera página antes de la descarga completa».
Ejemplo de código — Inicio rápido
Sección titulada «Ejemplo de código — Inicio rápido»A continuación se refleja la API pública documentada. El repositorio no incluye un ejemplo ejecutable para este módulo.
use NextPDF\Pro\Webview\LinearizedDocument;use NextPDF\Pro\Webview\ByteRangeResponder;
$document = LinearizedDocument::fromBytes($pdfBytes);$responder = new ByteRangeResponder($responseFactory, $streamFactory);
$response = $responder->respond($document, $request);Ejemplo de código — Envío y sondeo de la primera página
Sección titulada «Ejemplo de código — Envío y sondeo de la primera página»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);}Casos límite y trampas
Sección titulada «Casos límite y trampas»- Webview requiere un PDF genuinamente linealizado. Si el documento renderizado no está linealizado, habilite la linealización en el momento del renderizado, o sírvalo con entrega completa simple —
respondToBytes()todavía puede servir rangos sobre bytes arbitrarios (no linealizados) cuando solo necesita compatibilidad con rangos, no semántica de primera página. - Las actualizaciones incrementales importan: un documento al que se anexó más allá de su
/Ldeclarado se rechaza como una discrepancia de longitud, porque los desplazamientos de rango de bytes ya no serían confiables. - El responder limita el número de rangos distintos que respeta por solicitud. Una solicitud que pide más rangos fusionados que el límite, o más bytes totales que toda la representación, ve ignorado su
Rangey se le sirve un200completo.
Rendimiento
Sección titulada «Rendimiento»El prefijo de la primera página es el desplazamiento /E de fin de primera página recortado a la longitud del archivo, por lo que FirstPageProber::prefixFraction() informa de lo pequeña que es la obtención inicial respecto a todo el archivo — para un documento de muchas páginas, este es todo el sentido de Fast Web View. La construcción de la respuesta corta la cadena de bytes en memoria; el costo es proporcional a los bytes seleccionados. El ETag se calcula una sola vez por documento. Mida con documentos representativos.
Notas de seguridad
Sección titulada «Notas de seguridad»Trate la entrada como no confiable. LinearizedDocument::fromBytes() valida las invariantes de linealización antes de usar ningún desplazamiento. El responder rechaza un contentType que contenga caracteres de control para impedir la inyección de cabeceras, deriva un límite multipart que está garantizado que no aparece dentro del cuerpo, y fusiona los rangos solapados y acota su número y tamaño total para defenderse de la clase de denegación de servicio por amplificación de rango multipart (Apache HTTPD CVE-2011-3192). Este módulo no registra ningún contenido del documento.
Conformidad
Sección titulada «Conformidad»La entrega por rango de bytes sigue RFC 9110 (HTTP Semantics): §14 para las solicitudes de rango, §13.1.5 para If-Range y §15.3.7 para 416. El modelo de documento linealizado es la disposición Fast Web View descrita por ISO 32000-2 Annex F. El módulo no afirma más identificadores de cláusula externos que el comportamiento verificado por sus pruebas.
Nota sobre el límite de Enterprise
Sección titulada «Nota sobre el límite de Enterprise»Enterprise no cambia el comportamiento de Webview. Enterprise añade funciones de cumplimiento y archivo de nivel superior documentadas por separado; no son necesarias para servir un PDF linealizado por rangos de bytes.
Límite de publicación
Sección titulada «Límite de publicación»Esta página documenta únicamente el comportamiento observable externamente y la superficie de API pública admitida. Las rutas de espacio de nombres internas, las clases auxiliares, las tablas de mecanismos, los nombres de archivo de runbook y los prefijos de tickets quedan fuera del alcance.