Skip to content

fix: show request body for pending requests in Network tab - #10019

Closed
prathamswe wants to merge 2 commits into
flutter:masterfrom
prathamswe:fix/network-pending-request-body
Closed

prathamswe wants to merge 2 commits into
flutter:masterfrom
prathamswe:fix/network-pending-request-body

Conversation

@prathamswe

@prathamswe prathamswe commented Sep 23, 2026 •

Copy link
Copy Markdown

No open issue tracks this. Related: #9963 (Copy as cURL omitting headers/body on failed requests), #3042 (original Copy as cURL).

Summary

In the Network tab, the request body of an HTTP request is not shown, and Copy as cURL omits --data-raw, while the request is still waiting for a response (e.g. a slow POST). The body is only exposed once the response completes.

Root cause: selecting a request already fetches its full data (getHttpProfileRequest), including the request body, even while it is pending. But DartIOHttpRequestData.requestBody returns null until isResponseComplete, which hides a body that DevTools already has. dart:io records the full request body and sets the request endTime as soon as the request has been sent, before any response arrives.

Fix (http_request_data.dart):

  • requestBody is gated on isRequestComplete (request fully sent, or failed) instead of isResponseComplete. The body is now available for pending requests, in the Request tab and in Copy as cURL.
  • Request bodies are never shown truncated. If a request is selected while its body is still being written, the fetched body is partial. Previously it was cached and kept being shown after the request completed. It is now neither cached nor shown. The body stays hidden, so neither the partial body nor the empty body of the polled profile entry leaks into Copy as cURL, until the full data is fetched again after the request has been sent (e.g. by re-selecting it). No extra VM service calls are added.

Completed requests are unchanged. Requests that fail without a response now also expose their body.

Relation to #9963

#9963 is still open and touches the same line: it removes the isResponseComplete check entirely, which also exposes the body for pending requests. This PR differs and adds:

  1. No truncated bodies. Removing the check exposes a partially written body (e.g. {"email":) for requests still being sent, and Copy as cURL then produces a broken command. This PR only exposes the body once the request is sent, including when the request was selected mid-upload.
  2. Tests for the pending lifecycle, driven through the fake VM service: fetch while pending, then profile refreshes, then response completion.

The two PRs are complementary: this PR does not include #9963's request-header or fetch-before-copy changes. #9963's tests pass on top of this change. Whichever lands first, I'm happy to rebase the other on top.

Tests

New tests in test/http/curl_command_test.dart (constructed with plain DartIOHttpRequestData, not the test subclass that falls back to raw bytes):

  • A pending request awaiting its response includes the body in requestBody and Copy as cURL (fails before this change).
  • A request still being sent omits the body.
  • A completed request includes the body.
  • A request that failed without a response includes the body (fails before this change).
  • With the VM service, the body fetched while pending survives profile refreshes and response completion (fails before this change).
  • With the VM service, a request selected while still being sent never exposes the partial or empty body, and shows the complete body once fetched after being sent (fails with only the gate change).

Existing tests for requests without a body and for headers are unchanged and pass.

Test plan

  • flutter test test/http/curl_command_test.dart test/screens/network/ (154 passed)
  • Fix Copy as cURL omitting headers and body on failed requests #9963's test additions applied on top of this change: pass
  • dart format clean; flutter analyze reports no new issues (8 existing errors in unrelated test/test_infra/fixtures/ apps)
  • Manual: Copy as cURL on a pending POST in a running app

Pre-launch Checklist

General checklist

  • I read the Contributor Guide and followed the process outlined there for submitting PRs.
  • I read the Tree Hygiene wiki page, which explains my responsibilities.
  • I read the Flutter Style Guide recently, and have followed its advice.
  • I signed the CLA.
  • I updated/added relevant documentation (doc comments with ///).

Issues checklist

Tests checklist

  • I added new tests to check the change I am making...
  • OR there is a reason for not adding tests, which I explained in the PR description.

AI-tooling checklist

  • I did not use any AI tooling in creating this PR.
  • OR I did use AI tooling, and...
    • I read the AI contributions guidelines and agree to follow them.
    • I reviewed all AI-generated code before opening this PR.
    • I understand and am able to discuss the code in this PR.
    • I have verifed the accuracy of any AI-generated text included in the PR description.
    • I commit to verifying the accuracy of any AI-generated code or text that I upload in response to review comments.

Feature-change checklist

  • This PR does not change the DevTools UI or behavior and...
    • I added the release-notes-not-required label or left a comment requesting the label be added.
  • OR this PR does change the DevTools UI or behavior and...
    • I added an entry to packages/devtools_app/release_notes/NEXT_RELEASE_NOTES.md.
    • I included before/after screenshots and/or a GIF demo of the new UI to my PR description.
    • I ran the DevTools app locally to manually verify my changes.

build.yaml badge

@prathamswe
prathamswe requested a review from a team as a code owner September 23, 2026 08:15
@prathamswe
prathamswe requested review from srawlins and removed request for a team September 23, 2026 08:15
@google-cla

google-cla Bot commented Sep 23, 2026

Copy link
Copy Markdown

Thanks for your pull request! It looks like this may be your first contribution to a Google open source project. Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA).

View this failed invocation of the CLA check for more information.

For the most up to date status, view the checks section at the bottom of the pull request.

The request body was hidden until the response completed, so the Request
tab and Copy as cURL omitted it for requests still awaiting a response.
Gate it on the request having been sent instead, and never cache or show
a body fetched while the request was still being sent.
@prathamswe
prathamswe force-pushed the fix/network-pending-request-body branch from 5a19334 to 2044da8 Compare September 23, 2026 08:16

@gemini-code-assist gemini-code-assist 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.

Code Review

This pull request ensures that the HTTP request body is displayed and copied correctly for pending or failed requests once it has been fully sent, preventing truncated bodies from being shown. It introduces tracking for whether data was fetched before the request completed sending and adds comprehensive unit tests. The feedback recommends replacing the placeholder PR link in the release notes and suggests applying the same gating logic to the encodedRequest getter to prevent other components from accessing truncated request bodies.

* Fixed the Request tab and Copy as cURL missing the body of HTTP requests
that are still waiting for a response. A request body is only shown once it
has been fully sent, so it is never shown truncated. -
[#10019](https://github.com/flutter/devtools/pull/10019)

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.

medium

[MUST-FIX] Please replace the placeholder link [#TODO](https://github.com/flutter/devtools/pull/TODO) with the actual pull request number once it is created.

Comment on lines +415 to +417
if (!_request.isRequestComplete || _fetchedBeforeRequestSent) {
return null;
}

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.

medium

[CONCERN] The encodedRequest getter (around line 398) also returns fullRequest.requestBody directly without checking _request.isRequestComplete or _fetchedBeforeRequestSent. To prevent other components (such as binary/hex viewers) from accessing a truncated or partial request body, consider applying the same gating logic to encodedRequest as well.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants