<commit_before>﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Text;
using System.Threading.Tasks;
using Metrics.Reports;
using Metrics.Visualization;

namespace Owin.Metrics.Middleware
{
    using AppFunc = Func<IDictionary<string, object>, Task>;

    public class MetricsEndpointMiddleware
    {
        private readonly string endpointPrefix;
        private readonly OwinMetricsEndpointHandler endpointHandler;
        private AppFunc next;

        public MetricsEndpointMiddleware(string endpointPrefix, MetricsEndpointReports endpointConfig)
        {
            this.endpointPrefix = endpointPrefix.Trim('/');
            this.endpointHandler = new OwinMetricsEndpointHandler(endpointConfig.Endpoints);
        }

        public void Initialize(AppFunc next)
        {
            this.next = next;
        }

        public Task Invoke(IDictionary<string, object> environment)
        {
            var requestPath = environment["owin.RequestPath"] as string;
            var prefix = $"/{this.endpointPrefix}";
            if (requestPath.StartsWith(prefix, StringComparison.OrdinalIgnoreCase))
            {
                requestPath = requestPath.Substring(prefix.Length);

                if (requestPath == "/")
                {
                    return GetFlotWebApp(environment);
                }

                var response = this.endpointHandler.Process(requestPath, environment);
                if (response != null)
                {
                    return WriteResponse(response, environment);
                }
            }

            return this.next(environment);
        }

        private static Task GetFlotWebApp(IDictionary<string, object> environment)
        {
            var content = FlotWebApp.GetFlotApp();
            return WriteResponse(environment, content, "application/json");
        }

        private static async Task WriteResponse(IDictionary<string, object> environment, string content, string contentType, HttpStatusCode code = HttpStatusCode.OK)
        {
            var response = environment["owin.ResponseBody"] as Stream;
            var headers = environment["owin.ResponseHeaders"] as IDictionary<string, string[]>;

            var contentBytes = Encoding.UTF8.GetBytes(content);

            headers["ContentType"] = new[] { contentType };
            headers["Cache-Control"] = new[] { "no-cache, no-store, must-revalidate" };
            headers["Pragma"] = new[] { "no-cache" };
            headers["Expires"] = new[] { "0" };

            environment["owin.ResponseStatusCode"] = (int)code;

            await response.WriteAsync(contentBytes, 0, contentBytes.Length);
        }

        private static async Task WriteResponse(MetricsEndpointResponse response, IDictionary<string, object> environment)
        {
            var responseStream = environment["owin.ResponseBody"] as Stream;
            var headers = environment["owin.ResponseHeaders"] as IDictionary<string, string[]>;

            var contentBytes = Encoding.UTF8.GetBytes(response.Content);

            headers["ContentType"] = new[] { response.ContentType };
            headers["Cache-Control"] = new[] { "no-cache, no-store, must-revalidate" };
            headers["Pragma"] = new[] { "no-cache" };
            headers["Expires"] = new[] { "0" };

            environment["owin.ResponseStatusCode"] = (int)response.StatusCode;

            await responseStream.WriteAsync(contentBytes, 0, contentBytes.Length);
        }
    }
}<commit_msg>Fixed owin endpoint response encoding<commit_after>﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Text;
using System.Threading.Tasks;
using Metrics.Reports;
using Metrics.Visualization;

namespace Owin.Metrics.Middleware
{
    using AppFunc = Func<IDictionary<string, object>, Task>;

    public class MetricsEndpointMiddleware
    {
        private readonly string endpointPrefix;
        private readonly OwinMetricsEndpointHandler endpointHandler;
        private AppFunc next;

        public MetricsEndpointMiddleware(string endpointPrefix, MetricsEndpointReports endpointConfig)
        {
            this.endpointPrefix = endpointPrefix.Trim('/');
            this.endpointHandler = new OwinMetricsEndpointHandler(endpointConfig.Endpoints);
        }

        public void Initialize(AppFunc next)
        {
            this.next = next;
        }

        public Task Invoke(IDictionary<string, object> environment)
        {
            var requestPath = environment["owin.RequestPath"] as string;
            var prefix = $"/{this.endpointPrefix}";
            if (requestPath.StartsWith(prefix, StringComparison.OrdinalIgnoreCase))
            {
                requestPath = requestPath.Substring(prefix.Length);

                if (requestPath == "/")
                {
                    return GetFlotWebApp(environment);
                }

                var response = this.endpointHandler.Process(requestPath, environment);
                if (response != null)
                {
                    return WriteResponse(response, environment);
                }
            }

            return this.next(environment);
        }

        private static Task GetFlotWebApp(IDictionary<string, object> environment)
        {
            var content = FlotWebApp.GetFlotApp();
            return WriteResponse(environment, content, "application/json");
        }

        private static async Task WriteResponse(IDictionary<string, object> environment, string content, string contentType, HttpStatusCode code = HttpStatusCode.OK)
        {
            var response = environment["owin.ResponseBody"] as Stream;
            var headers = environment["owin.ResponseHeaders"] as IDictionary<string, string[]>;

            var contentBytes = Encoding.UTF8.GetBytes(content);

            headers["ContentType"] = new[] { contentType };
            headers["Cache-Control"] = new[] { "no-cache, no-store, must-revalidate" };
            headers["Pragma"] = new[] { "no-cache" };
            headers["Expires"] = new[] { "0" };

            environment["owin.ResponseStatusCode"] = (int)code;

            await response.WriteAsync(contentBytes, 0, contentBytes.Length);
        }

        private static async Task WriteResponse(MetricsEndpointResponse response, IDictionary<string, object> environment)
        {
            var responseStream = environment["owin.ResponseBody"] as Stream;
            var headers = environment["owin.ResponseHeaders"] as IDictionary<string, string[]>;

            var contentBytes = response.Encoding.GetBytes(response.Content);

            headers["ContentType"] = new[] { response.ContentType };
            headers["Cache-Control"] = new[] { "no-cache, no-store, must-revalidate" };
            headers["Pragma"] = new[] { "no-cache" };
            headers["Expires"] = new[] { "0" };

            environment["owin.ResponseStatusCode"] = (int)response.StatusCode;

            await responseStream.WriteAsync(contentBytes, 0, contentBytes.Length);
        }
    }
}
{'fraction_non_alphanumeric': 0.10317683441102052, 'fraction_numerical': 0.0015462468372223785, 'mean_word_length': 2.432223830197781, 'pattern_counts': {'":': 0, '<': 19, '<?xml version=': 0, '>': 19, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7391438', 'n_tokens_mistral': 1754, 'n_tokens_neox': 1714, 'n_words': 386}