Giter VIP home page Giter VIP logo

courtesyflush's Introduction

CourtesyFlush

A library to simplify flushing HTTP responses early in ASP.NET MVC.

CourtesyFlush

Installation

CourtesyFlush can be installed via NuGet:

Install-Package CourtesyFlush

Why Flush Early?

Flushing early can provide performance improvements in web applications and has been a recomended best practice in the web performance community since 2007.

To find out more, check out my blog where I covered the benefits of flushing early in two posts:

Usage

CourtesyFlush is easy to use. It builds on top of common ASP.NET MVC Action Filter functionality.

A full writeup of how to use CourtesyFlush is availble on my blog.

Release Notes

1.1

  • Added support for AntiForgeryTokens. Example usage:

    // The "GET" action that includes the token...
    [HttpGet, FlushHead(Title = "Flushed Title", FlushAntiForgeryToken = true)]
    public ActionResult Register()
    {
        return View();
        // Inside this view, call @Html.FlushedAntiForgeryToken() instead of @Html.AntiForgeryToken()
    }
    
    // The "POST" action with standard ValidateAntiForgeryToke attribute 
    [HttpPost, ValidateAntiForgeryToken]
    public ActionResult Register(string username, string password)
    {
        // handle valid request here
    }

    NOTE: AntiForgeryToken support only available in .NET 4.5

1.0

  • Re-branded from PerfMatters.Flush to CourtesyFlush

courtesyflush's People

Contributors

drayfar avatar nikmd23 avatar simonpucher avatar thomas-j-moffett avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

courtesyflush's Issues

Title attribute from resx file

Hi there
Would it be possible to create TitleResourceType=(typeof(Type)) and TitleResouceName="[string]" properties in the attribute, much like DataAnnotations so that we could pull the Title attribute from resource files?
Thanks
Ryan

Implementation of Flush Globally

I want to implement Flush in my whole project. But as I am working on nopCommerce based web application I am little bit confused How can I implement it because it does not contain any _Lauout.cshtml page as you have mentioned in your document that I need to write @Html.FlushHead() in _Lauout.cshtml page.

Can you please help me with this?

Thanks, Ankita

Invoking FlushHead from controller outputs GUID, works in _Layout

I tried using CourtesyFlush.
@Html.FlushHead() works fine, as does getting a HtmlHelper instance in the controller and invoking .Partial(โ€ฆ) there.
But when I try to use FlushHead() in a controller action, the flushing works fine but instead of the content, it renders (a seemingly random) GUID (or Hash) string.

.NET 4.5.1, MVC5

Any advice?

edit: If it's relevant, the controller and views are inside an area.

Antiforgery validation broken on browser Back Button

Nik,

First of all great work! I wanted to write something like you did but stumbled on your code and was pretty impressed!

I have been having an issue though whenever I hit back button with CortesyFlush. It seems to generate a new AntiForgeryCookie for every request causing the Antiforgery token validation to fail when the user hits the back button. I looked into the source code and identified the problem in WriteForgeryToken method, specifically the following line.

AntiForgery.GetTokens(null, out cookieToken, out formToken);

The method passes null for oldCookieToken causing the framework to create AntiForgeryCookie for every request. This will break ValidateAntiForgeryToken if the user hits back button and posts data back. The validation will fail because the cookie and form value do not match.

Is there any reason behind passing null for old token value in the above method?

I was able to fix the issue by making following code change in WriteForgeryToken method. Please let me know what you think. Btw, i am using .NET 4.5 version.

