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
@@ -64,6 +88,8 @@ typedef struct {
6488 ngx_http_cache_purge_conf_t * conf ;
6589 ngx_http_handler_pt handler ;
6690 ngx_http_handler_pt original_handler ;
91+
92+ ngx_uint_t resptype ; /* response content-type */
6793} ngx_http_cache_purge_loc_conf_t ;
6894
6995# if (NGX_HTTP_FASTCGI )
@@ -90,6 +116,9 @@ char *ngx_http_uwsgi_cache_purge_conf(ngx_conf_t *cf,
90116ngx_int_t ngx_http_uwsgi_cache_purge_handler (ngx_http_request_t * r );
91117# endif /* NGX_HTTP_UWSGI */
92118
119+ char * ngx_http_cache_purge_response_type_conf (ngx_conf_t * cf ,
120+ ngx_command_t * cmd , void * conf );
121+
93122ngx_int_t ngx_http_cache_purge_access_handler (ngx_http_request_t * r );
94123ngx_int_t ngx_http_cache_purge_access (ngx_array_t * a , ngx_array_t * a6 ,
95124 struct sockaddr * s );
@@ -150,7 +179,14 @@ static ngx_command_t ngx_http_cache_purge_module_commands[] = {
150179 NULL },
151180# endif /* NGX_HTTP_UWSGI */
152181
153- ngx_null_command
182+ { ngx_string ("cache_purge_response_type" ),
183+ NGX_HTTP_MAIN_CONF |NGX_HTTP_SRV_CONF |NGX_HTTP_LOC_CONF |NGX_CONF_TAKE1 ,
184+ ngx_http_cache_purge_response_type_conf ,
185+ NGX_HTTP_LOC_CONF_OFFSET ,
186+ 0 ,
187+ NULL },
188+
189+ ngx_null_command
154190};
155191
156192static ngx_http_module_t ngx_http_cache_purge_module_ctx = {
@@ -182,20 +218,6 @@ ngx_module_t ngx_http_cache_purge_module = {
182218 NGX_MODULE_V1_PADDING
183219};
184220
185- static char ngx_http_cache_purge_success_page_top [] =
186- "<html>" CRLF
187- "<head><title>Successful purge</title></head>" CRLF
188- "<body bgcolor=\"white\">" CRLF
189- "<center><h1>Successful purge</h1>" CRLF
190- ;
191-
192- static char ngx_http_cache_purge_success_page_tail [] =
193- CRLF "</center>" CRLF
194- "<hr><center>" NGINX_VER "</center>" CRLF
195- "</body>" CRLF
196- "</html>" CRLF
197- ;
198-
199221# if (NGX_HTTP_FASTCGI )
200222extern ngx_module_t ngx_http_fastcgi_module ;
201223
@@ -1095,6 +1117,7 @@ ngx_http_uwsgi_cache_purge_conf(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
10951117 return NGX_CONF_OK ;
10961118}
10971119
1120+
10981121ngx_int_t
10991122ngx_http_uwsgi_cache_purge_handler (ngx_http_request_t * r )
11001123{
@@ -1144,6 +1167,56 @@ ngx_http_uwsgi_cache_purge_handler(ngx_http_request_t *r)
11441167}
11451168# endif /* NGX_HTTP_UWSGI */
11461169
1170+
1171+ char *
1172+ ngx_http_cache_purge_response_type_conf (ngx_conf_t * cf , ngx_command_t * cmd , void * conf )
1173+ {
1174+ ngx_http_cache_purge_loc_conf_t * cplcf ;
1175+ ngx_str_t * value ;
1176+
1177+ cplcf = ngx_http_conf_get_module_loc_conf (cf , ngx_http_cache_purge_module );
1178+
1179+ /* check for duplicates / collisions */
1180+ if (cplcf -> resptype != NGX_CONF_UNSET_UINT && cf -> cmd_type == NGX_HTTP_LOC_CONF ) {
1181+ return "is duplicate" ;
1182+ }
1183+
1184+ /* sanity check */
1185+ if (cf -> args -> nelts < 2 ) {
1186+ return "is invalid paramter, ex) cache_purge_response_type (html|json|xml|text)" ;
1187+ }
1188+
1189+ if (cf -> args -> nelts > 2 ) {
1190+ return "is required only 1 option, ex) cache_purge_response_type (html|json|xml|text)" ;
1191+ }
1192+
1193+ value = cf -> args -> elts ;
1194+
1195+ if (ngx_strcmp (value [1 ].data , "html" ) != 0 && ngx_strcmp (value [1 ].data , "json" ) != 0
1196+ && ngx_strcmp (value [1 ].data , "xml" ) != 0 && ngx_strcmp (value [1 ].data , "text" ) != 0 ) {
1197+ ngx_conf_log_error (NGX_LOG_EMERG , cf , 0 ,
1198+ "invalid parameter \"%V\", expected"
1199+ " \"(html|json|xml|text)\" keyword" , & value [1 ]);
1200+ return NGX_CONF_ERROR ;
1201+ }
1202+
1203+ if (cf -> cmd_type == NGX_HTTP_MODULE ) {
1204+ return "(separate server or location syntax) is not allowed here" ;
1205+ }
1206+
1207+ if (ngx_strcmp (value [1 ].data , "html" ) == 0 ) {
1208+ cplcf -> resptype = NGX_REPONSE_TYPE_HTML ;
1209+ } else if (ngx_strcmp (value [1 ].data , "xml" ) == 0 ) {
1210+ cplcf -> resptype = NGX_REPONSE_TYPE_XML ;
1211+ } else if (ngx_strcmp (value [1 ].data , "json" ) == 0 ) {
1212+ cplcf -> resptype = NGX_REPONSE_TYPE_JSON ;
1213+ } else if (ngx_strcmp (value [1 ].data , "text" ) == 0 ) {
1214+ cplcf -> resptype = NGX_REPONSE_TYPE_TEXT ;
1215+ }
1216+
1217+ return NGX_CONF_OK ;
1218+ }
1219+
11471220ngx_int_t
11481221ngx_http_cache_purge_access_handler (ngx_http_request_t * r )
11491222{
@@ -1256,16 +1329,82 @@ ngx_http_cache_purge_send_response(ngx_http_request_t *r)
12561329 ngx_str_t * key ;
12571330 ngx_int_t rc ;
12581331 size_t len ;
1332+
1333+ size_t body_len ;
1334+ size_t resp_tmpl_len ;
1335+ u_char * buf ;
1336+ u_char * buf_keydata ;
1337+ u_char * p ;
1338+ const char * resp_ct ;
1339+ size_t resp_ct_size ;
1340+ const char * resp_body ;
1341+ size_t resp_body_size ;
1342+
1343+ ngx_http_cache_purge_loc_conf_t * cplcf ;
1344+ cplcf = ngx_http_get_module_loc_conf (r , ngx_http_cache_purge_module );
12591345
12601346 key = r -> cache -> keys .elts ;
12611347
1262- len = sizeof (ngx_http_cache_purge_success_page_top ) - 1
1263- + sizeof (ngx_http_cache_purge_success_page_tail ) - 1
1264- + sizeof ("<br>Key : " ) - 1 + sizeof (CRLF "<br>Path: " ) - 1
1265- + key [0 ].len + r -> cache -> file .name .len ;
1348+ buf_keydata = ngx_pcalloc (r -> pool , key [0 ].len + 1 );
1349+ if (buf_keydata == NULL ) {
1350+ return NGX_HTTP_INTERNAL_SERVER_ERROR ;
1351+ }
1352+
1353+ p = ngx_cpymem (buf_keydata , key [0 ].data , key [0 ].len );
1354+ if (p == NULL ) {
1355+ return NGX_HTTP_INTERNAL_SERVER_ERROR ;
1356+ }
1357+
1358+ switch (cplcf -> resptype ) {
1359+
1360+ case NGX_REPONSE_TYPE_JSON :
1361+ resp_ct = ngx_http_cache_purge_content_type_json ;
1362+ resp_ct_size = ngx_http_cache_purge_content_type_json_size ;
1363+ resp_body = ngx_http_cache_purge_body_templ_json ;
1364+ resp_body_size = ngx_http_cache_purge_body_templ_json_size ;
1365+ break ;
1366+
1367+ case NGX_REPONSE_TYPE_XML :
1368+ resp_ct = ngx_http_cache_purge_content_type_xml ;
1369+ resp_ct_size = ngx_http_cache_purge_content_type_xml_size ;
1370+ resp_body = ngx_http_cache_purge_body_templ_xml ;
1371+ resp_body_size = ngx_http_cache_purge_body_templ_xml_size ;
1372+ break ;
1373+
1374+ case NGX_REPONSE_TYPE_TEXT :
1375+ resp_ct = ngx_http_cache_purge_content_type_text ;
1376+ resp_ct_size = ngx_http_cache_purge_content_type_text_size ;
1377+ resp_body = ngx_http_cache_purge_body_templ_text ;
1378+ resp_body_size = ngx_http_cache_purge_body_templ_text_size ;
1379+ break ;
1380+
1381+ default :
1382+ case NGX_REPONSE_TYPE_HTML :
1383+ resp_ct = ngx_http_cache_purge_content_type_html ;
1384+ resp_ct_size = ngx_http_cache_purge_content_type_html_size ;
1385+ resp_body = ngx_http_cache_purge_body_templ_html ;
1386+ resp_body_size = ngx_http_cache_purge_body_templ_html_size ;
1387+ break ;
1388+ }
1389+
1390+ body_len = resp_body_size - 4 - 1 ;
1391+ r -> headers_out .content_type .len = resp_ct_size - 1 ;
1392+ r -> headers_out .content_type .data = (u_char * ) resp_ct ;
1393+
1394+ resp_tmpl_len = body_len + key [0 ].len + r -> cache -> file .name .len ;
1395+
1396+ buf = ngx_pcalloc (r -> pool , resp_tmpl_len );
1397+ if (buf == NULL ) {
1398+ return NGX_HTTP_INTERNAL_SERVER_ERROR ;
1399+ }
1400+
1401+ p = ngx_snprintf (buf , resp_tmpl_len , resp_body , buf_keydata , r -> cache -> file .name .data );
1402+ if (p == NULL ) {
1403+ return NGX_HTTP_INTERNAL_SERVER_ERROR ;
1404+ }
1405+
1406+ len = body_len + key [0 ].len + r -> cache -> file .name .len ;
12661407
1267- r -> headers_out .content_type .len = sizeof ("text/html" ) - 1 ;
1268- r -> headers_out .content_type .data = (u_char * ) "text/html" ;
12691408 r -> headers_out .status = NGX_HTTP_OK ;
12701409 r -> headers_out .content_length_n = len ;
12711410
@@ -1280,27 +1419,20 @@ ngx_http_cache_purge_send_response(ngx_http_request_t *r)
12801419 if (b == NULL ) {
12811420 return NGX_HTTP_INTERNAL_SERVER_ERROR ;
12821421 }
1422+
12831423
12841424 out .buf = b ;
12851425 out .next = NULL ;
12861426
1287- b -> last = ngx_cpymem (b -> last , ngx_http_cache_purge_success_page_top ,
1288- sizeof (ngx_http_cache_purge_success_page_top ) - 1 );
1289- b -> last = ngx_cpymem (b -> last , "<br>Key : " , sizeof ("<br>Key : " ) - 1 );
1290- b -> last = ngx_cpymem (b -> last , key [0 ].data , key [0 ].len );
1291- b -> last = ngx_cpymem (b -> last , CRLF "<br>Path: " ,
1292- sizeof (CRLF "<br>Path: " ) - 1 );
1293- b -> last = ngx_cpymem (b -> last , r -> cache -> file .name .data ,
1294- r -> cache -> file .name .len );
1295- b -> last = ngx_cpymem (b -> last , ngx_http_cache_purge_success_page_tail ,
1296- sizeof (ngx_http_cache_purge_success_page_tail ) - 1 );
1427+ b -> last = ngx_cpymem (b -> last , buf , resp_tmpl_len );
12971428 b -> last_buf = 1 ;
12981429
12991430 rc = ngx_http_send_header (r );
13001431 if (rc == NGX_ERROR || rc > NGX_OK || r -> header_only ) {
1301- return rc ;
1432+ return rc ;
13021433 }
13031434
1435+
13041436 return ngx_http_output_filter (r , & out );
13051437}
13061438
@@ -1615,7 +1747,6 @@ ngx_http_cache_purge_merge_conf(ngx_http_cache_purge_conf_t *conf,
16151747 conf -> method = prev -> method ;
16161748 conf -> access = prev -> access ;
16171749 conf -> access6 = prev -> access6 ;
1618-
16191750 } else {
16201751 conf -> enable = 0 ;
16211752 }
@@ -1655,6 +1786,8 @@ ngx_http_cache_purge_create_loc_conf(ngx_conf_t *cf)
16551786 conf -> uwsgi .enable = NGX_CONF_UNSET ;
16561787# endif /* NGX_HTTP_UWSGI */
16571788
1789+ conf -> resptype = NGX_CONF_UNSET_UINT ;
1790+
16581791 conf -> conf = NGX_CONF_UNSET_PTR ;
16591792
16601793 return conf ;
@@ -1681,6 +1814,8 @@ ngx_http_cache_purge_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
16811814
16821815 clcf = ngx_http_conf_get_module_loc_conf (cf , ngx_http_core_module );
16831816
1817+ ngx_conf_merge_uint_value (conf -> resptype , prev -> resptype , NGX_REPONSE_TYPE_HTML );
1818+
16841819# if (NGX_HTTP_FASTCGI )
16851820 ngx_http_cache_purge_merge_conf (& conf -> fastcgi , & prev -> fastcgi );
16861821
0 commit comments