3737 #error This module cannot be build against an unknown nginx version.
3838#endif
3939
40+ #define NGX_REPONSE_TYPE_HTML 1
41+ #define NGX_REPONSE_TYPE_XML 2
42+ #define NGX_REPONSE_TYPE_JSON 3
43+ #define NGX_REPONSE_TYPE_TEXT 4
44+
45+ static const char ngx_http_cache_purge_content_type_json [] = "application/json" ;
46+ static const char ngx_http_cache_purge_content_type_html [] = "text/html" ;
47+ static const char ngx_http_cache_purge_content_type_xml [] = "text/xml" ;
48+ static const char ngx_http_cache_purge_content_type_text [] = "text/plain" ;
49+
50+ static size_t ngx_http_cache_purge_content_type_json_size = sizeof (ngx_http_cache_purge_content_type_json );
51+ static size_t ngx_http_cache_purge_content_type_html_size = sizeof (ngx_http_cache_purge_content_type_html );
52+ static size_t ngx_http_cache_purge_content_type_xml_size = sizeof (ngx_http_cache_purge_content_type_xml );
53+ static size_t ngx_http_cache_purge_content_type_text_size = sizeof (ngx_http_cache_purge_content_type_text );
54+
55+ static const char ngx_http_cache_purge_body_templ_json [] = "{\"Key\": \"%s\",\"Path\": \"%s\"}" ;
56+ static const char ngx_http_cache_purge_body_templ_html [] = "<html><head><title>Successful purge</title></head><body bgcolor=\"white\"><center><h1>Successful purge</h1><br>Key : %s<br>Path : %s</center></body></html>" ;
57+ static const char ngx_http_cache_purge_body_templ_xml [] = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><status><Key><![CDATA[%s]]></Key><Path><![CDATA[%s]]></Path></status>" ;
58+ static const char ngx_http_cache_purge_body_templ_text [] = "Key:%s\nPath:%s\n" ;
59+
60+ static size_t ngx_http_cache_purge_body_templ_json_size = sizeof (ngx_http_cache_purge_body_templ_json );
61+ static size_t ngx_http_cache_purge_body_templ_html_size = sizeof (ngx_http_cache_purge_body_templ_html );
62+ static size_t ngx_http_cache_purge_body_templ_xml_size = sizeof (ngx_http_cache_purge_body_templ_xml );
63+ static size_t ngx_http_cache_purge_body_templ_text_size = sizeof (ngx_http_cache_purge_body_templ_text );
4064
4165#if (NGX_HTTP_CACHE )
4266
@@ -65,6 +89,8 @@ typedef struct {
6589 ngx_http_cache_purge_conf_t * conf ;
6690 ngx_http_handler_pt handler ;
6791 ngx_http_handler_pt original_handler ;
92+
93+ ngx_uint_t resptype ; /* response content-type */
6894} ngx_http_cache_purge_loc_conf_t ;
6995
7096# if (NGX_HTTP_FASTCGI )
@@ -91,6 +117,8 @@ char *ngx_http_uwsgi_cache_purge_conf(ngx_conf_t *cf,
91117ngx_int_t ngx_http_uwsgi_cache_purge_handler (ngx_http_request_t * r );
92118# endif /* NGX_HTTP_UWSGI */
93119
120+ char * ngx_http_cache_purge_response_type_conf (ngx_conf_t * cf ,
121+ ngx_command_t * cmd , void * conf );
94122static ngx_int_t
95123ngx_http_purge_file_cache_noop (ngx_tree_ctx_t * ctx , ngx_str_t * path );
96124static ngx_int_t
@@ -169,6 +197,14 @@ static ngx_command_t ngx_http_cache_purge_module_commands[] = {
169197 },
170198# endif /* NGX_HTTP_UWSGI */
171199
200+
201+ { ngx_string ("cache_purge_response_type" ),
202+ NGX_HTTP_MAIN_CONF |NGX_HTTP_SRV_CONF |NGX_HTTP_LOC_CONF |NGX_CONF_TAKE1 ,
203+ ngx_http_cache_purge_response_type_conf ,
204+ NGX_HTTP_LOC_CONF_OFFSET ,
205+ 0 ,
206+ NULL },
207+
172208 ngx_null_command
173209};
174210
@@ -201,20 +237,6 @@ ngx_module_t ngx_http_cache_purge_module = {
201237 NGX_MODULE_V1_PADDING
202238};
203239
204- static char ngx_http_cache_purge_success_page_top [] =
205- "<html>" CRLF
206- "<head><title>Successful purge</title></head>" CRLF
207- "<body bgcolor=\"white\">" CRLF
208- "<center><h1>Successful purge</h1>" CRLF
209- ;
210-
211- static char ngx_http_cache_purge_success_page_tail [] =
212- CRLF "</center>" CRLF
213- "<hr><center>" NGINX_VER "</center>" CRLF
214- "</body>" CRLF
215- "</html>" CRLF
216- ;
217-
218240# if (NGX_HTTP_FASTCGI )
219241extern ngx_module_t ngx_http_fastcgi_module ;
220242
@@ -1153,6 +1175,7 @@ ngx_http_uwsgi_cache_purge_conf(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
11531175 return NGX_CONF_OK ;
11541176}
11551177
1178+
11561179ngx_int_t
11571180ngx_http_uwsgi_cache_purge_handler (ngx_http_request_t * r ) {
11581181 ngx_http_file_cache_t * cache ;
@@ -1216,6 +1239,55 @@ ngx_http_uwsgi_cache_purge_handler(ngx_http_request_t *r) {
12161239# endif /* NGX_HTTP_UWSGI */
12171240
12181241
1242+ char *
1243+ ngx_http_cache_purge_response_type_conf (ngx_conf_t * cf , ngx_command_t * cmd , void * conf )
1244+ {
1245+ ngx_http_cache_purge_loc_conf_t * cplcf ;
1246+ ngx_str_t * value ;
1247+
1248+ cplcf = ngx_http_conf_get_module_loc_conf (cf , ngx_http_cache_purge_module );
1249+
1250+ /* check for duplicates / collisions */
1251+ if (cplcf -> resptype != NGX_CONF_UNSET_UINT && cf -> cmd_type == NGX_HTTP_LOC_CONF ) {
1252+ return "is duplicate" ;
1253+ }
1254+
1255+ /* sanity check */
1256+ if (cf -> args -> nelts < 2 ) {
1257+ return "is invalid paramter, ex) cache_purge_response_type (html|json|xml|text)" ;
1258+ }
1259+
1260+ if (cf -> args -> nelts > 2 ) {
1261+ return "is required only 1 option, ex) cache_purge_response_type (html|json|xml|text)" ;
1262+ }
1263+
1264+ value = cf -> args -> elts ;
1265+
1266+ if (ngx_strcmp (value [1 ].data , "html" ) != 0 && ngx_strcmp (value [1 ].data , "json" ) != 0
1267+ && ngx_strcmp (value [1 ].data , "xml" ) != 0 && ngx_strcmp (value [1 ].data , "text" ) != 0 ) {
1268+ ngx_conf_log_error (NGX_LOG_EMERG , cf , 0 ,
1269+ "invalid parameter \"%V\", expected"
1270+ " \"(html|json|xml|text)\" keyword" , & value [1 ]);
1271+ return NGX_CONF_ERROR ;
1272+ }
1273+
1274+ if (cf -> cmd_type == NGX_HTTP_MODULE ) {
1275+ return "(separate server or location syntax) is not allowed here" ;
1276+ }
1277+
1278+ if (ngx_strcmp (value [1 ].data , "html" ) == 0 ) {
1279+ cplcf -> resptype = NGX_REPONSE_TYPE_HTML ;
1280+ } else if (ngx_strcmp (value [1 ].data , "xml" ) == 0 ) {
1281+ cplcf -> resptype = NGX_REPONSE_TYPE_XML ;
1282+ } else if (ngx_strcmp (value [1 ].data , "json" ) == 0 ) {
1283+ cplcf -> resptype = NGX_REPONSE_TYPE_JSON ;
1284+ } else if (ngx_strcmp (value [1 ].data , "text" ) == 0 ) {
1285+ cplcf -> resptype = NGX_REPONSE_TYPE_TEXT ;
1286+ }
1287+
1288+ return NGX_CONF_OK ;
1289+ }
1290+
12191291static ngx_int_t
12201292ngx_http_purge_file_cache_noop (ngx_tree_ctx_t * ctx , ngx_str_t * path ) {
12211293 return NGX_OK ;
@@ -1397,16 +1469,82 @@ ngx_http_cache_purge_send_response(ngx_http_request_t *r) {
13971469 ngx_str_t * key ;
13981470 ngx_int_t rc ;
13991471 size_t len ;
1472+
1473+ size_t body_len ;
1474+ size_t resp_tmpl_len ;
1475+ u_char * buf ;
1476+ u_char * buf_keydata ;
1477+ u_char * p ;
1478+ const char * resp_ct ;
1479+ size_t resp_ct_size ;
1480+ const char * resp_body ;
1481+ size_t resp_body_size ;
1482+
1483+ ngx_http_cache_purge_loc_conf_t * cplcf ;
1484+ cplcf = ngx_http_get_module_loc_conf (r , ngx_http_cache_purge_module );
14001485
14011486 key = r -> cache -> keys .elts ;
14021487
1403- len = sizeof (ngx_http_cache_purge_success_page_top ) - 1
1404- + sizeof (ngx_http_cache_purge_success_page_tail ) - 1
1405- + sizeof ("<br>Key : " ) - 1 + sizeof (CRLF "<br>Path: " ) - 1
1406- + key [0 ].len + r -> cache -> file .name .len ;
1488+ buf_keydata = ngx_pcalloc (r -> pool , key [0 ].len + 1 );
1489+ if (buf_keydata == NULL ) {
1490+ return NGX_HTTP_INTERNAL_SERVER_ERROR ;
1491+ }
1492+
1493+ p = ngx_cpymem (buf_keydata , key [0 ].data , key [0 ].len );
1494+ if (p == NULL ) {
1495+ return NGX_HTTP_INTERNAL_SERVER_ERROR ;
1496+ }
1497+
1498+ switch (cplcf -> resptype ) {
1499+
1500+ case NGX_REPONSE_TYPE_JSON :
1501+ resp_ct = ngx_http_cache_purge_content_type_json ;
1502+ resp_ct_size = ngx_http_cache_purge_content_type_json_size ;
1503+ resp_body = ngx_http_cache_purge_body_templ_json ;
1504+ resp_body_size = ngx_http_cache_purge_body_templ_json_size ;
1505+ break ;
1506+
1507+ case NGX_REPONSE_TYPE_XML :
1508+ resp_ct = ngx_http_cache_purge_content_type_xml ;
1509+ resp_ct_size = ngx_http_cache_purge_content_type_xml_size ;
1510+ resp_body = ngx_http_cache_purge_body_templ_xml ;
1511+ resp_body_size = ngx_http_cache_purge_body_templ_xml_size ;
1512+ break ;
1513+
1514+ case NGX_REPONSE_TYPE_TEXT :
1515+ resp_ct = ngx_http_cache_purge_content_type_text ;
1516+ resp_ct_size = ngx_http_cache_purge_content_type_text_size ;
1517+ resp_body = ngx_http_cache_purge_body_templ_text ;
1518+ resp_body_size = ngx_http_cache_purge_body_templ_text_size ;
1519+ break ;
1520+
1521+ default :
1522+ case NGX_REPONSE_TYPE_HTML :
1523+ resp_ct = ngx_http_cache_purge_content_type_html ;
1524+ resp_ct_size = ngx_http_cache_purge_content_type_html_size ;
1525+ resp_body = ngx_http_cache_purge_body_templ_html ;
1526+ resp_body_size = ngx_http_cache_purge_body_templ_html_size ;
1527+ break ;
1528+ }
1529+
1530+ body_len = resp_body_size - 4 - 1 ;
1531+ r -> headers_out .content_type .len = resp_ct_size - 1 ;
1532+ r -> headers_out .content_type .data = (u_char * ) resp_ct ;
1533+
1534+ resp_tmpl_len = body_len + key [0 ].len + r -> cache -> file .name .len ;
1535+
1536+ buf = ngx_pcalloc (r -> pool , resp_tmpl_len );
1537+ if (buf == NULL ) {
1538+ return NGX_HTTP_INTERNAL_SERVER_ERROR ;
1539+ }
1540+
1541+ p = ngx_snprintf (buf , resp_tmpl_len , resp_body , buf_keydata , r -> cache -> file .name .data );
1542+ if (p == NULL ) {
1543+ return NGX_HTTP_INTERNAL_SERVER_ERROR ;
1544+ }
1545+
1546+ len = body_len + key [0 ].len + r -> cache -> file .name .len ;
14071547
1408- r -> headers_out .content_type .len = sizeof ("text/html" ) - 1 ;
1409- r -> headers_out .content_type .data = (u_char * ) "text/html" ;
14101548 r -> headers_out .status = NGX_HTTP_OK ;
14111549 r -> headers_out .content_length_n = len ;
14121550
@@ -1421,27 +1559,20 @@ ngx_http_cache_purge_send_response(ngx_http_request_t *r) {
14211559 if (b == NULL ) {
14221560 return NGX_HTTP_INTERNAL_SERVER_ERROR ;
14231561 }
1562+
14241563
14251564 out .buf = b ;
14261565 out .next = NULL ;
14271566
1428- b -> last = ngx_cpymem (b -> last , ngx_http_cache_purge_success_page_top ,
1429- sizeof (ngx_http_cache_purge_success_page_top ) - 1 );
1430- b -> last = ngx_cpymem (b -> last , "<br>Key : " , sizeof ("<br>Key : " ) - 1 );
1431- b -> last = ngx_cpymem (b -> last , key [0 ].data , key [0 ].len );
1432- b -> last = ngx_cpymem (b -> last , CRLF "<br>Path: " ,
1433- sizeof (CRLF "<br>Path: " ) - 1 );
1434- b -> last = ngx_cpymem (b -> last , r -> cache -> file .name .data ,
1435- r -> cache -> file .name .len );
1436- b -> last = ngx_cpymem (b -> last , ngx_http_cache_purge_success_page_tail ,
1437- sizeof (ngx_http_cache_purge_success_page_tail ) - 1 );
1567+ b -> last = ngx_cpymem (b -> last , buf , resp_tmpl_len );
14381568 b -> last_buf = 1 ;
14391569
14401570 rc = ngx_http_send_header (r );
14411571 if (rc == NGX_ERROR || rc > NGX_OK || r -> header_only ) {
14421572 return rc ;
14431573 }
14441574
1575+
14451576 return ngx_http_output_filter (r , & out );
14461577}
14471578
@@ -1831,7 +1962,6 @@ ngx_http_cache_purge_merge_conf(ngx_http_cache_purge_conf_t *conf,
18311962 conf -> purge_all = prev -> purge_all ;
18321963 conf -> access = prev -> access ;
18331964 conf -> access6 = prev -> access6 ;
1834-
18351965 } else {
18361966 conf -> enable = 0 ;
18371967 }
@@ -1870,6 +2000,8 @@ ngx_http_cache_purge_create_loc_conf(ngx_conf_t *cf) {
18702000 conf -> uwsgi .enable = NGX_CONF_UNSET ;
18712001# endif /* NGX_HTTP_UWSGI */
18722002
2003+ conf -> resptype = NGX_CONF_UNSET_UINT ;
2004+
18732005 conf -> conf = NGX_CONF_UNSET_PTR ;
18742006
18752007 return conf ;
@@ -1895,6 +2027,8 @@ ngx_http_cache_purge_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child) {
18952027
18962028 clcf = ngx_http_conf_get_module_loc_conf (cf , ngx_http_core_module );
18972029
2030+ ngx_conf_merge_uint_value (conf -> resptype , prev -> resptype , NGX_REPONSE_TYPE_HTML );
2031+
18982032# if (NGX_HTTP_FASTCGI )
18992033 ngx_http_cache_purge_merge_conf (& conf -> fastcgi , & prev -> fastcgi );
19002034
0 commit comments