@fedify/vocab-runtime 2.4.0-dev.2233 → 2.4.0-dev.2245
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/deno.json +2 -2
- package/dist/internal/jsonld-cache.cjs +1 -1
- package/dist/internal/jsonld-cache.js +1 -1
- package/dist/internal/portable-dereference.cjs +3 -6
- package/dist/internal/portable-dereference.js +3 -6
- package/dist/mod.cjs +2 -2
- package/dist/mod.d.cts +14 -3
- package/dist/mod.d.ts +14 -3
- package/dist/mod.js +2 -2
- package/dist/tests/{body-DQKTFMsH.cjs → body-C7LfsQJ3.cjs} +1 -1
- package/dist/tests/{body-BEYUpKvX.mjs → body-D50XSh7s.mjs} +1 -1
- package/dist/tests/body.test.cjs +1 -1
- package/dist/tests/body.test.mjs +1 -1
- package/dist/tests/decimal.test.cjs +3 -3
- package/dist/tests/decimal.test.mjs +3 -3
- package/dist/tests/{docloader-ra1lbBfP.mjs → docloader-BdcRw8S9.mjs} +3 -3
- package/dist/tests/{docloader-DHCYdBXf.cjs → docloader-oUrWeeUz.cjs} +3 -3
- package/dist/tests/docloader.test.cjs +59 -65
- package/dist/tests/docloader.test.mjs +38 -44
- package/dist/tests/internal/portable-dereference.test.cjs +21 -149
- package/dist/tests/internal/portable-dereference.test.mjs +3 -131
- package/dist/tests/{jsonld-cache-BKrsWPCQ.mjs → jsonld-cache-CKfgtxPB.mjs} +1 -1
- package/dist/tests/{jsonld-cache-BTgizq9A.cjs → jsonld-cache-DzxT9IXH.cjs} +1 -1
- package/dist/tests/jsonld-cache.test.cjs +2 -2
- package/dist/tests/jsonld-cache.test.mjs +2 -2
- package/dist/tests/multibase/multibase.test.cjs +7 -7
- package/dist/tests/multibase/multibase.test.mjs +5 -5
- package/dist/tests/portable-dereference-C_cwGjz6.mjs +132 -0
- package/dist/tests/portable-dereference-CyFYTBnr.cjs +149 -0
- package/dist/tests/{portable-media-DHaAEpaQ.cjs → portable-media-Bj5FXpUr.cjs} +3 -3
- package/dist/tests/{portable-media-1NjUQari.mjs → portable-media-D4NJcqkI.mjs} +3 -3
- package/dist/tests/portable-media.test.cjs +1 -1
- package/dist/tests/portable-media.test.mjs +1 -1
- package/dist/tests/portable-workers.test.cjs +36 -0
- package/dist/tests/portable-workers.test.d.cts +2 -0
- package/dist/tests/portable-workers.test.d.mts +2 -0
- package/dist/tests/portable-workers.test.mjs +35 -0
- package/dist/tests/{request-BQlkB8du.cjs → request-CBCk-e0R.cjs} +1 -1
- package/dist/tests/{request-D3elVRyB.mjs → request-wKyc91L5.mjs} +1 -1
- package/dist/tests/request.test.cjs +1 -1
- package/dist/tests/request.test.mjs +1 -1
- package/dist/tests/{url-Cdu4ASgJ.mjs → url-CWC-NI3a.mjs} +63 -7
- package/dist/tests/{url-CtHyzMR4.cjs → url-DsMBGqCc.cjs} +63 -7
- package/dist/tests/url.test.cjs +74 -1
- package/dist/tests/url.test.mjs +74 -1
- package/dist/{url-BHfQuRdy.cjs → url-BJMXv2kE.cjs} +63 -7
- package/dist/{url-DqqDZY9i.js → url-CZm2-7ZO.js} +63 -7
- package/package.json +6 -3
- package/scripts/test-bun.mjs +17 -0
- package/src/docloader.test.ts +82 -74
- package/src/internal/portable-dereference.ts +2 -5
- package/src/multibase/multibase.test.ts +5 -5
- package/src/portable-workers.test.ts +81 -0
- package/src/url.test.ts +90 -0
- package/src/url.ts +115 -13
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
const require_rolldown_runtime = require("./rolldown-runtime-emK7D4bc.cjs");
|
|
2
|
-
const require_request = require("./request-
|
|
2
|
+
const require_request = require("./request-CBCk-e0R.cjs");
|
|
3
3
|
const require_contexts = require("./contexts-DizzBjz4.cjs");
|
|
4
|
-
const require_url = require("./url-
|
|
5
|
-
const require_docloader = require("./docloader-
|
|
6
|
-
let node_test = require("node:test");
|
|
4
|
+
const require_url = require("./url-DsMBGqCc.cjs");
|
|
5
|
+
const require_docloader = require("./docloader-oUrWeeUz.cjs");
|
|
7
6
|
let node_zlib = require("node:zlib");
|
|
8
7
|
let _logtape_logtape = require("@logtape/logtape");
|
|
9
8
|
let node_assert = require("node:assert");
|
|
10
9
|
let node_dns_promises = require("node:dns/promises");
|
|
11
10
|
node_dns_promises = require_rolldown_runtime.__toESM(node_dns_promises, 1);
|
|
11
|
+
let _fedify_fixture = require("@fedify/fixture");
|
|
12
12
|
let node_http = require("node:http");
|
|
13
13
|
//#region ../../node_modules/.pnpm/glob-to-regexp@0.4.1/node_modules/glob-to-regexp/index.js
|
|
14
14
|
var require_glob_to_regexp = /* @__PURE__ */ require_rolldown_runtime.__commonJSMin(((exports, module) => {
|
|
@@ -1219,7 +1219,7 @@ var esm_default = new class FetchMock {
|
|
|
1219
1219
|
}({ ...defaultFetchMockConfig });
|
|
1220
1220
|
//#endregion
|
|
1221
1221
|
//#region src/docloader.test.ts
|
|
1222
|
-
(0,
|
|
1222
|
+
(0, _fedify_fixture.test)("getRemoteDocument() forwards options to alternate documents", async () => {
|
|
1223
1223
|
const records = [];
|
|
1224
1224
|
await (0, _logtape_logtape.reset)();
|
|
1225
1225
|
await (0, _logtape_logtape.configure)({
|
|
@@ -1265,7 +1265,7 @@ var esm_default = new class FetchMock {
|
|
|
1265
1265
|
await (0, _logtape_logtape.reset)();
|
|
1266
1266
|
}
|
|
1267
1267
|
});
|
|
1268
|
-
(0,
|
|
1268
|
+
(0, _fedify_fixture.test)("new FetchError()", () => {
|
|
1269
1269
|
const e = new require_request.FetchError("https://example.com/", "An error message.");
|
|
1270
1270
|
(0, node_assert.deepStrictEqual)(e.name, "FetchError");
|
|
1271
1271
|
(0, node_assert.deepStrictEqual)(e.url, new URL("https://example.com/"));
|
|
@@ -1278,7 +1278,7 @@ var esm_default = new class FetchMock {
|
|
|
1278
1278
|
(0, node_assert.ok)(e2.response != null);
|
|
1279
1279
|
(0, node_assert.deepStrictEqual)(e2.response.status, 410);
|
|
1280
1280
|
});
|
|
1281
|
-
(0,
|
|
1281
|
+
(0, _fedify_fixture.test)("getDocumentLoader()", async (t) => {
|
|
1282
1282
|
const fetchDocumentLoader = require_docloader.getDocumentLoader();
|
|
1283
1283
|
esm_default.spyGlobal();
|
|
1284
1284
|
esm_default.get("https://example.com/object", { body: {
|
|
@@ -1287,7 +1287,7 @@ var esm_default = new class FetchMock {
|
|
|
1287
1287
|
name: "Fetched object",
|
|
1288
1288
|
type: "Object"
|
|
1289
1289
|
} });
|
|
1290
|
-
await t.
|
|
1290
|
+
await t.step("ok", async () => {
|
|
1291
1291
|
(0, node_assert.deepStrictEqual)(await fetchDocumentLoader("https://example.com/object"), {
|
|
1292
1292
|
contextUrl: null,
|
|
1293
1293
|
documentUrl: "https://example.com/object",
|
|
@@ -1330,7 +1330,7 @@ var esm_default = new class FetchMock {
|
|
|
1330
1330
|
Link: "<https://example.com/object>; rel=\"alternate\"; type=\"application/ld+json; profile=\"https://www.w3.org/ns/activitystreams\"\""
|
|
1331
1331
|
}
|
|
1332
1332
|
});
|
|
1333
|
-
await t.
|
|
1333
|
+
await t.step("Link header", async () => {
|
|
1334
1334
|
(0, node_assert.deepStrictEqual)(await fetchDocumentLoader("https://example.com/link-ctx"), {
|
|
1335
1335
|
contextUrl: "https://www.w3.org/ns/activitystreams",
|
|
1336
1336
|
documentUrl: "https://example.com/link-ctx",
|
|
@@ -1351,7 +1351,7 @@ var esm_default = new class FetchMock {
|
|
|
1351
1351
|
}
|
|
1352
1352
|
});
|
|
1353
1353
|
});
|
|
1354
|
-
await t.
|
|
1354
|
+
await t.step("Link header relative url", async () => {
|
|
1355
1355
|
(0, node_assert.deepStrictEqual)(await fetchDocumentLoader("https://example.com/link-ctx"), {
|
|
1356
1356
|
contextUrl: "https://www.w3.org/ns/activitystreams",
|
|
1357
1357
|
documentUrl: "https://example.com/link-ctx",
|
|
@@ -1372,7 +1372,7 @@ var esm_default = new class FetchMock {
|
|
|
1372
1372
|
}
|
|
1373
1373
|
});
|
|
1374
1374
|
});
|
|
1375
|
-
await t.
|
|
1375
|
+
await t.step("wrong Link header syntax", async () => {
|
|
1376
1376
|
(0, node_assert.deepStrictEqual)(await fetchDocumentLoader("https://example.com/obj-w-wrong-link"), {
|
|
1377
1377
|
contextUrl: null,
|
|
1378
1378
|
documentUrl: "https://example.com/obj-w-wrong-link",
|
|
@@ -1396,7 +1396,7 @@ var esm_default = new class FetchMock {
|
|
|
1396
1396
|
</html>`,
|
|
1397
1397
|
headers: { "Content-Type": "text/html; charset=utf-8" }
|
|
1398
1398
|
});
|
|
1399
|
-
await t.
|
|
1399
|
+
await t.step("HTML <link>", async () => {
|
|
1400
1400
|
(0, node_assert.deepStrictEqual)(await fetchDocumentLoader("https://example.com/html-link"), {
|
|
1401
1401
|
contextUrl: null,
|
|
1402
1402
|
documentUrl: "https://example.com/object",
|
|
@@ -1420,7 +1420,7 @@ var esm_default = new class FetchMock {
|
|
|
1420
1420
|
</html>`,
|
|
1421
1421
|
headers: { "Content-Type": "application/xhtml+xml; charset=utf-8" }
|
|
1422
1422
|
});
|
|
1423
|
-
await t.
|
|
1423
|
+
await t.step("XHTML <link>", async () => {
|
|
1424
1424
|
(0, node_assert.deepStrictEqual)(await fetchDocumentLoader("https://example.com/xhtml-link"), {
|
|
1425
1425
|
contextUrl: null,
|
|
1426
1426
|
documentUrl: "https://example.com/object",
|
|
@@ -1446,7 +1446,7 @@ var esm_default = new class FetchMock {
|
|
|
1446
1446
|
</html>`,
|
|
1447
1447
|
headers: { "Content-Type": "text/html; charset=utf-8" }
|
|
1448
1448
|
});
|
|
1449
|
-
await t.
|
|
1449
|
+
await t.step("HTML <a>", async () => {
|
|
1450
1450
|
(0, node_assert.deepStrictEqual)(await fetchDocumentLoader("https://example.com/html-a"), {
|
|
1451
1451
|
contextUrl: null,
|
|
1452
1452
|
documentUrl: "https://example.com/object",
|
|
@@ -1468,7 +1468,7 @@ var esm_default = new class FetchMock {
|
|
|
1468
1468
|
</html>`,
|
|
1469
1469
|
headers: { "Content-Type": "text/html; charset=utf-8" }
|
|
1470
1470
|
});
|
|
1471
|
-
await t.
|
|
1471
|
+
await t.step("HTML without ActivityPub alternate link", async () => {
|
|
1472
1472
|
await (0, node_assert.rejects)(() => fetchDocumentLoader("https://example.com/html-no-alternate"), (error) => {
|
|
1473
1473
|
(0, node_assert.ok)(error instanceof require_request.FetchError);
|
|
1474
1474
|
(0, node_assert.ok)(error.message.includes("HTML document has no ActivityPub alternate link"));
|
|
@@ -1488,7 +1488,7 @@ var esm_default = new class FetchMock {
|
|
|
1488
1488
|
},
|
|
1489
1489
|
headers: { "Content-Type": "text/html; charset=utf-8" }
|
|
1490
1490
|
});
|
|
1491
|
-
await t.
|
|
1491
|
+
await t.step("wrong Content-Type with JSON body", async () => {
|
|
1492
1492
|
(0, node_assert.deepStrictEqual)(await fetchDocumentLoader("https://example.com/wrong-content-type"), {
|
|
1493
1493
|
contextUrl: null,
|
|
1494
1494
|
documentUrl: "https://example.com/wrong-content-type",
|
|
@@ -1507,7 +1507,7 @@ var esm_default = new class FetchMock {
|
|
|
1507
1507
|
"Content-Type": "text/html; charset=utf-8"
|
|
1508
1508
|
}
|
|
1509
1509
|
});
|
|
1510
|
-
await t.
|
|
1510
|
+
await t.step("HTML Content-Length over limit", async () => {
|
|
1511
1511
|
await (0, node_assert.rejects)(() => fetchDocumentLoader("https://example.com/large-html"), (error) => {
|
|
1512
1512
|
(0, node_assert.ok)(error instanceof require_request.FetchError);
|
|
1513
1513
|
(0, node_assert.ok)(error.message.includes("HTML document is too large to scan for an ActivityPub alternate link"));
|
|
@@ -1517,7 +1517,7 @@ var esm_default = new class FetchMock {
|
|
|
1517
1517
|
return true;
|
|
1518
1518
|
});
|
|
1519
1519
|
});
|
|
1520
|
-
await t.
|
|
1520
|
+
await t.step("HTML Content-Length over limit cancels body", async () => {
|
|
1521
1521
|
let canceled = false;
|
|
1522
1522
|
const response = new Response("<!DOCTYPE html>", { headers: {
|
|
1523
1523
|
"Content-Length": String(1048577),
|
|
@@ -1532,10 +1532,10 @@ var esm_default = new class FetchMock {
|
|
|
1532
1532
|
(0, node_assert.deepStrictEqual)(canceled, true);
|
|
1533
1533
|
});
|
|
1534
1534
|
esm_default.get("https://example.com/404", { status: 404 });
|
|
1535
|
-
await t.
|
|
1535
|
+
await t.step("not ok", async () => {
|
|
1536
1536
|
await (0, node_assert.rejects)(() => fetchDocumentLoader("https://example.com/404"), require_request.FetchError, "HTTP 404: https://example.com/404");
|
|
1537
1537
|
});
|
|
1538
|
-
await t.
|
|
1538
|
+
await t.step("preloaded contexts", async () => {
|
|
1539
1539
|
for (const [url, document] of Object.entries(require_contexts.preloadedContexts)) (0, node_assert.deepStrictEqual)(await fetchDocumentLoader(url), {
|
|
1540
1540
|
contextUrl: null,
|
|
1541
1541
|
documentUrl: url,
|
|
@@ -1543,7 +1543,7 @@ var esm_default = new class FetchMock {
|
|
|
1543
1543
|
});
|
|
1544
1544
|
});
|
|
1545
1545
|
esm_default.get("https://www.w3.org/ns/cid/v1", { status: 503 });
|
|
1546
|
-
await t.
|
|
1546
|
+
await t.step("preloaded CID v1 context", async () => {
|
|
1547
1547
|
const url = "https://www.w3.org/ns/cid/v1";
|
|
1548
1548
|
(0, node_assert.deepStrictEqual)(await fetchDocumentLoader(url), {
|
|
1549
1549
|
contextUrl: null,
|
|
@@ -1551,7 +1551,7 @@ var esm_default = new class FetchMock {
|
|
|
1551
1551
|
document: require_contexts.cid_v1_default
|
|
1552
1552
|
});
|
|
1553
1553
|
});
|
|
1554
|
-
await t.
|
|
1554
|
+
await t.step("preloaded FEP-ef61 context", async () => {
|
|
1555
1555
|
const url = "https://w3id.org/fep/ef61";
|
|
1556
1556
|
(0, node_assert.ok)(url in require_contexts.preloadedContexts);
|
|
1557
1557
|
(0, node_assert.deepStrictEqual)(await fetchDocumentLoader(url), {
|
|
@@ -1568,7 +1568,7 @@ var esm_default = new class FetchMock {
|
|
|
1568
1568
|
});
|
|
1569
1569
|
});
|
|
1570
1570
|
esm_default.get("https://w3id.org/fep/7aa9", { status: 502 });
|
|
1571
|
-
await t.
|
|
1571
|
+
await t.step("preloaded FEP-7aa9 context", async () => {
|
|
1572
1572
|
const url = "https://w3id.org/fep/7aa9";
|
|
1573
1573
|
(0, node_assert.deepStrictEqual)(await fetchDocumentLoader(url), {
|
|
1574
1574
|
contextUrl: null,
|
|
@@ -1598,7 +1598,7 @@ var esm_default = new class FetchMock {
|
|
|
1598
1598
|
});
|
|
1599
1599
|
(0, node_assert.deepStrictEqual)(esm_default.callHistory.calls(url).length, 0);
|
|
1600
1600
|
});
|
|
1601
|
-
await t.
|
|
1601
|
+
await t.step("deny non-HTTP/HTTPS", async () => {
|
|
1602
1602
|
await (0, node_assert.rejects)(() => fetchDocumentLoader("ftp://localhost"), require_url.UrlError);
|
|
1603
1603
|
});
|
|
1604
1604
|
esm_default.get("https://example.com/localhost-redirect", {
|
|
@@ -1623,13 +1623,13 @@ var esm_default = new class FetchMock {
|
|
|
1623
1623
|
name: "Fetched object",
|
|
1624
1624
|
type: "Object"
|
|
1625
1625
|
} });
|
|
1626
|
-
await t.
|
|
1626
|
+
await t.step("allowPrivateAddress: false", async () => {
|
|
1627
1627
|
await (0, node_assert.rejects)(() => fetchDocumentLoader("https://localhost/object"), require_url.UrlError);
|
|
1628
1628
|
await (0, node_assert.rejects)(() => fetchDocumentLoader("https://example.com/localhost-redirect"), require_url.UrlError);
|
|
1629
1629
|
await (0, node_assert.rejects)(() => fetchDocumentLoader("https://example.com/localhost-link"), require_url.UrlError);
|
|
1630
1630
|
});
|
|
1631
1631
|
const fetchDocumentLoader2 = require_docloader.getDocumentLoader({ allowPrivateAddress: true });
|
|
1632
|
-
await t.
|
|
1632
|
+
await t.step("allowPrivateAddress: true", async () => {
|
|
1633
1633
|
const expected = {
|
|
1634
1634
|
contextUrl: null,
|
|
1635
1635
|
documentUrl: "https://localhost/object",
|
|
@@ -1652,12 +1652,12 @@ var esm_default = new class FetchMock {
|
|
|
1652
1652
|
headers: { Location: `https://example.com/too-many-redirects/${Number(cl.url.split("/").at(-1)) + 1}` }
|
|
1653
1653
|
};
|
|
1654
1654
|
});
|
|
1655
|
-
await t.
|
|
1655
|
+
await t.step("too many redirects", async () => {
|
|
1656
1656
|
redirectAttempts = 0;
|
|
1657
1657
|
await (0, node_assert.rejects)(() => fetchDocumentLoader("https://example.com/too-many-redirects/0"), require_request.FetchError, "Too many redirections");
|
|
1658
1658
|
(0, node_assert.deepStrictEqual)(redirectAttempts, 21);
|
|
1659
1659
|
});
|
|
1660
|
-
await t.
|
|
1660
|
+
await t.step("custom max redirection", async () => {
|
|
1661
1661
|
redirectAttempts = 0;
|
|
1662
1662
|
const loader = require_docloader.getDocumentLoader({ maxRedirection: 1 });
|
|
1663
1663
|
await (0, node_assert.rejects)(() => loader("https://example.com/too-many-redirects/0"), require_request.FetchError, "Too many redirections");
|
|
@@ -1678,7 +1678,7 @@ var esm_default = new class FetchMock {
|
|
|
1678
1678
|
headers: { Location: "https://example.com/redirect-loop-a" }
|
|
1679
1679
|
};
|
|
1680
1680
|
});
|
|
1681
|
-
await t.
|
|
1681
|
+
await t.step("redirect loop", async () => {
|
|
1682
1682
|
loopAttempts = 0;
|
|
1683
1683
|
await (0, node_assert.rejects)(() => fetchDocumentLoader("https://example.com/redirect-loop-a"), require_request.FetchError, "Redirect loop detected");
|
|
1684
1684
|
(0, node_assert.deepStrictEqual)(loopAttempts, 2);
|
|
@@ -1691,7 +1691,7 @@ var esm_default = new class FetchMock {
|
|
|
1691
1691
|
headers: { Location: "/redirect-loop-relative" }
|
|
1692
1692
|
};
|
|
1693
1693
|
});
|
|
1694
|
-
await t.
|
|
1694
|
+
await t.step("redirect loop with relative location", async () => {
|
|
1695
1695
|
relativeLoopAttempts = 0;
|
|
1696
1696
|
await (0, node_assert.rejects)(() => fetchDocumentLoader("https://example.com/redirect-loop-relative"), require_request.FetchError, "Redirect loop detected");
|
|
1697
1697
|
(0, node_assert.deepStrictEqual)(relativeLoopAttempts, 1);
|
|
@@ -1701,7 +1701,7 @@ var esm_default = new class FetchMock {
|
|
|
1701
1701
|
body: maliciousPayload,
|
|
1702
1702
|
headers: { "Content-Type": "text/html; charset=utf-8" }
|
|
1703
1703
|
});
|
|
1704
|
-
await t.
|
|
1704
|
+
await t.step("ReDoS resistance (CVE-2025-68475)", async () => {
|
|
1705
1705
|
const start = performance.now();
|
|
1706
1706
|
await (0, node_assert.rejects)(() => fetchDocumentLoader("https://example.com/redos"), require_request.FetchError);
|
|
1707
1707
|
const elapsed = performance.now() - start;
|
|
@@ -1709,7 +1709,7 @@ var esm_default = new class FetchMock {
|
|
|
1709
1709
|
});
|
|
1710
1710
|
esm_default.hardReset();
|
|
1711
1711
|
});
|
|
1712
|
-
(0,
|
|
1712
|
+
(0, _fedify_fixture.test)("getDocumentLoader() bounds JSON, HTML, and alternate documents", async () => {
|
|
1713
1713
|
const url = "https://example.com/bounded";
|
|
1714
1714
|
esm_default.mockGlobal();
|
|
1715
1715
|
let oversized = true;
|
|
@@ -1739,7 +1739,7 @@ var esm_default = new class FetchMock {
|
|
|
1739
1739
|
esm_default.hardReset();
|
|
1740
1740
|
}
|
|
1741
1741
|
});
|
|
1742
|
-
(0,
|
|
1742
|
+
(0, _fedify_fixture.test)("getDocumentLoader() rejects oversized gzip responses from fetch", async () => {
|
|
1743
1743
|
const document = { name: "a".repeat(16 * 1024 * 1024) };
|
|
1744
1744
|
const compressed = (0, node_zlib.gzipSync)(JSON.stringify(document));
|
|
1745
1745
|
(0, node_assert.ok)(compressed.byteLength < 64 * 1024);
|
|
@@ -1769,7 +1769,7 @@ var esm_default = new class FetchMock {
|
|
|
1769
1769
|
});
|
|
1770
1770
|
}
|
|
1771
1771
|
});
|
|
1772
|
-
(0,
|
|
1772
|
+
(0, _fedify_fixture.test)("getRemoteDocument() bounds JSON by default", async () => {
|
|
1773
1773
|
let canceled = false;
|
|
1774
1774
|
let pulls = 0;
|
|
1775
1775
|
await (0, node_assert.rejects)(require_docloader.getRemoteDocument("https://example.com/document", new Response(new ReadableStream({
|
|
@@ -1786,17 +1786,14 @@ var esm_default = new class FetchMock {
|
|
|
1786
1786
|
(0, node_assert.deepStrictEqual)(canceled, true);
|
|
1787
1787
|
(0, node_assert.deepStrictEqual)(pulls, 257);
|
|
1788
1788
|
});
|
|
1789
|
-
(0,
|
|
1790
|
-
if ("Deno" in globalThis && (await Deno.permissions.query({ name: "net" })).state !== "granted")
|
|
1791
|
-
t.skip("requires the net permission");
|
|
1792
|
-
return;
|
|
1793
|
-
}
|
|
1789
|
+
(0, _fedify_fixture.test)("getDocumentLoader() logs DNS failures as such", async (t) => {
|
|
1790
|
+
if ("Deno" in globalThis && (await Deno.permissions.query({ name: "net" })).state !== "granted") throw new Error("This DNS test requires Deno network permission (--allow-net).");
|
|
1794
1791
|
const loader = require_docloader.getDocumentLoader();
|
|
1795
1792
|
for (const result of [
|
|
1796
1793
|
"throws",
|
|
1797
1794
|
"empty",
|
|
1798
1795
|
"private"
|
|
1799
|
-
]) await t.
|
|
1796
|
+
]) await t.step(result, async () => {
|
|
1800
1797
|
const originalLookup = node_dns_promises.default.lookup;
|
|
1801
1798
|
node_dns_promises.default.lookup = (() => result === "throws" ? Promise.reject(/* @__PURE__ */ new Error("Resolver unavailable")) : Promise.resolve(result === "empty" ? [] : [{
|
|
1802
1799
|
address: "127.0.0.1",
|
|
@@ -1844,14 +1841,14 @@ var esm_default = new class FetchMock {
|
|
|
1844
1841
|
}
|
|
1845
1842
|
});
|
|
1846
1843
|
});
|
|
1847
|
-
(0,
|
|
1844
|
+
(0, _fedify_fixture.test)("getDocumentLoader() bounds alternate document chains", async (t) => {
|
|
1848
1845
|
const base = "https://example.com/alternate-chain/";
|
|
1849
1846
|
const loader = require_docloader.getDocumentLoader({ allowPrivateAddress: true });
|
|
1850
1847
|
for (const mode of [
|
|
1851
1848
|
"header",
|
|
1852
1849
|
"html",
|
|
1853
1850
|
"mixed"
|
|
1854
|
-
]) for (const hops of [20, 21]) await t.
|
|
1851
|
+
]) for (const hops of [20, 21]) await t.step(`${mode}: ${hops} hops`, async () => {
|
|
1855
1852
|
esm_default.mockGlobal();
|
|
1856
1853
|
let requests = 0;
|
|
1857
1854
|
esm_default.get(`begin:${base}`, ({ url }) => {
|
|
@@ -1880,7 +1877,7 @@ var esm_default = new class FetchMock {
|
|
|
1880
1877
|
"alternate-redirect",
|
|
1881
1878
|
"redirect-alternate",
|
|
1882
1879
|
"redirect-intermediate"
|
|
1883
|
-
]) await t.
|
|
1880
|
+
]) await t.step(`${mode}: cycle`, async () => {
|
|
1884
1881
|
esm_default.mockGlobal();
|
|
1885
1882
|
let requests = 0;
|
|
1886
1883
|
esm_default.get(`begin:${base}`, ({ url }) => {
|
|
@@ -1902,7 +1899,7 @@ var esm_default = new class FetchMock {
|
|
|
1902
1899
|
esm_default.hardReset();
|
|
1903
1900
|
}
|
|
1904
1901
|
});
|
|
1905
|
-
await t.
|
|
1902
|
+
await t.step("alternate followed by 20 redirects shares the limit", async () => {
|
|
1906
1903
|
esm_default.mockGlobal();
|
|
1907
1904
|
let requests = 0;
|
|
1908
1905
|
esm_default.get(`begin:${base}`, ({ url }) => {
|
|
@@ -1922,7 +1919,7 @@ var esm_default = new class FetchMock {
|
|
|
1922
1919
|
esm_default.hardReset();
|
|
1923
1920
|
}
|
|
1924
1921
|
});
|
|
1925
|
-
await t.
|
|
1922
|
+
await t.step("relative alternate after redirect and isolated calls", async () => {
|
|
1926
1923
|
esm_default.mockGlobal();
|
|
1927
1924
|
esm_default.get(`${base}start`, Response.redirect(`${base}html`, 302));
|
|
1928
1925
|
esm_default.get(`${base}html`, alternate("./document", true));
|
|
@@ -1946,10 +1943,10 @@ var esm_default = new class FetchMock {
|
|
|
1946
1943
|
} });
|
|
1947
1944
|
}
|
|
1948
1945
|
});
|
|
1949
|
-
(0,
|
|
1946
|
+
(0, _fedify_fixture.test)("getDocumentLoader() preserves cancellation across alternates", async (t) => {
|
|
1950
1947
|
const base = "https://example.com/alternate-abort/";
|
|
1951
1948
|
const loader = require_docloader.getDocumentLoader({ allowPrivateAddress: true });
|
|
1952
|
-
for (const html of [false, true]) await t.
|
|
1949
|
+
for (const html of [false, true]) await t.step(html ? "HTML" : "Link header", async () => {
|
|
1953
1950
|
esm_default.mockGlobal();
|
|
1954
1951
|
const controller = new AbortController();
|
|
1955
1952
|
let requests = 0;
|
|
@@ -1972,7 +1969,7 @@ var esm_default = new class FetchMock {
|
|
|
1972
1969
|
}
|
|
1973
1970
|
});
|
|
1974
1971
|
});
|
|
1975
|
-
(0,
|
|
1972
|
+
(0, _fedify_fixture.test)("getDocumentLoader() rejects cancellation before fetching", async () => {
|
|
1976
1973
|
esm_default.mockGlobal();
|
|
1977
1974
|
let requests = 0;
|
|
1978
1975
|
const url = "https://example.com/pre-aborted-alternate";
|
|
@@ -2015,7 +2012,7 @@ function isTimeoutFetchError(error, url) {
|
|
|
2015
2012
|
(0, node_assert.deepStrictEqual)(error.cause.name, "TimeoutError");
|
|
2016
2013
|
return true;
|
|
2017
2014
|
}
|
|
2018
|
-
(0,
|
|
2015
|
+
(0, _fedify_fixture.test)("resolveDocumentLoaderTimeout() validates timeouts", () => {
|
|
2019
2016
|
(0, node_assert.deepStrictEqual)(require_docloader.resolveDocumentLoaderTimeout(void 0), 1e4);
|
|
2020
2017
|
(0, node_assert.deepStrictEqual)(require_docloader.resolveDocumentLoaderTimeout(null), null);
|
|
2021
2018
|
(0, node_assert.deepStrictEqual)(require_docloader.resolveDocumentLoaderTimeout(1500), 1500);
|
|
@@ -2030,7 +2027,7 @@ function isTimeoutFetchError(error, url) {
|
|
|
2030
2027
|
]) (0, node_assert.throws)(() => require_docloader.resolveDocumentLoaderTimeout(invalid), RangeError);
|
|
2031
2028
|
(0, node_assert.throws)(() => require_docloader.getDocumentLoader({ timeout: 0 }), RangeError);
|
|
2032
2029
|
});
|
|
2033
|
-
(0,
|
|
2030
|
+
(0, _fedify_fixture.test)("getDocumentLoader() times out a request without a response", async () => {
|
|
2034
2031
|
await withServer(() => {}, async (baseUrl) => {
|
|
2035
2032
|
const url = `${baseUrl}/hang`;
|
|
2036
2033
|
await (0, node_assert.rejects)(require_docloader.getDocumentLoader({
|
|
@@ -2039,7 +2036,7 @@ function isTimeoutFetchError(error, url) {
|
|
|
2039
2036
|
})(url), (e) => isTimeoutFetchError(e, url));
|
|
2040
2037
|
});
|
|
2041
2038
|
});
|
|
2042
|
-
(0,
|
|
2039
|
+
(0, _fedify_fixture.test)("getDocumentLoader() times out a stalled response body", async () => {
|
|
2043
2040
|
for (const status of [200, 404]) await withServer((_, response) => {
|
|
2044
2041
|
response.writeHead(status, { "Content-Type": "application/activity+json" });
|
|
2045
2042
|
response.write("{\"id\":");
|
|
@@ -2051,7 +2048,7 @@ function isTimeoutFetchError(error, url) {
|
|
|
2051
2048
|
})(url), (e) => isTimeoutFetchError(e, url));
|
|
2052
2049
|
});
|
|
2053
2050
|
});
|
|
2054
|
-
(0,
|
|
2051
|
+
(0, _fedify_fixture.test)("getDocumentLoader() shares the timeout across redirects", async () => {
|
|
2055
2052
|
let requests = 0;
|
|
2056
2053
|
await withServer((request, response) => {
|
|
2057
2054
|
requests++;
|
|
@@ -2078,8 +2075,8 @@ function isTimeoutFetchError(error, url) {
|
|
|
2078
2075
|
})(url)).document, { done: true });
|
|
2079
2076
|
});
|
|
2080
2077
|
});
|
|
2081
|
-
(0,
|
|
2082
|
-
for (const html of [false, true]) await t.
|
|
2078
|
+
(0, _fedify_fixture.test)("getDocumentLoader() shares the timeout across alternates", async (t) => {
|
|
2079
|
+
for (const html of [false, true]) await t.step(html ? "HTML" : "Link header", async () => {
|
|
2083
2080
|
await withServer((request, response) => {
|
|
2084
2081
|
const index = Number(request.url?.split("/").at(-1));
|
|
2085
2082
|
setTimeout(() => {
|
|
@@ -2104,7 +2101,7 @@ function isTimeoutFetchError(error, url) {
|
|
|
2104
2101
|
});
|
|
2105
2102
|
});
|
|
2106
2103
|
});
|
|
2107
|
-
(0,
|
|
2104
|
+
(0, _fedify_fixture.test)("getDocumentLoader() lets the caller's signal abort a request", async () => {
|
|
2108
2105
|
await withServer(() => {}, async (baseUrl) => {
|
|
2109
2106
|
const url = `${baseUrl}/hang`;
|
|
2110
2107
|
for (const timeout of [
|
|
@@ -2137,11 +2134,8 @@ function isTimeoutFetchError(error, url) {
|
|
|
2137
2134
|
});
|
|
2138
2135
|
});
|
|
2139
2136
|
});
|
|
2140
|
-
(0,
|
|
2141
|
-
if ("Deno" in globalThis && (await Deno.permissions.query({ name: "net" })).state !== "granted")
|
|
2142
|
-
t.skip("requires the net permission");
|
|
2143
|
-
return;
|
|
2144
|
-
}
|
|
2137
|
+
(0, _fedify_fixture.test)("getDocumentLoader() bounds DNS lookups that ignore the timeout", async () => {
|
|
2138
|
+
if ("Deno" in globalThis && (await Deno.permissions.query({ name: "net" })).state !== "granted") throw new Error("This DNS test requires Deno network permission (--allow-net).");
|
|
2145
2139
|
esm_default.mockGlobal();
|
|
2146
2140
|
let requests = 0;
|
|
2147
2141
|
const url = "https://slow-dns.example/object";
|
|
@@ -2169,7 +2163,7 @@ function isTimeoutFetchError(error, url) {
|
|
|
2169
2163
|
esm_default.hardReset();
|
|
2170
2164
|
}
|
|
2171
2165
|
});
|
|
2172
|
-
(0,
|
|
2166
|
+
(0, _fedify_fixture.test)("withDocumentLoaderTimeout() cleans up after each call", async () => {
|
|
2173
2167
|
const signals = [];
|
|
2174
2168
|
const loader = require_docloader.withDocumentLoaderTimeout((url, options) => {
|
|
2175
2169
|
signals.push(options.signal);
|
|
@@ -2186,7 +2180,7 @@ function isTimeoutFetchError(error, url) {
|
|
|
2186
2180
|
const inner = () => Promise.reject(/* @__PURE__ */ new Error("unused"));
|
|
2187
2181
|
(0, node_assert.ok)(require_docloader.withDocumentLoaderTimeout(inner, null) === inner);
|
|
2188
2182
|
});
|
|
2189
|
-
(0,
|
|
2183
|
+
(0, _fedify_fixture.test)("getRemoteDocument() keeps error bodies byte for byte", async () => {
|
|
2190
2184
|
const bytes = new Uint8Array([
|
|
2191
2185
|
239,
|
|
2192
2186
|
187,
|
|
@@ -2207,7 +2201,7 @@ function isTimeoutFetchError(error, url) {
|
|
|
2207
2201
|
(0, node_assert.deepStrictEqual)(error.response.status, 404);
|
|
2208
2202
|
(0, node_assert.deepStrictEqual)(new Uint8Array(await error.response.arrayBuffer()), bytes);
|
|
2209
2203
|
});
|
|
2210
|
-
(0,
|
|
2204
|
+
(0, _fedify_fixture.test)("getRemoteDocument() keeps metadata of bodiless or large errors", async () => {
|
|
2211
2205
|
const url = "https://example.com/error";
|
|
2212
2206
|
for (const response of [new Response(null, {
|
|
2213
2207
|
status: 304,
|
|
@@ -2224,7 +2218,7 @@ function isTimeoutFetchError(error, url) {
|
|
|
2224
2218
|
return true;
|
|
2225
2219
|
});
|
|
2226
2220
|
});
|
|
2227
|
-
(0,
|
|
2221
|
+
(0, _fedify_fixture.test)("getDocumentLoader() reports statuses that Response cannot hold", async () => {
|
|
2228
2222
|
await withServer((_, response) => {
|
|
2229
2223
|
response.writeHead(999);
|
|
2230
2224
|
response.end("Request denied");
|
|
@@ -2241,7 +2235,7 @@ function isTimeoutFetchError(error, url) {
|
|
|
2241
2235
|
(0, node_assert.deepStrictEqual)(await error.response.text(), "Request denied");
|
|
2242
2236
|
});
|
|
2243
2237
|
});
|
|
2244
|
-
(0,
|
|
2238
|
+
(0, _fedify_fixture.test)("getDocumentLoader() times out a stalled body of such a status", async () => {
|
|
2245
2239
|
await withServer((_, response) => {
|
|
2246
2240
|
response.writeHead(999);
|
|
2247
2241
|
response.write("Request");
|