diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/Common/InvokeRestMethodCommand.Common.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/Common/InvokeRestMethodCommand.Common.cs index 0d1506c6f88..0614147443a 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/Common/InvokeRestMethodCommand.Common.cs +++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/Common/InvokeRestMethodCommand.Common.cs @@ -16,13 +16,25 @@ public partial class InvokeRestMethodCommand /// /// gets or sets the parameter Method /// - [Parameter] + [Parameter(ParameterSetName = "StandardMethod")] public override WebRequestMethod Method { get { return base.Method; } set { base.Method = value; } } + /// + /// gets or sets the parameter CustomMethod + /// + [Parameter(ParameterSetName = "CustomMethod")] + [Alias("CM")] + [ValidateNotNullOrEmpty] + public override string CustomMethod + { + get { return base.CustomMethod; } + set { base.CustomMethod = value; } + } + #endregion Parameters #region Helper Methods 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 2eff4b1cb1f..560aa57a1e5 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 @@ -147,7 +147,7 @@ public virtual int MaximumRedirection /// /// gets or sets the Method property /// - [Parameter] + [Parameter(ParameterSetName = "StandardMethod")] public virtual WebRequestMethod Method { get { return _method; } @@ -155,6 +155,19 @@ public virtual WebRequestMethod Method } private WebRequestMethod _method = WebRequestMethod.Default; + /// + /// gets or sets the CustomMethod property + /// + [Parameter(ParameterSetName = "CustomMethod")] + [Alias("CM")] + [ValidateNotNullOrEmpty] + public virtual string CustomMethod + { + get { return _customMethod; } + set { _customMethod = value; } + } + private string _customMethod; + #endregion #region Proxy @@ -547,7 +560,8 @@ private Uri PrepareUri(Uri uri) IDictionary bodyAsDictionary; LanguagePrimitives.TryConvertTo(Body, out bodyAsDictionary); if ((null != bodyAsDictionary) - && (Method == WebRequestMethod.Default || Method == WebRequestMethod.Get)) + && ((IsStandardMethodSet() && (Method == WebRequestMethod.Default || Method == WebRequestMethod.Get)) + || (IsCustomMethodSet() && CustomMethod.ToUpperInvariant() == "GET"))) { UriBuilder uriBuilder = new UriBuilder(uri); if (uriBuilder.Query != null && uriBuilder.Query.Length > 1) @@ -626,6 +640,16 @@ private ErrorRecord GetValidationError(string msg, string errorId, params object return (error); } + private bool IsStandardMethodSet() + { + return (ParameterSetName == "StandardMethod"); + } + + private bool IsCustomMethodSet() + { + return (ParameterSetName == "CustomMethod"); + } + #endregion Helper Methods } } diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/CoreCLR/InvokeRestMethodCommand.CoreClr.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/CoreCLR/InvokeRestMethodCommand.CoreClr.cs index efd3762cc58..7d0d6c2d3bf 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/CoreCLR/InvokeRestMethodCommand.CoreClr.cs +++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/CoreCLR/InvokeRestMethodCommand.CoreClr.cs @@ -18,7 +18,7 @@ namespace Microsoft.PowerShell.Commands /// Intended to work against the wide spectrum of "RESTful" web services /// currently deployed across the web. /// - [Cmdlet(VerbsLifecycle.Invoke, "RestMethod", HelpUri = "https://go.microsoft.com/fwlink/?LinkID=217034")] + [Cmdlet(VerbsLifecycle.Invoke, "RestMethod", HelpUri = "https://go.microsoft.com/fwlink/?LinkID=217034", DefaultParameterSetName = "StandardMethod")] public partial class InvokeRestMethodCommand : WebRequestPSCmdlet { #region Virtual Method Overrides diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/CoreCLR/InvokeWebRequestCommand.CoreClr.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/CoreCLR/InvokeWebRequestCommand.CoreClr.cs index 0506ac15001..3dbfbeaae80 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/CoreCLR/InvokeWebRequestCommand.CoreClr.cs +++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/CoreCLR/InvokeWebRequestCommand.CoreClr.cs @@ -15,7 +15,7 @@ namespace Microsoft.PowerShell.Commands /// The Invoke-RestMethod command /// This command makes an HTTP or HTTPS request to a web server and returns the results. /// - [Cmdlet(VerbsLifecycle.Invoke, "WebRequest", HelpUri = "https://go.microsoft.com/fwlink/?LinkID=217035")] + [Cmdlet(VerbsLifecycle.Invoke, "WebRequest", HelpUri = "https://go.microsoft.com/fwlink/?LinkID=217035", DefaultParameterSetName = "StandardMethod")] public class InvokeWebRequestCommand : WebRequestPSCmdlet { #region Virtual Method Overrides diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/CoreCLR/WebRequestPSCmdlet.CoreClr.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/CoreCLR/WebRequestPSCmdlet.CoreClr.cs index ca38c1ed3e6..a1069f6c4db 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/CoreCLR/WebRequestPSCmdlet.CoreClr.cs +++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/CoreCLR/WebRequestPSCmdlet.CoreClr.cs @@ -154,7 +154,22 @@ internal virtual HttpClient GetHttpClient() internal virtual HttpRequestMessage GetRequest(Uri uri) { Uri requestUri = PrepareUri(uri); - HttpMethod httpMethod = GetHttpMethod(Method); + HttpMethod httpMethod = null; + + switch (ParameterSetName) + { + case "StandardMethod": + // set the method if the parameter was provided + httpMethod = GetHttpMethod(Method); + break; + case "CustomMethod": + if (!string.IsNullOrEmpty(CustomMethod)) + { + // set the method if the parameter was provided + httpMethod = new HttpMethod(CustomMethod.ToString().ToUpperInvariant()); + } + break; + } // create the base WebRequest object var request = new HttpRequestMessage(httpMethod, requestUri); @@ -229,7 +244,7 @@ internal virtual void FillRequestStream(HttpRequestMessage request) //request } // ContentType == null - else if (Method == WebRequestMethod.Post) + else if (Method == WebRequestMethod.Post || (IsCustomMethodSet() && CustomMethod.ToUpperInvariant() == "POST")) { // Win8:545310 Invoke-WebRequest does not properly set MIME type for POST string contentType = null; diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/FullClr/InvokeRestMethodCommand.FullClr.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/FullClr/InvokeRestMethodCommand.FullClr.cs index a723c3684c6..c07f151ab61 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/FullClr/InvokeRestMethodCommand.FullClr.cs +++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/FullClr/InvokeRestMethodCommand.FullClr.cs @@ -19,7 +19,7 @@ namespace Microsoft.PowerShell.Commands /// Intended to work against the wide spectrum of "RESTful" web services /// currently deployed across the web. /// - [Cmdlet(VerbsLifecycle.Invoke, "RestMethod", HelpUri = "https://go.microsoft.com/fwlink/?LinkID=217034")] + [Cmdlet(VerbsLifecycle.Invoke, "RestMethod", HelpUri = "https://go.microsoft.com/fwlink/?LinkID=217034", DefaultParameterSetName = "StandardMethod")] public partial class InvokeRestMethodCommand : WebRequestPSCmdlet { #region Virtual Method Overrides diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/FullClr/InvokeWebRequestCommand.FullClr.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/FullClr/InvokeWebRequestCommand.FullClr.cs index ed930f33116..cb5a5710783 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/FullClr/InvokeWebRequestCommand.FullClr.cs +++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/FullClr/InvokeWebRequestCommand.FullClr.cs @@ -13,7 +13,7 @@ namespace Microsoft.PowerShell.Commands /// The Invoke-RestMethod command /// This command makes an HTTP or HTTPS request to a web server and returns the results. /// - [Cmdlet(VerbsLifecycle.Invoke, "WebRequest", HelpUri = "https://go.microsoft.com/fwlink/?LinkID=217035")] + [Cmdlet(VerbsLifecycle.Invoke, "WebRequest", HelpUri = "https://go.microsoft.com/fwlink/?LinkID=217035", DefaultParameterSetName = "StandardMethod")] public class InvokeWebRequestCommand : WebRequestPSCmdlet { #region Virtual Method Overrides diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/FullClr/WebRequestPSCmdlet.FullClr.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/FullClr/WebRequestPSCmdlet.FullClr.cs index 06ed7591218..8922b9dd40a 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/FullClr/WebRequestPSCmdlet.FullClr.cs +++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/FullClr/WebRequestPSCmdlet.FullClr.cs @@ -84,10 +84,19 @@ internal virtual WebRequest GetRequest(Uri uri) request.Proxy = WebSession.Proxy; } - // set the method if the parameter was provided - if (WebRequestMethod.Default != Method) + switch (ParameterSetName) { - request.Method = Method.ToString().ToUpperInvariant(); + case "StandardMethod": + if (WebRequestMethod.Default != Method) + { + // set the method if the parameter was provided + request.Method = Method.ToString().ToUpperInvariant(); + } + break; + case "CustomMethod": + // set the method if the parameter was provided + request.Method = CustomMethod.ToUpperInvariant(); + break; } // pull in http specific properties @@ -248,7 +257,8 @@ internal virtual void FillRequestStream(WebRequest request) request.ContentType = ContentType; } // ContentType == null - else if (Method == WebRequestMethod.Post) + else if ((IsStandardMethodSet() && Method == WebRequestMethod.Post) + || (IsCustomMethodSet() && CustomMethod.ToUpperInvariant() == "POST")) { // Win8:545310 Invoke-WebRequest does not properly set MIME type for POST if (String.IsNullOrEmpty(request.ContentType)) diff --git a/test/powershell/Modules/Microsoft.PowerShell.Utility/WebCmdlets.Tests.ps1 b/test/powershell/Modules/Microsoft.PowerShell.Utility/WebCmdlets.Tests.ps1 index 66d618ddc61..07e65489f60 100644 --- a/test/powershell/Modules/Microsoft.PowerShell.Utility/WebCmdlets.Tests.ps1 +++ b/test/powershell/Modules/Microsoft.PowerShell.Utility/WebCmdlets.Tests.ps1 @@ -400,6 +400,35 @@ Describe "Invoke-WebRequest tests" -Tags "Feature" { $result.Error | Should BeNullOrEmpty } + It "Validate Invoke-WebRequest StandardMethod and CustomMethod parameter sets" { + + #Validate that parameter sets are functioning correctly + $errorId = "AmbiguousParameterSet,Microsoft.PowerShell.Commands.InvokeWebRequestCommand" + { Invoke-WebRequest -Uri 'http://http.lee.io/method' -Method GET -CustomMethod TEST } | ShouldBeErrorId $errorId + } + + It "Validate Invoke-WebRequest CustomMethod method is used" { + + $command = "Invoke-WebRequest -Uri 'http://http.lee.io/method' -CustomMethod TEST" + $result = ExecuteWebCommand -command $command + $result.Error | Should BeNullOrEmpty + ($result.Output.Content | ConvertFrom-Json).output.method | Should Be "TEST" + } + + It "Validate Invoke-WebRequest default ContentType for CustomMethod POST" { + + $command = "Invoke-WebRequest -Uri 'http://httpbin.org/post' -CustomMethod POST -Body 'testparam=testvalue'" + $result = ExecuteWebCommand -command $command + ($result.Output.Content | ConvertFrom-Json).form.testparam | Should Be "testvalue" + } + + It "Validate Invoke-WebRequest body is converted to query params for CustomMethod GET" { + + $command = "Invoke-WebRequest -Uri 'http://httpbin.org/get' -CustomMethod GET -Body @{'testparam'='testvalue'}" + $result = ExecuteWebCommand -command $command + ($result.Output.Content | ConvertFrom-Json).args.testparam | Should Be "testvalue" + } + It "Validate Invoke-WebRequest returns HTTP errors in exception" { $command = "Invoke-WebRequest -Uri http://httpbin.org/status/418" @@ -649,6 +678,34 @@ Describe "Invoke-RestMethod tests" -Tags "Feature" { $result.Error | Should BeNullOrEmpty } + It "Validate Invoke-RestMethod StandardMethod and CustomMethod parameter sets" { + + $errorId = "AmbiguousParameterSet,Microsoft.PowerShell.Commands.InvokeRestMethodCommand" + { Invoke-RestMethod -Uri 'http://http.lee.io/method' -Method GET -CustomMethod TEST } | ShouldBeErrorId $errorId + } + + It "Validate CustomMethod method is used" { + + $command = "Invoke-RestMethod -Uri 'http://http.lee.io/method' -CustomMethod TEST" + $result = ExecuteWebCommand -command $command + $result.Error | Should BeNullOrEmpty + $result.Output.output.method | Should Be "TEST" + } + + It "Validate Invoke-RestMethod default ContentType for CustomMethod POST" { + + $command = "Invoke-RestMethod -Uri 'http://httpbin.org/post' -CustomMethod POST -Body 'testparam=testvalue'" + $result = ExecuteWebCommand -command $command + $result.Output.form.testparam | Should Be "testvalue" + } + + It "Validate Invoke-RestMethod body is converted to query params for CustomMethod GET" { + + $command = "Invoke-RestMethod -Uri 'http://httpbin.org/get' -CustomMethod GET -Body @{'testparam'='testvalue'}" + $result = ExecuteWebCommand -command $command + $result.Output.args.testparam | Should Be "testvalue" + } + It "Invoke-RestMethod supports request that returns plain text response." { $command = "Invoke-RestMethod -Uri 'http://httpbin.org/encoding/utf8'"