wandenberg

0001-adding-parameter-to-purge-cache-by-groups.patch

Dec 5th, 2011
159
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. From 509d6c5becc5037830e176131ca9868986ee3bb3 Mon Sep 17 00:00:00 2001
  2. From: Wandenberg Peixoto <wandenberg@gmail.com>
  3. Date: Tue, 29 Nov 2011 13:53:11 -0200
  4. Subject: [PATCH] adding parameter to purge cache by groups
  5.  
  6. ---
  7. README.md                |   44 ++++++++-
  8.  ngx_cache_purge_module.c |  175 +++++++++++++++++++++++++++++----
  9.  t/proxy.t                |  247 +++++++++++++++++++++++++++++++++++++++++++++-
  10.  3 files changed, 443 insertions(+), 23 deletions(-)
  11.  
  12. diff --git a/README.md b/README.md
  13. index fd06a7e..cb2e583 100644
  14. --- a/README.md
  15. +++ b/README.md
  16. @@ -25,38 +25,53 @@ Configuration directives
  17.  ========================
  18.  fastcgi_cache_purge
  19.  -------------------
  20. -* **syntax**: `fastcgi_cache_purge zone_name key`
  21. +* **syntax**: `fastcgi_cache_purge zone_name key [group_key]`
  22.  * **default**: `none`
  23.  * **context**: `location`
  24.  
  25.  Sets area and key used for purging selected pages from `FastCGI`'s cache.
  26. +Group key is an optional parameter representing the group of cached files. Has to be set with the same value used on `proxy_cache_key` directive.
  27.  
  28.  
  29.  proxy_cache_purge
  30.  -----------------
  31. -* **syntax**: `proxy_cache_purge zone_name key`
  32. +* **syntax**: `proxy_cache_purge zone_name key [group_key]`
  33.  * **default**: `none`
  34.  * **context**: `location`
  35.  
  36.  Sets area and key used for purging selected pages from `proxy`'s cache.
  37. +Group key is an optional parameter representing the group of cached files. Has to be set with the same value used on `proxy_cache_key` directive.
  38.  
  39.  
  40.  scgi_cache_purge
  41.  ----------------
  42. -* **syntax**: `scgi_cache_purge zone_name key`
  43. +* **syntax**: `scgi_cache_purge zone_name key [group_key]`
  44.  * **default**: `none`
  45.  * **context**: `location`
  46.  
  47.  Sets area and key used for purging selected pages from `SCGI`'s cache.
  48. +Group key is an optional parameter representing the group of cached files. Has to be set with the same value used on `proxy_cache_key` directive.
  49.  
  50.  
  51.  uwsgi_cache_purge
  52.  -----------------
  53. -* **syntax**: `uwsgi_cache_purge zone_name key`
  54. +* **syntax**: `uwsgi_cache_purge zone_name key [group_key]`
  55.  * **default**: `none`
  56.  * **context**: `location`
  57.  
  58.  Sets area and key used for purging selected pages from `uWSGI`'s cache.
  59. +Group key is an optional parameter representing the group of cached files. Has to be set with the same value used on `proxy_cache_key` directive.
  60. +
  61. +
  62. +group_clean_cache_purge
  63. +-----------------------
  64. +* **syntax**: `group_clean_cache_purge eval_to_number`
  65. +* **default**: `0`
  66. +* **context**: `location`
  67. +
  68. +Sets a value to be evaluated to a number, if `0` only the page which match the key and group key is purged, otherwise all pages cached with the group key are purged from cache.
  69. +May use headers, arguments or any other variable or a fixed value.
  70. +
  71.  
  72.  
  73.  Sample configuration
  74. @@ -80,6 +95,27 @@ Sample configuration
  75.      }
  76.  
  77.  
  78. +Group configuration
  79. +===================
  80. +    http {
  81. +        proxy_cache_path  /tmp/cache  keys_zone=tmpcache:10m;
  82. +
  83. +        server {
  84. +            location / {
  85. +                proxy_pass         http://127.0.0.1:8000;
  86. +                proxy_cache        tmpcache;
  87. +                proxy_cache_key    $uri$is_args$args $arg_group-$host;
  88. +            }
  89. +
  90. +            location ~ /purge(/.*) {
  91. +                allow              127.0.0.1;
  92. +                deny               all;
  93. +                proxy_cache_purge  tmpcache $1$is_args$args $arg_group-$host;
  94. +                group_clean_cache_purge "$http_x_group_clean";
  95. +            }
  96. +        }
  97. +    }
  98. +
  99.  Testing
  100.  =======
  101.  `ngx_cache_purge` comes with complete test suite based on [Test::Nginx](http://github.com/agentzh/test-nginx).
  102. diff --git a/ngx_cache_purge_module.c b/ngx_cache_purge_module.c
  103. index f30112e..32dfc6f 100644
  104. --- a/ngx_cache_purge_module.c
  105. +++ b/ngx_cache_purge_module.c
  106. @@ -60,16 +60,26 @@ ngx_int_t   ngx_http_uwsgi_cache_purge_handler(ngx_http_request_t *r);
  107.  # endif /* NGX_HTTP_UWSGI */
  108.  
  109.  ngx_int_t   ngx_http_cache_purge_init(ngx_http_request_t *r,
  110. -    ngx_http_file_cache_t *cache, ngx_http_complex_value_t *cache_key);
  111. +    ngx_http_file_cache_t *cache, ngx_http_complex_value_t *cache_key, ngx_http_complex_value_t *cache_group_key);
  112.  void        ngx_http_cache_purge_handler(ngx_http_request_t *r);
  113.  
  114.  ngx_int_t   ngx_http_file_cache_purge(ngx_http_request_t *r);
  115.  
  116. +static void *ngx_http_cache_purge_create_loc_conf(ngx_conf_t *cf);
  117. +
  118. +static char *ngx_http_cache_purge_merge_loc_conf(ngx_conf_t *cf,
  119. +                void *parent, void *child);
  120. +
  121. +typedef struct {
  122. +    ngx_http_complex_value_t  *cache_group_clean;
  123. +} ngx_http_cache_purge_loc_conf_t;
  124. +
  125. +
  126.  static ngx_command_t  ngx_http_cache_purge_module_commands[] = {
  127.  
  128.  # if (NGX_HTTP_FASTCGI)
  129.      { ngx_string("fastcgi_cache_purge"),
  130. -      NGX_HTTP_LOC_CONF|NGX_CONF_TAKE2,
  131. +      NGX_HTTP_LOC_CONF|NGX_CONF_TAKE23,
  132.        ngx_http_fastcgi_cache_purge_conf,
  133.        NGX_HTTP_LOC_CONF_OFFSET,
  134.        0,
  135. @@ -78,7 +88,7 @@ static ngx_command_t  ngx_http_cache_purge_module_commands[] = {
  136.  
  137.  # if (NGX_HTTP_PROXY)
  138.      { ngx_string("proxy_cache_purge"),
  139. -      NGX_HTTP_LOC_CONF|NGX_CONF_TAKE2,
  140. +      NGX_HTTP_LOC_CONF|NGX_CONF_TAKE23,
  141.        ngx_http_proxy_cache_purge_conf,
  142.        NGX_HTTP_LOC_CONF_OFFSET,
  143.        0,
  144. @@ -87,7 +97,7 @@ static ngx_command_t  ngx_http_cache_purge_module_commands[] = {
  145.  
  146.  # if (NGX_HTTP_SCGI)
  147.      { ngx_string("scgi_cache_purge"),
  148. -      NGX_HTTP_LOC_CONF|NGX_CONF_TAKE2,
  149. +      NGX_HTTP_LOC_CONF|NGX_CONF_TAKE23,
  150.        ngx_http_scgi_cache_purge_conf,
  151.        NGX_HTTP_LOC_CONF_OFFSET,
  152.        0,
  153. @@ -96,13 +106,20 @@ static ngx_command_t  ngx_http_cache_purge_module_commands[] = {
  154.  
  155.  # if (NGX_HTTP_UWSGI)
  156.      { ngx_string("uwsgi_cache_purge"),
  157. -      NGX_HTTP_LOC_CONF|NGX_CONF_TAKE2,
  158. +      NGX_HTTP_LOC_CONF|NGX_CONF_TAKE23,
  159.        ngx_http_uwsgi_cache_purge_conf,
  160.        NGX_HTTP_LOC_CONF_OFFSET,
  161.        0,
  162.        NULL },
  163.  # endif /* NGX_HTTP_UWSGI */
  164.  
  165. +    { ngx_string("group_clean_cache_purge"),
  166. +      NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
  167. +      ngx_http_set_complex_value_slot,
  168. +      NGX_HTTP_LOC_CONF_OFFSET,
  169. +      offsetof(ngx_http_cache_purge_loc_conf_t, cache_group_clean),
  170. +      NULL },
  171. +
  172.        ngx_null_command
  173.  };
  174.  
  175. @@ -116,8 +133,8 @@ static ngx_http_module_t  ngx_http_cache_purge_module_ctx = {
  176.      NULL,  /* create server configuration */
  177.      NULL,  /* merge server configuration */
  178.  
  179. -    NULL,  /* create location configuration */
  180. -    NULL   /* merge location configuration */
  181. +    ngx_http_cache_purge_create_loc_conf,  /* create location configuration */
  182. +    ngx_http_cache_purge_merge_loc_conf   /* merge location configuration */
  183.  };
  184.  
  185.  ngx_module_t  ngx_http_cache_purge_module = {
  186. @@ -172,6 +189,7 @@ typedef struct {
  187.  #  endif /* nginx_version >= 8040 */
  188.  
  189.      ngx_http_complex_value_t       cache_key;
  190. +    ngx_http_complex_value_t       cache_group_key;
  191.  
  192.  #  if (NGX_PCRE)
  193.      ngx_regex_t                   *split_regex;
  194. @@ -183,7 +201,7 @@ char *
  195.  ngx_http_fastcgi_cache_purge_conf(ngx_conf_t *cf, ngx_command_t *cmd,
  196.      void *conf)
  197.  {
  198. -    ngx_http_compile_complex_value_t   ccv;
  199. +    ngx_http_compile_complex_value_t   ccv, group_ccv;
  200.      ngx_http_core_loc_conf_t          *clcf;
  201.      ngx_http_fastcgi_loc_conf_t       *flcf;
  202.      ngx_str_t                         *value;
  203. @@ -225,6 +243,19 @@ ngx_http_fastcgi_cache_purge_conf(ngx_conf_t *cf, ngx_command_t *cmd,
  204.          return NGX_CONF_ERROR;
  205.      }
  206.  
  207. +    if (cf->args->nelts > 3) {
  208. +        /* set proxy_cache_group_key part */
  209. +        ngx_memzero(&group_ccv, sizeof(ngx_http_compile_complex_value_t));
  210. +
  211. +        group_ccv.cf = cf;
  212. +        group_ccv.value = &value[3];
  213. +        group_ccv.complex_value = &flcf->cache_group_key;
  214. +
  215. +        if (ngx_http_compile_complex_value(&group_ccv) != NGX_OK) {
  216. +            return NGX_CONF_ERROR;
  217. +        }
  218. +    }
  219. +
  220.      /* set handler */
  221.      clcf = ngx_http_conf_get_module_loc_conf(cf, ngx_http_core_module);
  222.  
  223. @@ -241,7 +272,7 @@ ngx_http_fastcgi_cache_purge_handler(ngx_http_request_t *r)
  224.      flcf = ngx_http_get_module_loc_conf(r, ngx_http_fastcgi_module);
  225.  
  226.      if (ngx_http_cache_purge_init(r, flcf->upstream.cache->data,
  227. -                                  &flcf->cache_key)
  228. +                                  &flcf->cache_key, &flcf->cache_group_key)
  229.          != NGX_OK)
  230.      {
  231.          return NGX_HTTP_INTERNAL_SERVER_ERROR;
  232. @@ -295,6 +326,7 @@ typedef struct {
  233.      ngx_str_t                      url;
  234.  
  235.      ngx_http_complex_value_t       cache_key;
  236. +    ngx_http_complex_value_t       cache_group_key;
  237.  
  238.      ngx_http_proxy_vars_t          vars;
  239.  
  240. @@ -307,7 +339,7 @@ typedef struct {
  241.  char *
  242.  ngx_http_proxy_cache_purge_conf(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
  243.  {
  244. -    ngx_http_compile_complex_value_t   ccv;
  245. +    ngx_http_compile_complex_value_t   ccv, group_ccv;
  246.      ngx_http_core_loc_conf_t          *clcf;
  247.      ngx_http_proxy_loc_conf_t         *plcf;
  248.      ngx_str_t                         *value;
  249. @@ -349,6 +381,19 @@ ngx_http_proxy_cache_purge_conf(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
  250.          return NGX_CONF_ERROR;
  251.      }
  252.  
  253. +    if (cf->args->nelts > 3) {
  254. +        /* set proxy_cache_group_key part */
  255. +        ngx_memzero(&group_ccv, sizeof(ngx_http_compile_complex_value_t));
  256. +
  257. +        group_ccv.cf = cf;
  258. +        group_ccv.value = &value[3];
  259. +        group_ccv.complex_value = &plcf->cache_group_key;
  260. +
  261. +        if (ngx_http_compile_complex_value(&group_ccv) != NGX_OK) {
  262. +            return NGX_CONF_ERROR;
  263. +        }
  264. +    }
  265. +
  266.      /* set handler */
  267.      clcf = ngx_http_conf_get_module_loc_conf(cf, ngx_http_core_module);
  268.  
  269. @@ -365,7 +410,7 @@ ngx_http_proxy_cache_purge_handler(ngx_http_request_t *r)
  270.      plcf = ngx_http_get_module_loc_conf(r, ngx_http_proxy_module);
  271.  
  272.      if (ngx_http_cache_purge_init(r, plcf->upstream.cache->data,
  273. -                                  &plcf->cache_key)
  274. +                                  &plcf->cache_key, &plcf->cache_group_key)
  275.          != NGX_OK)
  276.      {
  277.          return NGX_HTTP_INTERNAL_SERVER_ERROR;
  278. @@ -399,12 +444,13 @@ typedef struct {
  279.      ngx_array_t               *scgi_values;
  280.  
  281.      ngx_http_complex_value_t   cache_key;
  282. +    ngx_http_complex_value_t   cache_group_key;
  283.  } ngx_http_scgi_loc_conf_t;
  284.  
  285.  char *
  286.  ngx_http_scgi_cache_purge_conf(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
  287.  {
  288. -    ngx_http_compile_complex_value_t   ccv;
  289. +    ngx_http_compile_complex_value_t   ccv, group_ccv;
  290.      ngx_http_core_loc_conf_t          *clcf;
  291.      ngx_http_scgi_loc_conf_t          *slcf;
  292.      ngx_str_t                         *value;
  293. @@ -446,6 +492,19 @@ ngx_http_scgi_cache_purge_conf(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
  294.          return NGX_CONF_ERROR;
  295.      }
  296.  
  297. +    if (cf->args->nelts > 3) {
  298. +        /* set proxy_cache_group_key part */
  299. +        ngx_memzero(&group_ccv, sizeof(ngx_http_compile_complex_value_t));
  300. +
  301. +        group_ccv.cf = cf;
  302. +        group_ccv.value = &value[3];
  303. +        group_ccv.complex_value = &slcf->cache_group_key;
  304. +
  305. +        if (ngx_http_compile_complex_value(&group_ccv) != NGX_OK) {
  306. +            return NGX_CONF_ERROR;
  307. +        }
  308. +    }
  309. +
  310.      /* set handler */
  311.      clcf = ngx_http_conf_get_module_loc_conf(cf, ngx_http_core_module);
  312.  
  313. @@ -462,7 +521,7 @@ ngx_http_scgi_cache_purge_handler(ngx_http_request_t *r)
  314.      slcf = ngx_http_get_module_loc_conf(r, ngx_http_scgi_module);
  315.  
  316.      if (ngx_http_cache_purge_init(r, slcf->upstream.cache->data,
  317. -                                  &slcf->cache_key)
  318. +                                  &slcf->cache_key, &slcf->cache_group_key)
  319.          != NGX_OK)
  320.      {
  321.          return NGX_HTTP_INTERNAL_SERVER_ERROR;
  322. @@ -496,6 +555,7 @@ typedef struct {
  323.      ngx_array_t               *uwsgi_values;
  324.  
  325.      ngx_http_complex_value_t   cache_key;
  326. +    ngx_http_complex_value_t   cache_group_key;
  327.  
  328.      ngx_str_t                  uwsgi_string;
  329.  
  330. @@ -506,7 +566,7 @@ typedef struct {
  331.  char *
  332.  ngx_http_uwsgi_cache_purge_conf(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
  333.  {
  334. -    ngx_http_compile_complex_value_t   ccv;
  335. +    ngx_http_compile_complex_value_t   ccv, group_ccv;
  336.      ngx_http_core_loc_conf_t          *clcf;
  337.      ngx_http_uwsgi_loc_conf_t         *ulcf;
  338.      ngx_str_t                         *value;
  339. @@ -548,6 +608,19 @@ ngx_http_uwsgi_cache_purge_conf(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
  340.          return NGX_CONF_ERROR;
  341.      }
  342.  
  343. +    if (cf->args->nelts > 3) {
  344. +        /* set proxy_cache_group_key part */
  345. +        ngx_memzero(&group_ccv, sizeof(ngx_http_compile_complex_value_t));
  346. +
  347. +        group_ccv.cf = cf;
  348. +        group_ccv.value = &value[3];
  349. +        group_ccv.complex_value = &ulcf->cache_group_key;
  350. +
  351. +        if (ngx_http_compile_complex_value(&group_ccv) != NGX_OK) {
  352. +            return NGX_CONF_ERROR;
  353. +        }
  354. +    }
  355. +
  356.      /* set handler */
  357.      clcf = ngx_http_conf_get_module_loc_conf(cf, ngx_http_core_module);
  358.  
  359. @@ -564,7 +637,7 @@ ngx_http_uwsgi_cache_purge_handler(ngx_http_request_t *r)
  360.      ulcf = ngx_http_get_module_loc_conf(r, ngx_http_uwsgi_module);
  361.  
  362.      if (ngx_http_cache_purge_init(r, ulcf->upstream.cache->data,
  363. -                                  &ulcf->cache_key)
  364. +                                  &ulcf->cache_key, &ulcf->cache_group_key)
  365.          != NGX_OK)
  366.      {
  367.          return NGX_HTTP_INTERNAL_SERVER_ERROR;
  368. @@ -585,16 +658,20 @@ ngx_http_cache_purge_send_response(ngx_http_request_t *r)
  369.  {
  370.      ngx_chain_t   out;
  371.      ngx_buf_t    *b;
  372. -    ngx_str_t    *key;
  373. +    ngx_str_t    *key, *group_key;
  374.      ngx_int_t     rc;
  375.      size_t        len;
  376.  
  377.      key = r->cache->keys.elts;
  378. +    group_key = r->cache->group_keys.elts;
  379.  
  380.      len = sizeof(ngx_http_cache_purge_success_page_top) - 1
  381.            + sizeof(ngx_http_cache_purge_success_page_tail) - 1
  382.            + sizeof("<br>Key : ") - 1 + sizeof(CRLF "<br>Path: ") - 1
  383.            + key[0].len + r->cache->file.name.len;
  384. +    if (r->cache->group_keys.nelts > 0) {
  385. +        len += sizeof("<br>Group Key : ") - 1 + group_key[0].len;
  386. +    }
  387.  
  388.      r->headers_out.content_type.len = sizeof("text/html") - 1;
  389.      r->headers_out.content_type.data = (u_char *) "text/html";
  390. @@ -620,6 +697,10 @@ ngx_http_cache_purge_send_response(ngx_http_request_t *r)
  391.                           sizeof(ngx_http_cache_purge_success_page_top) - 1);
  392.      b->last = ngx_cpymem(b->last, "<br>Key : ", sizeof("<br>Key : ") - 1);
  393.      b->last = ngx_cpymem(b->last, key[0].data, key[0].len);
  394. +    if (r->cache->group_keys.nelts > 0) {
  395. +        b->last = ngx_cpymem(b->last, "<br>Group Key : ", sizeof("<br>Group Key : ") - 1);
  396. +        b->last = ngx_cpymem(b->last, group_key[0].data, group_key[0].len);
  397. +    }
  398.      b->last = ngx_cpymem(b->last, CRLF "<br>Path: ",
  399.                           sizeof(CRLF "<br>Path: ") - 1);
  400.      b->last = ngx_cpymem(b->last, r->cache->file.name.data,
  401. @@ -638,7 +719,7 @@ ngx_http_cache_purge_send_response(ngx_http_request_t *r)
  402.  
  403.  ngx_int_t
  404.  ngx_http_cache_purge_init(ngx_http_request_t *r, ngx_http_file_cache_t *cache,
  405. -    ngx_http_complex_value_t *cache_key)
  406. +    ngx_http_complex_value_t *cache_key, ngx_http_complex_value_t *cache_group_key)
  407.  {
  408.      ngx_http_cache_t  *c;
  409.      ngx_str_t         *key;
  410. @@ -669,6 +750,23 @@ ngx_http_cache_purge_init(ngx_http_request_t *r, ngx_http_file_cache_t *cache,
  411.          return NGX_ERROR;
  412.      }
  413.  
  414. +    rc = ngx_array_init(&c->group_keys, r->pool, 1, sizeof(ngx_str_t));
  415. +    if (rc != NGX_OK) {
  416. +        return NGX_ERROR;
  417. +    }
  418. +
  419. +    if ((cache_group_key != NULL) && (cache_group_key->value.len > 0)) {
  420. +        key = ngx_array_push(&c->group_keys);
  421. +        if (key == NULL) {
  422. +            return NGX_ERROR;
  423. +        }
  424. +
  425. +        rc = ngx_http_complex_value(r, cache_group_key, key);
  426. +        if (rc != NGX_OK) {
  427. +            return NGX_ERROR;
  428. +        }
  429. +    }
  430. +
  431.      r->cache = c;
  432.      c->body_start = ngx_pagesize;
  433.      c->file_cache = cache;
  434. @@ -683,6 +781,8 @@ void
  435.  ngx_http_cache_purge_handler(ngx_http_request_t *r)
  436.  {
  437.      ngx_int_t  rc;
  438. +    ngx_http_cache_purge_loc_conf_t *cplc;
  439. +    ngx_str_t                        group_clean = ngx_null_string;
  440.  
  441.  #  if (NGX_HAVE_FILE_AIO)
  442.      if (r->aio) {
  443. @@ -690,7 +790,17 @@ ngx_http_cache_purge_handler(ngx_http_request_t *r)
  444.      }
  445.  #  endif
  446.  
  447. -    rc = ngx_http_file_cache_purge(r);
  448. +    cplc = ngx_http_get_module_loc_conf(r, ngx_http_cache_purge_module);
  449. +
  450. +    if (cplc->cache_group_clean != NULL) {
  451. +        ngx_http_complex_value(r, cplc->cache_group_clean, &group_clean);
  452. +    }
  453. +
  454. +    if ((group_clean.len > 0) && ngx_atoi(group_clean.data, group_clean.len)) {
  455. +        rc = ngx_http_file_cache_group_clean(r->cache->file_cache, r->cache->group_key);
  456. +    } else {
  457. +        rc = ngx_http_file_cache_purge(r);
  458. +    }
  459.  
  460.      ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
  461.                     "http file cache purge: %i, \"%s\"",
  462. @@ -780,6 +890,35 @@ ngx_http_file_cache_purge(ngx_http_request_t *r)
  463.      return NGX_OK;
  464.  }
  465.  
  466. +static void *
  467. +ngx_http_cache_purge_create_loc_conf(ngx_conf_t *cf)
  468. +{
  469. +    ngx_http_cache_purge_loc_conf_t  *conf;
  470. +
  471. +    conf = ngx_pcalloc(cf->pool, sizeof(ngx_http_cache_purge_loc_conf_t));
  472. +    if (conf == NULL) {
  473. +        return NGX_CONF_ERROR;
  474. +    }
  475. +
  476. +    conf->cache_group_clean = NULL;
  477. +
  478. +    return conf;
  479. +}
  480. +
  481. +
  482. +static char *
  483. +ngx_http_cache_purge_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
  484. +{
  485. +    ngx_http_cache_purge_loc_conf_t *prev = parent;
  486. +    ngx_http_cache_purge_loc_conf_t *conf = child;
  487. +
  488. +    if (conf->cache_group_clean == NULL) {
  489. +        conf->cache_group_clean = prev->cache_group_clean;
  490. +    }
  491. +
  492. +    return NGX_CONF_OK;
  493. +}
  494. +
  495.  #else /* !NGX_HTTP_CACHE */
  496.  
  497.  static ngx_http_module_t  ngx_http_cache_purge_module_ctx = {
  498. diff --git a/t/proxy.t b/t/proxy.t
  499. index 72a2405..2461191 100644
  500. --- a/t/proxy.t
  501. +++ b/t/proxy.t
  502. @@ -5,7 +5,7 @@ use Test::Nginx::Socket;
  503.  
  504.  repeat_each(1);
  505.  
  506. -plan tests => repeat_each() * (blocks() * 3 + 3 * 1);
  507. +plan tests => repeat_each() * 74;
  508.  
  509.  our $http_config = <<'_EOC_';
  510.      proxy_cache_path  /tmp/ngx_cache_purge_cache keys_zone=test_cache:10m;
  511. @@ -30,6 +30,25 @@ our $config = <<'_EOC_';
  512.      }
  513.  _EOC_
  514.  
  515. +our $config_group = <<'_EOC_';
  516. +    location /proxy_group {
  517. +        proxy_pass         $scheme://127.0.0.1:$server_port/etc/passwd;
  518. +        proxy_cache        test_cache;
  519. +        proxy_cache_key    $uri$is_args$args $arg_group;
  520. +        proxy_cache_valid  3m;
  521. +        add_header         X-Cache-Status $upstream_cache_status;
  522. +    }
  523. +
  524. +    location ~ /purge_group(/.*) {
  525. +        proxy_cache_purge  test_cache $1$is_args$args $arg_group;
  526. +        group_clean_cache_purge "$http_x_group_clean";
  527. +    }
  528. +
  529. +    location = /etc/passwd {
  530. +        root               /;
  531. +    }
  532. +_EOC_
  533. +
  534.  worker_connections(128);
  535.  no_shuffle();
  536.  run_tests();
  537. @@ -122,3 +141,229 @@ X-Cache-Status: HIT
  538.  --- response_body_like: root
  539.  --- timeout: 10
  540.  --- skip_nginx2: 4: < 0.8.3 or < 0.7.62
  541. +
  542. +
  543. +
  544. +=== TEST 7: prepare cache with group g1
  545. +--- http_config eval: $::http_config
  546. +--- config eval: $::config_group
  547. +--- request
  548. +GET /proxy_group/passwd?foo=bar&group=g1
  549. +--- error_code: 200
  550. +--- response_headers
  551. +Content-Type: text/plain
  552. +--- response_body_like: root
  553. +--- timeout: 10
  554. +--- skip_nginx2: 3: < 0.8.3 or < 0.7.62
  555. +
  556. +
  557. +
  558. +=== TEST 8: prepare cache with group g2
  559. +--- http_config eval: $::http_config
  560. +--- config eval: $::config_group
  561. +--- request
  562. +GET /proxy_group/passwd?foo=bar&group=g2
  563. +--- error_code: 200
  564. +--- response_headers
  565. +Content-Type: text/plain
  566. +--- response_body_like: root
  567. +--- timeout: 10
  568. +--- skip_nginx2: 3: < 0.8.3 or < 0.7.62
  569. +
  570. +
  571. +
  572. +=== TEST 9: prepare cache with group g2 (different parameters)
  573. +--- http_config eval: $::http_config
  574. +--- config eval: $::config_group
  575. +--- request
  576. +GET /proxy_group/passwd?foo=bar&bar=foo&group=g2
  577. +--- error_code: 200
  578. +--- response_headers
  579. +Content-Type: text/plain
  580. +--- response_body_like: root
  581. +--- timeout: 10
  582. +--- skip_nginx2: 3: < 0.8.3 or < 0.7.62
  583. +
  584. +
  585. +
  586. +=== TEST 10: get from cache with group g1
  587. +--- http_config eval: $::http_config
  588. +--- config eval: $::config_group
  589. +--- request
  590. +GET /proxy_group/passwd?foo=bar&group=g1
  591. +--- error_code: 200
  592. +--- response_headers
  593. +Content-Type: text/plain
  594. +X-Cache-Status: HIT
  595. +--- response_body_like: root
  596. +--- timeout: 10
  597. +--- skip_nginx2: 4: < 0.8.3 or < 0.7.62
  598. +
  599. +
  600. +
  601. +=== TEST 11: get from cache with group g2
  602. +--- http_config eval: $::http_config
  603. +--- config eval: $::config_group
  604. +--- request
  605. +GET /proxy_group/passwd?foo=bar&group=g2
  606. +--- error_code: 200
  607. +--- response_headers
  608. +Content-Type: text/plain
  609. +X-Cache-Status: HIT
  610. +--- response_body_like: root
  611. +--- timeout: 10
  612. +--- skip_nginx2: 4: < 0.8.3 or < 0.7.62
  613. +
  614. +
  615. +
  616. +=== TEST 12: get from cache with group g2 (different parameters)
  617. +--- http_config eval: $::http_config
  618. +--- config eval: $::config_group
  619. +--- request
  620. +GET /proxy_group/passwd?foo=bar&bar=foo&group=g2
  621. +--- error_code: 200
  622. +--- response_headers
  623. +Content-Type: text/plain
  624. +X-Cache-Status: HIT
  625. +--- response_body_like: root
  626. +--- timeout: 10
  627. +--- skip_nginx2: 3: < 0.8.3 or < 0.7.62
  628. +
  629. +
  630. +
  631. +=== TEST 13: purge from cache with group g1
  632. +--- http_config eval: $::http_config
  633. +--- config eval: $::config_group
  634. +--- request
  635. +DELETE /purge_group/?group=g1
  636. +--- more_headers
  637. +X-Group-Clean: 1
  638. +--- error_code: 200
  639. +--- response_headers
  640. +Content-Type: text/html
  641. +--- response_body_like: Successful purge
  642. +--- timeout: 10
  643. +--- skip_nginx2: 3: < 0.8.3 or < 0.7.62
  644. +
  645. +
  646. +
  647. +=== TEST 14: purge from cache with group g2 specific url
  648. +--- http_config eval: $::http_config
  649. +--- config eval: $::config_group
  650. +--- request
  651. +DELETE /purge_group/proxy_group/passwd?foo=bar&group=g2
  652. +--- more_headers
  653. +X-Group-Clean: 0
  654. +--- error_code: 200
  655. +--- response_headers
  656. +Content-Type: text/html
  657. +--- response_body_like: Successful purge
  658. +--- timeout: 10
  659. +--- skip_nginx2: 3: < 0.8.3 or < 0.7.62
  660. +
  661. +
  662. +
  663. +=== TEST 15: purge from empty cache with group g1
  664. +--- http_config eval: $::http_config
  665. +--- config eval: $::config_group
  666. +--- request
  667. +DELETE /purge_group/?group=g1
  668. +--- more_headers
  669. +X-Group-Clean: 1
  670. +--- error_code: 404
  671. +--- response_headers
  672. +Content-Type: text/html
  673. +--- response_body_like: 404 Not Found
  674. +--- timeout: 10
  675. +--- skip_nginx2: 3: < 0.8.3 or < 0.7.62
  676. +
  677. +
  678. +
  679. +=== TEST 16: purge from empty cache with group g2 specific url
  680. +--- http_config eval: $::http_config
  681. +--- config eval: $::config_group
  682. +--- request
  683. +DELETE /purge_group/proxy_group/passwd?foo=bar&group=g2
  684. +--- more_headers
  685. +X-Group-Clean: 0
  686. +--- error_code: 404
  687. +--- response_headers
  688. +Content-Type: text/html
  689. +--- response_body_like: 404 Not Found
  690. +--- timeout: 10
  691. +--- skip_nginx2: 3: < 0.8.3 or < 0.7.62
  692. +
  693. +
  694. +
  695. +=== TEST 17: get from source with group g1
  696. +--- http_config eval: $::http_config
  697. +--- config eval: $::config_group
  698. +--- request
  699. +GET /proxy_group/passwd?foo=bar&group=g1
  700. +--- error_code: 200
  701. +--- response_headers
  702. +Content-Type: text/plain
  703. +X-Cache-Status: MISS
  704. +--- response_body_like: root
  705. +--- timeout: 10
  706. +--- skip_nginx2: 4: < 0.8.3 or < 0.7.62
  707. +
  708. +
  709. +
  710. +=== TEST 18: get from source with group g2
  711. +--- http_config eval: $::http_config
  712. +--- config eval: $::config_group
  713. +--- request
  714. +GET /proxy_group/passwd?foo=bar&group=g2
  715. +--- error_code: 200
  716. +--- response_headers
  717. +Content-Type: text/plain
  718. +X-Cache-Status: MISS
  719. +--- response_body_like: root
  720. +--- timeout: 10
  721. +--- skip_nginx2: 4: < 0.8.3 or < 0.7.62
  722. +
  723. +
  724. +
  725. +=== TEST 19: get from source with group g1 (again)
  726. +--- http_config eval: $::http_config
  727. +--- config eval: $::config_group
  728. +--- request
  729. +GET /proxy_group/passwd?foo=bar&group=g1
  730. +--- error_code: 200
  731. +--- response_headers
  732. +Content-Type: text/plain
  733. +X-Cache-Status: HIT
  734. +--- response_body_like: root
  735. +--- timeout: 10
  736. +--- skip_nginx2: 4: < 0.8.3 or < 0.7.62
  737. +
  738. +
  739. +
  740. +=== TEST 20: get from source with group g2 (again, after purge)
  741. +--- http_config eval: $::http_config
  742. +--- config eval: $::config_group
  743. +--- request
  744. +GET /proxy_group/passwd?foo=bar&group=g2
  745. +--- error_code: 200
  746. +--- response_headers
  747. +Content-Type: text/plain
  748. +X-Cache-Status: HIT
  749. +--- response_body_like: root
  750. +--- timeout: 10
  751. +--- skip_nginx2: 4: < 0.8.3 or < 0.7.62
  752. +
  753. +
  754. +
  755. +=== TEST 21: get from cache (again, different parameters)
  756. +--- http_config eval: $::http_config
  757. +--- config eval: $::config_group
  758. +--- request
  759. +GET /proxy_group/passwd?foo=bar&bar=foo&group=g2
  760. +--- error_code: 200
  761. +--- response_headers
  762. +Content-Type: text/plain
  763. +X-Cache-Status: HIT
  764. +--- response_body_like: root
  765. +--- timeout: 10
  766. +--- skip_nginx2: 4: < 0.8.3 or < 0.7.62
  767. --
  768. 1.7.1
RAW Paste Data