Skip to content

feat: Improve response content type detection and SVG handling#6741

Merged
bijin-bruno merged 6 commits intousebruno:mainfrom
abhishek-bruno:fix/svg-default-preview
Jan 13, 2026
Merged

feat: Improve response content type detection and SVG handling#6741
bijin-bruno merged 6 commits intousebruno:mainfrom
abhishek-bruno:fix/svg-default-preview

Conversation

@abhishek-bruno
Copy link
Member

@abhishek-bruno abhishek-bruno commented Jan 8, 2026

Description

This PR enhances the response content type detection system with better support for SVG and other image formats, along with minor UI and export improvements.

Contribution Checklist:

  • I've used AI significantly to create this pull request
  • The pull request only addresses one issue or adds one feature.
  • The pull request does not introduce any breaking changes
  • I have added screenshots or gifs to help explain the change if applicable.
  • I have read the contribution guidelines.
  • Create an issue and link to the pull request.

Note: Keeping the PR small and focused helps make it easier to review and merge. If you have multiple changes you want to make, please consider submitting them as separate pull requests.

Publishing to New Package Managers

Please see here for more information.

Summary by CodeRabbit

  • New Features

    • Added AVIF image support in the response viewer so these images now render as previews.
  • Improvements

    • Enhanced SVG detection (handles XML declarations, comments, or leading whitespace and base64-encoded SVG) and now treats SVG as text-based for more reliable previews.
    • Preview selection now prefers detected content type over header values, improving accuracy of displayed previews.

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Jan 8, 2026

Walkthrough

Added AVIF and SVG detection to buffer/base64 content-type detection and adjusted preview logic to prefer detectedContentType over header-derived contentType; SVG is excluded from byte-format classification so it is treated as text for previews.

Changes

Cohort / File(s) Summary
Buffer MIME detections
packages/bruno-app/src/utils/response/index.js
Added isSvgContent helper; added AVIF (image/avif) magic-number checks; added explicit SVG detection (image/svg+xml) in detectContentTypeFromBuffer; added SVG pre-check in detectContentTypeFromBase64.
Preview content-type precedence
packages/bruno-app/src/components/ResponsePane/QueryResult/index.js
QueryResult now forwards detectedContentType ?? contentType to previews; isByteFormatType now returns false for svg, treating SVG as text for preview selection.

Sequence Diagram(s)

sequenceDiagram
  actor User
  participant QueryResult as QueryResult Component
  participant Utils as response utils
  participant Preview as QueryResultPreview

  User->>QueryResult: request preview with response bytes + headers
  QueryResult->>Utils: detectContentTypeFromBase64 / detectContentTypeFromBuffer(data)
  Utils-->>QueryResult: detectedContentType (e.g., image/svg+xml / image/avif / ...)
  QueryResult->>Preview: render(detectedContentType ?? headerContentType, data)
  Preview->>Preview: select renderer (text vs byte) — SVG treated as text
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Suggested reviewers

  • helloanoop
  • lohit-bruno
  • naman-bruno
  • bijin-bruno

Poem

Bytes hum quietly, a furtive art,
AVIF joins and SVG finds its part.
Detection leads where headers once steered,
Preview listens to what the buffer declared. 🎨🧩

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and accurately summarizes the main objective of the PR: improving response content type detection and SVG handling, which aligns with the changeset modifications.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings

📜 Recent review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 9af8196 and 1aac474.

📒 Files selected for processing (2)
  • packages/bruno-app/src/components/ResponsePane/QueryResult/index.js
  • packages/bruno-app/src/utils/response/index.js
🚧 Files skipped from review as they are similar to previous changes (1)
  • packages/bruno-app/src/utils/response/index.js
🧰 Additional context used
📓 Path-based instructions (1)
**/*.{js,jsx,ts,tsx}

📄 CodeRabbit inference engine (CODING_STANDARDS.md)

**/*.{js,jsx,ts,tsx}: Use 2 spaces for indentation. No tabs, just spaces
Stick to single quotes for strings. For JSX/TSX attributes, use double quotes (e.g., )
Always add semicolons at the end of statements
No trailing commas
Always use parentheses around parameters in arrow functions, even for single params
For multiline constructs, put opening braces on the same line, and ensure consistency. Minimum 2 elements for multiline
No newlines inside function parentheses
Space before and after the arrow in arrow functions. () => {} is good
No space between function name and parentheses. func() not func ()
Semicolons go at the end of the line, not on a new line
Names for functions need to be concise and descriptive
Add in JSDoc comments to add more details to the abstractions if needed
Add in meaningful comments instead of obvious ones where complex code flow is explained properly

Files:

  • packages/bruno-app/src/components/ResponsePane/QueryResult/index.js
