comparison src/http/modules/ngx_http_headers_filter_module.c @ 573:58475592100c release-0.3.8

nginx-0.3.8-RELEASE import *) Security: nginx now checks URI got from a backend in "X-Accel-Redirect" header line or in SSI file for the "/../" paths and zeroes. *) Change: nginx now does not treat the empty user name in the "Authorization" header line as valid one. *) Feature: the "ssl_session_timeout" directives of the ngx_http_ssl_module and ngx_imap_ssl_module. *) Feature: the "auth_http_header" directive of the ngx_imap_auth_http_module. *) Feature: the "add_header" directive. *) Feature: the ngx_http_realip_module. *) Feature: the new variables to use in the "log_format" directive: $bytes_sent, $apache_bytes_sent, $status, $time_gmt, $uri, $request_time, $request_length, $upstream_status, $upstream_response_time, $gzip_ratio, $uid_got, $uid_set, $connection, $pipe, and $msec. The parameters in the "%name" form will be canceled soon. *) Change: now the false variable values in the "if" directive are the empty string "" and string starting with "0". *) Bugfix: while using proxied or FastCGI-server nginx may leave connections and temporary files with client requests in open state. *) Bugfix: the worker processes did not flush the buffered logs on graceful exit. *) Bugfix: if the request URI was changes by the "rewrite" directive and the request was proxied in location given by regular expression, then the incorrect request was transferred to backend; the bug had appeared in 0.2.6. *) Bugfix: the "expires" directive did not remove the previous "Expires" header. *) Bugfix: nginx may stop to accept requests if the "rtsig" method and several worker processes were used. *) Bugfix: the "\"" and "\'" escape symbols were incorrectly handled in SSI commands. *) Bugfix: if the response was ended just after the SSI command and gzipping was used, then the response did not transferred complete or did not transferred at all.
author Igor Sysoev <igor@sysoev.ru>
date Wed, 09 Nov 2005 17:25:55 +0000
parents 45033d85b30e
children 4d9ea73a627a
comparison
equal deleted inserted replaced
572:ae8920455206 573:58475592100c
8 #include <ngx_core.h> 8 #include <ngx_core.h>
9 #include <ngx_http.h> 9 #include <ngx_http.h>
10 10
11 11
12 typedef struct { 12 typedef struct {
13 time_t expires; 13 time_t expires;
14 ngx_str_t cache_control;
15 ngx_array_t *headers;
14 } ngx_http_headers_conf_t; 16 } ngx_http_headers_conf_t;
15 17
16 18
17 #define NGX_HTTP_EXPIRES_UNSET -2147483647 19 #define NGX_HTTP_EXPIRES_UNSET -2147483647
18 #define NGX_HTTP_EXPIRES_OFF -2147483646 20 #define NGX_HTTP_EXPIRES_OFF -2147483646
20 22
21 23
22 static ngx_int_t ngx_http_headers_filter_init(ngx_cycle_t *cycle); 24 static ngx_int_t ngx_http_headers_filter_init(ngx_cycle_t *cycle);
23 static void *ngx_http_headers_create_conf(ngx_conf_t *cf); 25 static void *ngx_http_headers_create_conf(ngx_conf_t *cf);
24 static char *ngx_http_headers_merge_conf(ngx_conf_t *cf, 26 static char *ngx_http_headers_merge_conf(ngx_conf_t *cf,
25 void *parent, void *child); 27 void *parent, void *child);
26 static char *ngx_http_headers_expires(ngx_conf_t *cf, ngx_command_t *cmd, 28 static char *ngx_http_headers_expires(ngx_conf_t *cf, ngx_command_t *cmd,
27 void *conf); 29 void *conf);
30 static char *ngx_http_headers_add(ngx_conf_t *cf, ngx_command_t *cmd,
31 void *conf);
28 32
29 33
30 static ngx_command_t ngx_http_headers_filter_commands[] = { 34 static ngx_command_t ngx_http_headers_filter_commands[] = {
31 35
32 { ngx_string("expires"), 36 { ngx_string("expires"),
33 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, 37 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF
38 |NGX_CONF_TAKE1,
34 ngx_http_headers_expires, 39 ngx_http_headers_expires,
40 NGX_HTTP_LOC_CONF_OFFSET,
41 0,
42 NULL},
43
44 { ngx_string("add_header"),
45 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF
46 |NGX_CONF_TAKE2,
47 ngx_http_headers_add,
35 NGX_HTTP_LOC_CONF_OFFSET, 48 NGX_HTTP_LOC_CONF_OFFSET,
36 0, 49 0,
37 NULL}, 50 NULL},
38 51
39 ngx_null_command 52 ngx_null_command
77 static ngx_int_t 90 static ngx_int_t
78 ngx_http_headers_filter(ngx_http_request_t *r) 91 ngx_http_headers_filter(ngx_http_request_t *r)
79 { 92 {
80 size_t len; 93 size_t len;
81 ngx_uint_t i; 94 ngx_uint_t i;
82 ngx_table_elt_t *expires, *cc, **ccp; 95 ngx_table_elt_t *expires, *cc, **ccp, *h, *out;
83 ngx_http_headers_conf_t *conf; 96 ngx_http_headers_conf_t *conf;
84 97
85 if ((r->headers_out.status != NGX_HTTP_OK 98 if ((r->headers_out.status != NGX_HTTP_OK
86 && r->headers_out.status != NGX_HTTP_NOT_MODIFIED) 99 && r->headers_out.status != NGX_HTTP_NOT_MODIFIED)
87 || r->main != r) 100 || r->main != r)
115 ccp = r->headers_out.cache_control.elts; 128 ccp = r->headers_out.cache_control.elts;
116 129
117 if (ccp == NULL) { 130 if (ccp == NULL) {
118 131
119 if (ngx_array_init(&r->headers_out.cache_control, r->pool, 132 if (ngx_array_init(&r->headers_out.cache_control, r->pool,
120 1, sizeof(ngx_table_elt_t *)) != NGX_OK) 133 1, sizeof(ngx_table_elt_t *))
134 != NGX_OK)
121 { 135 {
122 return NGX_ERROR; 136 return NGX_ERROR;
123 } 137 }
124 138
125 ccp = ngx_array_push(&r->headers_out.cache_control); 139 ccp = ngx_array_push(&r->headers_out.cache_control);
186 } 200 }
187 } 201 }
188 } 202 }
189 } 203 }
190 204
205 if (conf->cache_control.len) {
206
207 ccp = r->headers_out.cache_control.elts;
208
209 if (ccp == NULL) {
210
211 if (ngx_array_init(&r->headers_out.cache_control, r->pool,
212 1, sizeof(ngx_table_elt_t *))
213 != NGX_OK)
214 {
215 return NGX_ERROR;
216 }
217 }
218
219 ccp = ngx_array_push(&r->headers_out.cache_control);
220 if (ccp == NULL) {
221 return NGX_ERROR;
222 }
223
224 cc = ngx_list_push(&r->headers_out.headers);
225 if (cc == NULL) {
226 return NGX_ERROR;
227 }
228
229 cc->hash = 1;
230 cc->key.len = sizeof("Cache-Control") - 1;
231 cc->key.data = (u_char *) "Cache-Control";
232 cc->value = conf->cache_control;
233
234 *ccp = cc;
235 }
236
237 if (conf->headers) {
238 h = conf->headers->elts;
239 for (i = 0; i < conf->headers->nelts; i++) {
240 out = ngx_list_push(&r->headers_out.headers);
241 if (out == NULL) {
242 return NGX_ERROR;
243 }
244
245 *out = h[i];
246 }
247 }
248
191 return ngx_http_next_header_filter(r); 249 return ngx_http_next_header_filter(r);
192 } 250 }
193 251
194 252
195 static ngx_int_t 253 static ngx_int_t
205 static void * 263 static void *
206 ngx_http_headers_create_conf(ngx_conf_t *cf) 264 ngx_http_headers_create_conf(ngx_conf_t *cf)
207 { 265 {
208 ngx_http_headers_conf_t *conf; 266 ngx_http_headers_conf_t *conf;
209 267
210 conf = ngx_palloc(cf->pool, sizeof(ngx_http_headers_conf_t)); 268 conf = ngx_pcalloc(cf->pool, sizeof(ngx_http_headers_conf_t));
211 if (conf == NULL) { 269 if (conf == NULL) {
212 return NGX_CONF_ERROR; 270 return NGX_CONF_ERROR;
213 } 271 }
272
273 /*
274 * set by ngx_pcalloc():
275 *
276 * conf->cache_control.len = 0;
277 * conf->cache_control.data = NULL;
278 * conf->headers = NULL;
279 */
214 280
215 conf->expires = NGX_HTTP_EXPIRES_UNSET; 281 conf->expires = NGX_HTTP_EXPIRES_UNSET;
216 282
217 return conf; 283 return conf;
218 } 284 }
225 ngx_http_headers_conf_t *conf = child; 291 ngx_http_headers_conf_t *conf = child;
226 292
227 if (conf->expires == NGX_HTTP_EXPIRES_UNSET) { 293 if (conf->expires == NGX_HTTP_EXPIRES_UNSET) {
228 conf->expires = (prev->expires == NGX_HTTP_EXPIRES_UNSET) ? 294 conf->expires = (prev->expires == NGX_HTTP_EXPIRES_UNSET) ?
229 NGX_HTTP_EXPIRES_OFF : prev->expires; 295 NGX_HTTP_EXPIRES_OFF : prev->expires;
296 }
297
298 if (conf->cache_control.data == NULL) {
299 conf->cache_control = prev->cache_control;
300 }
301
302 if (conf->headers == NULL) {
303 conf->headers = prev->headers;
230 } 304 }
231 305
232 return NGX_CONF_OK; 306 return NGX_CONF_OK;
233 } 307 }
234 308
285 hcf->expires = - hcf->expires; 359 hcf->expires = - hcf->expires;
286 } 360 }
287 361
288 return NGX_CONF_OK; 362 return NGX_CONF_OK;
289 } 363 }
364
365
366 static char *
367 ngx_http_headers_add(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
368 {
369 ngx_http_headers_conf_t *hcf = conf;
370
371 ngx_str_t *value;
372 ngx_table_elt_t *h;
373
374 value = cf->args->elts;
375
376 if (ngx_strcasecmp(value[1].data, "cache-control") == 0) {
377 hcf->cache_control = value[2];
378 return NGX_CONF_OK;
379 }
380
381 if (hcf->headers == NULL) {
382 hcf->headers = ngx_array_create(cf->pool, 1, sizeof(ngx_table_elt_t));
383 if (hcf->headers == NULL) {
384 return NGX_CONF_ERROR;
385 }
386 }
387
388 h = ngx_array_push(hcf->headers);
389 if (h == NULL) {
390 return NGX_CONF_ERROR;
391 }
392
393 h->hash = 1;
394 h->key = value[1];
395 h->value = value[2];
396
397 return NGX_CONF_OK;
398 }