SEBWIN-362: Implemented basic load error page for browser.
This commit is contained in:
parent
049cf8fe19
commit
f0504fa6d2
11 changed files with 141 additions and 30 deletions
|
@ -17,6 +17,7 @@ using SafeExamBrowser.Browser.Contracts.Filters;
|
|||
using SafeExamBrowser.Browser.Events;
|
||||
using SafeExamBrowser.Browser.Filters;
|
||||
using SafeExamBrowser.Browser.Handlers;
|
||||
using SafeExamBrowser.Browser.Pages;
|
||||
using SafeExamBrowser.Configuration.Contracts;
|
||||
using SafeExamBrowser.I18n.Contracts;
|
||||
using SafeExamBrowser.Logging.Contracts;
|
||||
|
@ -115,6 +116,7 @@ namespace SafeExamBrowser.Browser
|
|||
var displayHandler = new DisplayHandler();
|
||||
var downloadLogger = logger.CloneFor($"{nameof(DownloadHandler)} #{Id}");
|
||||
var downloadHandler = new DownloadHandler(appConfig, settings, downloadLogger);
|
||||
var htmlLoader = new HtmlLoader(text);
|
||||
var keyboardHandler = new KeyboardHandler();
|
||||
var lifeSpanHandler = new LifeSpanHandler();
|
||||
var requestFilter = new RequestFilter();
|
||||
|
@ -138,7 +140,7 @@ namespace SafeExamBrowser.Browser
|
|||
|
||||
InitializeRequestFilter(requestFilter);
|
||||
|
||||
control = new BrowserControl(contextMenuHandler, dialogHandler, displayHandler, downloadHandler, keyboardHandler, lifeSpanHandler, requestHandler, startUrl);
|
||||
control = new BrowserControl(contextMenuHandler, dialogHandler, displayHandler, downloadHandler, htmlLoader, keyboardHandler, lifeSpanHandler, requestHandler, startUrl);
|
||||
control.AddressChanged += Control_AddressChanged;
|
||||
control.LoadingStateChanged += Control_LoadingStateChanged;
|
||||
control.TitleChanged += Control_TitleChanged;
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
|
||||
using CefSharp;
|
||||
using CefSharp.WinForms;
|
||||
using SafeExamBrowser.Browser.Pages;
|
||||
using SafeExamBrowser.UserInterface.Contracts.Browser;
|
||||
using SafeExamBrowser.UserInterface.Contracts.Browser.Events;
|
||||
|
||||
|
@ -19,6 +20,8 @@ namespace SafeExamBrowser.Browser
|
|||
private IDialogHandler dialogHandler;
|
||||
private IDisplayHandler displayHandler;
|
||||
private IDownloadHandler downloadHandler;
|
||||
private string errorPage;
|
||||
private HtmlLoader htmlLoader;
|
||||
private IKeyboardHandler keyboardHandler;
|
||||
private ILifeSpanHandler lifeSpanHandler;
|
||||
private IRequestHandler requestHandler;
|
||||
|
@ -53,6 +56,7 @@ namespace SafeExamBrowser.Browser
|
|||
IDialogHandler dialogHandler,
|
||||
IDisplayHandler displayHandler,
|
||||
IDownloadHandler downloadHandler,
|
||||
HtmlLoader htmlLoader,
|
||||
IKeyboardHandler keyboardHandler,
|
||||
ILifeSpanHandler lifeSpanHandler,
|
||||
IRequestHandler requestHandler,
|
||||
|
@ -62,6 +66,7 @@ namespace SafeExamBrowser.Browser
|
|||
this.dialogHandler = dialogHandler;
|
||||
this.displayHandler = displayHandler;
|
||||
this.downloadHandler = downloadHandler;
|
||||
this.htmlLoader = htmlLoader;
|
||||
this.keyboardHandler = keyboardHandler;
|
||||
this.lifeSpanHandler = lifeSpanHandler;
|
||||
this.requestHandler = requestHandler;
|
||||
|
@ -70,6 +75,7 @@ namespace SafeExamBrowser.Browser
|
|||
public void Initialize()
|
||||
{
|
||||
AddressChanged += (o, args) => addressChanged?.Invoke(args.Address);
|
||||
LoadError += BrowserControl_LoadError;
|
||||
LoadingStateChanged += (o, args) => loadingStateChanged?.Invoke(args.IsLoading);
|
||||
TitleChanged += (o, args) => titleChanged?.Invoke(args.Title);
|
||||
|
||||
|
@ -80,6 +86,8 @@ namespace SafeExamBrowser.Browser
|
|||
LifeSpanHandler = lifeSpanHandler;
|
||||
MenuHandler = contextMenuHandler;
|
||||
RequestHandler = requestHandler;
|
||||
|
||||
errorPage = htmlLoader.LoadErrorPage();
|
||||
}
|
||||
|
||||
public void NavigateBackwards()
|
||||
|
@ -111,5 +119,15 @@ namespace SafeExamBrowser.Browser
|
|||
{
|
||||
GetBrowser().SetZoomLevel(level);
|
||||
}
|
||||
|
||||
private void BrowserControl_LoadError(object sender, LoadErrorEventArgs e)
|
||||
{
|
||||
var html = string.Copy(errorPage);
|
||||
|
||||
html = html.Replace("%%STATUS%%", $"{e.ErrorText} ({e.ErrorCode})");
|
||||
html = html.Replace("%%URL%%", e.FailedUrl);
|
||||
|
||||
e.Frame.LoadHtml(html, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,14 +8,12 @@
|
|||
|
||||
using System;
|
||||
using System.Collections.Specialized;
|
||||
using System.IO;
|
||||
using System.Net.Mime;
|
||||
using System.Reflection;
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
using CefSharp;
|
||||
using SafeExamBrowser.Browser.Contracts.Filters;
|
||||
using SafeExamBrowser.Browser.Filters;
|
||||
using SafeExamBrowser.Browser.Pages;
|
||||
using SafeExamBrowser.Configuration.Contracts;
|
||||
using SafeExamBrowser.I18n.Contracts;
|
||||
using SafeExamBrowser.Logging.Contracts;
|
||||
|
@ -32,6 +30,7 @@ namespace SafeExamBrowser.Browser.Handlers
|
|||
private string browserExamKey;
|
||||
private IResourceHandler contentHandler;
|
||||
private IRequestFilter filter;
|
||||
private HtmlLoader htmlLoader;
|
||||
private ILogger logger;
|
||||
private IResourceHandler pageHandler;
|
||||
private BrowserSettings settings;
|
||||
|
@ -42,6 +41,7 @@ namespace SafeExamBrowser.Browser.Handlers
|
|||
this.appConfig = appConfig;
|
||||
this.algorithm = new SHA256Managed();
|
||||
this.filter = filter;
|
||||
this.htmlLoader = new HtmlLoader(text);
|
||||
this.logger = logger;
|
||||
this.settings = settings;
|
||||
this.text = text;
|
||||
|
@ -186,9 +186,14 @@ namespace SafeExamBrowser.Browser.Handlers
|
|||
|
||||
private IResourceHandler ResourceHandlerFor(ResourceType resourceType)
|
||||
{
|
||||
if (contentHandler == default(IResourceHandler) || pageHandler == default(IResourceHandler))
|
||||
if (contentHandler == default(IResourceHandler))
|
||||
{
|
||||
InitializeResourceHandlers();
|
||||
contentHandler = CefSharp.ResourceHandler.FromString(htmlLoader.LoadBlockedContent());
|
||||
}
|
||||
|
||||
if (pageHandler == default(IResourceHandler))
|
||||
{
|
||||
pageHandler = CefSharp.ResourceHandler.FromString(htmlLoader.LoadBlockedPage());
|
||||
}
|
||||
|
||||
switch (resourceType)
|
||||
|
@ -200,26 +205,5 @@ namespace SafeExamBrowser.Browser.Handlers
|
|||
return contentHandler;
|
||||
}
|
||||
}
|
||||
|
||||
private void InitializeResourceHandlers()
|
||||
{
|
||||
var assembly = Assembly.GetAssembly(typeof(RequestFilter));
|
||||
var contentMessage = text.Get(TextKey.Browser_BlockedContentMessage);
|
||||
var contentStream = assembly.GetManifestResourceStream($"{typeof(RequestFilter).Namespace}.BlockedContent.html");
|
||||
var pageButton = text.Get(TextKey.Browser_BlockedPageButton);
|
||||
var pageMessage = text.Get(TextKey.Browser_BlockedPageMessage);
|
||||
var pageTitle = text.Get(TextKey.Browser_BlockedPageTitle);
|
||||
var pageStream = assembly.GetManifestResourceStream($"{typeof(RequestFilter).Namespace}.BlockedPage.html");
|
||||
var contentHtml = new StreamReader(contentStream).ReadToEnd();
|
||||
var pageHtml = new StreamReader(pageStream).ReadToEnd();
|
||||
|
||||
contentHtml = contentHtml.Replace("%%MESSAGE%%", contentMessage);
|
||||
contentHandler = CefSharp.ResourceHandler.FromString(contentHtml);
|
||||
|
||||
pageHtml = pageHtml.Replace("%%MESSAGE%%", pageMessage).Replace("%%TITLE%%", pageTitle).Replace("%%BACK_BUTTON%%", pageButton);
|
||||
pageHandler = CefSharp.ResourceHandler.FromString(pageHtml);
|
||||
|
||||
logger.Debug("Initialized resource handlers for blocked requests.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
75
SafeExamBrowser.Browser/Pages/HtmlLoader.cs
Normal file
75
SafeExamBrowser.Browser/Pages/HtmlLoader.cs
Normal file
|
@ -0,0 +1,75 @@
|
|||
/*
|
||||
* Copyright (c) 2020 ETH Zürich, Educational Development and Technology (LET)
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
using SafeExamBrowser.I18n.Contracts;
|
||||
|
||||
namespace SafeExamBrowser.Browser.Pages
|
||||
{
|
||||
internal class HtmlLoader
|
||||
{
|
||||
private IText text;
|
||||
|
||||
internal HtmlLoader(IText text)
|
||||
{
|
||||
this.text = text;
|
||||
}
|
||||
|
||||
internal string LoadBlockedContent()
|
||||
{
|
||||
var assembly = Assembly.GetAssembly(typeof(HtmlLoader));
|
||||
var path = $"{typeof(HtmlLoader).Namespace}.BlockedContent.html";
|
||||
|
||||
using (var stream = assembly.GetManifestResourceStream(path))
|
||||
using (var reader = new StreamReader(stream))
|
||||
{
|
||||
var html = reader.ReadToEnd();
|
||||
|
||||
html = html.Replace("%%MESSAGE%%", text.Get(TextKey.Browser_BlockedContentMessage));
|
||||
|
||||
return html;
|
||||
}
|
||||
}
|
||||
|
||||
internal string LoadBlockedPage()
|
||||
{
|
||||
var assembly = Assembly.GetAssembly(typeof(HtmlLoader));
|
||||
var path = $"{typeof(HtmlLoader).Namespace}.BlockedPage.html";
|
||||
|
||||
using (var stream = assembly.GetManifestResourceStream(path))
|
||||
using (var reader = new StreamReader(stream))
|
||||
{
|
||||
var html = reader.ReadToEnd();
|
||||
|
||||
html = html.Replace("%%BACK_BUTTON%%", text.Get(TextKey.Browser_BlockedPageButton));
|
||||
html = html.Replace("%%MESSAGE%%", text.Get(TextKey.Browser_BlockedPageMessage));
|
||||
html = html.Replace("%%TITLE%%", text.Get(TextKey.Browser_BlockedPageTitle));
|
||||
|
||||
return html;
|
||||
}
|
||||
}
|
||||
|
||||
internal string LoadErrorPage()
|
||||
{
|
||||
var assembly = Assembly.GetAssembly(typeof(HtmlLoader));
|
||||
var path = $"{typeof(HtmlLoader).Namespace}.LoadError.html";
|
||||
|
||||
using (var stream = assembly.GetManifestResourceStream(path))
|
||||
using (var reader = new StreamReader(stream))
|
||||
{
|
||||
var html = reader.ReadToEnd();
|
||||
|
||||
html = html.Replace("%%MESSAGE%%", text.Get(TextKey.Browser_LoadErrorPageMessage));
|
||||
html = html.Replace("%%TITLE%%", text.Get(TextKey.Browser_LoadErrorPageTitle));
|
||||
|
||||
return html;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
14
SafeExamBrowser.Browser/Pages/LoadError.html
Normal file
14
SafeExamBrowser.Browser/Pages/LoadError.html
Normal file
|
@ -0,0 +1,14 @@
|
|||
<!DOCTYPE html>
|
||||
<html style="height: 100%; width: 100%">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<title>%%TITLE%%</title>
|
||||
</head>
|
||||
<body style="background-color: lightgray; display: table; font-family: 'Segoe UI'; height: 98%; text-align: center; width: 99%">
|
||||
<div style="display: table-cell; vertical-align: middle">
|
||||
<h1 style="color: red">%%TITLE%%</h1>
|
||||
<p>%%MESSAGE%%</p>
|
||||
<p style="font-weight: bold">%%STATUS%%</p>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
|
@ -91,6 +91,7 @@
|
|||
<Compile Include="Handlers\LifeSpanHandler.cs" />
|
||||
<Compile Include="Handlers\RequestHandler.cs" />
|
||||
<Compile Include="Handlers\ResourceHandler.cs" />
|
||||
<Compile Include="Pages\HtmlLoader.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
|
@ -129,8 +130,11 @@
|
|||
</None>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<EmbeddedResource Include="Filters\BlockedContent.html" />
|
||||
<EmbeddedResource Include="Filters\BlockedPage.html" />
|
||||
<EmbeddedResource Include="Pages\BlockedContent.html" />
|
||||
<EmbeddedResource Include="Pages\BlockedPage.html" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<EmbeddedResource Include="Pages\LoadError.html" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
<PropertyGroup>
|
||||
|
|
|
@ -20,6 +20,8 @@ namespace SafeExamBrowser.I18n.Contracts
|
|||
Browser_BlockedPageButton,
|
||||
Browser_BlockedPageMessage,
|
||||
Browser_BlockedPageTitle,
|
||||
Browser_LoadErrorPageMessage,
|
||||
Browser_LoadErrorPageTitle,
|
||||
Browser_Name,
|
||||
Browser_Tooltip,
|
||||
BrowserWindow_DeveloperConsoleMenuItem,
|
||||
|
|
|
@ -18,6 +18,12 @@
|
|||
<Entry key="Browser_BlockedPageTitle">
|
||||
Seite blockiert
|
||||
</Entry>
|
||||
<Entry key="Browser_LoadErrorPageMessage">
|
||||
Beim Laden der Seite "%%URL%%" ist folgender Fehler aufgetreten:
|
||||
</Entry>
|
||||
<Entry key="Browser_LoadErrorPageTitle">
|
||||
Seiten-Ladefehler
|
||||
</Entry>
|
||||
<Entry key="Browser_Name">
|
||||
Browser
|
||||
</Entry>
|
||||
|
@ -139,7 +145,7 @@
|
|||
Automatisches Beenden fehlgeschlagen
|
||||
</Entry>
|
||||
<Entry key="MessageBox_BrowserNavigationBlocked">
|
||||
Zugriff auf "%%URL%%" is gemäss der aktiven Konfiguration nicht erlaubt.
|
||||
Zugriff auf "%%URL%%" ist gemäss der aktiven Konfiguration nicht erlaubt.
|
||||
</Entry>
|
||||
<Entry key="MessageBox_BrowserNavigationBlockedTitle">
|
||||
Seite blockiert
|
||||
|
|
|
@ -18,6 +18,12 @@
|
|||
<Entry key="Browser_BlockedPageTitle">
|
||||
Page Blocked
|
||||
</Entry>
|
||||
<Entry key="Browser_LoadErrorPageMessage">
|
||||
An error occurred while loading page "%%URL%%":
|
||||
</Entry>
|
||||
<Entry key="Browser_LoadErrorPageTitle">
|
||||
Page Load Error
|
||||
</Entry>
|
||||
<Entry key="Browser_Name">
|
||||
Browser
|
||||
</Entry>
|
||||
|
|
Loading…
Reference in a new issue