-
-
Save darrelmiller/5cc71b50f572f7d4139d to your computer and use it in GitHub Desktop.
Nancy caching using Last-Modified/If-Modified-Since header
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class Cache : ICache | |
{ | |
private ConcurrentDictionary<string, DateTime> cacheLookup = new ConcurrentDictionary<string,DateTime>(); | |
public Response Get(NancyContext ctx) | |
{ | |
DateTime lastmodified; | |
if(ctx.Request.Method == "GET" || ctx.Request.Method == "HEAD") | |
{ | |
if (!cacheLookup.TryGetValue(ctx.Request.Method + "-" + ctx.Request.Url.ToString(), out lastmodified)) | |
{ | |
return null; | |
} | |
if(!ctx.Request.Headers.IfModifiedSince.HasValue) | |
{ | |
return null; | |
} | |
var modifiedsince = ctx.Request.Headers.IfModifiedSince.Value; | |
if (modifiedsince < lastmodified) | |
{ | |
return null; | |
} | |
return new Response(){ StatusCode = 304 }; | |
} | |
return null; | |
} | |
public void AddOrUpdate(NancyContext ctx) | |
{ | |
if(ctx.Request.Method == "GET" || ctx.Request.Method == "POST" || ctx.Request.Method == "HEAD" ) | |
{ | |
var keyMethod = ctx.Request.Method; | |
if (keyMethod == "POST") { keyMethod == "GET"; } // You can only GET a cached POST response | |
var id = keyMethod + "-" + ctx.Request.Url.ToString();//GET - http://mydomain.com/products/1?foo=bar | |
var date = DateTime.UtcNow; | |
cacheLookup.AddOrUpdate(id,date,(key,value) => date); | |
ctx.Response.Headers.LastModified = date; | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
namespace Nancy.LastModified | |
{ | |
using System; | |
using Nancy; | |
public class MainModule : NancyModule | |
{ | |
public MainModule(ICache cache, ISomeRepoOrServiceOrOtherLayerYouLove someRepoOrServiceOrOtherLayerYouLove) | |
{ | |
Get["/{int:id}"] = x => { | |
return someRepoOrServiceOrOtherLayerYouLove.Get(x.id); | |
}; | |
Put["/{int:id}"] = x => { | |
var model = this.BindAndValidate<MyModel>(); | |
someRepoOrServiceOrOtherLayerYouLove.Update(x.id,model); | |
return 204; | |
}; | |
Delete["/{int:id}"] = x => { | |
someRepoOrServiceOrOtherLayerYouLove.Delete(x.id); | |
return 204; | |
}; | |
Before += ctx => { | |
return cache.Get(ctx); | |
}; | |
After += ctx => { | |
cache.AddOrUpdate(ctx); | |
}; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment