Search code examples
asp.netssloutputcachescene7

How do I configure ASP.Net OutputCache to vary by http vs https?


Here is the scenario, a user opens up non-secure page from our WebApp, let's call it PageA, in their browser and then clicks a link in there that takes them to a secure instance of PageB. Once in PageB the user can subsequently click a link that takes them back to a secure instance of PageA (which they already viewed and is in OutputCache). I observed that even though PageA is being accessed over a different URL after visiting PageB (the secure one) it's actually pulling the prior cached copy rather making a fresh one. I verified this behavior in a debugging session, and was surprised that ASP.Net used the same OutputCache item for a secure copy of the page.

My question is why is it this way? And how do I tell the ASP.Net OutPutCache to treat access from secure URL as a different/unique item than the non-secure equivalent?

[Background]

We recently switched our Web Sites images over to use Scene7/Akamai for all images. As a result of this we added code to use different Scene7 url's when viewing a given page on a secure connection. This OutputCache issue is not allowing for the logic that outputs the secure url's to execute, and is resulting in ugly browser warnings.


Solution

  • I think that you can do a VaryByCustom="scheme" and add this to your Global.asax.cs file (inlcuding a couple other others that I use as well app version & user):

        public override string GetVaryByCustomString(HttpContext context, string custom)
        {
            if (custom.Equals("version", StringComparison.CurrentCultureIgnoreCase))
            {
                Assembly asm = Assembly.GetExecutingAssembly();
                string[] parts = asm.FullName.Split(',');
                string version = parts[1].Trim().ToLower();
                return version;
            }
            else if (custom.Equals("user", StringComparison.CurrentCultureIgnoreCase))
            {
                var user = Membership.Users.CurrentUser;
                return null == user ? string.Empty : user.Id.ToString();
            }
            else if (custom.Equals("scheme", StringComparison.CurrentCultureIgnoreCase))
            {
                var scheme = context.Request.IsSecureConnection ? "https" : "http";
                return scheme;
            }
            else
                return base.GetVaryByCustomString(context, custom);
        }