Jump to content

adrianmak

Members
  • Posts

    533
  • Joined

  • Last visited

Everything posted by adrianmak

  1. Probably the above configuration is a basic, you may adjust some of the values regarding proxy cache directives.
  2. nginx.conf user www-data; worker_processes 4; pid /run/nginx.pid; events { worker_connections 768; # multi_accept on; } http { sendfile on; tcp_nopush on; tcp_nodelay on; keepalive_timeout 65; types_hash_max_size 2048; include /etc/nginx/mime.types; default_type application/octet-stream; include /etc/nginx/cache.conf; access_log /var/log/nginx/access.log; error_log /var/log/nginx/error.log; gzip on; gzip_disable "msie6"; gzip_vary on; gzip_proxied any; gzip_comp_level 2; include /etc/nginx/conf.d/*.conf; include /etc/nginx/sites-enabled/*; } 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 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_ignore_headers Set-Cookie; proxy_ignore_headers "Cache-Control" "Expires"; root /var/www/html; index index.php index.html index.htm; server_name dev.local.net; location / { try_files $uri $uri/ /index.php?it=$uri&$args; } location ~ \.php$ { 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; } } A modified basic-page.php of pw installation profile <?php $lastModified=($page->last_modified); $etag = md5($page->body); $ifModifiedSince=(isset($_SERVER['HTTP_IF_MODIFIED_SINCE']) ? $_SERVER['HTTP_IF_MODIFIED_S INCE'] : 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: $etag"); header('Cache-Control: public'); //check if page has changed. If not, send 304 and exit if ((@strtotime($_SERVER['HTTP_IF_MODIFIED_SINCE'])===$lastModified) || $etagHeader == $et ag) { header("HTTP/1.1 304 Not Modified"); exit; } //$content = "This is a demo"; // basic-page.php template file // Primary content is the page's body copy $content = $page->body; //$content .= $etag; // 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; }
  3. Story: https://processwire.com/talk/topic/9250-what-should-i-do-to-make-pw-to-work-with-a-reverse-proxy-cache/ After a few days of reading documentation, I got processwire to work with nginx reverse proxy cache. This is not a tutorial on how to install server software. A working nginx config copy will be posted on next reply. Ubuntu 14.04.1 x64 Nginx 1.4.6 apache 2.4.7 mysql 5.6.19 php 5.6.6 (php5-fpm) A new copy of content will be fetched instantly. A screencast of this demo
  4. 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; } }
  5. 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 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.
  6. 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. 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.
  7. adrianmak

    .htaccess

    I found that the header Expires always is Thu, 19 Nov 1981 08:52:00 GMT
  8. It is just for caching static file like css, js and images. I'm talking about caching a page instead
  9. I'm evaluating pw running with HHVM. I tried to run a skyscraper pw profile which i found the most sophisticated pw profile right now. PW is working fine
  10. do u have any experience to make pw to work with varnish ?
  11. 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 ?
  12. anybody used server caching like varnish, nginx configured as content caching on your pw's project ?
  13. I'm having the same issue. This is my function (which is sit on another php file )to print archive post, similar as the wordpress archive widget <?php function archive () { $out = " <h3>Archive</h3> "; $start = new DateTime('2010-01-01'); //$start->modify('first day of this month'); $end = new DateTime('2015-02-01'); //$end->modify('first day of next month'); $interval = DateInterval::createFromDateString('1 month'); $period = new DatePeriod($start, $interval, $end); $a = array(); foreach ($period as $dt) { array_push($a, $dt); } $a = array_reverse($a); foreach ($a as $dt) { $d = $dt->format("Y-m-d"); $nextmonth = date('Y-m-d', strtotime('+1 month', strtotime($d))); $count = count($pages->find("template=post, post_date>=$d, post_date<$nextmonth")); if ($count > 0) { $out .= "<a href='{$pages->get('template=home')->url}" . date('Y', strtotime($d)) . "/" . date('m', strtotime($d)) . "'>" . date('M Y', strtotime($d)) . " (" . $count . ")" . "</a><br/>"; } } return $out; } In a template file, the code will looks <? include('./archive.php'); $out = "This is content."; $sidebar = archive(); $page->body .= $out; include('./main.php'); // the master output file I will get this error in the log Error: Call to a member function find() on a non-object (line 26 of /var/www/html/pw1/site/templates/archive.php)
  14. I read the pageArray. I could provide user option to supply more fields to render. I have a question, My page fields setup doesn't has a summary field, all content are put in body field. I could write a small utility function to output say first 20 words. Could it be possible to put in the option markup say teaser({body}) ? function teaser($str, $num) { $words = explode(" ", $str); $first = join(" ", array_slice($words, 0, $num)); return $first; }
  15. Learn from skyscrapper pw profile, it is easy to output a list of content with pagination with just a line of code $content = $page->children("limit=10")->render(); However, it output title only. How to output other fields ? for example, summary of content, an image,
  16. <?php foreach($page->parents() as $parent) { echo "<a href='{$parent->url}'>{$parent->title}</a> "; } That only works when current page has a parent actually. For some page without a a physical parent. For instance, I implemented a wordpress like archive url. That is the url is build with url segment, like, http://mydomain.com/2005/05/post-title Home +---Blog +----post1 +----post2 +----post3 where 2005 and 05 are url segment but not a physical page, and you will only get Blog as the parent of all posts. Instead, in more sense the breadcrumb should be like Home > 2005 > 05
  17. is there such a hook of something like after save, such that a post's id is ready , then I could alter the page url/name with this id
  18. what is the page name ($page->name) refer to ? the page url ?
  19. By default, a page title will be used for page url, could I use other url pattern (must be assigned automatically) like page id
  20. i'm thinking about, the form submit handling, built the form process with pw template or a external php script (which I'm being used). Which method is better ?
×
×
  • Create New...