Mercurial > hg > nginx-vendor-0-7
comparison src/http/ngx_http_request.c @ 58:b55cbf18157e NGINX_0_1_29
nginx 0.1.29
*) 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; bug 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 <http://sysoev.ru> |
---|---|
date | Thu, 12 May 2005 00:00:00 +0400 |
parents | 3050baa54a26 |
children | df7d3fff122b |
comparison
equal
deleted
inserted
replaced
57:5df375c55338 | 58:b55cbf18157e |
---|---|
17 static void ngx_http_process_request_line(ngx_event_t *rev); | 17 static void ngx_http_process_request_line(ngx_event_t *rev); |
18 static void ngx_http_process_request_headers(ngx_event_t *rev); | 18 static void ngx_http_process_request_headers(ngx_event_t *rev); |
19 static ssize_t ngx_http_read_request_header(ngx_http_request_t *r); | 19 static ssize_t ngx_http_read_request_header(ngx_http_request_t *r); |
20 static ngx_int_t ngx_http_alloc_large_header_buffer(ngx_http_request_t *r, | 20 static ngx_int_t ngx_http_alloc_large_header_buffer(ngx_http_request_t *r, |
21 ngx_uint_t request_line); | 21 ngx_uint_t request_line); |
22 | |
23 static ngx_int_t ngx_http_process_header_line(ngx_http_request_t *r, | |
24 ngx_table_elt_t *h, ngx_uint_t offset); | |
25 static ngx_int_t ngx_http_process_cookie(ngx_http_request_t *r, | |
26 ngx_table_elt_t *h, ngx_uint_t offset); | |
27 | |
22 static ngx_int_t ngx_http_process_request_header(ngx_http_request_t *r); | 28 static ngx_int_t ngx_http_process_request_header(ngx_http_request_t *r); |
23 static ngx_int_t ngx_http_find_virtual_server(ngx_http_request_t *r); | 29 static ngx_int_t ngx_http_find_virtual_server(ngx_http_request_t *r); |
24 | 30 |
31 static void ngx_http_request_handler(ngx_event_t *ev); | |
25 static void ngx_http_set_write_handler(ngx_http_request_t *r); | 32 static void ngx_http_set_write_handler(ngx_http_request_t *r); |
26 | 33 static void ngx_http_writer(ngx_http_request_t *r); |
27 static void ngx_http_block_read(ngx_event_t *ev); | 34 static ngx_int_t ngx_http_postponed_handler(ngx_http_request_t *r); |
28 static void ngx_http_read_discarded_body_event(ngx_event_t *rev); | 35 |
36 static void ngx_http_block_read(ngx_http_request_t *r); | |
37 static void ngx_http_read_discarded_body_handler(ngx_http_request_t *r); | |
29 static ngx_int_t ngx_http_read_discarded_body(ngx_http_request_t *r); | 38 static ngx_int_t ngx_http_read_discarded_body(ngx_http_request_t *r); |
30 | 39 |
31 static void ngx_http_set_keepalive(ngx_http_request_t *r); | 40 static void ngx_http_set_keepalive(ngx_http_request_t *r); |
32 static void ngx_http_keepalive_handler(ngx_event_t *ev); | 41 static void ngx_http_keepalive_handler(ngx_event_t *ev); |
33 static void ngx_http_set_lingering_close(ngx_http_request_t *r); | 42 static void ngx_http_set_lingering_close(ngx_http_request_t *r); |
34 static void ngx_http_lingering_close_handler(ngx_event_t *ev); | 43 static void ngx_http_lingering_close_handler(ngx_event_t *ev); |
35 | 44 |
36 static u_char *ngx_http_log_error(ngx_log_t *log, u_char *buf, size_t len); | 45 static u_char *ngx_http_log_error(ngx_log_t *log, u_char *buf, size_t len); |
46 static u_char *ngx_http_log_error_handler(ngx_http_request_t *r, u_char *buf, | |
47 size_t len); | |
37 | 48 |
38 | 49 |
39 static char *ngx_http_client_errors[] = { | 50 static char *ngx_http_client_errors[] = { |
40 | 51 |
41 /* NGX_HTTP_PARSE_INVALID_METHOD */ | 52 /* NGX_HTTP_PARSE_INVALID_METHOD */ |
48 "client sent invalid method in HTTP/0.9 request" | 59 "client sent invalid method in HTTP/0.9 request" |
49 }; | 60 }; |
50 | 61 |
51 | 62 |
52 ngx_http_header_t ngx_http_headers_in[] = { | 63 ngx_http_header_t ngx_http_headers_in[] = { |
53 { ngx_string("Host"), offsetof(ngx_http_headers_in_t, host) }, | 64 { ngx_string("Host"), offsetof(ngx_http_headers_in_t, host), |
54 { ngx_string("Connection"), offsetof(ngx_http_headers_in_t, connection) }, | 65 ngx_http_process_header_line }, |
66 | |
67 { ngx_string("Connection"), offsetof(ngx_http_headers_in_t, connection), | |
68 ngx_http_process_header_line }, | |
69 | |
55 { ngx_string("If-Modified-Since"), | 70 { ngx_string("If-Modified-Since"), |
56 offsetof(ngx_http_headers_in_t, if_modified_since) }, | 71 offsetof(ngx_http_headers_in_t, if_modified_since), |
57 { ngx_string("User-Agent"), offsetof(ngx_http_headers_in_t, user_agent) }, | 72 ngx_http_process_header_line }, |
58 { ngx_string("Referer"), offsetof(ngx_http_headers_in_t, referer) }, | 73 |
74 { ngx_string("User-Agent"), offsetof(ngx_http_headers_in_t, user_agent), | |
75 ngx_http_process_header_line }, | |
76 | |
77 { ngx_string("Referer"), offsetof(ngx_http_headers_in_t, referer), | |
78 ngx_http_process_header_line }, | |
79 | |
59 { ngx_string("Content-Length"), | 80 { ngx_string("Content-Length"), |
60 offsetof(ngx_http_headers_in_t, content_length) }, | 81 offsetof(ngx_http_headers_in_t, content_length), |
82 ngx_http_process_header_line }, | |
83 | |
61 { ngx_string("Content-Type"), | 84 { ngx_string("Content-Type"), |
62 offsetof(ngx_http_headers_in_t, content_type) }, | 85 offsetof(ngx_http_headers_in_t, content_type), |
63 | 86 ngx_http_process_header_line }, |
64 { ngx_string("Range"), offsetof(ngx_http_headers_in_t, range) }, | 87 |
88 { ngx_string("Range"), offsetof(ngx_http_headers_in_t, range), | |
89 ngx_http_process_header_line }, | |
90 | |
65 #if 0 | 91 #if 0 |
66 { ngx_string("If-Range"), offsetof(ngx_http_headers_in_t, if_range) }, | 92 { ngx_string("If-Range"), offsetof(ngx_http_headers_in_t, if_range), |
93 ngx_http_process_header_line }, | |
67 #endif | 94 #endif |
68 | 95 |
69 #if (NGX_HTTP_GZIP) | 96 #if (NGX_HTTP_GZIP) |
70 { ngx_string("Accept-Encoding"), | 97 { ngx_string("Accept-Encoding"), |
71 offsetof(ngx_http_headers_in_t, accept_encoding) }, | 98 offsetof(ngx_http_headers_in_t, accept_encoding), |
72 { ngx_string("Via"), offsetof(ngx_http_headers_in_t, via) }, | 99 ngx_http_process_header_line }, |
100 | |
101 { ngx_string("Via"), offsetof(ngx_http_headers_in_t, via), | |
102 ngx_http_process_header_line }, | |
73 #endif | 103 #endif |
74 | 104 |
75 { ngx_string("Authorization"), | 105 { ngx_string("Authorization"), |
76 offsetof(ngx_http_headers_in_t, authorization) }, | 106 offsetof(ngx_http_headers_in_t, authorization), |
77 | 107 ngx_http_process_header_line }, |
78 { ngx_string("Keep-Alive"), offsetof(ngx_http_headers_in_t, keep_alive) }, | 108 |
109 { ngx_string("Keep-Alive"), offsetof(ngx_http_headers_in_t, keep_alive), | |
110 ngx_http_process_header_line }, | |
79 | 111 |
80 #if (NGX_HTTP_PROXY) | 112 #if (NGX_HTTP_PROXY) |
81 { ngx_string("X-Forwarded-For"), | 113 { ngx_string("X-Forwarded-For"), |
82 offsetof(ngx_http_headers_in_t, x_forwarded_for) }, | 114 offsetof(ngx_http_headers_in_t, x_forwarded_for), |
83 { ngx_string("X-Real-IP"), offsetof(ngx_http_headers_in_t, x_real_ip) }, | 115 ngx_http_process_header_line }, |
84 { ngx_string("X-URL"), offsetof(ngx_http_headers_in_t, x_url) }, | 116 |
117 { ngx_string("X-Real-IP"), offsetof(ngx_http_headers_in_t, x_real_ip), | |
118 ngx_http_process_header_line }, | |
119 | |
120 { ngx_string("X-URL"), offsetof(ngx_http_headers_in_t, x_url), | |
121 ngx_http_process_header_line }, | |
85 #endif | 122 #endif |
86 | 123 |
87 #if (NGX_HTTP_HEADERS) | 124 #if (NGX_HTTP_HEADERS) |
88 { ngx_string("Accept"), offsetof(ngx_http_headers_in_t, accept) }, | 125 { ngx_string("Accept"), offsetof(ngx_http_headers_in_t, accept), |
126 ngx_http_process_header_line }, | |
127 | |
89 { ngx_string("Accept-Language"), | 128 { ngx_string("Accept-Language"), |
90 offsetof(ngx_http_headers_in_t, accept_language) }, | 129 offsetof(ngx_http_headers_in_t, accept_language), |
91 #endif | 130 ngx_http_process_header_line }, |
92 | 131 #endif |
93 { ngx_null_string, 0 } | 132 |
133 { ngx_string("Cookie"), 0, ngx_http_process_cookie }, | |
134 | |
135 { ngx_null_string, 0, NULL } | |
94 }; | 136 }; |
95 | |
96 | |
97 #if 0 | |
98 static void | |
99 ngx_http_dummy(ngx_event_t *wev) | |
100 { | |
101 return; | |
102 } | |
103 #endif | |
104 | 137 |
105 | 138 |
106 void | 139 void |
107 ngx_http_init_connection(ngx_connection_t *c) | 140 ngx_http_init_connection(ngx_connection_t *c) |
108 { | 141 { |
124 c->log->action = "reading client request line"; | 157 c->log->action = "reading client request line"; |
125 | 158 |
126 c->log_error = NGX_ERROR_INFO; | 159 c->log_error = NGX_ERROR_INFO; |
127 | 160 |
128 rev = c->read; | 161 rev = c->read; |
129 rev->event_handler = ngx_http_init_request; | 162 rev->handler = ngx_http_init_request; |
130 | 163 |
131 /* STUB: epoll edge */ c->write->event_handler = ngx_http_empty_handler; | 164 /* STUB: epoll edge */ c->write->handler = ngx_http_empty_handler; |
132 | 165 |
133 if (rev->ready) { | 166 if (rev->ready) { |
134 /* the deferred accept(), rtsig, aio, iocp */ | 167 /* the deferred accept(), rtsig, aio, iocp */ |
135 | 168 |
136 if (ngx_accept_mutex) { | 169 if (ngx_accept_mutex) { |
162 | 195 |
163 if (ngx_handle_read_event(rev, 0) == NGX_ERROR) { | 196 if (ngx_handle_read_event(rev, 0) == NGX_ERROR) { |
164 ngx_http_close_connection(c); | 197 ngx_http_close_connection(c); |
165 return; | 198 return; |
166 } | 199 } |
167 | |
168 #if 0 | |
169 /* TODO: learn SO_SNDBUF (to use in zerocopy) via kqueue's EV_CLEAR event */ | |
170 | |
171 c->write->ready = 0; | |
172 c->write->event_handler = ngx_http_dummy; | |
173 | |
174 if (ngx_handle_write_event(c->write, 0) == NGX_ERROR) { | |
175 ngx_http_close_connection(c); | |
176 return; | |
177 } | |
178 #endif | |
179 | 200 |
180 #if (NGX_STAT_STUB) | 201 #if (NGX_STAT_STUB) |
181 ngx_atomic_inc(ngx_stat_reading); | 202 ngx_atomic_inc(ngx_stat_reading); |
182 #endif | 203 #endif |
183 | 204 |
333 | 354 |
334 r->main_conf = cscf->ctx->main_conf; | 355 r->main_conf = cscf->ctx->main_conf; |
335 r->srv_conf = cscf->ctx->srv_conf; | 356 r->srv_conf = cscf->ctx->srv_conf; |
336 r->loc_conf = cscf->ctx->loc_conf; | 357 r->loc_conf = cscf->ctx->loc_conf; |
337 | 358 |
338 rev->event_handler = ngx_http_process_request_line; | 359 rev->handler = ngx_http_process_request_line; |
339 | 360 |
340 #if (NGX_HTTP_SSL) | 361 #if (NGX_HTTP_SSL) |
341 | 362 |
342 sscf = ngx_http_get_module_srv_conf(r, ngx_http_ssl_module); | 363 sscf = ngx_http_get_module_srv_conf(r, ngx_http_ssl_module); |
343 if (sscf->enable) { | 364 if (sscf->enable) { |
348 { | 369 { |
349 ngx_http_close_connection(c); | 370 ngx_http_close_connection(c); |
350 return; | 371 return; |
351 } | 372 } |
352 | 373 |
353 rev->event_handler = ngx_http_ssl_handshake; | 374 rev->handler = ngx_http_ssl_handshake; |
354 | 375 |
355 /* | 376 /* |
356 * The majority of browsers do not send the "close notify" alert. | 377 * The majority of browsers do not send the "close notify" alert. |
357 * Among them are MSIE, Mozilla, Netscape 4, Konqueror, and Links. | 378 * Among them are MSIE, Mozilla, Netscape 4, Konqueror, and Links. |
358 * And what is more, MSIE ignores the server's alert. | 379 * And what is more, MSIE ignores the server's alert. |
394 if (r->pool == NULL) { | 415 if (r->pool == NULL) { |
395 ngx_http_close_connection(c); | 416 ngx_http_close_connection(c); |
396 return; | 417 return; |
397 } | 418 } |
398 | 419 |
399 if (ngx_array_init(&r->cleanup, r->pool, 4, sizeof(ngx_http_cleanup_t)) | |
400 == NGX_ERROR) | |
401 { | |
402 ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR); | |
403 ngx_http_close_connection(c); | |
404 return; | |
405 } | |
406 | |
407 | 420 |
408 if (ngx_list_init(&r->headers_out.headers, r->pool, 20, | 421 if (ngx_list_init(&r->headers_out.headers, r->pool, 20, |
409 sizeof(ngx_table_elt_t)) == NGX_ERROR) | 422 sizeof(ngx_table_elt_t)) == NGX_ERROR) |
410 { | 423 { |
411 ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR); | 424 ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR); |
412 ngx_http_close_connection(c); | 425 ngx_http_close_connection(c); |
413 return; | 426 return; |
414 } | 427 } |
424 c->single_connection = 1; | 437 c->single_connection = 1; |
425 r->connection = c; | 438 r->connection = c; |
426 | 439 |
427 r->start_time = ngx_time(); | 440 r->start_time = ngx_time(); |
428 | 441 |
429 r->file.fd = NGX_INVALID_FILE; | |
430 | |
431 r->headers_in.content_length_n = -1; | 442 r->headers_in.content_length_n = -1; |
432 r->headers_in.keep_alive_n = -1; | 443 r->headers_in.keep_alive_n = -1; |
433 r->headers_out.content_length_n = -1; | 444 r->headers_out.content_length_n = -1; |
434 r->headers_out.last_modified_time = -1; | 445 r->headers_out.last_modified_time = -1; |
435 | 446 |
436 r->http_state = NGX_HTTP_READING_REQUEST_STATE; | 447 r->http_state = NGX_HTTP_READING_REQUEST_STATE; |
437 | 448 |
438 ctx = c->log->data; | 449 ctx = c->log->data; |
439 ctx->request = r; | 450 ctx->request = r; |
451 r->log_handler = ngx_http_log_error_handler; | |
440 | 452 |
441 #if (NGX_STAT_STUB) | 453 #if (NGX_STAT_STUB) |
442 ngx_atomic_inc(ngx_stat_reading); | 454 ngx_atomic_inc(ngx_stat_reading); |
443 r->stat_reading = 1; | 455 r->stat_reading = 1; |
444 ngx_atomic_inc(ngx_stat_requests); | 456 ngx_atomic_inc(ngx_stat_requests); |
445 #endif | 457 #endif |
446 | 458 |
447 rev->event_handler(rev); | 459 rev->handler(rev); |
448 } | 460 } |
449 | 461 |
450 | 462 |
451 #if (NGX_HTTP_SSL) | 463 #if (NGX_HTTP_SSL) |
452 | 464 |
505 | 517 |
506 r->plain_http = 1; | 518 r->plain_http = 1; |
507 } | 519 } |
508 } | 520 } |
509 | 521 |
510 rev->event_handler = ngx_http_process_request_line; | 522 rev->handler = ngx_http_process_request_line; |
511 ngx_http_process_request_line(rev); | 523 ngx_http_process_request_line(rev); |
512 } | 524 } |
513 | 525 |
514 #endif | 526 #endif |
515 | 527 |
591 | 603 |
592 r->unparsed_uri.len = r->uri_end - r->uri_start; | 604 r->unparsed_uri.len = r->uri_end - r->uri_start; |
593 r->unparsed_uri.data = r->uri_start; | 605 r->unparsed_uri.data = r->uri_start; |
594 | 606 |
595 | 607 |
596 if (r->method == 0) { | 608 r->method_name.len = r->method_end - r->request_start + 1; |
597 r->method_name.len = r->method_end - r->request_start + 1; | 609 r->method_name.data = r->request_line.data; |
598 r->method_name.data = r->request_line.data; | |
599 } | |
600 | 610 |
601 | 611 |
602 if (r->http_protocol.data) { | 612 if (r->http_protocol.data) { |
603 r->http_protocol.len = r->request_end - r->http_protocol.data; | 613 r->http_protocol.len = r->request_end - r->http_protocol.data; |
604 } | 614 } |
632 | 642 |
633 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0, | 643 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0, |
634 "http exten: \"%V\"", &r->exten); | 644 "http exten: \"%V\"", &r->exten); |
635 | 645 |
636 if (r->http_version < NGX_HTTP_VERSION_10) { | 646 if (r->http_version < NGX_HTTP_VERSION_10) { |
637 rev->event_handler = ngx_http_block_read; | 647 r->read_event_handler = ngx_http_block_read; |
638 ngx_http_handler(r); | 648 ngx_http_handler(r); |
639 return; | 649 return; |
640 } | 650 } |
641 | 651 |
642 | 652 |
657 return; | 667 return; |
658 } | 668 } |
659 | 669 |
660 c->log->action = "reading client request headers"; | 670 c->log->action = "reading client request headers"; |
661 | 671 |
662 rev->event_handler = ngx_http_process_request_headers; | 672 rev->handler = ngx_http_process_request_headers; |
663 ngx_http_process_request_headers(rev); | 673 ngx_http_process_request_headers(rev); |
664 | 674 |
665 return; | 675 return; |
666 } | 676 } |
667 | 677 |
709 { | 719 { |
710 ssize_t n; | 720 ssize_t n; |
711 ngx_int_t rc, rv; | 721 ngx_int_t rc, rv; |
712 ngx_uint_t key; | 722 ngx_uint_t key; |
713 ngx_str_t header; | 723 ngx_str_t header; |
714 ngx_table_elt_t *h, **cookie; | 724 ngx_table_elt_t *h; |
715 ngx_connection_t *c; | 725 ngx_connection_t *c; |
716 ngx_http_header_t *hh; | 726 ngx_http_header_t *hh; |
717 ngx_http_request_t *r; | 727 ngx_http_request_t *r; |
718 ngx_http_core_main_conf_t *cmcf; | 728 ngx_http_core_main_conf_t *cmcf; |
719 | 729 |
771 | 781 |
772 rc = ngx_http_parse_header_line(r, r->header_in); | 782 rc = ngx_http_parse_header_line(r, r->header_in); |
773 | 783 |
774 if (rc == NGX_OK) { | 784 if (rc == NGX_OK) { |
775 | 785 |
786 #if 0 | |
776 if (r->invalid_header) { | 787 if (r->invalid_header) { |
777 | 788 |
778 /* there was error while a header line parsing */ | 789 /* there was error while a header line parsing */ |
779 | 790 |
780 header.len = r->header_end - r->header_name_start; | 791 header.len = r->header_end - r->header_name_start; |
783 ngx_log_error(NGX_LOG_INFO, c->log, 0, | 794 ngx_log_error(NGX_LOG_INFO, c->log, 0, |
784 "client sent invalid header line: \"%V\"", | 795 "client sent invalid header line: \"%V\"", |
785 &header); | 796 &header); |
786 continue; | 797 continue; |
787 } | 798 } |
799 #endif | |
788 | 800 |
789 /* a header line has been parsed successfully */ | 801 /* a header line has been parsed successfully */ |
790 | |
791 r->headers_n++; | |
792 | 802 |
793 h = ngx_list_push(&r->headers_in.headers); | 803 h = ngx_list_push(&r->headers_in.headers); |
794 if (h == NULL) { | 804 if (h == NULL) { |
795 ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR); | 805 ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR); |
796 ngx_http_close_connection(c); | 806 ngx_http_close_connection(c); |
805 | 815 |
806 h->value.len = r->header_end - r->header_start; | 816 h->value.len = r->header_end - r->header_start; |
807 h->value.data = r->header_start; | 817 h->value.data = r->header_start; |
808 h->value.data[h->value.len] = '\0'; | 818 h->value.data[h->value.len] = '\0'; |
809 | 819 |
810 if (h->key.len == sizeof("Cookie") - 1 | 820 key = h->hash % cmcf->headers_in_hash.hash_size; |
811 && ngx_strcasecmp(h->key.data, "Cookie") == 0) | 821 |
822 if (hh[key].name.len == h->key.len | |
823 && ngx_strcasecmp(hh[key].name.data, h->key.data) == 0) | |
812 { | 824 { |
813 cookie = ngx_array_push(&r->headers_in.cookies); | 825 if (hh[key].handler(r, h, hh[key].offset) != NGX_OK) { |
814 if (cookie == NULL) { | |
815 ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR); | |
816 ngx_http_close_connection(c); | |
817 return; | 826 return; |
818 } | |
819 | |
820 *cookie = h; | |
821 | |
822 } else { | |
823 key = h->hash % cmcf->headers_in_hash.hash_size; | |
824 | |
825 if (hh[key].name.len == h->key.len | |
826 && ngx_strcasecmp(hh[key].name.data, h->key.data) == 0) | |
827 { | |
828 *((ngx_table_elt_t **) | |
829 ((char *) &r->headers_in + hh[key].offset)) = h; | |
830 } | 827 } |
831 } | 828 } |
832 | 829 |
833 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, | 830 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, |
834 "http header: \"%V: %V\"", | 831 "http header: \"%V: %V\"", |
863 r->stat_reading = 0; | 860 r->stat_reading = 0; |
864 ngx_atomic_inc(ngx_stat_writing); | 861 ngx_atomic_inc(ngx_stat_writing); |
865 r->stat_writing = 1; | 862 r->stat_writing = 1; |
866 #endif | 863 #endif |
867 | 864 |
868 rev->event_handler = ngx_http_block_read; | 865 rev->handler = ngx_http_request_handler; |
866 c->write->handler = ngx_http_request_handler; | |
867 r->read_event_handler = ngx_http_block_read; | |
868 | |
869 ngx_http_handler(r); | 869 ngx_http_handler(r); |
870 return; | 870 return; |
871 } | 871 } |
872 | 872 |
873 if (rc == NGX_AGAIN) { | 873 if (rc == NGX_AGAIN) { |
1089 return NGX_OK; | 1089 return NGX_OK; |
1090 } | 1090 } |
1091 | 1091 |
1092 | 1092 |
1093 static ngx_int_t | 1093 static ngx_int_t |
1094 ngx_http_process_header_line(ngx_http_request_t *r, ngx_table_elt_t *h, | |
1095 ngx_uint_t offset) | |
1096 { | |
1097 ngx_table_elt_t **ph; | |
1098 | |
1099 ph = (ngx_table_elt_t **) ((char *) &r->headers_in + offset); | |
1100 | |
1101 if (*ph == NULL) { | |
1102 *ph = h; | |
1103 } | |
1104 | |
1105 return NGX_OK; | |
1106 } | |
1107 | |
1108 | |
1109 static ngx_int_t | |
1110 ngx_http_process_cookie(ngx_http_request_t *r, ngx_table_elt_t *h, | |
1111 ngx_uint_t offset) | |
1112 { | |
1113 ngx_table_elt_t **cookie; | |
1114 | |
1115 cookie = ngx_array_push(&r->headers_in.cookies); | |
1116 if (cookie == NULL) { | |
1117 ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR); | |
1118 ngx_http_close_connection(r->connection); | |
1119 return NGX_ERROR; | |
1120 } | |
1121 | |
1122 *cookie = h; | |
1123 | |
1124 return NGX_OK; | |
1125 } | |
1126 | |
1127 | |
1128 static ngx_int_t | |
1094 ngx_http_process_request_header(ngx_http_request_t *r) | 1129 ngx_http_process_request_header(ngx_http_request_t *r) |
1095 { | 1130 { |
1096 size_t len; | 1131 size_t len; |
1097 u_char *ua, *user_agent, ch; | 1132 u_char *ua, *user_agent, ch; |
1098 ngx_http_core_srv_conf_t *cscf; | 1133 ngx_http_core_srv_conf_t *cscf; |
1104 if (ch == ':') { | 1139 if (ch == ':') { |
1105 break; | 1140 break; |
1106 } | 1141 } |
1107 | 1142 |
1108 r->headers_in.host->value.data[len] = ngx_tolower(ch); | 1143 r->headers_in.host->value.data[len] = ngx_tolower(ch); |
1144 } | |
1145 | |
1146 if (r->headers_in.host->value.data[len - 1] == '.') { | |
1147 len--; | |
1109 } | 1148 } |
1110 | 1149 |
1111 r->headers_in.host_name_len = len; | 1150 r->headers_in.host_name_len = len; |
1112 | 1151 |
1113 if (ngx_http_find_virtual_server(r) != NGX_OK) { | 1152 if (ngx_http_find_virtual_server(r) != NGX_OK) { |
1165 } | 1204 } |
1166 | 1205 |
1167 if (r->headers_in.connection) { | 1206 if (r->headers_in.connection) { |
1168 if (r->headers_in.connection->value.len == 5 | 1207 if (r->headers_in.connection->value.len == 5 |
1169 && ngx_strcasecmp(r->headers_in.connection->value.data, "close") | 1208 && ngx_strcasecmp(r->headers_in.connection->value.data, "close") |
1170 == 0) | 1209 == 0) |
1171 { | 1210 { |
1172 r->headers_in.connection_type = NGX_HTTP_CONNECTION_CLOSE; | 1211 r->headers_in.connection_type = NGX_HTTP_CONNECTION_CLOSE; |
1173 | 1212 |
1174 } else if (r->headers_in.connection->value.len == 10 | 1213 } else if (r->headers_in.connection->value.len == 10 |
1175 && ngx_strcasecmp(r->headers_in.connection->value.data, | 1214 && ngx_strcasecmp(r->headers_in.connection->value.data, |
1176 "keep-alive") == 0) | 1215 "keep-alive") == 0) |
1177 { | 1216 { |
1178 r->headers_in.connection_type = NGX_HTTP_CONNECTION_KEEP_ALIVE; | 1217 r->headers_in.connection_type = NGX_HTTP_CONNECTION_KEEP_ALIVE; |
1179 | 1218 |
1180 if (r->headers_in.keep_alive) { | 1219 if (r->headers_in.keep_alive) { |
1181 r->headers_in.keep_alive_n = | 1220 r->headers_in.keep_alive_n = |
1235 | 1274 |
1236 static ngx_int_t | 1275 static ngx_int_t |
1237 ngx_http_find_virtual_server(ngx_http_request_t *r) | 1276 ngx_http_find_virtual_server(ngx_http_request_t *r) |
1238 { | 1277 { |
1239 ngx_int_t rc; | 1278 ngx_int_t rc; |
1240 ngx_uint_t i, n, key, found; | 1279 ngx_uint_t i, n, key; |
1241 ngx_http_server_name_t *name; | 1280 ngx_http_server_name_t *name; |
1242 ngx_http_core_loc_conf_t *clcf; | 1281 ngx_http_core_loc_conf_t *clcf; |
1243 ngx_http_core_srv_conf_t *cscf; | 1282 ngx_http_core_srv_conf_t *cscf; |
1244 ngx_http_core_main_conf_t *cmcf; | 1283 ngx_http_core_main_conf_t *cmcf; |
1245 | 1284 |
1257 } else { | 1296 } else { |
1258 name = r->virtual_names->names.elts; | 1297 name = r->virtual_names->names.elts; |
1259 n = r->virtual_names->names.nelts; | 1298 n = r->virtual_names->names.nelts; |
1260 } | 1299 } |
1261 | 1300 |
1262 found = 0; | |
1263 | |
1264 for (i = 0; i < n; i++) { | 1301 for (i = 0; i < n; i++) { |
1265 | 1302 |
1266 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, | 1303 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, |
1267 "server name: %V", &name[i].name); | 1304 "server name: %V", &name[i].name); |
1268 | 1305 |
1273 rc = ngx_strncmp(r->headers_in.host->value.data, | 1310 rc = ngx_strncmp(r->headers_in.host->value.data, |
1274 name[i].name.data, name[i].name.len); | 1311 name[i].name.data, name[i].name.len); |
1275 | 1312 |
1276 if (rc == 0) { | 1313 if (rc == 0) { |
1277 r->server_name = name[i].name; | 1314 r->server_name = name[i].name; |
1278 | 1315 goto found; |
1279 found = 1; | |
1280 break; | |
1281 } | 1316 } |
1282 | 1317 |
1283 if (rc < 0) { | 1318 if (rc < 0) { |
1284 /* the server names are lexicographically sorted */ | 1319 /* the server names are lexicographically sorted */ |
1285 break; | 1320 break; |
1286 } | 1321 } |
1287 } | 1322 } |
1288 | 1323 |
1289 if (!found && r->virtual_names->wildcards.nelts) { | 1324 if (r->virtual_names->wildcards.nelts) { |
1290 | 1325 |
1291 name = r->virtual_names->wildcards.elts; | 1326 name = r->virtual_names->wildcards.elts; |
1292 for (i = 0; i < r->virtual_names->wildcards.nelts; i++) { | 1327 for (i = 0; i < r->virtual_names->wildcards.nelts; i++) { |
1293 | 1328 |
1294 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, | 1329 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, |
1308 name[i].name.data, name[i].name.len) == 0) | 1343 name[i].name.data, name[i].name.len) == 0) |
1309 { | 1344 { |
1310 r->server_name.len = r->headers_in.host_name_len; | 1345 r->server_name.len = r->headers_in.host_name_len; |
1311 r->server_name.data = r->headers_in.host->value.data; | 1346 r->server_name.data = r->headers_in.host->value.data; |
1312 | 1347 |
1313 found = 1; | 1348 goto found; |
1314 break; | 1349 } |
1315 } | 1350 } |
1316 } | 1351 } |
1317 } | 1352 |
1318 | 1353 cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module); |
1319 if (found) { | 1354 |
1320 r->srv_conf = name[i].core_srv_conf->ctx->srv_conf; | 1355 if (cscf->restrict_host_names == NGX_HTTP_RESTRICT_HOST_OFF) { |
1321 r->loc_conf = name[i].core_srv_conf->ctx->loc_conf; | |
1322 | |
1323 clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); | |
1324 r->connection->log->file = clcf->err_log->file; | |
1325 | |
1326 if (!(r->connection->log->log_level & NGX_LOG_DEBUG_CONNECTION)) { | |
1327 r->connection->log->log_level = clcf->err_log->log_level; | |
1328 } | |
1329 | |
1330 return NGX_OK; | 1356 return NGX_OK; |
1331 } | 1357 } |
1332 | 1358 |
1333 cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module); | 1359 return NGX_ERROR; |
1334 | 1360 |
1335 if (cscf->restrict_host_names != NGX_HTTP_RESTRICT_HOST_OFF) { | 1361 found: |
1336 return NGX_ERROR; | 1362 |
1363 r->srv_conf = name[i].core_srv_conf->ctx->srv_conf; | |
1364 r->loc_conf = name[i].core_srv_conf->ctx->loc_conf; | |
1365 | |
1366 clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); | |
1367 r->connection->log->file = clcf->err_log->file; | |
1368 | |
1369 if (!(r->connection->log->log_level & NGX_LOG_DEBUG_CONNECTION)) { | |
1370 r->connection->log->log_level = clcf->err_log->log_level; | |
1337 } | 1371 } |
1338 | 1372 |
1339 return NGX_OK; | 1373 return NGX_OK; |
1340 } | 1374 } |
1341 | 1375 |
1342 | 1376 |
1377 static void | |
1378 ngx_http_request_handler(ngx_event_t *ev) | |
1379 { | |
1380 ngx_connection_t *c; | |
1381 ngx_http_request_t *r; | |
1382 | |
1383 c = ev->data; | |
1384 r = c->data; | |
1385 | |
1386 if (ev->write) { | |
1387 r->write_event_handler(r); | |
1388 | |
1389 } else { | |
1390 r->read_event_handler(r); | |
1391 } | |
1392 } | |
1393 | |
1394 | |
1343 void | 1395 void |
1344 ngx_http_finalize_request(ngx_http_request_t *r, int rc) | 1396 ngx_http_finalize_request(ngx_http_request_t *r, ngx_int_t rc) |
1345 { | 1397 { |
1398 ngx_http_request_t *pr; | |
1346 ngx_http_core_loc_conf_t *clcf; | 1399 ngx_http_core_loc_conf_t *clcf; |
1347 | 1400 |
1348 /* r may be already destroyed when rc == NGX_DONE */ | 1401 if (rc == NGX_DONE) { |
1349 | 1402 /* r may be already destroyed when rc == NGX_DONE */ |
1350 if (rc == NGX_DONE || r->main) { | 1403 return; |
1351 return; | 1404 } |
1352 } | 1405 |
1353 | 1406 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, |
1354 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, | 1407 "http finalize request: %d, \"%V\"", rc, &r->uri); |
1355 "http finalize request: %d", rc); | 1408 |
1409 if (r->parent && rc >= NGX_HTTP_SPECIAL_RESPONSE) { | |
1410 ngx_http_finalize_request(r, ngx_http_special_response_handler(r, rc)); | |
1411 return; | |
1412 } | |
1413 | |
1414 if (r->parent || rc == NGX_AGAIN) { | |
1415 r->write_event_handler = ngx_http_writer; | |
1416 } | |
1417 | |
1418 r->done = 1; | |
1419 | |
1420 if (r != r->connection->data) { | |
1421 return; | |
1422 } | |
1423 | |
1424 if (r->parent) { | |
1425 | |
1426 pr = r->parent; | |
1427 | |
1428 if (rc != NGX_AGAIN) { | |
1429 pr->connection->data = pr; | |
1430 } | |
1431 | |
1432 if (pr->postponed) { | |
1433 | |
1434 if (rc != NGX_AGAIN && pr->postponed->request == r) { | |
1435 pr->postponed = pr->postponed->next; | |
1436 | |
1437 if (pr->postponed == NULL) { | |
1438 return; | |
1439 } | |
1440 } | |
1441 | |
1442 if (pr->done) { | |
1443 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, | |
1444 "http wake request: \"%V\"", &pr->uri); | |
1445 | |
1446 pr->write_event_handler(pr); | |
1447 } | |
1448 } | |
1449 | |
1450 return; | |
1451 } | |
1356 | 1452 |
1357 if (rc >= NGX_HTTP_SPECIAL_RESPONSE) { | 1453 if (rc >= NGX_HTTP_SPECIAL_RESPONSE) { |
1358 | 1454 |
1359 if (r->connection->read->timer_set) { | 1455 if (r->connection->read->timer_set) { |
1360 ngx_del_timer(r->connection->read); | 1456 ngx_del_timer(r->connection->read); |
1377 } else if (rc == NGX_ERROR) { | 1473 } else if (rc == NGX_ERROR) { |
1378 ngx_http_close_request(r, 0); | 1474 ngx_http_close_request(r, 0); |
1379 ngx_http_close_connection(r->connection); | 1475 ngx_http_close_connection(r->connection); |
1380 return; | 1476 return; |
1381 | 1477 |
1382 } else if (rc == NGX_AGAIN) { | 1478 } else if (rc == NGX_AGAIN || r->out) { |
1383 ngx_http_set_write_handler(r); | 1479 ngx_http_set_write_handler(r); |
1384 return; | 1480 return; |
1385 } | 1481 } |
1386 | 1482 |
1387 if (r->connection->read->timer_set) { | 1483 if (r->connection->read->timer_set) { |
1428 ngx_http_set_write_handler(ngx_http_request_t *r) | 1524 ngx_http_set_write_handler(ngx_http_request_t *r) |
1429 { | 1525 { |
1430 ngx_event_t *wev; | 1526 ngx_event_t *wev; |
1431 ngx_http_core_loc_conf_t *clcf; | 1527 ngx_http_core_loc_conf_t *clcf; |
1432 | 1528 |
1529 r->http_state = NGX_HTTP_WRITING_REQUEST_STATE; | |
1530 | |
1433 wev = r->connection->write; | 1531 wev = r->connection->write; |
1434 wev->event_handler = ngx_http_writer; | |
1435 | |
1436 r->http_state = NGX_HTTP_WRITING_REQUEST_STATE; | |
1437 | 1532 |
1438 if (wev->ready && wev->delayed) { | 1533 if (wev->ready && wev->delayed) { |
1439 return; | 1534 return; |
1440 } | 1535 } |
1441 | 1536 |
1442 clcf = ngx_http_get_module_loc_conf(r->main ? r->main : r, | 1537 clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); |
1443 ngx_http_core_module); | |
1444 if (!wev->delayed) { | 1538 if (!wev->delayed) { |
1445 ngx_add_timer(wev, clcf->send_timeout); | 1539 ngx_add_timer(wev, clcf->send_timeout); |
1446 } | 1540 } |
1447 | 1541 |
1448 if (ngx_handle_write_event(wev, clcf->send_lowat) == NGX_ERROR) { | 1542 if (ngx_handle_write_event(wev, clcf->send_lowat) == NGX_ERROR) { |
1449 ngx_http_close_request(r, 0); | 1543 ngx_http_close_request(r, 0); |
1450 ngx_http_close_connection(r->connection); | 1544 ngx_http_close_connection(r->connection); |
1451 } | 1545 } |
1452 | 1546 } |
1453 return; | 1547 |
1454 } | 1548 |
1455 | 1549 static void |
1456 | 1550 ngx_http_writer(ngx_http_request_t *r) |
1457 void | |
1458 ngx_http_writer(ngx_event_t *wev) | |
1459 { | 1551 { |
1460 int rc; | 1552 int rc; |
1553 ngx_event_t *wev; | |
1461 ngx_connection_t *c; | 1554 ngx_connection_t *c; |
1462 ngx_http_request_t *r; | |
1463 ngx_http_core_loc_conf_t *clcf; | 1555 ngx_http_core_loc_conf_t *clcf; |
1464 | 1556 |
1465 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, wev->log, 0, "http writer handler"); | 1557 c = r->connection; |
1466 | 1558 wev = c->write; |
1467 c = wev->data; | 1559 |
1468 r = c->data; | 1560 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, wev->log, 0, |
1561 "http writer handler: \"%V\"", &r->uri); | |
1469 | 1562 |
1470 if (wev->timedout) { | 1563 if (wev->timedout) { |
1471 if (!wev->delayed) { | 1564 if (!wev->delayed) { |
1472 ngx_log_error(NGX_LOG_INFO, c->log, NGX_ETIMEDOUT, | 1565 ngx_log_error(NGX_LOG_INFO, c->log, NGX_ETIMEDOUT, |
1473 "client timed out"); | 1566 "client timed out"); |
1508 | 1601 |
1509 return; | 1602 return; |
1510 } | 1603 } |
1511 } | 1604 } |
1512 | 1605 |
1513 rc = ngx_http_output_filter(r, NULL); | 1606 if (r->postponed) { |
1514 | 1607 rc = ngx_http_postponed_handler(r); |
1515 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0, | 1608 |
1516 "http writer output filter: %d", rc); | 1609 if (rc == NGX_DONE) { |
1610 /* r may be already destroyed when rc == NGX_DONE */ | |
1611 return; | |
1612 } | |
1613 | |
1614 } else { | |
1615 rc = ngx_http_output_filter(r, NULL); | |
1616 | |
1617 } | |
1618 | |
1619 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0, | |
1620 "http writer output filter: %d, \"%V\"", rc, &r->uri); | |
1517 | 1621 |
1518 if (rc == NGX_AGAIN) { | 1622 if (rc == NGX_AGAIN) { |
1519 clcf = ngx_http_get_module_loc_conf(r->main ? r->main : r, | 1623 clcf = ngx_http_get_module_loc_conf(r->main ? r->main : r, |
1520 ngx_http_core_module); | 1624 ngx_http_core_module); |
1521 if (!wev->ready && !wev->delayed) { | 1625 if (!wev->ready && !wev->delayed) { |
1528 } | 1632 } |
1529 | 1633 |
1530 return; | 1634 return; |
1531 } | 1635 } |
1532 | 1636 |
1533 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "http writer done"); | 1637 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, wev->log, 0, |
1638 "http writer done: \"%V\"", &r->uri); | |
1534 | 1639 |
1535 ngx_http_finalize_request(r, rc); | 1640 ngx_http_finalize_request(r, rc); |
1536 } | 1641 } |
1537 | 1642 |
1538 | 1643 |
1644 static ngx_int_t | |
1645 ngx_http_postponed_handler(ngx_http_request_t *r) | |
1646 { | |
1647 ngx_int_t rc; | |
1648 ngx_http_postponed_request_t *pr; | |
1649 | |
1650 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, | |
1651 "http postpone handler \"%V\"", &r->uri); | |
1652 | |
1653 pr = r->postponed; | |
1654 | |
1655 if (pr->request == NULL) { | |
1656 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, | |
1657 "http postponed data \"%V\" %p", &r->uri, pr->out); | |
1658 | |
1659 rc = ngx_http_output_filter(r, NULL); | |
1660 | |
1661 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, | |
1662 "http postponed output filter: %d", rc); | |
1663 | |
1664 if (rc == NGX_AGAIN) { | |
1665 return rc; | |
1666 } | |
1667 | |
1668 if (rc == NGX_ERROR) { | |
1669 /* NGX_ERROR may be returned by any filter */ | |
1670 r->connection->write->error = 1; | |
1671 | |
1672 ngx_http_finalize_request(r, rc); | |
1673 | |
1674 return NGX_DONE; | |
1675 } | |
1676 | |
1677 pr = r->postponed; | |
1678 | |
1679 if (pr == NULL) { | |
1680 return NGX_OK; | |
1681 } | |
1682 } | |
1683 | |
1684 r = pr->request; | |
1685 r->connection->data = r; | |
1686 | |
1687 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, | |
1688 "http postponed request \"%V\"", &r->uri); | |
1689 | |
1690 r->write_event_handler(r); | |
1691 | |
1692 return NGX_DONE; | |
1693 } | |
1694 | |
1695 | |
1539 static void | 1696 static void |
1540 ngx_http_block_read(ngx_event_t *rev) | 1697 ngx_http_block_read(ngx_http_request_t *r) |
1541 { | 1698 { |
1542 ngx_connection_t *c; | 1699 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, |
1543 ngx_http_request_t *r; | 1700 "http read blocked"); |
1544 | |
1545 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, rev->log, 0, "http read blocked"); | |
1546 | 1701 |
1547 /* aio does not call this handler */ | 1702 /* aio does not call this handler */ |
1548 | 1703 |
1549 if ((ngx_event_flags & NGX_USE_LEVEL_EVENT) && rev->active) { | 1704 if ((ngx_event_flags & NGX_USE_LEVEL_EVENT) |
1550 if (ngx_del_event(rev, NGX_READ_EVENT, 0) == NGX_ERROR) { | 1705 && r->connection->read->active) |
1551 c = rev->data; | 1706 { |
1552 r = c->data; | 1707 if (ngx_del_event(r->connection->read, NGX_READ_EVENT, 0) |
1708 == NGX_ERROR) | |
1709 { | |
1553 ngx_http_close_request(r, 0); | 1710 ngx_http_close_request(r, 0); |
1554 ngx_http_close_connection(c); | 1711 ngx_http_close_connection(r->connection); |
1555 } | 1712 } |
1556 } | 1713 } |
1557 } | 1714 } |
1558 | 1715 |
1559 | 1716 |
1586 r->headers_in.content_length_n = 0; | 1743 r->headers_in.content_length_n = 0; |
1587 return NGX_OK; | 1744 return NGX_OK; |
1588 } | 1745 } |
1589 } | 1746 } |
1590 | 1747 |
1591 rev->event_handler = ngx_http_read_discarded_body_event; | 1748 r->read_event_handler = ngx_http_read_discarded_body_handler; |
1592 | 1749 |
1593 if (ngx_handle_level_read_event(rev) == NGX_ERROR) { | 1750 if (ngx_handle_read_event(rev, 0) == NGX_ERROR) { |
1594 return NGX_HTTP_INTERNAL_SERVER_ERROR; | 1751 return NGX_HTTP_INTERNAL_SERVER_ERROR; |
1595 } | 1752 } |
1596 | 1753 |
1597 return ngx_http_read_discarded_body(r); | 1754 return ngx_http_read_discarded_body(r); |
1598 } | 1755 } |
1599 | 1756 |
1600 | 1757 |
1601 static void | 1758 static void |
1602 ngx_http_read_discarded_body_event(ngx_event_t *rev) | 1759 ngx_http_read_discarded_body_handler(ngx_http_request_t *r) |
1603 { | 1760 { |
1604 ngx_int_t rc; | 1761 ngx_int_t rc; |
1605 ngx_connection_t *c; | |
1606 ngx_http_request_t *r; | |
1607 | |
1608 c = rev->data; | |
1609 r = c->data; | |
1610 | 1762 |
1611 rc = ngx_http_read_discarded_body(r); | 1763 rc = ngx_http_read_discarded_body(r); |
1612 | 1764 |
1613 if (rc == NGX_AGAIN) { | 1765 if (rc == NGX_AGAIN) { |
1614 if (ngx_handle_level_read_event(rev) == NGX_ERROR) { | 1766 if (ngx_handle_read_event(r->connection->read, 0) == NGX_ERROR) { |
1615 ngx_http_close_request(r, rc); | 1767 ngx_http_close_request(r, rc); |
1616 ngx_http_close_connection(c); | 1768 ngx_http_close_connection(r->connection); |
1617 return; | 1769 return; |
1618 } | 1770 } |
1619 } | 1771 } |
1620 | 1772 |
1621 if (rc != NGX_OK) { | 1773 if (rc != NGX_OK) { |
1622 ngx_http_close_request(r, rc); | 1774 ngx_http_close_request(r, rc); |
1623 ngx_http_close_connection(c); | 1775 ngx_http_close_connection(r->connection); |
1624 } | 1776 } |
1625 } | 1777 } |
1626 | 1778 |
1627 | 1779 |
1628 static ngx_int_t | 1780 static ngx_int_t |
1735 ngx_http_close_request(r, 0); | 1887 ngx_http_close_request(r, 0); |
1736 c->data = hc; | 1888 c->data = hc; |
1737 | 1889 |
1738 ngx_add_timer(rev, clcf->keepalive_timeout); | 1890 ngx_add_timer(rev, clcf->keepalive_timeout); |
1739 | 1891 |
1740 if (ngx_handle_level_read_event(rev) == NGX_ERROR) { | 1892 if (ngx_handle_read_event(rev, 0) == NGX_ERROR) { |
1741 ngx_http_close_connection(c); | 1893 ngx_http_close_connection(c); |
1742 return; | 1894 return; |
1743 } | 1895 } |
1744 | 1896 |
1745 wev = c->write; | 1897 wev = c->write; |
1746 wev->event_handler = ngx_http_empty_handler; | 1898 wev->handler = ngx_http_empty_handler; |
1747 | 1899 |
1748 if (b->pos < b->last) { | 1900 if (b->pos < b->last) { |
1749 | 1901 |
1750 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "pipelined request"); | 1902 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "pipelined request"); |
1751 | 1903 |
1807 } | 1959 } |
1808 | 1960 |
1809 hc->nbusy = 0; | 1961 hc->nbusy = 0; |
1810 } | 1962 } |
1811 | 1963 |
1812 rev->event_handler = ngx_http_keepalive_handler; | 1964 rev->handler = ngx_http_keepalive_handler; |
1813 | 1965 |
1814 if (wev->active) { | 1966 if (wev->active) { |
1815 if (ngx_event_flags & NGX_USE_KQUEUE_EVENT) { | 1967 if (ngx_event_flags & NGX_USE_KQUEUE_EVENT) { |
1816 if (ngx_del_event(wev, NGX_WRITE_EVENT, NGX_DISABLE_EVENT) | 1968 if (ngx_del_event(wev, NGX_WRITE_EVENT, NGX_DISABLE_EVENT) |
1817 == NGX_ERROR) | 1969 == NGX_ERROR) |
1942 | 2094 |
1943 n = c->recv(c, b->last, size); | 2095 n = c->recv(c, b->last, size); |
1944 c->log_error = NGX_ERROR_INFO; | 2096 c->log_error = NGX_ERROR_INFO; |
1945 | 2097 |
1946 if (n == NGX_AGAIN) { | 2098 if (n == NGX_AGAIN) { |
1947 if (ngx_handle_level_read_event(rev) == NGX_ERROR) { | 2099 if (ngx_handle_read_event(rev, 0) == NGX_ERROR) { |
1948 ngx_http_close_connection(c); | 2100 ngx_http_close_connection(c); |
1949 } | 2101 } |
1950 | 2102 |
1951 return; | 2103 return; |
1952 } | 2104 } |
1984 c = r->connection; | 2136 c = r->connection; |
1985 | 2137 |
1986 clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); | 2138 clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); |
1987 | 2139 |
1988 rev = c->read; | 2140 rev = c->read; |
1989 rev->event_handler = ngx_http_lingering_close_handler; | 2141 rev->handler = ngx_http_lingering_close_handler; |
1990 | 2142 |
1991 r->lingering_time = ngx_time() + clcf->lingering_time / 1000; | 2143 r->lingering_time = ngx_time() + clcf->lingering_time / 1000; |
1992 ngx_add_timer(rev, clcf->lingering_timeout); | 2144 ngx_add_timer(rev, clcf->lingering_timeout); |
1993 | 2145 |
1994 if (ngx_handle_level_read_event(rev) == NGX_ERROR) { | 2146 if (ngx_handle_read_event(rev, 0) == NGX_ERROR) { |
1995 ngx_http_close_request(r, 0); | 2147 ngx_http_close_request(r, 0); |
1996 ngx_http_close_connection(c); | 2148 ngx_http_close_connection(c); |
1997 return; | 2149 return; |
1998 } | 2150 } |
1999 | 2151 |
2000 wev = c->write; | 2152 wev = c->write; |
2001 wev->event_handler = ngx_http_empty_handler; | 2153 wev->handler = ngx_http_empty_handler; |
2002 | 2154 |
2003 if (wev->active) { | 2155 if (wev->active) { |
2004 if (ngx_event_flags & NGX_USE_KQUEUE_EVENT) { | 2156 if (ngx_event_flags & NGX_USE_KQUEUE_EVENT) { |
2005 if (ngx_del_event(wev, NGX_WRITE_EVENT, NGX_DISABLE_EVENT) | 2157 if (ngx_del_event(wev, NGX_WRITE_EVENT, NGX_DISABLE_EVENT) |
2006 == NGX_ERROR) | 2158 == NGX_ERROR) |
2073 return; | 2225 return; |
2074 } | 2226 } |
2075 | 2227 |
2076 } while (rev->ready); | 2228 } while (rev->ready); |
2077 | 2229 |
2078 if (ngx_handle_level_read_event(rev) == NGX_ERROR) { | 2230 if (ngx_handle_read_event(rev, 0) == NGX_ERROR) { |
2079 ngx_http_close_request(r, 0); | 2231 ngx_http_close_request(r, 0); |
2080 ngx_http_close_connection(c); | 2232 ngx_http_close_connection(c); |
2081 return; | 2233 return; |
2082 } | 2234 } |
2083 | 2235 |
2095 | 2247 |
2096 void | 2248 void |
2097 ngx_http_empty_handler(ngx_event_t *wev) | 2249 ngx_http_empty_handler(ngx_event_t *wev) |
2098 { | 2250 { |
2099 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, wev->log, 0, "http empty handler"); | 2251 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, wev->log, 0, "http empty handler"); |
2252 | |
2253 return; | |
2254 } | |
2255 | |
2256 | |
2257 void | |
2258 ngx_http_request_empty_handler(ngx_http_request_t *r) | |
2259 { | |
2260 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, | |
2261 "http requets empty handler"); | |
2100 | 2262 |
2101 return; | 2263 return; |
2102 } | 2264 } |
2103 | 2265 |
2104 | 2266 |
2120 return ngx_http_output_filter(r, &out); | 2282 return ngx_http_output_filter(r, &out); |
2121 } | 2283 } |
2122 | 2284 |
2123 | 2285 |
2124 void | 2286 void |
2125 ngx_http_close_request(ngx_http_request_t *r, int error) | 2287 ngx_http_close_request(ngx_http_request_t *r, ngx_int_t error) |
2126 { | 2288 { |
2127 ngx_uint_t i; | |
2128 ngx_log_t *log; | 2289 ngx_log_t *log; |
2290 struct linger linger; | |
2129 ngx_http_log_ctx_t *ctx; | 2291 ngx_http_log_ctx_t *ctx; |
2130 ngx_http_cleanup_t *cleanup; | |
2131 ngx_http_core_loc_conf_t *clcf; | 2292 ngx_http_core_loc_conf_t *clcf; |
2132 struct linger l; | |
2133 | 2293 |
2134 log = r->connection->log; | 2294 log = r->connection->log; |
2135 | 2295 |
2136 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, log, 0, "http close request"); | 2296 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, log, 0, "http close request"); |
2137 | 2297 |
2155 r->headers_out.status = error; | 2315 r->headers_out.status = error; |
2156 } | 2316 } |
2157 | 2317 |
2158 ngx_http_log_handler(r); | 2318 ngx_http_log_handler(r); |
2159 | 2319 |
2160 cleanup = r->cleanup.elts; | |
2161 for (i = 0; i < r->cleanup.nelts; i++) { | |
2162 if (!cleanup[i].valid) { | |
2163 continue; | |
2164 } | |
2165 | |
2166 #if (NGX_HTTP_CACHE) | |
2167 | |
2168 if (cleanup[i].cache) { | |
2169 ngx_http_cache_unlock(cleanup[i].data.cache.hash, | |
2170 cleanup[i].data.cache.cache, log); | |
2171 continue; | |
2172 } | |
2173 | |
2174 #endif | |
2175 | |
2176 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, log, 0, "http cleanup fd: %d", | |
2177 cleanup[i].data.file.fd); | |
2178 | |
2179 if (ngx_close_file(cleanup[i].data.file.fd) == NGX_FILE_ERROR) { | |
2180 ngx_log_error(NGX_LOG_ALERT, log, ngx_errno, | |
2181 ngx_close_file_n " \"%s\" failed", | |
2182 cleanup[i].data.file.name); | |
2183 } | |
2184 } | |
2185 | |
2186 /* STUB */ | |
2187 if (r->file.fd != NGX_INVALID_FILE) { | |
2188 if (ngx_close_file(r->file.fd) == NGX_FILE_ERROR) { | |
2189 ngx_log_error(NGX_LOG_ALERT, log, ngx_errno, | |
2190 ngx_close_file_n " \"%V\" failed", &r->file.name); | |
2191 } | |
2192 } | |
2193 | |
2194 if (r->request_body | |
2195 && r->request_body->temp_file | |
2196 && r->request_body->temp_file->file.fd != NGX_INVALID_FILE) | |
2197 { | |
2198 if (ngx_close_file(r->request_body->temp_file->file.fd) | |
2199 == NGX_FILE_ERROR) | |
2200 { | |
2201 ngx_log_error(NGX_LOG_ALERT, log, ngx_errno, | |
2202 ngx_close_file_n " deleted file \"%V\" failed", | |
2203 &r->request_body->temp_file->file.name); | |
2204 } | |
2205 } | |
2206 | |
2207 if (r->connection->timedout) { | 2320 if (r->connection->timedout) { |
2208 clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); | 2321 clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); |
2209 | 2322 |
2210 if (clcf->reset_timedout_connection) { | 2323 if (clcf->reset_timedout_connection) { |
2211 l.l_onoff = 1; | 2324 linger.l_onoff = 1; |
2212 l.l_linger = 0; | 2325 linger.l_linger = 0; |
2213 | 2326 |
2214 if (setsockopt(r->connection->fd, SOL_SOCKET, SO_LINGER, | 2327 if (setsockopt(r->connection->fd, SOL_SOCKET, SO_LINGER, |
2215 (const void *) &l, sizeof(struct linger)) == -1) | 2328 (const void *) &linger, sizeof(struct linger)) == -1) |
2216 { | 2329 { |
2217 ngx_log_error(NGX_LOG_ALERT, log, ngx_socket_errno, | 2330 ngx_log_error(NGX_LOG_ALERT, log, ngx_socket_errno, |
2218 "setsockopt(SO_LINGER) failed"); | 2331 "setsockopt(SO_LINGER) failed"); |
2219 } | 2332 } |
2220 } | 2333 } |
2221 } | 2334 } |
2222 | 2335 |
2223 /* the variuos request strings were allocated from r->pool */ | 2336 /* the various request strings were allocated from r->pool */ |
2224 ctx = log->data; | 2337 ctx = log->data; |
2225 ctx->request = NULL; | 2338 ctx->request = NULL; |
2226 | 2339 |
2227 r->request_line.len = 0; | 2340 r->request_line.len = 0; |
2228 | 2341 |
2261 | 2374 |
2262 #if (NGX_OPENSSL) | 2375 #if (NGX_OPENSSL) |
2263 | 2376 |
2264 if (c->ssl) { | 2377 if (c->ssl) { |
2265 if (ngx_ssl_shutdown(c) == NGX_AGAIN) { | 2378 if (ngx_ssl_shutdown(c) == NGX_AGAIN) { |
2266 c->read->event_handler = ngx_ssl_close_handler; | 2379 c->read->handler = ngx_ssl_close_handler; |
2267 c->write->event_handler = ngx_ssl_close_handler; | 2380 c->write->handler = ngx_ssl_close_handler; |
2268 return; | 2381 return; |
2269 } | 2382 } |
2270 } | 2383 } |
2271 | 2384 |
2272 #endif | 2385 #endif |
2288 { | 2401 { |
2289 u_char *p; | 2402 u_char *p; |
2290 ngx_http_request_t *r; | 2403 ngx_http_request_t *r; |
2291 ngx_http_log_ctx_t *ctx; | 2404 ngx_http_log_ctx_t *ctx; |
2292 | 2405 |
2293 p = buf; | |
2294 | |
2295 ctx = log->data; | |
2296 | |
2297 if (log->action) { | 2406 if (log->action) { |
2298 p = ngx_snprintf(p, len, " while %s", log->action); | 2407 p = ngx_snprintf(buf, len, " while %s", log->action); |
2299 len -= p - buf; | 2408 len -= p - buf; |
2300 buf = p; | 2409 buf = p; |
2301 } | 2410 } |
2302 | 2411 |
2412 ctx = log->data; | |
2413 | |
2303 p = ngx_snprintf(buf, len, ", client: %V", ctx->client); | 2414 p = ngx_snprintf(buf, len, ", client: %V", ctx->client); |
2415 len -= p - buf; | |
2304 | 2416 |
2305 r = ctx->request; | 2417 r = ctx->request; |
2306 | 2418 |
2307 if (r == NULL) { | 2419 if (r) { |
2308 return p; | 2420 return r->log_handler(r, p, len); |
2309 } | 2421 } |
2310 | 2422 |
2311 len -= p - buf; | 2423 return p; |
2312 buf = p; | 2424 } |
2425 | |
2426 | |
2427 static u_char * | |
2428 ngx_http_log_error_handler(ngx_http_request_t *r, u_char *buf, size_t len) | |
2429 { | |
2430 u_char *p; | |
2313 | 2431 |
2314 if (r->server_name.data) { | 2432 if (r->server_name.data) { |
2315 p = ngx_snprintf(buf, len, ", server: %V", &r->server_name); | 2433 p = ngx_snprintf(buf, len, ", server: %V", &r->server_name); |
2316 len -= p - buf; | 2434 len -= p - buf; |
2317 buf = p; | 2435 buf = p; |