Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -50,13 +50,13 @@ public HybridWebViewWebResourceRequestedEventArgs(Uri uri, string method)
/// Gets the headers associated with the request.
/// </summary>
public IReadOnlyDictionary<string, string> Headers =>
_headers ??= PlatformArgs?.GetRequestHeaders() ?? new Dictionary<string, string>();
_headers ??= PlatformArgs?.GetRequestHeaders() ?? new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);

/// <summary>
/// Gets the query parameters from the URI.
/// </summary>
public IReadOnlyDictionary<string, string> QueryParameters =>
_queryParams ??= WebUtils.ParseQueryString(Uri, false) ?? new Dictionary<string, string>();
_queryParams ??= WebUtils.ParseQueryString(Uri, false) ?? new Dictionary<string, string>(StringComparer.Ordinal);

/// <summary>
/// Gets or sets a value indicating whether the request has been handled.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@ namespace Microsoft.Maui.Controls;
public class PlatformHybridWebViewWebResourceRequestedEventArgs
{
#if WINDOWS

IReadOnlyDictionary<string, string>? _headers;

internal PlatformHybridWebViewWebResourceRequestedEventArgs(
global::Microsoft.Web.WebView2.Core.CoreWebView2 sender,
global::Microsoft.Web.WebView2.Core.CoreWebView2WebResourceRequestedEventArgs eventArgs)
Expand Down Expand Up @@ -53,50 +56,13 @@ internal PlatformHybridWebViewWebResourceRequestedEventArgs(WebResourceRequested

internal string? GetRequestMethod() => Request.Method;

internal IReadOnlyDictionary<string, string>? GetRequestHeaders() => new WrappedHeadersDictionary(Request.Headers);

class WrappedHeadersDictionary : IReadOnlyDictionary<string, string>
Comment on lines -56 to -58
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The previous way to use wrappers was me being "so clever" and "avoiding allocations" and "reducing copies"... But yeah, that was not sensible since the amount of things that would happen was so little. In order to hit this path, the user has to actually request the headers.

For all other cases, this doesn't do anything.

{
private global::Microsoft.Web.WebView2.Core.CoreWebView2HttpRequestHeaders _headers;

public WrappedHeadersDictionary(global::Microsoft.Web.WebView2.Core.CoreWebView2HttpRequestHeaders headers)
{
_headers = headers;
}

public string this[string key] =>
_headers.Contains(key)
? _headers.GetHeader(key)
: throw new KeyNotFoundException($"The key '{key}' was not found.");

public IEnumerable<string> Keys =>
_headers.Select(header => header.Key);

public IEnumerable<string> Values =>
_headers.Select(header => header.Value);

public int Count => _headers.Count();

public bool ContainsKey(string key) => _headers.Contains(key);

public bool TryGetValue(string key, out string value)
{
if (_headers.Contains(key))
{
value = _headers.GetHeader(key);
return true;
}
value = string.Empty;
return false;
}

public IEnumerator<KeyValuePair<string, string>> GetEnumerator() => _headers.GetEnumerator();

IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
}
internal IReadOnlyDictionary<string, string> GetRequestHeaders() =>
_headers ??= new Dictionary<string, string>(Request.Headers, StringComparer.OrdinalIgnoreCase);

#elif IOS || MACCATALYST

IReadOnlyDictionary<string, string>? _headers;

internal PlatformHybridWebViewWebResourceRequestedEventArgs(
global::WebKit.WKWebView sender,
global::WebKit.IWKUrlSchemeTask urlSchemeTask)
Expand Down Expand Up @@ -139,61 +105,30 @@ internal PlatformHybridWebViewWebResourceRequestedEventArgs(WebResourceRequested

internal string? GetRequestMethod() => Request.HttpMethod;

internal IReadOnlyDictionary<string, string>? GetRequestHeaders() => new WrappedHeadersDictionary(Request.Headers);
internal IReadOnlyDictionary<string, string> GetRequestHeaders() =>
_headers ??= CreateHeadersDictionary();

class WrappedHeadersDictionary : IReadOnlyDictionary<string, string>
Dictionary<string, string> CreateHeadersDictionary()
{
Foundation.NSDictionary _headers;

public WrappedHeadersDictionary(Foundation.NSDictionary headers)
{
_headers = headers;
}

public string this[string key] =>
TryGetValue(key, out var value)
? value
: throw new KeyNotFoundException($"The key '{key}' was not found.");

public IEnumerable<string> Keys => _headers.Keys.Select(k => k.ToString());

public IEnumerable<string> Values => _headers.Values.Select(v => v.ToString());

public int Count => (int)_headers.Count;

public bool ContainsKey(string key)
var headers = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
if (Request.Headers is { } rh)
{
using var nskey = new Foundation.NSString(key);
return _headers.ContainsKey(nskey);
}

public bool TryGetValue(string key, out string value)
{
using var nsKey = new Foundation.NSString(key);
if (_headers.ContainsKey(nsKey))
foreach (var key in rh.Keys)
{
value = _headers[nsKey].ToString();
return true;
if (key is Foundation.NSString keyString)
{
headers[keyString] = rh[keyString].ToString();
}
}
value = string.Empty;
return false;
}

public IEnumerator<KeyValuePair<string, string>> GetEnumerator()
{
foreach (var pair in _headers)
{
yield return new KeyValuePair<string, string>(pair.Key.ToString(), pair.Value.ToString());
}
}

IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
return headers;
}

#elif ANDROID

Action<global::Android.Webkit.WebResourceResponse?> _setResponse;
private global::Android.Webkit.WebResourceResponse? _response;
global::Android.Webkit.WebResourceResponse? _response;
IReadOnlyDictionary<string, string>? _headers;

internal PlatformHybridWebViewWebResourceRequestedEventArgs(
global::Android.Webkit.WebView sender,
Expand Down Expand Up @@ -228,9 +163,9 @@ internal PlatformHybridWebViewWebResourceRequestedEventArgs(WebResourceRequested

/// <summary>
/// Gets or sets the native response to return to the web view.
///
///
/// This property must be set to a valid response if the <see cref="HybridWebViewWebResourceRequestedEventArgs.Handled"/> property is set to true.
///
///
/// This is only available on Android.
/// </summary>
public global::Android.Webkit.WebResourceResponse? Response
Expand All @@ -247,7 +182,10 @@ internal PlatformHybridWebViewWebResourceRequestedEventArgs(WebResourceRequested

internal string? GetRequestMethod() => Request.Method;

internal IReadOnlyDictionary<string, string>? GetRequestHeaders() => Request.RequestHeaders?.AsReadOnly();
internal IReadOnlyDictionary<string, string> GetRequestHeaders() =>
_headers ??= Request.RequestHeaders is { } rh
? new Dictionary<string, string>(rh, StringComparer.OrdinalIgnoreCase)
: new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
Comment on lines +185 to +188
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unfortunately, depending on the server and how the headers are populated, Android sometimes converts the headers to lower case. So we always will ned a case-insensitive.

Windows was already case insensitive, so this just makes it all consistent.


#else

Expand Down
Loading
Loading