From 09a9a7bd0b84defde23e7a3bad814b8d77786c5a Mon Sep 17 00:00:00 2001 From: Jonas Jenwald Date: Tue, 10 Mar 2026 11:35:03 +0100 Subject: [PATCH] [api-minor] Remove the `length` parameter from `getDocument` This is an old API-parameter that is now unused within the PDF.js project itself, and its description says that it's (partly) being used for "range requests operations". Note that the `length` API-parameter is used to set the *initial* `contentLength` in various `BasePDFStreamReader` implementations, however it's always overridden by the "Content-Length" header (sent by the server) when that one exists *and* is a valid number. While we currently fallback to the keep the initial `contentLength` otherwise, note however how in that case range requests will always be *disabled* and thus the only spot in the code-base [where `fullReader.contentLength` is necessary](https://github.com/mozilla/pdf.js/blob/873378b71830a151d3350d812bf914b673149cd6/src/core/worker.js#L230-L236) cannot actually be reached. Hence the only possible reason to use the `length` API-parameter would be for improved progress reporting[1] during streaming of PDF data in rare cases where the "Content-Length" header is missing/invalid, but the user *somehow* has information from another source about the correct `length` of the PDF document. That situation feels very much like an edge-case, but it's obviously impossible to know if someone is depending on it. However, please note that there's a work-around available for users affected by this removal: - Implement a `PDFDataRangeTransport` instance together with custom data-fetching[2], since in that case its `length`-parameter will always be used as-is. Finally, updates various `BasePDFStreamReader` implementations to only set the `_isRangeSupported` field once the headers are available (since previously we'd just overwrite the "initial" value anyway). --- [1] I.e. to avoid the "indeterminate" loadingBar being displayed in the viewer. [2] This is what e.g. the Firefox PDF Viewer uses. --- src/core/worker.js | 10 ++-------- src/display/api.js | 5 ----- src/display/fetch_stream.js | 7 +------ src/display/network.js | 11 ++--------- src/display/network_utils.js | 2 +- src/display/node_stream.js | 14 ++++---------- test/unit/network_utils_spec.js | 2 +- 7 files changed, 11 insertions(+), 40 deletions(-) diff --git a/src/core/worker.js b/src/core/worker.js index 44e438a77..4aef9e996 100644 --- a/src/core/worker.js +++ b/src/core/worker.js @@ -196,7 +196,6 @@ class WorkerMessageHandler { password, disableAutoFetch, rangeChunkSize, - length, docBaseUrl, enableXfa, evaluatorOptions, @@ -209,7 +208,7 @@ class WorkerMessageHandler { enableXfa, evaluatorOptions, handler, - length, + length: 0, password, rangeChunkSize, }; @@ -287,14 +286,9 @@ class WorkerMessageHandler { } if (!newPdfManager) { - const pdfFile = arrayBuffersToBytes(cachedChunks); + pdfManagerArgs.source = arrayBuffersToBytes(cachedChunks); cachedChunks = null; - if (length && pdfFile.length !== length) { - warn("reported HTTP length is different from actual"); - } - pdfManagerArgs.source = pdfFile; - newPdfManager = new LocalPdfManager(pdfManagerArgs); resolve(newPdfManager); } diff --git a/src/display/api.js b/src/display/api.js index 23c994276..c8805b7bf 100644 --- a/src/display/api.js +++ b/src/display/api.js @@ -124,8 +124,6 @@ const RENDERING_CANCELLED_TIMEOUT = 100; // ms * cross-site Access-Control requests should be made using credentials such * as cookies or authorization headers. The default is `false`. * @property {string} [password] - For decrypting password-protected PDFs. - * @property {number} [length] - The PDF file length. It's used for progress - * reports and range requests operations. * @property {PDFDataRangeTransport} [range] - Allows for using a custom range * transport implementation. * @property {number} [rangeChunkSize] - Specify maximum number of bytes fetched @@ -353,7 +351,6 @@ function getDocument(src = {}) { const pagesMapper = src.pagesMapper || new PagesMapper(); // Parameters whose default values depend on other parameters. - const length = rangeTransport ? rangeTransport.length : (src.length ?? NaN); const useSystemFonts = typeof src.useSystemFonts === "boolean" ? src.useSystemFonts @@ -425,7 +422,6 @@ function getDocument(src = {}) { password, disableAutoFetch, rangeChunkSize, - length, docBaseUrl, enableXfa, evaluatorOptions: { @@ -497,7 +493,6 @@ function getDocument(src = {}) { networkStream = new NetworkStream({ url, - length, httpHeaders, withCredentials, rangeChunkSize, diff --git a/src/display/fetch_stream.js b/src/display/fetch_stream.js index 82270d7df..179f0a329 100644 --- a/src/display/fetch_stream.js +++ b/src/display/fetch_stream.js @@ -86,15 +86,12 @@ class PDFFetchStreamReader extends BasePDFStreamReader { const { disableRange, disableStream, - length, rangeChunkSize, url, withCredentials, } = stream._source; - this._contentLength = length; this._isStreamingSupported = !disableStream; - this._isRangeSupported = !disableRange; // Always create a copy of the headers. const headers = new Headers(stream.headers); @@ -114,10 +111,8 @@ class PDFFetchStreamReader extends BasePDFStreamReader { rangeChunkSize, disableRange, }); - + this._contentLength = contentLength; this._isRangeSupported = isRangeSupported; - // Setting right content length. - this._contentLength = contentLength || this._contentLength; this._filename = extractFilenameFromHeader(responseHeaders); diff --git a/src/display/network.js b/src/display/network.js index 86548c41f..a4d94be88 100644 --- a/src/display/network.js +++ b/src/display/network.js @@ -187,9 +187,6 @@ class PDFNetworkStreamReader extends BasePDFStreamReader { constructor(stream) { super(stream); - const { length } = stream._source; - - this._contentLength = length; // Note that `XMLHttpRequest` doesn't support streaming, and range requests // will be enabled (if supported) in `this.#onHeadersReceived` below. @@ -229,12 +226,8 @@ class PDFNetworkStreamReader extends BasePDFStreamReader { rangeChunkSize, disableRange, }); - - if (isRangeSupported) { - this._isRangeSupported = true; - } - // Setting right content length. - this._contentLength = contentLength || this._contentLength; + this._contentLength = contentLength; + this._isRangeSupported = isRangeSupported; this._filename = extractFilenameFromHeader(responseHeaders); diff --git a/src/display/network_utils.js b/src/display/network_utils.js index 67b2eb61a..bd2779706 100644 --- a/src/display/network_utils.js +++ b/src/display/network_utils.js @@ -50,7 +50,7 @@ function validateRangeRequestCapabilities({ ); } const rv = { - contentLength: undefined, + contentLength: 0, isRangeSupported: false, }; diff --git a/src/display/node_stream.js b/src/display/node_stream.js index 0d57ee789..0b4c9454e 100644 --- a/src/display/node_stream.js +++ b/src/display/node_stream.js @@ -62,12 +62,9 @@ class PDFNodeStreamReader extends BasePDFStreamReader { constructor(stream) { super(stream); - const { disableRange, disableStream, length, rangeChunkSize, url } = - stream._source; + const { disableRange, disableStream, rangeChunkSize, url } = stream._source; - this._contentLength = length; this._isStreamingSupported = !disableStream; - this._isRangeSupported = !disableRange; const fs = process.getBuiltinModule("fs"); fs.promises @@ -79,13 +76,10 @@ class PDFNodeStreamReader extends BasePDFStreamReader { this._reader = readableStream.getReader(); const { size } = stat; - if (size <= 2 * rangeChunkSize) { - // The file size is smaller than the size of two chunks, so it doesn't - // make any sense to abort the request and retry with a range request. - this._isRangeSupported = false; - } - // Setting right content length. this._contentLength = size; + // When the file size is smaller than the size of two chunks, it doesn't + // make any sense to abort the request and retry with a range request. + this._isRangeSupported = !disableRange && size > 2 * rangeChunkSize; // We need to stop reading when range is supported and streaming is // disabled. diff --git a/test/unit/network_utils_spec.js b/test/unit/network_utils_spec.js index 7890fcfc6..89d20f181 100644 --- a/test/unit/network_utils_spec.js +++ b/test/unit/network_utils_spec.js @@ -153,7 +153,7 @@ describe("network_utils", function () { }) ).toEqual({ isRangeSupported: false, - contentLength: undefined, + contentLength: 0, }); });