Skip to content

Conversation

Copy link
Contributor

Copilot AI commented Dec 2, 2025

Fix MapStaticAssets returning incorrect Content-Length for Range requests

  • You've read the Contributor Guide and Code of Conduct.
  • You've included unit or integration tests for your change, where applicable.
  • You've included inline docs for your change, where applicable.
  • There's an open issue for the PR that you are making. If you'd like to propose a new feature or change, please open an issue to discuss the change or find an existing issue.

Fix Range request handling in development mode with runtime file reloading

Description

In development mode with ReloadStaticAssetsAtRuntime enabled, MapStaticAssets returns the full file size in Content-Length for Range requests, causing mismatch with Content-Range and breaking video playback.

# Request 100 bytes
curl -H "Range: bytes=0-99" http://localhost:5253/video.mp4

# Response shows mismatch
Content-Length: 95507362      # Full file size (wrong)
Content-Range: bytes 0-99/95507362  # Correct range

Root cause: RuntimeStaticAssetResponseBodyFeature.SendFileAsync ignored the offset and count parameters, always sending the entire file.

Fix: Check response status code to detect Range requests (206 Partial Content) and preserve original offset/count parameters:

  • For 206 responses: forward original offset/count, don't overwrite Content-Length
  • For 200 responses: send entire file with updated Content-Length

Fixes #61601

Original prompt

This section details on the original issue you should resolve

<issue_title>MapStaticAssets returns incorrect Content-Length for custom Range</issue_title>
<issue_description>### Is there an existing issue for this?

  • I have searched the existing issues

Describe the bug

In Blazor projects, MapStaticAssets returns the full file size in the Content-Length header when a custom Range is requested, causing a mismatch between the Content-Length and Content-Range headers

Expected Behavior

Content-Length is equals to end - start + 1 where start and end are ranges from Content-Range response header

Steps To Reproduce

  1. Create an empty blazor project
dotnet new blazor --empty
  1. Add video file to wwwroot folder
  2. Run application
dotnet run
  1. Run curl command to fetch 100 bytes from application
curl -v -H "Range: bytes=0-99" http://localhost:5253/video.mp4 -o NIL
  1. Observe a mismatch between Content-Length and Content-Range
* Host localhost:5253 was resolved.
* IPv6: ::1
* IPv4: 127.0.0.1
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0*   Trying [::1]:5253...
* Connected to localhost (::1) port 5253
* using HTTP/1.x
> GET /video.mp4 HTTP/1.1
> Host: localhost:5253
> User-Agent: curl/8.14.1
> Accept: */*
> Range: bytes=0-99
>
* Request completely sent off
< HTTP/1.1 206 Partial Content
< Content-Length: 95507362
< Content-Type: video/mp4
< Date: Mon, 18 Aug 2025 19:39:00 GMT
< Server: Kestrel
< Accept-Ranges: bytes
< Accept-Ranges: bytes
< Cache-Control: no-cache
< Content-Range: bytes 0-99/95507362
< ETag: "Ohy6wB7zeYQVaLxVqXJBsAx5fNPo8NWfrXhRmX8qH1M="
< Last-Modified: Mon, 26 Jun 2023 21:12:26 GMT
<
{ [16384 bytes data]
100 91.0M  100 91.0M    0     0   122M      0 --:--:-- --:--:-- --:--:--  123M
* Connection dotnet/aspnetcore#0 to host localhost left intact
  1. Stop application, open Components\Pages\Home.razor and add following text:
<video controls>
    <source src="/video.mp4" type="video/mp4">
</video>
  1. Run application again
dotnet run
  1. Open Home page in firefox and observe "No video with supported format and MIME type found." or in chrome and observe that the video does not load

Exceptions (if any)

No response

.NET Version

9.0.302

Anything else?

.NET SDK:
Version: 9.0.302
Commit: bb2550b9af
Workload version: 9.0.300-manifests.88387b28
MSBuild version: 17.14.13+65391c53b

Runtime Environment:
OS Name: Windows
OS Version: 10.0.26100
OS Platform: Windows
RID: win-x64
Base Path: C:\Program Files\dotnet\sdk\9.0.302\

.NET workloads installed:
[maccatalyst]
Installation Source: VS 17.14.36327.8
Manifest Version: 18.5.9214/9.0.100
Manifest Path: C:\Program Files\dotnet\sdk-manifests\9.0.100\microsoft.net.sdk.maccatalyst\18.5.9214\WorkloadManifest.json
Install Type: Msi

[aspire]
Installation Source: VS 17.14.36327.8
Manifest Version: 8.2.2/8.0.100
Manifest Path: C:\Program Files\dotnet\sdk-manifests\8.0.100\microsoft.net.sdk.aspire\8.2.2\WorkloadManifest.json
Install Type: Msi

[ios]
Installation Source: VS 17.14.36327.8
Manifest Version: 18.5.9214/9.0.100
Manifest Path: C:\Program Files\dotnet\sdk-manifests\9.0.100\microsoft.net.sdk.ios\18.5.9214\WorkloadManifest.json
Install Type: Msi

[android]
Installation Source: VS 17.14.36327.8
Manifest Version: 35.0.78/9.0.100
Manifest Path: C:\Program Files\dotnet\sdk-manifests\9.0.100\microsoft.net.sdk.android\35.0.78\WorkloadManifest.json
Install Type: Msi

[maui-windows]
Installation Source: VS 17.14.36327.8
Manifest Version: 9.0.51/9.0.100
Manifest Path: C:\Program Files\dotnet\sdk-manifests\9.0.100\microsoft.net.sdk.maui\9.0.51\WorkloadManifest.json
Install Type: Msi

[wasm-tools]
Installation Source: VS 17.14.36327.8
Manifest Version: 9.0.7/9.0.100
Manifest Path: C:\Program Files\dotnet\sdk-manifests\9.0.100\microsoft.net.workload.mono.toolchain.current\9.0.7\WorkloadManifest.json
Install Type: Msi

Configured to use loose manifests when installing new manifests.

Host:
Version: 9.0.7
Architecture: x64
Commit: 3c298d9f00

.NET SDKs installed:
8.0.119 [C:\Program Files\dotnet\sdk]
8.0.413 [C:\Program Files\dotnet\sdk]
9.0.302 [C:\Program Files\dotnet\sdk]

.NET runtimes installed:
Microsoft.AspNetCore.App 3.1.27 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 3.1.32 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 5.0.17 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.Ap...


💬 We'd love your input! Share your thoughts on Copilot coding agent in our 2 minute survey.

@dotnet-policy-service
Copy link
Contributor

Greetings! You've submitted a PR that modifies code that is shared with https://github.com/dotnet/runtime . Please make sure you synchronize this code with the changes in that repo!

Co-authored-by: javiercn <6995051+javiercn@users.noreply.github.com>
Copilot AI changed the title [WIP] Fix incorrect Content-Length header for custom Range in MapStaticAssets Fix MapStaticAssets returning incorrect Content-Length for Range requests Dec 2, 2025
Copilot AI requested a review from javiercn December 2, 2025 22:38
Copilot finished work on behalf of javiercn December 2, 2025 22:38
@javiercn javiercn marked this pull request as ready for review December 3, 2025 16:18
Copilot finished reviewing on behalf of javiercn December 3, 2025 16:21
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR fixes a bug in the static assets middleware where range requests in development mode with runtime file reloading returned incorrect Content-Length headers. When MapStaticAssets with ReloadStaticAssetsAtRuntime enabled handled HTTP Range requests, it returned the full file size in Content-Length instead of the range size, causing video playback and other range-dependent features to break.

Key changes:

  • Modified RuntimeStaticAssetResponseBodyFeature.SendFileAsync to detect range requests (206 status code) and preserve original offset/count parameters
  • Added test coverage for range requests with modified assets

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.

File Description
src/StaticAssets/src/Development/StaticAssetDevelopmentRuntimeHandler.cs Fixed SendFileAsync to detect range requests via status code check and correctly handle offset/count parameters for both range (206) and full file (200) responses
src/StaticAssets/test/StaticAssetsIntegrationTests.cs Added comprehensive test RangeRequestReturnsCorrectContentLengthForModifiedAssets that verifies correct Content-Length for two different range requests

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.

MapStaticAssets returns incorrect Content-Length for custom Range WASH and java script a hit or miss if that web page runs

2 participants