37
37
#error This module cannot be build against an unknown nginx version.
38
38
#endif
39
39
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 );
40
64
41
65
#if (NGX_HTTP_CACHE )
42
66
@@ -65,6 +89,8 @@ typedef struct {
65
89
ngx_http_cache_purge_conf_t * conf ;
66
90
ngx_http_handler_pt handler ;
67
91
ngx_http_handler_pt original_handler ;
92
+
93
+ ngx_uint_t resptype ; /* response content-type */
68
94
} ngx_http_cache_purge_loc_conf_t ;
69
95
70
96
# if (NGX_HTTP_FASTCGI )
@@ -91,6 +117,8 @@ char *ngx_http_uwsgi_cache_purge_conf(ngx_conf_t *cf,
91
117
ngx_int_t ngx_http_uwsgi_cache_purge_handler (ngx_http_request_t * r );
92
118
# endif /* NGX_HTTP_UWSGI */
93
119
120
+ char * ngx_http_cache_purge_response_type_conf (ngx_conf_t * cf ,
121
+ ngx_command_t * cmd , void * conf );
94
122
static ngx_int_t
95
123
ngx_http_purge_file_cache_noop (ngx_tree_ctx_t * ctx , ngx_str_t * path );
96
124
static ngx_int_t
@@ -169,6 +197,14 @@ static ngx_command_t ngx_http_cache_purge_module_commands[] = {
169
197
},
170
198
# endif /* NGX_HTTP_UWSGI */
171
199
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
+
172
208
ngx_null_command
173
209
};
174
210
@@ -201,20 +237,6 @@ ngx_module_t ngx_http_cache_purge_module = {
201
237
NGX_MODULE_V1_PADDING
202
238
};
203
239
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
-
218
240
# if (NGX_HTTP_FASTCGI )
219
241
extern ngx_module_t ngx_http_fastcgi_module ;
220
242
@@ -1153,6 +1175,7 @@ ngx_http_uwsgi_cache_purge_conf(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
1153
1175
return NGX_CONF_OK ;
1154
1176
}
1155
1177
1178
+
1156
1179
ngx_int_t
1157
1180
ngx_http_uwsgi_cache_purge_handler (ngx_http_request_t * r ) {
1158
1181
ngx_http_file_cache_t * cache ;
@@ -1216,6 +1239,55 @@ ngx_http_uwsgi_cache_purge_handler(ngx_http_request_t *r) {
1216
1239
# endif /* NGX_HTTP_UWSGI */
1217
1240
1218
1241
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
+
1219
1291
static ngx_int_t
1220
1292
ngx_http_purge_file_cache_noop (ngx_tree_ctx_t * ctx , ngx_str_t * path ) {
1221
1293
return NGX_OK ;
@@ -1397,16 +1469,82 @@ ngx_http_cache_purge_send_response(ngx_http_request_t *r) {
1397
1469
ngx_str_t * key ;
1398
1470
ngx_int_t rc ;
1399
1471
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 );
1400
1485
1401
1486
key = r -> cache -> keys .elts ;
1402
1487
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 ;
1407
1547
1408
- r -> headers_out .content_type .len = sizeof ("text/html" ) - 1 ;
1409
- r -> headers_out .content_type .data = (u_char * ) "text/html" ;
1410
1548
r -> headers_out .status = NGX_HTTP_OK ;
1411
1549
r -> headers_out .content_length_n = len ;
1412
1550
@@ -1421,27 +1559,20 @@ ngx_http_cache_purge_send_response(ngx_http_request_t *r) {
1421
1559
if (b == NULL ) {
1422
1560
return NGX_HTTP_INTERNAL_SERVER_ERROR ;
1423
1561
}
1562
+
1424
1563
1425
1564
out .buf = b ;
1426
1565
out .next = NULL ;
1427
1566
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 );
1438
1568
b -> last_buf = 1 ;
1439
1569
1440
1570
rc = ngx_http_send_header (r );
1441
1571
if (rc == NGX_ERROR || rc > NGX_OK || r -> header_only ) {
1442
1572
return rc ;
1443
1573
}
1444
1574
1575
+
1445
1576
return ngx_http_output_filter (r , & out );
1446
1577
}
1447
1578
@@ -1831,7 +1962,6 @@ ngx_http_cache_purge_merge_conf(ngx_http_cache_purge_conf_t *conf,
1831
1962
conf -> purge_all = prev -> purge_all ;
1832
1963
conf -> access = prev -> access ;
1833
1964
conf -> access6 = prev -> access6 ;
1834
-
1835
1965
} else {
1836
1966
conf -> enable = 0 ;
1837
1967
}
@@ -1870,6 +2000,8 @@ ngx_http_cache_purge_create_loc_conf(ngx_conf_t *cf) {
1870
2000
conf -> uwsgi .enable = NGX_CONF_UNSET ;
1871
2001
# endif /* NGX_HTTP_UWSGI */
1872
2002
2003
+ conf -> resptype = NGX_CONF_UNSET_UINT ;
2004
+
1873
2005
conf -> conf = NGX_CONF_UNSET_PTR ;
1874
2006
1875
2007
return conf ;
@@ -1895,6 +2027,8 @@ ngx_http_cache_purge_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child) {
1895
2027
1896
2028
clcf = ngx_http_conf_get_module_loc_conf (cf , ngx_http_core_module );
1897
2029
2030
+ ngx_conf_merge_uint_value (conf -> resptype , prev -> resptype , NGX_REPONSE_TYPE_HTML );
2031
+
1898
2032
# if (NGX_HTTP_FASTCGI )
1899
2033
ngx_http_cache_purge_merge_conf (& conf -> fastcgi , & prev -> fastcgi );
1900
2034
0 commit comments