Skip to content

Instantly share code, notes, and snippets.

@hnakamur
Created November 21, 2016 00:57
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save hnakamur/18993e5258d99b08dab21b6e26713c49 to your computer and use it in GitHub Desktop.
Save hnakamur/18993e5258d99b08dab21b6e26713c49 to your computer and use it in GitHub Desktop.
diff between github.com/FRiCKLE/ngx_cache_purge and github.com/nginx-modules/ngx_cache_purge
diff -ruNb -x .git github.com/FRiCKLE/ngx_cache_purge/CHANGES github.com/nginx-modules/ngx_cache_purge/CHANGES
--- github.com/FRiCKLE/ngx_cache_purge/CHANGES 2016-10-04 15:24:37.166263127 +0900
+++ github.com/nginx-modules/ngx_cache_purge/CHANGES 2016-11-21 09:32:32.633142251 +0900
@@ -1,3 +1,21 @@
+2016-11-20 VERSION 2.4
+ * Fix compatibility with nginx-1.7.12+.
+ * explain the purge logic
+ * feat(purge all): Include option to purge all the cached files
+ This option can be slow if a lot of content is cached, or if the
+ storage used for the cache is slow. But you really should be using
+ RAM as your cache storage.
+ * feat(partial keys): Support partial keys to purge multiple keys.
+ Put an '*' at the end of your purge cache URL.
+ e.g:
+ proxy_cache_key $scheme$host$uri$is_args$args$cookie_JSESSIONID;
+ curl -X PURGE https://example.com/pass*
+ This will remove every cached page whose key cache starting with:
+ httpsexample.com/pass*
+ Be careful not passing any value for the values after the $uri, or put
+ it at the end of your cache key.
+ * Convert a config file to build a dynamic module
+
2014-12-23 VERSION 2.3
* Fix compatibility with nginx-1.7.9+.
diff -ruNb -x .git github.com/FRiCKLE/ngx_cache_purge/config github.com/nginx-modules/ngx_cache_purge/config
--- github.com/FRiCKLE/ngx_cache_purge/config 2016-10-04 15:24:37.166263127 +0900
+++ github.com/nginx-modules/ngx_cache_purge/config 2016-11-21 09:32:32.633142251 +0900
@@ -15,7 +15,17 @@
fi
ngx_addon_name=ngx_http_cache_purge_module
-HTTP_MODULES="$HTTP_MODULES ngx_http_cache_purge_module"
-NGX_ADDON_SRCS="$NGX_ADDON_SRCS $ngx_addon_dir/ngx_cache_purge_module.c"
+CACHE_PURGE_SRCS="$ngx_addon_dir/ngx_cache_purge_module.c"
+
+if [ -n "$ngx_module_link" ]; then
+ ngx_module_type=HTTP
+ ngx_module_name="$ngx_addon_name"
+ ngx_module_srcs="$CACHE_PURGE_SRCS"
+
+ . auto/module
+else
+ HTTP_MODULES="$HTTP_MODULES $ngx_addon_name"
+ NGX_ADDON_SRCS="$NGX_ADDON_SRCS $CACHE_PURGE_SRCS"
+fi
have=NGX_CACHE_PURGE_MODULE . auto/have
diff -ruNb -x .git github.com/FRiCKLE/ngx_cache_purge/ngx_cache_purge_module.c github.com/nginx-modules/ngx_cache_purge/ngx_cache_purge_module.c
--- github.com/FRiCKLE/ngx_cache_purge/ngx_cache_purge_module.c 2016-10-04 15:24:37.166263127 +0900
+++ github.com/nginx-modules/ngx_cache_purge/ngx_cache_purge_module.c 2016-11-21 09:32:32.633142251 +0900
@@ -27,8 +27,8 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#include <nginx.h>
#include <ngx_config.h>
+#include <nginx.h>
#include <ngx_core.h>
#include <ngx_http.h>
@@ -43,6 +43,7 @@
typedef struct {
ngx_flag_t enable;
ngx_str_t method;
+ ngx_flag_t purge_all;
ngx_array_t *access; /* array of ngx_in_cidr_t */
ngx_array_t *access6; /* array of ngx_in6_cidr_t */
} ngx_http_cache_purge_conf_t;
@@ -90,6 +91,11 @@
ngx_int_t ngx_http_uwsgi_cache_purge_handler(ngx_http_request_t *r);
# endif /* NGX_HTTP_UWSGI */
+static ngx_int_t
+ngx_http_purge_file_cache_noop(ngx_tree_ctx_t *ctx, ngx_str_t *path);
+static ngx_int_t
+ngx_http_purge_file_cache_delete_file(ngx_tree_ctx_t *ctx, ngx_str_t *path);
+
ngx_int_t ngx_http_cache_purge_access_handler(ngx_http_request_t *r);
ngx_int_t ngx_http_cache_purge_access(ngx_array_t *a, ngx_array_t *a6,
struct sockaddr *s);
@@ -105,6 +111,11 @@
ngx_int_t ngx_http_file_cache_purge(ngx_http_request_t *r);
+
+void ngx_http_cache_purge_all(ngx_http_request_t *r, ngx_http_file_cache_t *cache);
+void ngx_http_cache_purge_partial(ngx_http_request_t *r, ngx_http_file_cache_t *cache);
+ngx_int_t ngx_http_cache_purge_is_partial(ngx_http_request_t *r);
+
char *ngx_http_cache_purge_conf(ngx_conf_t *cf,
ngx_http_cache_purge_conf_t *cpcf);
@@ -380,6 +391,7 @@
{
ngx_http_file_cache_t *cache;
ngx_http_fastcgi_loc_conf_t *flcf;
+ ngx_http_cache_purge_loc_conf_t *cplcf;
# if (nginx_version >= 1007009)
ngx_http_fastcgi_main_conf_t *fmcf;
ngx_int_t rc;
@@ -414,6 +426,20 @@
return NGX_HTTP_INTERNAL_SERVER_ERROR;
}
+ /* Purge-all option */
+ cplcf = ngx_http_get_module_loc_conf(r, ngx_http_cache_purge_module);
+ if (cplcf->conf->purge_all) {
+ ngx_http_cache_purge_all(r, cache);
+ }
+ else {
+ if (ngx_http_cache_purge_is_partial(r)) {
+ ngx_log_debug(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
+ "http file cache purge with partial enabled");
+
+ ngx_http_cache_purge_partial(r, cache);
+ }
+ }
+
# if (nginx_version >= 8011)
r->main->count++;
# endif
@@ -651,6 +677,7 @@
{
ngx_http_file_cache_t *cache;
ngx_http_proxy_loc_conf_t *plcf;
+ ngx_http_cache_purge_loc_conf_t *cplcf;
# if (nginx_version >= 1007009)
ngx_http_proxy_main_conf_t *pmcf;
ngx_int_t rc;
@@ -685,6 +712,20 @@
return NGX_HTTP_INTERNAL_SERVER_ERROR;
}
+ /* Purge-all option */
+ cplcf = ngx_http_get_module_loc_conf(r, ngx_http_cache_purge_module);
+ if (cplcf->conf->purge_all) {
+ ngx_http_cache_purge_all(r, cache);
+ }
+ else {
+ if (ngx_http_cache_purge_is_partial(r)) {
+ ngx_log_debug(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
+ "http file cache purge with partial enabled");
+
+ ngx_http_cache_purge_partial(r, cache);
+ }
+ }
+
# if (nginx_version >= 8011)
r->main->count++;
# endif
@@ -864,6 +905,7 @@
{
ngx_http_file_cache_t *cache;
ngx_http_scgi_loc_conf_t *slcf;
+ ngx_http_cache_purge_loc_conf_t *cplcf;
# if (nginx_version >= 1007009)
ngx_http_scgi_main_conf_t *smcf;
ngx_int_t rc;
@@ -898,6 +940,20 @@
return NGX_HTTP_INTERNAL_SERVER_ERROR;
}
+ /* Purge-all option */
+ cplcf = ngx_http_get_module_loc_conf(r, ngx_http_cache_purge_module);
+ if (cplcf->conf->purge_all) {
+ ngx_http_cache_purge_all(r, cache);
+ }
+ else {
+ if (ngx_http_cache_purge_is_partial(r)) {
+ ngx_log_debug(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
+ "http file cache purge with partial enabled");
+
+ ngx_http_cache_purge_partial(r, cache);
+ }
+ }
+
# if (nginx_version >= 8011)
r->main->count++;
# endif
@@ -1100,6 +1156,7 @@
{
ngx_http_file_cache_t *cache;
ngx_http_uwsgi_loc_conf_t *ulcf;
+ ngx_http_cache_purge_loc_conf_t *cplcf;
# if (nginx_version >= 1007009)
ngx_http_uwsgi_main_conf_t *umcf;
ngx_int_t rc;
@@ -1134,6 +1191,20 @@
return NGX_HTTP_INTERNAL_SERVER_ERROR;
}
+ /* Purge-all option */
+ cplcf = ngx_http_get_module_loc_conf(r, ngx_http_cache_purge_module);
+ if (cplcf->conf->purge_all) {
+ ngx_http_cache_purge_all(r, cache);
+ }
+ else {
+ if (ngx_http_cache_purge_is_partial(r)) {
+ ngx_log_debug(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
+ "http file cache purge with partial enabled");
+
+ ngx_http_cache_purge_partial(r, cache);
+ }
+ }
+
# if (nginx_version >= 8011)
r->main->count++;
# endif
@@ -1144,6 +1215,83 @@
}
# endif /* NGX_HTTP_UWSGI */
+
+static ngx_int_t
+ngx_http_purge_file_cache_noop(ngx_tree_ctx_t *ctx, ngx_str_t *path)
+{
+ return NGX_OK;
+}
+
+static ngx_int_t
+ngx_http_purge_file_cache_delete_file(ngx_tree_ctx_t *ctx, ngx_str_t *path)
+{
+ ngx_log_debug1(NGX_LOG_DEBUG_HTTP, ctx->log, 0,
+ "http file cache delete: \"%s\"", path->data);
+
+ if (ngx_delete_file(path->data) == NGX_FILE_ERROR) {
+ ngx_log_error(NGX_LOG_CRIT, ctx->log, ngx_errno,
+ ngx_delete_file_n " \"%s\" failed", path->data);
+ }
+
+ return NGX_OK;
+}
+
+
+static ngx_int_t
+ngx_http_purge_file_cache_delete_partial_file(ngx_tree_ctx_t *ctx, ngx_str_t *path)
+{
+ u_char *key_partial;
+ u_char *key_in_file;
+ ngx_uint_t len;
+ ngx_flag_t remove_file = 0;
+
+ key_partial = ctx->data;
+ len = ngx_strlen(key_partial);
+
+ /* if key_partial is empty always match, because is a '*' */
+ if (len == 0) {
+ ngx_log_debug(NGX_LOG_DEBUG_HTTP, ctx->log, 0,
+ "empty key_partial, forcing deletion");
+ remove_file = 1;
+ }
+ else {
+ ngx_file_t file;
+
+ file.offset = file.sys_offset = 0;
+ file.fd = ngx_open_file(path->data, NGX_FILE_RDONLY, NGX_FILE_OPEN,
+ NGX_FILE_DEFAULT_ACCESS);
+
+ /* I don't know if it's a good idea to use the ngx_cycle pool for this,
+ but the request is not available here */
+ key_in_file = ngx_pcalloc(ngx_cycle->pool, sizeof(u_char) * (len + 1));
+
+ /* KEY: /proxy/passwd */
+ /* since we don't need the "KEY: " ignore 5 + 1 extra u_char from last
+ intro */
+ /* Optimization: we don't need to read the full key only the n chars
+ included in key_partial */
+ ngx_read_file(&file, key_in_file, sizeof(u_char) * len,
+ sizeof(ngx_http_file_cache_header_t) + sizeof(u_char) * 6);
+ ngx_close_file(file.fd);
+
+ ngx_log_debug2(NGX_LOG_DEBUG_HTTP, ctx->log, 0,
+ "http cache file \"%s\" key read: \"%s\"", path->data, key_in_file);
+
+ if (ngx_strncasecmp(key_in_file, key_partial, len) == 0) {
+ ngx_log_debug(NGX_LOG_DEBUG_HTTP, ctx->log, 0,
+ "match found, deleting file \"%s\"", path->data);
+ remove_file = 1;
+ }
+ }
+
+ if (remove_file && ngx_delete_file(path->data) == NGX_FILE_ERROR) {
+ ngx_log_error(NGX_LOG_CRIT, ctx->log, ngx_errno,
+ ngx_delete_file_n " \"%s\" failed", path->data);
+ }
+
+ return NGX_OK;
+}
+
ngx_int_t
ngx_http_cache_purge_access_handler(ngx_http_request_t *r)
{
@@ -1401,6 +1549,7 @@
void
ngx_http_cache_purge_handler(ngx_http_request_t *r)
{
+ ngx_http_cache_purge_loc_conf_t *cplcf;
ngx_int_t rc;
# if (NGX_HAVE_FILE_AIO)
@@ -1409,11 +1558,15 @@
}
# endif
+ cplcf = ngx_http_get_module_loc_conf(r, ngx_http_cache_purge_module);
+ rc = NGX_OK;
+ if (!cplcf->conf->purge_all && !ngx_http_cache_purge_is_partial(r)) {
rc = ngx_http_file_cache_purge(r);
ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
"http file cache purge: %i, \"%s\"",
rc, r->cache->file.name.data);
+ }
switch (rc) {
case NGX_OK:
@@ -1499,6 +1652,73 @@
return NGX_OK;
}
+
+void
+ngx_http_cache_purge_all(ngx_http_request_t *r, ngx_http_file_cache_t *cache) {
+ ngx_log_debug(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
+ "purge_all http in %s",
+ cache->path->name.data);
+
+ /* Walk the tree and remove all the files */
+ ngx_tree_ctx_t tree;
+ tree.init_handler = NULL;
+ tree.file_handler = ngx_http_purge_file_cache_delete_file;
+ tree.pre_tree_handler = ngx_http_purge_file_cache_noop;
+ tree.post_tree_handler = ngx_http_purge_file_cache_noop;
+ tree.spec_handler = ngx_http_purge_file_cache_noop;
+ tree.data = NULL;
+ tree.alloc = 0;
+ tree.log = ngx_cycle->log;
+
+ ngx_walk_tree(&tree, &cache->path->name);
+}
+
+void
+ngx_http_cache_purge_partial(ngx_http_request_t *r, ngx_http_file_cache_t *cache) {
+ ngx_log_debug(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
+ "purge_partial http in %s",
+ cache->path->name.data);
+
+ u_char *key_partial;
+ ngx_str_t *key;
+ ngx_http_cache_t *c;
+ ngx_uint_t len;
+
+ c = r->cache;
+ key = c->keys.elts;
+ len = key[0].len;
+
+ /* Only check the first key */
+ key_partial = ngx_pcalloc(r->pool, sizeof(u_char) * len);
+ ngx_memcpy(key_partial, key[0].data, sizeof(u_char) * (len - 1));
+
+ /* Walk the tree and remove all the files matching key_partial */
+ ngx_tree_ctx_t tree;
+ tree.init_handler = NULL;
+ tree.file_handler = ngx_http_purge_file_cache_delete_partial_file;
+ tree.pre_tree_handler = ngx_http_purge_file_cache_noop;
+ tree.post_tree_handler = ngx_http_purge_file_cache_noop;
+ tree.spec_handler = ngx_http_purge_file_cache_noop;
+ tree.data = key_partial;
+ tree.alloc = 0;
+ tree.log = ngx_cycle->log;
+
+ ngx_walk_tree(&tree, &cache->path->name);
+}
+
+ngx_int_t
+ngx_http_cache_purge_is_partial(ngx_http_request_t *r)
+{
+ ngx_str_t *key;
+ ngx_http_cache_t *c;
+
+ c = r->cache;
+ key = c->keys.elts;
+
+ /* Only check the first key */
+ return key[0].data[key[0].len - 1] == '*';
+}
+
char *
ngx_http_cache_purge_conf(ngx_conf_t *cf, ngx_http_cache_purge_conf_t *cpcf)
{
@@ -1510,7 +1730,11 @@
ngx_str_t *value;
ngx_int_t rc;
ngx_uint_t i;
+ ngx_uint_t from_position;
+
+ from_position = 2;
+ /* xxx_cache_purge on|off|<method> [purge_all] [from all|<ip> [.. <ip>]] */
value = cf->args->elts;
if (ngx_strcmp(value[1].data, "off") == 0) {
@@ -1529,20 +1753,27 @@
return NGX_CONF_OK;
}
+ /* We will purge all the keys */
+ if (ngx_strcmp(value[from_position].data, "purge_all") == 0) {
+ cpcf->purge_all = 1;
+ from_position++;
+ }
+
+
/* sanity check */
- if (ngx_strcmp(value[2].data, "from") != 0) {
+ if (ngx_strcmp(value[from_position].data, "from") != 0) {
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
"invalid parameter \"%V\", expected"
- " \"from\" keyword", &value[2]);
+ " \"from\" keyword", &value[from_position]);
return NGX_CONF_ERROR;
}
- if (ngx_strcmp(value[3].data, "all") == 0) {
+ if (ngx_strcmp(value[from_position + 1].data, "all") == 0) {
cpcf->enable = 1;
return NGX_CONF_OK;
}
- for (i = 3; i < cf->args->nelts; i++) {
+ for (i = (from_position + 1); i < cf->args->nelts; i++) {
rc = ngx_ptocidr(&value[i], &cidr);
if (rc == NGX_ERROR) {
@@ -1560,7 +1791,7 @@
switch (cidr.family) {
case AF_INET:
if (cpcf->access == NULL) {
- cpcf->access = ngx_array_create(cf->pool, cf->args->nelts - 3,
+ cpcf->access = ngx_array_create(cf->pool, cf->args->nelts - (from_position + 1),
sizeof(ngx_in_cidr_t));
if (cpcf->access == NULL) {
return NGX_CONF_ERROR;
@@ -1580,7 +1811,7 @@
# if (NGX_HAVE_INET6)
case AF_INET6:
if (cpcf->access6 == NULL) {
- cpcf->access6 = ngx_array_create(cf->pool, cf->args->nelts - 3,
+ cpcf->access6 = ngx_array_create(cf->pool, cf->args->nelts - (from_position + 1),
sizeof(ngx_in6_cidr_t));
if (cpcf->access6 == NULL) {
return NGX_CONF_ERROR;
@@ -1613,6 +1844,7 @@
if (prev->enable == 1) {
conf->enable = prev->enable;
conf->method = prev->method;
+ conf->purge_all = prev->purge_all;
conf->access = prev->access;
conf->access6 = prev->access6;
diff -ruNb -x .git github.com/FRiCKLE/ngx_cache_purge/README.md github.com/nginx-modules/ngx_cache_purge/README.md
--- github.com/FRiCKLE/ngx_cache_purge/README.md 2016-10-04 15:24:37.166263127 +0900
+++ github.com/nginx-modules/ngx_cache_purge/README.md 2016-11-21 09:32:32.633142251 +0900
@@ -1,7 +1,8 @@
About
=====
`ngx_cache_purge` is `nginx` module which adds ability to purge content from
-`FastCGI`, `proxy`, `SCGI` and `uWSGI` caches.
+`FastCGI`, `proxy`, `SCGI` and `uWSGI` caches. A purge operation removes the
+content with the same cache key as the purge request has.
Sponsors
@@ -18,7 +19,7 @@
===============================================
fastcgi_cache_purge
-------------------
-* **syntax**: `fastcgi_cache_purge on|off|<method> [from all|<ip> [.. <ip>]]`
+* **syntax**: `fastcgi_cache_purge on|off|<method> [purge_all] [from all|<ip> [.. <ip>]]`
* **default**: `none`
* **context**: `http`, `server`, `location`
@@ -27,7 +28,7 @@
proxy_cache_purge
-----------------
-* **syntax**: `proxy_cache_purge on|off|<method> [from all|<ip> [.. <ip>]]`
+* **syntax**: `proxy_cache_purge on|off|<method> [purge_all] [from all|<ip> [.. <ip>]]`
* **default**: `none`
* **context**: `http`, `server`, `location`
@@ -36,7 +37,7 @@
scgi_cache_purge
----------------
-* **syntax**: `scgi_cache_purge on|off|<method> [from all|<ip> [.. <ip>]]`
+* **syntax**: `scgi_cache_purge on|off|<method> [purge_all] [from all|<ip> [.. <ip>]]`
* **default**: `none`
* **context**: `http`, `server`, `location`
@@ -45,7 +46,7 @@
uwsgi_cache_purge
-----------------
-* **syntax**: `uwsgi_cache_purge on|off|<method> [from all|<ip> [.. <ip>]]`
+* **syntax**: `uwsgi_cache_purge on|off|<method> [purge_all] [from all|<ip> [.. <ip>]]`
* **default**: `none`
* **context**: `http`, `server`, `location`
@@ -90,6 +91,18 @@
Sets area and key used for purging selected pages from `uWSGI`'s cache.
+
+Partial Keys
+============
+Sometimes it's not possible to pass the exact key cache to purge a page. For example; when the content of a cookie or the params are part of the key.
+You can specify a partial key adding an asterisk at the end of the URL.
+
+ curl -X PURGE /page*
+
+The asterisk must be the last character of the key, so you **must** put the $uri variable at the end.
+
+
+
Sample configuration (same location syntax)
===========================================
http {
@@ -104,6 +117,22 @@
}
}
}
+
+
+Sample configuration (same location syntax - purge all cached files)
+====================================================================
+ http {
+ proxy_cache_path /tmp/cache keys_zone=tmpcache:10m;
+
+ server {
+ location / {
+ proxy_pass http://127.0.0.1:8000;
+ proxy_cache tmpcache;
+ proxy_cache_key $uri$is_args$args;
+ proxy_cache_purge PURGE purge_all from 127.0.0.1;
+ }
+ }
+ }
Sample configuration (separate location syntax)
diff -ruNb -x .git github.com/FRiCKLE/ngx_cache_purge/t/proxy3.t github.com/nginx-modules/ngx_cache_purge/t/proxy3.t
--- github.com/FRiCKLE/ngx_cache_purge/t/proxy3.t 1970-01-01 09:00:00.000000000 +0900
+++ github.com/nginx-modules/ngx_cache_purge/t/proxy3.t 2016-11-21 09:32:32.633142251 +0900
@@ -0,0 +1,140 @@
+# vi:filetype=perl
+
+use lib 'lib';
+use Test::Nginx::Socket;
+
+repeat_each(1);
+
+plan tests => 32;
+
+our $http_config = <<'_EOC_';
+ proxy_cache_path /tmp/ngx_cache_purge_cache keys_zone=test_cache:10m;
+ proxy_temp_path /tmp/ngx_cache_purge_temp 1 2;
+_EOC_
+
+our $config = <<'_EOC_';
+ location /proxy {
+ proxy_pass $scheme://127.0.0.1:$server_port/etc/passwd;
+ proxy_cache test_cache;
+ proxy_cache_key $uri$is_args$args;
+ proxy_cache_valid 3m;
+ add_header X-Cache-Status $upstream_cache_status;
+
+ proxy_cache_purge PURGE purge_all from 1.0.0.0/8 127.0.0.0/8 3.0.0.0/8;
+ }
+
+
+ location = /etc/passwd {
+ root /var/www/html;
+ }
+_EOC_
+
+worker_connections(128);
+no_shuffle();
+run_tests();
+
+no_diff();
+
+__DATA__
+
+=== TEST 1: prepare passwd
+--- http_config eval: $::http_config
+--- config eval: $::config
+--- request
+GET /proxy/passwd
+--- error_code: 200
+--- response_headers
+Content-Type: text/plain
+--- response_body_like: root
+--- timeout: 10
+--- no_error_log eval
+qr/\[(warn|error|crit|alert|emerg)\]/
+
+
+=== TEST 2: prepare shadow
+--- http_config eval: $::http_config
+--- config eval: $::config
+--- request
+GET /proxy/shadow
+--- error_code: 200
+--- response_headers
+Content-Type: text/plain
+--- response_body_like: root
+--- timeout: 10
+--- no_error_log eval
+qr/\[(warn|error|crit|alert|emerg)\]/
+
+
+
+=== TEST 3: get from cache passwd
+--- http_config eval: $::http_config
+--- config eval: $::config
+--- request
+GET /proxy/passwd
+--- error_code: 200
+--- response_headers
+Content-Type: text/plain
+X-Cache-Status: HIT
+--- response_body_like: root
+--- timeout: 10
+--- no_error_log eval
+qr/\[(warn|error|crit|alert|emerg)\]/
+
+
+=== TEST 4: get from cache shadow
+--- http_config eval: $::http_config
+--- config eval: $::config
+--- request
+GET /proxy/shadow
+--- error_code: 200
+--- response_headers
+Content-Type: text/plain
+X-Cache-Status: HIT
+--- response_body_like: root
+--- timeout: 10
+--- no_error_log eval
+qr/\[(warn|error|crit|alert|emerg)\]/
+
+
+=== TEST 5: purge from cache
+--- http_config eval: $::http_config
+--- config eval: $::config
+--- request
+PURGE /proxy/any
+--- error_code: 200
+--- response_headers
+Content-Type: text/html
+--- response_body_like: Successful purge
+--- timeout: 10
+--- no_error_log eval
+qr/\[(warn|error|crit|alert|emerg)\]/
+
+
+=== TEST 6: get from empty cache passwd
+--- http_config eval: $::http_config
+--- config eval: $::config
+--- request
+GET /proxy/passwd
+--- error_code: 200
+--- response_headers
+Content-Type: text/plain
+X-Cache-Status: MISS
+--- response_body_like: root
+--- timeout: 10
+--- no_error_log eval
+qr/\[(warn|error|crit|alert|emerg)\]/
+
+
+=== TEST 7: get from empty cache shadow
+--- http_config eval: $::http_config
+--- config eval: $::config
+--- request
+GET /proxy/shadow
+--- error_code: 200
+--- response_headers
+Content-Type: text/plain
+X-Cache-Status: MISS
+--- response_body_like: root
+--- timeout: 10
+--- no_error_log eval
+qr/\[(warn|error|crit|alert|emerg)\]/
diff -ruNb -x .git github.com/FRiCKLE/ngx_cache_purge/t/proxy4.t github.com/nginx-modules/ngx_cache_purge/t/proxy4.t
--- github.com/FRiCKLE/ngx_cache_purge/t/proxy4.t 1970-01-01 09:00:00.000000000 +0900
+++ github.com/nginx-modules/ngx_cache_purge/t/proxy4.t 2016-11-21 09:32:32.633142251 +0900
@@ -0,0 +1,168 @@
+# vi:filetype=perl
+
+use lib 'lib';
+use Test::Nginx::Socket;
+
+repeat_each(1);
+
+plan tests => 41;
+
+our $http_config = <<'_EOC_';
+ proxy_cache_path /tmp/ngx_cache_purge_cache keys_zone=test_cache:10m;
+ proxy_temp_path /tmp/ngx_cache_purge_temp 1 2;
+_EOC_
+
+our $config = <<'_EOC_';
+ location /proxy {
+ proxy_pass $scheme://127.0.0.1:$server_port/etc/passwd;
+ proxy_cache test_cache;
+ proxy_cache_key $uri$is_args$args;
+ proxy_cache_valid 3m;
+ add_header X-Cache-Status $upstream_cache_status;
+
+ proxy_cache_purge PURGE from 1.0.0.0/8 127.0.0.0/8 3.0.0.0/8;
+ }
+
+
+ location = /etc/passwd {
+ root /var/www/html;
+ }
+_EOC_
+
+worker_connections(128);
+no_shuffle();
+run_tests();
+
+no_diff();
+
+__DATA__
+
+=== TEST 1: prepare passwd
+--- http_config eval: $::http_config
+--- config eval: $::config
+--- request
+GET /proxy/passwd
+--- error_code: 200
+--- response_headers
+Content-Type: text/plain
+--- response_body_like: root
+--- timeout: 10
+--- no_error_log eval
+qr/\[(warn|error|crit|alert|emerg)\]/
+
+
+=== TEST 2: prepare passwd2
+--- http_config eval: $::http_config
+--- config eval: $::config
+--- request
+GET /proxy/passwd2
+--- error_code: 200
+--- response_headers
+Content-Type: text/plain
+--- response_body_like: root
+--- timeout: 10
+--- no_error_log eval
+qr/\[(warn|error|crit|alert|emerg)\]/
+
+
+=== TEST 3: prepare shadow
+--- http_config eval: $::http_config
+--- config eval: $::config
+--- request
+GET /proxy/shadow
+--- error_code: 200
+--- response_headers
+Content-Type: text/plain
+--- response_body_like: root
+--- timeout: 10
+--- no_error_log eval
+qr/\[(warn|error|crit|alert|emerg)\]/
+
+
+=== TEST 4: get from cache passwd
+--- http_config eval: $::http_config
+--- config eval: $::config
+--- request
+GET /proxy/passwd
+--- error_code: 200
+--- response_headers
+Content-Type: text/plain
+X-Cache-Status: HIT
+--- response_body_like: root
+--- timeout: 10
+--- no_error_log eval
+qr/\[(warn|error|crit|alert|emerg)\]/
+
+
+=== TEST 5: get from cache passwd2
+--- http_config eval: $::http_config
+--- config eval: $::config
+--- request
+GET /proxy/passwd2
+--- error_code: 200
+--- response_headers
+Content-Type: text/plain
+X-Cache-Status: HIT
+--- response_body_like: root
+--- timeout: 10
+--- no_error_log eval
+qr/\[(warn|error|crit|alert|emerg)\]/
+
+
+=== TEST 6: purge from cache
+--- http_config eval: $::http_config
+--- config eval: $::config
+--- request
+PURGE /proxy/pass*
+--- error_code: 200
+--- response_headers
+Content-Type: text/html
+--- response_body_like: Successful purge
+--- timeout: 10
+--- no_error_log eval
+qr/\[(warn|error|crit|alert|emerg)\]/
+
+
+=== TEST 7: get from empty cache passwd
+--- http_config eval: $::http_config
+--- config eval: $::config
+--- request
+GET /proxy/passwd
+--- error_code: 200
+--- response_headers
+Content-Type: text/plain
+X-Cache-Status: MISS
+--- response_body_like: root
+--- timeout: 10
+--- no_error_log eval
+qr/\[(warn|error|crit|alert|emerg)\]/
+
+
+=== TEST 8: get from empty cache passwd2
+--- http_config eval: $::http_config
+--- config eval: $::config
+--- request
+GET /proxy/passwd2
+--- error_code: 200
+--- response_headers
+Content-Type: text/plain
+X-Cache-Status: MISS
+--- response_body_like: root
+--- timeout: 10
+--- no_error_log eval
+qr/\[(warn|error|crit|alert|emerg)\]/
+
+
+=== TEST 9: get from cache shadow
+--- http_config eval: $::http_config
+--- config eval: $::config
+--- request
+GET /proxy/shadow
+--- error_code: 200
+--- response_headers
+Content-Type: text/plain
+X-Cache-Status: HIT
+--- response_body_like: root
+--- timeout: 10
+--- no_error_log eval
+qr/\[(warn|error|crit|alert|emerg)\]/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment