11 | 11 |
static void ngx_http_process_request_line(ngx_event_t *rev);
|
12 | 12 |
static void ngx_http_process_request_headers(ngx_event_t *rev);
|
13 | 13 |
static ssize_t ngx_http_read_request_header(ngx_http_request_t *r);
|
14 | |
static ngx_int_t ngx_http_alloc_header_buf(ngx_http_request_t *r,
|
15 | |
ngx_uint_t request_line);
|
|
14 |
static ngx_int_t ngx_http_alloc_large_header_buffer(ngx_http_request_t *r,
|
|
15 |
ngx_uint_t request_line);
|
16 | 16 |
static ngx_int_t ngx_http_process_request_header(ngx_http_request_t *r);
|
17 | 17 |
|
18 | 18 |
static void ngx_http_set_write_handler(ngx_http_request_t *r);
|
|
194 | 194 |
return;
|
195 | 195 |
}
|
196 | 196 |
|
197 | |
if (c->data) {
|
198 | |
hc = c->data;
|
199 | |
r = hc->request;
|
200 | |
|
|
197 |
hc = c->data;
|
|
198 |
|
|
199 |
if (hc == NULL) {
|
|
200 |
if (!(hc = ngx_pcalloc(c->pool, sizeof(ngx_http_connection_t)))) {
|
|
201 |
|
|
202 |
#if (NGX_STAT_STUB)
|
|
203 |
(*ngx_stat_reading)--;
|
|
204 |
#endif
|
|
205 |
|
|
206 |
ngx_http_close_connection(c);
|
|
207 |
return;
|
|
208 |
}
|
|
209 |
}
|
|
210 |
|
|
211 |
r = hc->request;
|
|
212 |
|
|
213 |
if (r) {
|
201 | 214 |
ngx_memzero(r, sizeof(ngx_http_request_t));
|
202 | 215 |
|
203 | 216 |
r->pipeline = hc->pipeline;
|
|
217 |
|
|
218 |
if (hc->nbusy) {
|
|
219 |
r->header_in = hc->busy[0];
|
|
220 |
}
|
204 | 221 |
|
205 | 222 |
#if (NGX_STAT_STUB)
|
206 | 223 |
(*ngx_stat_reading)++;
|
207 | 224 |
#endif
|
208 | 225 |
|
209 | 226 |
} else {
|
210 | |
if (!(hc = ngx_pcalloc(c->pool, sizeof(ngx_http_connection_t)))) {
|
211 | |
|
212 | |
#if (NGX_STAT_STUB)
|
213 | |
(*ngx_stat_reading)--;
|
214 | |
#endif
|
215 | |
|
216 | |
ngx_http_close_connection(c);
|
217 | |
return;
|
218 | |
}
|
219 | |
|
220 | 227 |
if (!(r = ngx_pcalloc(c->pool, sizeof(ngx_http_request_t)))) {
|
221 | 228 |
|
222 | 229 |
#if (NGX_STAT_STUB)
|
|
354 | 361 |
}
|
355 | 362 |
}
|
356 | 363 |
|
|
364 |
if (r->header_in == NULL) {
|
|
365 |
r->header_in = c->buffer;
|
|
366 |
}
|
|
367 |
|
357 | 368 |
if (!(r->pool = ngx_create_pool(cscf->request_pool_size, c->log))) {
|
358 | 369 |
ngx_http_close_connection(c);
|
359 | 370 |
return;
|
|
386 | 397 |
|
387 | 398 |
c->single_connection = 1;
|
388 | 399 |
r->connection = c;
|
389 | |
r->header_in = c->buffer;
|
390 | 400 |
|
391 | 401 |
r->file.fd = NGX_INVALID_FILE;
|
392 | 402 |
|
|
469 | 479 |
|
470 | 480 |
static void ngx_http_process_request_line(ngx_event_t *rev)
|
471 | 481 |
{
|
472 | |
u_char *p;
|
473 | |
ssize_t n;
|
474 | |
ngx_int_t rc, offset;
|
475 | |
ngx_connection_t *c;
|
476 | |
ngx_http_request_t *r;
|
477 | |
ngx_http_log_ctx_t *ctx;
|
478 | |
ngx_http_core_srv_conf_t *cscf;
|
|
482 |
u_char *p;
|
|
483 |
ssize_t n;
|
|
484 |
ngx_int_t rc, rv, offset;
|
|
485 |
ngx_connection_t *c;
|
|
486 |
ngx_http_request_t *r;
|
|
487 |
ngx_http_log_ctx_t *ctx;
|
479 | 488 |
|
480 | 489 |
c = rev->data;
|
481 | 490 |
r = c->data;
|
|
488 | 497 |
return;
|
489 | 498 |
}
|
490 | 499 |
|
491 | |
n = ngx_http_read_request_header(r);
|
492 | |
|
493 | |
if (n == NGX_AGAIN || n == NGX_ERROR) {
|
494 | |
return;
|
495 | |
}
|
496 | |
|
497 | |
rc = ngx_http_parse_request_line(r, r->header_in);
|
498 | |
|
499 | |
if (rc == NGX_OK) {
|
500 | |
|
501 | |
/* the request line has been parsed successfully */
|
502 | |
|
503 | |
cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module);
|
504 | |
|
505 | |
if (r->http_version >= NGX_HTTP_VERSION_10
|
506 | |
&& cscf->large_client_header == 0
|
507 | |
&& r->header_in->pos == r->header_in->end)
|
508 | |
{
|
509 | |
/* no space for "\r\n" at the end of the header */
|
510 | |
|
511 | |
ngx_http_client_error(r, NGX_HTTP_PARSE_TOO_LONG_URI,
|
512 | |
NGX_HTTP_REQUEST_URI_TOO_LARGE);
|
513 | |
return;
|
514 | |
}
|
515 | |
|
516 | |
|
517 | |
/* copy unparsed URI */
|
518 | |
|
519 | |
r->unparsed_uri.len = r->uri_end - r->uri_start;
|
520 | |
r->unparsed_uri.data = ngx_palloc(r->pool, r->unparsed_uri.len + 1);
|
521 | |
if (r->unparsed_uri.data == NULL) {
|
522 | |
ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
|
523 | |
ngx_http_close_connection(c);
|
524 | |
return;
|
525 | |
}
|
526 | |
|
527 | |
ngx_cpystrn(r->unparsed_uri.data, r->uri_start,
|
528 | |
r->unparsed_uri.len + 1);
|
529 | |
|
530 | |
|
531 | |
/* copy URI */
|
532 | |
|
533 | |
if (r->args_start) {
|
534 | |
r->uri.len = r->args_start - 1 - r->uri_start;
|
535 | |
} else {
|
536 | |
r->uri.len = r->uri_end - r->uri_start;
|
537 | |
}
|
538 | |
|
539 | |
if (!(r->uri.data = ngx_palloc(r->pool, r->uri.len + 1))) {
|
540 | |
ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
|
541 | |
ngx_http_close_connection(c);
|
542 | |
return;
|
543 | |
}
|
544 | |
|
545 | |
if (r->complex_uri) {
|
546 | |
rc = ngx_http_parse_complex_uri(r);
|
547 | |
|
548 | |
if (rc == NGX_HTTP_INTERNAL_SERVER_ERROR) {
|
549 | |
ngx_http_close_request(r, rc);
|
550 | |
ngx_http_close_connection(c);
|
|
500 |
rc = NGX_AGAIN;
|
|
501 |
|
|
502 |
for ( ;; ) {
|
|
503 |
|
|
504 |
if (rc == NGX_AGAIN) {
|
|
505 |
n = ngx_http_read_request_header(r);
|
|
506 |
|
|
507 |
if (n == NGX_AGAIN || n == NGX_ERROR) {
|
551 | 508 |
return;
|
552 | 509 |
}
|
553 | |
|
554 | |
if (rc != NGX_OK) {
|
555 | |
r->request_line.len = r->request_end - r->request_start;
|
556 | |
r->request_line.data = r->request_start;
|
557 | |
|
558 | |
ngx_http_client_error(r, rc, NGX_HTTP_BAD_REQUEST);
|
559 | |
return;
|
560 | |
}
|
561 | |
|
562 | |
} else {
|
563 | |
ngx_cpystrn(r->uri.data, r->uri_start, r->uri.len + 1);
|
564 | |
}
|
565 | |
|
566 | |
|
567 | |
r->request_line.len = r->request_end - r->request_start;
|
568 | |
|
569 | |
if (cscf->large_client_header) {
|
570 | |
|
571 | |
/*
|
572 | |
* if the large client headers are enabled then
|
573 | |
* we need to copy the request line
|
574 | |
*/
|
575 | |
|
576 | |
r->request_line.data = ngx_palloc(r->pool, r->request_line.len + 1);
|
577 | |
if (r->request_line.data == NULL) {
|
|
510 |
}
|
|
511 |
|
|
512 |
rc = ngx_http_parse_request_line(r, r->header_in);
|
|
513 |
|
|
514 |
if (rc == NGX_OK) {
|
|
515 |
|
|
516 |
/* the request line has been parsed successfully */
|
|
517 |
|
|
518 |
/* copy unparsed URI */
|
|
519 |
|
|
520 |
r->unparsed_uri.len = r->uri_end - r->uri_start;
|
|
521 |
r->unparsed_uri.data = ngx_palloc(r->pool, r->unparsed_uri.len + 1);
|
|
522 |
if (r->unparsed_uri.data == NULL) {
|
578 | 523 |
ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
|
579 | 524 |
ngx_http_close_connection(c);
|
580 | 525 |
return;
|
581 | 526 |
}
|
582 | 527 |
|
583 | |
ngx_cpystrn(r->request_line.data, r->request_start,
|
584 | |
r->request_line.len + 1);
|
585 | |
|
586 | |
} else {
|
587 | |
r->request_line.data = r->request_start;
|
588 | |
r->request_line.data[r->request_line.len] = '\0';
|
589 | |
}
|
590 | |
|
591 | |
if (r->method == 0) {
|
592 | |
r->method_name.len = r->method_end - r->request_start + 1;
|
593 | |
r->method_name.data = r->request_line.data;
|
594 | |
}
|
595 | |
|
596 | |
if (r->uri_ext) {
|
597 | |
|
598 | |
/* copy URI extention */
|
|
528 |
ngx_cpystrn(r->unparsed_uri.data, r->uri_start,
|
|
529 |
r->unparsed_uri.len + 1);
|
|
530 |
|
|
531 |
|
|
532 |
/* copy URI */
|
599 | 533 |
|
600 | 534 |
if (r->args_start) {
|
601 | |
r->exten.len = r->args_start - 1 - r->uri_ext;
|
|
535 |
r->uri.len = r->args_start - 1 - r->uri_start;
|
602 | 536 |
} else {
|
603 | |
r->exten.len = r->uri_end - r->uri_ext;
|
604 | |
}
|
605 | |
|
606 | |
if (!(r->exten.data = ngx_palloc(r->pool, r->exten.len + 1))) {
|
|
537 |
r->uri.len = r->uri_end - r->uri_start;
|
|
538 |
}
|
|
539 |
|
|
540 |
if (!(r->uri.data = ngx_palloc(r->pool, r->uri.len + 1))) {
|
607 | 541 |
ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
|
608 | 542 |
ngx_http_close_connection(c);
|
609 | 543 |
return;
|
610 | 544 |
}
|
611 | 545 |
|
612 | |
ngx_cpystrn(r->exten.data, r->uri_ext, r->exten.len + 1);
|
613 | |
}
|
614 | |
|
615 | |
if (r->args_start && r->uri_end > r->args_start) {
|
616 | |
|
617 | |
/* copy URI arguments */
|
618 | |
|
619 | |
r->args.len = r->uri_end - r->args_start;
|
620 | |
|
621 | |
if (!(r->args.data = ngx_palloc(r->pool, r->args.len + 1))) {
|
|
546 |
if (r->complex_uri) {
|
|
547 |
rc = ngx_http_parse_complex_uri(r);
|
|
548 |
|
|
549 |
if (rc == NGX_HTTP_INTERNAL_SERVER_ERROR) {
|
|
550 |
ngx_http_close_request(r, rc);
|
|
551 |
ngx_http_close_connection(c);
|
|
552 |
return;
|
|
553 |
}
|
|
554 |
|
|
555 |
if (rc != NGX_OK) {
|
|
556 |
r->request_line.len = r->request_end - r->request_start;
|
|
557 |
r->request_line.data = r->request_start;
|
|
558 |
|
|
559 |
ngx_http_client_error(r, rc, NGX_HTTP_BAD_REQUEST);
|
|
560 |
return;
|
|
561 |
}
|
|
562 |
|
|
563 |
} else {
|
|
564 |
ngx_cpystrn(r->uri.data, r->uri_start, r->uri.len + 1);
|
|
565 |
}
|
|
566 |
|
|
567 |
|
|
568 |
r->request_line.len = r->request_end - r->request_start;
|
|
569 |
r->request_line.data = r->request_start;
|
|
570 |
r->request_line.data[r->request_line.len] = '\0';
|
|
571 |
|
|
572 |
if (r->method == 0) {
|
|
573 |
r->method_name.len = r->method_end - r->request_start + 1;
|
|
574 |
r->method_name.data = r->request_line.data;
|
|
575 |
}
|
|
576 |
|
|
577 |
if (r->uri_ext) {
|
|
578 |
|
|
579 |
/* copy URI extention */
|
|
580 |
|
|
581 |
if (r->args_start) {
|
|
582 |
r->exten.len = r->args_start - 1 - r->uri_ext;
|
|
583 |
} else {
|
|
584 |
r->exten.len = r->uri_end - r->uri_ext;
|
|
585 |
}
|
|
586 |
|
|
587 |
if (!(r->exten.data = ngx_palloc(r->pool, r->exten.len + 1))) {
|
|
588 |
ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
|
|
589 |
ngx_http_close_connection(c);
|
|
590 |
return;
|
|
591 |
}
|
|
592 |
|
|
593 |
ngx_cpystrn(r->exten.data, r->uri_ext, r->exten.len + 1);
|
|
594 |
}
|
|
595 |
|
|
596 |
if (r->args_start && r->uri_end > r->args_start) {
|
|
597 |
|
|
598 |
/* copy URI arguments */
|
|
599 |
|
|
600 |
r->args.len = r->uri_end - r->args_start;
|
|
601 |
|
|
602 |
if (!(r->args.data = ngx_palloc(r->pool, r->args.len + 1))) {
|
|
603 |
ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
|
|
604 |
ngx_http_close_connection(c);
|
|
605 |
return;
|
|
606 |
}
|
|
607 |
|
|
608 |
ngx_cpystrn(r->args.data, r->args_start, r->args.len + 1);
|
|
609 |
}
|
|
610 |
|
|
611 |
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0,
|
|
612 |
"http request line: \"%s\"", r->request_line.data);
|
|
613 |
|
|
614 |
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0,
|
|
615 |
"http uri: \"%s\"", r->uri.data);
|
|
616 |
|
|
617 |
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0,
|
|
618 |
"http args: \"%s\"",
|
|
619 |
r->args.data ? r->args.data : (u_char *) "");
|
|
620 |
|
|
621 |
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0,
|
|
622 |
"http exten: \"%s\"",
|
|
623 |
r->exten.data ? r->exten.data : (u_char *) "");
|
|
624 |
|
|
625 |
if (r->http_version < NGX_HTTP_VERSION_10) {
|
|
626 |
rev->event_handler = ngx_http_block_read;
|
|
627 |
ngx_http_handler(r);
|
|
628 |
return;
|
|
629 |
}
|
|
630 |
|
|
631 |
|
|
632 |
if (ngx_list_init(&r->headers_in.headers, r->pool, 20,
|
|
633 |
sizeof(ngx_table_elt_t)) == NGX_ERROR)
|
|
634 |
{
|
622 | 635 |
ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
|
623 | 636 |
ngx_http_close_connection(c);
|
624 | 637 |
return;
|
625 | 638 |
}
|
626 | 639 |
|
627 | |
ngx_cpystrn(r->args.data, r->args_start, r->args.len + 1);
|
628 | |
}
|
629 | |
|
630 | |
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0,
|
631 | |
"http request line: \"%s\"", r->request_line.data);
|
632 | |
|
633 | |
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0,
|
634 | |
"http uri: \"%s\"", r->uri.data);
|
635 | |
|
636 | |
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0,
|
637 | |
"http args: \"%s\"",
|
638 | |
r->args.data ? r->args.data : (u_char *) "");
|
639 | |
|
640 | |
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0,
|
641 | |
"http exten: \"%s\"",
|
642 | |
r->exten.data ? r->exten.data : (u_char *) "");
|
643 | |
|
644 | |
if (r->http_version < NGX_HTTP_VERSION_10) {
|
645 | |
rev->event_handler = ngx_http_block_read;
|
646 | |
ngx_http_handler(r);
|
|
640 |
|
|
641 |
if (ngx_array_init(&r->headers_in.cookies, r->pool, 5,
|
|
642 |
sizeof(ngx_table_elt_t *)) == NGX_ERROR)
|
|
643 |
{
|
|
644 |
ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
|
|
645 |
ngx_http_close_connection(c);
|
|
646 |
return;
|
|
647 |
}
|
|
648 |
|
|
649 |
|
|
650 |
ctx = c->log->data;
|
|
651 |
ctx->action = "reading client request headers";
|
|
652 |
ctx->url = r->unparsed_uri.data;
|
|
653 |
|
|
654 |
rev->event_handler = ngx_http_process_request_headers;
|
|
655 |
ngx_http_process_request_headers(rev);
|
|
656 |
|
647 | 657 |
return;
|
648 | |
}
|
649 | |
|
650 | |
|
651 | |
if (ngx_list_init(&r->headers_in.headers, r->pool, 20,
|
652 | |
sizeof(ngx_table_elt_t)) == NGX_ERROR)
|
653 | |
{
|
654 | |
ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
|
655 | |
ngx_http_close_connection(c);
|
|
658 |
|
|
659 |
} else if (rc != NGX_AGAIN) {
|
|
660 |
|
|
661 |
/* there was error while a request line parsing */
|
|
662 |
|
|
663 |
for (p = r->request_start; p < r->header_in->last; p++) {
|
|
664 |
if (*p == CR || *p == LF) {
|
|
665 |
break;
|
|
666 |
}
|
|
667 |
}
|
|
668 |
|
|
669 |
r->request_line.len = p - r->request_start;
|
|
670 |
r->request_line.data = r->request_start;
|
|
671 |
|
|
672 |
if (rc == NGX_HTTP_PARSE_INVALID_METHOD) {
|
|
673 |
r->http_version = NGX_HTTP_VERSION_10;
|
|
674 |
}
|
|
675 |
|
|
676 |
ngx_http_client_error(r, rc,
|
|
677 |
(rc == NGX_HTTP_PARSE_INVALID_METHOD) ?
|
|
678 |
NGX_HTTP_NOT_IMPLEMENTED:
|
|
679 |
NGX_HTTP_BAD_REQUEST);
|
656 | 680 |
return;
|
657 | 681 |
}
|
658 | 682 |
|
659 | |
|
660 | |
if (ngx_array_init(&r->headers_in.cookies, r->pool, 5,
|
661 | |
sizeof(ngx_table_elt_t *)) == NGX_ERROR)
|
662 | |
{
|
663 | |
ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
|
664 | |
ngx_http_close_connection(c);
|
665 | |
return;
|
666 | |
}
|
667 | |
|
668 | |
|
669 | |
ctx = c->log->data;
|
670 | |
ctx->action = "reading client request headers";
|
671 | |
ctx->url = r->unparsed_uri.data;
|
672 | |
|
673 | |
if (cscf->large_client_header
|
674 | |
&& r->header_in->pos == r->header_in->last)
|
675 | |
{
|
676 | |
r->header_in->pos = r->header_in->last = r->header_in->start;
|
677 | |
}
|
678 | |
|
679 | |
rev->event_handler = ngx_http_process_request_headers;
|
680 | |
ngx_http_process_request_headers(rev);
|
681 | |
|
682 | |
return;
|
683 | |
|
684 | |
} else if (rc != NGX_AGAIN) {
|
685 | |
|
686 | |
/* there was error while a request line parsing */
|
687 | |
|
688 | |
for (p = r->request_start; p < r->header_in->last; p++) {
|
689 | |
if (*p == CR || *p == LF) {
|
690 | |
break;
|
691 | |
}
|
692 | |
}
|
693 | |
|
694 | |
r->request_line.len = p - r->request_start;
|
695 | |
r->request_line.data = r->request_start;
|
696 | |
|
697 | |
if (rc == NGX_HTTP_PARSE_INVALID_METHOD) {
|
698 | |
r->http_version = NGX_HTTP_VERSION_10;
|
699 | |
}
|
700 | |
|
701 | |
ngx_http_client_error(r, rc,
|
702 | |
(rc == NGX_HTTP_PARSE_INVALID_METHOD) ?
|
703 | |
NGX_HTTP_NOT_IMPLEMENTED:
|
704 | |
NGX_HTTP_BAD_REQUEST);
|
705 | |
return;
|
706 | |
}
|
707 | |
|
708 | |
/* NGX_AGAIN: a request line parsing is still not complete */
|
709 | |
|
710 | |
if (r->header_in->last == r->header_in->end) {
|
711 | |
|
712 | |
/*
|
713 | |
* If it's a pipelined request and a request line is not complete
|
714 | |
* then we have to copy it to the start of the r->header_in buf.
|
715 | |
* We have to copy it here only if the large client headers
|
716 | |
* are enabled otherwise a request line had been already copied
|
717 | |
* to the start of the r->header_in buf in ngx_http_set_keepalive().
|
718 | |
*/
|
719 | |
|
720 | |
cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module);
|
721 | |
|
722 | |
if (cscf->large_client_header) {
|
723 | |
offset = r->request_start - r->header_in->start;
|
724 | |
|
725 | |
if (offset == 0) {
|
|
683 |
/* NGX_AGAIN: a request line parsing is still incomplete */
|
|
684 |
|
|
685 |
if (r->header_in->last == r->header_in->end) {
|
|
686 |
|
|
687 |
rv = ngx_http_alloc_large_header_buffer(r, 1);
|
|
688 |
|
|
689 |
if (rv == NGX_ERROR) {
|
|
690 |
ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
|
|
691 |
ngx_http_close_connection(c);
|
|
692 |
return;
|
|
693 |
}
|
|
694 |
|
|
695 |
if (rv == NGX_DECLINED) {
|
726 | 696 |
ngx_http_client_error(r, NGX_HTTP_PARSE_TOO_LONG_URI,
|
727 | 697 |
NGX_HTTP_REQUEST_URI_TOO_LARGE);
|
728 | 698 |
return;
|
729 | 699 |
}
|
730 | |
|
731 | |
ngx_memcpy(r->header_in->start, r->request_start,
|
732 | |
r->header_in->last - r->request_start);
|
733 | |
|
734 | |
r->header_in->pos -= offset;
|
735 | |
r->header_in->last -= offset;
|
736 | |
r->request_start = r->header_in->start;
|
737 | |
r->request_end -= offset;
|
738 | |
r->uri_start -= offset;
|
739 | |
r->uri_end -= offset;
|
740 | |
if (r->uri_ext) {
|
741 | |
r->uri_ext -= offset;
|
742 | |
}
|
743 | |
if (r->args_start) {
|
744 | |
r->args_start -= offset;
|
745 | |
}
|
746 | |
|
747 | |
} else {
|
748 | |
ngx_http_client_error(r, NGX_HTTP_PARSE_TOO_LONG_URI,
|
749 | |
NGX_HTTP_REQUEST_URI_TOO_LARGE);
|
750 | |
}
|
751 | |
}
|
752 | |
|
753 | |
return;
|
|
700 |
}
|
|
701 |
}
|
754 | 702 |
}
|
755 | 703 |
|
756 | 704 |
|
757 | 705 |
static void ngx_http_process_request_headers(ngx_event_t *rev)
|
758 | 706 |
{
|
759 | |
ssize_t n;
|
760 | |
ngx_int_t rc, i, offset;
|
761 | |
ngx_table_elt_t *h, **cookie;
|
762 | |
ngx_connection_t *c;
|
763 | |
ngx_http_request_t *r;
|
764 | |
ngx_http_core_srv_conf_t *cscf;
|
|
707 |
ssize_t n;
|
|
708 |
ngx_int_t rc, rv, i, offset;
|
|
709 |
ngx_table_elt_t *h, **cookie;
|
|
710 |
ngx_connection_t *c;
|
|
711 |
ngx_http_request_t *r;
|
765 | 712 |
|
766 | 713 |
c = rev->data;
|
767 | 714 |
r = c->data;
|
|
774 | 721 |
return;
|
775 | 722 |
}
|
776 | 723 |
|
777 | |
cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module);
|
778 | |
|
779 | 724 |
rc = NGX_AGAIN;
|
780 | 725 |
|
781 | 726 |
for ( ;; ) {
|
|
727 |
|
782 | 728 |
if (rc == NGX_AGAIN) {
|
|
729 |
|
|
730 |
if (r->header_in->last == r->header_in->end) {
|
|
731 |
|
|
732 |
rv = ngx_http_alloc_large_header_buffer(r, 0);
|
|
733 |
|
|
734 |
if (rv == NGX_ERROR) {
|
|
735 |
ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
|
|
736 |
ngx_http_close_connection(c);
|
|
737 |
return;
|
|
738 |
}
|
|
739 |
|
|
740 |
if (rv == NGX_DECLINED) {
|
|
741 |
ngx_http_client_error(r, NGX_HTTP_PARSE_TOO_LONG_HEADER,
|
|
742 |
NGX_HTTP_BAD_REQUEST);
|
|
743 |
return;
|
|
744 |
}
|
|
745 |
}
|
|
746 |
|
783 | 747 |
n = ngx_http_read_request_header(r);
|
784 | 748 |
|
785 | 749 |
if (n == NGX_AGAIN || n == NGX_ERROR) {
|
|
808 | 772 |
}
|
809 | 773 |
|
810 | 774 |
h->key.len = r->header_name_end - r->header_name_start;
|
|
775 |
h->key.data = r->header_name_start;
|
|
776 |
h->key.data[h->key.len] = '\0';
|
|
777 |
|
811 | 778 |
h->value.len = r->header_end - r->header_start;
|
812 | |
|
813 | |
/* if the large client headers are enabled then
|
814 | |
we need to copy the header name and value */
|
815 | |
|
816 | |
if (cscf->large_client_header) {
|
817 | |
h->key.data = ngx_palloc(r->pool,
|
818 | |
h->key.len + 1 + h->value.len + 1);
|
819 | |
if (h->key.data == NULL) {
|
820 | |
ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
|
821 | |
ngx_http_close_connection(c);
|
822 | |
return;
|
823 | |
}
|
824 | |
|
825 | |
h->value.data = h->key.data + h->key.len + 1;
|
826 | |
ngx_cpystrn(h->key.data, r->header_name_start, h->key.len + 1);
|
827 | |
ngx_cpystrn(h->value.data, r->header_start, h->value.len + 1);
|
828 | |
|
829 | |
} else {
|
830 | |
h->key.data = r->header_name_start;
|
831 | |
h->key.data[h->key.len] = '\0';
|
832 | |
h->value.data = r->header_start;
|
833 | |
h->value.data[h->value.len] = '\0';
|
834 | |
}
|
|
779 |
h->value.data = r->header_start;
|
|
780 |
h->value.data[h->value.len] = '\0';
|
835 | 781 |
|
836 | 782 |
if (h->key.len == sizeof("Cookie") - 1
|
837 | 783 |
&& ngx_strcasecmp(h->key.data, "Cookie") == 0)
|
838 | 784 |
{
|
839 | |
if (!(cookie = ngx_push_array(&r->headers_in.cookies))) {
|
|
785 |
if (!(cookie = ngx_array_push(&r->headers_in.cookies))) {
|
840 | 786 |
ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
|
841 | 787 |
ngx_http_close_connection(c);
|
842 | 788 |
return;
|
|
864 | 810 |
ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
|
865 | 811 |
"http header: \"%s: %s\"",
|
866 | 812 |
h->key.data, h->value.data);
|
867 | |
|
868 | |
if (cscf->large_client_header
|
869 | |
&& r->header_in->pos == r->header_in->last)
|
870 | |
{
|
871 | |
r->header_in->pos = r->header_in->last = r->header_in->start;
|
872 | |
}
|
873 | 813 |
|
874 | 814 |
continue;
|
875 | 815 |
|
|
934 | 874 |
|
935 | 875 |
/* NGX_AGAIN: a header line parsing is still not complete */
|
936 | 876 |
|
937 | |
if (r->header_in->last == r->header_in->end) {
|
938 | |
|
939 | |
#if 1
|
940 | |
/* ngx_http_alloc_large_header_buffer() */
|
941 | |
|
942 | |
rc = ngx_http_alloc_header_buf(r, 0);
|
943 | |
|
944 | |
if (rc == NGX_ERROR) {
|
945 | |
ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
|
946 | |
ngx_http_close_connection(c);
|
947 | |
return;
|
948 | |
}
|
949 | |
|
950 | |
if (rc == NGX_DECLINED) {
|
951 | |
ngx_http_client_error(r, NGX_HTTP_PARSE_TOO_LONG_HEADER,
|
952 | |
NGX_HTTP_BAD_REQUEST);
|
953 | |
return;
|
954 | |
}
|
955 | |
#endif
|
956 | |
|
957 | |
#if 0
|
958 | |
/*
|
959 | |
* if the large client headers are enabled then
|
960 | |
* we need to compact r->header_in buf
|
961 | |
*/
|
962 | |
|
963 | |
if (cscf->large_client_header) {
|
964 | |
offset = r->header_name_start - r->header_in->start;
|
965 | |
|
966 | |
if (offset == 0) {
|
967 | |
ngx_http_client_error(r, NGX_HTTP_PARSE_TOO_LONG_HEADER,
|
968 | |
NGX_HTTP_BAD_REQUEST);
|
969 | |
return;
|
970 | |
}
|
971 | |
|
972 | |
ngx_memcpy(r->header_in->start, r->header_name_start,
|
973 | |
r->header_in->last - r->header_name_start);
|
974 | |
|
975 | |
r->header_in->last -= offset;
|
976 | |
r->header_in->pos -= offset;
|
977 | |
r->header_name_start = r->header_in->start;
|
978 | |
r->header_name_end -= offset;
|
979 | |
r->header_start -= offset;
|
980 | |
r->header_end -= offset;
|
981 | |
|
982 | |
} else {
|
983 | |
ngx_http_client_error(r, NGX_HTTP_PARSE_TOO_LONG_HEADER,
|
984 | |
NGX_HTTP_BAD_REQUEST);
|
985 | |
return;
|
986 | |
}
|
987 | |
#endif
|
988 | |
}
|
989 | 877 |
}
|
990 | 878 |
}
|
991 | 879 |
|
|
1044 | 932 |
}
|
1045 | 933 |
|
1046 | 934 |
|
1047 | |
#if 1
|
1048 | |
|
1049 | |
static ngx_int_t ngx_http_alloc_header_buf(ngx_http_request_t *r,
|
1050 | |
ngx_uint_t request_line)
|
|
935 |
static ngx_int_t ngx_http_alloc_large_header_buffer(ngx_http_request_t *r,
|
|
936 |
ngx_uint_t request_line)
|
1051 | 937 |
{
|
1052 | 938 |
u_char *old, *new;
|
1053 | 939 |
ngx_int_t offset;
|
|
1058 | 944 |
ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
|
1059 | 945 |
"http alloc large header buffer");
|
1060 | 946 |
|
|
947 |
if (request_line && r->state == 0) {
|
|
948 |
|
|
949 |
/* the client fills up the buffer with "\r\n" */
|
|
950 |
|
|
951 |
r->header_in->pos = r->header_in->start;
|
|
952 |
r->header_in->last = r->header_in->start;
|
|
953 |
|
|
954 |
return NGX_OK;
|
|
955 |
}
|
|
956 |
|
1061 | 957 |
old = request_line ? r->request_start : r->header_name_start;
|
1062 | 958 |
|
1063 | 959 |
cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module);
|
1064 | 960 |
|
1065 | |
if ((size_t) (r->header_in->pos - old) >= cscf->client_large_buffers.size) {
|
|
961 |
if (r->state != 0
|
|
962 |
&& (size_t) (r->header_in->pos - old)
|
|
963 |
>= cscf->large_client_header_buffers.size)
|
|
964 |
{
|
1066 | 965 |
return NGX_DECLINED;
|
1067 | 966 |
}
|
1068 | 967 |
|
|
1071 | 970 |
if (hc->nfree) {
|
1072 | 971 |
b = hc->free[--hc->nfree];
|
1073 | 972 |
|
1074 | |
} else if (hc->nbusy < cscf->client_large_buffers.num) {
|
|
973 |
} else if (hc->nbusy < cscf->large_client_header_buffers.num) {
|
1075 | 974 |
|
1076 | 975 |
if (hc->busy == NULL) {
|
1077 | 976 |
hc->busy = ngx_palloc(r->connection->pool,
|
1078 | |
cscf->client_large_buffers.num * sizeof(ngx_buf_t *));
|
|
977 |
cscf->large_client_header_buffers.num * sizeof(ngx_buf_t *));
|
1079 | 978 |
if (hc->busy == NULL) {
|
1080 | 979 |
return NGX_ERROR;
|
1081 | 980 |
}
|
1082 | 981 |
}
|
1083 | 982 |
|
1084 | 983 |
b = ngx_create_temp_buf(r->connection->pool,
|
1085 | |
cscf->client_large_buffers.size);
|
|
984 |
cscf->large_client_header_buffers.size);
|
1086 | 985 |
if (b == NULL) {
|
1087 | 986 |
return NGX_ERROR;
|
1088 | 987 |
}
|
|
1093 | 992 |
|
1094 | 993 |
hc->busy[hc->nbusy++] = b;
|
1095 | 994 |
|
|
995 |
if (r->state == 0) {
|
|
996 |
/*
|
|
997 |
* r->state == 0 means that a header line was parsed successfully
|
|
998 |
* and we do not need to copy incomplete header line and
|
|
999 |
* to relocate the parser header pointers
|
|
1000 |
*/
|
|
1001 |
|
|
1002 |
r->header_in = b;
|
|
1003 |
|
|
1004 |
return NGX_OK;
|
|
1005 |
}
|
|
1006 |
|
1096 | 1007 |
new = b->start;
|
1097 | 1008 |
|
1098 | 1009 |
ngx_memcpy(new, old, r->header_in->last - old);
|
|
1102 | 1013 |
|
1103 | 1014 |
if (request_line) {
|
1104 | 1015 |
r->request_start = new;
|
1105 | |
r->request_end = new + (r->request_end - old);
|
|
1016 |
|
|
1017 |
if (r->request_end) {
|
|
1018 |
r->request_end = new + (r->request_end - old);
|
|
1019 |
}
|
|
1020 |
|
|
1021 |
r->method_end = new + (r->method_end - old);
|
1106 | 1022 |
|
1107 | 1023 |
r->uri_start = new + (r->uri_start - old);
|
1108 | 1024 |
r->uri_end = new + (r->uri_end - old);
|
|
1025 |
|
|
1026 |
if (r->schema_start) {
|
|
1027 |
r->schema_start = new + (r->schema_start - old);
|
|
1028 |
r->schema_end = new + (r->schema_end - old);
|
|
1029 |
}
|
|
1030 |
|
|
1031 |
if (r->host_start) {
|
|
1032 |
r->host_start = new + (r->host_start - old);
|
|
1033 |
r->host_end = new + (r->host_end - old);
|
|
1034 |
}
|
|
1035 |
|
|
1036 |
if (r->port_start) {
|
|
1037 |
r->port_start = new + (r->port_start - old);
|
|
1038 |
r->port_end = new + (r->port_end - old);
|
|
1039 |
}
|
1109 | 1040 |
|
1110 | 1041 |
if (r->uri_ext) {
|
1111 | 1042 |
r->uri_ext = new + (r->uri_ext - old);
|
|
1126 | 1057 |
|
1127 | 1058 |
return NGX_OK;
|
1128 | 1059 |
}
|
1129 | |
|
1130 | |
#endif
|
1131 | 1060 |
|
1132 | 1061 |
|
1133 | 1062 |
static ngx_int_t ngx_http_process_request_header(ngx_http_request_t *r)
|
|
1558 | 1487 |
|
1559 | 1488 |
static ngx_int_t ngx_http_read_discarded_body(ngx_http_request_t *r)
|
1560 | 1489 |
{
|
1561 | |
ssize_t size, n;
|
1562 | |
ngx_http_core_loc_conf_t *clcf;
|
|
1490 |
ssize_t size, n;
|
|
1491 |
u_char buffer[NGX_HTTP_DISCARD_BUFFER_SIZE];
|
1563 | 1492 |
|
1564 | 1493 |
ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
|
1565 | 1494 |
"http read discarded body");
|
|
1568 | 1497 |
return NGX_OK;
|
1569 | 1498 |
}
|
1570 | 1499 |
|
1571 | |
clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
|
1572 | |
|
1573 | |
if (r->discarded_buffer == NULL) {
|
1574 | |
r->discarded_buffer = ngx_palloc(r->pool, clcf->discarded_buffer_size);
|
1575 | |
if (r->discarded_buffer == NULL) {
|
1576 | |
return NGX_HTTP_INTERNAL_SERVER_ERROR;
|
1577 | |
}
|
1578 | |
}
|
1579 | 1500 |
|
1580 | 1501 |
size = r->headers_in.content_length_n;
|
1581 | 1502 |
|
1582 | |
if (size > (ssize_t) clcf->discarded_buffer_size) {
|
1583 | |
size = (ssize_t) clcf->discarded_buffer_size;
|
1584 | |
}
|
1585 | |
|
1586 | |
n = r->connection->recv(r->connection, r->discarded_buffer, size);
|
|
1503 |
if (size > NGX_HTTP_DISCARD_BUFFER_SIZE) {
|
|
1504 |
size = NGX_HTTP_DISCARD_BUFFER_SIZE;
|
|
1505 |
}
|
|
1506 |
|
|
1507 |
n = r->connection->recv(r->connection, buffer, size);
|
1587 | 1508 |
|
1588 | 1509 |
if (n == NGX_ERROR) {
|
1589 | 1510 |
|
1590 | 1511 |
r->closed = 1;
|
1591 | 1512 |
|
1592 | 1513 |
/*
|
1593 | |
* when a client request body is discarded then we already set
|
|
1514 |
* if a client request body is discarded then we already set
|
1594 | 1515 |
* some HTTP response code for client and we can ignore the error
|
1595 | 1516 |
*/
|
1596 | 1517 |
|
|
1609 | 1530 |
|
1610 | 1531 |
static void ngx_http_set_keepalive(ngx_http_request_t *r)
|
1611 | 1532 |
{
|
|
1533 |
ngx_int_t i;
|
1612 | 1534 |
size_t len;
|
1613 | |
ngx_buf_t *b;
|
|
1535 |
ngx_buf_t *b, *f;
|
1614 | 1536 |
ngx_event_t *rev, *wev;
|
1615 | 1537 |
ngx_connection_t *c;
|
1616 | 1538 |
ngx_http_connection_t *hc;
|
|
1627 | 1549 |
ctx->action = "closing request";
|
1628 | 1550 |
|
1629 | 1551 |
hc = r->http_connection;
|
|
1552 |
b = r->header_in;
|
|
1553 |
|
|
1554 |
clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
|
|
1555 |
|
|
1556 |
if (b->pos < b->last || clcf->keepalive_buffers) {
|
|
1557 |
|
|
1558 |
/*
|
|
1559 |
* the pipelined request or we like to keep the allocated
|
|
1560 |
* ngx_http_request_t and the client header buffers while keepalive
|
|
1561 |
*/
|
|
1562 |
|
|
1563 |
if (b != c->buffer) {
|
|
1564 |
|
|
1565 |
/* move the large header buffers to the free list */
|
|
1566 |
|
|
1567 |
cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module);
|
|
1568 |
|
|
1569 |
if (hc->free == NULL) {
|
|
1570 |
hc->free = ngx_palloc(c->pool,
|
|
1571 |
cscf->large_client_header_buffers.num * sizeof(ngx_buf_t *));
|
|
1572 |
if (hc->free == NULL) {
|
|
1573 |
ngx_http_close_connection(c);
|
|
1574 |
return;
|
|
1575 |
}
|
|
1576 |
}
|
|
1577 |
|
|
1578 |
for (i = 0; i < hc->nbusy - 1; i++) {
|
|
1579 |
f = hc->busy[i];
|
|
1580 |
hc->free[hc->nfree++] = f;
|
|
1581 |
f->pos = f->start;
|
|
1582 |
f->last = f->start;
|
|
1583 |
}
|
|
1584 |
|
|
1585 |
hc->busy[0] = b;
|
|
1586 |
hc->nbusy = 1;
|
|
1587 |
}
|
|
1588 |
}
|
|
1589 |
|
1630 | 1590 |
ngx_http_close_request(r, 0);
|
1631 | 1591 |
c->data = hc;
|
1632 | 1592 |
|
1633 | |
clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
|
1634 | 1593 |
ngx_add_timer(rev, clcf->keepalive_timeout);
|
1635 | 1594 |
|
1636 | 1595 |
if (ngx_handle_level_read_event(rev) == NGX_ERROR) {
|
|
1638 | 1597 |
return;
|
1639 | 1598 |
}
|
1640 | 1599 |
|
1641 | |
b = c->buffer;
|
1642 | 1600 |
wev = c->write;
|
1643 | 1601 |
wev->event_handler = ngx_http_empty_handler;
|
1644 | 1602 |
|
1645 | |
|
1646 | 1603 |
if (b->pos < b->last) {
|
1647 | 1604 |
|
1648 | |
/*
|
1649 | |
* The pipelined request.
|
1650 | |
*
|
1651 | |
* We do not know here whether the pipelined request is complete
|
1652 | |
* so if the large client headers are not enabled
|
1653 | |
* we need to copy the data to the start of c->buffer.
|
1654 | |
* This copy should be rare because clients that support
|
1655 | |
* pipelined requests (Mozilla 1.x, Opera 6.x+) are still rare.
|
1656 | |
*/
|
1657 | |
|
1658 | |
cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module);
|
1659 | |
|
1660 | |
if (!cscf->large_client_header) {
|
1661 | |
len = b->last - b->pos;
|
1662 | |
ngx_memcpy(b->start, b->pos, len);
|
1663 | |
b->pos = b->start;
|
1664 | |
b->last = b->start + len;
|
1665 | |
}
|
|
1605 |
/* the pipelined request */
|
1666 | 1606 |
|
1667 | 1607 |
ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "pipelined request");
|
1668 | 1608 |
|
|
1675 | 1615 |
hc->pipeline = 0;
|
1676 | 1616 |
|
1677 | 1617 |
b->pos = b->last = b->start;
|
|
1618 |
|
|
1619 |
if (!clcf->keepalive_buffers) {
|
|
1620 |
|
|
1621 |
if (ngx_pfree(c->pool, r) == NGX_OK) {
|
|
1622 |
hc->request = NULL;
|
|
1623 |
}
|
|
1624 |
|
|
1625 |
if (ngx_pfree(c->pool, c->buffer->start) == NGX_OK) {
|
|
1626 |
c->buffer = NULL;
|
|
1627 |
}
|
|
1628 |
|
|
1629 |
if (hc->free) {
|
|
1630 |
for (i = 0; i < hc->nfree; i++) {
|
|
1631 |
ngx_pfree(c->pool, hc->free[i]);
|
|
1632 |
hc->free[i] = NULL;
|
|
1633 |
}
|
|
1634 |
|
|
1635 |
hc->nfree = 0;
|
|
1636 |
}
|
|
1637 |
|
|
1638 |
if (hc->busy) {
|
|
1639 |
for (i = 0; i < hc->nbusy; i++) {
|
|
1640 |
ngx_pfree(c->pool, hc->busy[i]);
|
|
1641 |
hc->busy[i] = NULL;
|
|
1642 |
}
|
|
1643 |
|
|
1644 |
hc->nbusy = 0;
|
|
1645 |
}
|
|
1646 |
}
|
|
1647 |
|
1678 | 1648 |
rev->event_handler = ngx_http_keepalive_handler;
|
1679 | 1649 |
|
1680 | 1650 |
if (wev->active) {
|
|
1705 | 1675 |
c->tcp_nopush = NGX_TCP_NOPUSH_UNSET;
|
1706 | 1676 |
}
|
1707 | 1677 |
|
|
1678 |
#if 0
|
|
1679 |
/* if "keepalive_buffers off" then we need some other place */
|
1708 | 1680 |
r->http_state = NGX_HTTP_KEEPALIVE_STATE;
|
|
1681 |
#endif
|
1709 | 1682 |
|
1710 | 1683 |
if (rev->ready) {
|
1711 | 1684 |
ngx_http_keepalive_handler(rev);
|
|
1715 | 1688 |
|
1716 | 1689 |
static void ngx_http_keepalive_handler(ngx_event_t *rev)
|
1717 | 1690 |
{
|
1718 | |
ssize_t n;
|
1719 | |
ngx_connection_t *c;
|
1720 | |
ngx_http_log_ctx_t *ctx;
|
|
1691 |
ssize_t n;
|
|
1692 |
ngx_buf_t *b;
|
|
1693 |
ngx_connection_t *c;
|
|
1694 |
ngx_http_log_ctx_t *ctx;
|
|
1695 |
ngx_http_connection_t *hc;
|
1721 | 1696 |
|
1722 | 1697 |
c = rev->data;
|
1723 | 1698 |
|
|
1727 | 1702 |
ngx_http_close_connection(c);
|
1728 | 1703 |
return;
|
1729 | 1704 |
}
|
|
1705 |
|
|
1706 |
hc = c->data;
|
|
1707 |
b = hc->nbusy ? hc->busy[0] : c->buffer;
|
1730 | 1708 |
|
1731 | 1709 |
/*
|
1732 | 1710 |
* MSIE closes a keepalive connection with RST flag
|
|
1736 | 1714 |
c->log_error = NGX_ERROR_IGNORE_ECONNRESET;
|
1737 | 1715 |
ngx_set_socket_errno(0);
|
1738 | 1716 |
|
1739 | |
n = c->recv(c, c->buffer->last, c->buffer->end - c->buffer->last);
|
|
1717 |
n = c->recv(c, b->last, b->end - b->last);
|
1740 | 1718 |
c->log_error = NGX_ERROR_INFO;
|
1741 | 1719 |
|
1742 | 1720 |
if (n == NGX_AGAIN) {
|
|
1758 | 1736 |
return;
|
1759 | 1737 |
}
|
1760 | 1738 |
|
1761 | |
c->buffer->last += n;
|
|
1739 |
b->last += n;
|
1762 | 1740 |
rev->log->handler = ngx_http_log_error;
|
1763 | 1741 |
ctx->action = "reading client request line";
|
1764 | |
|
1765 | |
#if 0
|
1766 | |
if (!(hc = ngx_pcalloc(c->pool, sizeof(ngx_http_connection_t)) {
|
1767 | |
ngx_http_close_connection(c);
|
1768 | |
return;
|
1769 | |
}
|
1770 | |
|
1771 | |
hc->request = r;
|
1772 | |
c->data = r;
|
1773 | |
#endif
|
1774 | 1742 |
|
1775 | 1743 |
ngx_http_init_request(rev);
|
1776 | 1744 |
}
|
|
1839 | 1807 |
ngx_connection_t *c;
|
1840 | 1808 |
ngx_http_request_t *r;
|
1841 | 1809 |
ngx_http_core_loc_conf_t *clcf;
|
|
1810 |
u_char buffer[NGX_HTTP_LINGERING_BUFFER_SIZE];
|
1842 | 1811 |
|
1843 | 1812 |
c = rev->data;
|
1844 | 1813 |
r = c->data;
|
|
1859 | 1828 |
return;
|
1860 | 1829 |
}
|
1861 | 1830 |
|
1862 | |
clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
|
1863 | |
|
1864 | |
if (r->discarded_buffer == NULL) {
|
1865 | |
|
1866 | |
/* TODO: r->header_in->start (if large headers are enabled)
|
1867 | |
or the end of parsed header (otherwise)
|
1868 | |
instead of r->header_in->last */
|
1869 | |
|
1870 | |
if (r->header_in->end - r->header_in->last
|
1871 | |
>= (ssize_t) clcf->discarded_buffer_size)
|
1872 | |
{
|
1873 | |
r->discarded_buffer = r->header_in->last;
|
1874 | |
|
1875 | |
} else {
|
1876 | |
r->discarded_buffer = ngx_palloc(c->pool,
|
1877 | |
clcf->discarded_buffer_size);
|
1878 | |
if (r->discarded_buffer) {
|
1879 | |
ngx_http_close_request(r, 0);
|
1880 | |
ngx_http_close_connection(c);
|
1881 | |
return;
|
1882 | |
}
|
1883 | |
}
|
1884 | |
}
|
1885 | |
|
1886 | 1831 |
do {
|
1887 | |
n = c->recv(c, r->discarded_buffer, clcf->discarded_buffer_size);
|
|
1832 |
n = c->recv(c, buffer, NGX_HTTP_LINGERING_BUFFER_SIZE);
|
1888 | 1833 |
|
1889 | 1834 |
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0, "lingering read: %d", n);
|
1890 | 1835 |
|
|
1896 | 1841 |
|
1897 | 1842 |
} while (rev->ready);
|
1898 | 1843 |
|
|
1844 |
clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
|
|
1845 |
|
1899 | 1846 |
timer *= 1000;
|
|
1847 |
|
1900 | 1848 |
if (timer > clcf->lingering_timeout) {
|
1901 | 1849 |
timer = clcf->lingering_timeout;
|
1902 | 1850 |
}
|