Skip to content

Commit aff4bb5

Browse files
committed
Simplify bounded HTML reads
The bounded HTML path can rely on the standard Response body type instead of defensive assertions for non-standard mocks. The parser now preserves HTML-labelled JSON compatibility by attempting JSON.parse() directly and converts syntax failures into the same FetchError used for ordinary HTML. #913 (comment) #913 (comment) #913 (comment) #913 (comment) #913 (comment) Assisted-by: Codex:gpt-5.5
1 parent 58fa680 commit aff4bb5

2 files changed

Lines changed: 7 additions & 53 deletions

File tree

packages/vocab-runtime/src/docloader.test.ts

Lines changed: 0 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -369,38 +369,6 @@ test("getDocumentLoader()", async (t) => {
369369
deepStrictEqual(canceled, true);
370370
});
371371

372-
await t.test("HTML body without getReader falls back to text", async () => {
373-
const response = new Response(
374-
JSON.stringify({
375-
"@context": "https://www.w3.org/ns/activitystreams",
376-
id: "https://example.com/body-without-get-reader",
377-
name: "Fetched object",
378-
type: "Object",
379-
}),
380-
{ headers: { "Content-Type": "text/html; charset=utf-8" } },
381-
);
382-
Object.defineProperty(response, "body", { value: {} });
383-
deepStrictEqual(
384-
await getRemoteDocument(
385-
"https://example.com/body-without-get-reader",
386-
response,
387-
() => {
388-
throw new Error("unexpected alternate fetch");
389-
},
390-
),
391-
{
392-
contextUrl: null,
393-
documentUrl: "https://example.com/body-without-get-reader",
394-
document: {
395-
"@context": "https://www.w3.org/ns/activitystreams",
396-
id: "https://example.com/body-without-get-reader",
397-
name: "Fetched object",
398-
type: "Object",
399-
},
400-
},
401-
);
402-
});
403-
404372
fetchMock.get("https://example.com/404", { status: 404 });
405373

406374
await t.test("not ok", async () => {

packages/vocab-runtime/src/docloader.ts

Lines changed: 7 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -122,9 +122,8 @@ function createResponseMetadata(response: Response): Response {
122122
}
123123

124124
async function cancelResponseBody(response: Response): Promise<void> {
125-
const body = response.body as { cancel?: unknown } | null;
126-
if (body != null && typeof body.cancel === "function") {
127-
await body.cancel();
125+
if (response.body != null) {
126+
await response.body.cancel();
128127
}
129128
}
130129

@@ -135,28 +134,15 @@ async function readBoundedText(
135134
const contentLength = response.headers.get("Content-Length");
136135
if (contentLength != null) {
137136
const size = Number(contentLength);
138-
if (Number.isFinite(size) && size > maxBytes) {
137+
if (size > maxBytes) {
139138
await cancelResponseBody(response);
140139
return { text: "", size, tooLarge: true };
141140
}
142141
}
143142

144143
if (response.body == null) return { text: "", size: 0, tooLarge: false };
145144

146-
const body = response.body as ReadableStream<Uint8Array> & {
147-
getReader?: unknown;
148-
};
149-
if (typeof body.getReader !== "function") {
150-
const text = await response.text();
151-
const size = new TextEncoder().encode(text).byteLength;
152-
return {
153-
text: size <= maxBytes ? text : "",
154-
size,
155-
tooLarge: size > maxBytes,
156-
};
157-
}
158-
159-
const reader = body.getReader();
145+
const reader = response.body.getReader();
160146
const decoder = new TextDecoder();
161147
let text = "";
162148
let size = 0;
@@ -319,10 +305,10 @@ export async function getRemoteDocument(
319305
return await fetch(new URL(attribs.href, docUrl).href);
320306
}
321307
}
322-
const trimmed = html.text.trimStart();
323-
if (trimmed.startsWith("{") || trimmed.startsWith("[")) {
308+
try {
324309
document = JSON.parse(html.text);
325-
} else {
310+
} catch (error) {
311+
if (!(error instanceof SyntaxError)) throw error;
326312
throw new FetchError(
327313
documentUrl,
328314
`HTML document has no ActivityPub alternate link ` +

0 commit comments

Comments
 (0)