Mercurial > hg > nginx
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); |