Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cache-Control headers not sent in response despite being configured on response object

I'm trying to set cache headers in ASP.NET MVC Web API, but the response from IIS suggests that the CacheControl values set are being ignored.

My original assumption was that I was using the EnableCorsAttribute in System.Web.Http.Cors, which is necessary in this use case. However, even without that attribute, the response Cache-Control header is still 'private'.

Is there something I am doing wrong here?

    // GET api/<version>/content
    // [EnableCors(origins: "*", headers: "*", methods: "*")]
    public HttpResponseMessage Get(HttpRequestMessage request)
    {
        int cacheMaxAgeSeconds;

        string cacheMaxAgeString = request.GetQueryString("cache-max-age") ?? request.GetQueryString("cache-max-age-seconds");

        string rawUri = request.RequestUri.ToString();

        try
        {
            cacheMaxAgeSeconds = cacheMaxAgeString == null ? Config.ApiCacheControlMaxSeconds : int.Parse(cacheMaxAgeString);
        }
        catch (Exception ex)
        {
            cacheMaxAgeSeconds = Config.ApiCacheControlMaxSeconds;

            //... 
        }

        try
        {
            //...

            var response = new HttpResponseMessage(HttpStatusCode.OK)
            {
                Content = new StringContent("...", Encoding.UTF8, "application/json")
            };

            response.Headers.CacheControl = new CacheControlHeaderValue
            {
                Public = true,
                MaxAge = TimeSpan.FromSeconds(cacheMaxAgeSeconds)
            };

            return response;
        }
        catch (Exception apiEx)
        {
            //...
        }
    }

Response

HTTP/1.1 200 OK
Cache-Control: private
Content-Type: application/json; charset=utf-8
Date: Thu, 23 Jul 2015 10:53:17 GMT
Server: Microsoft-IIS/7.5
Set-Cookie: ASP.NET_SessionId=knjh4pncbrhad30kjykvwxyz; path=/; HttpOnly
X-AspNet-Version: 4.0.30319
X-Powered-By: ASP.NET
Content-Length: 2367
Connection: keep-alive
like image 910
gb2d Avatar asked Jul 23 '15 10:07

gb2d


People also ask

What happens if there is no Cache-Control header?

Without the cache control header the browser requests the resource every time it loads a new(?) page.

What should you add to a Cache-Control response header to specify that a response?

private. The private response directive indicates that the response can be stored only in a private cache (e.g. local caches in browsers). You should add the private directive for user-personalized content, especially for responses received after login and for sessions managed via cookies.


2 Answers

Code below sets "cache-control: public, max-age=15" correctly in vanilla WebApi application (System.Web.Http 4.0.0.0). So... it's probably not the WebApi itself that causes the issue.

You may have some magic in your project that changes cache settings (think of global action filters or something similar). Or maybe you are going through proxy which rewrites HTTP headers.

    public HttpResponseMessage Get()
    {
        var content = new JavaScriptSerializer().Serialize(new { foo = "bar" });

        var response = new HttpResponseMessage(HttpStatusCode.OK)
        {
            Content = new StringContent(content, Encoding.UTF8, "application/json")
        };

        response.Headers.CacheControl = new CacheControlHeaderValue
        {
            Public = true,
            MaxAge = TimeSpan.FromSeconds(15)
        };

        return response;
    }

// returns in the response: "Cache-Control: public, max-age=15"
like image 131
pkmiec Avatar answered Nov 15 '22 14:11

pkmiec


The answer, having picked this up some weeks later:

Cache-Control header appears to be set to 'private' when running debug builds. The issue goes away when I run with a release build.

like image 28
gb2d Avatar answered Nov 15 '22 15:11

gb2d