Pro edición
Webview — Referencia detallada
De un vistazo
Sección titulada «De un vistazo»Esta página documenta la superficie pública NextPDF\Pro\Webview, el modelo de solicitud/respuesta por rango de bytes y los modos de fallo exactos, más allá de la página de presentación pública.
Disponibilidad y licenciamiento
Sección titulada «Disponibilidad y licenciamiento»Esta capacidad se distribuye en NextPDF Pro (nextpdf/pro) y se activa con un sobre de licencia de nivel Pro. Un despliegue sin ese derecho no carga las clases de la capacidad. Compare ediciones y obtenga una licencia.
No existe ningún indicador de licencia por característica; el código se distribuye con la edición Pro. El ResponseFactoryInterface / StreamFactoryInterface de PSR-17 y el tipo de medio del cuerpo son parámetros de constructor en tiempo de ejecución, no controles de licenciamiento.
Superficie de la API pública
Sección titulada «Superficie de la API pública»composer require nextpdf/proTipos públicos bajo NextPDF\Pro\Webview:
LinearizedDocument— un PDF linealizado validado y preparado para la entrega.ByteRangeResponder— el responder HTTP por rango de bytes RFC 9110.ByteRange— un rango de bytes inclusivo satisfacible sobre una representación.FirstPageProber— la prueba estructural de «la primera página antes de la descarga completa».
Tipos de excepción bajo NextPDF\Pro\Webview\Exception:
WebviewException(interfaz marcadora),UnsupportedDocumentException,RangeNotSatisfiableException.
LinearizedDocument
Sección titulada «LinearizedDocument»Una clase final readonly con un constructor privado; se instancia mediante el constructor con nombre.
static fromBytes(string $bytes): self— analiza los bytes a través delLinearizationView::fromPdf()del lado de lectura de Core. LanzaUnsupportedDocumentExceptioncuando el documento no está linealizado, cuando el/Ldeclarado no coincide con la longitud real en bytes, o cuando el desplazamiento/Ede fin de primera página no es un desplazamiento positivo dentro del archivo.length(): int— la longitud del documento en bytes.firstPagePrefixLength(): int— el prefijo inicial mínimo que contiene la primera página completa: el desplazamiento/E, recortado a la longitud del archivo.firstPageByteRange(): ByteRange— el rango inclusivo[0, /E - 1]que entrega la primera página. LanzaRangeNotSatisfiableExceptionsolo si el prefijo está vacío (defensa en profundidad;fromBytes()ya garantiza0 < /E <= length).slice(int $firstByte, int $lastByte): string— corte programático estricto con desplazamientos inclusivos; lanzaRangeNotSatisfiableExceptioncuando está fuera de límites.etag(): string— la etiqueta de entidad SHA-256 fuerte y determinista para los bytes, memoizada una sola vez en la construcción.
Propiedades públicas de solo lectura: bytes (los bytes en bruto del PDF) y view (el LinearizationView de Core).
ByteRangeResponder
Sección titulada «ByteRangeResponder»Una clase final readonly implementada únicamente contra PSR-7 / PSR-17.
__construct(ResponseFactoryInterface $responses, StreamFactoryInterface $streams, string $contentType = 'application/pdf')— lanzaInvalidArgumentExceptioncuando$contentTypecontiene caracteres de control (se interpola en las cabeceras de respuesta y de las partes multipart; CR/LF y otros bytes de control se rechazan para impedir la inyección de cabeceras).respond(LinearizedDocument $document, ServerRequestInterface $request): ResponseInterface— responde a una solicitud de rango para un documento linealizado, usando el propioETagdel documento.respondToBytes(string $bytes, ServerRequestInterface $request, ?string $etag = null): ResponseInterface— responde a una solicitud de rango para bytes arbitrarios (una representación que debe admitir rangos sin estar linealizada). ElETagse deriva de los bytes cuando esnull.firstPageResponse(LinearizedDocument $document): ResponseInterface— construye un206que transporta exactamente el rango de bytes de la primera página; la forma de envío por servidor de «la primera página antes de la descarga completa».
ByteRange
Sección titulada «ByteRange»Un objeto de valor final readonly para un único rango de bytes inclusivo satisfacible (RFC 9110 §14.1.2).
__construct(int $firstByte, int $lastByte, int $contentLength)— impone la satisfacibilidad0 <= firstByte <= lastByte <= contentLength - 1; lanzaRangeNotSatisfiableExceptionen caso contrario.length(): int— el tramo inclusivo (lastByte - firstByte + 1), siempre>= 1.contentRange(): string— el valor del campoContent-Rangede RFC 9110 §14.4bytes first-last/length.
Propiedades públicas de solo lectura: firstByte, lastByte, contentLength.
FirstPageProber
Sección titulada «FirstPageProber»Una clase final readonly construida a partir de un LinearizedDocument.
prefixLength(): int— recuento mínimo de bytes iniciales necesario para renderizar la primera página.prefixFraction(): float— fracción de todo el archivo (0.0–1.0) que representa el prefijo; devuelve1.0para un archivo de longitud cero.hintStreamWithinPrefix(): bool— si el objeto de flujo de pistas primario se encuentra por completo dentro del prefijo de la primera página (de modo que el prefijo por sí solo permite a un lector localizar los objetos de la página 1). El flujo de pistas debe tener longitud positiva.isFirstPageSelfContained(): bool— la prueba estructural combinada: un prefijo positivo que cabe dentro del archivo y contiene por completo el flujo de pistas.
Modelo de solicitud/respuesta por rango de bytes
Sección titulada «Modelo de solicitud/respuesta por rango de bytes»ByteRangeResponder sigue RFC 9110 §14. Tras calcular la longitud y un ETag SHA-256 fuerte, lee las cabeceras Range e If-Range y decide:
| Condición | Estado | Notas |
|---|---|---|
Sin Range aplicable, o If-Range no coincide con el ETag fuerte actual | 200 OK | Cuerpo completo. Solo se respeta la forma de etiqueta de entidad fuerte de If-Range (RFC 9110 §13.1.5). |
Unidad de rango no reconocida o Range sintácticamente no válido | 200 OK | La cabecera se ignora (RFC 9110 §14.2). |
| Un rango satisfacible | 206 Partial Content | Transporta Content-Range. |
| Varios rangos satisfacibles | 206 Partial Content | multipart/byteranges con un límite derivado. |
| Rangos de bytes válidos, ninguno satisfacible | 416 Range Not Satisfiable | Transporta Content-Range: bytes */length (RFC 9110 §15.3.7). |
Toda respuesta anuncia Accept-Ranges: bytes y el ETag fuerte. Las respuestas 200 y 206 también establecen Content-Type y Content-Length.
El análisis de rangos acepta únicamente la unidad bytes=. Admite first-last explícito, first- abierto (recortado al final) y el sufijo -N (los N bytes finales; un sufijo al menos tan grande como la representación selecciona toda ella). Un - solitario (o cualquier otra especificación malformada) hace que toda la cabecera Range sea sintácticamente no válida, de modo que la cabecera se ignora y se devuelve la representación 200 OK completa. Un sufijo -0, o cualquier especificación cuyo primer desplazamiento esté en el final o más allá, es una especificación insatisfacible y se descarta; si ninguna especificación de la cabecera es satisfacible, la respuesta es 416 Range Not Satisfiable. Los desplazamientos decimales grandes se comparan sin depender de la saturación por desbordamiento de enteros, de modo que un valor Range de 30 dígitos se gestiona de forma independiente de la plataforma. Los rangos satisfacibles solapados se fusionan antes de construir ningún cuerpo; los rangos genuinamente distintos (no solapados) se conservan como partes multipart separadas.
Modos de fallo y modelo de excepciones
Sección titulada «Modos de fallo y modelo de excepciones»WebviewException es una interfaz marcadora que extiende Throwable; captúrela para gestionar todo el subsistema de forma uniforme. Ambas excepciones concretas la implementan.
UnsupportedDocumentException(extiendeInvalidArgumentException) — la lanzaLinearizedDocument::fromBytes()cuando los bytes no son un documento linealizado utilizable. Constructores con nombre:notLinearized()(sin diccionario de parámetros/Linearized),lengthMismatch($declaredLength, $actualLength)(el/Ldeclarado no coincide con la longitud real — truncado, anexado mediante una actualización incremental más allá de/L, o no conforme), ymalformedFirstPageOffset($firstPageEndOffset, $length)(el desplazamiento/Eno es un desplazamiento positivo dentro del archivo).RangeNotSatisfiableException(extiendeOutOfRangeException) — el error de corte programático, lanzado porByteRange::__construct()yLinearizedDocument::slice()/firstPageByteRange()cuando un rango inclusivo cae fuera del documento. Constructor con nombre:outOfBounds($firstByte, $lastByte, $length).
El responder HTTP no lanza RangeNotSatisfiableException para las cabeceras Range del cliente: un rango HTTP insatisfacible es una respuesta 416 (RFC 9110 §15.3.7), no una excepción. Esa excepción se reserva para el corte programático directo, donde una solicitud fuera de límites es un error del llamante. ByteRangeResponder::__construct() lanza una InvalidArgumentException simple (no una WebviewException) cuando el contentType configurado contiene caracteres de control.
Endurecimiento contra la denegación de servicio
Sección titulada «Endurecimiento contra la denegación de servicio»El responder limita el número de rangos fusionados distintos que respeta por solicitud (la clase de amplificación de rango multipart, Apache HTTPD CVE-2011-3192). Cuando una solicitud pide más rangos fusionados que el límite, o más bytes totales que toda la representación, el Range se ignora y se devuelve un 200 completo. El límite multipart se deriva de forma determinista y se vuelve a derivar hasta que está garantizado que no aparece dentro del cuerpo, preservando una salida reproducible a la vez que se descarta la colisión de límites.
Conformidad
Sección titulada «Conformidad»El comportamiento por rango de bytes sigue RFC 9110 (HTTP Semantics): §14 (solicitudes de rango), §13.1.5 (If-Range), §14.4 (Content-Range) y §15.3.7 (416). La disposición de documento linealizado es el modelo Fast Web View de ISO 32000-2 Annex F. El módulo no afirma más identificadores de cláusula externos que el comportamiento verificado por sus pruebas.
Casos límite y comportamiento en modo FIPS
Sección titulada «Casos límite y comportamiento en modo FIPS»respondToBytes()sirve rangos sobre bytes arbitrarios cuando no se necesita la semántica de primera página.- Un validador
If-Rangede fecha HTTP se trata como una no coincidencia →200completo (el cliente simplemente vuelve a obtener el archivo). - El
ETages un hash SHA-256 usado puramente como validador de caché fuerte; este módulo no realiza ninguna firma ni otra operación criptográfica y no define ningún comportamiento específico de FIPS.
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 de alcance.