comparison src/http/ngx_http_event.c @ 96:a23d010f356d

nginx-0.0.1-2003-05-27-16:18:54 import
author Igor Sysoev <igor@sysoev.ru>
date Tue, 27 May 2003 12:18:54 +0000
parents b48066122884
children a059e1aa65d4
comparison
equal deleted inserted replaced
95:b48066122884 96:a23d010f356d
73 }; 73 };
74 74
75 75
76 void ngx_http_init_connection(ngx_connection_t *c) 76 void ngx_http_init_connection(ngx_connection_t *c)
77 { 77 {
78 int event; 78 int event;
79 ngx_event_t *rev; 79 ngx_event_t *rev;
80 ngx_http_log_ctx_t *lcx; 80 ngx_http_log_ctx_t *lcx;
81 ngx_http_conf_ctx_t *ctx;
82 81
83 c->addr_text.data = ngx_palloc(c->pool, c->addr_text_max_len); 82 c->addr_text.data = ngx_palloc(c->pool, c->addr_text_max_len);
84 if (c->addr_text.data == NULL) { 83 if (c->addr_text.data == NULL) {
85 ngx_http_close_connection(c); 84 ngx_http_close_connection(c);
86 return; 85 return;
137 } 136 }
138 137
139 138
140 static void ngx_http_init_request(ngx_event_t *rev) 139 static void ngx_http_init_request(ngx_event_t *rev)
141 { 140 {
141 int i;
142 socklen_t len;
143 struct sockaddr_in addr_in;
142 ngx_connection_t *c; 144 ngx_connection_t *c;
143 ngx_http_request_t *r; 145 ngx_http_request_t *r;
144 ngx_http_conf_ctx_t *ctx; 146 ngx_http_in_port_t *in_port;
147 ngx_http_in_addr_t *in_addr;
148 ngx_http_server_name_t *server_name;
145 ngx_http_core_srv_conf_t *cscf; 149 ngx_http_core_srv_conf_t *cscf;
146 150
147 c = rev->data; 151 c = rev->data;
148 ctx = c->ctx; 152
149 153 r = ngx_pcalloc(c->pool, sizeof(ngx_http_request_t));
150 cscf = ngx_http_get_module_srv_conf(ctx, ngx_http_core_module_ctx); 154 if (r == NULL) {
151 cscf = ngx_http_get_module_srv_conf(cscf->ctx, ngx_http_core_module_ctx); 155 ngx_http_close_connection(c);
156 return;
157 }
158
159 /* find the server configuration for the address:port */
160
161 /* AF_INET only */
162
163 in_port = c->servers;
164 in_addr = in_port->addrs.elts;
165
166 r->port = in_port->port;
167 r->port_name = &in_port->port_name;
168
169 i = 0;
170
171 if (in_port->addrs.nelts > 1) {
172
173 /* there're the several addresses on this port and one of them
174 is "*:port" so getsockname() is needed to determine
175 the server address */
176
177 /* TODO: AcceptEx() already gave this sockaddr_in */
178
179 len = sizeof(struct sockaddr_in);
180 if (getsockname(c->fd, (struct sockaddr *) &addr_in, &len) == -1) {
181 ngx_log_error(NGX_LOG_CRIT, rev->log, ngx_socket_errno,
182 "getsockname() failed");
183 ngx_http_close_connection(c);
184 return;
185 }
186
187 r->in_addr = addr_in.sin_addr.s_addr;
188
189 /* the last in_port->addrs address is "*" */
190
191 for ( /* void */ ; i < in_port->addrs.nelts - 1; i++) {
192 if (in_addr[i].addr == r->in_addr) {
193 break;
194 }
195 }
196
197 } else {
198 r->in_addr = in_addr[0].addr;
199 }
200
201 r->virtual_names = &in_addr[i].names;
202
203 /* the default server configuration for the address:port */
204 cscf = in_addr[i].core_srv_conf;
205
206 r->main_conf = cscf->ctx->main_conf;
207 r->srv_conf = cscf->ctx->srv_conf;
208 r->loc_conf = cscf->ctx->loc_conf;
209
210 server_name = cscf->server_names.elts;
211 r->server_name = &server_name->name;
152 212
153 if (c->buffer == NULL) { 213 if (c->buffer == NULL) {
154 c->buffer = ngx_create_temp_hunk(c->pool, 214 c->buffer = ngx_create_temp_hunk(c->pool,
155 cscf->client_header_buffer_size, 215 cscf->client_header_buffer_size,
156 0, 0); 216 0, 0);
158 ngx_http_close_connection(c); 218 ngx_http_close_connection(c);
159 return; 219 return;
160 } 220 }
161 } 221 }
162 222
163 r = ngx_pcalloc(c->pool, sizeof(ngx_http_request_t));
164 if (r == NULL) {
165 ngx_http_close_connection(c);
166 return;
167 }
168
169 r->pool = ngx_create_pool(cscf->request_pool_size, c->log); 223 r->pool = ngx_create_pool(cscf->request_pool_size, c->log);
170 if (r->pool == NULL) { 224 if (r->pool == NULL) {
171 ngx_http_close_connection(c); 225 ngx_http_close_connection(c);
172 return; 226 return;
173 } 227 }
183 if (r->ctx == NULL) { 237 if (r->ctx == NULL) {
184 ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR); 238 ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
185 ngx_http_close_connection(c); 239 ngx_http_close_connection(c);
186 return; 240 return;
187 } 241 }
188
189 r->main_conf = ctx->main_conf;
190 r->srv_conf = ctx->srv_conf;
191 r->loc_conf = ctx->loc_conf;
192 242
193 c->sent = 0; 243 c->sent = 0;
194 c->data = r; 244 c->data = r;
195 r->connection = c; 245 r->connection = c;
196 r->pipeline = c->pipeline; 246 r->pipeline = c->pipeline;
237 287
238 if (rc == NGX_OK) { 288 if (rc == NGX_OK) {
239 289
240 /* the request line has been parsed successfully */ 290 /* the request line has been parsed successfully */
241 291
242 cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module_ctx); 292 cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module);
243 293
244 if (r->http_version >= NGX_HTTP_VERSION_10 294 if (r->http_version >= NGX_HTTP_VERSION_10
245 && cscf->large_client_header == 0 295 && cscf->large_client_header == 0
246 && r->header_in->pos == r->header_in->end) 296 && r->header_in->pos == r->header_in->end)
247 { 297 {
267 return; 317 return;
268 } 318 }
269 319
270 ngx_cpystrn(r->uri.data, r->uri_start, r->uri.len + 1); 320 ngx_cpystrn(r->uri.data, r->uri_start, r->uri.len + 1);
271 321
272 #if 1 /* needed to log url on errors in proxy only ? */ 322 #if 1 /* THINK: needed to log url on errors in proxy only ? */
273 323
274 /* copy unparsed URI */ 324 /* copy unparsed URI */
275 325
276 r->unparsed_uri.len = r->uri_end - r->uri_start; 326 r->unparsed_uri.len = r->uri_end - r->uri_start;
277 r->unparsed_uri.data = ngx_palloc(r->pool, r->unparsed_uri.len + 1); 327 r->unparsed_uri.data = ngx_palloc(r->pool, r->unparsed_uri.len + 1);
351 if (r->exten.data[0] == '\0') { r->exten.data = NULL; } 401 if (r->exten.data[0] == '\0') { r->exten.data = NULL; }
352 if (r->args.data[0] == '\0') { r->args.data = NULL; } 402 if (r->args.data[0] == '\0') { r->args.data = NULL; }
353 #endif 403 #endif
354 404
355 if (r->http_version == NGX_HTTP_VERSION_9) { 405 if (r->http_version == NGX_HTTP_VERSION_9) {
356 if (ngx_http_find_server_conf(r) == NGX_ERROR) {
357 ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
358 ngx_http_close_connection(c);
359 return;
360 }
361
362 rev->event_handler = ngx_http_block_read; 406 rev->event_handler = ngx_http_block_read;
363 ngx_http_handler(r); 407 ngx_http_handler(r);
364 return; 408 return;
365 } 409 }
366 410
398 then we need to copy it to the start of the r->header_in hunk. 442 then we need to copy it to the start of the r->header_in hunk.
399 We need to copy it here only if the large client headers 443 We need to copy it here only if the large client headers
400 are enabled otherwise a request line had been already copied 444 are enabled otherwise a request line had been already copied
401 to the start of the r->header_in hunk in ngx_http_set_keepalive() */ 445 to the start of the r->header_in hunk in ngx_http_set_keepalive() */
402 446
403 cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module_ctx); 447 cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module);
404 448
405 if (cscf->large_client_header) { 449 if (cscf->large_client_header) {
406 offset = r->request_start - r->header_in->start; 450 offset = r->request_start - r->header_in->start;
407 451
408 if (offset == 0) { 452 if (offset == 0) {
444 size_t len; 488 size_t len;
445 ssize_t n; 489 ssize_t n;
446 ngx_table_elt_t *h; 490 ngx_table_elt_t *h;
447 ngx_connection_t *c; 491 ngx_connection_t *c;
448 ngx_http_request_t *r; 492 ngx_http_request_t *r;
449 ngx_http_log_ctx_t *ctx; 493 ngx_http_server_name_t *name;
450 ngx_http_core_srv_conf_t *cscf; 494 ngx_http_core_srv_conf_t *cscf;
451 495
452 c = rev->data; 496 c = rev->data;
453 r = c->data; 497 r = c->data;
454 498
457 if (rev->timedout) { 501 if (rev->timedout) {
458 ngx_http_close_request(r, NGX_HTTP_REQUEST_TIME_OUT); 502 ngx_http_close_request(r, NGX_HTTP_REQUEST_TIME_OUT);
459 ngx_http_close_connection(c); 503 ngx_http_close_connection(c);
460 return; 504 return;
461 } 505 }
506
507 cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module);
462 508
463 rc = NGX_AGAIN; 509 rc = NGX_AGAIN;
464 510
465 for ( ;; ) { 511 for ( ;; ) {
466 if (rc == NGX_AGAIN) { 512 if (rc == NGX_AGAIN) {
487 h->key.len = r->header_name_end - r->header_name_start; 533 h->key.len = r->header_name_end - r->header_name_start;
488 h->value.len = r->header_end - r->header_start; 534 h->value.len = r->header_end - r->header_start;
489 535
490 /* if the large client headers are enabled then 536 /* if the large client headers are enabled then
491 we need to copy the header name and value */ 537 we need to copy the header name and value */
492
493 cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module_ctx);
494 538
495 if (cscf->large_client_header) { 539 if (cscf->large_client_header) {
496 h->key.data = ngx_palloc(r->pool, 540 h->key.data = ngx_palloc(r->pool,
497 h->key.len + 1 + h->value.len + 1); 541 h->key.len + 1 + h->value.len + 1);
498 if (h->key.data == NULL) { 542 if (h->key.data == NULL) {
530 && r->header_in->pos == r->header_in->last) 574 && r->header_in->pos == r->header_in->last)
531 { 575 {
532 r->header_in->pos = r->header_in->last = r->header_in->start; 576 r->header_in->pos = r->header_in->last = r->header_in->start;
533 } 577 }
534 578
579 continue;
580
535 } else if (rc == NGX_HTTP_PARSE_HEADER_DONE) { 581 } else if (rc == NGX_HTTP_PARSE_HEADER_DONE) {
536 582
537 /* a whole header has been parsed successfully */ 583 /* a whole header has been parsed successfully */
538 584
539 ngx_log_debug(r->connection->log, "HTTP header done"); 585 ngx_log_debug(r->connection->log, "HTTP header done");
543 if (r->headers_in.host->value.data[len] == ':') { 589 if (r->headers_in.host->value.data[len] == ':') {
544 break; 590 break;
545 } 591 }
546 } 592 }
547 r->headers_in.host_name_len = len; 593 r->headers_in.host_name_len = len;
594
595 /* find the name based server configuration */
596
597 name = r->virtual_names->elts;
598 for (i = 0; i < r->virtual_names->nelts; i++) {
599 if (r->headers_in.host_name_len != name[i].name.len) {
600 continue;
601 }
602
603 if (ngx_strncasecmp(r->headers_in.host->value.data,
604 name[i].name.data,
605 r->headers_in.host_name_len) == 0)
606 {
607 r->srv_conf = name[i].core_srv_conf->ctx->srv_conf;
608 r->loc_conf = name[i].core_srv_conf->ctx->loc_conf;
609 break;
610 }
611 }
548 612
549 } else { 613 } else {
550 if (r->http_version > NGX_HTTP_VERSION_10) { 614 if (r->http_version > NGX_HTTP_VERSION_10) {
551 ngx_http_header_parse_error(r, 615 ngx_http_header_parse_error(r,
552 NGX_HTTP_PARSE_NO_HOST_HEADER); 616 NGX_HTTP_PARSE_NO_HOST_HEADER);
566 ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST); 630 ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST);
567 return; 631 return;
568 } 632 }
569 } 633 }
570 634
571 if (ngx_http_find_server_conf(r) == NGX_ERROR) {
572 ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
573 ngx_http_close_connection(c);
574 return;
575 }
576
577 rev->event_handler = ngx_http_block_read; 635 rev->event_handler = ngx_http_block_read;
578 ngx_http_handler(r); 636 ngx_http_handler(r);
579 return; 637 return;
580 638
581 } else if (rc != NGX_AGAIN) { 639 } else if (rc != NGX_AGAIN) {
592 650
593 if (r->header_in->last == r->header_in->end) { 651 if (r->header_in->last == r->header_in->end) {
594 652
595 /* if the large client headers are enabled then 653 /* if the large client headers are enabled then
596 we need to compact r->header_in hunk */ 654 we need to compact r->header_in hunk */
597
598 cscf = ngx_http_get_module_main_conf(r, ngx_http_core_module_ctx);
599 655
600 if (cscf->large_client_header) { 656 if (cscf->large_client_header) {
601 offset = r->header_name_start - r->header_in->start; 657 offset = r->header_name_start - r->header_in->start;
602 658
603 if (offset == 0) { 659 if (offset == 0) {
651 ngx_del_timer(rev); 707 ngx_del_timer(rev);
652 } else { 708 } else {
653 rev->timer_set = 1; 709 rev->timer_set = 1;
654 } 710 }
655 711
656 cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module_ctx); 712 cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module);
657 713
658 ngx_add_timer(rev, cscf->client_header_timeout); 714 ngx_add_timer(rev, cscf->client_header_timeout);
659 r->header_timeout_set = 1; 715 r->header_timeout_set = 1;
660 } 716 }
661 717
756 812
757 if (wev->delayed && wev->ready) { 813 if (wev->delayed && wev->ready) {
758 return; 814 return;
759 } 815 }
760 816
761 clcf = (ngx_http_core_loc_conf_t *) 817 clcf = ngx_http_get_module_loc_conf(r->main ? r->main : r,
762 ngx_http_get_module_loc_conf(r->main ? r->main : r, 818 ngx_http_core_module);
763 ngx_http_core_module_ctx);
764 ngx_add_timer(wev, clcf->send_timeout); 819 ngx_add_timer(wev, clcf->send_timeout);
765 wev->timer_set = 1; 820 wev->timer_set = 1;
766 821
767 if (ngx_event_flags & (NGX_HAVE_AIO_EVENT|NGX_HAVE_EDGE_EVENT)) { 822 if (ngx_event_flags & (NGX_HAVE_AIO_EVENT|NGX_HAVE_EDGE_EVENT)) {
768 /* aio, iocp, epoll */ 823 /* aio, iocp, epoll */
797 { 852 {
798 int rc; 853 int rc;
799 ngx_event_t *rev; 854 ngx_event_t *rev;
800 ngx_connection_t *c; 855 ngx_connection_t *c;
801 ngx_http_request_t *r; 856 ngx_http_request_t *r;
802 ngx_http_core_loc_conf_t *lcf; 857 ngx_http_core_loc_conf_t *clcf;
803 858
804 c = (ngx_connection_t *) wev->data; 859 c = wev->data;
805 r = (ngx_http_request_t *) c->data; 860 r = c->data;
806 861
807 rc = ngx_http_output_filter(r, NULL); 862 rc = ngx_http_output_filter(r, NULL);
808 863
809 ngx_log_debug(c->log, "writer output filter: %d" _ rc); 864 ngx_log_debug(c->log, "writer output filter: %d" _ rc);
810 865
811 if (rc == NGX_AGAIN) { 866 if (rc == NGX_AGAIN) {
812 867
813 lcf = (ngx_http_core_loc_conf_t *) 868 clcf = ngx_http_get_module_loc_conf(r->main ? r->main : r,
814 ngx_http_get_module_loc_conf(r->main ? r->main : r, 869 ngx_http_core_module);
815 ngx_http_core_module_ctx);
816 if (wev->timer_set) { 870 if (wev->timer_set) {
817 ngx_del_timer(wev); 871 ngx_del_timer(wev);
818 } else { 872 } else {
819 wev->timer_set = 1; 873 wev->timer_set = 1;
820 } 874 }
821 875
822 ngx_add_timer(wev, lcf->send_timeout); 876 ngx_add_timer(wev, clcf->send_timeout);
823 877
824 return; 878 return;
825 } 879 }
826 880
827 if (rc == NGX_ERROR) { 881 if (rc == NGX_ERROR) {
939 { 993 {
940 int rc; 994 int rc;
941 ngx_connection_t *c; 995 ngx_connection_t *c;
942 ngx_http_request_t *r; 996 ngx_http_request_t *r;
943 997
944 c = (ngx_connection_t *) rev->data; 998 c = rev->data;
945 r = (ngx_http_request_t *) c->data; 999 r = c->data;
946 1000
947 rc = ngx_http_read_discarded_body(r); 1001 rc = ngx_http_read_discarded_body(r);
948 1002
949 if (rc != NGX_OK) { 1003 if (rc != NGX_OK) {
950 ngx_http_close_request(r, rc); 1004 ngx_http_close_request(r, rc);
955 1009
956 static int ngx_http_read_discarded_body(ngx_http_request_t *r) 1010 static int ngx_http_read_discarded_body(ngx_http_request_t *r)
957 { 1011 {
958 size_t size; 1012 size_t size;
959 ssize_t n; 1013 ssize_t n;
960 ngx_http_core_loc_conf_t *lcf; 1014 ngx_http_core_loc_conf_t *clcf;
961 1015
962 ngx_log_debug(r->connection->log, "http read discarded body"); 1016 ngx_log_debug(r->connection->log, "http read discarded body");
963 1017
964 lcf = (ngx_http_core_loc_conf_t *) 1018 clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
965 ngx_http_get_module_loc_conf(r, ngx_http_core_module_ctx);
966 1019
967 if (r->discarded_buffer == NULL) { 1020 if (r->discarded_buffer == NULL) {
968 r->discarded_buffer = ngx_palloc(r->pool, lcf->discarded_buffer_size); 1021 r->discarded_buffer = ngx_palloc(r->pool, clcf->discarded_buffer_size);
969 if (r->discarded_buffer == NULL) { 1022 if (r->discarded_buffer == NULL) {
970 return NGX_HTTP_INTERNAL_SERVER_ERROR; 1023 return NGX_HTTP_INTERNAL_SERVER_ERROR;
971 } 1024 }
972 } 1025 }
973 1026
974 size = r->headers_in.content_length_n; 1027 size = r->headers_in.content_length_n;
975 if (size > lcf->discarded_buffer_size) { 1028 if (size > clcf->discarded_buffer_size) {
976 size = lcf->discarded_buffer_size; 1029 size = clcf->discarded_buffer_size;
977 } 1030 }
978 1031
979 n = ngx_event_recv(r->connection, r->discarded_buffer, size); 1032 n = ngx_event_recv(r->connection, r->discarded_buffer, size);
980 if (n == NGX_ERROR) { 1033 if (n == NGX_ERROR) {
981 return NGX_HTTP_BAD_REQUEST; 1034 return NGX_HTTP_BAD_REQUEST;
999 ngx_connection_t *c; 1052 ngx_connection_t *c;
1000 ngx_http_log_ctx_t *ctx; 1053 ngx_http_log_ctx_t *ctx;
1001 ngx_http_core_srv_conf_t *cscf; 1054 ngx_http_core_srv_conf_t *cscf;
1002 ngx_http_core_loc_conf_t *clcf; 1055 ngx_http_core_loc_conf_t *clcf;
1003 1056
1004 c = (ngx_connection_t *) r->connection; 1057 c = r->connection;
1005 rev = c->read; 1058 rev = c->read;
1006 1059
1007 ngx_log_debug(c->log, "set http keepalive handler"); 1060 ngx_log_debug(c->log, "set http keepalive handler");
1008 1061
1009 ctx = (ngx_http_log_ctx_t *) c->log->data; 1062 ctx = (ngx_http_log_ctx_t *) c->log->data;
1014 ngx_del_timer(rev); 1067 ngx_del_timer(rev);
1015 } else { 1068 } else {
1016 rev->timer_set = 1; 1069 rev->timer_set = 1;
1017 } 1070 }
1018 1071
1019 clcf = (ngx_http_core_loc_conf_t *) 1072 clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
1020 ngx_http_get_module_loc_conf(r, ngx_http_core_module_ctx);
1021 1073
1022 ngx_add_timer(rev, clcf->keepalive_timeout); 1074 ngx_add_timer(rev, clcf->keepalive_timeout);
1023 1075
1024 if (rev->blocked && (ngx_event_flags & NGX_USE_LEVEL_EVENT)) { 1076 if (rev->blocked && (ngx_event_flags & NGX_USE_LEVEL_EVENT)) {
1025 if (ngx_add_event(rev, NGX_READ_EVENT, NGX_LEVEL_EVENT) == NGX_ERROR) { 1077 if (ngx_add_event(rev, NGX_READ_EVENT, NGX_LEVEL_EVENT) == NGX_ERROR) {
1043 so if the large client headers are not enabled 1095 so if the large client headers are not enabled
1044 we need to copy the data to the start of c->buffer. 1096 we need to copy the data to the start of c->buffer.
1045 This copy should be rare because clients that support 1097 This copy should be rare because clients that support
1046 pipelined requests (Mozilla 1.x, Opera 6.x) are still rare */ 1098 pipelined requests (Mozilla 1.x, Opera 6.x) are still rare */
1047 1099
1048 cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module_ctx); 1100 cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module);
1049 1101
1050 if (!cscf->large_client_header) { 1102 if (!cscf->large_client_header) {
1051 len = h->last - h->pos; 1103 len = h->last - h->pos;
1052 ngx_memcpy(h->start, h->pos, len); 1104 ngx_memcpy(h->start, h->pos, len);
1053 h->pos = h->start; 1105 h->pos = h->start;
1054 h->last = h->start + len; 1106 h->last = h->start + len;
1055 } 1107 }
1056 1108
1109 ngx_log_debug(c->log, "pipelined request");
1110
1057 c->pipeline = 1; 1111 c->pipeline = 1;
1058 ctx->action = "reading client pipelined request line"; 1112 ctx->action = "reading client pipelined request line";
1059 ngx_http_init_request(rev); 1113 ngx_http_init_request(rev);
1060 return; 1114 return;
1061 } 1115 }
1138 1192
1139 static void ngx_http_set_lingering_close(ngx_http_request_t *r) 1193 static void ngx_http_set_lingering_close(ngx_http_request_t *r)
1140 { 1194 {
1141 ngx_event_t *rev; 1195 ngx_event_t *rev;
1142 ngx_connection_t *c; 1196 ngx_connection_t *c;
1143 ngx_http_core_loc_conf_t *lcf; 1197 ngx_http_core_loc_conf_t *clcf;
1144 1198
1145 c = r->connection; 1199 c = r->connection;
1146 rev = c->read; 1200 rev = c->read;
1147 1201
1148 lcf = (ngx_http_core_loc_conf_t *) 1202 clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
1149 ngx_http_get_module_loc_conf(r, ngx_http_core_module_ctx); 1203
1150 1204 r->lingering_time = ngx_time() + clcf->lingering_time / 1000;
1151 r->lingering_time = ngx_time() + lcf->lingering_time / 1000;
1152 rev->event_handler = ngx_http_lingering_close_handler; 1205 rev->event_handler = ngx_http_lingering_close_handler;
1153 1206
1154 if (rev->timer_set) { 1207 if (rev->timer_set) {
1155 ngx_del_timer(rev); 1208 ngx_del_timer(rev);
1156 } else { 1209 } else {
1157 rev->timer_set = 1; 1210 rev->timer_set = 1;
1158 } 1211 }
1159 1212
1160 ngx_add_timer(rev, lcf->lingering_timeout); 1213 ngx_add_timer(rev, clcf->lingering_timeout);
1161 1214
1162 if (rev->blocked && (ngx_event_flags & NGX_USE_LEVEL_EVENT)) { 1215 if (rev->blocked && (ngx_event_flags & NGX_USE_LEVEL_EVENT)) {
1163 if (ngx_add_event(rev, NGX_READ_EVENT, NGX_LEVEL_EVENT) == NGX_ERROR) { 1216 if (ngx_add_event(rev, NGX_READ_EVENT, NGX_LEVEL_EVENT) == NGX_ERROR) {
1164 ngx_http_close_request(r, 0); 1217 ngx_http_close_request(r, 0);
1165 ngx_http_close_connection(c); 1218 ngx_http_close_connection(c);
1199 { 1252 {
1200 ssize_t n; 1253 ssize_t n;
1201 ngx_msec_t timer; 1254 ngx_msec_t timer;
1202 ngx_connection_t *c; 1255 ngx_connection_t *c;
1203 ngx_http_request_t *r; 1256 ngx_http_request_t *r;
1204 ngx_http_core_loc_conf_t *lcf; 1257 ngx_http_core_loc_conf_t *clcf;
1205 1258
1206 c = (ngx_connection_t *) rev->data; 1259 c = rev->data;
1207 r = (ngx_http_request_t *) c->data; 1260 r = c->data;
1208 1261
1209 ngx_log_debug(c->log, "http lingering close handler"); 1262 ngx_log_debug(c->log, "http lingering close handler");
1210 1263
1211 if (rev->timedout) { 1264 if (rev->timedout) {
1212 ngx_http_close_request(r, 0); 1265 ngx_http_close_request(r, 0);
1219 ngx_http_close_request(r, 0); 1272 ngx_http_close_request(r, 0);
1220 ngx_http_close_connection(c); 1273 ngx_http_close_connection(c);
1221 return; 1274 return;
1222 } 1275 }
1223 1276
1224 lcf = (ngx_http_core_loc_conf_t *) 1277 clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
1225 ngx_http_get_module_loc_conf(r, ngx_http_core_module_ctx);
1226 1278
1227 if (r->discarded_buffer == NULL) { 1279 if (r->discarded_buffer == NULL) {
1228 1280
1229 /* TODO: r->header_in->start (if large headers are enabled) 1281 /* TODO: r->header_in->start (if large headers are enabled)
1230 or the end of parsed header (otherwise) 1282 or the end of parsed header (otherwise)
1231 instead of r->header_in->last */ 1283 instead of r->header_in->last */
1232 1284
1233 if ((size_t)(r->header_in->end - r->header_in->last) 1285 if ((size_t)(r->header_in->end - r->header_in->last)
1234 >= lcf->discarded_buffer_size) { 1286 >= clcf->discarded_buffer_size) {
1235 r->discarded_buffer = r->header_in->last; 1287 r->discarded_buffer = r->header_in->last;
1236 1288
1237 } else { 1289 } else {
1238 r->discarded_buffer = ngx_palloc(c->pool, 1290 r->discarded_buffer = ngx_palloc(c->pool,
1239 lcf->discarded_buffer_size); 1291 clcf->discarded_buffer_size);
1240 if (r->discarded_buffer) { 1292 if (r->discarded_buffer) {
1241 ngx_http_close_request(r, 0); 1293 ngx_http_close_request(r, 0);
1242 ngx_http_close_connection(c); 1294 ngx_http_close_connection(c);
1243 return; 1295 return;
1244 } 1296 }
1245 } 1297 }
1246 } 1298 }
1247 1299
1248 do { 1300 do {
1249 n = ngx_event_recv(c, r->discarded_buffer, lcf->discarded_buffer_size); 1301 n = ngx_event_recv(c, r->discarded_buffer, clcf->discarded_buffer_size);
1250 1302
1251 ngx_log_debug(c->log, "lingering read: %d" _ n); 1303 ngx_log_debug(c->log, "lingering read: %d" _ n);
1252 1304
1253 if (n == NGX_ERROR || n == 0) { 1305 if (n == NGX_ERROR || n == 0) {
1254 ngx_http_close_request(r, 0); 1306 ngx_http_close_request(r, 0);
1257 } 1309 }
1258 1310
1259 } while (rev->ready); 1311 } while (rev->ready);
1260 1312
1261 timer *= 1000; 1313 timer *= 1000;
1262 if (timer > lcf->lingering_timeout) { 1314 if (timer > clcf->lingering_timeout) {
1263 timer = lcf->lingering_timeout; 1315 timer = clcf->lingering_timeout;
1264 } 1316 }
1265 1317
1266 if (rev->timer_set) { 1318 if (rev->timer_set) {
1267 ngx_del_timer(rev); 1319 ngx_del_timer(rev);
1268 } else { 1320 } else {
1332 if (c->write->timer_set) { 1384 if (c->write->timer_set) {
1333 ngx_del_timer(c->write); 1385 ngx_del_timer(c->write);
1334 c->write->timer_set = 0; 1386 c->write->timer_set = 0;
1335 } 1387 }
1336 1388
1337 if (1) { 1389 if (ngx_del_conn) {
1338 ngx_del_conn(c); 1390 ngx_del_conn(c);
1339 1391
1340 } else { 1392 } else {
1341 if (c->read->active) { 1393 if (c->read->active) {
1342 ngx_del_event(c->read, NGX_READ_EVENT, NGX_CLOSE_EVENT); 1394 ngx_del_event(c->read, NGX_READ_EVENT, NGX_CLOSE_EVENT);