private static void WriteForgeryToken(ControllerBase controller)
{
            string cookieToken, formToken;
            var context = controller.ControllerContext.HttpContext;
            var response = context.Response;
            string oldCookieTokenValue = null;
            string antiForgeryCookieName = AntiForgeryConfig.CookieName;
            HttpCookie cookie = context.Request.Cookies[antiForgeryCookieName];
            ///If the AF cookie is present, do not override cookie. Just use to create form token
            if(cookie != null && !String.IsNullOrEmpty(cookie.Value))
            {
                oldCookieTokenValue = cookie.Value;
                AntiForgery.GetTokens(oldCookieTokenValue, out cookieToken, out formToken);            
            }
            else
            {
               //If AF cookie is not present create a new one
                AntiForgery.GetTokens(null, out cookieToken, out formToken);                
                response.Cookies.Set(new HttpCookie(AntiForgeryConfig.CookieName, cookieToken) { HttpOnly = true });
            }
            
            context.Items[FlushedAntiForgeryTokenKey] = formToken;

            if (AntiForgeryConfig.RequireSsl && !context.Request.IsSecureConnection)
            {
                throw new  InvalidOperationException("WebPageResources.AntiForgeryWorker_RequireSSL");
                    //TODO: Find string message
            }
          

            if (!AntiForgeryConfig.SuppressXFrameOptionsHeader)
            {
                // Adding X-Frame-Options header to prevent ClickJacking. See
                // http://tools.ietf.org/html/draft-ietf-websec-x-frame-options-10
                // for more information.
                response.AddHeader("X-Frame-Options", "SAMEORIGIN");
            }
 }

Lost chunks on Azure

Hi,

I do not know where is the problem, but I am occasionally getting page loaded with only header on Azure websites (https with gzip). It seems as the first chunk with head arrives but that's it. After one or two reloads everything works fine and is not reproducible. Any ideas?

Oh, btw. I am posting without ending tag. It seems most browsers still preload styles, but I have an option to inject other styles on the fly.

AntiForgeryToken is broken - cannot append header after HTTP headers have been sent

Using FlushHead() and Html.AntiForgeryToken() gives an error.

Server cannot append header after HTTP headers have been sent.

Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.

Exception Details: System.Web.HttpException: Server cannot append header after HTTP headers have been sent.

Source Error:

Line 5:      using (Html.BeginForm("LogOff", "Account", new {area = ""}, FormMethod.Post, new {id = "logoutForm", @class = "navbar-right"}))
Line 6:      {
Line 7:          @Html.AntiForgeryToken()
Line 8:  
Line 9:          <ul class="nav navbar-nav navbar-right">

Fall back to AntiForgeryToken if FlushedAntiForgeryToken does not exist

Hey @nikmd23 - really liking this package, thanks for the hard work! I have some partial views in my solution which are sometimes rendered inline on a page (and thus have the head flushed), and are sometimes rendered outside of a page via AJAX (and thus do not have the head flushed). Because of this, I need to use the FlushedAntiForgeryToken only some of the time. Do you see any problem with updating the code to fall back to AntiForgeryToken if FlushedAntiForgeryToken is not present?

I tested this with the following additional extension in my code:

    public static MvcHtmlString FallbackAntiForgeryToken(this HtmlHelper html)
        {
            var token = html.ViewContext.HttpContext.Items["_FlushedAntiForgeryToken"] as string;
            if (!string.IsNullOrEmpty(token))
            {
                return html.FlushedAntiForgeryToken();
            }

            return html.AntiForgeryToken();
        }

I'm happy to submit a pull request if you don't see an issue with this. Thanks!

Add Committers

Hi @justinvp & @simonpucher,

You guys have both submitted great pull requests (#7 & #9, respectively), but I've been too busy to review them and pull them in.

I apologize for that.

I don't see myself slowing down anytime soon, so I'd like to propose adding both of you as committers to this repository. You could review each others pull requests and help get them accepted.

If you'd like to continue to work on CourtesyFlush after that, then great, but you don't have to. I can help get a release out, or give you permissions to push to NuGet.org - whichever you'd prefer.

Thoughts?

A new AntiForgeryToken cookie is set on every request

The ControllerBaseExtension.WriteForgeryToken creates a new AntiForgeryToken cookie on every request, which breaks validation when multiple tabs are used because the cookie becomes out of sync with the hidden form input. This can be fixed by passing the existing AntiForgeryToken cookie value to AntiForgery.GetTokens. I'll submit a pull request for this change as well, let me know if it looks good to you.

Allow for additional flushes

Is there a way to invoke additional flushes with other site sections somehow?

Usecase: I'd like to flush a large menu once its model is ready so users can have first contentful paint as soon as possible, and potentially navigate the site further while the rest of the stuff is underway.

P.S. Is this still your recommended way of doing flushes in ASP.NET MVC?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.