Я пытаюсь вызвать кэширование очень неприятной части Сценария PHP, который активно пытается сопротивляться кэшированию ни на каком серьезном основании путем активной установки всех заголовков антикэша:
Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0
Content-Type: text/html; charset=UTF-8
Date: Thu, 22 May 2014 08:43:53 GMT
Expires: Thu, 19 Nov 1981 08:52:00 GMT
Last-Modified:
Pragma: no-cache
Set-Cookie: ECSESSID=...; path=/
Vary: User-Agent,Accept-Encoding
Server: Apache/2.4.6 (Ubuntu)
X-Powered-By: PHP/5.5.3-1ubuntu2.3
Если вообще преодолимый я не хочу должным быть изменять эту стороннюю часть кода вообще и вместо этого просто заставлять Apache кэшировать страницу некоторое время. Я делаю это очень выборочно только к очень определенным страницам, которые не оказывают реального влияния на сеансовые куки и т.п., т.е. которые не содержат персонализированной информации.
CacheDefaultExpire 600
CacheMinExpire 600
CacheMaxExpire 1800
CacheHeader On
CacheDetailHeader On
CacheIgnoreHeaders Set-Cookie
CacheIgnoreCacheControl On
CacheIgnoreNoLastMod On
CacheStoreExpired On
CacheStoreNoStore On
CacheLock On
CacheEnable disk /the/script.php
Apache кэширует страницу хорошо:
[cache:debug] AH00698: cache: Key for entity /the/script.php?(null) is http://example.com:80/the/script.php?
[cache_disk:debug] AH00709: Recalled cached URL info header http://example.com:80/the/script.php?
[cache_disk:debug] AH00720: Recalled headers for URL http://example.com:80/the/script.php?
[cache:debug] AH00695: Cached response for /the/script.php isn't fresh. Adding conditional request headers.
[cache:debug] AH00750: Adding CACHE_SAVE filter for /the/script.php
[cache:debug] AH00751: Adding CACHE_REMOVE_URL filter for /the/script.php
[cache:debug] AH00769: cache: Caching url: /the/script.php
[cache:debug] AH00770: cache: Removing CACHE_REMOVE_URL filter.
[cache_disk:debug] AH00737: commit_entity: Headers and body for URL http://example.com:80/the/script.php? cached.
Однако это всегда настаивает, что "кэшируемый ответ не нов" и никогда не обслуживает кэшированную версию. Я предполагаю, что это имеет отношение Expires
заголовок, который отмечает документ, как истекли (но я не знаю, является ли это корректным предположением). Я попытался перезаписать и сбросить заголовки с помощью mod_headers, но это не помогает; безотносительно комбинации я пробую кэш, не впечатлен вообще. Я предполагаю, что порядок операции является неправильным, и заголовки переписываются после того, как кэш видит их. early
обработка заголовка не помогает также. Я экспериментировал с CacheQuickHandler Off
и пытаясь установить явные цепочки фильтра, но ничто не помогает. Но я действительно главным образом ввожу по абсолютному адресу в темноте, поскольку у меня нет большого опыта с конфигурированием цепочек фильтра Apache.
Существует ли прямое решение для того, как кэшировать эту неприятную часть кода?
Пустой Last-Modified: заголовок делает запрос не кэшируемым.
Итак, первое, что нужно сделать, это сгенерировать один, одно решение - использовать php auto_prepend_file
:
Создать файл prepend.php
с содержимым, подобным этому:
<?php header("Last-Modified:" . gmdate("D, d M Y H:i:s"), " GMT"); ?>
Затем добавить в конфигурацию vhost директиву: php_value auto_prepend_file path_to_prepend.php
На этом этапе необходимо проверить, что ответ сервера имеет правильный заголовок Last-Modified:
. Если нет, то мы не сможем его кэшировать, если да, может быть ваша работа с mod_headers и mod_cache сейчас работает?
Если нет, то вы можете использовать squid и apache следующим образом:
В вашем корректном vhost'е просто включите mod_rewrite
и используйте его для перенаправления трафика, который вы хотите кэшировать:
<VirtualHost your_current_virtual_host:80> ServerName your.site.com .. RewriteEngine on # This enables the caching server to see the request as http://your.site.com/.. ProxyPreserveHost on # This should be at VirtualHost level, not <Directory> or .htaccess # The DoSquid env variable decides if we send the request to the cache server # Adjust it for your needs RewriteRule /the/script.php - [E=DoSquid:Yes] # POSTs are not cacheable RewriteCond %{REQUEST_METHOD} ^POST$ RewriteRule .* - [E:DoSquid:No] # Feel free to add any rule which makes sense for your needs # Requests from localhost are calls from the "primary" vhost ( see below ) RewriteCond %{REMOTE_ADDR} ^127\.0\.0\.1$ [E:DoSquid:No] RewriteCond %{ENV:DoSquid} ^Yes$ RewriteRule /the/script.php http://ip_of_caching_server/this/script.php [P,L,QSA] .. .. <VirtualHost/> # This VirtualHost will be accessed by your caching server as the primary server for your site # Port 8009 can be anything, it just must be a separate virtual host <VirtualHost your_current_virtual_host:8009> ServerName your.site.com .. RewriteEngine on # Here a make a massive usage of mod_headers in order to have a cacheable response # Needless to say, this might completely break your application. The responses are # Completely anonymized Header unset Set-Cookie Header unset Etag Header unset Pragma RequestHeader unset Cookie # Now fix the Cache-Control header.. Header merge Cache-Control public # The max-age is a pain. We have to set one if it's not set, and we have to change it if it's 0 Header merge Cache-Control "max-age=bidon" # Case when we have: Cache-Control max-age=.., .... Header edit Cache-Control "^(.*)max-age=(.*)max-age=bidon, (.*)$" $1max-age=$2$3 # Case when we have: Cache-Control yyy=bidon, max-age=.." Header edit Cache-Control "^(.*)max-age=(.*), max-age=bidon$" $1max-age=$2 # Now Replace the value if there was not a max-age, set to 10mn Header edit Cache-Control "max-age=bidon" "max-age=600" # Now Replace the value if there was a max-age=0, set to 10mn Header edit Cache-Control "max-age=0" "max-age=600" # Remove Cache-Control parameters which prevent caching Header edit Cache-Control "no-cache, " "" Header edit Cache-Control "no-store, " "" Header edit Cache-Control "post-check=0, " "" Header edit Cache-Control "pre-check=0, " "" Header edit Cache-Control "must-revalidate, " "" # The request is now forwarded to the first vhost. It will not loop because we do not cache requests from 127.0.0.1 ProxyPreserveHost on RewriteRule ^(.*)$ http://127.0.0.1/$1 [P,L,QSA] .. .. <VirtualHost/>
Вероятно, вы можете использовать что угодно: squid, apache, paint. с помощью squid вы должны настроить его как обратный прокси и объявить cache_peer your.site.com parent 8009 0 no-query originserver ...
.
Может быть, вы просто включите mod_cache
во втором vhost, чтобы получить то, что вы хотите.