From e20a24b54e2a08035b628738f02fef5ce69f7367 Mon Sep 17 00:00:00 2001 From: Ariel Date: Fri, 15 May 2026 11:12:27 +0300 Subject: [PATCH] fix(web): render AVIF images and IANA icon favicons in the response tab (#8232) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fix(web): render AVIF images and IANA icon favicons in the response tab The `ViewImage` regex in `HttpMessage.tsx` rejected two valid image content types, so the response tab did not render them inline: 1. `image/avif` was missing from the alternation. AVIF is widely served by image CDNs and decoded natively in `` by Chrome 85+, Firefox 93+, and Safari 16.1+. 2. `image/vnd.microsoft.icon` (the IANA-canonical `.ico` MIME) never matched because the alternation had `vnc.microsoft.icon` — a `vnc`/`vnd` typo. The de-facto legacy `image/x-icon` continued to work, which made the bug easy to miss. The dots are also unescaped, so the regex coincidentally matches `image/vncXmicrosoftXicon` for any single character `X`. Added `avif`, corrected `vnc` → `vnd`, and escaped the dots. Added a `ViewImage.matches` unit test covering both the additions and the existing image MIME types. * [autofix.ci] apply automated fixes --------- Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com> --- CHANGELOG.md | 2 ++ .../contentviews/HttpMessageSpec.tsx | 21 +++++++++++++++++++ .../components/contentviews/HttpMessage.tsx | 2 +- 3 files changed, 24 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 352f935ed..7bc986e2d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,8 @@ ## Unreleased: mitmproxy next +- mitmweb: Fix AVIF images and `image/vnd.microsoft.icon` favicons not rendering in the response tab. + ([#8232](https://github.com/mitmproxy/mitmproxy/pull/8232), @ariel42) ## 12 May 2026: mitmproxy 12.2.3 diff --git a/web/src/js/__tests__/components/contentviews/HttpMessageSpec.tsx b/web/src/js/__tests__/components/contentviews/HttpMessageSpec.tsx index 473d4f170..09773088b 100644 --- a/web/src/js/__tests__/components/contentviews/HttpMessageSpec.tsx +++ b/web/src/js/__tests__/components/contentviews/HttpMessageSpec.tsx @@ -101,6 +101,27 @@ test("ViewImage", async () => { expect(asFragment()).toMatchSnapshot(); }); +test("ViewImage.matches", () => { + const flow = TFlow(); + const matches = (contentType: string) => { + flow.response.headers = [["Content-Type", contentType]]; + return ViewImage.matches(flow.response); + }; + expect(matches("image/png")).toBe(true); + expect(matches("image/jpeg")).toBe(true); + expect(matches("image/jpg")).toBe(true); + expect(matches("image/gif")).toBe(true); + expect(matches("image/webp")).toBe(true); + expect(matches("image/avif")).toBe(true); + expect(matches("image/svg+xml")).toBe(true); + expect(matches("image/vnd.microsoft.icon")).toBe(true); + expect(matches("image/x-icon")).toBe(true); + expect(matches("IMAGE/AVIF")).toBe(true); + expect(matches("image/heic")).toBe(false); + expect(matches("application/json")).toBe(false); + expect(matches("video/mp4")).toBe(false); +}); + /* This test differs from the one above because clicking the copy button triggers 'handleClickCopyButton'. In the previous test, the response contained "raw content," which caused an "invalid JSON response body" error diff --git a/web/src/js/components/contentviews/HttpMessage.tsx b/web/src/js/components/contentviews/HttpMessage.tsx index 95db7d447..373a3a823 100644 --- a/web/src/js/components/contentviews/HttpMessage.tsx +++ b/web/src/js/components/contentviews/HttpMessage.tsx @@ -228,7 +228,7 @@ function CopyButton({ flow, message }: CopyButtonProps) { } const isImage = - /^image\/(png|jpe?g|gif|webp|vnc.microsoft.icon|x-icon|svg\+xml)$/i; + /^image\/(png|jpe?g|gif|webp|avif|vnd\.microsoft\.icon|x-icon|svg\+xml)$/i; ViewImage.matches = (msg) => isImage.test(MessageUtils.getContentType(msg) || "");