proxy_cache_pass, fastcgi_cache_bypass, uwsgi_cache_bypass, scgi_cache_bypass
diff --git a/src/http/modules/ngx_http_fastcgi_module.c b/src/http/modules/ngx_http_fastcgi_module.c
index 81a3a01..192de79 100644
--- a/src/http/modules/ngx_http_fastcgi_module.c
+++ b/src/http/modules/ngx_http_fastcgi_module.c
@@ -330,6 +330,13 @@
0,
&ngx_http_fastcgi_module },
+ { ngx_string("fastcgi_cache_bypass"),
+ NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE,
+ ngx_http_set_predicate_slot,
+ NGX_HTTP_LOC_CONF_OFFSET,
+ offsetof(ngx_http_fastcgi_loc_conf_t, upstream.cache_bypass),
+ NULL },
+
{ ngx_string("fastcgi_no_cache"),
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE,
ngx_http_set_predicate_slot,
@@ -1985,6 +1992,7 @@
#if (NGX_HTTP_CACHE)
conf->upstream.cache = NGX_CONF_UNSET_PTR;
conf->upstream.cache_min_uses = NGX_CONF_UNSET_UINT;
+ conf->upstream.cache_bypass = NGX_CONF_UNSET_PTR;
conf->upstream.no_cache = NGX_CONF_UNSET_PTR;
conf->upstream.cache_valid = NGX_CONF_UNSET_PTR;
#endif
@@ -2208,6 +2216,9 @@
conf->upstream.cache_methods |= NGX_HTTP_GET|NGX_HTTP_HEAD;
+ ngx_conf_merge_ptr_value(conf->upstream.cache_bypass,
+ prev->upstream.cache_bypass, NULL);
+
ngx_conf_merge_ptr_value(conf->upstream.no_cache,
prev->upstream.no_cache, NULL);
diff --git a/src/http/modules/ngx_http_proxy_module.c b/src/http/modules/ngx_http_proxy_module.c
index c1ae681..2fff21c 100644
--- a/src/http/modules/ngx_http_proxy_module.c
+++ b/src/http/modules/ngx_http_proxy_module.c
@@ -339,6 +339,13 @@
0,
&ngx_http_proxy_module },
+ { ngx_string("proxy_cache_bypass"),
+ NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE,
+ ngx_http_set_predicate_slot,
+ NGX_HTTP_LOC_CONF_OFFSET,
+ offsetof(ngx_http_proxy_loc_conf_t, upstream.cache_bypass),
+ NULL },
+
{ ngx_string("proxy_no_cache"),
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE,
ngx_http_set_predicate_slot,
@@ -1678,6 +1685,7 @@
#if (NGX_HTTP_CACHE)
conf->upstream.cache = NGX_CONF_UNSET_PTR;
conf->upstream.cache_min_uses = NGX_CONF_UNSET_UINT;
+ conf->upstream.cache_bypass = NGX_CONF_UNSET_PTR;
conf->upstream.no_cache = NGX_CONF_UNSET_PTR;
conf->upstream.cache_valid = NGX_CONF_UNSET_PTR;
#endif
@@ -1902,6 +1910,9 @@
|NGX_HTTP_UPSTREAM_FT_OFF;
}
+ ngx_conf_merge_ptr_value(conf->upstream.cache_bypass,
+ prev->upstream.cache_bypass, NULL);
+
ngx_conf_merge_ptr_value(conf->upstream.no_cache,
prev->upstream.no_cache, NULL);
diff --git a/src/http/modules/ngx_http_scgi_module.c b/src/http/modules/ngx_http_scgi_module.c
index 3524b63..9f89650 100644
--- a/src/http/modules/ngx_http_scgi_module.c
+++ b/src/http/modules/ngx_http_scgi_module.c
@@ -196,6 +196,13 @@
0,
&ngx_http_scgi_module },
+ { ngx_string("scgi_cache_bypass"),
+ NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE,
+ ngx_http_set_predicate_slot,
+ NGX_HTTP_LOC_CONF_OFFSET,
+ offsetof(ngx_http_scgi_loc_conf_t, upstream.cache_bypass),
+ NULL },
+
{ ngx_string("scgi_no_cache"),
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE,
ngx_http_set_predicate_slot,
@@ -1015,6 +1022,7 @@
#if (NGX_HTTP_CACHE)
conf->upstream.cache = NGX_CONF_UNSET_PTR;
conf->upstream.cache_min_uses = NGX_CONF_UNSET_UINT;
+ conf->upstream.cache_bypass = NGX_CONF_UNSET_PTR;
conf->upstream.no_cache = NGX_CONF_UNSET_PTR;
conf->upstream.cache_valid = NGX_CONF_UNSET_PTR;
#endif
@@ -1234,6 +1242,9 @@
conf->upstream.cache_methods |= NGX_HTTP_GET|NGX_HTTP_HEAD;
+ ngx_conf_merge_ptr_value(conf->upstream.cache_bypass,
+ prev->upstream.cache_bypass, NULL);
+
ngx_conf_merge_ptr_value(conf->upstream.no_cache,
prev->upstream.no_cache, NULL);
diff --git a/src/http/modules/ngx_http_uwsgi_module.c b/src/http/modules/ngx_http_uwsgi_module.c
index e4ed1f0..f27a3dc 100644
--- a/src/http/modules/ngx_http_uwsgi_module.c
+++ b/src/http/modules/ngx_http_uwsgi_module.c
@@ -223,6 +223,13 @@
0,
&ngx_http_uwsgi_module },
+ { ngx_string("uwsgi_cache_bypass"),
+ NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE,
+ ngx_http_set_predicate_slot,
+ NGX_HTTP_LOC_CONF_OFFSET,
+ offsetof(ngx_http_uwsgi_loc_conf_t, upstream.cache_bypass),
+ NULL },
+
{ ngx_string("uwsgi_no_cache"),
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE,
ngx_http_set_predicate_slot,
@@ -1068,6 +1075,7 @@
#if (NGX_HTTP_CACHE)
conf->upstream.cache = NGX_CONF_UNSET_PTR;
conf->upstream.cache_min_uses = NGX_CONF_UNSET_UINT;
+ conf->upstream.cache_bypass = NGX_CONF_UNSET_PTR;
conf->upstream.no_cache = NGX_CONF_UNSET_PTR;
conf->upstream.cache_valid = NGX_CONF_UNSET_PTR;
#endif
@@ -1287,6 +1295,9 @@
conf->upstream.cache_methods |= NGX_HTTP_GET|NGX_HTTP_HEAD;
+ ngx_conf_merge_ptr_value(conf->upstream.cache_bypass,
+ prev->upstream.cache_bypass, NULL);
+
ngx_conf_merge_ptr_value(conf->upstream.no_cache,
prev->upstream.no_cache, NULL);
diff --git a/src/http/ngx_http_cache.h b/src/http/ngx_http_cache.h
index 20544d1..36b14b2 100644
--- a/src/http/ngx_http_cache.h
+++ b/src/http/ngx_http_cache.h
@@ -14,11 +14,12 @@
#define NGX_HTTP_CACHE_MISS 1
-#define NGX_HTTP_CACHE_EXPIRED 2
-#define NGX_HTTP_CACHE_STALE 3
-#define NGX_HTTP_CACHE_UPDATING 4
-#define NGX_HTTP_CACHE_HIT 5
-#define NGX_HTTP_CACHE_SCARCE 6
+#define NGX_HTTP_CACHE_BYPASS 2
+#define NGX_HTTP_CACHE_EXPIRED 3
+#define NGX_HTTP_CACHE_STALE 4
+#define NGX_HTTP_CACHE_UPDATING 5
+#define NGX_HTTP_CACHE_HIT 6
+#define NGX_HTTP_CACHE_SCARCE 7
#define NGX_HTTP_CACHE_KEY_LEN 16
@@ -122,6 +123,7 @@
ngx_int_t ngx_http_file_cache_new(ngx_http_request_t *r);
+ngx_int_t ngx_http_file_cache_create(ngx_http_request_t *r);
void ngx_http_file_cache_create_key(ngx_http_request_t *r);
ngx_int_t ngx_http_file_cache_open(ngx_http_request_t *r);
void ngx_http_file_cache_set_header(ngx_http_request_t *r, u_char *buf);
diff --git a/src/http/ngx_http_file_cache.c b/src/http/ngx_http_file_cache.c
index 9df954f..2fefe09 100644
--- a/src/http/ngx_http_file_cache.c
+++ b/src/http/ngx_http_file_cache.c
@@ -46,6 +46,7 @@
ngx_str_t ngx_http_cache_status[] = {
ngx_string("MISS"),
+ ngx_string("BYPASS"),
ngx_string("EXPIRED"),
ngx_string("STALE"),
ngx_string("UPDATING"),
@@ -165,6 +166,38 @@
}
+ngx_int_t
+ngx_http_file_cache_create(ngx_http_request_t *r)
+{
+ ngx_http_cache_t *c;
+ ngx_pool_cleanup_t *cln;
+ ngx_http_file_cache_t *cache;
+
+ ngx_http_file_cache_create_key(r);
+
+ c = r->cache;
+ cache = c->file_cache;
+
+ cln = ngx_pool_cleanup_add(r->pool, 0);
+ if (cln == NULL) {
+ return NGX_ERROR;
+ }
+
+ if (ngx_http_file_cache_exists(cache, c) == NGX_ERROR) {
+ return NGX_ERROR;
+ }
+
+ cln->handler = ngx_http_file_cache_cleanup;
+ cln->data = c;
+
+ if (ngx_http_file_cache_name(r, cache->path) != NGX_OK) {
+ return NGX_ERROR;
+ }
+
+ return NGX_OK;
+}
+
+
void
ngx_http_file_cache_create_key(ngx_http_request_t *r)
{
diff --git a/src/http/ngx_http_upstream.c b/src/http/ngx_http_upstream.c
index 51c34c8..8ee5aea 100644
--- a/src/http/ngx_http_upstream.c
+++ b/src/http/ngx_http_upstream.c
@@ -633,9 +633,17 @@
if (c == NULL) {
- rc = ngx_http_test_predicates(r, u->conf->no_cache);
- if (rc != NGX_OK) {
- return rc;
+ switch (ngx_http_test_predicates(r, u->conf->cache_bypass)) {
+
+ case NGX_ERROR:
+ return NGX_ERROR;
+
+ case NGX_DECLINED:
+ u->cache_status = NGX_HTTP_CACHE_BYPASS;
+ return NGX_DECLINED;
+
+ default: /* NGX_OK */
+ break;
}
if (!(r->method & u->conf->cache_methods)) {
@@ -2090,6 +2098,47 @@
r->cache->file.fd = NGX_INVALID_FILE;
}
+ switch (ngx_http_test_predicates(r, u->conf->no_cache)) {
+
+ case NGX_ERROR:
+ ngx_http_upstream_finalize_request(r, u, 0);
+ return;
+
+ case NGX_DECLINED:
+ u->cacheable = 0;
+ break;
+
+ default: /* NGX_OK */
+
+ if (u->cache_status == NGX_HTTP_CACHE_BYPASS) {
+
+ if (ngx_http_file_cache_new(r) != NGX_OK) {
+ ngx_http_upstream_finalize_request(r, u, 0);
+ return;
+ }
+
+ if (u->create_key(r) != NGX_OK) {
+ ngx_http_upstream_finalize_request(r, u, 0);
+ return;
+ }
+
+ /* TODO: add keys */
+
+ r->cache->min_uses = u->conf->cache_min_uses;
+ r->cache->body_start = u->conf->buffer_size;
+ r->cache->file_cache = u->conf->cache->data;
+
+ if (ngx_http_file_cache_create(r) != NGX_OK) {
+ ngx_http_upstream_finalize_request(r, u, 0);
+ return;
+ }
+
+ u->cacheable = 1;
+ }
+
+ break;
+ }
+
if (u->cacheable) {
time_t now, valid;
diff --git a/src/http/ngx_http_upstream.h b/src/http/ngx_http_upstream.h
index bcdfc5f..ef460a4 100644
--- a/src/http/ngx_http_upstream.h
+++ b/src/http/ngx_http_upstream.h
@@ -163,7 +163,8 @@
ngx_uint_t cache_methods;
ngx_array_t *cache_valid;
- ngx_array_t *no_cache; /* ngx_http_complex_value_t */
+ ngx_array_t *cache_bypass;
+ ngx_array_t *no_cache;
#endif
ngx_array_t *store_lengths;