From 075b351f10916f355e7ca9b9901dddb41d9308a6 Mon Sep 17 00:00:00 2001 From: CarloToso <105941898+CarloToso@users.noreply.github.com> Date: Tue, 2 Jul 2024 00:35:23 +0200 Subject: [PATCH] Fix WebCmdlets when `-Body` is specified but `ContentType` is not (#23952) --- .../Common/WebRequestPSCmdlet.Common.cs | 3 +- .../WebCmdlets.Tests.ps1 | 48 ++++++++++++++++++- 2 files changed, 48 insertions(+), 3 deletions(-) diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs index eb1b0dccc1f..7a7c112db93 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs +++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs @@ -1596,9 +1596,8 @@ internal void SetRequestContent(HttpRequestMessage request, string content) ArgumentNullException.ThrowIfNull(content); Encoding encoding = null; - string contentType = WebSession.ContentHeaders[HttpKnownHeaderNames.ContentType]; - if (contentType is not null) + if (WebSession.ContentHeaders.TryGetValue(HttpKnownHeaderNames.ContentType, out string contentType) && contentType is not null) { // If Content-Type contains the encoding format (as CharSet), use this encoding format // to encode the Body of the WebRequest sent to the server. Default Encoding format diff --git a/test/powershell/Modules/Microsoft.PowerShell.Utility/WebCmdlets.Tests.ps1 b/test/powershell/Modules/Microsoft.PowerShell.Utility/WebCmdlets.Tests.ps1 index 7fac6fad324..922483e21d0 100644 --- a/test/powershell/Modules/Microsoft.PowerShell.Utility/WebCmdlets.Tests.ps1 +++ b/test/powershell/Modules/Microsoft.PowerShell.Utility/WebCmdlets.Tests.ps1 @@ -692,8 +692,9 @@ Describe "Invoke-WebRequest tests" -Tags "Feature", "RequireAdminOnWindows" { $uri = Get-WebListenerUrl -Test $method $body = GetTestData -contentType $contentType $command = "Invoke-WebRequest -Uri $uri -Body '$body' -Method $method -ContentType $contentType" + $commandNoContentType = "Invoke-WebRequest -Uri $uri -Body '$body' -Method $method" - It "Invoke-WebRequest -Uri $uri -Method $method -ContentType $contentType -Body [body data]" { + It "Invoke-WebRequest -Uri $uri -Method $method -ContentType $contentType -Body [body data]" { $result = ExecuteWebCommand -command $command ValidateResponse -response $result @@ -705,6 +706,29 @@ Describe "Invoke-WebRequest tests" -Tags "Feature", "RequireAdminOnWindows" { # Validate that the response Content.data field is the same as what we sent. $jsonContent.data | Should -Be $body } + + It "Invoke-WebRequest -Uri $uri -Method $method -Body [body data]" { + + $result = ExecuteWebCommand -command $commandNoContentType + ValidateResponse -response $result + + # Validate response content + $jsonContent = $result.Output.Content | ConvertFrom-Json + $jsonContent.url | Should -Match $uri + if ($method -eq "POST") + { + $jsonContent.headers.'Content-Type' | Should -Match "application/x-www-form-urlencoded" + # Validate that the response Content.form field is the same as what we sent. + [string]$jsonContent.form | Should -Be ([string][PSCustomObject]@{$body.Split("=")[0] = [System.Object[]]}) + $jsonContent.data | Should -BeNullOrEmpty + } + else + { + # Validate that the response Content.data field is the same as what we sent. + $jsonContent.data | Should -Be $body + } + + } } } @@ -2752,6 +2776,7 @@ Describe "Invoke-RestMethod tests" -Tags "Feature", "RequireAdminOnWindows" { $uri = Get-WebListenerUrl -Test $method $body = GetTestData -contentType $contentType $command = "Invoke-RestMethod -Uri $uri -Body '$body' -Method $method -ContentType $contentType" + $commandNoContentType = "Invoke-RestMethod -Uri $uri -Body '$body' -Method $method" It "Invoke-RestMethod -Uri $uri -Method $method -ContentType $contentType -Body [body data]" { @@ -2764,6 +2789,27 @@ Describe "Invoke-RestMethod tests" -Tags "Feature", "RequireAdminOnWindows" { # Validate that the response Content.data field is the same as what we sent. $result.Output.data | Should -Be $body } + + It "Invoke-RestMethod -Uri $uri -Method $method -Body [body data]" { + + $result = ExecuteWebCommand -command $commandNoContentType + + # Validate response + $result.Output.url | Should -Match $uri + + if ($method -eq "POST") + { + $result.Output.headers.'Content-Type' | Should -Match "application/x-www-form-urlencoded" + # Validate that the response Content.form field is the same as what we sent. + [string]$result.Output.form | Should -Be ([string][PSCustomObject]@{$body.Split("=")[0] = [System.Object[]]}) + $result.Output.data | Should -BeNullOrEmpty + } + else + { + # Validate that the response Content.data field is the same as what we sent. + $result.Output.data | Should -Be $body + } + } } }