2012-10-04 42 views
8

मैं अपनी स्थिर सामग्री (छवियों, जावास्क्रिप्ट फ़ाइलों, सीएसएस फाइलों आदि) को फ़ाइल अद्यतन होने के बाद पूरी तरह से सेवा करने के लिए चाहता हूं।क्या नैन्सीएफएक्स ईटीएजी और लास्ट-संशोधित हेडर के माध्यम से स्थिर सामग्री कैशिंग का समर्थन करता है?

यदि फ़ाइल को अंतिम बार अनुरोध नहीं किया गया था (जैसा कि ETag और Last-Modified प्रतिक्रिया शीर्षलेख मानों द्वारा निर्धारित किया गया है) तो मैं क्लाइंट ब्राउज़र द्वारा फ़ाइलों के कैश किए गए संस्करणों का उपयोग करना चाहता हूं।

क्या नैन्सी इस कार्यक्षमता का समर्थन करता है?

उत्तर

14

नैन्सी आंशिक रूप से ETag और Last-Modified हेडर का समर्थन करता है। यह उन्हें सभी स्थिर फाइलों के लिए सेट करता है लेकिन संस्करण 0.13 के रूप में यह इन मानों के साथ कुछ भी नहीं करता है। यहाँ नैन्सी कोड है:

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

उपयोग ETag और Last-Modified हैडर मान आप संशोधित एक्सटेंशन तरीकों में से एक जोड़े को जोड़ने की जरूरत है की बनाने के लिए। मैं GitHub में नैन्सी स्रोत कोड से सीधे इन उधार (के रूप में इस कार्यक्षमता एक भविष्य के रिलीज के लिए योजना बनाई है), लेकिन मूल विचार साइमन Cropp से आया है - Conditional responses with NancyFX

एक्सटेंशन के तरीके

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

अंत में आप की जरूरत है अपने नैन्सी बूटस्ट्रैपर में AfterRequest हुक का उपयोग करके इन विधियों को कॉल करने के लिए।

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 
} 

Fiddler साथ प्रतिक्रियाओं देखना आप अपने स्थिर फ़ाइलों के लिए पहली हिट देखेंगे एक 200 - OK स्थिति कोड के साथ उन्हें डाउनलोड करता है।

इसके बाद प्रत्येक अनुरोध 304 - Not Modified स्थिति कोड देता है। फ़ाइल अपडेट होने के बाद, इसे एक बार फिर से अनुरोध करने के लिए इसे 200 - OK स्थिति कोड ... और इसी तरह से डाउनलोड किया जाता है।