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 ccca155d4bc8aa..c140c2ccb9e404 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 @@ -133,9 +133,6 @@ private static async Task CallFetch(HttpRequestMessage reques int headerCount = request.Headers.Count + request.Content?.Headers.Count ?? 0; List headerNames = new List(headerCount); List headerValues = new List(headerCount); - List optionNames = new List(); - List optionValues = new List(); - JSObject abortController = BrowserHttpInterop.CreateAbortController(); CancellationTokenRegistration? abortRegistration = cancellationToken.Register(() => { @@ -147,12 +144,27 @@ private static async Task CallFetch(HttpRequestMessage reques }); try { - optionNames.Add("method"); - optionValues.Add(request.Method.Method); + if (request.RequestUri == null) + { + throw new ArgumentNullException(nameof(request.RequestUri)); + } + + string uri = request.RequestUri.IsAbsoluteUri ? request.RequestUri.AbsoluteUri : request.RequestUri.ToString(); + + bool hasFetchOptions = request.Options.TryGetValue(FetchOptions, out IDictionary? fetchOptions); + int optionCount = 1 + (allowAutoRedirect.HasValue ? 1 : 0) + (hasFetchOptions && fetchOptions != null ? fetchOptions.Count : 0); + int optionIndex = 0; + string[] optionNames = new string[optionCount]; + object?[] optionValues = new object?[optionCount]; + + optionNames[optionIndex] = "method"; + optionValues[optionIndex] = request.Method.Method; + optionIndex++; if (allowAutoRedirect.HasValue) { - optionNames.Add("redirect"); - optionValues.Add(allowAutoRedirect.Value ? "follow" : "manual"); + optionNames[optionIndex] = "redirect"; + optionValues[optionIndex] = allowAutoRedirect.Value ? "follow" : "manual"; + optionIndex++; } foreach (KeyValuePair> header in request.Headers) @@ -176,21 +188,16 @@ private static async Task CallFetch(HttpRequestMessage reques } } - if (request.Options.TryGetValue(FetchOptions, out IDictionary? fetchOptions)) + if (hasFetchOptions && fetchOptions != null) { foreach (KeyValuePair item in fetchOptions) { - optionNames.Add(item.Key); - optionValues.Add(item.Value); + optionNames[optionIndex] = item.Key; + optionValues[optionIndex] = item.Value; + optionIndex++; } } - if (request.RequestUri == null) - { - throw new ArgumentNullException(nameof(request.RequestUri)); - } - - string uri = request.RequestUri.IsAbsoluteUri ? request.RequestUri.AbsoluteUri : request.RequestUri.ToString(); Task? promise; cancellationToken.ThrowIfCancellationRequested(); if (request.Content != null) @@ -201,7 +208,7 @@ private static async Task CallFetch(HttpRequestMessage reques .ConfigureAwait(true); cancellationToken.ThrowIfCancellationRequested(); - promise = BrowserHttpInterop.Fetch(uri, headerNames.ToArray(), headerValues.ToArray(), optionNames.ToArray(), optionValues.ToArray(), abortController, body); + promise = BrowserHttpInterop.Fetch(uri, headerNames.ToArray(), headerValues.ToArray(), optionNames, optionValues, abortController, body); } else { @@ -209,13 +216,14 @@ private static async Task CallFetch(HttpRequestMessage reques .ConfigureAwait(true); cancellationToken.ThrowIfCancellationRequested(); - promise = BrowserHttpInterop.Fetch(uri, headerNames.ToArray(), headerValues.ToArray(), optionNames.ToArray(), optionValues.ToArray(), abortController, buffer); + promise = BrowserHttpInterop.Fetch(uri, headerNames.ToArray(), headerValues.ToArray(), optionNames, optionValues, abortController, buffer); } } else { - promise = BrowserHttpInterop.Fetch(uri, headerNames.ToArray(), headerValues.ToArray(), optionNames.ToArray(), optionValues.ToArray(), abortController); + promise = BrowserHttpInterop.Fetch(uri, headerNames.ToArray(), headerValues.ToArray(), optionNames, optionValues, abortController); } + cancellationToken.ThrowIfCancellationRequested(); ValueTask wrappedTask = BrowserHttpInterop.CancelationHelper(promise, cancellationToken, abortController); JSObject fetchResponse = await wrappedTask.ConfigureAwait(true);