Skip to content

feat(app): open response URLs as transient requests#8189

Open
jessejamesblack wants to merge 4 commits into
usebruno:mainfrom
jessejamesblack:feature/presigned-url-response-links
Open

feat(app): open response URLs as transient requests#8189
jessejamesblack wants to merge 4 commits into
usebruno:mainfrom
jessejamesblack:feature/presigned-url-response-links

Conversation

@jessejamesblack

@jessejamesblack jessejamesblack commented Jun 4, 2026

Copy link
Copy Markdown

Description

Adds support for opening URLs found in response bodies as transient, unsaved HTTP requests. This supports presigned URL workflows where an API returns a URL that should immediately be sent as a follow-up request.

For S3 presigned URLs with x-id=PutObject, Bruno opens the transient request as PUT, disables auth, preserves URL encoding, and opens the Body tab so upload data can be configured.

Closes #8188

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.

Validation

  • npm.cmd run test --workspace=packages/bruno-app -- src/components/ResponsePane/QueryResult/QueryResultPreview/JsonPreview.spec.js src/providers/ReduxStore/slices/collections/actions.spec.js src/utils/codemirror/linkAware.spec.js --runInBand
  • npx.cmd eslint packages/bruno-app/src/utils/codemirror/linkAware.js packages/bruno-app/src/utils/codemirror/linkAware.spec.js packages/bruno-app/src/components/CodeEditor/index.js packages/bruno-app/src/components/ResponsePane/QueryResult/QueryResultPreview/index.js packages/bruno-app/src/components/ResponsePane/QueryResult/QueryResultPreview/JsonPreview.js packages/bruno-app/src/components/ResponsePane/QueryResult/QueryResultPreview/JsonPreview.spec.js packages/bruno-app/src/globalStyles.js packages/bruno-app/src/providers/ReduxStore/middlewares/tasks/middleware.js packages/bruno-app/src/providers/ReduxStore/slices/collections/actions.js packages/bruno-app/src/providers/ReduxStore/slices/collections/actions.spec.js
  • npm.cmd run build:web

Summary by CodeRabbit

Release Notes

  • New Features

    • Click on HTTP(S) links within response data to automatically create linked requests.
    • Visual indicators now distinguish clickable links in response previews.
  • Tests

    • Added comprehensive test coverage for link-click interactions.

@coderabbitai

coderabbitai Bot commented Jun 4, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Walkthrough

This PR implements clickable HTTP(S) URLs in response bodies. Clicking a URL in CodeEditor or JsonPreview response views creates and opens a transient, unsaved request with inferred method (GET or PUT for presigned URLs). The feature threads through CodeMirror link-detection, view components, and Redux request-queuing infrastructure.

Changes

Clickable Response URLs as Transient Requests

Layer / File(s) Summary
Link-aware click infrastructure
src/utils/codemirror/linkAware.js, src/utils/codemirror/linkAware.spec.js, src/globalStyles.js
CodeMirror link clicks now accept an optional onLinkClick callback to intercept clicks without requiring Cmd/Ctrl modifier; click target receives link-click-enabled class and hint text varies based on handler availability.
JsonPreview URL selection detection
src/components/ResponsePane/QueryResult/QueryResultPreview/JsonPreview.js, JsonPreview.spec.js
JsonPreview validates selected values as HTTP(S) URLs via isHttpUrl helper and forwards only valid URLs to onLinkClick; non-URLs are silently ignored.
CodeEditor link-click forwarding
src/components/CodeEditor/index.js
CodeEditor conditionally wires onLinkClick into CodeMirror's link-aware setup; clicking links invokes handleLinkClick method to forward URLs to the callback.
Request pane-tab routing through Redux
src/providers/ReduxStore/slices/collections/actions.js, actions.spec.js, src/providers/ReduxStore/middlewares/tasks/middleware.js
newHttpRequest action now accepts and forwards requestPaneTab through all request-creation branches (transient, root-level, folder); task middleware uses provided pane-tab when opening requests, falling back to default if omitted.
Response link-click handler and transient request creation
src/components/ResponsePane/QueryResult/QueryResultPreview/index.js
QueryResultPreview orchestrates click-to-request flow via handleResponseLinkClick; helper functions parse request names, detect presigned PUT requests, ensure filename uniqueness, and validate inputs; dispatch errors surface via toast notifications; both CodeEditor and JsonPreview components receive wired callbacks.

Sequence Diagram

sequenceDiagram
  participant User
  participant JsonPreview
  participant QueryResultPreview
  participant Redux
  participant TaskMiddleware
  
  User->>JsonPreview: click URL in response body
  JsonPreview->>JsonPreview: onSelect validates HTTP(S) URL
  JsonPreview->>QueryResultPreview: handleResponseLinkClick(url)
  QueryResultPreview->>QueryResultPreview: parse request name, infer method
  QueryResultPreview->>Redux: dispatch newHttpRequest(transient config)
  Redux->>TaskMiddleware: insertTaskIntoQueue with requestPaneTab
  TaskMiddleware->>User: open transient request in selected pane
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

  • usebruno/bruno#7058: Modifies the same OPEN_REQUEST task flow; main PR adds requestPaneTab forwarding from transient link-click requests while the related PR auto-opens saved transient requests by changing preview-handling behavior.

