Skip to content

Commit d152e92

Browse files
Merge pull request #20614 from Snuffleupagus/BasePDFStream-url
Change all relevant `BasePDFStream` implementations to take an actual `URL` instance
2 parents f4326e1 + 6509fdb commit d152e92

11 files changed

Lines changed: 46 additions & 41 deletions

src/display/api_utils.js

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,21 +25,26 @@ function getUrlProp(val) {
2525
return null; // The 'url' is unused with `PDFDataRangeTransport`.
2626
}
2727
if (val instanceof URL) {
28-
return val.href;
28+
return val;
2929
}
3030
if (typeof val === "string") {
3131
if (
3232
typeof PDFJSDev !== "undefined" &&
3333
PDFJSDev.test("GENERIC") &&
3434
isNodeJS
3535
) {
36-
return val; // Use the url as-is in Node.js environments.
36+
if (/^[a-z][a-z0-9\-+.]+:/i.test(val)) {
37+
return new URL(val);
38+
}
39+
// eslint-disable-next-line no-undef
40+
const url = process.getBuiltinModule("url");
41+
return new URL(url.pathToFileURL(val));
3742
}
3843

3944
// The full path is required in the 'url' field.
4045
const url = URL.parse(val, window.location);
4146
if (url) {
42-
return url.href;
47+
return url;
4348
}
4449
}
4550
throw new Error(

src/display/display_utils.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -464,7 +464,7 @@ function isValidFetchUrl(url, baseUrl) {
464464
}
465465
const res = baseUrl ? URL.parse(url, baseUrl) : URL.parse(url);
466466
// The Fetch API only supports the http/https protocols, and not file/ftp.
467-
return res?.protocol === "http:" || res?.protocol === "https:";
467+
return /https?:/.test(res?.protocol ?? "");
468468
}
469469

470470
/**

src/display/fetch_stream.js

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
* limitations under the License.
1414
*/
1515

16-
import { AbortException, warn } from "../shared/util.js";
16+
import { AbortException, assert, warn } from "../shared/util.js";
1717
import {
1818
BasePDFStream,
1919
BasePDFStreamRangeReader,
@@ -67,8 +67,13 @@ class PDFFetchStream extends BasePDFStream {
6767

6868
constructor(source) {
6969
super(source, PDFFetchStreamReader, PDFFetchStreamRangeReader);
70-
this.isHttp = /^https?:/i.test(source.url);
71-
this.headers = createHeaders(this.isHttp, source.httpHeaders);
70+
const { httpHeaders, url } = source;
71+
72+
assert(
73+
/https?:/.test(url.protocol),
74+
"PDFFetchStream only supports http(s):// URLs."
75+
);
76+
this.headers = createHeaders(/* isHttp = */ true, httpHeaders);
7277
}
7378
}
7479

@@ -106,7 +111,7 @@ class PDFFetchStreamReader extends BasePDFStreamReader {
106111
const { allowRangeRequests, suggestedLength } =
107112
validateRangeRequestCapabilities({
108113
responseHeaders,
109-
isHttp: stream.isHttp,
114+
isHttp: true,
110115
rangeChunkSize,
111116
disableRange,
112117
});

src/display/network.js

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -48,9 +48,11 @@ class PDFNetworkStream extends BasePDFStream {
4848

4949
constructor(source) {
5050
super(source, PDFNetworkStreamReader, PDFNetworkStreamRangeReader);
51-
this.url = source.url;
52-
this.isHttp = /^https?:/i.test(this.url);
53-
this.headers = createHeaders(this.isHttp, source.httpHeaders);
51+
const { httpHeaders, url } = source;
52+
53+
this.url = url;
54+
this.isHttp = /https?:/.test(url.protocol);
55+
this.headers = createHeaders(this.isHttp, httpHeaders);
5456
}
5557

5658
/**

src/display/network_utils.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -101,9 +101,9 @@ function extractFilenameFromHeader(responseHeaders) {
101101

102102
function createResponseError(status, url) {
103103
return new ResponseException(
104-
`Unexpected server response (${status}) while retrieving PDF "${url}".`,
104+
`Unexpected server response (${status}) while retrieving PDF "${url.href}".`,
105105
status,
106-
/* missing = */ status === 404 || (status === 0 && url.startsWith("file:"))
106+
/* missing = */ status === 404 || (status === 0 && url.protocol === "file:")
107107
);
108108
}
109109

src/display/node_stream.js

Lines changed: 6 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -28,16 +28,6 @@ if (typeof PDFJSDev !== "undefined" && PDFJSDev.test("MOZCENTRAL")) {
2828
);
2929
}
3030

