Nancy hỗ trợ một phần các tiêu đề ETag
và Last-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ị ETag
và Last-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.