Mercurial > hg > nginx
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 } |