fix(chutes): cancel userinfo error response body before returning null (#109677)

This commit is contained in:
wangmiao0668000666
2026-07-17 16:11:11 +08:00
committed by GitHub
parent e693d279b3
commit 538263bafd
2 changed files with 43 additions and 0 deletions
+41
View File
@@ -270,6 +270,47 @@ describe("chutes plugin OAuth", () => {
expect(timeoutSpy).toHaveBeenCalledTimes(2);
});
it("cancels the userinfo error response body when profile lookup fails", async () => {
let canceled = false;
let bytesPulled = 0;
const userInfoResponse = new Response(
new ReadableStream<Uint8Array>({
pull(controller) {
if (bytesPulled > 0) {
controller.close();
return;
}
bytesPulled += 1;
controller.enqueue(new TextEncoder().encode("temporarily unavailable"));
},
cancel() {
canceled = true;
},
}),
{ status: 503 },
);
const fetchFn = vi.fn(async (input: RequestInfo | URL) => {
const url = fetchInputUrl(input);
if (url === CHUTES_TOKEN_ENDPOINT) {
return new Response(
'{"access_token":"at_123","refresh_token":"rt_123","expires_in":3600}',
{ status: 200, headers: { "Content-Type": "application/json" } },
);
}
if (url === CHUTES_USERINFO_ENDPOINT) {
return userInfoResponse;
}
return new Response("not found", { status: 404 });
});
const credentials = await loginWithFetch(fetchFn);
expect(canceled).toBe(true);
expect(credentials.access).toBe("at_123");
expect(credentials.email).toBeUndefined();
expect(credentials.accountId).toBeUndefined();
});
it("cancels authentication when the caller aborts during userinfo", async () => {
const controller = new AbortController();
const reason = new Error("cancelled by caller");
+2
View File
@@ -129,6 +129,8 @@ async function fetchChutesUserInfo(params: {
}),
});
if (!response.ok) {
// Release the connection instead of leaving the error body to idle timeout.
await response.body?.cancel().catch(() => undefined);
return null;
}
const data = await readProviderJsonResponse<unknown>(response, "Chutes userinfo");