2012-10-04 17 views
8

Quiero que mi contenido estático (imágenes, archivos javascript, archivos css, etc.) se publique por completo solo después de que se haya actualizado el archivo.¿NancyFX admite el almacenamiento en caché de contenido estático a través de los encabezados ETag y Last-Modified?

Si un archivo no ha cambiado desde la última vez solicitada (según lo determinado por los valores de encabezado de respuesta ETag y Last-Modified) entonces yo quiero las versiones en caché de los archivos para ser utilizados por el navegador del cliente.

¿Admite Nancy esta funcionalidad?

Respuesta

14

Nancy admite parcialmente los encabezados ETag y Last-Modified. Los establece para todos los archivos estáticos pero a partir de la versión 0.13 no hace nada con estos valores. aquí está el código Nancy:

Nancy.Responses.GenericFileResponse.cs

if (IsSafeFilePath(rootPath, fullPath)) 
{ 
    Filename = Path.GetFileName(fullPath); 

    var fi = new FileInfo(fullPath); 
    // TODO - set a standard caching time and/or public? 
    Headers["ETag"] = fi.LastWriteTimeUtc.Ticks.ToString("x"); 
    Headers["Last-Modified"] = fi.LastWriteTimeUtc.ToString("R"); 
    Contents = GetFileContent(fullPath); 
    ContentType = contentType; 
    StatusCode = HttpStatusCode.OK; 
    return; 
} 

Para hacer uso de los valores ETag y Last-Modified de cabecera que necesita añadir un par de extensiones métodos modificados. Tomé prestado éstos directamente desde el código fuente de Nancy en GitHub (ya que esta funcionalidad está prevista para una versión futura), pero la idea original vino de Simon Cropp - Conditional responses with NancyFX

métodos de extensión

public static void CheckForIfNonMatch(this NancyContext context) 
{ 
    var request = context.Request; 
    var response = context.Response; 

    string responseETag; 
    if (!response.Headers.TryGetValue("ETag", out responseETag)) return; 
    if (request.Headers.IfNoneMatch.Contains(responseETag)) 
    { 
     context.Response = HttpStatusCode.NotModified; 
    } 
} 

public static void CheckForIfModifiedSince(this NancyContext context) 
{ 
    var request = context.Request; 
    var response = context.Response; 

    string responseLastModified; 
    if (!response.Headers.TryGetValue("Last-Modified", out responseLastModified)) return; 
    DateTime lastModified; 

    if (!request.Headers.IfModifiedSince.HasValue || !DateTime.TryParseExact(responseLastModified, "R", CultureInfo.InvariantCulture, DateTimeStyles.None, out lastModified)) return; 
    if (lastModified <= request.Headers.IfModifiedSince.Value) 
    { 
     context.Response = HttpStatusCode.NotModified; 
    } 
} 

último que necesita para llamar a estos métodos utilizando el gancho AfterRequest en su Nancy BootStrapper.

Bootstrapper

public class MyBootstrapper :DefaultNancyBootstrapper 
{ 
    protected override void ApplicationStartup(TinyIoCContainer container, IPipelines pipelines) 
    { 
     pipelines.AfterRequest += ctx => 
     { 
      ctx.CheckForIfNoneMatch(); 
      ctx.CheckForIfModifiedSince(); 
     }; 
     base.ApplicationStartup(container, pipelines); 
    } 
    //more stuff 
} 

Viendo las respuestas con Fiddler verá el primer golpe a los archivos estáticos los descarga con un Código 200 - OK Estado.

A continuación, cada solicitud devuelve un código de estado 304 - Not Modified. Después de actualizar un archivo, solicitarlo una vez más lo descarga con un código de estado 200 - OK ... y así sucesivamente.

Cuestiones relacionadas