/// <summary> /// Raises events that used to occur after a request had been processed. /// </summary> /// <param name="context"></param> /// <param name="requestArgs"></param> /// <param name="startTime"></param> private void RaiseRequestCompletedEvents(Context context, RequestReceivedEventArgs requestArgs, DateTime startTime) { var requestReceivedEventArgsId = requestArgs.UniqueId; try { var request = context.Request; var response = context.Response; var fullClientAddress = String.Format("{0}:{1}", requestArgs.ClientAddress, request.RemoteEndPoint.Port); var responseArgs = new ResponseSentEventArgs( requestArgs.PathAndFile, fullClientAddress, requestArgs.ClientAddress, response.ContentLength, MimeType.GetContentClassification(response.MimeType), request, (int)response.StatusCode, (int)(WebServer.Provider.UtcNow - startTime).TotalMilliseconds, context.BasicUserName ); WebServer.OnResponseSent(responseArgs); } catch (Exception ex) { // The HttpListener version doesn't log these as there can be lot of them, but given that // this stuff is all brand new I think I'd like to see what exceptions are being thrown // during processing. var log = Factory.ResolveSingleton <ILog>(); log.WriteLine("Caught exception in general request handling event handlers: {0}", ex); } }
/// <summary> /// Processes the request for the content of a bundle. /// </summary> /// <param name="args"></param> private void HandleRequestForBundle(RequestReceivedEventArgs args) { List <string> bundlePathsAndFiles; lock (_SyncLock) _BundleToRequestFileNameMap.TryGetValue(args.File.ToLower(), out bundlePathsAndFiles); if (bundlePathsAndFiles != null) { var bundle = GetUtf8Content(bundlePathsAndFiles); var content = Encoding.UTF8.GetBytes(bundle); var preamble = Encoding.UTF8.GetPreamble(); args.Handled = true; args.Response.EnableCompression(args.Request); args.Response.StatusCode = HttpStatusCode.OK; args.Response.MimeType = MimeType.GetForExtension(Path.GetExtension(args.PathAndFile)); args.Response.ContentEncoding = Encoding.UTF8; args.Classification = MimeType.GetContentClassification(args.Response.MimeType); args.Response.ContentLength = content.LongLength + preamble.LongLength; using (var memoryStream = new MemoryStream(preamble)) { StreamHelper.CopyStream(memoryStream, args.Response.OutputStream, 10); } using (var memoryStream = new MemoryStream(content)) { StreamHelper.CopyStream(memoryStream, args.Response.OutputStream, 4096); } } }
public void MimeType_GetContentClassification_Returns_Correct_Content_Classification_For_Mime_Type() { var worksheet = new ExcelWorksheetData(TestContext); var mimeType = worksheet.EString("MimeType"); var classification = worksheet.ParseEnum <ContentClassification>("Classification"); Assert.AreEqual(classification, MimeType.GetContentClassification(mimeType)); }
/// <summary> /// Reads the content of the text file passed across, modifies it and then sends it back to the browser. /// </summary> /// <param name="args"></param> /// <param name="fileName"></param> /// <param name="extension"></param> /// <param name="modifyContent"></param> private void ModifyAndSendContent(RequestReceivedEventArgs args, string fileName, string extension, Action<TextContent> modifyContent) { var textContent = LoadTextFileWithBom(fileName); modifyContent(textContent); var bytes = textContent.GetBytes(); args.Response.EnableCompression(args.Request); args.Response.ContentLength = bytes.Length; args.Response.MimeType = MimeType.GetForExtension(extension); args.Classification = MimeType.GetContentClassification(args.Response.MimeType); args.Response.StatusCode = HttpStatusCode.OK; using(var stream = new MemoryStream(bytes)) { StreamHelper.CopyStream(stream, args.Response.OutputStream); } }
/// <summary> /// Raises events that used to occur after a request had been processed. /// </summary> /// <param name="context"></param> /// <param name="requestArgs"></param> /// <param name="startTime"></param> private void RaiseRequestCompletedEvents(Context context, RequestReceivedEventArgs requestArgs, DateTime startTime) { var requestReceivedEventArgsId = requestArgs.UniqueId; try { var request = context.Request; var response = context.Response; var fullClientAddress = String.Format("{0}:{1}", requestArgs.ClientAddress, request.RemoteEndPoint.Port); var responseArgs = new ResponseSentEventArgs( requestArgs.PathAndFile, fullClientAddress, requestArgs.ClientAddress, response.ContentLength, MimeType.GetContentClassification(response.MimeType), request, (int)response.StatusCode, (int)(WebServer.Provider.UtcNow - startTime).TotalMilliseconds, context.BasicUserName ); WebServer.OnResponseSent(responseArgs); } catch (Exception ex) { // The HttpListener version doesn't log these as there can be lot of them, but given that // this stuff is all brand new I think I'd like to see what exceptions are being thrown // during processing. var log = Factory.ResolveSingleton <ILog>(); log.WriteLine("Caught exception in general request handling event handlers: {0}", ex); } // The request finished event has to be raised after the response has been sent. This is // a bit tricky with OWIN because we don't know when the response has finished. So we're // just going to wait a couple of seconds on a background thread, raise the event and // hope for the best. In practise the event is used by web admin views to do things that // might reset the connection, they're not common. lock (_SyncLock) { _FinishedWebRequests.AddLast(new FinishedWebRequest() { RequestId = requestArgs.UniqueId, RaiseEventTimeUtc = DateTime.UtcNow.AddSeconds(2), }); } }
/// <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; }