comparison src/http/modules/ngx_http_headers_filter_module.c @ 5817:74ffe03555d0

Headers filter: "add_header" with "always" parameter (ticket #98). If specified, the header field is set regardless of the status code.
author Sergey Kandaurov <pluknet@nginx.com>
date Fri, 29 Aug 2014 18:00:10 +0400
parents 7ed23dcfea3d
children 36e61455a8f4
comparison
equal deleted inserted replaced
5816:16a371063d20 5817:74ffe03555d0
26 struct ngx_http_header_val_s { 26 struct ngx_http_header_val_s {
27 ngx_http_complex_value_t value; 27 ngx_http_complex_value_t value;
28 ngx_str_t key; 28 ngx_str_t key;
29 ngx_http_set_header_pt handler; 29 ngx_http_set_header_pt handler;
30 ngx_uint_t offset; 30 ngx_uint_t offset;
31 ngx_uint_t always; /* unsigned always:1 */
31 }; 32 };
32 33
33 34
34 typedef enum { 35 typedef enum {
35 NGX_HTTP_EXPIRES_OFF, 36 NGX_HTTP_EXPIRES_OFF,
96 0, 97 0,
97 NULL}, 98 NULL},
98 99
99 { ngx_string("add_header"), 100 { ngx_string("add_header"),
100 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF 101 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF
101 |NGX_CONF_TAKE2, 102 |NGX_CONF_TAKE23,
102 ngx_http_headers_add, 103 ngx_http_headers_add,
103 NGX_HTTP_LOC_CONF_OFFSET, 104 NGX_HTTP_LOC_CONF_OFFSET,
104 0, 105 0,
105 NULL}, 106 NULL},
106 107
144 145
145 static ngx_int_t 146 static ngx_int_t
146 ngx_http_headers_filter(ngx_http_request_t *r) 147 ngx_http_headers_filter(ngx_http_request_t *r)
147 { 148 {
148 ngx_str_t value; 149 ngx_str_t value;
149 ngx_uint_t i; 150 ngx_uint_t i, safe_status;
150 ngx_http_header_val_t *h; 151 ngx_http_header_val_t *h;
151 ngx_http_headers_conf_t *conf; 152 ngx_http_headers_conf_t *conf;
152 153
153 conf = ngx_http_get_module_loc_conf(r, ngx_http_headers_filter_module); 154 conf = ngx_http_get_module_loc_conf(r, ngx_http_headers_filter_module);
154 155
155 if ((conf->expires == NGX_HTTP_EXPIRES_OFF && conf->headers == NULL) 156 if ((conf->expires == NGX_HTTP_EXPIRES_OFF && conf->headers == NULL)
156 || r != r->main 157 || r != r->main)
157 || (r->headers_out.status != NGX_HTTP_OK
158 && r->headers_out.status != NGX_HTTP_CREATED
159 && r->headers_out.status != NGX_HTTP_NO_CONTENT
160 && r->headers_out.status != NGX_HTTP_PARTIAL_CONTENT
161 && r->headers_out.status != NGX_HTTP_MOVED_PERMANENTLY
162 && r->headers_out.status != NGX_HTTP_MOVED_TEMPORARILY
163 && r->headers_out.status != NGX_HTTP_SEE_OTHER
164 && r->headers_out.status != NGX_HTTP_NOT_MODIFIED
165 && r->headers_out.status != NGX_HTTP_TEMPORARY_REDIRECT))
166 { 158 {
167 return ngx_http_next_header_filter(r); 159 return ngx_http_next_header_filter(r);
168 } 160 }
169 161
170 if (conf->expires != NGX_HTTP_EXPIRES_OFF) { 162 switch (r->headers_out.status) {
163
164 case NGX_HTTP_OK:
165 case NGX_HTTP_CREATED:
166 case NGX_HTTP_NO_CONTENT:
167 case NGX_HTTP_PARTIAL_CONTENT:
168 case NGX_HTTP_MOVED_PERMANENTLY:
169 case NGX_HTTP_MOVED_TEMPORARILY:
170 case NGX_HTTP_SEE_OTHER:
171 case NGX_HTTP_NOT_MODIFIED:
172 case NGX_HTTP_TEMPORARY_REDIRECT:
173 safe_status = 1;
174 break;
175
176 default:
177 safe_status = 0;
178 break;
179 }
180
181 if (conf->expires != NGX_HTTP_EXPIRES_OFF && safe_status) {
171 if (ngx_http_set_expires(r, conf) != NGX_OK) { 182 if (ngx_http_set_expires(r, conf) != NGX_OK) {
172 return NGX_ERROR; 183 return NGX_ERROR;
173 } 184 }
174 } 185 }
175 186
176 if (conf->headers) { 187 if (conf->headers) {
177 h = conf->headers->elts; 188 h = conf->headers->elts;
178 for (i = 0; i < conf->headers->nelts; i++) { 189 for (i = 0; i < conf->headers->nelts; i++) {
190
191 if (!safe_status && !h[i].always) {
192 continue;
193 }
179 194
180 if (ngx_http_complex_value(r, &h[i].value, &value) != NGX_OK) { 195 if (ngx_http_complex_value(r, &h[i].value, &value) != NGX_OK) {
181 return NGX_ERROR; 196 return NGX_ERROR;
182 } 197 }
183 198
601 } 616 }
602 617
603 hv->key = value[1]; 618 hv->key = value[1];
604 hv->handler = ngx_http_add_header; 619 hv->handler = ngx_http_add_header;
605 hv->offset = 0; 620 hv->offset = 0;
621 hv->always = 0;
606 622
607 set = ngx_http_set_headers; 623 set = ngx_http_set_headers;
608 for (i = 0; set[i].name.len; i++) { 624 for (i = 0; set[i].name.len; i++) {
609 if (ngx_strcasecmp(value[1].data, set[i].name.data) != 0) { 625 if (ngx_strcasecmp(value[1].data, set[i].name.data) != 0) {
610 continue; 626 continue;
629 645
630 if (ngx_http_compile_complex_value(&ccv) != NGX_OK) { 646 if (ngx_http_compile_complex_value(&ccv) != NGX_OK) {
631 return NGX_CONF_ERROR; 647 return NGX_CONF_ERROR;
632 } 648 }
633 649
650 if (cf->args->nelts == 3) {
651 return NGX_CONF_OK;
652 }
653
654 if (ngx_strcmp(value[3].data, "always") != 0) {
655 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
656 "invalid parameter \"%V\"", &value[3]);
657 return NGX_CONF_ERROR;
658 }
659
660 hv->always = 1;
661
634 return NGX_CONF_OK; 662 return NGX_CONF_OK;
635 } 663 }