🧠 Learnings (3)
📚 Learning: 2025-12-02T09:45:31.709Z
Learnt from: sid-bruno
Repo: usebruno/bruno PR: 6266
File: packages/bruno-app/src/components/ResponsePane/ResponseCopy/index.js:38-38
Timestamp: 2025-12-02T09:45:31.709Z
Learning: In the ResponseCopy component (packages/bruno-app/src/components/ResponsePane/ResponseCopy/index.js), the copy button is intentionally disabled using `!response.data` to prevent copying stream resets which result in empty strings.

Applied to files:

  • packages/bruno-app/src/components/ResponsePane/QueryResult/index.js
📚 Learning: 2025-12-17T21:41:24.730Z
Learnt from: naman-bruno
Repo: usebruno/bruno PR: 6407
File: packages/bruno-app/src/components/Environments/ConfirmCloseEnvironment/index.js:5-41
Timestamp: 2025-12-17T21:41:24.730Z
Learning: Do not suggest PropTypes validation for React components in the Bruno codebase. The project does not use PropTypes, so reviews should avoid proposing PropTypes and rely on the existing typing/validation approach (e.g., TypeScript or alternative runtime checks) if applicable. This guideline applies broadly to all JavaScript/JSX components in the repo.

Applied to files:

  • packages/bruno-app/src/components/ResponsePane/QueryResult/index.js
📚 Learning: 2026-01-09T18:25:14.640Z
Learnt from: kanakkholwal
Repo: usebruno/bruno PR: 6767
File: packages/bruno-app/src/components/ResponseExample/index.js:221-226
Timestamp: 2026-01-09T18:25:14.640Z
Learning: In the Bruno Electron renderer code (packages/bruno-app), assume window.ipcRenderer is always available and skip existence checks. Do not guard for ipcRenderer in this Electron context; use window.ipcRenderer directly (e.g., window.ipcRenderer.send(...), window.ipcRenderer.on(...)). If there are non-Electron contexts (such as test environments or non-Electron builds), add guards or mocks to avoid runtime errors there, but for the intended Electron renderer files, this pattern should be applied broadly within packages/bruno-app.

Applied to files:

  • packages/bruno-app/src/components/ResponsePane/QueryResult/index.js
🧬 Code graph analysis (1)
packages/bruno-app/src/components/ResponsePane/QueryResult/index.js (4)
packages/bruno-app/src/utils/common/index.js (1)
  • contentType (97-97)
packages/bruno-app/src/providers/ReduxStore/slices/collections/index.js (1)
  • contentType (1521-1521)
packages/bruno-electron/src/ipc/network/interpolate-vars.js (2)
  • contentType (6-6)
  • contentType (76-76)
packages/bruno-electron/src/ipc/network/axios-instance.js (1)
  • contentType (84-84)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (6)
  • GitHub Check: SSL Tests - macOS
  • GitHub Check: Playwright E2E Tests
  • GitHub Check: SSL Tests - Linux
  • GitHub Check: SSL Tests - Windows
  • GitHub Check: Unit Tests
  • GitHub Check: CLI Tests
🔇 Additional comments (2)
packages/bruno-app/src/components/ResponsePane/QueryResult/index.js (2)

68-71: LGTM – SVG exclusion logic is sound.

The case-insensitive check correctly identifies SVG content types and excludes them from byte format handling, allowing SVG to be treated as text for preview purposes. The guard at line 82 ensures contentType is truthy before this function is invoked.


207-207: LGTM – Preferring detected content type is the right approach.

Using detectedContentType ?? contentType ensures that when buffer-based detection succeeds (especially for SVG), it takes precedence over the header-derived type. This aligns well with the related changes in detectContentTypeFromBase64 and isSvgContent utilities.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@pull-request-size pull-request-size bot added size/S and removed size/XS labels Jan 8, 2026
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

🤖 Fix all issues with AI agents
In @packages/bruno-app/src/components/ResponsePane/QueryResult/index.js:
- Line 206: getDefaultResponseFormat currently treats all image/* types the
same, causing SVG (image/svg+xml) to be returned as base64 instead of HTML;
update getDefaultResponseFormat to check for 'image/svg+xml' (using
detectedContentType or contentType input) before the generic /^image\// rule and
return { format: 'html', tab: 'preview' } for SVG so SVG responses default to
HTML preview; locate the getDefaultResponseFormat function and insert this
SVG-specific rule above the existing image rule.

In @packages/bruno-app/src/utils/response/index.js:
- Around line 179-181: EPS detection currently compares against the wrong
signature (%!PSF) and will never match real files; update the check that
inspects the bytes array (the block that returns 'image/eps') to compare the
correct sequence "%!PS-Adobe" and ensure the surrounding buffer-length guard
requires at least 10 bytes (i.e., verify bytes.length >= 10 before accessing
indices) so you don't read out of bounds.
- Around line 175-177: The current SVG detection only matches the exact bytes
sequence for "<svg " at the start, which misses valid SVGs (XML prolog, "<svg>",
newline/tab, namespace prefixes). Update the detection that currently inspects
bytes[...] to instead read and decode up to the first 512 bytes, strip any
leading XML declaration or whitespace, convert to lowercase, and test for a
pattern like "<svg" allowing optional ":" and non-alphanumeric after it (e.g.,
use a regex testing for /^<\s*svg(\b|:)/ or scanning for "<svg" anywhere in the
first 512 bytes). Replace the exact bytes[0]... check with this more robust
search so files beginning with "<?xml" or "<svg>" or "<svg:svg>" are correctly
identified as 'image/svg+xml'.
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 19afbc3 and 1572c38.

📒 Files selected for processing (2)
  • packages/bruno-app/src/components/ResponsePane/QueryResult/index.js
  • packages/bruno-app/src/utils/response/index.js
🧰 Additional context used
📓 Path-based instructions (1)
**/*.{js,jsx,ts,tsx}

📄 CodeRabbit inference engine (CODING_STANDARDS.md)

**/*.{js,jsx,ts,tsx}: Use 2 spaces for indentation. No tabs, just spaces
Stick to single quotes for strings. For JSX/TSX attributes, use double quotes (e.g., )
Always add semicolons at the end of statements
No trailing commas
Always use parentheses around parameters in arrow functions, even for single params
For multiline constructs, put opening braces on the same line, and ensure consistency. Minimum 2 elements for multiline
No newlines inside function parentheses
Space before and after the arrow in arrow functions. () => {} is good
No space between function name and parentheses. func() not func ()
Semicolons go at the end of the line, not on a new line
Names for functions need to be concise and descriptive
Add in JSDoc comments to add more details to the abstractions if needed
Add in meaningful comments instead of obvious ones where complex code flow is explained properly

Files:

  • packages/bruno-app/src/components/ResponsePane/QueryResult/index.js
  • packages/bruno-app/src/utils/response/index.js
🧠 Learnings (1)
📚 Learning: 2025-12-17T21:41:24.730Z
Learnt from: naman-bruno
Repo: usebruno/bruno PR: 6407
File: packages/bruno-app/src/components/Environments/ConfirmCloseEnvironment/index.js:5-41
Timestamp: 2025-12-17T21:41:24.730Z
Learning: Do not suggest PropTypes validation for React components in the Bruno codebase. The project does not use PropTypes, so reviews should avoid proposing PropTypes and rely on the existing typing/validation approach (e.g., TypeScript or alternative runtime checks) if applicable. This guideline applies broadly to all JavaScript/JSX components in the repo.

Applied to files:

  • packages/bruno-app/src/components/ResponsePane/QueryResult/index.js
  • packages/bruno-app/src/utils/response/index.js
🧬 Code graph analysis (1)
packages/bruno-app/src/components/ResponsePane/QueryResult/index.js (5)
packages/bruno-app/src/utils/common/index.js (1)
  • contentType (97-97)
packages/bruno-electron/src/ipc/network/interpolate-vars.js (2)
  • contentType (6-6)
  • contentType (76-76)
packages/bruno-app/src/providers/ReduxStore/slices/collections/index.js (1)
  • contentType (1498-1498)
packages/bruno-tests/src/index.js (1)
  • contentType (30-30)
packages/bruno-electron/src/ipc/network/axios-instance.js (1)
  • contentType (84-84)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (6)
  • GitHub Check: SSL Tests - Windows
  • GitHub Check: SSL Tests - Linux
  • GitHub Check: SSL Tests - macOS
  • GitHub Check: Playwright E2E Tests
  • GitHub Check: Unit Tests
  • GitHub Check: CLI Tests

@pull-request-size pull-request-size bot added size/M and removed size/S labels Jan 8, 2026
@abhishek-bruno abhishek-bruno changed the title feat: add SVG support for HTML preview in response format handling feat: Improve response content type detection and SVG handling Jan 8, 2026
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (2)
packages/bruno-app/src/utils/response/index.js (1)

206-208: Consider using isSvgContent for more robust SVG detection.

The current check requires exactly <svg (with space), which misses valid SVG files like <svg>, <svg\n>, or <svg\t>. Since isSvgContent is already available and detectContentTypeFromBuffer has access to the full buffer, using it here would improve detection consistency.

♻️ Proposed improvement
-  if (bytes[0] === 0x3C && bytes[1] === 0x73 && bytes[2] === 0x76 && bytes[3] === 0x67 && bytes[4] === 0x20) {
-    return 'image/svg+xml';
-  }
+  if (isSvgContent(buffer)) {
+    return 'image/svg+xml';
+  }
packages/bruno-app/src/components/ResponsePane/QueryResult/index.js (1)

123-125: Remove unused dependency from useMemo.

The isLargeResponse variable isn't used in the computation, causing unnecessary recalculations when it changes.

♻️ Proposed fix
  const detectedContentType = useMemo(() => {
    return detectContentTypeFromBase64(dataBuffer);
-  }, [dataBuffer, isLargeResponse]);
+  }, [dataBuffer]);
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 4bdb334 and 9af8196.

📒 Files selected for processing (2)
  • packages/bruno-app/src/components/ResponsePane/QueryResult/index.js
  • packages/bruno-app/src/utils/response/index.js
🧰 Additional context used
📓 Path-based instructions (1)
**/*.{js,jsx,ts,tsx}

