FazBrowse GitHub Viewer | Trending |
URL:
| Home
Tools: [Download Repo ZIP]   [Original HTTPS Page]

Allow a blank/empty ContentType to be passed to Invoke-WebRequest for compatibility with PS6 and earlier by spongemike2 · Pull Request #11421 · PowerShell/PowerShell · GitHub

Allow a blank/empty ContentType to be passed to Invoke-WebRequest for compatibility with PS6 and earlier - #11421

Merged
Dongbo Wang (daxian-dbw) merged 4 commits into
PowerShell:masterfrom
spongemike2:spongemike2/Fix11396
Jan 6, 2020
Merged

Allow a blank/empty ContentType to be passed to Invoke-WebRequest for compatibility with PS6 and earlier#11421
Dongbo Wang (daxian-dbw) merged 4 commits into
PowerShell:masterfrom
spongemike2:spongemike2/Fix11396

Conversation

spongemike2 commented Dec 21, 2019
edited by iSazonov
Loading

Copy link
Copy Markdown
Contributor

PR Summary

Regarding Invoke-WebRequest:

A change was made to PowerShell Core with commit 2285ece613 that changes the way web request headers are handled when the web request has no body. Previously, they would be ignored. Now, they are processed anyway, including the ContentType header, which makes no sense when there's no body. Now, the headers are processed anyway, and if there's a ContentType header with an empty string value, it will fail.

When a customer tries to pass in a blank (i.e., $null) ContentType to a function that takes a string because they have no body, it gets treated as an empty string, not $null.

This works fin in Windows PowerShell (PS5 and earlier) and PowerShell Core 6, because their code bases don't have commit 2285ece613.

When it fails, they get a message saying that they can avoid this by passing -SkipHeaderValidation, but this flag isn't available in Windows PowerShell, and using it would require a crude hard-coded version check to see if you're on Windows PowerShell or PowerShell Core.

This change merely skips adding headers to the request if the header value is nothing (null or whitespace).

Question: Should we only do this skip for the ContentType header?

Fix #11396

PR Context

Without this, PS scripts that run fine in Windows PowerShell and PowerShell Core 6 break.

PR Checklist

Michael J. Lyons and others added 2 commits December 21, 2019 09:15
…no body.

Regarding `Invoke-WebRequest`:

A change was made to PowerShell Core with commit `2285ece613` that changes the way web request headers are handled when the web request has no body. Previously, they would be ignored. Now, they are processed anyway, including the `ContentType` header, which makes no sense when there's no body. Now, the headers are processed anyway, and if there's a `ContentType` header with an empty string value, it will fail.

When a customer tries to pass in a blank (i.e., `$null`) `ContentType` to a function that takes a `string` because they have no body, it gets treated as an empty string, not `$null`.

This works fin in Windows PowerShell (PS5 and earlier) and PowerShell Core 6, because their code bases don't have commit `2285ece613`.

When it fails, they get a message saying that they can avoid this by passing `-SkipHeaderValidation`, but this flag isn't available in Windows PowerShell, and using it would require a crude hard-coded version check to see if you're on Windows PowerShell or PowerShell Core.

This change merely skips adding headers to the request if the header value is nothing (null or whitespace).

**Question**: Should we only do this *skip* for the `ContentType` header?

PowerShell#11396
Fix for issue 11396 regarding blank ContentType for web request with no body

Microsoft Contribution License Agreements (msftclas) commented Dec 21, 2019
edited
Loading

Copy link
Copy Markdown


All CLA requirements met.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

Collecting some discussions about empty HTTP headers from elsewhere:

From the Fetch issue referenced by Steve:

I'm sorry but can someone just say Yes or No whether empty header values are legal HTTP?
Are they allowed by HTTP? Yes. Are they allowed / defined to have meaning for an individual header field? It depends on the field's definition. That said, it's not good practice to do it.

And dotnet seems to currently enforce the "it's not a good idea to do it" opinion (it rejects empty headers).

Suppose at some point, the dotnet Issue was addressed, and they decided to allow empty headers. Would we (PowerShell) then want to expose that ability in PS (to have an empty header value)? We could remove this null/empty check, and then the dotnet API would allow it… and it would be sent to the server. Would the HTTP server allow it? Dunno. So that could be a breaking change, too.

