Question

En écrivant un IHttpHandler personnalisé, je suis tombé sur un comportement auquel je ne m'attendais pas concernant l'objet HttpCachePolicy.

Mon gestionnaire calcule et définit une balise d'entité (en utilisant la méthode SetETag sur le HttpCachePolicy associé à l'objet de réponse actuel).Si je définis le contrôle du cache sur public à l'aide de la méthode SetCacheability, tout fonctionne à merveille et le serveur envoie l'en-tête de la balise électronique.Si je le règle sur privé, l'en-tête de la balise électronique sera supprimé.

Peut-être que je n'ai tout simplement pas assez regardé, mais je n'ai rien vu dans la spécification HTTP/1.1 qui justifierait ce comportement.Pourquoi ne voudriez-vous pas envoyer E-Tag aux navigateurs tout en interdisant aux proxys de stocker les données ?

using System;
using System.Web;

public class Handler : IHttpHandler {
    public void ProcessRequest (HttpContext ctx) {
        ctx.Response.Cache.SetCacheability(HttpCacheability.Private);
        ctx.Response.Cache.SetETag("\"static\"");
        ctx.Response.ContentType = "text/plain";
        ctx.Response.Write("Hello World");
    }

    public bool IsReusable { get { return true; } }
}

Je reviendrai

Cache-Control: private
Content-Type: text/plain; charset=utf-8
Content-Length: 11

Mais si nous le changeons en public, il reviendra

Cache-Control: public
Content-Type: text/plain; charset=utf-8
Content-Length: 11
Etag: "static"

Je l'ai exécuté jusqu'à présent sur le serveur de développement ASP.NET et IIS6 avec les mêmes résultats.De plus, je ne parviens pas à définir explicitement l'ETag en utilisant

Response.AppendHeader("ETag", "static")

Mise à jour:Il est possible d'ajouter manuellement l'en-tête ETag lors de l'exécution dans IIS7. Je soupçonne que cela est dû à l'intégration étroite entre ASP.NET et le pipeline IIS7.

Clarification:C'est une longue question mais la question centrale est la suivante : pourquoi ASP.NET fait-il cela, comment puis-je le contourner et dois-je le faire ?

Mise à jour:je vais accepter La réponse de Tony puisque c'est essentiellement correct (allez Tony !).J'ai trouvé que si vous souhaitez émuler entièrement HttpCacheability.Private, vous pouvez définir la capacité de cache sur ServerAndPrivate, mais vous disposez également d'un cache d'appels.SetOmitVaryStar(vrai) sinon le cache ajoutera le Varier:* en-tête à la sortie et vous ne voulez pas cela.Je modifierai cela dans la réponse lorsque j'obtiendrai les autorisations de modification (ou si vous voyez ce Tony, vous pourriez peut-être modifier votre réponse pour inclure cet appel ?)

Était-ce utile?

La solution

Je pense que vous devez utiliser HttpCacheability.ServerAndPrivate

Cela devrait vous donner le contrôle du cache :private dans les en-têtes et vous permet de définir un ETag.

La documentation à ce sujet doit être un peu meilleure.

Modifier: Markus a constaté que vous deviez également appeler cache.SetOmitVaryStar(true) sinon le cache ajoutera le Vary :* en-tête à la sortie et vous ne voulez pas cela.

Autres conseils

Malheureusement, si vous regardez System.Web.HttpCachePolicy.UpdateCachedHeaders() dans .NET Reflector, vous voyez qu'il existe une instruction if vérifiant spécifiquement que la capacité de cache n'est pas privée avant d'effectuer des tâches ETag.En tout cas, j'ai toujours trouvé ça Last-Modified/If-Modified-Since fonctionne bien pour nos données et est de toute façon un peu plus facile à surveiller dans Fiddler.

Si, comme moi, vous n'êtes pas satisfait de la solution de contournement mentionnée ici consistant à utiliser Cacheability.ServerAndPrivate et que vous souhaitez vraiment utiliser Private à la place - peut-être parce que vous personnalisez les pages individuellement pour les utilisateurs et que cela n'a aucun sens de mettre en cache sur le serveur - alors au moins dans .NET 3.5, vous pouvez définir ETag via Response.Headers.Add et cela fonctionne très bien.

N.-B.si vous faites cela, vous devez implémenter vous-même la comparaison des en-têtes client et la gestion des réponses HTTP 304 - je ne sais pas si .NET s'en charge pour vous dans des circonstances normales.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top