Skip to content

Instantly share code, notes, and snippets.

@amaitland
Last active July 30, 2019 10:39
Show Gist options
  • Save amaitland/b225fe6591a0f01af68e53f3f48a09ce to your computer and use it in GitHub Desktop.
Save amaitland/b225fe6591a0f01af68e53f3f48a09ce to your computer and use it in GitHub Desktop.
Scheme Handler Examples
using System;
using System.IO;
using System.Net;
namespace CefSharp.MinimalExample.WinForms
{
//This class would only be used if you choose Option #2
public class CustomFolderSchemeHandlerFactory : ISchemeHandlerFactory
{
private readonly string rootFolder;
private readonly string imagesRootFolder;
private readonly string defaultPage;
private readonly string schemeName;
private readonly string hostName;
private readonly FileShare resourceFileShare;
/// <summary>
/// Initialize a new instance of CustomFolderSchemeHandlerFactory
/// </summary>
/// <param name="rootFolder">Root Folder where all your files exist, requests cannot be made outside of this folder</param>
/// <param name="schemeName">if not null then schemeName checking will be implemented</param>
/// <param name="hostName">if not null then hostName checking will be implemented</param>
/// <param name="defaultPage">default page if no page specified, defaults to index.html</param>
/// <param name="resourceFileShare">file share mode used to open resources, defaults to FileShare.Read</param>
public CustomFolderSchemeHandlerFactory(string rootFolder, string imagesRootFolder, string schemeName = null, string hostName = null, string defaultPage = "index.html", FileShare resourceFileShare = FileShare.Read)
{
this.rootFolder = Path.GetFullPath(rootFolder);
this.imagesRootFolder = imagesRootFolder;
this.defaultPage = defaultPage;
this.schemeName = schemeName;
this.hostName = hostName;
this.resourceFileShare = resourceFileShare;
if (!Directory.Exists(this.rootFolder))
{
throw new DirectoryNotFoundException(this.rootFolder);
}
}
/// <summary>
/// If the file requested is within the rootFolder then a IResourceHandler reference to the file requested will be returned
/// otherwise a 404 ResourceHandler will be returned.
/// </summary>
/// <param name="browser">the browser window that originated the
/// request or null if the request did not originate from a browser window
/// (for example, if the request came from CefURLRequest).</param>
/// <param name="frame">frame that originated the request
/// or null if the request did not originate from a browser window
/// (for example, if the request came from CefURLRequest).</param>
/// <param name="schemeName">the scheme name</param>
/// <param name="request">The request. (will not contain cookie data)</param>
/// <returns>
/// A IResourceHandler
/// </returns>
IResourceHandler ISchemeHandlerFactory.Create(IBrowser browser, IFrame frame, string schemeName, IRequest request)
{
if (this.schemeName != null && !schemeName.Equals(this.schemeName, StringComparison.OrdinalIgnoreCase))
{
return ResourceHandler.ForErrorMessage(string.Format("SchemeName {0} does not match the expected SchemeName of {1}.", schemeName, this.schemeName), HttpStatusCode.NotFound);
}
var uri = new Uri(request.Url);
if (this.hostName != null && !uri.Host.Equals(this.hostName, StringComparison.OrdinalIgnoreCase))
{
return ResourceHandler.ForErrorMessage(string.Format("HostName {0} does not match the expected HostName of {1}.", uri.Host, this.hostName), HttpStatusCode.NotFound);
}
//Get the absolute path and remove the leading slash
var asbolutePath = uri.AbsolutePath.Substring(1);
if (string.IsNullOrEmpty(asbolutePath))
{
asbolutePath = defaultPage;
}
var filePath = WebUtility.UrlDecode(Path.GetFullPath(Path.Combine(rootFolder, asbolutePath)));
//Initial search to see if the file is in our root folder
if (filePath.StartsWith(rootFolder, StringComparison.OrdinalIgnoreCase) && File.Exists(filePath))
{
var fileExtension = Path.GetExtension(filePath);
var mimeType = ResourceHandler.GetMimeType(fileExtension);
var stream = new FileStream(filePath, FileMode.Open, FileAccess.Read, resourceFileShare);
return ResourceHandler.FromStream(stream, mimeType);
}
filePath = WebUtility.UrlDecode(Path.GetFullPath(Path.Combine(imagesRootFolder, asbolutePath)));
//If no match found in our root folder then check the file requested is within the images path
if (filePath.StartsWith(imagesRootFolder, StringComparison.OrdinalIgnoreCase) && File.Exists(filePath))
{
var fileExtension = Path.GetExtension(filePath);
var mimeType = ResourceHandler.GetMimeType(fileExtension);
var stream = new FileStream(filePath, FileMode.Open, FileAccess.Read, resourceFileShare);
return ResourceHandler.FromStream(stream, mimeType);
}
return ResourceHandler.ForErrorMessage("File Not Found - " + filePath, HttpStatusCode.NotFound);
}
}
}
//Option Number #1
//Use a different FolderSchemeHandlerFactory for our images folder
var localHtmlFolder = string.Format(@"{0}\html-resources\html\", Application.StartupPath);
var imagesFolder = @"c:\local\images";
//Regiser the first scheme handler factory for serving our main resources, html files etc.
//NOTE: Using https instead of a custom scheme name, I'd avise using either http or https instead of a custom scheme name
//if you use this option.
settings.RegisterScheme(new CefCustomScheme
{
SchemeName = "https",
DomainName = "mydomain.local",
SchemeHandlerFactory = new FolderSchemeHandlerFactory(
rootFolder: localHtmlFolder,
hostName: "mydomain.local",
defaultPage: "index.html"
)
});
//Second scheme handler factory for serving images from a different folder to our html
settings.RegisterScheme(new CefCustomScheme
{
SchemeName = "https",
DomainName = "images.mydomain.local",
SchemeHandlerFactory = new FolderSchemeHandlerFactory(
rootFolder: imagesFolder,
hostName: "images.mydomain.local"
)
});
//Option #2
//Use a CustomFolderSchemeHandlerFactory instance that initially looks for files in
//localHtmlFolder, if not found will search imagesFolder
var localHtmlFolder = string.Format(@"{0}\html-resources\html\", Application.StartupPath);
var imagesFolder = @"c:\local\images";
settings.RegisterScheme(new CefCustomScheme
{
SchemeName = "localfolder",
DomainName = "cefsharp",
SchemeHandlerFactory = new CustomFolderSchemeHandlerFactory(
rootFolder: localHtmlFolder,
imagesRootFolder: imagesFolder,
hostName: "cefsharp",
defaultPage: "index.html"
)
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment