OutputCache отправляет неверный заголовок Vary, когда вызов попадает в кеш

У меня есть метод действия, который я хочу кешировать:

[OutputCache(Duration=60*5, Location=OutputCacheLocation.Any, VaryByCustom="index")]
public ActionResult Index()
{
    return View();
}

При таком подходе:

public override string GetVaryByCustomString(HttpContext context, string custom)
{
    context.Response.Cache.SetOmitVaryStar(true);
    context.Response.Cache.VaryByHeaders["Cookie"] = true;

    if (User.Identity.IsAuthenticated)
    {
        Debug.Print("Authenticated");
        context.Response.Cache.SetNoServerCaching();
        context.Response.Cache.SetCacheability(HttpCacheability.Private);
        return null;
    }
    else
    {
        Debug.Print("Non authenticated");
        return custom;
    }
}

Идея заключалась всохраняйте кэшированную версию страницы для неаутентифицированных пользователей, но избегайте кэширования для аутентифицированных.

Я думал, что это всегда вернетVary:Cookie Заголовок HTTP, но это не так. Выполнение теста с Fiddler и выдача дважды одного и того же запроса, в первом HTTP-вызове все идет хорошо:

HTTP/1.1 200 OK
Cache-Control: public, max-age=300
Content-Type: text/html; charset=utf-8
Expires: Thu, 09 Feb 2012 10:53:36 GMT
Last-Modified: Thu, 09 Feb 2012 10:48:36 GMT
Vary: Cookie
Server: Microsoft-IIS/7.5
X-AspNetMvc-Version: 3.0
X-AspNet-Version: 4.0.30319
X-Powered-By: ASP.NET
Date: Thu, 09 Feb 2012 10:48:37 GMT
Content-Length: 441

Но во втором он перезаписывает заголовок:

HTTP/1.1 200 OK
Cache-Control: public, max-age=297
Content-Type: text/html; charset=utf-8
Expires: Thu, 09 Feb 2012 10:53:36 GMT
Last-Modified: Thu, 09 Feb 2012 10:48:36 GMT
Vary: *
Server: Microsoft-IIS/7.5
X-AspNetMvc-Version: 3.0
X-AspNet-Version: 4.0.30319
X-Powered-By: ASP.NET
Date: Thu, 09 Feb 2012 10:48:39 GMT
Content-Length: 441

Итак, насколько мне известно, браузеры не будут кэшировать запрос, даже если он общедоступный, посколькуVary:* означает, что запрос был создан с параметрами, которых нет ни в URL, ни в заголовках HTTP. Есть ли способ это исправить?

С уважением.

ОБНОВИТЬ:

Аналогичным образом, когда я отправляю два идентичных аутентифицированных запроса, первый вызов получаетprivate модификатор, но неVary заголовок:

HTTP/1.1 200 OK
Cache-Control: private, max-age=300
Content-Type: text/html; charset=utf-8
Expires: Thu, 09 Feb 2012 12:43:14 GMT
Last-Modified: Thu, 09 Feb 2012 12:38:14 GMT
Server: Microsoft-IIS/7.5
X-AspNetMvc-Version: 3.0
X-AspNet-Version: 4.0.30319
X-Powered-By: ASP.NET
Date: Thu, 09 Feb 2012 12:38:14 GMT
Content-Length: 443

Но второй получает тот же ответ, что и запрос без аутентификации:

HTTP/1.1 200 OK
Cache-Control: public, max-age=298
Content-Type: text/html; charset=utf-8
Expires: Thu, 09 Feb 2012 12:44:32 GMT
Last-Modified: Thu, 09 Feb 2012 12:39:32 GMT
Vary: *
Server: Microsoft-IIS/7.5
X-AspNetMvc-Version: 3.0
X-AspNet-Version: 4.0.30319
X-Powered-By: ASP.NET
Date: Thu, 09 Feb 2012 12:39:33 GMT
Content-Length: 443

Я загрузилтестовый проект, показывающий проблему может быть, вы захотите попробовать.

Пожалуйста, имейте в виду, что естьIHttpModule который устанавливает запрос как аутентифицированный или нет, в зависимости от того, есть ли в запросе cookie или нет, это не «реальный» подход, он только для целей тестирования.

Проект содержит только веб-страницу со ссылкой на себя, ссылку для входа в систему и другую ссылку для выхода из системы:

Вход в систему: отправляет печенье вHTTP 302 перенаправление на домашнюю страницу снова.LogOut: отправляет просроченный файл cookie вHTTP 302 Переадресация на домашнюю страницу снова.

ожидаемый / идеал поведение будет:

Получите доступ к индексу и получите страницу с сервера. На странице показывается дата «А».Пользователь снова получает доступ к индексу, и браузер показывает кешированную версию. На странице отображается дата «А».Очистить кеш браузера.Индекс доступа пользователя снова, и браузер показывает версию сервера в кэше. На странице показывается дата «А».Пользователь нажимает кнопку входа, и брат получает новую страницу, на которой отображается дата «B».Пользователь нажимает кнопку выхода, и браузер получает страницу с кэшированным сервером. На странице снова появится дата «А».

Но это поведение до сих пор:

Получите доступ к индексу и получите страницу с сервера. На странице показывается дата «А».Пользователь снова получает доступ к индексу, и браузер показывает кешированную версию. На странице отображается дата «А».Очистить кеш браузера.Индекс доступа пользователя снова, и браузер показывает версию сервера в кэше. На странице показывается дата «А».Пользователь нажимает кнопку входа, и брат получает новую страницу, на которой отображается дата «B».Пользователь нажимает кнопку выхода, а браузердолжен получить сервер кэшированной страницы, но это не так, На странице снова отображается дата «B» из кеша браузера. Это потому, что отсутствиеVary заголовок в аутентифицированном ответе.

Я не знаю, ошибаюсь ли я в кешировании, просто не хватает какой-то детали илиOutputCache не очень хорошо работает, но я был бы признателен за любые рекомендации.

Приветствия.

ОБНОВЛЕНИЕ 2:

Я намерен использовать семантику кеша HTTP для:

Разрешить браузерам и прокси кэшировать «публичную» версию страницы.Разрешить браузерам кэшировать «аутентифицированную» версию страницы для своего пользователя.

Если я изменю объявление OutputCache, чтобы выполнять кэширование только на сервере и предотвращать последующее и клиентское кэширование:

[OutputCache(Duration=60*5, Location=OutputCacheLocation.Server, VaryByCustom="index")]

он ведет себя, как и ожидалось, но кеш нисходящего потока и клиентского кеша запрещен, а это не то, чего я хочу.

Ответы на вопрос(3)

Ваш ответ на вопрос