2012-10-04 42 views
8

Tôi muốn nội dung tĩnh của mình (hình ảnh, tệp javascript, tệp css, v.v.) chỉ được phân phối đầy đủ sau khi tệp đã được cập nhật.NancyFX có hỗ trợ bộ nhớ đệm nội dung tĩnh qua các tiêu đề ETag và Last-Modified không?

Nếu tệp chưa thay đổi kể từ khi được yêu cầu lần cuối (như được xác định bởi các giá trị tiêu đề phản hồi ETagLast-Modified) thì tôi muốn các phiên bản lưu trữ của tệp được trình duyệt khách sử dụng.

Nancy có hỗ trợ chức năng này không?

Trả lời

14

Nancy hỗ trợ một phần các tiêu đề ETagLast-Modified. Nó đặt chúng cho tất cả các tệp tĩnh nhưng kể từ phiên bản 0.13 nó không có gì với các giá trị này. đây là mã 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; 
} 

Để làm sử dụng trong những giá trị ETagLast-Modified tiêu đề bạn cần phải thêm một vài phương pháp phần mở rộng sửa đổi. Tôi mượn những trực tiếp từ mã nguồn Nancy trong GitHub (như chức năng này được lên kế hoạch cho một phiên bản tương lai) nhưng ý tưởng ban đầu đến từ Simon Cropp - Conditional responses with NancyFX

Mở rộng phương pháp

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

Cuối cùng bạn cần để gọi những phương thức này bằng cách sử dụng móc AfterRequest trong Trình khởi động Nancy của bạn.

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 
} 

Xem các câu trả lời với Fiddler bạn sẽ thấy những hit đầu tiên đến các tập tin tĩnh của bạn tải chúng với Mã 200 - OK Trạng thái.

Sau đó, mỗi yêu cầu trả về mã trạng thái 304 - Not Modified. Sau khi một tệp được cập nhật, hãy yêu cầu một lần nữa tải xuống tệp với Mã trạng thái 200 - OK ... v.v.

Các vấn đề liên quan