Skip to content

Commit b8a4171

Browse files
authored
Merge pull request #15 from presslabs/page-cache-redis
Add support for page cache
2 parents 2064e41 + 4fd6851 commit b8a4171

File tree

4 files changed

+217
-3
lines changed

4 files changed

+217
-3
lines changed
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
# vim: set ft=nginx:
2+
3+
{{- $chosenBackend := default "" .Env.STACK_PAGE_CACHE_BACKEND }}
4+
{{- $redisHost := default "localhost" .Env.STACK_PAGE_CACHE_REDIS_HOST }}
5+
{{- $redisPort := default "6379" .Env.STACK_PAGE_CACHE_REDIS_PORT }}
6+
{{- $memcachedHost := default "127.0.0.1" .Env.STACK_PAGE_CACHE_MEMCACHED_HOST }}
7+
{{- $memcachedPort := default "11211" .Env.STACK_PAGE_CACHE_MEMCACHED_PORT }}
8+
9+
{{- if eq $chosenBackend "redis" }}
10+
11+
location = /.stack-cache-fetch {
12+
internal;
13+
14+
set $redis_key $args;
15+
redis_pass {{ $redisHost }}:{{ $redisPort }};
16+
}
17+
18+
location = /.stack-cache-store {
19+
internal;
20+
21+
set_unescape_uri $exptime $arg_exptime;
22+
set_unescape_uri $key $arg_key;
23+
24+
redis2_query set $key $echo_request_body;
25+
redis2_query expire $key $exptime;
26+
redis2_pass {{ $redisHost }}:{{ $redisPort }};
27+
}
28+
29+
{{- else if eq $chosenBackend "memcached" }}
30+
location = /.stack-cache-fetch {
31+
internal;
32+
33+
set $memc_key $args;
34+
35+
memc_connect_timeout 500ms;
36+
memc_read_timeout 500ms;
37+
memc_ignore_client_abort on;
38+
39+
memc_pass {{ $memcachedHost }}:{{ $memcachedPort }};
40+
}
41+
42+
location = /.stack-cache-store {
43+
internal;
44+
45+
set_unescape_uri $exptime $arg_exptime;
46+
set_unescape_uri $key $arg_key;
47+
48+
set $memc_key $key;
49+
set $memc_exptime $exptime;
50+
51+
memc_connect_timeout 500ms;
52+
memc_send_timeout 500ms;
53+
memc_ignore_client_abort on;
54+
55+
memc_pass {{ $memcachedHost }}:{{ $memcachedPort }};
56+
}
57+
{{- end }}

php/docker/templates/nginx-vhost-conf.d/80-index.conf

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,9 @@ location / {
55
}
66

77
location ~ \.php$ {
8-
fastcgi_pass $upstream;
8+
include /usr/local/docker/etc/nginx-vhost-conf.d/page-cache.d/*.conf;
9+
fastcgi_pass $upstream;
910
fastcgi_read_timeout {{ max 60 (add 10 (default "30" .Env.PHP_REQUEST_TIMEOUT | atoi)) }};
10-
fastcgi_index index.php;
11-
include /usr/local/openresty/nginx/conf/fastcgi.conf;
11+
fastcgi_index index.php;
12+
include /usr/local/openresty/nginx/conf/fastcgi.conf;
1213
}
Lines changed: 156 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,156 @@
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

Comments
 (0)