Mercurial > hg > nginx-quic
comparison src/http/ngx_http_header_filter_module.c @ 509:9b8c906f6e63 release-0.1.29
nginx-0.1.29-RELEASE import
*) Feature: the ngx_http_ssi_module supports "include virtual" command.
*) Feature: the ngx_http_ssi_module supports the condition command like
'if expr="$NAME"' and "else" and "endif" commands. Only one nested
level is supported.
*) Feature: the ngx_http_ssi_module supports the DATE_LOCAL and
DATE_GMT variables and "config timefmt" command.
*) Feature: the "ssi_ignore_recycled_buffers" directive.
*) Bugfix: the "echo" command did not show the default value for the
empty QUERY_STRING variable.
*) Change: the ngx_http_proxy_module was rewritten.
*) Feature: the "proxy_redirect", "proxy_pass_request_headers",
"proxy_pass_request_body", and "proxy_method" directives.
*) Feature: the "proxy_set_header" directive. The "proxy_x_var" was
canceled and must be replaced with the proxy_set_header directive.
*) Change: the "proxy_preserve_host" is canceled and must be replaced
with the "proxy_set_header Host $host" and the "proxy_redirect off"
directives, the "proxy_set_header Host $host:$proxy_port" directive
and the appropriate proxy_redirect directives.
*) Change: the "proxy_set_x_real_ip" is canceled and must be replaced
with the "proxy_set_header X-Real-IP $remote_addr" directive.
*) Change: the "proxy_add_x_forwarded_for" is canceled and must be
replaced with
the "proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for"
directive.
*) Change: the "proxy_set_x_url" is canceled and must be replaced with
the "proxy_set_header X-URL http://$host:$server_port$request_uri"
directive.
*) Feature: the "fastcgi_param" directive.
*) Change: the "fastcgi_root", "fastcgi_set_var" and "fastcgi_params"
directive are canceled and must be replaced with the fastcgi_param
directives.
*) Feature: the "index" directive can use the variables.
*) Feature: the "index" directive can be used at http and server levels.
*) Change: the last index only in the "index" directive can be absolute.
*) Feature: the "rewrite" directive can use the variables.
*) Feature: the "internal" directive.
*) Feature: the CONTENT_LENGTH, CONTENT_TYPE, REMOTE_PORT, SERVER_ADDR,
SERVER_PORT, SERVER_PROTOCOL, DOCUMENT_ROOT, SERVER_NAME,
REQUEST_METHOD, REQUEST_URI, and REMOTE_USER variables.
*) Change: nginx now passes the invalid lines in a client request
headers or a backend response header.
*) Bugfix: if the backend did not transfer response for a long time and
the "send_timeout" was less than "proxy_read_timeout", then nginx
returned the 408 response.
*) Bugfix: the segmentation fault was occurred if the backend sent an
invalid line in response header; the bug had appeared in 0.1.26.
*) Bugfix: the segmentation fault may occurred in FastCGI fault
tolerance configuration.
*) Bugfix: the "expires" directive did not remove the previous
"Expires" and "Cache-Control" headers.
*) Bugfix: nginx did not take into account trailing dot in "Host"
header line.
*) Bugfix: the ngx_http_auth_module did not work under Linux.
*) Bugfix: the rewrite directive worked incorrectly, if the arguments
were in a request.
*) Bugfix: nginx could not be built on MacOS X.
author | Igor Sysoev <igor@sysoev.ru> |
---|---|
date | Thu, 12 May 2005 14:58:06 +0000 |
parents | d4ea69372b94 |
children | c12967aadd87 |
comparison
equal
deleted
inserted
replaced
508:ca1020ce99ba | 509:9b8c906f6e63 |
---|---|
13 static ngx_int_t ngx_http_header_filter_init(ngx_cycle_t *cycle); | 13 static ngx_int_t ngx_http_header_filter_init(ngx_cycle_t *cycle); |
14 static ngx_int_t ngx_http_header_filter(ngx_http_request_t *r); | 14 static ngx_int_t ngx_http_header_filter(ngx_http_request_t *r); |
15 | 15 |
16 | 16 |
17 static ngx_http_module_t ngx_http_header_filter_module_ctx = { | 17 static ngx_http_module_t ngx_http_header_filter_module_ctx = { |
18 NULL, /* pre conf */ | 18 NULL, /* preconfiguration */ |
19 NULL, /* postconfiguration */ | |
19 | 20 |
20 NULL, /* create main configuration */ | 21 NULL, /* create main configuration */ |
21 NULL, /* init main configuration */ | 22 NULL, /* init main configuration */ |
22 | 23 |
23 NULL, /* create server configuration */ | 24 NULL, /* create server configuration */ |
27 NULL, /* merge location configuration */ | 28 NULL, /* merge location configuration */ |
28 }; | 29 }; |
29 | 30 |
30 | 31 |
31 ngx_module_t ngx_http_header_filter_module = { | 32 ngx_module_t ngx_http_header_filter_module = { |
32 NGX_MODULE, | 33 NGX_MODULE_V1, |
33 &ngx_http_header_filter_module_ctx, /* module context */ | 34 &ngx_http_header_filter_module_ctx, /* module context */ |
34 NULL, /* module directives */ | 35 NULL, /* module directives */ |
35 NGX_HTTP_MODULE, /* module type */ | 36 NGX_HTTP_MODULE, /* module type */ |
36 ngx_http_header_filter_init, /* init module */ | 37 ngx_http_header_filter_init, /* init module */ |
37 NULL /* init process */ | 38 NULL /* init process */ |
38 }; | 39 }; |
39 | 40 |
40 | 41 |
41 static char server_string[] = "Server: " NGINX_VER CRLF; | 42 static char ngx_http_server_string[] = "Server: " NGINX_VER CRLF; |
42 | 43 |
43 | 44 |
44 static ngx_str_t http_codes[] = { | 45 static ngx_str_t ngx_http_status_lines[] = { |
45 | 46 |
46 ngx_string("200 OK"), | 47 ngx_string("200 OK"), |
47 ngx_null_string, /* "201 Created" */ | 48 ngx_null_string, /* "201 Created" */ |
48 ngx_null_string, /* "202 Accepted" */ | 49 ngx_null_string, /* "202 Accepted" */ |
49 ngx_null_string, /* "203 Non-Authoritative Information" */ | 50 ngx_null_string, /* "203 Non-Authoritative Information" */ |
113 /* ngx_null_string, */ /* "509 unused" */ | 114 /* ngx_null_string, */ /* "509 unused" */ |
114 /* ngx_null_string, */ /* "510 Not Extended" */ | 115 /* ngx_null_string, */ /* "510 Not Extended" */ |
115 }; | 116 }; |
116 | 117 |
117 | 118 |
118 ngx_http_header_t ngx_http_headers_out[] = { | 119 ngx_http_header0_t ngx_http_headers_out[] = { |
119 { ngx_string("Server"), offsetof(ngx_http_headers_out_t, server) }, | 120 { ngx_string("Server"), offsetof(ngx_http_headers_out_t, server) }, |
120 { ngx_string("Date"), offsetof(ngx_http_headers_out_t, date) }, | 121 { ngx_string("Date"), offsetof(ngx_http_headers_out_t, date) }, |
122 #if 0 | |
121 { ngx_string("Content-Type"), | 123 { ngx_string("Content-Type"), |
122 offsetof(ngx_http_headers_out_t, content_type) }, | 124 offsetof(ngx_http_headers_out_t, content_type) }, |
125 #endif | |
123 { ngx_string("Content-Length"), | 126 { ngx_string("Content-Length"), |
124 offsetof(ngx_http_headers_out_t, content_length) }, | 127 offsetof(ngx_http_headers_out_t, content_length) }, |
125 { ngx_string("Content-Encoding"), | 128 { ngx_string("Content-Encoding"), |
126 offsetof(ngx_http_headers_out_t, content_encoding) }, | 129 offsetof(ngx_http_headers_out_t, content_encoding) }, |
127 { ngx_string("Location"), offsetof(ngx_http_headers_out_t, location) }, | 130 { ngx_string("Location"), offsetof(ngx_http_headers_out_t, location) }, |
148 ngx_chain_t out; | 151 ngx_chain_t out; |
149 ngx_list_part_t *part; | 152 ngx_list_part_t *part; |
150 ngx_table_elt_t *header; | 153 ngx_table_elt_t *header; |
151 ngx_http_core_loc_conf_t *clcf; | 154 ngx_http_core_loc_conf_t *clcf; |
152 | 155 |
156 if (r->main) { | |
157 return NGX_OK; | |
158 } | |
159 | |
153 if (r->http_version < NGX_HTTP_VERSION_10) { | 160 if (r->http_version < NGX_HTTP_VERSION_10) { |
154 return NGX_OK; | 161 return NGX_OK; |
155 } | 162 } |
156 | 163 |
157 if (r->method == NGX_HTTP_HEAD) { | 164 if (r->method == NGX_HTTP_HEAD) { |
207 + NGX_HTTP_LEVEL_200 | 214 + NGX_HTTP_LEVEL_200 |
208 + NGX_HTTP_LEVEL_300 | 215 + NGX_HTTP_LEVEL_300 |
209 + NGX_HTTP_LEVEL_400; | 216 + NGX_HTTP_LEVEL_400; |
210 } | 217 } |
211 | 218 |
212 len += http_codes[status].len; | 219 len += ngx_http_status_lines[status].len; |
213 } | 220 } |
214 | 221 |
215 if (r->headers_out.server && r->headers_out.server->key.len) { | 222 if (r->headers_out.server == NULL) { |
216 len += r->headers_out.server->key.len | 223 len += sizeof(ngx_http_server_string) - 1; |
217 + r->headers_out.server->value.len + 2; | 224 } |
218 } else { | 225 |
219 len += sizeof(server_string) - 1; | 226 if (r->headers_out.date == NULL) { |
220 } | |
221 | |
222 if (r->headers_out.date && r->headers_out.date->key.len) { | |
223 len += r->headers_out.date->key.len | |
224 + r->headers_out.date->value.len + 2; | |
225 } else { | |
226 len += sizeof("Date: Mon, 28 Sep 1970 06:00:00 GMT" CRLF) - 1; | 227 len += sizeof("Date: Mon, 28 Sep 1970 06:00:00 GMT" CRLF) - 1; |
227 } | 228 } |
228 | 229 |
229 if (r->headers_out.content_length == NULL) { | 230 if (r->headers_out.content_type.len) { |
230 if (r->headers_out.content_length_n >= 0) { | |
231 len += sizeof("Content-Length: ") - 1 + NGX_OFF_T_LEN + 2; | |
232 } | |
233 } | |
234 | |
235 if (r->headers_out.content_type && r->headers_out.content_type->value.len) { | |
236 r->headers_out.content_type->key.len = 0; | |
237 len += sizeof("Content-Type: ") - 1 | 231 len += sizeof("Content-Type: ") - 1 |
238 + r->headers_out.content_type->value.len + 2; | 232 + r->headers_out.content_type.len + 2; |
239 | 233 |
240 if (r->headers_out.charset.len) { | 234 if (r->headers_out.charset.len) { |
241 len += sizeof("; charset=") - 1 + r->headers_out.charset.len; | 235 len += sizeof("; charset=") - 1 + r->headers_out.charset.len; |
242 } | 236 } |
237 } | |
238 | |
239 if (r->headers_out.content_length == NULL | |
240 && r->headers_out.content_length_n >= 0) | |
241 { | |
242 len += sizeof("Content-Length: ") - 1 + NGX_OFF_T_LEN + 2; | |
243 } | |
244 | |
245 if (r->headers_out.last_modified == NULL | |
246 && r->headers_out.last_modified_time != -1) | |
247 { | |
248 len += sizeof("Last-Modified: Mon, 28 Sep 1970 06:00:00 GMT" CRLF) - 1; | |
243 } | 249 } |
244 | 250 |
245 if (r->headers_out.location | 251 if (r->headers_out.location |
246 && r->headers_out.location->value.len | 252 && r->headers_out.location->value.len |
247 && r->headers_out.location->value.data[0] == '/') | 253 && r->headers_out.location->value.data[0] == '/') |
248 { | 254 { |
249 r->headers_out.location->key.len = 0; | 255 r->headers_out.location->hash = 0; |
256 | |
250 len += sizeof("Location: http://") - 1 | 257 len += sizeof("Location: http://") - 1 |
251 + r->server_name.len + r->headers_out.location->value.len + 2; | 258 + r->server_name.len + r->headers_out.location->value.len + 2; |
252 | 259 |
253 if (r->port != 80) { | 260 if (r->port != 80) { |
254 len += r->port_text->len; | 261 len += r->port_text->len; |
255 } | 262 } |
256 } | |
257 | |
258 if (r->headers_out.last_modified && r->headers_out.last_modified->key.len) { | |
259 len += r->headers_out.last_modified->key.len | |
260 + r->headers_out.last_modified->value.len + 2; | |
261 | |
262 } else if (r->headers_out.last_modified_time != -1) { | |
263 len += sizeof("Last-Modified: Mon, 28 Sep 1970 06:00:00 GMT" CRLF) - 1; | |
264 } | 263 } |
265 | 264 |
266 if (r->chunked) { | 265 if (r->chunked) { |
267 len += sizeof("Transfer-Encoding: chunked" CRLF) - 1; | 266 len += sizeof("Transfer-Encoding: chunked" CRLF) - 1; |
268 } | 267 } |
301 part = part->next; | 300 part = part->next; |
302 header = part->elts; | 301 header = part->elts; |
303 i = 0; | 302 i = 0; |
304 } | 303 } |
305 | 304 |
306 if (header[i].key.len == 0) { | 305 if (header[i].hash == 0) { |
307 continue; | 306 continue; |
308 } | 307 } |
309 | 308 |
310 len += header[i].key.len + sizeof(": ") - 1 + header[i].value.len | 309 len += header[i].key.len + sizeof(": ") - 1 + header[i].value.len |
311 + sizeof(CRLF) - 1; | 310 + sizeof(CRLF) - 1; |
323 if (r->headers_out.status_line.len) { | 322 if (r->headers_out.status_line.len) { |
324 b->last = ngx_cpymem(b->last, r->headers_out.status_line.data, | 323 b->last = ngx_cpymem(b->last, r->headers_out.status_line.data, |
325 r->headers_out.status_line.len); | 324 r->headers_out.status_line.len); |
326 | 325 |
327 } else { | 326 } else { |
328 b->last = ngx_cpymem(b->last, http_codes[status].data, | 327 b->last = ngx_cpymem(b->last, ngx_http_status_lines[status].data, |
329 http_codes[status].len); | 328 ngx_http_status_lines[status].len); |
330 } | 329 } |
331 *b->last++ = CR; *b->last++ = LF; | 330 *b->last++ = CR; *b->last++ = LF; |
332 | 331 |
333 if (!(r->headers_out.server && r->headers_out.server->key.len)) { | 332 if (r->headers_out.server == NULL) { |
334 b->last = ngx_cpymem(b->last, server_string, sizeof(server_string) - 1); | 333 b->last = ngx_cpymem(b->last, ngx_http_server_string, |
335 } | 334 sizeof(ngx_http_server_string) - 1); |
336 | 335 } |
337 if (!(r->headers_out.date && r->headers_out.date->key.len)) { | 336 |
337 if (r->headers_out.date == NULL) { | |
338 b->last = ngx_cpymem(b->last, "Date: ", sizeof("Date: ") - 1); | 338 b->last = ngx_cpymem(b->last, "Date: ", sizeof("Date: ") - 1); |
339 b->last = ngx_cpymem(b->last, ngx_cached_http_time.data, | 339 b->last = ngx_cpymem(b->last, ngx_cached_http_time.data, |
340 ngx_cached_http_time.len); | 340 ngx_cached_http_time.len); |
341 | 341 |
342 *b->last++ = CR; *b->last++ = LF; | 342 *b->last++ = CR; *b->last++ = LF; |
343 } | 343 } |
344 | 344 |
345 if (r->headers_out.content_length == NULL) { | 345 if (r->headers_out.content_type.len) { |
346 if (r->headers_out.content_length_n >= 0) { | |
347 b->last = ngx_sprintf(b->last, "Content-Length: %O" CRLF, | |
348 r->headers_out.content_length_n); | |
349 } | |
350 } | |
351 | |
352 if (r->headers_out.content_type && r->headers_out.content_type->value.len) { | |
353 b->last = ngx_cpymem(b->last, "Content-Type: ", | 346 b->last = ngx_cpymem(b->last, "Content-Type: ", |
354 sizeof("Content-Type: ") - 1); | 347 sizeof("Content-Type: ") - 1); |
355 p = b->last; | 348 p = b->last; |
356 b->last = ngx_cpymem(b->last, r->headers_out.content_type->value.data, | 349 b->last = ngx_cpymem(b->last, r->headers_out.content_type.data, |
357 r->headers_out.content_type->value.len); | 350 r->headers_out.content_type.len); |
358 | 351 |
359 if (r->headers_out.charset.len) { | 352 if (r->headers_out.charset.len) { |
360 b->last = ngx_cpymem(b->last, "; charset=", | 353 b->last = ngx_cpymem(b->last, "; charset=", |
361 sizeof("; charset=") - 1); | 354 sizeof("; charset=") - 1); |
362 b->last = ngx_cpymem(b->last, r->headers_out.charset.data, | 355 b->last = ngx_cpymem(b->last, r->headers_out.charset.data, |
363 r->headers_out.charset.len); | 356 r->headers_out.charset.len); |
364 | 357 |
365 r->headers_out.content_type->value.len = b->last - p; | 358 /* update r->headers_out.content_type for possible logging */ |
366 r->headers_out.content_type->value.data = p; | 359 |
367 } | 360 r->headers_out.content_type.len = b->last - p; |
361 r->headers_out.content_type.data = p; | |
362 } | |
363 | |
364 *b->last++ = CR; *b->last++ = LF; | |
365 } | |
366 | |
367 if (r->headers_out.content_length == NULL | |
368 && r->headers_out.content_length_n >= 0) | |
369 { | |
370 b->last = ngx_sprintf(b->last, "Content-Length: %O" CRLF, | |
371 r->headers_out.content_length_n); | |
372 } | |
373 | |
374 if (r->headers_out.last_modified == NULL | |
375 && r->headers_out.last_modified_time != -1) | |
376 { | |
377 b->last = ngx_cpymem(b->last, "Last-Modified: ", | |
378 sizeof("Last-Modified: ") - 1); | |
379 b->last = ngx_http_time(b->last, r->headers_out.last_modified_time); | |
368 | 380 |
369 *b->last++ = CR; *b->last++ = LF; | 381 *b->last++ = CR; *b->last++ = LF; |
370 } | 382 } |
371 | 383 |
372 if (r->headers_out.location | 384 if (r->headers_out.location |
384 } | 396 } |
385 | 397 |
386 b->last = ngx_cpymem(b->last, r->headers_out.location->value.data, | 398 b->last = ngx_cpymem(b->last, r->headers_out.location->value.data, |
387 r->headers_out.location->value.len); | 399 r->headers_out.location->value.len); |
388 | 400 |
401 /* update r->headers_out.location->value for possible logging */ | |
402 | |
389 r->headers_out.location->value.len = b->last - p; | 403 r->headers_out.location->value.len = b->last - p; |
390 r->headers_out.location->value.data = p; | 404 r->headers_out.location->value.data = p; |
391 | |
392 *b->last++ = CR; *b->last++ = LF; | |
393 } | |
394 | |
395 if (!(r->headers_out.last_modified && r->headers_out.last_modified->key.len) | |
396 && r->headers_out.last_modified_time != -1) | |
397 { | |
398 b->last = ngx_cpymem(b->last, "Last-Modified: ", | |
399 sizeof("Last-Modified: ") - 1); | |
400 b->last = ngx_http_time(b->last, r->headers_out.last_modified_time); | |
401 | 405 |
402 *b->last++ = CR; *b->last++ = LF; | 406 *b->last++ = CR; *b->last++ = LF; |
403 } | 407 } |
404 | 408 |
405 if (r->chunked) { | 409 if (r->chunked) { |
434 part = part->next; | 438 part = part->next; |
435 header = part->elts; | 439 header = part->elts; |
436 i = 0; | 440 i = 0; |
437 } | 441 } |
438 | 442 |
439 if (header[i].key.len == 0) { | 443 if (header[i].hash == 0) { |
440 continue; | 444 continue; |
441 } | 445 } |
442 | 446 |
443 b->last = ngx_cpymem(b->last, header[i].key.data, header[i].key.len); | 447 b->last = ngx_cpymem(b->last, header[i].key.data, header[i].key.len); |
444 *b->last++ = ':' ; *b->last++ = ' ' ; | 448 *b->last++ = ':' ; *b->last++ = ' ' ; |