Skip to content

[HybridWebView] Add the ability to intercept all web resource requests #28876

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

Merged
merged 3 commits into from
May 29, 2025

Conversation

mattleibow
Copy link
Member

@mattleibow mattleibow commented Apr 9, 2025

Description of Change

Note

I have created demo repo with the NuGet packages from the PR (but for .NET 9)
https://github.com/mattleibow/MauiHybridWebViewInterceptionDemo

Intercepting requests before they leave the browser will allow for the addition of headers as well as cancellation of the requests.

The API is only really fully shapeable once all the platforms are complete as each platform is really different, but the idea I have right now is a mix of all the platforms.

// CONTROLS  /  XAML

public class HybridWebView : IHybridWebView
{
    // new event where all things are happening
    public event EventHandler<HybridWebViewWebResourceRequestedEventArgs>? WebResourceRequested;
}

public class HybridWebViewWebResourceRequestedEventArgs
{
    // access to the platform-specific features
    public PlatformHybridWebViewWebResourceRequestedEventArgs? PlatformArgs { get; }

    // general properties
    public Uri Uri { get; }
    public string Method { get; }
    public IReadOnlyDictionary<string, string> Headers { get; }
    public IReadOnlyDictionary<string, string> QueryParameters { get; }

    // flag property to indicate that the app will continue processing
    public bool Handled { get; set; }

    // if the event is handled, then one of these MUST be called before the event handler returns
    public void SetResponse(int code, string reason, IReadOnlyDictionary<string, string>? headers, Stream? content);
    public void SetResponse(int code, string reason, IReadOnlyDictionary<string, string>? headers, Task<Stream?> contentTask);

    // some APIs that are extension method overloads in the extensions class (HybridWebViewWebResourceRequestedEventArgsExtensions)
    //
    // no data returned, typically a error or redirect
    // public void SetResponse(int code, string reason);
    //
    // data returned, but no headers except the content type
    // public void SetResponse(int code, string reason, string contentType, Stream? content);
    // public void SetResponse(int code, string reason, string contentType, Task<Stream?> contentTask);
}

// Extension methods that make things easier (see more info on the main event args)
public static class HybridWebViewWebResourceRequestedEventArgsExtensions
{
    public static void SetResponse(this HybridWebViewWebResourceRequestedEventArgs e, int code, string reason);

    public static void SetResponse(this HybridWebViewWebResourceRequestedEventArgs e, int code, string reason, string contentType, Stream? content);
    public static void SetResponse(this HybridWebViewWebResourceRequestedEventArgs e, int code, string reason, string contentType, Task<Stream?> contentTask);
}

public class PlatformHybridWebViewWebResourceRequestedEventArgs
{
#if WINDOWS

    // Platform event sender
    public global::Microsoft.Web.WebView2.Core.CoreWebView2 Sender { get; }
    // Platform event args
    public global::Microsoft.Web.WebView2.Core.CoreWebView2WebResourceRequestedEventArgs RequestEventArgs { get; }
    // Platform event args request (convenience)
    public global::Microsoft.Web.WebView2.Core.CoreWebView2WebResourceRequest Request { get; }

#elif IOS || MACCATALYST

    // Platform event sender
    public global::WebKit.WKWebView Sender { get; }
    // Platform event args
    public global::WebKit.IWKUrlSchemeTask UrlSchemeTask { get; }
    // Platform event args request (convenience)
    public Foundation.NSUrlRequest Request { get; }

#elif ANDROID

    // Platform event sender
    public global::Android.Webkit.WebView Sender { get; }
    // Platform event args
    public global::Android.Webkit.IWebResourceRequest Request { get; }
    // User response instance to return to the bowser (mut always be set if event is handled)
    public global::Android.Webkit.WebResourceResponse? Response { get; set; }

#endif
}


// CORE

public class WebResourceRequestedEventArgs
{
#if WINDOWS
    public global::Microsoft.Web.WebView2.Core.CoreWebView2 Sender { get; }
    public global::Microsoft.Web.WebView2.Core.CoreWebView2WebResourceRequestedEventArgs RequestEventArgs { get; }
#elif IOS || MACCATALYST
    public global::WebKit.WKWebView Sender { get; }
    public global::WebKit.IWKUrlSchemeTask UrlSchemeTask { get; }
#elif ANDROID
    public global::Android.Webkit.WebView Sender { get; }
    public global::Android.Webkit.IWebResourceRequest Request { get; }
    public global::Android.Webkit.WebResourceResponse? Response { get; set; }
#endif
}

public interface IHybridWebView : IView
{
    bool WebResourceRequested(WebResourceRequestedEventArgs args);
}

Tasks

  • WebView
    • Android
    • iOS/macOS
    • Windows
  • HybridWebView
    • Android
    • iOS/macOS
    • Windows
  • BlazorWebView
    • Android
    • iOS/macOS
    • Windows

Issues Fixed

Fixes #11382


Implementation Restrictions

  • Android
    • Android does not directly allow "intercept-and-continue" for requests. The implementation is to rather notify you that a request is about to happen and you can either replace the whole request or do nothing and let the webview do it.
    • Android does not support custom schemes.
  • iOS/Mac Catalyst
Platform Intercept HTTPS Intercept Custom Schemes Request Modification
Android
iOS
Mac Catalyst
Windows 1

Notes:

