// Copyright © 2014 The CefSharp Authors. All rights reserved. // // Use of this source code is governed by a BSD-style license that can be found in the LICENSE file. using System; using System.Collections.Concurrent; using System.Collections.Generic; using CefSharp.Internals; namespace CefSharp { /// /// Default implementation of it's used /// internally for the LoadHtml implementation - basically a resource handler is /// registered for a specific Url. /// public class ResourceRequestHandlerFactory : IResourceRequestHandlerFactory { /// /// Resource handler thread safe dictionary /// public ConcurrentDictionary Handlers { get; private set; } /// /// Create a new instance of DefaultResourceHandlerFactory /// /// string equality comparer public ResourceRequestHandlerFactory(IEqualityComparer comparer = null) { Handlers = new ConcurrentDictionary(comparer ?? StringComparer.OrdinalIgnoreCase); } /// /// Register a handler for the specified Url /// /// url /// The data in byte[] format that will be used for the response /// mime type /// Whether or not the handler should be used once (true) or until manually unregistered (false) /// returns true if the Url was successfully parsed into a Uri otherwise false public virtual bool RegisterHandler(string url, byte[] data, string mimeType = ResourceHandler.DefaultMimeType, bool oneTimeUse = false) { Uri uri; if (Uri.TryCreate(url, UriKind.Absolute, out uri)) { var entry = new ResourceRequestHandlerFactoryItem(data, mimeType, oneTimeUse); Handlers.AddOrUpdate(uri.AbsoluteUri, entry, (k, v) => entry); return true; } return false; } /// /// Unregister a handler for the specified Url /// /// Url /// returns true if successfully removed public virtual bool UnregisterHandler(string url) { return Handlers.TryRemove(url, out _); } /// /// Are there any 's registered? /// bool IResourceRequestHandlerFactory.HasHandlers { get { return Handlers.Count > 0; } } /// IResourceRequestHandler IResourceRequestHandlerFactory.GetResourceRequestHandler(IWebBrowser chromiumWebBrowser, IBrowser browser, IFrame frame, IRequest request, bool isNavigation, bool isDownload, string requestInitiator, ref bool disableDefaultHandling) { return GetResourceRequestHandler(chromiumWebBrowser, browser, frame, request, isNavigation, isDownload, requestInitiator, ref disableDefaultHandling); } /// /// Called on the CEF IO thread before a resource request is initiated. /// /// the ChromiumWebBrowser control /// represent the source browser of the request /// represent the source frame of the request /// represents the request contents and cannot be modified in this callback /// will be true if the resource request is a navigation /// will be true if the resource request is a download /// is the origin (scheme + domain) of the page that initiated the request /// to true to disable default handling of the request, in which case it will need to be handled via or it will be canceled /// To allow the resource load to proceed with default handling return null. To specify a handler for the resource return a object. If this callback returns null the same method will be called on the associated , if any protected virtual IResourceRequestHandler GetResourceRequestHandler(IWebBrowser chromiumWebBrowser, IBrowser browser, IFrame frame, IRequest request, bool isNavigation, bool isDownload, string requestInitiator, ref bool disableDefaultHandling) { try { ResourceRequestHandlerFactoryItem entry; if (Handlers.TryGetValue(request.Url, out entry)) { if (entry.OneTimeUse) { Handlers.TryRemove(request.Url, out entry); } return new InMemoryResourceRequestHandler(entry.Data, entry.MimeType); } return null; } finally { request.Dispose(); } } } }