Suggested reviewers

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

Poem

🔗 A URL gleams in your JSON tree,
Click it once—a request flows free!
Presigned URLs, PUT or GET,
Transient helpers, no save sweat. ✨

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main feature: enabling URLs found in response bodies to be opened as transient HTTP requests.
Linked Issues check ✅ Passed The PR fully implements the requested feature from #8188: clicking URLs in response bodies opens them as transient requests, with PUT method detection for presigned URLs and proper auth/tab handling.
Out of Scope Changes check ✅ Passed All changes are scoped to implementing the response URL-to-transient-request feature and supporting infrastructure; no unrelated modifications detected.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

@jessejamesblack jessejamesblack marked this pull request as ready for review June 4, 2026 21:33

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In
`@packages/bruno-app/src/components/ResponsePane/QueryResult/QueryResultPreview/index.js`:
- Around line 96-123: handleResponseLinkClick currently accepts any URL and
creates a transient HTTP request; add a protocol gate so only http and https
links proceed. Inside handleResponseLinkClick (before calling
getRequestNameFromUrl / isPutObjectPresignedUrl and dispatching newHttpRequest),
validate the URL using the URL constructor or a simple protocol check and return
early if the protocol is not "http:" or "https:". Keep all existing behavior and
parameters (requestName via getRequestNameFromUrl, isPutObjectPresignedUrl,
getUniqueLinkedRequestFilename, newHttpRequest dispatch) unchanged when the
protocol is allowed, and show no change (or bail silently) for non-HTTP(S)
schemes.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 37848597-befe-40d6-9a9b-ad0a8b556eb3

📥 Commits

Reviewing files that changed from the base of the PR and between b70bfb2 and 41ffdf0.

📒 Files selected for processing (10)
  • packages/bruno-app/src/components/CodeEditor/index.js
  • packages/bruno-app/src/components/ResponsePane/QueryResult/QueryResultPreview/JsonPreview.js
  • packages/bruno-app/src/components/ResponsePane/QueryResult/QueryResultPreview/JsonPreview.spec.js
  • packages/bruno-app/src/components/ResponsePane/QueryResult/QueryResultPreview/index.js
  • packages/bruno-app/src/globalStyles.js
  • packages/bruno-app/src/providers/ReduxStore/middlewares/tasks/middleware.js
  • packages/bruno-app/src/providers/ReduxStore/slices/collections/actions.js
  • packages/bruno-app/src/providers/ReduxStore/slices/collections/actions.spec.js
  • packages/bruno-app/src/utils/codemirror/linkAware.js
  • packages/bruno-app/src/utils/codemirror/linkAware.spec.js

Comment on lines +96 to +123
const handleResponseLinkClick = useCallback((url) => {
if (!url || !collection?.uid) {
return;
}

const requestName = getRequestNameFromUrl(url);
const isPutObject = isPutObjectPresignedUrl(url);

dispatch(
newHttpRequest({
requestName,
filename: getUniqueLinkedRequestFilename(collection, requestName),
requestType: 'http-request',
requestUrl: url,
requestMethod: isPutObject ? 'PUT' : 'GET',
collectionUid: collection.uid,
itemUid: null,
isTransient: true,
auth: {
mode: 'none'
},
settings: {
encodeUrl: false
},
...(isPutObject ? { requestPaneTab: 'body' } : {})
})
).catch((err) => toast.error(formatIpcError(err) || 'An error occurred while adding the request'));
}, [collection, dispatch]);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Restrict link-click transient request creation to HTTP(S) protocols.

The shared handler accepts any URL string today; from the editor path this can open transient requests for non-HTTP schemes. Add a protocol gate here so behavior stays aligned with the HTTP(S)-only feature contract.

🔧 Proposed fix
+const isHttpUrl = (url) => {
+  try {
+    const protocol = new URL(url).protocol;
+    return protocol === 'http:' || protocol === 'https:';
+  } catch (e) {
+    return false;
+  }
+};
+
 const QueryResultPreview = ({
@@
-  const handleResponseLinkClick = useCallback((url) => {
-    if (!url || !collection?.uid) {
+  const handleResponseLinkClick = useCallback((url) => {
+    if (!url || !collection?.uid || !isHttpUrl(url)) {
       return;
     }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@packages/bruno-app/src/components/ResponsePane/QueryResult/QueryResultPreview/index.js`
around lines 96 - 123, handleResponseLinkClick currently accepts any URL and
creates a transient HTTP request; add a protocol gate so only http and https
links proceed. Inside handleResponseLinkClick (before calling
getRequestNameFromUrl / isPutObjectPresignedUrl and dispatching newHttpRequest),
validate the URL using the URL constructor or a simple protocol check and return
early if the protocol is not "http:" or "https:". Keep all existing behavior and
parameters (requestName via getRequestNameFromUrl, isPutObjectPresignedUrl,
getUniqueLinkedRequestFilename, newHttpRequest dispatch) unchanged when the
protocol is allowed, and show no change (or bail silently) for non-HTTP(S)
schemes.

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.

Open response body URLs as transient requests

1 participant