Address response bodies by response id instead of a filesystem path

The body commands took a path from the client, so a token holder could
read any file the process could. They now take a response id and resolve
the location themselves, and the UI never sees a path at all: the desktop
host asks the backend where the file is, and the bridge fetches
/responses/:id/body.

Ephemeral responses (GraphQL introspection) never reach the database, so
resolution falls back to the path send writes them to.
This commit is contained in:
Gregory Schier
2026-08-14 17:02:05 -07:00
parent 99a318224f
commit 448d349af8
18 changed files with 366 additions and 110 deletions
@@ -8,6 +8,7 @@ import { useCopyHttpResponse } from "../hooks/useCopyHttpResponse";
import { useHttpResponseEvents } from "../hooks/useHttpResponseEvents";
import { usePinnedHttpResponse } from "../hooks/usePinnedHttpResponse";
import { useResponseBodyBytes, useResponseBodyText } from "../hooks/useResponseBodyText";
import { useResponseBodyUrl } from "../hooks/useResponseBodyUrl";
import { useResponseViewMode } from "../hooks/useResponseViewMode";
import { useSaveResponse } from "../hooks/useSaveResponse";
import { useTimelineViewMode } from "../hooks/useTimelineViewMode";
@@ -409,14 +410,13 @@ function EnsureCompleteResponse({
Component,
}: {
response: HttpResponse;
Component: ComponentType<{ bodyPath: string }>;
Component: ComponentType<{ url: string }>;
}) {
if (response.bodyPath === null) {
return <div>Empty response body</div>;
}
// Wait until the response has been fully-downloaded before asking for it
const complete = response.state === "closed";
const bodyUrl = useResponseBodyUrl(complete ? response : null);
// Wait until the response has been fully-downloaded
if (response.state !== "closed") {
if (!complete || bodyUrl.isPending) {
return (
<EmptyStateText>
<LoadingIcon />
@@ -424,7 +424,15 @@ function EnsureCompleteResponse({
);
}
return <Component bodyPath={response.bodyPath} />;
if (bodyUrl.error) {
return <Banner color="danger">{String(bodyUrl.error)}</Banner>;
}
if (bodyUrl.data == null) {
return <div>Empty response body</div>;
}
return <Component url={bodyUrl.data} />;
}
function HttpSvgViewer({ response }: { response: HttpResponse }) {