Example #1
0
    public async override Task Invoke(IOwinContext context)
    {
        //to intercept MVC responses, because they don't go through OWIN
        HttpResponse        httpResponse  = HttpContext.Current.Response;
        OutputCaptureStream outputCapture = new OutputCaptureStream(httpResponse.Filter);

        httpResponse.Filter = outputCapture;

        IOwinResponse owinResponse = context.Response;
        //buffer the response stream in order to intercept downstream writes
        Stream owinResponseStream = owinResponse.Body;

        owinResponse.Body = new MemoryStream();
        await Next.Invoke(context);

        if (outputCapture.CapturedData.Length == 0)
        {
            //response is formed by OWIN
            //make sure the response we buffered is flushed to the client
            owinResponse.Body.Position = 0;
            await owinResponse.Body.CopyToAsync(owinResponseStream);
        }
        else
        {
            //response by MVC
            //write captured data to response body as if it was written by OWIN
            outputCapture.CapturedData.Position = 0;
            outputCapture.CapturedData.CopyTo(owinResponse.Body);
        }

        LogResponse(owinResponse);
    }
Example #2
0
        public override async Task Invoke(IOwinContext context)
        {
            HttpResponse        httpResponse  = HttpContext.Current.Response;
            OutputCaptureStream outputCapture = new OutputCaptureStream(httpResponse.Filter);

            httpResponse.Filter = outputCapture;

            IOwinResponse owinResponse = context.Response;
            //buffer the response stream in order to intercept downstream writes
            Stream owinResponseStream = owinResponse.Body;

            owinResponse.Body = new MemoryStream();

            //开始记录
            var requestLog = new ApiRequest();

            HttpContext.Current.Items["api_request"] = requestLog;
            requestLog.Headers     = context.Request.Headers;
            requestLog.URI         = context.Request.Path.ToString();
            requestLog.QueryString = context.Request.QueryString.HasValue ? context.Request.QueryString.Value : "";


            using (var sr = new StreamReader(context.Request.Body))
            {
                requestLog.RequestParams = sr.ReadToEnd();
            }
            requestLog.Method = context.Request.Method;

            var wathch = new Stopwatch();

            wathch.Start();
            await Next.Invoke(context);

            if (outputCapture.CapturedData.Length == 0)
            {
                //response is formed by OWIN
                //make sure the response we buffered is flushed to the client
                owinResponse.Body.Position = 0;
                await owinResponse.Body.CopyToAsync(owinResponseStream);
            }
            else
            {
                //response by MVC
                //write captured data to response body as if it was written by OWIN
                outputCapture.CapturedData.Position = 0;
                outputCapture.CapturedData.CopyTo(owinResponse.Body);
            }
            byte[] b = ((MemoryStream)owinResponse.Body).ToArray();

            requestLog.Result = System.Text.Encoding.UTF8.GetString(b, 0, b.Length);
            requestLog.Status = context.Response.StatusCode;
            wathch.Stop();
            requestLog.ElapsedTime = wathch.Elapsed.TotalMilliseconds;

            Log(requestLog);
        }
        public async override Task Invoke(IOwinContext context)
        {
            using (var stream = context.Response.Body)

            {
                using (var buffer = new MemoryStream())
                {
                    context.Response.Body = buffer;

                    HttpResponse httpResponse = HttpContext.Current.Response;

                    OutputCaptureStream outputCapture = new OutputCaptureStream(httpResponse.Filter);

                    httpResponse.Filter = outputCapture;

                    if (_options.Script.UseNonce || _options.Style.UseNonce)
                    {
                        _options.Nonce = createNonce();
                        context.Set <string>(_options.Nonce, "ScriptNonce");
                    }

                    addCspHeaders(context, _options);

                    await Next.Invoke(context);

                    string currentNonce = _options.Nonce;

                    var isHtml = context.Response.ContentType?.ToLower().Contains("text/html");
                    if (context.Response.StatusCode == 200 && isHtml.GetValueOrDefault())
                    {
                        var capturedStream = outputCapture.CapturedData;

                        capturedStream.Seek(0, SeekOrigin.Begin);

                        using (var reader = new StreamReader(capturedStream))
                        {
                            string responseBody = await reader.ReadToEndAsync();

                            if (responseBody != "")
                            {
                                string domSelector;

                                HtmlDocument responsePage = new HtmlDocument();

                                capturedStream.Seek(0, SeekOrigin.Begin);

                                responsePage.Load(capturedStream);

                                domSelector = "//*[@data-nonceSecret]";

                                if (_options.Script.UseNonce)
                                {
                                    domSelector += " | //script";
                                }

                                if (_options.Style.UseNonce)
                                {
                                    domSelector += " | //style | //link[@as='style'] | //link[@rel='stylesheet']";
                                }

                                HtmlNodeCollection nodeCollection = responsePage.DocumentNode.SelectNodes(domSelector);

                                if (nodeCollection != null)
                                {
                                    foreach (HtmlNode currentNode in nodeCollection)
                                    {
                                        if (_options.NonceSecret != null)
                                        {
                                            if (currentNode.GetAttributeValue("data-nonceSecret", null) == _options.NonceSecret)
                                            {
                                                if (_options.Script.UseNonce)
                                                {
                                                    if (currentNode.Name == "script")
                                                    {
                                                        currentNode.SetAttributeValue("nonce", currentNonce);
                                                    }
                                                }
                                                if (_options.Style.UseNonce)
                                                {
                                                    if (currentNode.Name == "link" || currentNode.Name == "style")
                                                    {
                                                        currentNode.SetAttributeValue("nonce", currentNonce);
                                                    }
                                                }
                                            }
                                        }
                                        else
                                        {
                                            if (_options.Script.UseNonce)
                                            {
                                                if (currentNode.Name == "script")
                                                {
                                                    currentNode.SetAttributeValue("nonce", currentNonce);
                                                }
                                            }
                                            if (_options.Style.UseNonce)
                                            {
                                                if (currentNode.Name == "link" || currentNode.Name == "style")
                                                {
                                                    currentNode.SetAttributeValue("nonce", currentNonce);
                                                }
                                            }
                                        }

                                        if (currentNode.Attributes.Contains("data-nonceSecret"))
                                        {
                                            currentNode.Attributes["data-nonceSecret"].Remove();
                                        }
                                    }
                                }

                                MemoryStream newOutputStream = new MemoryStream();

                                httpResponse.Clear();

                                responsePage.Save(newOutputStream);

                                newOutputStream.Seek(0, SeekOrigin.Begin);

                                newOutputStream.CopyTo(stream);
                            }
                        }
                    }
                }
            }
        }