Parar o IIS 7.5 de enviar a idade máxima de controle de cache em códigos de erro

10

Eu tenho algum conteúdo estático com os Max-Agecabeçalhos de controle de cache anexados, para que os clientes armazenem em cache o conteúdo estático. No entanto, o IIS 7.5 ainda envia esse cabeçalho quando houver respostas de erro aconselhando o cliente a armazená-lo em cache.

Isso tem o efeito negativo de que alguns proxies armazenarão em cache essa resposta de erro. Eu poderia, Vary: Accept,Accept-Encodingmas isso realmente não aborda o problema raiz de Max-Agesair com respostas de erro.

A web.configseção atual relevante do IIS é:

<configuration>
  <system.webServer>
    <staticContent>
      <clientCache cacheControlMode="UseMaxAge" cacheControlMaxAge="7.00:00:00" />
    </staticContent>
  </system.webServer>
</configuration>

Existe uma maneira de que eu possa fazê-lo para não solicitar aos clientes ou proxies que armazenem em cache códigos de erro 400/500?

Kyle Brandt
fonte
Você está usando páginas de erro personalizadas?
9303 Justin Niessner
@Justin - Não, não neste caso
Nick Craver
O IIS 7.0 não envia Max-Age em 40 * para mim. Não tenho certeza se é uma discrepância entre as versões do IIS.
David Murdoch
Além disso, como forçar o conteúdo estático a enviar um código de erro 500?
David Murdoch
1
@DavidMurdoch, por exemplo, estamos vendo 406 respostas enviadas com cabeçalhos de controle de cache quando os usuários solicitam javascript, mas o cliente aceita apenas tipos MIME de imagem. Os proxies estão respeitando esta diretiva de armazenamento em cache (como deveriam, pelas especificações) e outros usuários não conseguem baixar o script.
Jarrod Dixon

Respostas:

2

Eu criei um "conjunto" de testes rudimentar.

Quando executo os testes com um mínimo de Web.config no IIS 7.0 (modo pipline integrado no .NET 4.0) tudo passa; o Cache-Controlcabeçalho de resposta do arquivo de teste é definido como privatequando o Acceptcabeçalho da solicitação não corresponde ao do arquivo Content-Type.

Isso me leva a acreditar que você tem algum módulo que interrompe a rotina de cache estático do IIS ou o IIS 7.0 e 7.5 diferem aqui.

Aqui estão os arquivos que eu usei (sans, some-script.jspois é apenas um arquivo vazio):

Web.Config:

<?xml version="1.0"?>
<configuration>
    <system.web>
        <compilation debug="true" targetFramework="4.0">
        </compilation>
    </system.web>
    <system.webServer>
        <staticContent>
            <!-- Set expire headers to 30 days for static content-->
            <clientCache cacheControlMode="UseMaxAge" cacheControlMaxAge="7.00:00:00" />
        </staticContent>
    </system.webServer>
</configuration>

test.html:

<!doctype html>
<html>
<head>
    <title>http://serverfault.com/questions/346975</title>
    <style>
        body > div
        {
            border:1px solid;
            padding:10px;
            margin:10px;
        }
    </style>
</head>
    <body>
        <div>
            <h2>Request JS file with Accepts: accept/nothing</h2>
            <b>Response Headers: </b>
            <pre id="responseHeaders-1">loading&hellip</pre>
        </div>

        <div>
            <h2>Request JS file with Accepts: */*</h2>
            <b>Response Headers: </b>
            <pre id="responseHeaders-2">loading&hellip</pre>
        </div>

        <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
        <script>
            var responseHeaders1 = $("#responseHeaders-1"),
                responseHeaders2 = $("#responseHeaders-2"),
                fetchScript = function (accepts, element, successMsg, errorMsg) {

                    var jXhr = $.ajax({
                        // fetch the resource "fresh" each time since we are testing the Cache-Control header and not caching itself
                        "url": "some-script.js?" + (new Date).getTime(),
                        "headers": {
                            "Accept" : accepts
                        },
                        "complete": function () {
                            var headers = jXhr.getAllResponseHeaders();
                            headers = headers.replace(/(Cache-Control:.+)/i, "<strong><u>$1</u></strong>");
                            element.html(headers);
                        },
                        "success": function () {
                            element.after("<div>" + successMsg + "</div>");
                        },
                        "error": function () {
                            element.after("<div>" + errorMsg + "</div>");
                        }
                    });
                };

                fetchScript("accept/nothing", responseHeaders1, "Uh, your server is sending stuff when the client doesn't accept it.", "Your server (probably) responded correctly.");
                fetchScript("*/*", responseHeaders2, "Your server responded correctly.", "Something went wrong.");
        </script>
    </body>
</html>
David Murdoch
fonte
Podemos reproduzir suas descobertas usando solicitações para o host local - você tentou fazer os mesmos testes em uma máquina remota?
Geoff Dalgas
Sim eu fiz. se.vervestudios.co/tests/se-test/test.html (nota para as pessoas do futuro, o link anterior foi apenas para e provavelmente fins de teste temporários não funciona mais, sorry)
David Murdoch
O erro incorporado nessa resposta expõe algumas informações um tanto arriscadas - veja aqui . Parece que seu servidor acredita que todas as solicitações foram emitidas localmente - consulte: iis.net/ConfigReference/system.webServer/httpErrors Se você ativar CustomErrors através de: <httpErrors errorMode = "Custom" />, você verá o mesmo problema que estamos enfrentando @ David
Geoff Dalgas
0

você deve especificar que tipo de conteúdo você irá armazenar em cache. por exemplo, você pode armazenar em cache scripts, css, image ..etc. então use a <location path ="Scripts">tag antes da <system.webServer>tag. para que sua configuração da web fique assim.

 <location path ="Scripts">
    <system.webServer>
      <staticContent>
        <clientCache cacheControlMode="UseMaxAge" cacheControlMaxAge="07:00:00" />
      </staticContent>
    </system.webServer>
  </location>
  <location path ="css">
    <system.webServer>
      <staticContent>
        <clientCache cacheControlMode="UseMaxAge" cacheControlMaxAge="07:00:00" />
      </staticContent>
    </system.webServer>
 </location>
Asanga Ambagaspitiya
fonte
Isso realmente aborda essa questão?
pintainhos