Allow using a folder path in WebCmdlet's OutFile parameter#19007
Allow using a folder path in WebCmdlet's OutFile parameter#19007iSazonov merged 30 commits intoPowerShell:masterfrom
Conversation
| else | ||
| { | ||
| // Get file name from last segment of Uri | ||
| OutFile = Path.Combine(OutFile, System.Net.WebUtility.UrlDecode(response.RequestMessage.RequestUri.Segments[^1])); |
There was a problem hiding this comment.
I don't value. It is better to generate an error.
There was a problem hiding this comment.
I think you're wrong, I have tested some websites and they rarely (never) use the Content-Disposition header. So it would always generate an error.
Tested downloads: Firefox, Chrome, 7zip, Adobe Reader
There was a problem hiding this comment.
In this case there is no point in analyzing Content-Disposition at all :-)
There was a problem hiding this comment.
LGTM. Please update the PR description.
There was a problem hiding this comment.
Done. What should we do about the problem with -Resume ?
I'll add a new error
Added error when Resume is used and outfile doesn't point to a file
There was a problem hiding this comment.
Content-Disposition may not be used often (I can't speak to that), but it is definitely used, including on GitHub:
E.g., in an archive download for a given project, such as https://github.com/mklement0/fileicon/archive/stable.zip, where using the last URL segment wouldn't even tell you the name of the product, the Content-Disposition field provides a helpful file name:
# -> 'attachment; filename=fileicon-stable.zip'
(Invoke-WebRequest -Method Head https://github.com/mklement0/fileicon/archive/stable.zip).Headers['Content-Disposition']Both curl and wget support Content-Disposition, albeit on an opt-in basis (-J and --content-disposition)
There was a problem hiding this comment.
@mklement0 Please describe the desired behaviour and I will implement it, I removed the check for Content-Disposition only because @iSazonov requested it
There was a problem hiding this comment.
Thanks, @CarloToso.
My suggestion is as follows - though I wonder if it requires a wider discussion:
I suggest also making the feature opt-in, given the following warning from man curl with respect to its opt-in (-J / --remote-header-name):
WARNING: Exercise judicious use of this option, especially on
Windows. A rogue server could send you the name of a DLL or
other file that could be loaded automatically by Windows or some
third party software.
That requires a new switch, say -UseSuggestedFileName, which would have to report an error if the -OutFile argument targets a file.
There's also a discoverability problem - also with the use-last-URI-segment approach, given that redirections may be involved, and that the new default behavior uses the redirected-to URI's last segment:
- How does the user learn what file name was ultimately used (short of examining the target directory for the most recently added file)?
- At the very least,
-Verboseshould include this information. -PassThrushould use an ETS instance member to decorate the passed-throughMicrosoft.PowerShell.Commands.BasicHtmlWebResponseObjectinstance with a.FullNameproperty that reflects the output file's full path.
- At the very least,
As for how to parse Content-Disposition and fallback behavior:
-
Based on the previously linked description, the C# equivalent of the following is probably good enough in practice, though the recommendation is to give precedence to
filename*(sic) entries:<value-of-Content-Disposition-field(s)> -replace '^.*\bfilename\*?="?([^;"]+)?.*', '$1'- If there's no
Content-Dispositionfield or if the file-name extraction fails, fall back to the last-URI-segment approach
There was a problem hiding this comment.
Maybe you could move this discussion to issue #11671
|
The test error looks like a random failure unrelated to this PR |
...erShell.Commands.Utility/commands/utility/WebCmdlet/Common/InvokeRestMethodCommand.Common.cs
Outdated
Show resolved
Hide resolved
...erShell.Commands.Utility/commands/utility/WebCmdlet/Common/InvokeRestMethodCommand.Common.cs
Outdated
Show resolved
Hide resolved
...erShell.Commands.Utility/commands/utility/WebCmdlet/Common/InvokeRestMethodCommand.Common.cs
Outdated
Show resolved
Hide resolved
...t.PowerShell.Commands.Utility/commands/utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs
Outdated
Show resolved
Hide resolved
...Shell.Commands.Utility/commands/utility/WebCmdlet/CoreCLR/InvokeWebRequestCommand.CoreClr.cs
Outdated
Show resolved
Hide resolved
| } | ||
|
|
||
| // OutFile must not be a directory to use Resume. | ||
| if (Resume.IsPresent && Directory.Exists(QualifiedOutFile)) |
There was a problem hiding this comment.
- If we resolve the path we should cache it here and use later.
- It seems it is not correct check since we could get the file name from URL.
There was a problem hiding this comment.
- I agree with you, I'll do it later
- I think it's correct, this is the logic:
- if -Outfile points to a file, old logic you can use resume
- if -Outfile points to a folder (Directory.Exists(QualifiedOutFile)) you can't use the resume switch (throws an error) and the filename is taken later from the url
There was a problem hiding this comment.
@iSazonov I think I need a hand with caching the resolved path
This comment was marked as duplicate.
This comment was marked as duplicate.
Sorry, something went wrong.
...t.PowerShell.Commands.Utility/commands/utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs
Outdated
Show resolved
Hide resolved
|
@CarloToso We need new tests for null, empty, folder. |
|
This pull request has been automatically marked as Review Needed because it has been there has not been any activity for 7 days. |
#firefox download
curl "https://download.mozilla.org/?product=firefox-stub&os=win&lang=it" -L -O
#--> _product=firefox-stub&os=win&lang=it
Invoke-WebRequest "https://download.mozilla.org/?product=firefox-stub&os=win&lang=it" -OutFile .\
#--> Firefox Installer.exe (BETTER)
#github download
curl "https://github.com/mklement0/ttab/archive/stable.zip" -L -O
#--> stable.zip (BETTER)
Invoke-WebRequest "https://github.com/mklement0/ttab/archive/stable.zip" -OutFile .\
#--> stable@mklement0 It seems to me that both approaches have some issues... What should we do? |
|
@CarloToso, yes, both approaches are defensible.
The If we stick with what you have now, we should offer a way to discover the filename via (a) The latter will also become important if and when we implement (Curiously |
|
@CarloToso, realistically speaking, given that my plea to decide on the pass-through issue before merging this PR are falling on deaf ears: In the absence of a feature that allows discovery of the output filename via Also - I'm not sure how you're handling this - note that PS> curl -LO http://example.org
curl: Remote file name has no length!
curl: (23) Failed writing received data to disk/applicationThis can notably also happen if the last URI segment happens to be invalid as a filename. |
|
@mklement0 I'm slowly working on addressing your suggestions about
One or Two other PR:
I don't think I should add more commits to this PR |
|
Thank you, @CarloToso, that makes sense, except I'm unclear on what you mean by:
|
|
|
Thanks for clarifying , @CarloToso. Just food for thought, we can defer further discussion to your future PRs: Re 1: How would you decide in cases where both methods yield a viable filename? Re 2: Personally, I think warning in the documentation is sufficient (which is what |
|
@iSazonov @SteveL-MSFT Can we merge this? So I con continue working on the name from Content-Disposition feature |
test/powershell/Modules/Microsoft.PowerShell.Utility/WebCmdlets.Tests.ps1
Outdated
Show resolved
Hide resolved
test/powershell/Modules/Microsoft.PowerShell.Utility/WebCmdlets.Tests.ps1
Outdated
Show resolved
Hide resolved
…s.Tests.ps1 Co-authored-by: Steve Lee <slee@microsoft.com>
…s.Tests.ps1 Co-authored-by: Steve Lee <slee@microsoft.com>
|
This PR has Quantification details
Why proper sizing of changes matters
Optimal pull request sizes drive a better predictable PR flow as they strike a
What can I do to optimize my changes
How to interpret the change counts in git diff output
Was this comment helpful? 👍 :ok_hand: :thumbsdown: (Email) |
|
🎉 Handy links: |
PR Summary
In Invoke-WebRequest and Invoke-RestMethod
-Outfileonly works if you specify a file pathAfter this PR:
- the path to an existing file (which is then quietly replaced, as before)
- the path to an existing directory followed by the name of a new file to be created
@mklement0
The filename is taken from the last segment of the Uri
Problems:
-Resumeand I'm not sure it canPR Context
#11671
PR Checklist
.h,.cpp,.cs,.ps1and.psm1files have the correct copyright headerWIP:or[ WIP ]to the beginning of the title (theWIPbot will keep its status check atPendingwhile the prefix is present) and remove the prefix when the PR is ready.(which runs in a different PS Host).