@Copilot Copilot AI review requested due to automatic review settings April 9, 2025 00:00
@mattleibow mattleibow requested a review from a team as a code owner April 9, 2025 00:00
@mattleibow mattleibow requested review from rmarinho and PureWeen April 9, 2025 00:00
@mattleibow mattleibow marked this pull request as draft April 9, 2025 00:00
Copy link
Contributor

@Copilot Copilot AI left a comment

Choose a reason for hiding this comment

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

Copilot reviewed 5 out of 6 changed files in this pull request and generated no comments.

Files not reviewed (1)
  • src/Controls/tests/DeviceTests/Resources/Raw/HybridTestRoot/index.html: Language not supported
Comments suppressed due to low confidence (2)

src/Core/src/Handlers/HybridWebView/HybridWebViewHandler.Windows.cs:241

  • Switching to a universal filter '*' may intercept more requests than intended, including external resources. Consider verifying that this change does not introduce performance impacts or unintended side effects.
webView.CoreWebView2.AddWebResourceRequestedFilter("*", CoreWebView2WebResourceContext.All);

src/Controls/samples/Controls.Sample/Pages/Controls/HybridWebViewPage.xaml.cs:22

  • [nitpick] The string literal 'badthing' is used directly in the condition; consider extracting it into a named constant to improve readability and ensure consistency.
if (e.PlatformArgs.WebResourceRequestedEventArgs.Request.Uri.Contains("badthing", StringComparison.InvariantCultureIgnoreCase))

@mattleibow mattleibow added this to the .NET 10.0-preview4 milestone Apr 9, 2025
@mattleibow
Copy link
Member Author

Maybe if we land this, we won't need a "proxy" endpoint as all endpoints will become proxy-able: #25867

@mattleibow mattleibow force-pushed the dev/intercept-requests branch 3 times, most recently from bb61da6 to 91f3bb2 Compare April 15, 2025 14:24
@mattleibow mattleibow requested review from Eilon and tj-devel709 April 15, 2025 14:39
@mattleibow mattleibow force-pushed the dev/intercept-requests branch from a0103f5 to a6bc950 Compare April 17, 2025 20:37
@mattleibow mattleibow changed the title Start adding the ability to intercept all requests Add the ability to intercept all web resource requests Apr 18, 2025
@mattleibow mattleibow force-pushed the dev/intercept-requests branch 2 times, most recently from b5635ad to 41ba062 Compare April 30, 2025 15:58
@mattleibow mattleibow force-pushed the dev/intercept-requests branch from 41ba062 to 9b25d52 Compare May 2, 2025 20:11
@mattleibow mattleibow changed the base branch from main to net10.0 May 2, 2025 20:11
@mattleibow mattleibow marked this pull request as ready for review May 2, 2025 20:11
@mattleibow mattleibow moved this from Todo to Ready To Review in MAUI SDK Ongoing May 5, 2025
@mattleibow
Copy link
Member Author

/backport to release/10.0.1xx-preview4

Copy link
Contributor

github-actions bot commented May 5, 2025

Started backporting to release/10.0.1xx-preview4: https://github.com/dotnet/maui/actions/runs/14839378964

@mattleibow mattleibow force-pushed the dev/intercept-requests branch from 9b25d52 to ff05a43 Compare May 5, 2025 19:36
@mattleibow mattleibow changed the base branch from net10.0 to release/10.0.1xx-preview4 May 5, 2025 19:37
@mattleibow mattleibow force-pushed the dev/intercept-requests branch from a2ecaa0 to a0483ab Compare May 22, 2025 12:03
@mattleibow
Copy link
Member Author

/rebase

@github-actions github-actions bot force-pushed the dev/intercept-requests branch from a0483ab to 189ed00 Compare May 26, 2025 19:57
@rmarinho
Copy link
Member

/rebase

@github-actions github-actions bot force-pushed the dev/intercept-requests branch from 189ed00 to 0c3297e Compare May 28, 2025 10:40
rmarinho
rmarinho previously approved these changes May 28, 2025
Copy link
Member

@rmarinho rmarinho left a comment

Choose a reason for hiding this comment

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

Testing on iOS and Android seems to work as expected if I set Handled=true but Android we do load more things

Android iOS
Screenshot_1748447344 Simulator Screenshot - appiumTest-02C18A7C-6294-4014-B68D-8627A64B4D54-iPhone Xs - 2025-05-28 at 16 46 26
macOS Windows
image image

@github-project-automation github-project-automation bot moved this from Ready To Review to Approved in MAUI SDK Ongoing May 28, 2025
@rmarinho
Copy link
Member

Windows seems to also not load the base page

Screenshot 2025-05-28 at 17 14 29

@mattleibow
Copy link
Member Author

Test failures are unrelated

@mattleibow mattleibow merged commit f01808d into net10.0 May 29, 2025
127 of 129 checks passed
@mattleibow mattleibow deleted the dev/intercept-requests branch May 29, 2025 14:33
@github-project-automation github-project-automation bot moved this from Approved to Done in MAUI SDK Ongoing May 29, 2025
@mattleibow mattleibow changed the title Add the ability to intercept all web resource requests [HybridWebView] Add the ability to intercept all web resource requests Jun 12, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Status: Done
Development

Successfully merging this pull request may close these issues.

Intercepting requests from BlazorWebView
2 participants