-
Notifications
You must be signed in to change notification settings - Fork 4.8k
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
[browser][http] Add support for AllowAutoRedirect. #41394
Conversation
Tagging subscribers to this area: @dotnet/ncl |
src/libraries/System.Net.Http/src/System/Net/Http/BrowserHttpHandler/BrowserHttpHandler.cs
Outdated
Show resolved
Hide resolved
…andler/BrowserHttpHandler.cs Co-authored-by: campersau <buchholz.bastian@googlemail.com>
src/libraries/System.Net.Http/src/System/Net/Http/BrowserHttpHandler/BrowserHttpHandler.cs
Outdated
Show resolved
Hide resolved
src/libraries/System.Net.Http/src/System/Net/Http/BrowserHttpHandler/BrowserHttpHandler.cs
Outdated
Show resolved
Hide resolved
src/libraries/System.Net.Http/src/System/Net/Http/BrowserHttpHandler/BrowserHttpHandler.cs
Outdated
Show resolved
Hide resolved
src/libraries/System.Net.Http/src/System/Net/Http/BrowserHttpHandler/BrowserHttpHandler.cs
Outdated
Show resolved
Hide resolved
src/libraries/System.Net.Http/src/System/Net/Http/BrowserHttpHandler/BrowserHttpHandler.cs
Outdated
Show resolved
Hide resolved
src/libraries/System.Net.Http/src/System/Net/Http/BrowserHttpHandler/BrowserHttpHandler.cs
Outdated
Show resolved
Hide resolved
src/libraries/System.Net.Http/src/System/Net/Http/BrowserHttpHandler/BrowserHttpHandler.cs
Outdated
Show resolved
Hide resolved
src/libraries/System.Net.Http/src/System/Net/Http/BrowserHttpHandler/BrowserHttpHandler.cs
Outdated
Show resolved
Hide resolved
…direct was explicitly set or not.
…andler/BrowserHttpHandler.cs Co-authored-by: Marie Píchová <11718369+ManickaP@users.noreply.github.com>
/cc @mkArtakMSFT @pranavkm just wanted to make sure you guys saw this in case you want to weigh in on it. |
…into wasm-http-redirect # Conflicts: # src/libraries/System.Net.Http/src/System/Net/Http/BrowserHttpHandler/BrowserHttpHandler.cs
src/libraries/System.Net.Http/src/System/Net/Http/BrowserHttpHandler/BrowserHttpHandler.cs
Outdated
Show resolved
Hide resolved
src/libraries/System.Net.Http/src/System/Net/Http/BrowserHttpHandler/BrowserHttpHandler.cs
Show resolved
Hide resolved
// The Response's status is 0, headers are empty, body is null and trailer is empty. | ||
if (status.ResponseType == "opaqueredirect") | ||
{ | ||
httpResponse.SetReasonPhraseWithoutValidation(status.ResponseType); |
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.
@karelz who could review this part? Should we try harder to map the result to status codes or expose that differently to the developers?
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.
Hello everyone. Is there any update on this?
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.
Also there is a line in the PR comments about mapping a result and the approach for this PR:
Instead of faking a 3XX status code the implementation uses the ReasonPhrase to return the fetch response type
opaqueredirect
.
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.
CC @dotnet/ncl
Hrm this is an interesting one. It seems like there is not a perfect solution here -- fetch API seems poorly made. ¯\_(ツ)_/¯
Without setting a normal redirect status code, we break compat with any existing code handling redirects.
But, it seems wrong to fake a status code when we don't know what the actual status code was. If we were to fake a status code, a temporary redirect seems like the best choice -- permanent redirect could cause dangerous handling e.g. updating a URI in a database.
To add a third bad option, what do we think of this? It at least gives the user some flexibility here.
public class BrowserHttpHandler
{
public const HttpStatusCode OpaqueRedirect = (HttpStatusCode)1000;
// if false, return TemporaryRedirect. if true, return OpaqueRedirect.
public bool ReturnOpaqueRedirect { get; set; } = false;
}
(note, using a status code like this may not be advisable as an on-by-default option, as you might have some code doing e.g. if(StatusCode >= 500)
)
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 I am understanding the above wouldn't this change the Public API as well?
Just to be clear -- since the fetch API does not give you the redirect URL, even with 'manual', there's basically nothing you can do with a redirect result other than know that it was a redirect, right? So any existing code that wants to handle redirects manually is going to be broken anyway. As such I'm fine just indicating the redirect via the ReasonPhrase, as originally proposed. It seems like fetch basically gives you two options, either auto-follow redirects, or don't handle redirects at all. |
It seems to be used very little, I'm having trouble finding an exact answer, but some places indicate that Otherwise I'm not sure how it would be different from 'error`. @marek-safar can you clarify? |
@scalablecory The only case to go on is the issue Cannot get next URL for redirect="manual" that is closed on the actual fetch implementation repo which is what browsers actually use. There is another issue labeled as Clarify "manual" redirect mode . Maybe that helps to clarify as It actually specifies the following: manual "
|
Just to follow up. If one uses |
My problem with adding code for this if it does work in some browsers and not others was to have a consistent interface at the least. If one browser work and another does not it will just cause even more confusion to the user. At least this way |
Okay, if "manual" is not giving consistent useful information across browsers, I guess setting the reason phrase is fine. It seems like it has a use that only makes sense in the browser, so portability is not a concern. |
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.
since @scalablecory is fine with it
Thanks everyone |
In a blazor scenario using http client, having made a request that gets redirected - I'd like to auto follow but via a browser navigate to the new URL (i.e change the window.location to the new URL) instead of following via a new fetch request. Is this option possible? I don't need to have the new URL or the response actually surfaced to me from http client for this scenario. |
Right now the property
AllowAutoRedirect
throwsPlatform Not Supported Exception
trying to access this parameter.SupportsRedirectConfiguration
,AllowAutoRedirect
.MaxAutomaticRedirections
still throws PNSE as per comments below. Leaving it atPlatform Not Supported Exception
since it is not supported by platform fetch api. It may be confusing to see this set and fetch not respecting the value.The fetch api supports three values for redirection and transparently follows HTTP-redirects, like 301, 302 etc.
The redirect option allows to change that:
Note
The
manual
value above does not really follow what the documentation says. See issue Cannot get next URL for redirect="manual" another issue pertaining to this issue is Header to opt out of opaque redirect .This PR will set the redirect property on the request object to
manual
ifAllowAutoRedirect
is false:One way to handle the redirect manually is checking the response message
IsSuccessStatusCode
is false and theReasonPhrase
isopaqueredirect
.As per the issue that is referenced the next URL is not modified to the the next URL location.
sample output from simulated test:
If trying to set the
AllowAutoRedirect
after any request has been made then the following error is thrown:There are a number of differences when using the
fetch
api that does not line up with the dotnet core implementation.Implementation summary:
Fix the issue of PNSE in existing code when using
AllowAutoRedirect
. A better way would have been checking the propertySupportsRedirectConfiguration
as it returned false before this PR. Attempted Use With Blazor wasm return "Property AllowAutoRedirect is not supported." octokit/octokit.net#2188Allow the
Get
orPost
of the HttpClient to not follow a redirect. As per the issue [wasm] Blazor 303 responses, and fetch vs navigation #39365What is different from dotnet core
AllowAutoRedirect
:The fetch API does not return a status code. Cannot get next URL for redirect="manual". Instead of faking a
3XX
status code the implementation uses theReasonPhrase
to return the fetch response typeopaqueredirect
.The fetch API does not return the next URL of the redirect. atomic-http-redirect-handling which basically says that it is implemented that way to block cross-site scripting attack.
One way to handle the redirect manually is checking the response message
IsSuccessStatusCode
is false and theReasonPhrase
isopaqueredirect
.References:
Close: #41255
Close: #39365