/// <summary> /// Called whenever the website loads HTML from disk. /// </summary> /// <param name="sender"></param> /// <param name="args"></param> private void WebSite_HtmlLoadedFromFile(object sender, TextContentEventArgs args) { var normalisedPathAndFile = NormaliseFullPath(args.PathAndFile); var htmlLocalisers = _HtmlLocalisers; var webAdminViewMap = _WebAdminViewMapByFullPath; var templateMarkerFileNames = _TemplateMarkerFileNames; if (htmlLocalisers != null && webAdminViewMap != null && templateMarkerFileNames != null) { WebAdminView webAdminView; if (webAdminViewMap.TryGetValue(normalisedPathAndFile, out webAdminView)) { foreach (var kvp in templateMarkerFileNames) { args.Content = ExpandTemplateMarkerFromFile(args.Content, kvp.Key, kvp.Value); } IHtmlLocaliser htmlLocaliser; if (webAdminView.StringResources != null && htmlLocalisers.TryGetValue(webAdminView.StringResources, out htmlLocaliser)) { args.Content = htmlLocaliser.Html(args.Content, args.Encoding); } args.Content = htmlLocalisers[typeof(WebAdminStrings)].Html(args.Content, args.Encoding); args.Content = htmlLocalisers[typeof(VirtualRadar.Localisation.Strings)].Html(args.Content, args.Encoding); args.Content = htmlLocalisers[typeof(VirtualRadar.WebSite.WebSiteStrings)].Html(args.Content, args.Encoding); _ViewMethodMapper.ViewRequested(webAdminView, args); } } }
/// <summary> /// Raised when the OWIN file system server is about to serve a text file. /// </summary> /// <param name="sender"></param> /// <param name="args"></param> private void FileSystemConfiguration_TextLoadedFromFile(object sender, TextContentEventArgs args) { if (args.MimeType == MimeType.Html) { OnHtmlLoadedFromFile(args); } }
public void FileSystemServer_TextLoadedFromFile_Raised_For_Supported_Mime_Types() { foreach (var kvp in new Dictionary <string, string>() { { ".css", MimeType.Css }, { ".html", MimeType.Html }, { ".js", MimeType.Javascript }, { ".txt", MimeType.Text } }) { TestCleanup(); TestInitialise(); var extension = kvp.Key; var mimeType = kvp.Value; var errorMessage = $"extension={extension}, mimeType={mimeType}"; AddSiteRootAndFile(@"c:\web\root", $"Folder/File{extension}", "Hello"); ConfigureRequest($"/Folder/File{extension}"); TextContentEventArgs args = null; _ServerConfiguration.Setup(r => r.RaiseTextLoadedFromFile(It.IsAny <TextContentEventArgs>())).Callback((TextContentEventArgs e) => { args = e; }); _Pipeline.BuildAndCallMiddleware(_Server.AppFuncBuilder, _Environment.Environment); _ServerConfiguration.Verify(r => r.RaiseTextLoadedFromFile(It.IsAny <TextContentEventArgs>()), Times.Once(), errorMessage); Assert.AreEqual($"/Folder/File{extension}", args.PathAndFile, errorMessage); Assert.AreEqual("Hello", args.Content, errorMessage); Assert.AreEqual(Encoding.UTF8.EncodingName, args.Encoding.EncodingName, errorMessage); Assert.AreEqual(mimeType, args.MimeType, errorMessage); } }
/// <summary> /// Called whenever the web site fetches an HTML file from disk. /// </summary> /// <param name="sender"></param> /// <param name="e"></param> void WebSite_HtmlLoadedFromFile(object sender, TextContentEventArgs e) { var key = e.PathAndFile.ToLower(); if(key.StartsWith("/feedfilter/")) { e.Content = _HtmlLocaliser.Html(e.Content, e.Encoding); } }
public void WebSite_HtmlLoadedFromFile_Not_Raised_For_Non_HTML_Mime_Types() { var listener = new EventRecorder <TextContentEventArgs>(); _WebSite.HtmlLoadedFromFile += listener.Handler; _WebSite.AttachSiteToServer(_WebServer.Object); var args = new TextContentEventArgs("/index.html", "The Content", Encoding.Unicode, MimeType.Css); _FileSystemServerConfiguration.Raise(r => r.TextLoadedFromFile += null, args); Assert.AreEqual(0, listener.CallCount); }
public void FileSystemConfiguration_RaiseTextLoadedFromFile_Raises_TextLoadedFromFile() { var eventRecorder = new EventRecorder <TextContentEventArgs>(); _Configuration.TextLoadedFromFile += eventRecorder.Handler; var args = new TextContentEventArgs(null, null, null, null); _Configuration.RaiseTextLoadedFromFile(args); Assert.AreEqual(1, eventRecorder.CallCount); Assert.AreSame(_Configuration, eventRecorder.Sender); Assert.AreSame(args, eventRecorder.Args); }
public void FileSystemServer_TextLoadedFromFile_Not_Raised_For_Other_Mime_Types() { AddSiteRootAndFile(@"c:\web\root", "Folder/File.ts", "Hello"); ConfigureRequest($"/Folder/File.ts"); TextContentEventArgs args = null; _ServerConfiguration.Setup(r => r.RaiseTextLoadedFromFile(It.IsAny <TextContentEventArgs>())).Callback((TextContentEventArgs e) => { args = e; }); _Pipeline.BuildAndCallMiddleware(_Server.AppFuncBuilder, _Environment.Environment); _ServerConfiguration.Verify(r => r.RaiseTextLoadedFromFile(It.IsAny <TextContentEventArgs>()), Times.Never()); }
public void WebSite_HtmlLoadedFromFile_Raised_When_OWIN_FileSystemConfiguration_Raises_TextLoadedFromFile() { var listener = new EventRecorder <TextContentEventArgs>(); _WebSite.HtmlLoadedFromFile += listener.Handler; _WebSite.AttachSiteToServer(_WebServer.Object); var args = new TextContentEventArgs("/index.html", "The Content", Encoding.Unicode, MimeType.Html); _FileSystemServerConfiguration.Raise(r => r.TextLoadedFromFile += null, args); Assert.AreEqual(1, listener.CallCount); Assert.AreSame(_WebSite, listener.Sender); Assert.AreSame(args, listener.Args); }
/// <summary> /// Records a request for a <see cref="WebAdminView"/>. /// </summary> /// <param name="webAdminView"></param> /// <param name="args"></param> public void ViewRequested(WebAdminView webAdminView, TextContentEventArgs args) { lock (_SyncLock) { var pathAndFileWithoutExtension = RemoveExtension(webAdminView.PathAndFile); var key = NormaliseString(pathAndFileWithoutExtension); var isMultiInstance = args.Content.Contains(ViewIdMarker); if (!isMultiInstance) { StartSingleViewInstance(webAdminView, key); } else { var viewId = StartMultiViewInstance(webAdminView, key, args); args.Content = args.Content.Replace(ViewIdMarker, viewId); } } }
public void FileSystemServer_TextLoadedFromFile_Reports_Encoding_Correctly() { var content = "£1.23"; var bytes = Encoding.UTF32.GetPreamble().Concat(Encoding.UTF32.GetBytes(content)).ToArray(); AddSiteRootAndFile(@"c:\web\root", "Folder/File.html", bytes); ConfigureRequest("/Folder/File.html"); TextContentEventArgs args = null; _ServerConfiguration.Setup(r => r.RaiseTextLoadedFromFile(It.IsAny <TextContentEventArgs>())).Callback((TextContentEventArgs e) => { args = e; }); _Pipeline.BuildAndCallMiddleware(_Server.AppFuncBuilder, _Environment.Environment); _ServerConfiguration.Verify(r => r.RaiseTextLoadedFromFile(It.IsAny <TextContentEventArgs>()), Times.Once()); Assert.AreEqual("/Folder/File.html", args.PathAndFile); Assert.AreEqual("£1.23", args.Content); Assert.AreEqual(Encoding.UTF32.EncodingName, args.Encoding.EncodingName); Assert.AreEqual(MimeType.Html, args.MimeType); }
/// <summary> /// Raises the TextLoadedFromFile event on the singleton configuration object if the mime type indicates /// that it's a recognised text file. /// </summary> /// <param name="request"></param> /// <param name="content"></param> /// <param name="mimeType"></param> /// <returns></returns> private byte[] RaiseTextLoadedFromFile(PipelineRequest request, byte[] content, string mimeType) { if (mimeType == MimeType.Css || mimeType == MimeType.Html || mimeType == MimeType.Javascript || mimeType == MimeType.Text) { var textContent = TextContent.Load(content); var args = new TextContentEventArgs( request.FlattenedPath, textContent.Content, textContent.Encoding, mimeType ); _Configuration.RaiseTextLoadedFromFile(args); textContent.Content = args.Content; content = textContent.GetBytes(includePreamble: true); } return(content); }
private string StartMultiViewInstance(WebAdminView webAdminView, string key, TextContentEventArgs args) { Dictionary <string, MappedView> runningInstances; if (!_MultiViewInstances.TryGetValue(key, out runningInstances)) { runningInstances = new Dictionary <string, MappedView>(); } string viewId; do { viewId = Guid.NewGuid().ToString(); } while(runningInstances.ContainsKey(viewId)); MappedView mappedView = CreateView(webAdminView); mappedView.ViewId = viewId; var newInnerMap = CollectionHelper.ShallowCopy(runningInstances); newInnerMap.Add(viewId, mappedView); var newOuterMap = CollectionHelper.ShallowCopy(_MultiViewInstances); if (newOuterMap.ContainsKey(key)) { newOuterMap[key] = newInnerMap; } else { newOuterMap.Add(key, newInnerMap); } _MultiViewInstances = newOuterMap; return(viewId); }
/// <summary> /// Raises <see cref="HtmlLoadedFromFile"/>. /// </summary> /// <param name="args"></param> internal void OnHtmlLoadedFromFile(TextContentEventArgs args) { EventHelper.RaiseQuickly(HtmlLoadedFromFile, this, args); }
/// <summary> /// See base class docs. /// </summary> /// <param name="server"></param> /// <param name="args"></param> /// <returns></returns> protected override bool DoHandleRequest(IWebServer server, RequestReceivedEventArgs args) { var requestFile = GetRequestFile(args.PathParts, args.File); var result = requestFile != null && !String.IsNullOrEmpty(requestFile.FileName) && File.Exists(requestFile.FileName); if(result) { var normalisedRequestPath = NormaliseRequestPath(args.PathAndFile); var extension = Path.GetExtension(requestFile.FileName); var isProtected = requestFile.Root.IsProtectedContent; var checksumEntry = isProtected ? requestFile.Root.FindChecksum(normalisedRequestPath, requestPathIsNormalised: true) : null; result = !isProtected || checksumEntry != null; if(result) { var isHtml = ".html".Equals(extension, StringComparison.OrdinalIgnoreCase) || ".htm".Equals(extension, StringComparison.OrdinalIgnoreCase); if(isProtected && !requestFile.Root.TestChecksum(checksumEntry, requestFile.FileName)) { Factory.Singleton.Resolve<ILog>().Singleton.WriteLine("Will not serve {0}, it has failed the checksum test", args.PathAndFile); if(!isHtml) { args.Response.StatusCode = HttpStatusCode.BadRequest; } else { Responder.SendText(args.Request, args.Response, "<HTML><HEAD><TITLE>No</TITLE></HEAD><BODY>VRS will not serve content that has been tampered with. Install the custom content plugin if you want to alter the site's files.</BODY></HTML>", Encoding.UTF8, MimeType.Html); args.Classification = ContentClassification.Html; } } else { if(isHtml) { ModifyAndSendContent(args, requestFile.FileName, extension, r => { var textContentArgs = new TextContentEventArgs(args.Request, args.PathAndFile, r.Content, r.Encoding); _WebSite.OnHtmlLoadedFromFile(textContentArgs); r.Content = textContentArgs.Content; _WebSite.InjectHtmlContent(args.PathAndFile, r); _WebSite.BundleHtml(args.PathAndFile, r); }); } else if(".js".Equals(extension, StringComparison.OrdinalIgnoreCase)) { ModifyAndSendContent(args, requestFile.FileName, extension, r => { _WebSite.InjectIntoJavaScript(args.PathAndFile, r); _WebSite.MinifyJavaScript(r); }); } else if(".css".Equals(extension, StringComparison.OrdinalIgnoreCase)) { ModifyAndSendContent(args, requestFile.FileName, extension, r => { _WebSite.MinifyCss(r); }); } else { args.Response.MimeType = MimeType.GetForExtension(extension); var enableCompression = true; if(args.Response.MimeType == MimeType.IconImage) enableCompression = false; else if(args.Response.MimeType.StartsWith("image/")) enableCompression = false; if(enableCompression) args.Response.EnableCompression(args.Request); args.Response.ContentLength = new FileInfo(requestFile.FileName).Length; args.Classification = MimeType.GetContentClassification(args.Response.MimeType); args.Response.StatusCode = HttpStatusCode.OK; using(var fileStream = new FileStream(requestFile.FileName, FileMode.Open, FileAccess.Read)) { StreamHelper.CopyStream(fileStream, args.Response.OutputStream, 4096); } } } } } return result; }
/// <summary> /// See interface docs. /// </summary> /// <param name="args"></param> public void RaiseTextLoadedFromFile(TextContentEventArgs args) { EventHelper.Raise(TextLoadedFromFile, this, () => args); }