Skip to content

Commit f935928

Browse files
committed
implemented the srcache_cache_methods directive to specify request methods that are cacheable, by default, only GET and HEAD are cacheable.
1 parent f2061c8 commit f935928

File tree

3 files changed

+250
-11
lines changed

3 files changed

+250
-11
lines changed

src/ngx_http_srcache_filter_module.c

Lines changed: 52 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1+
#ifndef DDEBUG
12
#define DDEBUG 0
3+
#endif
24
#include "ddebug.h"
35

46
/*
@@ -46,6 +48,16 @@ static ngx_int_t ngx_http_srcache_fetch_subrequest(ngx_http_request_t *r,
4648
ngx_http_srcache_loc_conf_t *conf, ngx_http_srcache_ctx_t *ctx);
4749

4850

51+
static ngx_conf_bitmask_t ngx_http_srcache_cache_method_mask[] = {
52+
{ ngx_string("GET"), NGX_HTTP_GET},
53+
{ ngx_string("HEAD"), NGX_HTTP_HEAD },
54+
{ ngx_string("POST"), NGX_HTTP_POST },
55+
{ ngx_string("PUT"), NGX_HTTP_PUT },
56+
{ ngx_string("DELETE"), NGX_HTTP_DELETE },
57+
{ ngx_null_string, 0 }
58+
};
59+
60+
4961
static ngx_command_t ngx_http_srcache_commands[] = {
5062

5163
{ ngx_string("srcache_buffer"),
@@ -96,6 +108,13 @@ static ngx_command_t ngx_http_srcache_commands[] = {
96108
offsetof(ngx_http_srcache_loc_conf_t, store_skip),
97109
NULL },
98110

111+
{ ngx_string("srcache_cache_methods"),
112+
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE,
113+
ngx_conf_set_bitmask_slot,
114+
NGX_HTTP_LOC_CONF_OFFSET,
115+
offsetof(ngx_http_srcache_loc_conf_t, cache_methods),
116+
&ngx_http_srcache_cache_method_mask },
117+
99118
ngx_null_command
100119
};
101120

@@ -234,6 +253,10 @@ ngx_http_srcache_header_filter(ngx_http_request_t *r)
234253
return ngx_http_next_header_filter(r);
235254
}
236255

256+
if (!(r->method | slcf->cache_methods)) {
257+
return ngx_http_next_header_filter(r);
258+
}
259+
237260
if (slcf->store_skip != NULL
238261
&& ngx_http_complex_value(r, slcf->store_skip, &skip) == NGX_OK
239262
&& skip.len
@@ -532,24 +555,29 @@ ngx_http_srcache_filter_init(ngx_conf_t *cf)
532555
static void *
533556
ngx_http_srcache_create_loc_conf(ngx_conf_t *cf)
534557
{
535-
ngx_http_srcache_loc_conf_t *slcf;
558+
ngx_http_srcache_loc_conf_t *conf;
536559

537-
slcf = ngx_palloc(cf->pool, sizeof(ngx_http_srcache_loc_conf_t));
538-
if (slcf == NULL) {
560+
conf = ngx_pcalloc(cf->pool, sizeof(ngx_http_srcache_loc_conf_t));
561+
if (conf == NULL) {
539562
return NULL;
540563
}
541564

542-
slcf->fetch = NGX_CONF_UNSET_PTR;
543-
slcf->store = NGX_CONF_UNSET_PTR;
565+
/*
566+
* set by ngx_pcalloc():
567+
*
568+
* conf->fetch_skip = NULL;
569+
* conf->store_skip = NULL;
570+
* conf->cache_methods = 0;
571+
*/
544572

545-
slcf->fetch_skip = NULL;
546-
slcf->store_skip = NULL;
573+
conf->fetch = NGX_CONF_UNSET_PTR;
574+
conf->store = NGX_CONF_UNSET_PTR;
547575

548-
slcf->buf_size = NGX_CONF_UNSET_SIZE;
576+
conf->buf_size = NGX_CONF_UNSET_SIZE;
549577

550-
slcf->store_max_size = NGX_CONF_UNSET_SIZE;
578+
conf->store_max_size = NGX_CONF_UNSET_SIZE;
551579

552-
return slcf;
580+
return conf;
553581
}
554582

555583

@@ -575,6 +603,12 @@ ngx_http_srcache_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
575603
conf->store_skip = prev->store_skip;
576604
}
577605

606+
if (conf->cache_methods == 0) {
607+
conf->cache_methods = prev->cache_methods;
608+
}
609+
610+
conf->cache_methods |= NGX_HTTP_GET|NGX_HTTP_HEAD;
611+
578612
return NGX_CONF_OK;
579613
}
580614

@@ -690,6 +724,13 @@ ngx_http_srcache_access_handler(ngx_http_request_t *r)
690724

691725
dd("store defined? %p", conf->store);
692726

