예제 #1
0
 private void AddCustomScheme(string scheme, ResolveWebResourceDelegate requestHandler)
 {
     // Because of WKWebView limitations, this can only be called during the constructor
     // before the first call to Show. To enforce this, it's private and is only called
     // in response to the constructor options.
     WebResourceRequestedCallback callback = (string url, out int numBytes, out string contentType) =>
     {
         var responseStream = requestHandler(url, out contentType, out Encoding encoding);
         if (responseStream == null)
         {
             // Webview should pass through request to normal handlers (e.g., network)
             // or handle as 404 otherwise
             numBytes = 0;
             return(default);
예제 #2
0
            /// <summary>
            /// Resolves an Uri to a stream.
            /// </summary>
            /// <param name="uri">The uri to resolve.</param>
            /// <param name="resolveWebResourceDelegate">The delegate to call.</param>
            /// <returns>A Stream.</returns>
            private Stream Resolve(string uri, ResolveWebResourceDelegate resolveWebResourceDelegate)
            {
                var result = resolveWebResourceDelegate(uri, out string contentType, out Encoding encoding);

                if (result == null)
                {
                    throw new ArgumentOutOfRangeException(uri.ToString());
                }

                if (contentType == "text/html")
                {
                    var finalStream = new MemoryStream((int)result.Length + 100);

                    using (var tempStream = new MemoryStream((int)result.Length + 100))
                        using (var reader = new StreamReader(result, encoding))
                            using (var writer = new StreamWriter(tempStream, encoding))
                            {
                                var defaultHandler = this.schemeHandlers["http"];

                                var content = reader.ReadToEnd();
                                foreach (var handler in this.schemeHandlers.Where(s => s.Value != defaultHandler))
                                {
                                    var hash = GetHashString(handler.Key);
                                    content = content.Replace($"{handler.Key}://", $"{hash}/");
                                }

                                writer.Write(content);
                                writer.Flush();
                                tempStream.Position = 0;
                                tempStream.CopyTo(finalStream);
                                finalStream.Position = 0;
                            }

                    result.Dispose();
                    result = finalStream;
                }

                return(result);
            }
예제 #3
0
 /// <summary>
 /// Add a custom scheme with a handler to the webiew.
 /// </summary>
 /// <param name="schemeName">The scheme name to handle.</param>
 /// <param name="handler">The handler for the scheme.</param>
 internal void AddCustomScheme(string schemeName, ResolveWebResourceDelegate handler)
 {
     this.schemeHandlers.Add(schemeName, handler);
 }
 public SchemeHandler(ResolveWebResourceDelegate handler)
 {
     this.handler = handler;
 }
예제 #5
0
 /// <summary>
 /// Initializes a new instance of the <see cref="UrlSchemeHandler"/> class.
 /// </summary>
 /// <param name="requestHandler">A reference to the requesthandler delegate.</param>
 public UrlSchemeHandler(ResolveWebResourceDelegate requestHandler)
 {
     this.requestHandler = requestHandler;
 }
        /// <summary>
        /// Runs Blazor using the specified <see cref="IBlazorWebView"/> implementation,
        /// using the path to the index.html host file and optionally a delegate to
        /// resolve the normal (non framework) resources.
        /// </summary>
        /// <typeparam name="TStartup">A startup class.</typeparam>
        /// <param name="blazorWebView">An <see cref="IBlazorWebView"/> implementation.</param>
        /// <param name="hostHtmlPath">The specified oath to the index.html file.</param>
        /// <param name="defaultResolveDelegate">An optional delegate to resolve non framework resources.</param>
        /// <returns>An <see cref="IDisposable "/> instance that can be used to cleanup Blazor.</returns>
        public static IDisposable Run <TStartup>(IBlazorWebView blazorWebView, string hostHtmlPath, ResolveWebResourceDelegate defaultResolveDelegate = null)
        {
            if (defaultResolveDelegate == null)
            {
                var contentRootAbsolute = Path.GetDirectoryName(Path.GetFullPath(hostHtmlPath));

                defaultResolveDelegate = (string url, out string contentType, out Encoding encoding) =>
                {
                    // TODO: Only intercept for the hostname 'app' and passthrough for others
                    // TODO: Prevent directory traversal?
                    var appFile = Path.Combine(contentRootAbsolute, new Uri(url).AbsolutePath.Substring(1));
                    if (appFile == contentRootAbsolute)
                    {
                        appFile = hostHtmlPath;
                    }

                    contentType = GetContentType(appFile);

                    if (!File.Exists(appFile))
                    {
                        encoding = Encoding.Default;
                        return(null);
                    }

                    return(GetEncodingAndOpen(appFile, out encoding));
                };
            }

            BlazorWebView = blazorWebView;
            BlazorWebView.Initialize(options =>
            {
                options.SchemeHandlers.Add(BlazorAppScheme, defaultResolveDelegate);

                // framework:// is resolved as embedded resources
                options.SchemeHandlers.Add("framework", (string url, out string contentType, out Encoding encoding) =>
                {
                    contentType = GetContentType(url);
                    encoding    = Encoding.UTF8;
                    return(SupplyFrameworkFile(url));
                });
            });

            CancellationTokenSource appLifetimeCts = new CancellationTokenSource();

            Task.Factory.StartNew(async() =>
            {
                try
                {
                    var ipc = new IPC(BlazorWebView);
                    await RunAsync <TStartup>(ipc, appLifetimeCts.Token);
                }
                catch (Exception ex)
                {
                    UnhandledException(ex);
                    throw;
                }
            });

            try
            {
                BlazorWebView.NavigateToUrl(BlazorAppScheme + "://app/");
            }
            catch
            {
                appLifetimeCts.Cancel();
                throw;
            }

            return(new DelegateDisposable(() => appLifetimeCts.Cancel()));
        }
예제 #7
0
        /// <summary>
        /// Adds a custom scheme handler to the collection of schemes to handle.
        /// </summary>
        /// <param name="webConfig">The webiew configuration.</param>
        /// <param name="scheme">The scheme to use.</param>
        /// <param name="requestHandler">The handler for the scheme.</param>
        private void AddCustomScheme(WKWebViewConfiguration webConfig, string scheme, ResolveWebResourceDelegate requestHandler)
        {
            var urlSchemeHandler = new UrlSchemeHandler(requestHandler);

            webConfig.SetUrlSchemeHandler(urlSchemeHandler, scheme);
        }
예제 #8
0
 /// <summary>
 /// Adds a scheme handler to the EdgeResolver.
 /// </summary>
 /// <param name="schemeName">The name of the scheme.</param>
 /// <param name="handler">The handler.</param>
 public void AddSchemeHandler(string schemeName, ResolveWebResourceDelegate handler)
 {
     this.schemeHandlers.Add(schemeName, handler);
 }