Поддерживает ли NancyFX кэширование статического контента с помощью заголовков ETag и Last-Modified?

Я хочу, чтобы мой статический контент (изображения, файлы javascript, файлы css и т. д.) обслуживался полностью только после обновления файла.

Если файл не изменился с момента его последнего запроса (что определяется значениями заголовка ответа ETag и Last-Modified), то я хочу, чтобы кэшированные версии файлов использовались клиентским браузером.

Поддерживает ли Нэнси эту функцию?


person biofractal    schedule 04.10.2012    source источник
comment
Для статического контента вы можете использовать это: mike-ward.net/2014/01/13/   -  person RhinoDevel    schedule 06.11.2018


Ответы (1)


Нэнси частично поддерживает заголовки 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 (поскольку эта функциональность запланирована в будущем выпуске), но первоначальная идея исходила от Саймона Кроппа — условные ответы с НэнсиFX

Методы расширения

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 в вашем Nancy 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... и так далее.

person biofractal    schedule 09.11.2012
comment
Я не думаю, что расширение .AfterRequest будет введено для статического контента. - person RhinoDevel; 06.11.2018