Handle resume responses without Content-Range#27529
Open
KirtiRamchandani wants to merge 1 commit into
Open
Conversation
Contributor
There was a problem hiding this comment.
Pull request overview
Note
Copilot was unable to run its full agentic suite in this review.
Updates PowerShell web cmdlets’ -Resume handling to tolerate non-compliant 416 RequestedRangeNotSatisfiable responses that omit Content-Range, treating them as “already complete”, and adds test coverage for this behavior.
Changes:
- Add a WebListener endpoint that returns
416without aContent-Rangeheader when aRangerequest is made. - Refactor and harden resume-range handling in
WebRequestPSCmdletto avoid null dereferences and treat missingContent-Rangeas complete. - Add Pester tests for
Invoke-WebRequestandInvoke-RestMethodvalidating the new-Resumebehavior.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 3 comments.
| File | Description |
|---|---|
| test/tools/WebListener/Controllers/ResumeController.cs | Adds a new test endpoint to simulate 416 without Content-Range for range requests |
| test/powershell/Modules/Microsoft.PowerShell.Utility/WebCmdlets.Tests.ps1 | Adds regression tests for -Resume behavior when Content-Range is missing |
| src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs | Refactors resume logic into helpers and treats missing Content-Range as “already complete” |
Comment on lines
+80
to
+85
| string rangeHeader; | ||
| if (TryGetRangeHeader(out rangeHeader)) | ||
| { | ||
| Response.StatusCode = StatusCodes.Status416RequestedRangeNotSatisfiable; | ||
| return; | ||
| } |
| await Response.Body.WriteAsync(FileBytes, 0, FileBytes.Length); | ||
| } | ||
|
|
||
| public async void MissingContentRange() |
Comment on lines
+1742
to
+1744
| // RFC 9110 only says 416 responses SHOULD include Content-Range. Treat a missing | ||
| // header as an already-complete resume instead of failing with a null reference. | ||
| return contentRange is null || (contentRange.HasLength && contentRange.Length == _resumeFileSize); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
Invoke-WebRequest -ResumeandInvoke-RestMethod -Resumecan throw aNullReferenceExceptionwhen a server responds to an already-complete range request with416 Requested Range Not Satisfiablebut omits the optionalContent-Rangeheader.Fixes #23948.
Root Cause
The resume code dereferenced
response.Content.Headers.ContentRangefor every416response. RFC 9110 says a416response should includeContent-Range, but it is not mandatory, and some servers omit it when the requested range starts at EOF.Solution
416responses withoutContent-Rangeas an already-complete resumed download.Content-Rangeis present and shows the remote size differs from the local file size.416withoutContent-Range.Invoke-WebRequestandInvoke-RestMethod.Tests
NullReferenceExceptionlocally with a tiny HTTP server returning416withoutContent-Range.Start-PSBuild -Configuration Debug -NoPSModuleRestorePublish-PSTestToolsInvoke-WebRequest -ResumeandInvoke-RestMethod -Resumeagainst the newMissingContentRangeendpoint.git diff --check(only existing Windows line-ending notices)