示例#1
0
        /// <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);
            }
        }
示例#2
0
        /// <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);
                }
            }
        }
示例#3
0
        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));
        }
示例#4
0
        /// <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);
            }
        }
示例#5
0
        /// <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),
                });
            }
        }
示例#6
0
        /// <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;
        }