Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it fine if first response is private with AppCache (Symfony2)?

I'm trying to use http caching. In my controller I'm setting a response as follows:

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

dev mode

In dev environment first response is a 200 with following headers:

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

For next 2 minutes every response is a 304 with following headers:

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

This is basically what I expect it to be.

prod mode

In prod mode response headers are different. Note that in app.php I wrap the kernel in AppCache.

First response is a 200 with following headers:

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

So it's a private no-cache response.

Every next request is pretty much what I'd expect it to be; a 304 with following headers:

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

Should I worry about it? Is it an expected behaviour?

What will happen if I put Varnish or Akamai server in front of it?

I did a bit of debugging and I figured that response is private because of last-modified header. HttpCache kernel uses EsiResponseCacheStrategy to update the cached response (HttpCache::handle() method).

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

EsiResponseCacheStrategy turns a response into non cacheable if it uses either Last-Response or ETag (EsiResponseCacheStrategy::add() method):

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

Response::isValidateable() returns true if Last-Response or ETag header is present.

It results in overwriting the Cache-Control header (EsiResponseCacheStrategy::update() method):

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

I asked this question on Symfony2 user group but I didn't get an answer so far: https://groups.google.com/d/topic/symfony2/6lpln11POq8/discussion

Update.

Since I no longer have access to the original code I tried to reproduce the scenario with the latest Symfony standard edition.

Response headers are more consistent now, but still seem to be wrong.

As soon as I set a Last-Modified header on the response, the first response made by a browser has a:

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

Second response has an expected:

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

If I avoid sending If-Modified-Since header, every request returns must-revalidate, no-cache, private.

It doesn't matter if the request was made in prod or dev environment anymore.

like image 271
Jakub Zalas Avatar asked Mar 05 '12 14:03

Jakub Zalas


1 Answers

I have faced same problem. I had to supply 'public' headers my cdn. By default when gateway caching is enabled in prod mode, it returns 200 OK with private, nocache must validate headers.

I solved problem this way.

In app.php, before I send response to user ($respond->send), I have overwritten the cache control header to blank and set cache headers to public and max age(some value).

//code snippet from app.php

    $response = $kernel->handle($request);     $response->headers->set('Cache-Control', '');     $response->setPublic();     $response->setMaxAge(86400);     $response->send();         
like image 83
srikanthsatturi Avatar answered Sep 21 '22 19:09

srikanthsatturi