-
Notifications
You must be signed in to change notification settings - Fork 8.1k
Allow using a folder path in WebCmdlet's OutFile parameter #19007
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Allow using a folder path in WebCmdlet's OutFile parameter #19007
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't value. It is better to generate an error.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In this case there is no point in analyzing Content-Disposition at all :-)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Removed
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM. Please update the PR description.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- 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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- 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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@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).