Or we could just say "no, you just can't send empty headers with PS". Given that that is already the case (you can't send an empty HTTP header, else dotnet throws (although I don't know if that behavior has always been that way with dotnet)), and nobody has complained (actually I have no idea if anyone has complained, but it hasn't become a blocking issue that has been addressed--I'm relying on actual PS people to validate what I'm saying here), it seems like a reasonable position to stick to.

Given all that, I think this change looks good.

Copy link
Copy Markdown
Contributor Author

One option to make it even more future-proof would be to add another condition to this check, and only ignore blank headers if the body is also empty or non-existent. Then, it will actually behave closer to the PS6 version of the code, which doesn't allow any custom headers if there's no body.

Copy link
Copy Markdown
Collaborator

spongemike2 I may lack some context or experience in this area, but from memory there are some perfectly valid requests that can be made with headers and no body, aren't there?

Copy link
Copy Markdown
Contributor Author

Rain Sallow (/u/ta11ow) (@vexx32), I am not an expert in this area, but if I had to guess, I would say yes, which is presumably why the change was made that broke this. However, headers that have no value? I think that's unlikely to be useful. Rather than specifying a header with a blank value, which dotnetcore doesn't allow, one could get effectively the same information conveyed by omitting the header altogether. Which is why I think (even though I'm not 100% sure) that my change should be safe.

if (!string.IsNullOrWhiteSpace(entry.Value))
{
try
if (SkipHeaderValidation)

Ilya (iSazonov) Dec 23, 2019
edited
Loading

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

If our intention is to follow Core (that is to send headers with empty value) the check should be here: Update.

Also please add a test.

Steve Lee (SteveL-MSFT) left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

Can we add a test? I believe there is an existing test case to validate headers are passed, so just augment it with an empty header.

Steve Lee (SteveL-MSFT) added this to the GA-consider milestone Dec 23, 2019

Copy link
Copy Markdown
Contributor Author

Test added. Verified that the new test fails prior to this change, and succeeds with it.

Copy link
Copy Markdown
Collaborator

spongemike2 could you edit the PR title summary to something a bit more descriptive? Thanks! 😊

spongemike2 changed the title Spongemike2/fix11396 Allow a blank/empty ContentType to be passed to Invoke-WebRequest for compatibility with PS6 and earlier Dec 28, 2019

Copy link
Copy Markdown
Contributor Author

spongemike2 could you edit the PR title summary to something a bit more descriptive? Thanks!

Done.

Copy link
Copy Markdown
Contributor Author

Anything else needed?

Ilya (iSazonov) added CL-General Indicates that a PR should be marked as a general cmdlet change in the Change Log and removed Area-Cmdlets-Utility labels Jan 1, 2020
Dongbo Wang (daxian-dbw) merged commit 1376d31 into PowerShell:master Jan 6, 2020

Copy link
Copy Markdown
Collaborator

I think It is a breaking change and we should add CL-BreakingChange

spongemike2 deleted the spongemike2/Fix11396 branch January 6, 2020 20:22

Copy link
Copy Markdown
Member

It looks to me a regression we made in 7.0 time frame and we are fixing it before 7.0 GA. It's a behavior changes only comparing with 7.0 previews, so I think it's not a breaking change. But do let me know if I'm missing something.

Copy link
Copy Markdown
Contributor Author

It looks to me a regression we made in 7.0 time frame and we are fixing it before 7.0 GA. It's a behavior changes only comparing with 7.0 previews, so I think it's not a breaking change. But do let me know if I'm missing something.

I agree. It would have been an unknown breaking change if it wasn't fixed before GA, but we caught it and fixed it.

Copy link
Copy Markdown
Collaborator

I agree if this will be in GA.

Copy link
Copy Markdown

🎉v7.0.0-rc.2 has been released which incorporates this pull request.:tada:

Handy links:

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

Labels

CL-General Indicates that a PR should be marked as a general cmdlet change in the Change Log

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Breaking change: Invoke-WebRequest -ContentType with empty string now fails

8 participants


Back | FazBrowse Home | New Git URL