Est-ce bien si la première réponse est privée avec AppCache (Symfony2)?

140

J'essaye d'utiliser la mise en cache http. Dans mon contrôleur, je règle une réponse comme suit:

$response->setPublic();
$response->setMaxAge(120);
$response->setSharedMaxAge(120);
$response->setLastModified($lastModifiedAt);

mode de développement

Dans l'environnement de développement, la première réponse est un 200 avec les en-têtes suivants:

cache-control:max-age=120, public, s-maxage=120
last-modified:Wed, 29 Feb 2012 19:00:00 GMT

Pour les 2 prochaines minutes, chaque réponse est un 304 avec les en-têtes suivants:

cache-control:max-age=120, public, s-maxage=120

C'est essentiellement ce à quoi je m'attends.

mode prod

En mode production, les en-têtes de réponse sont différents. Notez que dans app.php, j'enveloppe le noyau dans AppCache.

La première réponse est un 200 avec les en-têtes suivants:

cache-control:must-revalidate, no-cache, private
last-modified:Thu, 01 Mar 2012 11:17:35 GMT

C'est donc une réponse privée sans cache.

Chaque demande suivante correspond à peu près à ce que j'attendais; un 304 avec les en-têtes suivants:

cache-control:max-age=120, public, s-maxage=120

Dois-je m'en soucier? Est-ce un comportement attendu?

Que se passera-t-il si je place le serveur Varnish ou Akamai devant lui?

J'ai fait un peu de débogage et j'ai pensé que la réponse était privée en raison de l'en-tête modifié en dernier. Le noyau HttpCache utilise EsiResponseCacheStrategy pour mettre à jour la réponse mise en cache ( méthode HttpCache :: handle () ).

if (HttpKernelInterface::MASTER_REQUEST === $type) {
    $this->esiCacheStrategy->update($response);
}

EsiResponseCacheStrategy transforme une réponse en non mise en cache si elle utilise Last-Response ou ETag ( méthode EsiResponseCacheStrategy :: add () ):

if ($response->isValidateable()) {
    $this->cacheable = false;
} else {
    // ... 
}

Response :: isValidateable () retourne true si l'en-tête Last-Response ou ETag est présent.

Il en résulte l' écrasement de l'en-tête Cache-Control ( méthode EsiResponseCacheStrategy :: update () ):

if (!$this->cacheable) {
    $response->headers->set('Cache-Control', 'no-cache, must-revalidate');

    return;
}

J'ai posé cette question sur le groupe d'utilisateurs Symfony2 mais je n'ai pas encore obtenu de réponse: https://groups.google.com/d/topic/symfony2/6lpln11POq8/discussion

Mettre à jour.

Comme je n'ai plus accès au code original, j'ai essayé de reproduire le scénario avec la dernière édition standard de Symfony .

Les en-têtes de réponse sont plus cohérents maintenant, mais semblent toujours être erronés.

Dès que j'ai défini un en- Last-Modifiedtête sur la réponse, la première réponse faite par un navigateur a un:

Cache-Control:must-revalidate, no-cache, private

La deuxième réponse a un attendu:

Cache-Control:max-age=120, public, s-maxage=120

Si j'évite d'envoyer un en- If-Modified-Sincetête, chaque demande revient must-revalidate, no-cache, private.

Peu importe si la demande a été faite dans prodou dans l' devenvironnement.

Jakub Zalas
la source
3
quand je désactive le $ kernel = new AppCache ($ kernel); il m'est montré comme public. mais alors il répondra toujours avec un code 200 ... J'utilise comme un proxy nginx rêver.
Michael
sont les vôtres app.phpet app_dev.phples mêmes? (ignorant le débogage et env)
Florian Klein
1
Je n'ai plus accès à ce projet donc je ne peux pas le confirmer. Je me souviens que les contrôleurs étaient ceux par défaut avec AppCache activé.
Jakub Zalas
1
@Florian J'ai essayé de reproduire le problème et j'ai un comportement un peu différent avec la dernière version de Symfony (voir une mise à jour).
Jakub Zalas
2
Voulez-vous définir debug=>truegetOptions () dans AppCache pour obtenir l'en- X-Symfony-Cachetête?
denkiryokuhatsuden

Réponses:

9

J'ai rencontré le même problème. J'ai dû fournir des en-têtes "publics" à mon cdn. Par défaut, lorsque la mise en cache de la passerelle est activée en mode prod, elle renvoie 200 OK avec private, nocache doit valider les en-têtes.

J'ai résolu le problème de cette façon.

Dans app.php, avant d'envoyer une réponse à l'utilisateur ($ respond-> send), j'ai écrasé l'en-tête de contrôle du cache pour qu'il soit vide et défini les en-têtes de cache sur public et max age (une certaine valeur).

// extrait de code de app.php

    $response = $kernel->handle($request);
    $response->headers->set('Cache-Control', '');
    $response->setPublic();
    $response->setMaxAge(86400);
    $response->send();        
srikanthsatturi
la source
Avez-vous obtenu des réponses privées malgré le fait qu'elles aient été rendues publiques dans un contrôleur?
Jakub Zalas
Oui, si j'active la mise en cache de la passerelle et l'exécute en mode prod. J'avais besoin de la solution ci-dessus pour le contenu statique.
srikanthsatturi
-4

Le comportement que vous rencontrez est intentionnel. Les documents Symfony2 décrivent explicitement les situations dans lesquelles privé et public sont utilisés, la valeur par défaut étant privée .

Udan
la source
Ce n'est pas mon cas, désolé.
Jakub Zalas