4343typedef struct {
4444 ngx_flag_t enable ;
4545 ngx_str_t method ;
46+ ngx_flag_t purge_all ;
4647 ngx_array_t * access ; /* array of ngx_in_cidr_t */
4748 ngx_array_t * access6 ; /* array of ngx_in6_cidr_t */
4849} ngx_http_cache_purge_conf_t ;
@@ -90,6 +91,11 @@ char *ngx_http_uwsgi_cache_purge_conf(ngx_conf_t *cf,
9091ngx_int_t ngx_http_uwsgi_cache_purge_handler (ngx_http_request_t * r );
9192# endif /* NGX_HTTP_UWSGI */
9293
94+ static ngx_int_t
95+ ngx_http_purge_file_cache_noop (ngx_tree_ctx_t * ctx , ngx_str_t * path );
96+ static ngx_int_t
97+ ngx_http_purge_file_cache_delete_file (ngx_tree_ctx_t * ctx , ngx_str_t * path );
98+
9399ngx_int_t ngx_http_cache_purge_access_handler (ngx_http_request_t * r );
94100ngx_int_t ngx_http_cache_purge_access (ngx_array_t * a , ngx_array_t * a6 ,
95101 struct sockaddr * s );
@@ -105,6 +111,9 @@ void ngx_http_cache_purge_handler(ngx_http_request_t *r);
105111
106112ngx_int_t ngx_http_file_cache_purge (ngx_http_request_t * r );
107113
114+
115+ void ngx_http_cache_purge_all (ngx_http_request_t * r , ngx_http_file_cache_t * cache );
116+
108117char * ngx_http_cache_purge_conf (ngx_conf_t * cf ,
109118 ngx_http_cache_purge_conf_t * cpcf );
110119
@@ -378,11 +387,12 @@ ngx_http_fastcgi_cache_purge_conf(ngx_conf_t *cf, ngx_command_t *cmd,
378387ngx_int_t
379388ngx_http_fastcgi_cache_purge_handler (ngx_http_request_t * r )
380389{
381- ngx_http_file_cache_t * cache ;
382- ngx_http_fastcgi_loc_conf_t * flcf ;
390+ ngx_http_file_cache_t * cache ;
391+ ngx_http_fastcgi_loc_conf_t * flcf ;
392+ ngx_http_cache_purge_loc_conf_t * cplcf ;
383393# if (nginx_version >= 1007009 )
384- ngx_http_fastcgi_main_conf_t * fmcf ;
385- ngx_int_t rc ;
394+ ngx_http_fastcgi_main_conf_t * fmcf ;
395+ ngx_int_t rc ;
386396# endif /* nginx_version >= 1007009 */
387397
388398 if (ngx_http_upstream_create (r ) != NGX_OK ) {
@@ -414,6 +424,12 @@ ngx_http_fastcgi_cache_purge_handler(ngx_http_request_t *r)
414424 return NGX_HTTP_INTERNAL_SERVER_ERROR ;
415425 }
416426
427+ // Purge-all option
428+ cplcf = ngx_http_get_module_loc_conf (r , ngx_http_cache_purge_module );
429+ if (cplcf -> conf -> purge_all ) {
430+ ngx_http_cache_purge_all (r , cache );
431+ }
432+
417433# if (nginx_version >= 8011 )
418434 r -> main -> count ++ ;
419435# endif
@@ -649,11 +665,12 @@ ngx_http_proxy_cache_purge_conf(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
649665ngx_int_t
650666ngx_http_proxy_cache_purge_handler (ngx_http_request_t * r )
651667{
652- ngx_http_file_cache_t * cache ;
653- ngx_http_proxy_loc_conf_t * plcf ;
668+ ngx_http_file_cache_t * cache ;
669+ ngx_http_proxy_loc_conf_t * plcf ;
670+ ngx_http_cache_purge_loc_conf_t * cplcf ;
654671# if (nginx_version >= 1007009 )
655- ngx_http_proxy_main_conf_t * pmcf ;
656- ngx_int_t rc ;
672+ ngx_http_proxy_main_conf_t * pmcf ;
673+ ngx_int_t rc ;
657674# endif /* nginx_version >= 1007009 */
658675
659676 if (ngx_http_upstream_create (r ) != NGX_OK ) {
@@ -685,6 +702,12 @@ ngx_http_proxy_cache_purge_handler(ngx_http_request_t *r)
685702 return NGX_HTTP_INTERNAL_SERVER_ERROR ;
686703 }
687704
705+ // Purge-all option
706+ cplcf = ngx_http_get_module_loc_conf (r , ngx_http_cache_purge_module );
707+ if (cplcf -> conf -> purge_all ) {
708+ ngx_http_cache_purge_all (r , cache );
709+ }
710+
688711# if (nginx_version >= 8011 )
689712 r -> main -> count ++ ;
690713# endif
@@ -862,11 +885,12 @@ ngx_http_scgi_cache_purge_conf(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
862885ngx_int_t
863886ngx_http_scgi_cache_purge_handler (ngx_http_request_t * r )
864887{
865- ngx_http_file_cache_t * cache ;
866- ngx_http_scgi_loc_conf_t * slcf ;
888+ ngx_http_file_cache_t * cache ;
889+ ngx_http_scgi_loc_conf_t * slcf ;
890+ ngx_http_cache_purge_loc_conf_t * cplcf ;
867891# if (nginx_version >= 1007009 )
868- ngx_http_scgi_main_conf_t * smcf ;
869- ngx_int_t rc ;
892+ ngx_http_scgi_main_conf_t * smcf ;
893+ ngx_int_t rc ;
870894# endif /* nginx_version >= 1007009 */
871895
872896 if (ngx_http_upstream_create (r ) != NGX_OK ) {
@@ -898,6 +922,12 @@ ngx_http_scgi_cache_purge_handler(ngx_http_request_t *r)
898922 return NGX_HTTP_INTERNAL_SERVER_ERROR ;
899923 }
900924
925+ // Purge-all option
926+ cplcf = ngx_http_get_module_loc_conf (r , ngx_http_cache_purge_module );
927+ if (cplcf -> conf -> purge_all ) {
928+ ngx_http_cache_purge_all (r , cache );
929+ }
930+
901931# if (nginx_version >= 8011 )
902932 r -> main -> count ++ ;
903933# endif
@@ -1098,11 +1128,12 @@ ngx_http_uwsgi_cache_purge_conf(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
10981128ngx_int_t
10991129ngx_http_uwsgi_cache_purge_handler (ngx_http_request_t * r )
11001130{
1101- ngx_http_file_cache_t * cache ;
1102- ngx_http_uwsgi_loc_conf_t * ulcf ;
1131+ ngx_http_file_cache_t * cache ;
1132+ ngx_http_uwsgi_loc_conf_t * ulcf ;
1133+ ngx_http_cache_purge_loc_conf_t * cplcf ;
11031134# if (nginx_version >= 1007009 )
1104- ngx_http_uwsgi_main_conf_t * umcf ;
1105- ngx_int_t rc ;
1135+ ngx_http_uwsgi_main_conf_t * umcf ;
1136+ ngx_int_t rc ;
11061137# endif /* nginx_version >= 1007009 */
11071138
11081139 if (ngx_http_upstream_create (r ) != NGX_OK ) {
@@ -1134,6 +1165,12 @@ ngx_http_uwsgi_cache_purge_handler(ngx_http_request_t *r)
11341165 return NGX_HTTP_INTERNAL_SERVER_ERROR ;
11351166 }
11361167
1168+ // Purge-all option
1169+ cplcf = ngx_http_get_module_loc_conf (r , ngx_http_cache_purge_module );
1170+ if (cplcf -> conf -> purge_all ) {
1171+ ngx_http_cache_purge_all (r , cache );
1172+ }
1173+
11371174# if (nginx_version >= 8011 )
11381175 r -> main -> count ++ ;
11391176# endif
@@ -1144,6 +1181,27 @@ ngx_http_uwsgi_cache_purge_handler(ngx_http_request_t *r)
11441181}
11451182# endif /* NGX_HTTP_UWSGI */
11461183
1184+
1185+ static ngx_int_t
1186+ ngx_http_purge_file_cache_noop (ngx_tree_ctx_t * ctx , ngx_str_t * path )
1187+ {
1188+ return NGX_OK ;
1189+ }
1190+
1191+ static ngx_int_t
1192+ ngx_http_purge_file_cache_delete_file (ngx_tree_ctx_t * ctx , ngx_str_t * path )
1193+ {
1194+ ngx_log_debug1 (NGX_LOG_DEBUG_HTTP , ctx -> log , 0 ,
1195+ "http file cache delete: \"%s\"" , path -> data );
1196+
1197+ if (ngx_delete_file (path -> data ) == NGX_FILE_ERROR ) {
1198+ ngx_log_error (NGX_LOG_CRIT , ctx -> log , ngx_errno ,
1199+ ngx_delete_file_n " \"%s\" failed" , path -> data );
1200+ }
1201+
1202+ return NGX_OK ;
1203+ }
1204+
11471205ngx_int_t
11481206ngx_http_cache_purge_access_handler (ngx_http_request_t * r )
11491207{
@@ -1401,6 +1459,7 @@ ngx_http_cache_purge_init(ngx_http_request_t *r, ngx_http_file_cache_t *cache,
14011459void
14021460ngx_http_cache_purge_handler (ngx_http_request_t * r )
14031461{
1462+ ngx_http_cache_purge_loc_conf_t * cplcf ;
14041463 ngx_int_t rc ;
14051464
14061465# if (NGX_HAVE_FILE_AIO )
@@ -1409,11 +1468,17 @@ ngx_http_cache_purge_handler(ngx_http_request_t *r)
14091468 }
14101469# endif
14111470
1412- rc = ngx_http_file_cache_purge (r );
1471+ cplcf = ngx_http_get_module_loc_conf (r , ngx_http_cache_purge_module );
1472+ if (cplcf -> conf -> purge_all ) {
1473+ rc = NGX_OK ;
1474+ }
1475+ else {
1476+ rc = ngx_http_file_cache_purge (r );
14131477
1414- ngx_log_debug2 (NGX_LOG_DEBUG_HTTP , r -> connection -> log , 0 ,
1478+ ngx_log_debug2 (NGX_LOG_DEBUG_HTTP , r -> connection -> log , 0 ,
14151479 "http file cache purge: %i, \"%s\"" ,
14161480 rc , r -> cache -> file .name .data );
1481+ }
14171482
14181483 switch (rc ) {
14191484 case NGX_OK :
@@ -1499,6 +1564,27 @@ ngx_http_file_cache_purge(ngx_http_request_t *r)
14991564 return NGX_OK ;
15001565}
15011566
1567+
1568+ void
1569+ ngx_http_cache_purge_all (ngx_http_request_t * r , ngx_http_file_cache_t * cache ) {
1570+ ngx_log_debug (NGX_LOG_DEBUG_HTTP , r -> connection -> log , 0 ,
1571+ "purge_all http in %s" ,
1572+ cache -> path -> name .data );
1573+
1574+ // Walk the tree and remove all the files
1575+ ngx_tree_ctx_t tree ;
1576+ tree .init_handler = NULL ;
1577+ tree .file_handler = ngx_http_purge_file_cache_delete_file ;
1578+ tree .pre_tree_handler = ngx_http_purge_file_cache_noop ;
1579+ tree .post_tree_handler = ngx_http_purge_file_cache_noop ;
1580+ tree .spec_handler = ngx_http_purge_file_cache_noop ;
1581+ tree .data = cache ;
1582+ tree .alloc = 0 ;
1583+ tree .log = ngx_cycle -> log ;
1584+
1585+ ngx_walk_tree (& tree , & cache -> path -> name );
1586+ }
1587+
15021588char *
15031589ngx_http_cache_purge_conf (ngx_conf_t * cf , ngx_http_cache_purge_conf_t * cpcf )
15041590{
@@ -1510,7 +1596,11 @@ ngx_http_cache_purge_conf(ngx_conf_t *cf, ngx_http_cache_purge_conf_t *cpcf)
15101596 ngx_str_t * value ;
15111597 ngx_int_t rc ;
15121598 ngx_uint_t i ;
1599+ ngx_uint_t from_position ;
15131600
1601+ from_position = 2 ;
1602+
1603+ // xxx_cache_purge on|off|<method> [purge_all] [from all|<ip> [.. <ip>]]
15141604 value = cf -> args -> elts ;
15151605
15161606 if (ngx_strcmp (value [1 ].data , "off" ) == 0 ) {
@@ -1529,20 +1619,27 @@ ngx_http_cache_purge_conf(ngx_conf_t *cf, ngx_http_cache_purge_conf_t *cpcf)
15291619 return NGX_CONF_OK ;
15301620 }
15311621
1622+ // We will purge all the keys
1623+ if (ngx_strcmp (value [from_position ].data , "purge_all" ) == 0 ) {
1624+ cpcf -> purge_all = 1 ;
1625+ from_position ++ ;
1626+ }
1627+
1628+
15321629 /* sanity check */
1533- if (ngx_strcmp (value [2 ].data , "from" ) != 0 ) {
1630+ if (ngx_strcmp (value [from_position ].data , "from" ) != 0 ) {
15341631 ngx_conf_log_error (NGX_LOG_EMERG , cf , 0 ,
15351632 "invalid parameter \"%V\", expected"
1536- " \"from\" keyword" , & value [2 ]);
1633+ " \"from\" keyword" , & value [from_position ]);
15371634 return NGX_CONF_ERROR ;
15381635 }
15391636
1540- if (ngx_strcmp (value [3 ].data , "all" ) == 0 ) {
1637+ if (ngx_strcmp (value [from_position + 1 ].data , "all" ) == 0 ) {
15411638 cpcf -> enable = 1 ;
15421639 return NGX_CONF_OK ;
15431640 }
15441641
1545- for (i = 3 ; i < cf -> args -> nelts ; i ++ ) {
1642+ for (i = ( from_position + 1 ) ; i < cf -> args -> nelts ; i ++ ) {
15461643 rc = ngx_ptocidr (& value [i ], & cidr );
15471644
15481645 if (rc == NGX_ERROR ) {
@@ -1560,7 +1657,7 @@ ngx_http_cache_purge_conf(ngx_conf_t *cf, ngx_http_cache_purge_conf_t *cpcf)
15601657 switch (cidr .family ) {
15611658 case AF_INET :
15621659 if (cpcf -> access == NULL ) {
1563- cpcf -> access = ngx_array_create (cf -> pool , cf -> args -> nelts - 3 ,
1660+ cpcf -> access = ngx_array_create (cf -> pool , cf -> args -> nelts - ( from_position + 1 ) ,
15641661 sizeof (ngx_in_cidr_t ));
15651662 if (cpcf -> access == NULL ) {
15661663 return NGX_CONF_ERROR ;
@@ -1580,7 +1677,7 @@ ngx_http_cache_purge_conf(ngx_conf_t *cf, ngx_http_cache_purge_conf_t *cpcf)
15801677# if (NGX_HAVE_INET6 )
15811678 case AF_INET6 :
15821679 if (cpcf -> access6 == NULL ) {
1583- cpcf -> access6 = ngx_array_create (cf -> pool , cf -> args -> nelts - 3 ,
1680+ cpcf -> access6 = ngx_array_create (cf -> pool , cf -> args -> nelts - ( from_position + 1 ) ,
15841681 sizeof (ngx_in6_cidr_t ));
15851682 if (cpcf -> access6 == NULL ) {
15861683 return NGX_CONF_ERROR ;
@@ -1613,6 +1710,7 @@ ngx_http_cache_purge_merge_conf(ngx_http_cache_purge_conf_t *conf,
16131710 if (prev -> enable == 1 ) {
16141711 conf -> enable = prev -> enable ;
16151712 conf -> method = prev -> method ;
1713+ conf -> purge_all = prev -> purge_all ;
16161714 conf -> access = prev -> access ;
16171715 conf -> access6 = prev -> access6 ;
16181716
0 commit comments