Czy to dobrze, jeśli pierwsza odpowiedź jest prywatna z AppCache (Symfony2)?

140

Próbuję użyć buforowania http. W moim kontrolerze ustawiam odpowiedź w następujący sposób:

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

tryb deweloperski

W środowisku deweloperskim pierwszą odpowiedzią jest 200 z następującymi nagłówkami:

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

Przez następne 2 minuty każda odpowiedź to 304 z następującymi nagłówkami:

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

Zasadniczo tego oczekuję.

tryb prod

W trybie produkcyjnym nagłówki odpowiedzi są różne. Zauważ, że w app.php zawijam jądro w AppCache.

Pierwsza odpowiedź to 200 z następującymi nagłówkami:

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

Więc jest to prywatna odpowiedź bez pamięci podręcznej.

Każda kolejna prośba jest mniej więcej tym, czego bym się spodziewał; a 304 z następującymi nagłówkami:

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

Powinienem się tym martwić? Czy jest to oczekiwane zachowanie?

Co się stanie, jeśli postawię przed nim serwer Varnish lub Akamai?

Zrobiłem trochę debugowania i doszedłem do wniosku, że odpowiedź jest prywatna z powodu ostatnio zmodyfikowanego nagłówka. Jądro HttpCache używa EsiResponseCacheStrategy do aktualizacji buforowanej odpowiedzi ( metoda HttpCache :: handle () ).

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

EsiResponseCacheStrategy zamienia odpowiedź w niebuforowalną, jeśli używa metody Last-Response lub ETag ( metoda EsiResponseCacheStrategy :: add () ):

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

Response :: isValidateable () zwraca wartość true, jeśli obecny jest nagłówek Last-Response lub ETag.

Powoduje to nadpisanie nagłówka Cache-Control ( metoda EsiResponseCacheStrategy :: update () ):

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

    return;
}

Zadałem to pytanie na grupie użytkowników Symfony2, ale do tej pory nie otrzymałem odpowiedzi: https://groups.google.com/d/topic/symfony2/6lpln11POq8/discussion

Aktualizacja.

Ponieważ nie mam już dostępu do oryginalnego kodu, próbowałem odtworzyć scenariusz w najnowszej standardowej edycji Symfony .

Nagłówki odpowiedzi są teraz bardziej spójne, ale nadal wydają się błędne.

Jak tylko ustawię Last-Modifiednagłówek odpowiedzi, pierwsza odpowiedź wysłana przez przeglądarkę ma:

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

Druga odpowiedź ma oczekiwane:

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

Jeśli unikam wysyłania If-Modified-Sincenagłówka, każde żądanie wraca must-revalidate, no-cache, private.

Nie ma znaczenia, czy żądanie zostało już wysłane w środowisku prodczy w devśrodowisku.

Jakub Zalas
źródło
3
kiedy wyłączam $ kernel = new AppCache ($ kernel); jest mi pokazywany jako publiczny. ale wtedy zawsze będzie odpowiadać kodem 200 ... używam jako revery proxy nginx.
Michael,
są twoje app.phpi app_dev.phpto samo? (ignorując debug i env)
Florian Klein
1
Nie mam już dostępu do tego projektu, więc nie mogę tego potwierdzić. Pamiętam, że kontrolery były domyślne z włączoną funkcją AppCache.
Jakub Zalas
1
@Florian Próbowałem odtworzyć problem i mam nieco inne zachowanie w najnowszej wersji Symfony (zobacz aktualizację).
Jakub Zalas
2
Czy debug=>trueustawiłbyś getOptions () w AppCache, aby uzyskać X-Symfony-Cachenagłówek?
denkiryokuhatsuden

Odpowiedzi:

9

Miałem ten sam problem. Musiałem dostarczyć nagłówki „publiczne” do mojego CDN. Domyślnie, gdy buforowanie bramy jest włączone w trybie produkcyjnym, zwraca 200 OK z prywatnym, nocache musi sprawdzić poprawność nagłówków.

W ten sposób rozwiązałem problem.

W app.php, zanim wyślę odpowiedź do użytkownika ($ respond-> send), nadpisałem nagłówek kontroli pamięci podręcznej na pusty i ustawiłem nagłówki pamięci podręcznej na publiczne i maksymalny wiek (pewna wartość).

// fragment kodu z app.php

    $response = $kernel->handle($request);
    $response->headers->set('Cache-Control', '');
    $response->setPublic();
    $response->setMaxAge(86400);
    $response->send();        
srikanthsatturi
źródło
Czy otrzymałeś odpowiedzi prywatne, mimo że zostały one ustawione jako publiczne w kontrolerze?
Jakub Zalas
Tak, jeśli włączę buforowanie bramy i uruchomię ją w trybie produkcyjnym. Potrzebowałem powyższego rozwiązania dla zawartości statycznej.
srikanthsatturi
-4

Zachowanie, którego doświadczasz, jest zamierzone. Dokumenty Symfony2 wyraźnie opisują sytuacje, w których używane są prywatne i publiczne , przy czym domyślnie jest to prywatność .

Udan
źródło
To nie moja sprawa, przepraszam.
Jakub Zalas