// 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();
}
}
}
}