Klaus Demo nginx / f7abd72
nginx-0.0.11-2004-09-23-10:32:00 import Igor Sysoev 17 years ago
8 changed file(s) with 435 addition(s) and 472 deletion(s). Raw diff Collapse all Expand all
2020 b->temporary = 1;
2121
2222 /*
23
2324 b->file_pos = 0;
2425 b->file_last = 0;
2526
2728 b->shadow = NULL;
2829
2930 b->tag = 0;
30 */
31
32 */
3133
3234 return b;
3335 }
4343 */
4444
4545 for (p = pool, n = pool->next; /* void */; p = n, n = n->next) {
46 ngx_log_debug1(NGX_LOG_DEBUG_ALLOC, pool->log, 0,
47 "free: " PTR_FMT, p);
46 ngx_log_debug2(NGX_LOG_DEBUG_ALLOC, pool->log, 0,
47 "free: " PTR_FMT ", unused: " SIZE_T_FMT,
48 p, p->end - p->last);
4849
4950 if (n == NULL) {
5051 break;
7071 ngx_pool_large_t *large, *last;
7172
7273 if (size <= (size_t) NGX_MAX_ALLOC_FROM_POOL
73 && size <= (size_t) (pool->end - (char *) pool))
74 && size <= (size_t) (pool->end - (char *) pool) - sizeof(ngx_pool_t))
7475 {
7576 for (p = pool, n = pool->next; /* void */; p = n, n = n->next) {
7677 m = ngx_align(p->last);
105106 last = NULL;
106107
107108 if (pool->large) {
108 for (last = pool->large; /* void */; last = last->next) {
109 for (last = pool->large; /* void */ ; last = last->next) {
109110 if (last->alloc == NULL) {
110111 large = last;
111112 last = NULL;
149150 }
150151
151152
152 void ngx_pfree(ngx_pool_t *pool, void *p)
153 ngx_int_t ngx_pfree(ngx_pool_t *pool, void *p)
153154 {
154155 ngx_pool_large_t *l;
155156
159160 "free: " PTR_FMT, l->alloc);
160161 free(l->alloc);
161162 l->alloc = NULL;
162 }
163 }
163
164 return NGX_OK;
165 }
166 }
167
168 return NGX_DECLINED;
164169 }
165170
166171
4242
4343 void *ngx_palloc(ngx_pool_t *pool, size_t size);
4444 void *ngx_pcalloc(ngx_pool_t *pool, size_t size);
45 void ngx_pfree(ngx_pool_t *pool, void *p);
45 ngx_int_t ngx_pfree(ngx_pool_t *pool, void *p);
4646
4747
4848 #endif /* _NGX_PALLOC_H_INCLUDED_ */
9595 offsetof(ngx_http_core_srv_conf_t, client_header_buffer_size),
9696 NULL },
9797
98 { ngx_string("client_large_buffers"),
98 { ngx_string("large_client_header_buffers"),
9999 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE2,
100100 ngx_conf_set_bufs_slot,
101101 NGX_HTTP_SRV_CONF_OFFSET,
102 offsetof(ngx_http_core_srv_conf_t, client_large_buffers),
103 NULL },
104
105 { ngx_string("large_client_header"),
106 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_FLAG,
107 ngx_conf_set_flag_slot,
108 NGX_HTTP_SRV_CONF_OFFSET,
109 offsetof(ngx_http_core_srv_conf_t, large_client_header),
102 offsetof(ngx_http_core_srv_conf_t, large_client_header_buffers),
110103 NULL },
111104
112105 { ngx_string("restrict_host_names"),
238231 ngx_set_keepalive,
239232 NGX_HTTP_LOC_CONF_OFFSET,
240233 0,
234 NULL },
235
236 { ngx_string("keepalive_buffers"),
237 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
238 ngx_conf_set_flag_slot,
239 NGX_HTTP_LOC_CONF_OFFSET,
240 offsetof(ngx_http_core_loc_conf_t, keepalive_buffers),
241241 NULL },
242242
243243 { ngx_string("lingering_time"),
12741274 cscf->request_pool_size = NGX_CONF_UNSET_SIZE;
12751275 cscf->client_header_timeout = NGX_CONF_UNSET_MSEC;
12761276 cscf->client_header_buffer_size = NGX_CONF_UNSET_SIZE;
1277 cscf->large_client_header = NGX_CONF_UNSET;
12781277 cscf->restrict_host_names = NGX_CONF_UNSET_UINT;
12791278
12801279 return cscf;
13321331 }
13331332
13341333 ngx_conf_merge_size_value(conf->connection_pool_size,
1335 prev->connection_pool_size, 16384);
1334 prev->connection_pool_size, 2048);
13361335 ngx_conf_merge_msec_value(conf->post_accept_timeout,
13371336 prev->post_accept_timeout, 30000);
13381337 ngx_conf_merge_size_value(conf->request_pool_size,
13411340 prev->client_header_timeout, 60000);
13421341 ngx_conf_merge_size_value(conf->client_header_buffer_size,
13431342 prev->client_header_buffer_size, 1024);
1344 ngx_conf_merge_bufs_value(conf->client_large_buffers,
1345 prev->client_large_buffers, 4, ngx_pagesize);
1346 ngx_conf_merge_value(conf->large_client_header,
1347 prev->large_client_header, 1);
1343 ngx_conf_merge_bufs_value(conf->large_client_header_buffers,
1344 prev->large_client_header_buffers,
1345 4, ngx_pagesize);
1346
1347 if (conf->large_client_header_buffers.size < conf->connection_pool_size) {
1348 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
1349 "the \"large_client_header_buffers\" size must be "
1350 "equal to or bigger than \"connection_pool_size\"");
1351 return NGX_CONF_ERROR;
1352 }
1353
13481354 ngx_conf_merge_unsigned_value(conf->restrict_host_names,
13491355 prev->restrict_host_names, 0);
13501356
13861392 lcf->send_lowat = NGX_CONF_UNSET_SIZE;
13871393 lcf->postpone_output = NGX_CONF_UNSET_SIZE;
13881394 lcf->limit_rate = NGX_CONF_UNSET_SIZE;
1389 lcf->discarded_buffer_size = NGX_CONF_UNSET_SIZE;
13901395 lcf->keepalive_timeout = NGX_CONF_UNSET_MSEC;
13911396 lcf->keepalive_header = NGX_CONF_UNSET;
1397 lcf->keepalive_buffers = NGX_CONF_UNSET;
13921398 lcf->lingering_time = NGX_CONF_UNSET_MSEC;
13931399 lcf->lingering_timeout = NGX_CONF_UNSET_MSEC;
13941400 lcf->reset_timedout_connection = NGX_CONF_UNSET;
14731479 ngx_conf_merge_size_value(conf->postpone_output, prev->postpone_output,
14741480 1460);
14751481 ngx_conf_merge_size_value(conf->limit_rate, prev->limit_rate, 0);
1476 ngx_conf_merge_size_value(conf->discarded_buffer_size,
1477 prev->discarded_buffer_size, 1500);
14781482 ngx_conf_merge_msec_value(conf->keepalive_timeout,
14791483 prev->keepalive_timeout, 75000);
14801484 ngx_conf_merge_sec_value(conf->keepalive_header,
14811485 prev->keepalive_header, 0);
1486 ngx_conf_merge_value(conf->keepalive_buffers, prev->keepalive_buffers, 1);
14821487 ngx_conf_merge_msec_value(conf->lingering_time,
14831488 prev->lingering_time, 30000);
14841489 ngx_conf_merge_msec_value(conf->lingering_timeout,
6565 size_t request_pool_size;
6666 size_t client_header_buffer_size;
6767
68 ngx_bufs_t client_large_buffers;
68 ngx_bufs_t large_client_header_buffers;
6969
7070 ngx_msec_t post_accept_timeout;
7171 ngx_msec_t client_header_timeout;
7272
7373 ngx_uint_t restrict_host_names;
74
75 ngx_flag_t large_client_header;
7674 } ngx_http_core_srv_conf_t;
7775
7876
152150 ngx_str_t default_type;
153151
154152 size_t client_max_body_size; /* client_max_body_size */
155 size_t discarded_buffer_size; /* discarded_buffer_size */
156153 size_t client_body_buffer_size; /* client_body_buffer_size */
157154 size_t send_lowat; /* send_lowat */
158155 size_t postpone_output; /* postpone_output */
161158 ngx_msec_t client_body_timeout; /* client_body_timeout */
162159 ngx_msec_t send_timeout; /* send_timeout */
163160 ngx_msec_t keepalive_timeout; /* keepalive_timeout */
164 time_t keepalive_header; /* keepalive_timeout */
165161 ngx_msec_t lingering_time; /* lingering_time */
166162 ngx_msec_t lingering_timeout; /* lingering_timeout */
167163
164 time_t keepalive_header; /* keepalive_timeout */
165
166 ngx_flag_t keepalive_buffers; /* keepalive_buffers */
168167 ngx_flag_t sendfile; /* sendfile */
169168 ngx_flag_t tcp_nopush; /* tcp_nopush */
170169 ngx_flag_t reset_timedout_connection; /* reset_timedout_connection */
1111 static void ngx_http_process_request_line(ngx_event_t *rev);
1212 static void ngx_http_process_request_headers(ngx_event_t *rev);
1313 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);
1616 static ngx_int_t ngx_http_process_request_header(ngx_http_request_t *r);
1717
1818 static void ngx_http_set_write_handler(ngx_http_request_t *r);
194194 return;
195195 }
196196
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) {
201214 ngx_memzero(r, sizeof(ngx_http_request_t));
202215
203216 r->pipeline = hc->pipeline;
217
218 if (hc->nbusy) {
219 r->header_in = hc->busy[0];
220 }
204221
205222 #if (NGX_STAT_STUB)
206223 (*ngx_stat_reading)++;
207224 #endif
208225
209226 } 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
220227 if (!(r = ngx_pcalloc(c->pool, sizeof(ngx_http_request_t)))) {
221228
222229 #if (NGX_STAT_STUB)
354361 }
355362 }
356363
364 if (r->header_in == NULL) {
365 r->header_in = c->buffer;
366 }
367
357368 if (!(r->pool = ngx_create_pool(cscf->request_pool_size, c->log))) {
358369 ngx_http_close_connection(c);
359370 return;
386397
387398 c->single_connection = 1;
388399 r->connection = c;
389 r->header_in = c->buffer;
390400
391401 r->file.fd = NGX_INVALID_FILE;
392402
469479
470480 static void ngx_http_process_request_line(ngx_event_t *rev)
471481 {
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;
479488
480489 c = rev->data;
481490 r = c->data;
488497 return;
489498 }
490499
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) {
551508 return;
552509 }
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) {
578523 ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
579524 ngx_http_close_connection(c);
580525 return;
581526 }
582527
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 */
599533
600534 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;
602536 } 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))) {
607541 ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
608542 ngx_http_close_connection(c);
609543 return;
610544 }
611545
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 {
622635 ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
623636 ngx_http_close_connection(c);
624637 return;
625638 }
626639
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
647657 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);
656680 return;
657681 }
658682
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) {
726696 ngx_http_client_error(r, NGX_HTTP_PARSE_TOO_LONG_URI,
727697 NGX_HTTP_REQUEST_URI_TOO_LARGE);
728698 return;
729699 }
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 }
754702 }
755703
756704
757705 static void ngx_http_process_request_headers(ngx_event_t *rev)
758706 {
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;
765712
766713 c = rev->data;
767714 r = c->data;
774721 return;
775722 }
776723
777 cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module);
778
779724 rc = NGX_AGAIN;
780725
781726 for ( ;; ) {
727
782728 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
783747 n = ngx_http_read_request_header(r);
784748
785749 if (n == NGX_AGAIN || n == NGX_ERROR) {
808772 }
809773
810774 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
811778 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';
835781
836782 if (h->key.len == sizeof("Cookie") - 1
837783 && ngx_strcasecmp(h->key.data, "Cookie") == 0)
838784 {
839 if (!(cookie = ngx_push_array(&r->headers_in.cookies))) {
785 if (!(cookie = ngx_array_push(&r->headers_in.cookies))) {
840786 ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
841787 ngx_http_close_connection(c);
842788 return;
864810 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
865811 "http header: \"%s: %s\"",
866812 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 }
873813
874814 continue;
875815
934874
935875 /* NGX_AGAIN: a header line parsing is still not complete */
936876
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 }
989877 }
990878 }
991879
1044932 }
1045933
1046934
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)
1051937 {
1052938 u_char *old, *new;
1053939 ngx_int_t offset;
1058944 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
1059945 "http alloc large header buffer");
1060946
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
1061957 old = request_line ? r->request_start : r->header_name_start;
1062958
1063959 cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module);
1064960
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 {
1066965 return NGX_DECLINED;
1067966 }
1068967
1071970 if (hc->nfree) {
1072971 b = hc->free[--hc->nfree];
1073972
1074 } else if (hc->nbusy < cscf->client_large_buffers.num) {
973 } else if (hc->nbusy < cscf->large_client_header_buffers.num) {
1075974
1076975 if (hc->busy == NULL) {
1077976 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 *));
1079978 if (hc->busy == NULL) {
1080979 return NGX_ERROR;
1081980 }
1082981 }
1083982
1084983 b = ngx_create_temp_buf(r->connection->pool,
1085 cscf->client_large_buffers.size);
984 cscf->large_client_header_buffers.size);
1086985 if (b == NULL) {
1087986 return NGX_ERROR;
1088987 }
1093992
1094993 hc->busy[hc->nbusy++] = b;
1095994
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
10961007 new = b->start;
10971008
10981009 ngx_memcpy(new, old, r->header_in->last - old);
11021013
11031014 if (request_line) {
11041015 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);
11061022
11071023 r->uri_start = new + (r->uri_start - old);
11081024 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 }
11091040
11101041 if (r->uri_ext) {
11111042 r->uri_ext = new + (r->uri_ext - old);
11261057
11271058 return NGX_OK;
11281059 }
1129
1130 #endif
11311060
11321061
11331062 static ngx_int_t ngx_http_process_request_header(ngx_http_request_t *r)
15581487
15591488 static ngx_int_t ngx_http_read_discarded_body(ngx_http_request_t *r)
15601489 {
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];
15631492
15641493 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
15651494 "http read discarded body");
15681497 return NGX_OK;
15691498 }
15701499
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 }
15791500
15801501 size = r->headers_in.content_length_n;
15811502
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);
15871508
15881509 if (n == NGX_ERROR) {
15891510
15901511 r->closed = 1;
15911512
15921513 /*
1593 * when a client request body is discarded then we already set
1514 * if a client request body is discarded then we already set
15941515 * some HTTP response code for client and we can ignore the error
15951516 */
15961517
16091530
16101531 static void ngx_http_set_keepalive(ngx_http_request_t *r)
16111532 {
1533 ngx_int_t i;
16121534 size_t len;
1613 ngx_buf_t *b;
1535 ngx_buf_t *b, *f;
16141536 ngx_event_t *rev, *wev;
16151537 ngx_connection_t *c;
16161538 ngx_http_connection_t *hc;
16271549 ctx->action = "closing request";
16281550
16291551 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
16301590 ngx_http_close_request(r, 0);
16311591 c->data = hc;
16321592
1633 clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
16341593 ngx_add_timer(rev, clcf->keepalive_timeout);
16351594
16361595 if (ngx_handle_level_read_event(rev) == NGX_ERROR) {
16381597 return;
16391598 }
16401599
1641 b = c->buffer;
16421600 wev = c->write;
16431601 wev->event_handler = ngx_http_empty_handler;
16441602
1645
16461603 if (b->pos < b->last) {
16471604
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 */
16661606
16671607 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "pipelined request");
16681608
16751615 hc->pipeline = 0;
16761616
16771617 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
16781648 rev->event_handler = ngx_http_keepalive_handler;
16791649
16801650 if (wev->active) {
17051675 c->tcp_nopush = NGX_TCP_NOPUSH_UNSET;
17061676 }
17071677
1678 #if 0
1679 /* if "keepalive_buffers off" then we need some other place */
17081680 r->http_state = NGX_HTTP_KEEPALIVE_STATE;
1681 #endif
17091682
17101683 if (rev->ready) {
17111684 ngx_http_keepalive_handler(rev);
17151688
17161689 static void ngx_http_keepalive_handler(ngx_event_t *rev)
17171690 {
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;
17211696
17221697 c = rev->data;
17231698
17271702 ngx_http_close_connection(c);
17281703 return;
17291704 }
1705
1706 hc = c->data;
1707 b = hc->nbusy ? hc->busy[0] : c->buffer;
17301708
17311709 /*
17321710 * MSIE closes a keepalive connection with RST flag
17361714 c->log_error = NGX_ERROR_IGNORE_ECONNRESET;
17371715 ngx_set_socket_errno(0);
17381716
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);
17401718 c->log_error = NGX_ERROR_INFO;
17411719
17421720 if (n == NGX_AGAIN) {
17581736 return;
17591737 }
17601738
1761 c->buffer->last += n;
1739 b->last += n;
17621740 rev->log->handler = ngx_http_log_error;
17631741 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
17741742
17751743 ngx_http_init_request(rev);
17761744 }
18391807 ngx_connection_t *c;
18401808 ngx_http_request_t *r;
18411809 ngx_http_core_loc_conf_t *clcf;
1810 u_char buffer[NGX_HTTP_LINGERING_BUFFER_SIZE];
18421811
18431812 c = rev->data;
18441813 r = c->data;
18591828 return;
18601829 }
18611830
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
18861831 do {
1887 n = c->recv(c, r->discarded_buffer, clcf->discarded_buffer_size);
1832 n = c->recv(c, buffer, NGX_HTTP_LINGERING_BUFFER_SIZE);
18881833
18891834 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0, "lingering read: %d", n);
18901835
18961841
18971842 } while (rev->ready);
18981843
1844 clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
1845
18991846 timer *= 1000;
1847
19001848 if (timer > clcf->lingering_timeout) {
19011849 timer = clcf->lingering_timeout;
19021850 }
00 #ifndef _NGX_HTTP_REQUEST_H_INCLUDED_
11 #define _NGX_HTTP_REQUEST_H_INCLUDED_
2
3
4 #define NGX_HTTP_DISCARD_BUFFER_SIZE 4096
5 #define NGX_HTTP_LINGERING_BUFFER_SIZE 4096
26
37
48 #define NGX_HTTP_VERSION_9 9
6565 #if (NGX_DEBUG && !NGX_NO_DEBUG_MALLOC)
6666
6767 #if __FreeBSD_version >= 500014
68 _malloc_options = "J";
68 _malloc_options = "JAV";
6969 #else
70 malloc_options = "J";
70 malloc_options = "JAV";
7171 #endif
7272
7373 #endif