Outputcache and 410 status response not working
Asked Answered
H

1

7

I would like to throw a 410 status code for a page that does some database lookups. However it seems that outputcache only caches 200 status code pages. Is there anyway around this? I want to cache 410 pages for a while so the database doesn't get it, but it just skips the cache and hits the database again.

[OutputCache(Duration = 3600, VaryByParam = "eventid,teamid,v,r")]
    public virtual ActionResult Team(int? teamId, int? eventId)
    {
Hadlee answered 10/8, 2022 at 13:5 Comment(0)
D
2

OutputCache and almost all HTTP level caches are designed to ignore failed responses, anything other more than 399, all status code above 399 are error codes.

You can manually set Response Headers like

context.Response.Headers.CacheControl = "public, max-age=3600"

This is what OutputCache does internally, however, OutputCache might also provide server level cache if setup.

But if you use CDN, I doubt they will respect cache control in case of failed response status codes.

But it is not recommended. Lets say for some reason user deletes the cookies or cookie gets corrupted. And user receives 410 error. And user goes back to login and logs in correctly, and now for same request user will continue to receive 410 for one hour.

Or otherwise let’s say your database is unavailable and database throws 410 error, so even with valid cookie or valid authorization, user will receive cached error response. Caching layer doesn’t know when not to cache.

Instead, you can use MemoryCache, to cache error results in your memory for couple of seconds without going to database each time. Though the results will still hit the web servers.

CloudFlare and Azure provides web application firewall, which allows intelligently blocking errornous traffic if you are worried about DDOS kind of attacks. This approach seems better than using HTTP Cache, as you will have no control over user's cache. And you can't programmatically clear cache after successful login.

Decimalize answered 31/8, 2022 at 17:25 Comment(7)
I am not sure if this is what I want. Are you saying if I put that code in on a 401 error that the outputcache will pick it up. I had to create a list in memory just for this issue.Hadlee
No, OutputCache will ignore all errors above 399. You can manually set cache control. But again it is not advisable. You have two options, one use memory cache to reduce database server queries, or use Web application firewall to temporarily disable DDOS kind of attacks. Can you elaborate your scenario on why you want to cache 41* errors?Decimalize
Apple Calendar is hitting an endpoint two dozen times a day on past events. I want to throw a 404 error, but only when verifying from the database it was a past event. I dont want to hit the database everytime to verify this is a 404 page. I want to cache it for say a day throwing a 404 error.Hadlee
In that case why do you want to throw error code, instead you can simply empty content with 200 status and configure your app to ignore empty successful results. This is how we are doing it.Decimalize
Because I would think Apple Calendar may stop making requests to past events if a 404 error is thrown. They certainly wont do it for a 200 status code.Hadlee
You can use etag with cache control to reduce requests. For older or invalid requests, add immutable with cache control header with etag.Decimalize
I think with an upvote of 7, people want a better answer. Ill play around with it to see if it works ok.Hadlee

© 2022 - 2024 — McMap. All rights reserved.