Example #1
0
 public BodyStatistics(BodyStatistics statistics)
 {
     this.Minimum = statistics.Minimum;
     this.Maximum = statistics.Maximum;
     this.Average = statistics.Average;
     this.Total   = statistics.Total;
     this.Count   = statistics.Count;
 }
Example #2
0
        public async Task InvokeAsync(HttpContext context, RequestDelegate next)
        {
            // Record start time of request.
            var startTime = DateTime.Now;

            // Save a reference to the original body of the response.
            var originalBody = context.Response.Body;

            try
            {
                // Need to change response body to a stream that has a length.
                using (var memoryStream = new MemoryStream())
                {
                    // Swap the response body with a MemoryStream, which can read and seek.
                    context.Response.Body = memoryStream;

                    // Send request down pipeline.
                    await next(context);

                    // Get the content type of the response to determine encoding.
                    var contentType = new ContentType(context.Response.ContentType);

                    context.Response.Body.SeekToBegining();

                    BodyStatistics requestBodyStatistics;

                    lock (lockObj)
                    {
                        // Add the request data to the statistics data.
                        this.bodyStatistics.AddRequest(context.Response.Body.Length);

                        // Create a new variable with a copy of the body statistics for thread safety.
                        requestBodyStatistics = new BodyStatistics(this.bodyStatistics);
                    }

                    // Calculate the length of time the request took.
                    var interval = DateTime.Now - startTime;

                    // Write the gathered information to any HTML page.
                    await WriteContent(memoryStream, contentType, requestBodyStatistics, interval);

                    // Copy the data in the local MemoryStream to the original body.
                    await memoryStream.CopyToAsync(originalBody);
                }
            }
            finally
            {
                // Set the reference to the original body in the response object so it gets returned to the client.
                context.Response.Body = originalBody;
            }
        }
Example #3
0
        private static async Task WriteContent(Stream stream, ContentType contentType, BodyStatistics bodyStatistics, TimeSpan interval)
        {
            // Only inject the gathered information into HTML pages.
            if (contentType.MediaType == "text/html")
            {
                // Get an encoding object for use later.
                var encoding = Encoding.GetEncoding(contentType.CharSet);

                stream.SeekToBegining();

                // Construct the HTML to be injected.
                var content = $"Time: {interval.TotalMilliseconds} ms<br/ >Body length minimum: {bodyStatistics.Minimum}<br/ >Body length maximum: {bodyStatistics.Maximum}<br/ >Body length average: {bodyStatistics.Average}";

                // Parse the HTML that is to be returned to the client.
                var parser   = new HtmlParser();
                var document = await parser.ParseDocumentAsync(stream);

                // Create a new HTML div element to hold the injected informatin.
                var div = document.CreateElement("div");
                div.InnerHtml = content;

                // Add the new HTML div to the document.
                document.Body.Prepend(div);

                stream.SeekToBegining();

                // Truncate the stream that will be sent to the client so as to not return anything that shouldn't.
                stream.SetLength(0);

                // Write the HTML with the injected information to the response stream.
                using (var writer = new StreamWriter(stream, encoding, 4096, true))
                {
                    await writer.WriteAsync(document.DocumentElement.OuterHtml);
                }

                stream.SeekToBegining();
            }
        }