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;