31-
const urlRegex = /^[a-z][a-z0-9\-+.]+:/i;
32-
33-
function parseUrlOrPath(sourceUrl) {
34-
if (urlRegex.test(sourceUrl)) {
35-
return new URL(sourceUrl);
36-
}
37-
const url = process.getBuiltinModule("url");
38-
return new URL(url.pathToFileURL(sourceUrl));
39-
}
40-
4131
function getReadableStream(readStream) {
4232
const { Readable } = process.getBuiltinModule("stream");
4333

@@ -68,9 +58,10 @@ function getArrayBuffer(val) {
6858
class PDFNodeStream extends BasePDFStream {
6959
constructor(source) {
7060
super(source, PDFNodeStreamReader, PDFNodeStreamRangeReader);
71-
this.url = parseUrlOrPath(source.url);
61+
const { url } = source;
62+
7263
assert(
73-
this.url.protocol === "file:",
64+
url.protocol === "file:",
7465
"PDFNodeStream only supports file:// URLs."
7566
);
7667
}
@@ -81,14 +72,13 @@ class PDFNodeStreamReader extends BasePDFStreamReader {
8172

8273
constructor(stream) {
8374
super(stream);
84-
const { disableRange, disableStream, length, rangeChunkSize } =
75+
const { disableRange, disableStream, length, rangeChunkSize, url } =
8576
stream._source;
8677

8778
this._contentLength = length;
8879
this._isStreamingSupported = !disableStream;
8980
this._isRangeSupported = !disableRange;
9081

91-
const url = stream.url;
9282
const fs = process.getBuiltinModule("fs");
9383
fs.promises
9484
.lstat(url)
@@ -117,7 +107,7 @@ class PDFNodeStreamReader extends BasePDFStreamReader {
117107
})
118108
.catch(error => {
119109
if (error.code === "ENOENT") {
120-
error = createResponseError(/* status = */ 0, url.href);
110+
error = createResponseError(/* status = */ 0, url);
121111
}
122112
this._headersCapability.reject(error);
123113
});
@@ -150,8 +140,8 @@ class PDFNodeStreamRangeReader extends BasePDFStreamRangeReader {
150140

151141
constructor(stream, begin, end) {
152142
super(stream, begin, end);
143+
const { url } = stream._source;
153144

154-
const url = stream.url;
155145
const fs = process.getBuiltinModule("fs");
156146
try {
157147
const readStream = fs.createReadStream(url, {

test/unit/common_pdfstream_tests.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ async function testCrossOriginRedirects({
2424
redirectIfRange,
2525
testRangeReader,
2626
}) {
27-
const basicApiUrl = TestPdfsServer.resolveURL("basicapi.pdf").href;
27+
const basicApiUrl = TestPdfsServer.resolveURL("basicapi.pdf");
2828
const basicApiFileLength = 105779;
2929

3030
const rangeSize = 32768;
@@ -83,7 +83,7 @@ function getCrossOriginUrlWithRedirects(testserverUrl, redirectIfRange) {
8383
if (redirectIfRange) {
8484
url.searchParams.set("redirectIfRange", "1");
8585
}
86-
return url.href;
86+
return url;
8787
}
8888

8989
export { testCrossOriginRedirects };

test/unit/fetch_stream_spec.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ import { TestPdfsServer } from "./test_utils.js";
2020

2121
describe("fetch_stream", function () {
2222
function getPdfUrl() {
23-
return TestPdfsServer.resolveURL("tracemonkey.pdf").href;
23+
return TestPdfsServer.resolveURL("tracemonkey.pdf");
2424
}
2525
const pdfLength = 1016315;
2626

test/unit/network_spec.js

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ import { testCrossOriginRedirects } from "./common_pdfstream_tests.js";
1919
import { TestPdfsServer } from "./test_utils.js";
2020

2121
describe("network", function () {
22-
const pdf1 = new URL("../pdfs/tracemonkey.pdf", window.location).href;
22+
const pdf1 = new URL("../pdfs/tracemonkey.pdf", window.location);
2323
const pdf1Length = 1016315;
2424

2525
it("read without stream and range", async function () {
@@ -124,9 +124,12 @@ describe("network", function () {
124124
}
125125

126126
async function readRanges(mode) {
127+
const pdfUrl = new URL(pdf1);
128+
pdfUrl.searchParams.set("test-network-break-ranges", mode);
129+
127130
const rangeSize = 32768;
128131
const stream = new PDFNetworkStream({
129-
url: `${pdf1}?test-network-break-ranges=${mode}`,
132+
url: pdfUrl,
130133
length: pdf1Length,
131134
rangeChunkSize: rangeSize,
132135
disableStream: true,

test/unit/network_utils_spec.js

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -372,22 +372,22 @@ describe("network_utils", function () {
372372

373373
expect(error instanceof ResponseException).toEqual(true);
374374
expect(error.message).toEqual(
375-
`Unexpected server response (${status}) while retrieving PDF "${url}".`
375+
`Unexpected server response (${status}) while retrieving PDF "${url.href}".`
376376
);
377377
expect(error.status).toEqual(status);
378378
expect(error.missing).toEqual(missing);
379379
}
380380

381381
it("handles missing PDF file responses", function () {
382-
testCreateResponseError("https://foo.com/bar.pdf", 404, true);
382+
testCreateResponseError(new URL("https://foo.com/bar.pdf"), 404, true);
383383

384-
testCreateResponseError("file://foo.pdf", 0, true);
384+
testCreateResponseError(new URL("file://foo.pdf"), 0, true);
385385
});
386386

387387
it("handles unexpected responses", function () {
388-
testCreateResponseError("https://foo.com/bar.pdf", 302, false);
388+
testCreateResponseError(new URL("https://foo.com/bar.pdf"), 302, false);
389389

390-
testCreateResponseError("https://foo.com/bar.pdf", 0, false);
390+
testCreateResponseError(new URL("https://foo.com/bar.pdf"), 0, false);
391391
});
392392
});
393393
});

0 commit comments

Comments
 (0)