From 8bc23bbf31c62ef59e638c43bddcee798a5b7724 Mon Sep 17 00:00:00 2001 From: Deepak Ganesh Date: Sun, 26 Jul 2026 15:46:14 +0530 Subject: [PATCH] Detect XML structured suffix response types Treat RSS, Atom, XHTML, SVG, and other +xml media types as text while preserving JSON, event stream, and binary detection. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- src/utils.ts | 7 ++++++- test/index.test.ts | 22 ++++++++++++++++++++++ 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/src/utils.ts b/src/utils.ts index 3bc0dbf5..e5f65287 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -50,6 +50,7 @@ const textTypes = new Set([ ]); const JSON_RE = /^application\/(?:[\w!#$%&*.^`~-]*\+)?json(;.+)?$/i; +const XML_RE = /^(?:application|image)\/(?:[\w!#$%&*.^`~-]+\+)?xml$/i; // This provides reasonable defaults for the correct parser based on Content-Type header. export function detectResponseType(_contentType = ""): ResponseType { @@ -75,7 +76,11 @@ export function detectResponseType(_contentType = ""): ResponseType { return "stream"; } - if (textTypes.has(contentType) || contentType.startsWith("text/")) { + if ( + XML_RE.test(contentType) || + textTypes.has(contentType) || + contentType.startsWith("text/") + ) { return "text"; } diff --git a/test/index.test.ts b/test/index.test.ts index 5ac20b07..87692156 100644 --- a/test/index.test.ts +++ b/test/index.test.ts @@ -10,6 +10,28 @@ import { import { Readable } from "node:stream"; import { H3, HTTPError, readBody, serve } from "h3"; import { $fetch } from "../src/index.ts"; +import { detectResponseType } from "../src/utils.ts"; + +describe("detectResponseType", () => { + it.each([ + "application/xml", + "application/rss+xml", + "application/atom+xml", + "application/xhtml+xml", + "image/svg+xml", + "text/xml", + "application/soap+xml; charset=utf-8", + "APPLICATION/RSS+XML", + ])("detects %s as text", (contentType) => { + expect(detectResponseType(contentType)).to.equal("text"); + }); + + it("preserves other response type detection", () => { + expect(detectResponseType("application/octet-stream")).to.equal("blob"); + expect(detectResponseType("application/ld+json")).to.equal("json"); + expect(detectResponseType("text/event-stream")).to.equal("stream"); + }); +}); describe("ofetch", () => { let listener: ReturnType;