Skip to content

Commit

Permalink
Add FolderSchemeHandlerFactory - maps request urls to files on disk w…
Browse files Browse the repository at this point in the history
…ithin a specified folder.

Resolve #1717
  • Loading branch information
amaitland committed Jun 22, 2016
1 parent 153296d commit ca2085e
Show file tree
Hide file tree
Showing 4 changed files with 116 additions and 1 deletion.
10 changes: 10 additions & 0 deletions CefSharp.Example/CefExample.cs
Expand Up @@ -9,6 +9,7 @@
using CefSharp.Example.Properties;
using CefSharp.Example.Proxy;
using CefSharp.Internals;
using CefSharp.SchemeHandler;

namespace CefSharp.Example
{
Expand Down Expand Up @@ -150,6 +151,15 @@ public static void Init(bool osr, bool multiThreadedMessageLoop)
SchemeHandlerFactory = new CefSharpSchemeHandlerFactory()
});

settings.RegisterScheme(new CefCustomScheme
{
SchemeName = "localfolder",
SchemeHandlerFactory = new FolderSchemeHandlerFactory(rootFolder: @"..\..\..\..\CefSharp.Example\Resources",
schemeName: "localfolder", //Optional param no schemename checking if null
hostName: "cefsharp", //Optional param no hostname checking if null
defaultPage: "home.html") //Optional param will default to index.html
});

settings.RegisterExtension(new CefExtension("cefsharp/example", Resources.extension));

settings.FocusedNodeChangedEnabled = true;
Expand Down
1 change: 1 addition & 0 deletions CefSharp/CefSharp.csproj
Expand Up @@ -194,6 +194,7 @@
<Compile Include="ResourceType.cs" />
<Compile Include="ResponseAction.cs" />
<Compile Include="Internals\ScreenInfo.cs" />
<Compile Include="SchemeHandler\FolderSchemeHandlerFactory.cs" />
<Compile Include="TaskCompletionHandler.cs" />
<Compile Include="TaskCookieVisitor.cs" />
<Compile Include="TaskPrintToPdfCallback.cs" />
Expand Down
2 changes: 1 addition & 1 deletion CefSharp/ISchemeHandlerFactory.cs
Expand Up @@ -23,7 +23,7 @@ public interface ISchemeHandlerFactory
/// <param name="schemeName">the scheme name</param>
/// <param name="request">The request. (will not contain cookie data)</param>
/// <returns>
/// Return a new ISchemeHandler instance to handle the request or an empty
/// Return a new <see cref="IResourceHandler"/> instance to handle the request or an empty
/// reference to allow default handling of the request
/// </returns>
IResourceHandler Create(IBrowser browser, IFrame frame, string schemeName, IRequest request);
Expand Down
104 changes: 104 additions & 0 deletions CefSharp/SchemeHandler/FolderSchemeHandlerFactory.cs
@@ -0,0 +1,104 @@
// Copyright © 2010-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 CefSharp;
using System;
using System.IO;
using System.Net;

namespace CefSharp.SchemeHandler
{
/// <summary>
/// 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
/// </summary>
public class FolderSchemeHandlerFactory : ISchemeHandlerFactory
{
private string rootFolder;
private string defaultPage;
private string schemeName;
private string hostName;

/// <summary>
/// Initialize a new instance of FolderSchemeHandlerFactory
/// </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>
public FolderSchemeHandlerFactory(string rootFolder, string schemeName = null, string hostName = null, string defaultPage = "index.html")
{
this.rootFolder = Path.GetFullPath(rootFolder);
this.defaultPage = defaultPage;
this.schemeName = schemeName;
this.hostName = hostName;

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))
{
var invalidSchemeName = ResourceHandler.FromString(string.Format("SchemeName {0} does not match the expected SchemeName of {1}.", schemeName, this.schemeName));
invalidSchemeName.StatusCode = (int)HttpStatusCode.NotFound;

return invalidSchemeName;
}

var uri = new Uri(request.Url);

if (this.hostName != null && !uri.Host.Equals(this.hostName, StringComparison.OrdinalIgnoreCase))
{
var invalidHostName = ResourceHandler.FromString(string.Format("HostName {0} does not match the expected HostName of {1}.", uri.Host, this.hostName));
invalidHostName.StatusCode = (int)HttpStatusCode.NotFound;

return invalidHostName;
}

//Get the absolute path and remove the leading slash
var asbolutePath = uri.AbsolutePath.Substring(1);

if (string.IsNullOrEmpty(asbolutePath))
{
asbolutePath = defaultPage;
}

var filePath = 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 = ResourceHandler.GetMimeType(fileExtension);
return ResourceHandler.FromFilePath(filePath, mimeType);
}

var fileNotFoundResourceHandler = ResourceHandler.FromString("File Not Found - " + filePath);
fileNotFoundResourceHandler.StatusCode = (int)HttpStatusCode.NotFound;

return fileNotFoundResourceHandler;
}
}
}

0 comments on commit ca2085e

Please sign in to comment.