Pro エディション
Webview — 詳細リファレンス
このページでは、公開ランディングページの範囲を超えて、公開された NextPDF\Pro\Webview サーフェス、バイトレンジのリクエスト/レスポンスモデル、そして正確な失敗モードを記述します。
提供状況とライセンス
「提供状況とライセンス」という見出しのセクションこの機能は NextPDF Pro(nextpdf/pro)で提供され、Pro ティアのライセンスエンベロープで有効化されます。そのエンタイトルメントを持たないデプロイメントは、この機能のクラスをロードしません。エディションを比較してライセンスを取得。
機能ごとのライセンスフラグはありません。コードは Pro エディションに同梱されています。PSR-17 の ResponseFactoryInterface / StreamFactoryInterface と本文のメディアタイプは、ライセンス制御ではなくランタイムのコンストラクターパラメーターです。
公開 API サーフェス
「公開 API サーフェス」という見出しのセクションcomposer require nextpdf/proNextPDF\Pro\Webview の下の公開型:
LinearizedDocument— 配信用に準備された、検証済みの線形化済み PDF。ByteRangeResponder— RFC 9110 のバイトレンジ HTTP レスポンダー。ByteRange— 表現に対する 1 つの充足可能な包含的バイトレンジ。FirstPageProber— 「全体のダウンロード前に最初のページを」という構造的証明。
NextPDF\Pro\Webview\Exception の下の例外型:
WebviewException(マーカーインターフェース)、UnsupportedDocumentException、RangeNotSatisfiableException。
LinearizedDocument
「LinearizedDocument」という見出しのセクションprivate コンストラクターを持つ final readonly クラス。名前付きコンストラクターを介してインスタンス化します。
static fromBytes(string $bytes): self— Core の読み取り側LinearizationView::fromPdf()を通じてバイト列を解析します。ドキュメントが線形化されていない場合、宣言された/Lが実際のバイト長と一致しない場合、または/E(最初のページの末尾)オフセットがファイル内の正のオフセットでない場合に、UnsupportedDocumentExceptionをスローします。length(): int— ドキュメントの長さ(バイト)。firstPagePrefixLength(): int— 完全な最初のページを含む最小の先頭プレフィックス。ファイル長にクランプされた/Eオフセットです。firstPageByteRange(): ByteRange— 最初のページを配信する包含的レンジ[0, /E - 1]。プレフィックスが空の場合にのみRangeNotSatisfiableExceptionをスローします(多層防御。fromBytes()はすでに0 < /E <= lengthを保証しています)。slice(int $firstByte, int $lastByte): string— 包含的オフセットによる厳格なプログラムによるスライス。範囲外のときRangeNotSatisfiableExceptionをスローします。etag(): string— バイト列に対する、強く決定論的な SHA-256 のエンティティタグ。構築時に一度だけメモ化されます。
公開 readonly プロパティ: bytes(生の PDF バイト列)と view(Core の LinearizationView)。
ByteRangeResponder
「ByteRangeResponder」という見出しのセクションPSR-7 / PSR-17 のみに対して実装された final readonly クラス。
__construct(ResponseFactoryInterface $responses, StreamFactoryInterface $streams, string $contentType = 'application/pdf')—$contentTypeが制御文字を含む場合にInvalidArgumentExceptionをスローします(これはレスポンスおよび multipart の各パートヘッダーに補間されるため、ヘッダーインジェクションを防ぐために CR/LF やその他の制御バイトは拒否されます)。respond(LinearizedDocument $document, ServerRequestInterface $request): ResponseInterface— ドキュメント自身のETagを用いて、線形化済みドキュメントに対するレンジリクエストに応答します。respondToBytes(string $bytes, ServerRequestInterface $request, ?string $etag = null): ResponseInterface— 任意のバイト列(線形化されていなくてもレンジをサポートすべき表現)に対するレンジリクエストに応答します。ETagはnullのときバイト列から導出されます。firstPageResponse(LinearizedDocument $document): ResponseInterface— 最初のページのバイトレンジをちょうど運ぶ206を構築します。「全体のダウンロード前に最初のページを」のサーバープッシュ形式です。
ByteRange
「ByteRange」という見出しのセクション単一の充足可能な包含的バイトレンジ(RFC 9110 §14.1.2)のための final readonly 値オブジェクト。
__construct(int $firstByte, int $lastByte, int $contentLength)— 充足可能性0 <= firstByte <= lastByte <= contentLength - 1を強制します。そうでなければRangeNotSatisfiableExceptionをスローします。length(): int— 包含的なスパン(lastByte - firstByte + 1)。常に>= 1です。contentRange(): string— RFC 9110 §14.4 のContent-Rangeフィールド値bytes first-last/length。
公開 readonly プロパティ: firstByte、lastByte、contentLength。
FirstPageProber
「FirstPageProber」という見出しのセクションLinearizedDocument から構築される final readonly クラス。
prefixLength(): int— 最初のページをレンダリングするために必要な、最小の先頭バイト数。prefixFraction(): float— プレフィックスが表すファイル全体の割合(0.0–1.0)。長さ 0 のファイルに対しては1.0を返します。hintStreamWithinPrefix(): bool— プライマリヒントストリームオブジェクトが最初のページのプレフィックスの内側に完全に収まっているか(そのためプレフィックスだけでリーダーがページ 1 のオブジェクトを特定できるか)。ヒントストリームは正の長さを持たなければなりません。isFirstPageSelfContained(): bool— 結合された構造的証明。ファイル内に収まり、かつヒントストリームを完全に含む、正のプレフィックスであること。
バイトレンジのリクエスト/レスポンスモデル
「バイトレンジのリクエスト/レスポンスモデル」という見出しのセクションByteRangeResponder は RFC 9110 §14 に従います。長さと強い SHA-256 の ETag を計算した後、Range ヘッダーと If-Range ヘッダーを読み取り、次のように決定します。
| 条件 | ステータス | 注記 |
|---|---|---|
適用可能な Range がない、または If-Range が現在の強い ETag と一致しない | 200 OK | 全本文。If-Range は強いエンティティタグ形式のみが尊重されます(RFC 9110 §13.1.5)。 |
認識されないレンジ単位、または構文的に無効な Range | 200 OK | ヘッダーは無視されます(RFC 9110 §14.2)。 |
| 1 つの充足可能なレンジ | 206 Partial Content | Content-Range を運びます。 |
| 複数の充足可能なレンジ | 206 Partial Content | 導出された境界を伴う multipart/byteranges。 |
| 有効なバイトレンジでありながら、いずれも充足不可能 | 416 Range Not Satisfiable | Content-Range: bytes */length を運びます(RFC 9110 §15.3.7)。 |
すべてのレスポンスは Accept-Ranges: bytes と強い ETag をアドバタイズします。200 および 206 のレスポンスは、Content-Type と Content-Length も設定します。
レンジ解析は bytes= 単位のみを受け付けます。明示的な first-last、開放端の first-(末尾にクランプ)、サフィックス -N(最後の N バイト。表現と同じかそれ以上のサフィックスはその全体を選択)をサポートします。裸の -(またはその他の不正な spec)は Range ヘッダー全体を構文的に無効にするため、ヘッダーは無視され、全体の 200 OK 表現が返されます。-0 サフィックス、または最初のオフセットが末尾以上であるあらゆる spec は、充足不可能な spec であり、破棄されます。ヘッダー内のどの spec も充足可能でない場合、レスポンスは 416 Range Not Satisfiable です。大きな 10 進オフセットは整数オーバーフローの飽和に依存せずに比較されるため、30 桁の Range 値はプラットフォームに依存せず扱われます。重複する充足可能なレンジは、本文が構築される前に結合されます。真に異なる(重複しない)レンジは、別個の multipart パートとして保持されます。
失敗モードと例外モデル
「失敗モードと例外モデル」という見出しのセクションWebviewException は Throwable を拡張するマーカーインターフェースです。サブシステム全体を統一的に処理するにはこれをキャッチしてください。具体的な両方の例外がこれを実装します。
UnsupportedDocumentException(InvalidArgumentExceptionを拡張) — バイト列が使用可能な線形化済みドキュメントでないときにLinearizedDocument::fromBytes()によって発生します。名前付きコンストラクター:notLinearized()(/Linearizedパラメーターディクショナリがない)、lengthMismatch($declaredLength, $actualLength)(宣言された/Lが実際の長さと一致しない — 切り詰められた、/Lを超える差分更新で追記された、または非準拠)、malformedFirstPageOffset($firstPageEndOffset, $length)(/Eオフセットがファイル内の正のオフセットでない)。RangeNotSatisfiableException(OutOfRangeExceptionを拡張) — プログラムによるスライスのエラー。包含的レンジがドキュメントの外側に収まるときにByteRange::__construct()およびLinearizedDocument::slice()/firstPageByteRange()によって発生します。名前付きコンストラクター:outOfBounds($firstByte, $lastByte, $length)。
HTTP レスポンダーは、クライアントの Range ヘッダーに対して RangeNotSatisfiableException をスローしません — 充足不可能な HTTP レンジは 416 レスポンス(RFC 9110 §15.3.7)であり、例外ではありません。その例外は、範囲外のリクエストが呼び出し元のエラーである、直接的なプログラムによるスライスのために予約されています。ByteRangeResponder::__construct() は、構成された contentType が制御文字を含むとき、(WebviewException ではなく)素の InvalidArgumentException をスローします。
サービス拒否対策のハードニング
「サービス拒否対策のハードニング」という見出しのセクションレスポンダーは、1 リクエストあたりに尊重する個別の結合済みレンジの数に上限を設けます(multipart レンジ増幅クラス、Apache HTTPD CVE-2011-3192)。リクエストが結合済みレンジの上限を超えて要求するか、表現全体を超える合計バイト数を要求すると、Range は無視され、全体の 200 が返されます。multipart の境界は決定論的に導出され、本文内に出現しないことが保証されるまで再導出されるため、再現可能な出力を保ちつつ境界の衝突を排除します。
バイトレンジの振る舞いは RFC 9110(HTTP Semantics)に従います。すなわち §14(レンジリクエスト)、§13.1.5(If-Range)、§14.4(Content-Range)、§15.3.7(416)です。線形化済みドキュメントのレイアウトは ISO 32000-2 Annex F の Fast Web View モデルです。このモジュールは、テストによって検証された振る舞いを超えて、外部の節識別子を一切主張しません。
エッジケースと FIPS モードの振る舞い
「エッジケースと FIPS モードの振る舞い」という見出しのセクションrespondToBytes()は、最初のページのセマンティクスが必要ない場合に、任意のバイト列に対してレンジを提供します。If-Rangeの HTTP-date バリデーターは非一致として扱われます → 全体の200(クライアントは単に再フェッチします)。ETagは、強いキャッシュバリデーターとして純粋に使用される SHA-256 ハッシュです。このモジュールは署名やその他の暗号操作を一切実行せず、FIPS 固有の振る舞いを定義しません。
公開範囲の境界
「公開範囲の境界」という見出しのセクションこのページは、外部から観測可能な振る舞いと、サポートされる公開 API サーフェスのみを記述します。内部の名前空間パス、ヘルパークラス、メカニズムの表、ランブックのファイル名、チケットのプレフィックスは対象外です。