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.


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();        

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 .


Ce n'est pas mon cas, désolé.
— Jakub Zalas
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.