Skip to content

Conversation

github-actions[bot]
Copy link
Contributor

@github-actions github-actions bot commented Aug 28, 2025

Backport of #50452 to release/10.0.1xx

Handle gzip-compressed responses in ResponseStreamWrapper

Updates hot reload middleware to decompress a compressed response body before attempting to perform script injection.

Description

This PR fixes an issue where hot reload middleware corrupts the response body when a static HTML file gets served using MapStaticAssets().

The bug occurs due to a combination of factors:

  • When a runtime edit is made to a static asset that was compressed at build time, the file needs to get re-compressed dynamically. A compression level of "No compression" is used to make this re-compression efficient.
  • The low compression level means HTML responses still contain some plaintext. This allows the hot reload script injection logic to detect the closing </body> tag and insert a <script> into the response.
  • Because the response was compressed, it gets corrupted by the inserted script and the browser fails to load the page.

To address this problem, there are two high-level changes in this PR:

  • Hot reload middleware now decompresses HTML responses if gzip compression is detected
  • The script injection logic now correctly handles the case where the closing </body> tag is split between multiple writes to the response stream (long-standing issue)
    • This is a precautionary change to prevent increased stream segmentation from causing script injection to fail more frequently than it did previously

Fixes #50451
Fixes dotnet/aspnetcore#58940

Customer Impact

Customers impacted by this bug will experience the browser failing to load pages served via MapStaticAssets(). They will need to perform one of the following workarounds during development:

  • Explicitly disable the feature that re-compresses static assets if they get changed at runtime
  • Disable hot reload

Many customers have reported running into the bug since it was introduced in .NET 9. At the time of writing, dotnet/aspnetcore#58940 has at least 11 reactions from the community.

Regression?

  • Yes
  • No

This bug has existed since the introduction of MapStaticAssets() in .NET 9. However, it blocks many customers from migrating away from the older static files middleware.

Risk

  • High
  • Medium
  • Low

The feature has thorough automated tests. Manual validation has also confirmed that:

  • The original bug is fixed
  • Script injection succeeds when the response is compressed
  • Hot reload continues to function normally

Verification

  • Manual (required)
  • Automated

Packaging changes reviewed?

  • Yes
  • No
  • N/A

@github-actions github-actions bot requested a review from a team as a code owner August 28, 2025 19:49
@SimonZhao888
Copy link
Member

/azp run

Copy link

Azure Pipelines successfully started running 1 pipeline(s).

@MackinnonBuck
Copy link
Member

@marcpopMSFT This was approved in tactics - are we clear to merge into the release/10.0.1xx branch?

@baronfel
Copy link
Member

baronfel commented Sep 4, 2025

If it's tactics approved then yes. RC2 is open for merges.

@MackinnonBuck MackinnonBuck merged commit f338f70 into release/10.0.1xx Sep 4, 2025
27 of 28 checks passed
@MackinnonBuck MackinnonBuck deleted the backport/pr-50452-to-release/10.0.1xx branch September 4, 2025 16:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants