Jump to content

What should I do to make pw to work with a reverse proxy cache ?


adrianmak
 Share

Recommended Posts

It's seems that pw core doesn't manipulate http header regarding caching.

Therefore, putting a reverse proxy in front of a web server is taking no effect on caching.

Could I write a module to plugin into pw to take care of http heder cache control ?

or should it be done in pw's core ?

Link to comment
Share on other sites

Before ProcessWire hands of to your templates' code it does not output any markup. So you should be able to change headers anytime before that and even in your templates' files if you're not outputting markup by yourself before that.

Link to comment
Share on other sites

It is just for caching static file like css, js and images. I'm talking about caching a page instead

Nope. That's just what the rules wrapped with FilesMatch-checks do. If you take a closer look, you'll spot that some rules are defined without any FilesMatch rules:

<IfModule mod_headers.c>
  ...
  Header unset ETag
  Header append Cache-Control "public"
</IfModule>

Of course you can specify whatever value you want to for these headers. What @LostKobrakai mentioned above is possible too, but I mostly prefer to use that for headers that depend on very specific page settings, need to contain some page-specific details, etc.

  • Like 1
Link to comment
Share on other sites

I'm added few lines of code for page/template required caching.

$maxAge = 300; // 5mins

header('Expires: '.gmdate('D, d M Y H:i:s', time() + $maxAge).' GMT', true);
header('Cache-Control: public, max-age='.$maxAge, true);
header('Pragma: ', true);

And it is working fine. As we can see cached content is hit.

post-2272-0-84302800-1425512266_thumb.pn

However, when a page's content is updated, front-end users have to wait for the cache expire date in order to get the new content.

In the above example. Users have to wait for 5 mins at most.

Is there something to do, to let the reverse proxy cache know the requested url is updated. In order to fetch cached copy, a new copy should fetch to the user.

Link to comment
Share on other sites

To find a way to make updating a page will let the reverse proxy cache know to grab a new copy.

I found this article

https://css-tricks.com/snippets/php/intelligent-php-cache-control/

The original code is

<?php
//get the last-modified-date of this very file
$lastModified=filemtime(__FILE__);
//get a unique hash of this file (etag)
$etagFile = md5_file(__FILE__);
//get the HTTP_IF_MODIFIED_SINCE header if set
$ifModifiedSince=(isset($_SERVER['HTTP_IF_MODIFIED_SINCE']) ? $_SERVER['HTTP_IF_MODIFIED_SINCE'] : false);
//get the HTTP_IF_NONE_MATCH header if set (etag: unique file hash)
$etagHeader=(isset($_SERVER['HTTP_IF_NONE_MATCH']) ? trim($_SERVER['HTTP_IF_NONE_MATCH']) : false);

//set last-modified header
header("Last-Modified: ".gmdate("D, d M Y H:i:s", $lastModified)." GMT");
//set etag-header
header("Etag: $etagFile");
//make sure caching is turned on
header('Cache-Control: public');

//check if page has changed. If not, send 304 and exit
if (@strtotime($_SERVER['HTTP_IF_MODIFIED_SINCE'])==$lastModified || $etagHeader == $etagFile)
{
       header("HTTP/1.1 304 Not Modified");
       exit;
}

//your normal code
echo "This page was last modified: ".date("d.m.Y H:i:s",time());

?>

I modified a little bit. Instead of generate a md5 checksum from filename. I used to generate md5 from a URI

the $etagFile will be

$etagFile = md5($_SERVER['REQUEST_URI'];

The caching works. After updating the php file content, I will get a new copy almost instantly :)

post-2272-0-83873100-1425550460_thumb.pn

Then I applied the same logic to a pw template. The pw site is using default multi-language installation profile.

I applied the code on basic-page.php template with some modification

The $lastModified var will get from a template field last_modified. This field will hook to a custom module, for every page save, this field will be update with the current date&time.

The $etagFile var will get from $page->URL

Then, the final code of basic-page.php will be

<?php
$lastModified=($page->last_modified);
$etagFile = md5($page->url);
$ifModifiedSince=(isset($_SERVER['HTTP_IF_MODIFIED_SINCE']) ? $_SERVER['HTTP_IF_MODIFIED_SINCE'] : false);
$etagHeader=(isset($_SERVER['HTTP_IF_NONE_MATCH']) ? trim($_SERVER['HTTP_IF_NONE_MATCH']) : false);

header("Last-Modified: ".gmdate("D, d M Y H:i:s", $lastModified)." GMT");
header("Etag: $etagFile");
header('Cache-Control: public');

//check if page has changed. If not, send 304 and exit
if (@strtotime($_SERVER['HTTP_IF_MODIFIED_SINCE'])==$lastModified || $etagHeader == $etagFile)
{
       header("HTTP/1.1 304 Not Modified");
       exit;
}

// basic-page.php template file

// Primary content is the page's body copy
$content = $page->body;
$content .= $etagFile;  // for debug info

// If the page has children, then render navigation to them under the body.
// See the _func.php for the renderNav example function.
if($page->hasChildren) $content .= renderNav($page->children, 0, 'summary');

// if the rootParent (section) page has more than 1 child, then render
// section navigation in the sidebar
if($page->rootParent->hasChildren > 1) {
        $sidebar = renderNav($page->rootParent, 3) . $page->sidebar;
}

Everything all set. Clicking several page refresh,
The response header always showing X-Cache-Stauts MISS

That's mean the page is not cached obviously.

Link to comment
Share on other sites

To simplify my test, I eliminated prependTemplateFile and appendTemplateFile file, and in the basic-page.php template, output the content body directly.

No other content.

But page is still not be cached.

I'm not sure it is a pw's problem (may be need special nginx tweaks to work with pw)

anybody could help ?

/etc/nginx/nginx.conf

user www-data;
worker_processes 4;
pid /run/nginx.pid;

events {
        worker_connections 768;
        # multi_accept on;
}

http {

        ##
        # Basic Settings
        ##

        sendfile on;
        tcp_nopush on;
        tcp_nodelay on;
        keepalive_timeout 65;
        types_hash_max_size 2048;
        # server_tokens off;

        # server_names_hash_bucket_size 64;
        # server_name_in_redirect off;

        include /etc/nginx/mime.types;
        default_type application/octet-stream;

        ##
        # Content caching
        ##

        include /etc/nginx/cache.conf;

        ##
        # Logging Settings

        access_log /var/log/nginx/access.log;
        error_log /var/log/nginx/error.log;

        ##
        # Gzip Settings
        ##

        gzip on;
        gzip_disable "msie6";

        gzip_vary on;
        # gzip_proxied any;
        # gzip_comp_level 6;
        # gzip_buffers 16 8k;
        # gzip_http_version 1.1;
        # gzip_types text/plain text/css application/json application/x-javascript text/xm
l application/xml application/xml+rss text/javascript;

        ##
        # nginx-naxsi config
        ##
        # Uncomment it if you installed nginx-naxsi
        ##

        #include /etc/nginx/naxsi_core.rules;

        ##
        # nginx-passenger config
        ##
        # Uncomment it if you installed nginx-passenger
        ##

        #passenger_root /usr;
        #passenger_ruby /usr/bin/ruby;

        ##
        # Virtual Host Configs
        ##

        include /etc/nginx/conf.d/*.conf;
        include /etc/nginx/sites-enabled/*;
}

/etc/nginx/cache.conf

proxy_cache_path /etc/nginx/cache levels=1:2 keys_zone=one:100m
           inactive=60m
           loader_threshold=300
           loader_files=200
           max_size=200m;
proxy_cache_key "$scheme$proxy_host$uri$is_args$args";

/etc/nginx/sites-available/default.conf

server {
        listen 80 default_server;

        proxy_cache one;
        add_header X-Cache-Status $upstream_cache_status;
        proxy_cache_valid any 1m;
        proxy_cache_min_uses 3;
        ##proxy_cache_bypass $cookie_nocache $arg_nocache$arg_comment;

        root /var/www/html;
        index index.php index.html index.htm;

        # Make site accessible from http://localhost/
        server_name dev.local.net;

        location / {
                try_files $uri $uri/ /index.php?it=$uri&$args;
        }

        location ~ \.php$ {
                # First attempt to serve request as file, then
                # as directory, then fall back to displaying a 404.
                #try_files $uri $uri/ /index.php;
                # Uncomment to enable naxsi on this location
                # include /etc/nginx/naxsi.rules
                #add_header X-Cache-Status $upstream_cache_status;
                #proxy_cache_valid any 1m;
                #proxy_cache_min_uses 3;
                #proxy_cache_bypass $cookie_nocache $arg_nocache$arg_comment;
                proxy_pass http://127.0.0.1:8080;
                proxy_set_header Host $host;
                proxy_set_header X-Real-IP $remote_addr;
                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
                proxy_set_header X-Forwarded-Proto $scheme;
        }

        location ~ /\. {
                deny all;
        }
}

Link to comment
Share on other sites

 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...