1+ # vim: set ft=nginx: 
2+ 
3+ {{ - $chosenBackend  := default ""  .Env.STACK_PAGE_CACHE_BACKEND }} 
4+ {{ - $allowedBackends  := list "redis"  "memcached"  "custom"  }} 
5+ {{ - $memcachedHost  := default "127.0.0.1"  .Env.STACK_PAGE_CACHE_MEMCACHED_HOST }} 
6+ {{ - $memcachedPort  := default "11211"  .Env.STACK_PAGE_CACHE_MEMCACHED_PORT }} 
7+ {{ - $truthStrings  := list "true"  "on"  "yes"  -}} 
8+ {{ - $keyPrefix  := default "nginx-cache:"  .Env.STACK_PAGE_CACHE_KEY_PREFIX }} 
9+ {{ - $keyUID  := default "https$request_method$host$request_uri"  .Env.STACK_PAGE_CACHE_KEY_UID }} 
10+ 
11+ {{ - if  has $chosenBackend  $allowedBackends  }} 
12+ set  $skip_cache  0; 
13+ 
14+ set_by_lua_block $skip_cache  { 
15+     local scheme = ngx.var.scheme
16+     local uri = ngx.var.request_uri
17+     local request = ngx.ctx.request or {} 
18+     ngx.ctx.request = request
19+     local user_agent = ngx.var.http_user_agent or '' 
20+     local request_method = ngx.req.get_method() 
21+ 
22+     re = {} 
23+     re.wp_loggedin = [[wordpress_logged_in|wordpress_no_cache|comment_author_|wp-postpass_|wp_gdsr_|fbs_|wp-query_monitor_]]
24+     re.woocommerce_cookies = [[woocommerce_cart_hash|woocommerce_items_in_cart|wp_woocommerce_session_]]
25+     re.woocommerce_args = [[remove_item|removed_item|remove_coupon|undo_item|order|add-to-cart|added-to-cart|revoke-key]]
26+     re.bbpress_cookies = [[EmailID]]
27+ 
28+     function find_plain( s, sub) 
29+         if  string.find( s, sub, 1, true)  == nil then
30+             return  false
31+         end
32+ 
33+         return  true
34+     end
35+ 
36+     request.is_wp_admin = ( 
37+         not ngx.re.match ( uri, "^.*/wp-admin/admin-ajax.php" ) 
38+         and ngx.re.match ( uri, "^.*/(wp-admin/|wp-login.php|wp-signup.php|wp-cron.php|xmlrpc.php|git-webhook.php|feed/|sitemap.xml|sitemap_index.xml)" , "o" ) 
39+     ) 
40+ 
41+     request.wp_loggedin = ( ngx.re.match ( ngx.var.http_cookie or '', re.wp_loggedin, 'io' )  and true or false) 
42+ 
43+     request.query_string = ( ngx.var.is_args or '') .. (ngx.var.args or '' ) 
44+ 
45+     request.is_woocommerce = ( 
46+         ngx.re.match ( request.query_string or '', re.woocommerce_args, 'io' )  or
47+         ( ngx.re.match ( ngx.var.http_cookie or '', re.woocommerce_cookies, 'io' )  and true)  or
48+         ( find_plain( uri, '/wc-api/') or ngx.re.match(request.query_string, 'wc-api=', 'o' )) 
49+     ) 
50+ 
51+     request.is_dynamic = ( 
52+         request.is_wp_admin or
53+         request.wp_loggedin or
54+         request.is_woocommerce or
55+         ( request_method ~ = 'GET'  and
56+         request_method ~ = 'HEAD' )  or
57+         -- skip cache if  there are query strings ( TODO: improve this logic for  better cache hit) 
58+         request.query_string ~ = '' 
59+     ) 
60+ 
61+     local cache_bypass = ( ngx.var.skip_cache or '0') ~= '0' 
62+         or ( ngx.re.match ( ngx.var.http_cookie or '', re.bbpress_cookies, 'io' )  and true) 
63+         or false
64+ 
65+     local skip_cache = 0
66+     if  request.is_dynamic or cache_bypass then
67+         skip_cache = 1
68+     end
69+ 
70+     return  skip_cache
71+ } 
72+ 
73+ set  $key  "" ; 
74+ set  $key_prefix  {{  $keyPrefix  }} ; 
75+ set  $key_uid  {{  $keyUID  }} ; 
76+ set  $escaped_key  "" ; 
77+ set_escape_uri $escaped_key_prefix  $key_prefix ; 
78+ set_escape_uri $escaped_key_uid  $key_uid ; 
79+ 
80+ # Use versioned keys with memcached by default, for implementing cache flush 
81+ {{ - if  and ( eq $chosenBackend  "memcached" )  (  has ( default "on"  .Env.STACK_PAGE_CACHE_MEMCACHED_USE_VERSION)  $truthStrings )  }} 
82+ rewrite_by_lua_block { 
83+     if  ngx.var.skip_cache == "1"  then
84+         return 
85+     end
86+ 
87+     local memcached = require "resty.memcached" 
88+ 
89+     local function identity( key)  return  key end
90+ 
91+     local memc, err = memcached:new{ 
92+         -- don't escape/unescape keys
93+         key_transform = {  identity, identity } 
94+     } 
95+ 
96+     if  not memc then
97+         ngx.log( ngx.ERR, "failed to instantiate memcached: " , err) 
98+         return 
99+     end
100+ 
101+     memc:set_timeout( 1000 ) 
102+ 
103+     local ok, err = memc:connect( "{{ $memcachedHost }}:{{ $memcachedPort }}" ) 
104+     if  not ok then
105+         ngx.log( ngx.ERR, "failed to connect to memcached: " , err) 
106+         return 
107+     end
108+ 
109+     local versionKey = ngx.var.key_prefix .. "version" 
110+ 
111+     local version, flags, err = memc:get( versionKey) 
112+     if  err then
113+         ngx.log( ngx.ERR, "failed to get memcached version: " , err) 
114+         return 
115+     end
116+ 
117+     if  not version then
118+         ngx.log( ngx.INFO, "memcached version not found, attempting to set one..." ) 
119+ 
120+         version = tostring( os.time())  .. ":" 
121+         local ok, err = memc:set ( versionKey, version) 
122+         if  not ok then
123+             ngx.log( ngx.ERR, "failed to set memcached version: " , err) 
124+             return 
125+         end
126+     end
127+ 
128+     ngx.var.key = ngx.var.key_prefix .. version .. ngx.var.key_uid
129+     ngx.var.escaped_key = ngx.var.escaped_key_prefix .. ngx.escape_uri( version)  .. ngx.var.escaped_key_uid
130+ 
131+     local ok, err = memc:close() 
132+     if  not ok then
133+         ngx.say( "failed to close memcached: " , err) 
134+         return 
135+     end
136+ } 
137+ 
138+ {{ - else }} 
139+ # default key is nginx-cache:https$request_method$host$request_uri 
140+ set  $key  $key_prefix$key_uid ; 
141+ set  $escaped_key  $escaped_key_prefix$escaped_key_uid ; 
142+ {{ - end }} 
143+ 
144+ srcache_fetch_skip $skip_cache ; 
145+ srcache_store_skip $skip_cache ; 
146+ srcache_store_statuses {{  default "200 301 302"  .Env.STACK_PAGE_CACHE_STORE_STATUSES }} ; 
147+ 
148+ # https://github.com/openresty/srcache-nginx-module#srcache_response_cache_control 
149+ srcache_response_cache_control {{  default "on"  .Env.STACK_PAGE_CACHE_RESPONSE_CACHE_CONTROL }} ; 
150+ 
151+ srcache_fetch GET /.stack-cache-fetch $key ; 
152+ srcache_store PUT /.stack-cache-store key=$escaped_key &exptime={{  default "360"  .Env.STACK_PAGE_CACHE_EXPIRE_SECONDS | atoi }} ; 
153+ 
154+ more_set_headers "x-cache-fetch $srcache_fetch_status" ; 
155+ 
156+ {{ - end }} 
0 commit comments