diff --git a/src/libraries/System.Net.Http/src/System.Net.Http.csproj b/src/libraries/System.Net.Http/src/System.Net.Http.csproj index 1badaad9ca3c4..b77e735c629ba 100644 --- a/src/libraries/System.Net.Http/src/System.Net.Http.csproj +++ b/src/libraries/System.Net.Http/src/System.Net.Http.csproj @@ -674,6 +674,8 @@ + diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/BrowserHttpHandler/BrowserHttpHandler.cs b/src/libraries/System.Net.Http/src/System/Net/Http/BrowserHttpHandler/BrowserHttpHandler.cs index 5b026591ab5ca..eb474cde52641 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/BrowserHttpHandler/BrowserHttpHandler.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/BrowserHttpHandler/BrowserHttpHandler.cs @@ -34,6 +34,9 @@ internal sealed class BrowserHttpHandler : HttpMessageHandler private static readonly HttpRequestOptionsKey EnableStreamingResponse = new HttpRequestOptionsKey("WebAssemblyEnableStreamingResponse"); private static readonly HttpRequestOptionsKey> FetchOptions = new HttpRequestOptionsKey>("WebAssemblyFetchOptions"); + private bool _allowAutoRedirect = HttpHandlerDefaults.DefaultAutomaticRedirection; + // flag to determine if the _allowAutoRedirect was explicitly set or not. + private bool _isAllowAutoRedirectTouched; /// /// Gets whether the current Browser supports streaming responses @@ -95,8 +98,12 @@ public ICredentials? Credentials public bool AllowAutoRedirect { - get => throw new PlatformNotSupportedException(); - set => throw new PlatformNotSupportedException(); + get => _allowAutoRedirect; + set + { + _allowAutoRedirect = value; + _isAllowAutoRedirectTouched = true; + } } public int MaxAutomaticRedirections @@ -125,7 +132,7 @@ public SslClientAuthenticationOptions SslOptions public bool SupportsAutomaticDecompression => false; public bool SupportsProxy => false; - public bool SupportsRedirectConfiguration => false; + public bool SupportsRedirectConfiguration => true; private Dictionary? _properties; public IDictionary Properties => _properties ??= new Dictionary(); @@ -146,6 +153,22 @@ protected internal override async Task SendAsync(HttpReques requestObject.SetObjectProperty("method", request.Method.Method); + // Only set if property was specifically modified and is not default value + if (_isAllowAutoRedirectTouched) + { + // Allowing or Disallowing redirects. + // Here we will set redirect to `manual` instead of error if AllowAutoRedirect is + // false so there is no exception thrown + // + // https://developer.mozilla.org/en-US/docs/Web/API/Response/type + // + // other issues from whatwg/fetch: + // + // https://github.com/whatwg/fetch/issues/763 + // https://github.com/whatwg/fetch/issues/601 + requestObject.SetObjectProperty("redirect", AllowAutoRedirect ? "follow" : "manual"); + } + // We need to check for body content if (request.Content != null) { @@ -224,9 +247,20 @@ protected internal override async Task SendAsync(HttpReques JSObject t = (JSObject)await response.ConfigureAwait(continueOnCapturedContext: true); var status = new WasmFetchResponse(t, abortController, abortCts, abortRegistration); - HttpResponseMessage httpResponse = new HttpResponseMessage((HttpStatusCode)status.Status); + // Here we will set the ReasonPhrase so that it can be evaluated later. + // We do not have a status code but this will signal some type of what happened + // after interrogating the status code for success or not i.e. IsSuccessStatusCode + // + // https://developer.mozilla.org/en-US/docs/Web/API/Response/type + // opaqueredirect: The fetch request was made with redirect: "manual". + // The Response's status is 0, headers are empty, body is null and trailer is empty. + if (status.ResponseType == "opaqueredirect") + { + httpResponse.SetReasonPhraseWithoutValidation(status.ResponseType); + } + bool streamingEnabled = false; if (StreamingSupported) {