📄 CodeRabbit inference engine (CODING_STANDARDS.md)

**/*.{js,jsx,ts,tsx}: Use 2 spaces for indentation. No tabs, just spaces
Stick to single quotes for strings. For JSX/TSX attributes, use double quotes (e.g., )
Always add semicolons at the end of statements
No trailing commas
Always use parentheses around parameters in arrow functions, even for single params
For multiline constructs, put opening braces on the same line, and ensure consistency. Minimum 2 elements for multiline
No newlines inside function parentheses
Space before and after the arrow in arrow functions. () => {} is good
No space between function name and parentheses. func() not func ()
Semicolons go at the end of the line, not on a new line
Names for functions need to be concise and descriptive
Add in JSDoc comments to add more details to the abstractions if needed
Add in meaningful comments instead of obvious ones where complex code flow is explained properly

Files:

  • packages/bruno-app/src/utils/response/index.js
  • packages/bruno-app/src/components/ResponsePane/QueryResult/index.js
🧠 Learnings (1)
📚 Learning: 2025-12-17T21:41:24.730Z
Learnt from: naman-bruno
Repo: usebruno/bruno PR: 6407
File: packages/bruno-app/src/components/Environments/ConfirmCloseEnvironment/index.js:5-41
Timestamp: 2025-12-17T21:41:24.730Z
Learning: Do not suggest PropTypes validation for React components in the Bruno codebase. The project does not use PropTypes, so reviews should avoid proposing PropTypes and rely on the existing typing/validation approach (e.g., TypeScript or alternative runtime checks) if applicable. This guideline applies broadly to all JavaScript/JSX components in the repo.

Applied to files:

  • packages/bruno-app/src/utils/response/index.js
  • packages/bruno-app/src/components/ResponsePane/QueryResult/index.js
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (6)
  • GitHub Check: SSL Tests - macOS
  • GitHub Check: SSL Tests - Linux
  • GitHub Check: SSL Tests - Windows
  • GitHub Check: Playwright E2E Tests
  • GitHub Check: Unit Tests
  • GitHub Check: CLI Tests
🔇 Additional comments (5)
packages/bruno-app/src/utils/response/index.js (3)

95-123: LGTM: Solid SVG detection logic.

The isSvgContent helper correctly handles multiple SVG variations:

  • Fast path for immediate <svg tags
  • Slow path for XML declarations, doctypes, and comments
  • Proper boundary checks with limit = length - 3 for safe array access

192-195: LGTM: AVIF detection correctly positioned.

The byte offsets align with the ISO Base Media File Format specification (bytes 4-7: "ftyp", bytes 8-11: "avif").


276-278: LGTM: Comprehensive SVG detection for base64 content.

Using isSvgContent here provides robust detection after the initial magic number checks.

packages/bruno-app/src/components/ResponsePane/QueryResult/index.js (2)

69-69: LGTM: Correct SVG handling as text-based format.

The case-insensitive check properly excludes SVG from byte formats since it's XML-based. This aligns with the enhanced SVG detection in the utils layer.


207-207: LGTM: Appropriate preference for detected content type.

Using the nullish coalescing operator to prefer detectedContentType over header-based contentType improves reliability, especially for SVG and other formats where headers may be incorrect or missing.

@abhishek-bruno abhishek-bruno force-pushed the fix/svg-default-preview branch from 9af8196 to 1aac474 Compare January 12, 2026 06:59
@bijin-bruno bijin-bruno merged commit e4a1fca into usebruno:main Jan 13, 2026
8 checks passed
@coderabbitai coderabbitai bot mentioned this pull request Feb 5, 2026
5 tasks
FraCata00 pushed a commit to FraCata00/bruno that referenced this pull request Feb 9, 2026
…uno#6741)

* feat: add SVG support for HTML preview in response format handling

* feat: enhance content type detection by adding support for AVIF and SVG formats

* fix: exclude SVG from byte format type detection in response preview

* feat: add helper function to detect SVG content in response handling

* fix: ensure SVG content type detection is case insensitive and remove EPS detection

* fix: correct byte offset for AVIF content type detection in response handling
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants