Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
78b7742
Outfile without filename
CarloToso Jan 23, 2023
27a7d34
remove useless
CarloToso Jan 23, 2023
64b8011
revert
CarloToso Jan 23, 2023
e3ca008
remove get filename from content-disposition
CarloToso Jan 23, 2023
6758fb6
add resume error
CarloToso Jan 23, 2023
f74c92c
removed extra )
CarloToso Jan 23, 2023
0a6684e
OutFile -> QualifiedOutFile
CarloToso Jan 25, 2023
ce97583
Follow Suggestion
CarloToso Jan 25, 2023
78dca27
remove comments, use QualifiedOutFile
CarloToso Jan 25, 2023
2bee51b
cache QualifiedOutFile
CarloToso Jan 25, 2023
6c319ff
cache stuff; ShouldSaveToOutFile; fix
CarloToso Jan 26, 2023
eda8be1
remove forgotten line
CarloToso Jan 26, 2023
a58a77e
try removing _shouldSaveToOutFile
CarloToso Jan 27, 2023
38aa845
remove commented out strings
CarloToso Jan 27, 2023
f00ecb6
small adjustments
CarloToso Jan 27, 2023
d3bfcac
revert
CarloToso Feb 1, 2023
2de1ae3
test -Resume should fail if -OutFile folder
CarloToso Feb 1, 2023
b9186c4
test -OutFile folder Downloads the file and names it
CarloToso Feb 2, 2023
699aa76
Merge branch 'master' into WebCmdlets-Outfile-filename
CarloToso Feb 2, 2023
f1595db
small fixes
CarloToso Feb 2, 2023
a9b4ef1
fix test
CarloToso Feb 2, 2023
fa38d1f
Add suggestions
CarloToso Feb 2, 2023
26da022
merge
CarloToso Feb 10, 2023
d39e0f1
Merge branch 'master' into WebCmdlets-Outfile-filename
CarloToso Feb 10, 2023
2932d00
Merge branch 'master' into WebCmdlets-Outfile-filename
CarloToso Feb 24, 2023
39cfff2
Add -Verbose FileName
CarloToso Mar 14, 2023
ea7f69f
Add and use WebResponseHelper.GetOutFilePath
CarloToso Mar 14, 2023
01ee69a
Url -> Uri
CarloToso Mar 14, 2023
6a17610
Update test/powershell/Modules/Microsoft.PowerShell.Utility/WebCmdlet…
CarloToso Mar 20, 2023
43e82dc
Update test/powershell/Modules/Microsoft.PowerShell.Utility/WebCmdlet…
CarloToso Mar 20, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -140,8 +140,12 @@ internal override void ProcessResponse(HttpResponseMessage response)
}
}
else if (ShouldSaveToOutFile)
{
StreamHelper.SaveStreamToFile(baseResponseStream, QualifiedOutFile, this, response.Content.Headers.ContentLength.GetValueOrDefault(), _cancelToken.Token);
{
string outFilePath = WebResponseHelper.GetOutFilePath(response, _qualifiedOutFile);

WriteVerbose(string.Create(System.Globalization.CultureInfo.InvariantCulture, $"File Name: {Path.GetFileName(_qualifiedOutFile)}"));

StreamHelper.SaveStreamToFile(baseResponseStream, outFilePath, this, response.Content.Headers.ContentLength.GetValueOrDefault(), _cancelToken.Token);
}

if (!string.IsNullOrEmpty(StatusCodeVariable))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -474,6 +474,8 @@ public virtual string CustomMethod

internal string QualifiedOutFile => QualifyFilePath(OutFile);

internal string _qualifiedOutFile;

internal bool ShouldCheckHttpStatus => !SkipHttpErrorCheck;

/// <summary>
Expand Down Expand Up @@ -820,7 +822,7 @@ internal virtual void ValidateParameters()
}

// Output ??
if (PassThru && OutFile is null)
if (PassThru.IsPresent && OutFile is null)
{
ErrorRecord error = GetValidationError(WebCmdletStrings.OutFileMissing, "WebCmdletOutFileMissingException", nameof(PassThru));
ThrowTerminatingError(error);
Expand All @@ -832,6 +834,15 @@ internal virtual void ValidateParameters()
ErrorRecord error = GetValidationError(WebCmdletStrings.OutFileMissing, "WebCmdletOutFileMissingException", nameof(Resume));
ThrowTerminatingError(error);
}

_qualifiedOutFile = ShouldSaveToOutFile ? QualifiedOutFile : null;

// OutFile must not be a directory to use Resume.
if (Resume.IsPresent && Directory.Exists(_qualifiedOutFile))
{
ErrorRecord error = GetValidationError(WebCmdletStrings.ResumeNotFilePath, "WebCmdletResumeNotFilePathException", _qualifiedOutFile);
ThrowTerminatingError(error);
}
}

internal virtual void PrepareSession()
Expand Down Expand Up @@ -1083,6 +1094,7 @@ internal virtual HttpRequestMessage GetRequest(Uri uri)
if (Resume.IsPresent)
{
FileInfo fileInfo = new(QualifiedOutFile);

if (fileInfo.Exists)
{
request.Headers.Range = new RangeHeaderValue(fileInfo.Length, null);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,11 @@ internal override void ProcessResponse(HttpResponseMessage response)

if (ShouldSaveToOutFile)
{
StreamHelper.SaveStreamToFile(responseStream, QualifiedOutFile, this, response.Content.Headers.ContentLength.GetValueOrDefault(), _cancelToken.Token);
string outFilePath = WebResponseHelper.GetOutFilePath(response, _qualifiedOutFile);

WriteVerbose(string.Create(System.Globalization.CultureInfo.InvariantCulture, $"File Name: {Path.GetFileName(_qualifiedOutFile)}"));

StreamHelper.SaveStreamToFile(responseStream, outFilePath, this, response.Content.Headers.ContentLength.GetValueOrDefault(), _cancelToken.Token);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Net.Http;

namespace Microsoft.PowerShell.Commands
Expand Down Expand Up @@ -34,6 +35,14 @@ internal static Dictionary<string, IEnumerable<string>> GetHeadersDictionary(Htt
return headers;
}

internal static string GetOutFilePath(HttpResponseMessage response, string _qualifiedOutFile)
{
// Get file name from last segment of Uri
string lastUriSegment = System.Net.WebUtility.UrlDecode(response.RequestMessage.RequestUri.Segments[^1]);

return Directory.Exists(_qualifiedOutFile) ? Path.Join(_qualifiedOutFile, lastUriSegment) : _qualifiedOutFile;
}

internal static string GetProtocol(HttpResponseMessage response) => string.Create(CultureInfo.InvariantCulture, $"HTTP/{response.Version}");

internal static int GetStatusCode(HttpResponseMessage response) => (int)response.StatusCode;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,9 @@
</data>
<data name="ReadResponseProgressStatus" xml:space="preserve">
<value>Downloaded: {0} of {1}</value>
</data>
<data name="ResumeNotFilePath" xml:space="preserve">
<value>The Resume switch can only be used if OutFile targets a file but it resolves to a directory: {0}.</value>
</data>
<data name="SessionConflict" xml:space="preserve">
<value>The cmdlet cannot run because the following conflicting parameters are specified: Session and SessionVariable. Specify either Session or SessionVariable, then retry.</value>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -719,6 +719,19 @@ Describe "Invoke-WebRequest tests" -Tags "Feature", "RequireAdminOnWindows" {
$jsonContent.headers.Host | Should -Be $uri.Authority
}

It "Invoke-WebRequest -OutFile folder Downloads the file and names it" {
$uri = Get-WebListenerUrl -Test 'Get'
$content = Invoke-WebRequest -Uri $uri
$outFile = Join-Path $TestDrive $content.BaseResponse.RequestMessage.RequestUri.Segments[-1]

# ensure the file does not exist
Remove-Item -Force -ErrorAction Ignore -Path $outFile
Invoke-WebRequest -Uri $uri -OutFile $TestDrive

Test-Path $outFile | Should -Be $true
Get-Item $outFile | Select-Object -ExpandProperty Length | Should -Be $content.Content.Length
}

It "Invoke-WebRequest should fail if -OutFile is <Name>." -TestCases @(
@{ Name = "empty"; Value = [string]::Empty }
@{ Name = "null"; Value = $null }
Expand Down Expand Up @@ -1943,6 +1956,11 @@ Describe "Invoke-WebRequest tests" -Tags "Feature", "RequireAdminOnWindows" {
Should -Throw -ErrorId 'WebCmdletOutFileMissingException,Microsoft.PowerShell.Commands.InvokeWebRequestCommand'
}

It "Invoke-WebRequest -Resume should fail if -OutFile folder" {
{ Invoke-WebRequest -Resume -Uri $resumeUri -OutFile $TestDrive -ErrorAction Stop } |
Should -Throw -ErrorId 'WebCmdletResumeNotFilePathException,Microsoft.PowerShell.Commands.InvokeWebRequestCommand'
}

It "Invoke-WebRequest -Resume Downloads the whole file when the file does not exist" {
$response = Invoke-WebRequest -Uri $resumeUri -OutFile $outFile -Resume -PassThru

Expand Down Expand Up @@ -2477,6 +2495,19 @@ Describe "Invoke-RestMethod tests" -Tags "Feature", "RequireAdminOnWindows" {
$jsonContent.headers.Host | Should -Be $uri.Authority
}

It "Invoke-RestMethod -OutFile folder Downloads the file and names it" {
$uri = Get-WebListenerUrl -Test 'Get'
$content = Invoke-WebRequest -Uri $uri
$outFile = Join-Path $TestDrive $content.BaseResponse.RequestMessage.RequestUri.Segments[-1]

# ensure the file does not exist
Remove-Item -Force -ErrorAction Ignore -Path $outFile
Invoke-RestMethod -Uri $uri -OutFile $TestDrive

Test-Path $outFile | Should -Be $true
Get-Item $outFile | Select-Object -ExpandProperty Length | Should -Be $content.Content.Length
}

It "Invoke-RestMethod should fail if -OutFile is <Name>." -TestCases @(
@{ Name = "empty"; Value = [string]::Empty }
@{ Name = "null"; Value = $null }
Expand Down Expand Up @@ -3627,6 +3658,11 @@ Describe "Invoke-RestMethod tests" -Tags "Feature", "RequireAdminOnWindows" {
Should -Throw -ErrorId 'WebCmdletOutFileMissingException,Microsoft.PowerShell.Commands.InvokeRestMethodCommand'
}

It "Invoke-RestMethod -Resume should fail if -OutFile folder" {
{ Invoke-RestMethod -Resume -Uri $resumeUri -OutFile $TestDrive -ErrorAction Stop } |
Should -Throw -ErrorId 'WebCmdletResumeNotFilePathException,Microsoft.PowerShell.Commands.InvokeRestMethodCommand'
}

It "Invoke-RestMethod -Resume Downloads the whole file when the file does not exist" {
# ensure the file does not exist
Remove-Item -Force -ErrorAction 'SilentlyContinue' -Path $outFile
Expand Down