727+
dd("req method: %lu", (unsigned long) r->method);
728+
dd("cache methods: %lu", (unsigned long) conf->cache_methods);
729+
730+
if (!(r->method & conf->cache_methods)) {
731+
return NGX_DECLINED;
732+
}
733+
693734
if (conf->fetch_skip != NULL
694735
&& ngx_http_complex_value(r, conf->fetch_skip, &skip) == NGX_OK
695736
&& skip.len
@@ -736,7 +777,7 @@ ngx_http_srcache_access_handler(ngx_http_request_t *r)
736777

737778
dd("sending header");
738779

739-
if (ctx->body_from_cache) {
780+
if (ctx->body_from_cache && !(r->method & NGX_HTTP_HEAD)) {
740781
len = 0;
741782

742783
for (cl = ctx->body_from_cache; cl->next; cl = cl->next) {

src/ngx_http_srcache_filter_module.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ typedef struct {
3232
size_t store_max_size;
3333
ngx_http_complex_value_t *fetch_skip;
3434
ngx_http_complex_value_t *store_skip;
35+
ngx_uint_t cache_methods;
3536

3637
unsigned postponed_to_access_phase_end;
3738
} ngx_http_srcache_loc_conf_t;

t/methods.t

Lines changed: 197 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,197 @@
1+
# vi:filetype=
2+
3+
use lib 'lib';
4+
use Test::Nginx::Socket;
5+
6+
#repeat_each(2);
7+
8+
plan tests => repeat_each() * 4 * blocks();
9+
10+
$ENV{TEST_NGINX_MEMCACHED_PORT} ||= 11211;
11+
12+
#master_on();
13+
no_shuffle();
14+
15+
run_tests();
16+
17+
__DATA__
18+
19+
=== TEST 1: flush all
20+
--- config
21+
location /flush {
22+
set $memc_cmd 'flush_all';
23+
memc_pass 127.0.0.1:$TEST_NGINX_MEMCACHED_PORT;
24+
}
25+
--- response_headers
26+
Content-Type: text/plain
27+
Content-Length: 4
28+
--- request
29+
GET /flush
30+
--- response_body eval: "OK\r\n"
31+
32+
33+
34+
=== TEST 2: basic fetch (cache miss)
35+
--- config
36+
location /foo {
37+
default_type text/css;
38+
srcache_fetch GET /memc $uri;
39+
srcache_store PUT /memc $uri;
40+
41+
echo hello;
42+
}
43+
44+
location /memc {
45+
internal;
46+
47+
set $memc_key $query_string;
48+
set $memc_exptime 300;
49+
memc_pass 127.0.0.1:$TEST_NGINX_MEMCACHED_PORT;
50+
}
51+
--- request
52+
GET /foo
53+
--- response_headers
54+
Content-Type: text/css
55+
Content-Length:
56+
--- response_body
57+
hello
58+
59+
60+
61+
=== TEST 3: basic fetch (cache hit)
62+
--- config
63+
location /foo {
64+
default_type text/css;
65+
srcache_fetch GET /memc $uri;
66+
srcache_store PUT /memc $uri;
67+
68+
echo world;
69+
}
70+
71+
location /memc {
72+
internal;
73+
74+
set $memc_key $query_string;
75+
set $memc_exptime 300;
76+
memc_pass 127.0.0.1:$TEST_NGINX_MEMCACHED_PORT;
77+
}
78+
--- request
79+
GET /foo
80+
--- response_headers
81+
Content-Type: text/css
82+
Content-Length: 6
83+
--- response_body
84+
hello
85+
86+
87+
88+
=== TEST 4: basic fetch (POST cache miss for POST by default)
89+
--- config
90+
location /foo {
91+
default_type text/css;
92+
srcache_fetch GET /memc $uri;
93+
srcache_store PUT /memc $uri;
94+
95+
echo world;
96+
}
97+
98+
location /memc {
99+
internal;
100+
101+
set $memc_key $query_string;
102+
set $memc_exptime 300;
103+
memc_pass 127.0.0.1:$TEST_NGINX_MEMCACHED_PORT;
104+
}
105+
--- request
106+
POST /foo
107+
hiya, china
108+
--- response_headers
109+
Content-Type: text/css
110+
! Content-Length
111+
--- response_body
112+
world
113+
114+
115+
116+
=== TEST 5: basic fetch (POST cache hit if we enable POST explicitly)
117+
--- config
118+
location /foo {
119+
default_type text/css;
120+
srcache_fetch GET /memc $uri;
121+
srcache_store PUT /memc $uri;
122+
srcache_cache_methods POST;
123+
124+
echo world;
125+
}
126+
127+
location /memc {
128+
internal;
129+
130+
set $memc_key $query_string;
131+
set $memc_exptime 300;
132+
memc_pass 127.0.0.1:$TEST_NGINX_MEMCACHED_PORT;
133+
}
134+
--- request
135+
POST /foo
136+
hiya, china
137+
--- response_headers
138+
Content-Type: text/css
139+
Content-Length: 6
140+
--- response_body
141+
hello
142+
143+
144+
145+
=== TEST 6: basic fetch (GET still cache hit if we enable POST and PUT explicitly)
146+
--- config
147+
location /foo {
148+
default_type text/css;
149+
srcache_fetch GET /memc $uri;
150+
srcache_store PUT /memc $uri;
151+
srcache_cache_methods POST PUT;
152+
153+
echo world;
154+
}
155+
156+
location /memc {
157+
internal;
158+
159+
set $memc_key $query_string;
160+
set $memc_exptime 300;
161+
memc_pass 127.0.0.1:$TEST_NGINX_MEMCACHED_PORT;
162+
}
163+
--- request
164+
GET /foo
165+
--- response_headers
166+
Content-Type: text/css
167+
Content-Length: 6
168+
--- response_body
169+
hello
170+
171+
172+
173+
=== TEST 7: basic fetch (HEAD still cache hit if we enable POST explicitly)
174+
--- config
175+
location /foo {
176+
default_type text/css;
177+
srcache_fetch GET /memc $uri;
178+
srcache_store PUT /memc $uri;
179+
srcache_cache_methods POST;
180+
181+
echo world;
182+
}
183+
184+
location /memc {
185+
internal;
186+
187+
set $memc_key $query_string;
188+
set $memc_exptime 300;
189+
memc_pass 127.0.0.1:$TEST_NGINX_MEMCACHED_PORT;
190+
}
191+
--- request
192+
HEAD /foo
193+
--- response_headers
194+
Content-Type: text/css
195+
Content-Length: 0
196+
--- response_body
197+

0 commit comments

Comments
 (0)