Skip to content

Instantly share code, notes, and snippets.

@darrelmiller
Forked from jchannon/cacheimplementation.cs
Last active September 2, 2015 20:21
Show Gist options
  • Save darrelmiller/5cc71b50f572f7d4139d to your computer and use it in GitHub Desktop.
Save darrelmiller/5cc71b50f572f7d4139d to your computer and use it in GitHub Desktop.
Nancy caching using Last-Modified/If-Modified-Since header
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;
}
}
}
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