You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Feature Request: create switch to persist HTTP method when following a redirect for Invoke-RestMethod or Invoke-WebRequest #14531
This request is for a parameter which persists the original HTTP method used in Invoke-RestMethod and Invoke-WebRequest upon redirect. Currently, when the client receives a redirect from the web server, the HTTP client used by said cmdlets reissues the HTTP call but persistently uses HTTP GET, regardless what method was originally used.
This is typical to how browsers operate, and it's also how cURL operates out of the box, too.
Here is an example:
Invoke-RestMethod-Uri "http://test.acook.io"-Method POST
The web server will redirect the request to https:// and process index.php which just prints out $_SERVER['REQUEST_METHOD'] (link)
A parameter that instructions the cmdlets to persist the originally intended HTTP method through redirects would be useful in scenarios where the web server issues a 30x redirect of http:// to https://.
cURL offers this parameter idea, but for just POST methods, via --post301, --post302 and --post303.
Ideally, this request is to have a switch which persists all types of HTTP methods through redirects via said cmdlets.
changed the title [-]Feature Request: create switch to not convert POST requests to GET when following a redirect for Invoke-RestMethod or Invoke-WebRequest[/-][+]Feature Request: create switch to persist HTTP method when following a redirect for Invoke-RestMethod or Invoke-WebRequest[/+]on Jan 2, 2021
This is typical to how browsers operate, and it's also how cURL operates out of the box, too.
If it is typical behavior why do we need new parameter? I'd expect you request to change the cmdlet behavior to make it standard.
Could you please make more investigation? What do any standards say about this? What is behavior of others popular clients (curl, wget, IE, ...)? Please add links (to docs) if possible.
If it is typical behavior why do we need new parameter? I'd expect you request to change the cmdlet behavior to make it standard.
If you sent a POST request to a REST API, using PowerShell, and you forgot to explicitly define https:// in the URL, would you like the HTTP method to remain as POST and not get converted to GET? The answer would likely be yes, and I think that's a valid use case. It's interesting to note that cURL offers this parameter idea, but for just POST methods, via --post301, --post302 and --post303.
As far as I'm aware this is a feature request but if I've done it wrong please tell me.
Could you please make more investigation? What do any standards say about this? What is behavior of others popular clients (curl, wget, IE, ...)? Please add links (to docs) if possible.
I believe section 6.4 will helps us here. This quote from a note at the start of that section is interesting:
Note: In HTTP/1.0, the status codes 301 (Moved Permanently) and
302 (Found) were defined for the first type of redirect
([RFC1945], Section 9.3). Early user agents split on whether the
method applied to the redirect target would be the same as the
original request or would be rewritten as GET. Although HTTP
originally defined the former semantics for 301 and 302 (to match
its original implementation at CERN), and defined 303 (See Other)
to match the latter semantics, prevailing practice gradually
converged on the latter semantics for 301 and 302 as well. The
first revision of HTTP/1.1 added 307 (Temporary Redirect) to
indicate the former semantics without being impacted by divergent
practice. Over 10 years later, most user agents still do method
rewriting for 301 and 302; therefore, this specification makes
that behavior conformant when the original request is POST.
The cmdlet is already following "the latter semantics" (rewrite as GET). This feature request is for a parameter which forces Invoke-RestMethod and Invoke-WebRequest to follow "the former semantics" (persist as original method).
Ah, sorry, I thought we still follow old behavior. In the case we need more feedback. Do know important scenarios where the feature is critical? Specially Azure scenarios?
It's absolutely not critical, it's definitely a quality of life type thing. Most people would simply change the -Uri parameter to be https:// and get on with their lives.
However, where this feature request will be most helpful is for module authors. For example, for modules which are written for a web service's REST API. Perhaps a parameter for each function in said module allowed the user to specify a URL to their target host/service and they passed example.com to said parameter. By default, most HTTP agents will send out the request over tcp/80 and the majority of web servers today will respond with a redirect to https://example.com. As it stands today, if the function of the module was to HTTP POST, that would get rewritten as HTTP GET and potentially produce erroneous results.
This puts module authors in a bit of a dilemma of sorts. Questions like "Do I try and look out for the redirect response and handle that within my code?" or "Should I force the parameter to only accept https://?". Having this new parameter to persist the original HTTP method would simplify that common situation for modules which are essentially REST API wrappers.
Adam Cook (@codaamok) Thanks! Now I see you want a flexibility if a server sends 301 or 302 (I am not sure about 303) wrong status instead of 307 one. I agree it could be useful and I agree to mentor implementation but we need more detail proposal (one parameter? some?) and more feedback.
It looks like same experience for 303; rewrites POST to GET. Otherwise, yes, exactly, 307 is arguably what REST API web servers should be using.
As a starting point, I think support for the new parameter(s) should focus on only 301, 302 and 303 status codes.
For my needs, just one switch parameter -PersistHTTPMethod for all three status codes would be fine. However I can imagine there may be others out there that might want more granularity e.g. same parameter name but accept a string array of four possible values: 301, 302, 303 and All - allowing the user to pass a combination of status codes.
An alternative might be three switch parameters -PersistHTTPMethod301, -PersistHTTPMethod302 and -PersistHTTPMethod303 however that would add noise to the parameter list for the cmdlets - it depends how "offended" the team is with that.
Activity
[-]Feature Request: create switch to not convert POST requests to GET when following a redirect for Invoke-RestMethod or Invoke-WebRequest[/-][+]Feature Request: create switch to persist HTTP method when following a redirect for Invoke-RestMethod or Invoke-WebRequest[/+]iSazonov commentedon Jan 7, 2021
Adam Cook (@codaamok) Thanks for raising the issue!
codaamok commentedon Jan 9, 2021
If you sent a POST request to a REST API, using PowerShell, and you forgot to explicitly define
https://in the URL, would you like the HTTP method to remain as POST and not get converted to GET? The answer would likely be yes, and I think that's a valid use case. It's interesting to note that cURL offers this parameter idea, but for just POST methods, via --post301, --post302 and --post303.As far as I'm aware this is a feature request but if I've done it wrong please tell me.
I believe section 6.4 will helps us here. This quote from a note at the start of that section is interesting:
iSazonov commentedon Jan 9, 2021
codaamok commentedon Jan 9, 2021
The cmdlet is already following "the latter semantics" (rewrite as GET). This feature request is for a parameter which forces
Invoke-RestMethodandInvoke-WebRequestto follow "the former semantics" (persist as original method).iSazonov commentedon Jan 9, 2021
Ah, sorry, I thought we still follow old behavior. In the case we need more feedback. Do know important scenarios where the feature is critical? Specially Azure scenarios?
/cc Mark Kraus (@markekraus)
codaamok commentedon Jan 9, 2021
It's absolutely not critical, it's definitely a quality of life type thing. Most people would simply change the
-Uriparameter to behttps://and get on with their lives.However, where this feature request will be most helpful is for module authors. For example, for modules which are written for a web service's REST API. Perhaps a parameter for each function in said module allowed the user to specify a URL to their target host/service and they passed
example.comto said parameter. By default, most HTTP agents will send out the request over tcp/80 and the majority of web servers today will respond with a redirect tohttps://example.com. As it stands today, if the function of the module was to HTTP POST, that would get rewritten as HTTP GET and potentially produce erroneous results.This puts module authors in a bit of a dilemma of sorts. Questions like "Do I try and look out for the redirect response and handle that within my code?" or "Should I force the parameter to only accept
https://?". Having this new parameter to persist the original HTTP method would simplify that common situation for modules which are essentially REST API wrappers.iSazonov commentedon Jan 9, 2021
Adam Cook (@codaamok) Thanks! Now I see you want a flexibility if a server sends 301 or 302 (I am not sure about 303) wrong status instead of 307 one. I agree it could be useful and I agree to mentor implementation but we need more detail proposal (one parameter? some?) and more feedback.
codaamok commentedon Jan 9, 2021
It looks like same experience for 303; rewrites POST to GET. Otherwise, yes, exactly, 307 is arguably what REST API web servers should be using.
As a starting point, I think support for the new parameter(s) should focus on only 301, 302 and 303 status codes.
For my needs, just one switch parameter
-PersistHTTPMethodfor all three status codes would be fine. However I can imagine there may be others out there that might want more granularity e.g. same parameter name but accept a string array of four possible values:301,302,303andAll- allowing the user to pass a combination of status codes.An alternative might be three switch parameters
-PersistHTTPMethod301,-PersistHTTPMethod302and-PersistHTTPMethod303however that would add noise to the parameter list for the cmdlets - it depends how "offended" the team is with that.codaamok commentedon Jan 9, 2021
Thinking about it a little more, the parameter name would likely depend on whether support is possible for persisting any HTTP method, or just POST.
iSazonov commentedon Jan 10, 2021
We already have
Methodparameter so we have no need duplicate this in the new parameter.For discussion:
We could replace "Persist" with "Preserve".