Skip to content

Commit 6b08180

Browse files
committed
implemented the srcache_request_cache_control directive to allow request headers "Cache-Control: no-cache" or "Pragma: no-cache" to force bypassing cache lookup. this directive is turned off by default.
1 parent fbcb7bb commit 6b08180

File tree

5 files changed

+229
-1
lines changed

5 files changed

+229
-1
lines changed

src/ngx_http_srcache_filter_module.c

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,13 @@ static ngx_command_t ngx_http_srcache_commands[] = {
115115
offsetof(ngx_http_srcache_loc_conf_t, cache_methods),
116116
&ngx_http_srcache_cache_method_mask },
117117

118+
{ ngx_string("srcache_request_cache_control"),
119+
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
120+
ngx_conf_set_flag_slot,
121+
NGX_HTTP_LOC_CONF_OFFSET,
122+
offsetof(ngx_http_srcache_loc_conf_t, req_cache_control),
123+
NULL },
124+
118125
ngx_null_command
119126
};
120127

@@ -275,7 +282,9 @@ ngx_http_srcache_header_filter(ngx_http_request_t *r)
275282

276283
dd("error page: %d", (int) r->error_page);
277284

278-
if (r->headers_out.status != NGX_HTTP_OK) {
285+
if (r->headers_out.status < NGX_HTTP_OK
286+
&& r->headers_out.status >= NGX_HTTP_SPECIAL_RESPONSE)
287+
{
279288
dd("fetch: ignore bad response with status %d",
280289
(int) r->headers_out.status);
281290

@@ -579,6 +588,8 @@ ngx_http_srcache_create_loc_conf(ngx_conf_t *cf)
579588

580589
conf->store_max_size = NGX_CONF_UNSET_SIZE;
581590

591+
conf->req_cache_control = NGX_CONF_UNSET;
592+
582593
return conf;
583594
}
584595

@@ -611,6 +622,8 @@ ngx_http_srcache_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
611622

612623
conf->cache_methods |= NGX_HTTP_GET|NGX_HTTP_HEAD;
613624

625+
ngx_conf_merge_value(conf->req_cache_control, prev->req_cache_control, 0);
626+
614627
return NGX_CONF_OK;
615628
}
616629

@@ -733,6 +746,21 @@ ngx_http_srcache_access_handler(ngx_http_request_t *r)
733746
return NGX_DECLINED;
734747
}
735748

749+
if (conf->req_cache_control) {
750+
if (ngx_http_srcache_request_no_cache(r) == NGX_OK) {
751+
/* register a ctx to give a chance to srcache_store to run */
752+
ctx = ngx_pcalloc(r->pool, sizeof(ngx_http_srcache_filter_module));
753+
754+
if (ctx == NULL) {
755+
return NGX_HTTP_INTERNAL_SERVER_ERROR;
756+
}
757+
758+
ngx_http_set_ctx(r, ctx, ngx_http_srcache_filter_module);
759+
760+
return NGX_DECLINED;
761+
}
762+
}
763+
736764
if (conf->fetch_skip != NULL
737765
&& ngx_http_complex_value(r, conf->fetch_skip, &skip) == NGX_OK
738766
&& skip.len

src/ngx_http_srcache_filter_module.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ typedef struct {
3333
ngx_http_complex_value_t *fetch_skip;
3434
ngx_http_complex_value_t *store_skip;
3535
ngx_uint_t cache_methods;
36+
ngx_flag_t req_cache_control;
3637

3738
unsigned postponed_to_access_phase_end;
3839
} ngx_http_srcache_loc_conf_t;

src/ngx_http_srcache_util.c

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -382,3 +382,59 @@ ngx_http_srcache_set_content_length_header(ngx_http_request_t *r, off_t len)
382382
}
383383

384384

385+
ngx_int_t
386+
ngx_http_srcache_request_no_cache(ngx_http_request_t *r)
387+
{
388+
ngx_table_elt_t *h;
389+
ngx_list_part_t *part;
390+
u_char *p;
391+
u_char *last;
392+
ngx_uint_t i;
393+
394+
part = &r->headers_in.headers.part;
395+
h = part->elts;
396+
397+
for (i = 0; /* void */; i++) {
398+
399+
if (i >= part->nelts) {
400+
if (part->next == NULL) {
401+
break;
402+
}
403+
404+
part = part->next;
405+
h = part->elts;
406+
i = 0;
407+
}
408+
409+
if (h[i].key.len == sizeof("Cache-Control") - 1
410+
&& ngx_strncasecmp(h[i].key.data, (u_char *) "Cache-Control",
411+
sizeof("Cache-Control") - 1) == 0)
412+
{
413+
p = h[i].value.data;
414+
last = p + h[i].value.len;
415+
416+
if (ngx_strlcasestrn(p, last, (u_char *) "no-cache", 8 - 1) != NULL)
417+
{
418+
return NGX_OK;
419+
}
420+
421+
continue;
422+
}
423+
424+
if (h[i].key.len == sizeof("Pragma") - 1
425+
&& ngx_strncasecmp(h[i].key.data, (u_char *) "Pragma",
426+
sizeof("Pragma") - 1) == 0)
427+
{
428+
p = h[i].value.data;
429+
last = p + h[i].value.len;
430+
431+
if (ngx_strlcasestrn(p, last, (u_char *) "no-cache", 8 - 1) != NULL)
432+
{
433+
return NGX_OK;
434+
}
435+
}
436+
}
437+
438+
return NGX_DECLINED;
439+
}
440+

src/ngx_http_srcache_util.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ ngx_int_t ngx_http_srcache_add_copy_chain(ngx_pool_t *pool,
3434
ngx_chain_t **chain, ngx_chain_t *in);
3535
ngx_int_t ngx_http_srcache_post_request_at_head(ngx_http_request_t *r,
3636
ngx_http_posted_request_t *pr);
37+
ngx_int_t ngx_http_srcache_request_no_cache(ngx_http_request_t *r);
3738

3839

3940
#endif /* NGX_HTTP_SRCACHE_UTIL_H */

t/req-cache-control.t

Lines changed: 142 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,142 @@
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: request cache-control: no-cache
89+
--- config
90+
location /foo {
91+
default_type text/css;
92+
srcache_fetch GET /memc $uri;
93+
srcache_store PUT /memc $uri;
94+
srcache_request_cache_control on;
95+
96+
echo world;
97+
}
98+
99+
location /memc {
100+
internal;
101+
102+
set $memc_key $query_string;
103+
set $memc_exptime 300;
104+
memc_pass 127.0.0.1:$TEST_NGINX_MEMCACHED_PORT;
105+
}
106+
--- request
107+
GET /foo
108+
--- more_headers
109+
cache-control: No-Cache
110+
--- response_headers
111+
Content-Type: text/css
112+
Content-Length:
113+
--- response_body
114+
world
115+
116+
117+
118+
=== TEST 5: basic fetch (cache hit again)
119+
--- config
120+
location /foo {
121+
default_type text/css;
122+
srcache_fetch GET /memc $uri;
123+
srcache_store PUT /memc $uri;
124+
125+
echo world;
126+
}
127+
128+
location /memc {
129+
internal;
130+
131+
set $memc_key $query_string;
132+
set $memc_exptime 300;
133+
memc_pass 127.0.0.1:$TEST_NGINX_MEMCACHED_PORT;
134+
}
135+
--- request
136+
GET /foo
137+
--- response_headers
138+
Content-Type: text/css
139+
Content-Length: 6
140+
--- response_body
141+
world
142+

0 commit comments

Comments
 (0)