2012-10-04 13 views
8

Desidero che il contenuto statico (immagini, file javascript, file css, ecc.) Venga pubblicato completamente solo dopo che il file è stato aggiornato.NancyFX supporta il caching del contenuto statico tramite le intestazioni ETag e Last-Modified?

Se un file non è stato modificato dall'ultima richiesta (come determinato dai valori di intestazione di risposta ETag e Last-Modified), desidero che le versioni memorizzate nella cache dei file vengano utilizzate dal browser client.

Nancy supporta questa funzionalità?

risposta

14

Nancy supporta parzialmente le intestazioni ETag e Last-Modified. Li imposta per tutti i file statici ma a partire dalla versione 0.13 non fa nulla con questi valori. ecco il codice 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; 
} 

Per rendere uso dei valori ETag e Last-Modified intestazione è necessario aggiungere un paio di metodi estensioni modificati. Ho preso in prestito questi direttamente dal codice sorgente Nancy a GitHub (come questa funzionalità è previsto per una release futura), ma l'idea originale è venuto da Simon Cropp - Conditional responses with NancyFX

Metodi di estensione

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; 
    } 
} 

Infine, è necessario chiamare questi metodi utilizzando l'hook AfterRequest in 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 
} 

Guardando le risposte con Fiddler si vedrà il primo colpo ai file statici li scarica con un codice di stato 200 - OK.

Successivamente ciascuna richiesta restituisce un codice di stato 304 - Not Modified. Dopo che un file è stato aggiornato, richiedendolo nuovamente lo scarica con un codice di stato 200 - OK ... e così via.