// Copyright © 2016 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.IO; using System.Net; namespace CefSharp.SchemeHandler { /// /// FolderSchemeHandlerFactory is a very simple scheme handler that allows you /// to map requests for urls to a folder on your file system. For example /// creating a setting the rootFolder to c:\projects\CefSharp\CefSharp.Example\Resources /// registering the scheme handler /// public class FolderSchemeHandlerFactory : ISchemeHandlerFactory { private readonly string rootFolder; private readonly string defaultPage; private readonly string schemeName; private readonly string hostName; private readonly FileShare resourceFileShare; /// /// is being deprecated in favour of using /// Chromiums native mimeType lookup which is accessible using Cef.GetMimeType, this method is however /// not directly avaliable as it exists in CefSharp.Core, to get around this we set /// this static delegate with a reference to Cef.GetMimeType when Cef.Initialize is called. /// public static Func GetMimeTypeDelegate = (s) => { return ResourceHandler.GetMimeType(s); }; /// /// Initialize a new instance of FolderSchemeHandlerFactory /// /// Root Folder where all your files exist, requests cannot be made outside of this folder /// if not null then schemeName checking will be implemented /// if not null then hostName checking will be implemented /// default page if no page specified, defaults to index.html /// file share mode used to open resources, defaults to FileShare.Read public FolderSchemeHandlerFactory(string rootFolder, string schemeName = null, string hostName = null, string defaultPage = "index.html", FileShare resourceFileShare = FileShare.Read) { this.rootFolder = Path.GetFullPath(rootFolder); this.defaultPage = defaultPage; this.schemeName = schemeName; this.hostName = hostName; this.resourceFileShare = resourceFileShare; if (!Directory.Exists(this.rootFolder)) { throw new DirectoryNotFoundException(this.rootFolder); } } /// /// 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. /// /// 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). /// 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). /// the scheme name /// The request. (will not contain cookie data) /// /// A IResourceHandler /// IResourceHandler ISchemeHandlerFactory.Create(IBrowser browser, IFrame frame, string schemeName, IRequest request) { return Create(browser, frame, schemeName, request); } /// /// 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. /// /// 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). /// 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). /// the scheme name /// The request. (will not contain cookie data) /// /// A IResourceHandler /// protected virtual IResourceHandler 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))); //Check the file requested is within the specified path and that the file exists if (filePath.StartsWith(rootFolder, StringComparison.OrdinalIgnoreCase) && File.Exists(filePath)) { var fileExtension = Path.GetExtension(filePath); var mimeType = GetMimeTypeDelegate(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); } } }