OutputCache está enviando um cabeçalho Vary errado quando a chamada atinge o cache

Tenho um método de ação que quero armazenar em cache:

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

Com esta abordagem:

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

A ideia era mantenha uma versão em cache da página para usuários não autenticados, mas evite o cache para usuários autenticados.

Eu pensei que sempre retornaria umVary:Cookie Cabeçalho HTTP, mas não é. Fazendo um teste com o Fiddler e emitindo duas vezes a mesma solicitação, na primeira chamada HTTP, ele funciona bem:

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

Mas no segundo, ele substitui o cabeçalho:

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

Então, até onde eu sei, os navegadores não armazenarão em cache a solicitação, mesmo que seja pública, poisVary:* significa que a solicitação foi gerada com parâmetros que não estão na URL nem nos cabeçalhos HTTP. Existe uma maneira de corrigir isso

Saudações

ATUALIZAR

De maneira semelhante, quando envio duas solicitações autenticadas idênticas, a primeira chamada recebe oprivate modificador, mas não oVary cabeçalho:

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

Mas o segundo obtém a mesma resposta que uma solicitação não autenticada:

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

Fiz upload de umtest projeto mostrando o problema pode ser que você queira experimentá-l

Esteja ciente de que existe umIHttpModule que define uma solicitação como autenticada ou não, dependendo se a solicitação possui um cookie ou não, essa não é uma abordagem da "vida real", é apenas para fins de test

O projeto contém apenas uma página da web com um link para si mesmo, um link que efetua login e outro link que efetua logout:

LogIn: envia um cookie em umHTTP 302 redirecionamento para a página inicial novamentLogOut: envia um cookie expirado em umHTTP 302 redirecionamento para a página inicial novament

O esperado / ideal o comportamento seria:

Índice de acesso do usuário e obtenha a página do servidor. A página mostra a data "A". Índice de acesso do usuário novamente e o navegador mostra a versão em cache. A página mostra a data "A"impe o cache do navegado Índice de acesso do usuário novamente e o navegador mostra a versão em cache do servidor. A página mostra a data "A". usuário clica no login e o broswer recebe uma nova página, que mostra a data "B" usuário clica em logout e o navegador obtém a página em cache do servidor. A página mostra a data "A" novamente.

Mas este é o comportamento até agora:

Índice de acesso do usuário e obtenha a página do servidor. A página mostra a data "A". Índice de acesso do usuário novamente e o navegador mostra a versão em cache. A página mostra a data "A"impe o cache do navegado Índice de acesso do usuário novamente e o navegador mostra a versão em cache do servidor. A página mostra a data "A". usuário clica no login e o broswer recebe uma nova página, que mostra a data "B" usuário clica em logout e o navegador deve obter a página em cache do servidor, mas não. A página mostra a data "B" novamente no cache do navegador. Isso ocorre porque a falta doVary cabeçalho na resposta autenticad

Não sei se entendi algo errado sobre o cache, faltando apenas alguns detalhes ou oOutputCache não funciona muito bem, mas gostaria de receber qualquer orientação.

Felicidades

UPDATE 2:

Minha intenção é usar a semântica do cache HTTP para:

Permitir que navegadores e proxys armazenem em cache a versão "pública" da páginPermitir que os navegadores armazenem em cache a versão "autenticada" da página para seu usuári

Se eu alterar a declaração OutputCache para fazer o cache apenas no servidor e impedir o cache downstream e do cliente:

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

se comporta conforme o esperado, mas o cache downstream e o cliente são impedidos, e não é isso que eu quer

questionAnswers(6)

yourAnswerToTheQuestion