Skip to content

Commit d74abda

Browse files
committed
Add FolderSchemeHandlerFactory - maps request urls to files on disk within a specified folder.
Resolve #1717
1 parent 578ff7e commit d74abda

File tree

4 files changed

+116
-1
lines changed

4 files changed

+116
-1
lines changed

CefSharp.Example/CefExample.cs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
using CefSharp.Example.Properties;
1010
using CefSharp.Example.Proxy;
1111
using CefSharp.Internals;
12+
using CefSharp.SchemeHandler;
1213

1314
namespace CefSharp.Example
1415
{
@@ -150,6 +151,15 @@ public static void Init(bool osr, bool multiThreadedMessageLoop)
150151
SchemeHandlerFactory = new CefSharpSchemeHandlerFactory()
151152
});
152153

154+
settings.RegisterScheme(new CefCustomScheme
155+
{
156+
SchemeName = "localfolder",
157+
SchemeHandlerFactory = new FolderSchemeHandlerFactory(rootFolder: @"..\..\..\..\CefSharp.Example\Resources",
158+
schemeName: "localfolder", //Optional param no schemename checking if null
159+
hostName: "cefsharp", //Optional param no hostname checking if null
160+
defaultPage: "home.html") //Optional param will default to index.html
161+
});
162+
153163
settings.RegisterExtension(new CefExtension("cefsharp/example", Resources.extension));
154164

155165
settings.FocusedNodeChangedEnabled = true;

CefSharp/CefSharp.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,7 @@
194194
<Compile Include="ResourceType.cs" />
195195
<Compile Include="ResponseAction.cs" />
196196
<Compile Include="Internals\ScreenInfo.cs" />
197+
<Compile Include="SchemeHandler\FolderSchemeHandlerFactory.cs" />
197198
<Compile Include="TaskCompletionHandler.cs" />
198199
<Compile Include="TaskCookieVisitor.cs" />
199200
<Compile Include="TaskPrintToPdfCallback.cs" />

CefSharp/ISchemeHandlerFactory.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ public interface ISchemeHandlerFactory
2323
/// <param name="schemeName">the scheme name</param>
2424
/// <param name="request">The request. (will not contain cookie data)</param>
2525
/// <returns>
26-
/// Return a new ISchemeHandler instance to handle the request or an empty
26+
/// Return a new <see cref="IResourceHandler"/> instance to handle the request or an empty
2727
/// reference to allow default handling of the request
2828
/// </returns>
2929
IResourceHandler Create(IBrowser browser, IFrame frame, string schemeName, IRequest request);
Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
// Copyright © 2010-2016 The CefSharp Authors. All rights reserved.
2+
//
3+
// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
4+
5+
using CefSharp;
6+
using System;
7+
using System.IO;
8+
using System.Net;
9+
10+
namespace CefSharp.SchemeHandler
11+
{
12+
/// <summary>
13+
/// FolderSchemeHandlerFactory is a very simple scheme handler that allows you
14+
/// to map requests for urls to a folder on your file system. For example
15+
/// creating a setting the rootFolder to c:\projects\CefSharp\CefSharp.Example\Resources
16+
/// registering the scheme handler
17+
/// </summary>
18+
public class FolderSchemeHandlerFactory : ISchemeHandlerFactory
19+
{
20+
private string rootFolder;
21+
private string defaultPage;
22+
private string schemeName;
23+
private string hostName;
24+
25+
/// <summary>
26+
/// Initialize a new instance of FolderSchemeHandlerFactory
27+
/// </summary>
28+
/// <param name="rootFolder">Root Folder where all your files exist, requests cannot be made outside of this folder</param>
29+
/// <param name="schemeName">if not null then schemeName checking will be implemented</param>
30+
/// <param name="hostName">if not null then hostName checking will be implemented</param>
31+
/// <param name="defaultPage">default page if no page specified, defaults to index.html</param>
32+
public FolderSchemeHandlerFactory(string rootFolder, string schemeName = null, string hostName = null, string defaultPage = "index.html")
33+
{
34+
this.rootFolder = Path.GetFullPath(rootFolder);
35+
this.defaultPage = defaultPage;
36+
this.schemeName = schemeName;
37+
this.hostName = hostName;
38+
39+
if (!Directory.Exists(this.rootFolder))
40+
{
41+
throw new DirectoryNotFoundException(this.rootFolder);
42+
}
43+
}
44+
45+
/// <summary>
46+
/// If the file requested is within the rootFolder then a IResourceHandler reference to the file requested will be returned
47+
/// otherwise a 404 ResourceHandler will be returned.
48+
/// </summary>
49+
/// <param name="browser">the browser window that originated the
50+
/// request or null if the request did not originate from a browser window
51+
/// (for example, if the request came from CefURLRequest).</param>
52+
/// <param name="frame">frame that originated the request
53+
/// or null if the request did not originate from a browser window
54+
/// (for example, if the request came from CefURLRequest).</param>
55+
/// <param name="schemeName">the scheme name</param>
56+
/// <param name="request">The request. (will not contain cookie data)</param>
57+
/// <returns>
58+
/// A IResourceHandler
59+
/// </returns>
60+
IResourceHandler ISchemeHandlerFactory.Create(IBrowser browser, IFrame frame, string schemeName, IRequest request)
61+
{
62+
if (this.schemeName != null && !schemeName.Equals(this.schemeName, StringComparison.OrdinalIgnoreCase))
63+
{
64+
var invalidSchemeName = ResourceHandler.FromString(string.Format("SchemeName {0} does not match the expected SchemeName of {1}.", schemeName, this.schemeName));
65+
invalidSchemeName.StatusCode = (int)HttpStatusCode.NotFound;
66+
67+
return invalidSchemeName;
68+
}
69+
70+
var uri = new Uri(request.Url);
71+
72+
if (this.hostName != null && !uri.Host.Equals(this.hostName, StringComparison.OrdinalIgnoreCase))
73+
{
74+
var invalidHostName = ResourceHandler.FromString(string.Format("HostName {0} does not match the expected HostName of {1}.", uri.Host, this.hostName));
75+
invalidHostName.StatusCode = (int)HttpStatusCode.NotFound;
76+
77+
return invalidHostName;
78+
}
79+
80+
//Get the absolute path and remove the leading slash
81+
var asbolutePath = uri.AbsolutePath.Substring(1);
82+
83+
if (string.IsNullOrEmpty(asbolutePath))
84+
{
85+
asbolutePath = defaultPage;
86+
}
87+
88+
var filePath = Path.GetFullPath(Path.Combine(rootFolder, asbolutePath));
89+
90+
//Check the file requested is within the specified path and that the file exists
91+
if(filePath.StartsWith(rootFolder, StringComparison.OrdinalIgnoreCase) && File.Exists(filePath))
92+
{
93+
var fileExtension = Path.GetExtension(filePath);
94+
var mimeType = ResourceHandler.GetMimeType(fileExtension);
95+
return ResourceHandler.FromFilePath(filePath, mimeType);
96+
}
97+
98+
var fileNotFoundResourceHandler = ResourceHandler.FromString("File Not Found - " + filePath);
99+
fileNotFoundResourceHandler.StatusCode = (int)HttpStatusCode.NotFound;
100+
101+
return fileNotFoundResourceHandler;
102+
}
103+
}
104+
}

0 commit comments

Comments
 (0)