comparison src/http/ngx_http_event.c @ 87:5f6d848dcbef

nginx-0.0.1-2003-05-13-20:02:32 import
author Igor Sysoev <igor@sysoev.ru>
date Tue, 13 May 2003 16:02:32 +0000
parents 3973260705cc
children 29bf798b583f
comparison
equal deleted inserted replaced
86:3973260705cc 87:5f6d848dcbef
19 19
20 20
21 static void ngx_http_init_request(ngx_event_t *ev); 21 static void ngx_http_init_request(ngx_event_t *ev);
22 static void ngx_http_process_request_line(ngx_event_t *rev); 22 static void ngx_http_process_request_line(ngx_event_t *rev);
23 static void ngx_http_process_request_headers(ngx_event_t *rev); 23 static void ngx_http_process_request_headers(ngx_event_t *rev);
24
25
26
27 static ssize_t ngx_http_read_request_header(ngx_http_request_t *r); 24 static ssize_t ngx_http_read_request_header(ngx_http_request_t *r);
28 25
29 26 static void ngx_http_writer(ngx_event_t *ev);
30 27
31 static int ngx_http_process_request(ngx_event_t *ev);
32 static int ngx_http_process_request_header_line(ngx_http_request_t *r);
33 static int ngx_http_request_handler(ngx_http_request_t *r, int error);
34
35 static int ngx_http_writer(ngx_event_t *ev);
36 static int ngx_http_block_read(ngx_event_t *ev); 28 static int ngx_http_block_read(ngx_event_t *ev);
37 static int ngx_http_read_discarded_body(ngx_event_t *ev); 29 static int ngx_http_read_discarded_body(ngx_event_t *ev);
38 static int ngx_http_set_keepalive(ngx_http_request_t *r); 30
39 static int ngx_http_keepalive_handler(ngx_event_t *ev); 31 static void ngx_http_set_keepalive(ngx_http_request_t *r);
40 static int ngx_http_set_lingering_close(ngx_http_request_t *r); 32 static void ngx_http_keepalive_handler(ngx_event_t *ev);
41 static int ngx_http_lingering_close_handler(ngx_event_t *ev); 33 static void ngx_http_set_lingering_close(ngx_http_request_t *r);
42 34 static void ngx_http_lingering_close_handler(ngx_event_t *ev);
43 static int ngx_http_close_connection(ngx_connection_t *c); 35
44 static void ngx_http_header_parse_error(ngx_http_request_t *r, int parse_err); 36 static void ngx_http_header_parse_error(ngx_http_request_t *r, int parse_err);
45 static size_t ngx_http_log_error(void *data, char *buf, size_t len); 37 static size_t ngx_http_log_error(void *data, char *buf, size_t len);
46 38
47 39
48 /* NGX_HTTP_PARSE_ ... errors */ 40 /* NGX_HTTP_PARSE_ ... errors */
67 { ngx_string("If-Modified-Since"), 59 { ngx_string("If-Modified-Since"),
68 offsetof(ngx_http_headers_in_t, if_modified_since) }, 60 offsetof(ngx_http_headers_in_t, if_modified_since) },
69 { ngx_string("Content-Length"), 61 { ngx_string("Content-Length"),
70 offsetof(ngx_http_headers_in_t, content_length) }, 62 offsetof(ngx_http_headers_in_t, content_length) },
71 63
64 #if 0
65
72 { ngx_string("User-Agent"), offsetof(ngx_http_headers_in_t, user_agent) }, 66 { ngx_string("User-Agent"), offsetof(ngx_http_headers_in_t, user_agent) },
67
68 #endif
73 69
74 { ngx_null_string, 0 } 70 { ngx_null_string, 0 }
75 }; 71 };
76 72
77 73
133 } 129 }
134 130
135 if (ngx_add_event(rev, NGX_READ_EVENT, event) == NGX_ERROR) { 131 if (ngx_add_event(rev, NGX_READ_EVENT, event) == NGX_ERROR) {
136 ngx_http_close_connection(c); 132 ngx_http_close_connection(c);
137 } 133 }
138
139 return;
140 } 134 }
141 135
142 136
143 static void ngx_http_init_request(ngx_event_t *rev) 137 static void ngx_http_init_request(ngx_event_t *rev)
144 { 138 {
200 r->headers_out.content_length = -1; 194 r->headers_out.content_length = -1;
201 r->headers_out.last_modified_time = -1; 195 r->headers_out.last_modified_time = -1;
202 196
203 rev->event_handler = ngx_http_process_request_line; 197 rev->event_handler = ngx_http_process_request_line;
204 ngx_http_process_request_line(rev); 198 ngx_http_process_request_line(rev);
205
206 return;
207 } 199 }
208 200
209 201
210 static void ngx_http_process_request_line(ngx_event_t *rev) 202 static void ngx_http_process_request_line(ngx_event_t *rev)
211 { 203 {
266 258
267 ngx_cpystrn(r->uri.data, r->uri_start, r->uri.len + 1); 259 ngx_cpystrn(r->uri.data, r->uri_start, r->uri.len + 1);
268 260
269 r->request_line.len = r->request_end - r->request_start; 261 r->request_line.len = r->request_end - r->request_start;
270 262
271 /* if the large client header is enabled then 263 /* if the large client headers are enabled then
272 we need to copy a request line */ 264 we need to copy a request line */
273 265
274 if (ngx_http_large_client_header) { 266 if (ngx_http_large_client_header) {
275 267
276 r->request_line.data = ngx_palloc(r->pool, r->request_line.len + 1); 268 r->request_line.data = ngx_palloc(r->pool, r->request_line.len + 1);
344 336
345 ngx_cpystrn(lcx->url, r->uri_start, r->uri_end - r->uri_start + 1); 337 ngx_cpystrn(lcx->url, r->uri_start, r->uri_end - r->uri_start + 1);
346 } 338 }
347 339
348 if (r->http_version == NGX_HTTP_VERSION_9) { 340 if (r->http_version == NGX_HTTP_VERSION_9) {
349 /* STUB */ return; 341 ngx_http_handler(r);
342 return;
350 } 343 }
351 344
352 lcx->action = "reading client request headers"; 345 lcx->action = "reading client request headers";
353 r->headers_in.headers = ngx_create_table(r->pool, 10); 346 r->headers_in.headers = ngx_create_table(r->pool, 10);
354 347
356 && r->header_in->pos == r->header_in->last) 349 && r->header_in->pos == r->header_in->last)
357 { 350 {
358 r->header_in->pos = r->header_in->last = r->header_in->start; 351 r->header_in->pos = r->header_in->last = r->header_in->start;
359 } 352 }
360 353
354 rev->event_handler = ngx_http_process_request_headers;
355 ngx_http_process_request_headers(rev);
356
357 return;
358
361 } else if (rc != NGX_AGAIN) { 359 } else if (rc != NGX_AGAIN) {
362 360
363 /* there was error while a request line parsing */ 361 /* there was error while a request line parsing */
364 362
365 ngx_http_header_parse_error(r, rc); 363 ngx_http_header_parse_error(r, rc);
366 ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST); 364 ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST);
365
367 return; 366 return;
368 } 367 }
369 368
370 /* NGX_AGAIN: a request line parsing is still not complete */ 369 /* NGX_AGAIN: a request line parsing is still not complete */
371 370
381 offset = r->request_start - r->header_in->start; 380 offset = r->request_start - r->header_in->start;
382 381
383 if (offset == 0) { 382 if (offset == 0) {
384 ngx_http_header_parse_error(r, NGX_HTTP_PARSE_TOO_LONG_URI); 383 ngx_http_header_parse_error(r, NGX_HTTP_PARSE_TOO_LONG_URI);
385 ngx_http_finalize_request(r, NGX_HTTP_REQUEST_URI_TOO_LARGE); 384 ngx_http_finalize_request(r, NGX_HTTP_REQUEST_URI_TOO_LARGE);
385
386 return; 386 return;
387 } 387 }
388 388
389 ngx_memcpy(r->header_in->start, r->request_start, 389 ngx_memcpy(r->header_in->start, r->request_start,
390 r->header_in->last - r->request_start); 390 r->header_in->last - r->request_start);
403 } 403 }
404 404
405 } else { 405 } else {
406 ngx_http_header_parse_error(r, NGX_HTTP_PARSE_TOO_LONG_URI); 406 ngx_http_header_parse_error(r, NGX_HTTP_PARSE_TOO_LONG_URI);
407 ngx_http_finalize_request(r, NGX_HTTP_REQUEST_URI_TOO_LARGE); 407 ngx_http_finalize_request(r, NGX_HTTP_REQUEST_URI_TOO_LARGE);
408 return; 408 }
409 } 409 }
410 }
411
412 rev->event_handler = ngx_http_process_request_headers;
413 ngx_http_process_request_headers(rev);
414 410
415 return; 411 return;
416 } 412 }
417 413
418 414
419 static void ngx_http_process_request_headers(ngx_event_t *rev) 415 static void ngx_http_process_request_headers(ngx_event_t *rev)
420 { 416 {
421 int rc, offset; 417 int rc, i, offset;
422 size_t len; 418 size_t len;
423 ssize_t n; 419 ssize_t n;
420 ngx_table_elt_t *h;
424 ngx_connection_t *c; 421 ngx_connection_t *c;
425 ngx_http_request_t *r; 422 ngx_http_request_t *r;
426 ngx_http_log_ctx_t *ctx; 423 ngx_http_log_ctx_t *ctx;
427 424
425 c = (ngx_connection_t *) rev->data;
426 r = (ngx_http_request_t *) c->data;
427
428 ngx_log_debug(rev->log, "http process request header line");
429
428 if (rev->timedout) { 430 if (rev->timedout) {
429 ngx_http_close_request(r, NGX_HTTP_REQUEST_TIME_OUT); 431 ngx_http_close_request(r, NGX_HTTP_REQUEST_TIME_OUT);
430 ngx_http_close_connection(c); 432 ngx_http_close_connection(c);
431 return; 433 return;
432 } 434 }
433 435
434 n = ngx_http_read_request_header(r); 436 rc = NGX_AGAIN;
435
436 if (n == NGX_AGAIN || n == NGX_ERROR) {
437 return;
438 }
439 437
440 for ( ;; ) { 438 for ( ;; ) {
439 if (rc == NGX_AGAIN) {
440 n = ngx_http_read_request_header(r);
441
442 if (n == NGX_AGAIN || n == NGX_ERROR) {
443 return;
444 }
445 }
446
441 rc = ngx_parse_http_header_line(r, r->header_in); 447 rc = ngx_parse_http_header_line(r, r->header_in);
442 448
443 /* a header line has been parsed successfully */
444
445 if (rc == NGX_OK) { 449 if (rc == NGX_OK) {
446 if (ngx_http_process_request_header_line(r) == NGX_ERROR) { 450
447 return NGX_HTTP_INTERNAL_SERVER_ERROR; 451 /* a header line has been parsed successfully */
448 } 452
453 h = ngx_push_table(r->headers_in.headers);
454 if (h == NULL) {
455 ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
456 ngx_http_close_connection(c);
457 return;
458 }
459
460 h->key.len = r->header_name_end - r->header_name_start;
461 h->value.len = r->header_end - r->header_start;
462
463 /* if the large client headers are enabled then
464 we need to copy the header name and value */
465
466 if (ngx_http_large_client_header) {
467 h->key.data = ngx_palloc(r->pool,
468 h->key.len + 1 + h->value.len + 1);
469 if (h->key.data == NULL) {
470 ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
471 ngx_http_close_connection(c);
472 return;
473 }
474
475 h->value.data = h->key.data + h->key.len + 1;
476 ngx_cpystrn(h->key.data, r->header_name_start, h->key.len + 1);
477 ngx_cpystrn(h->value.data, r->header_start, h->value.len + 1);
478
479 } else {
480 h->key.data = r->header_name_start;
481 h->key.data[h->key.len] = '\0';
482 h->value.data = r->header_start;
483 h->value.data[h->value.len] = '\0';
484 }
485
486 for (i = 0; headers_in[i].name.len != 0; i++) {
487 if (headers_in[i].name.len != h->key.len) {
488 continue;
489 }
490
491 if (ngx_strcasecmp(headers_in[i].name.data, h->key.data) == 0) {
492 *((ngx_table_elt_t **)
493 ((char *) &r->headers_in + headers_in[i].offset)) = h;
494 }
495 }
496
497 ngx_log_debug(r->connection->log, "HTTP header: '%s: %s'" _
498 h->key.data _ h->value.data);
449 499
450 if (ngx_http_large_client_header 500 if (ngx_http_large_client_header
451 && r->header_in->pos == r->header_in->last) 501 && r->header_in->pos == r->header_in->last)
452 { 502 {
453 r->header_in->pos = r->header_in->last = r->header_in->start; 503 r->header_in->pos = r->header_in->last = r->header_in->start;
454 } 504 }
455 505
456 return NGX_AGAIN;
457
458 /* a whole header has been parsed successfully */
459
460 } else if (rc == NGX_HTTP_PARSE_HEADER_DONE) { 506 } else if (rc == NGX_HTTP_PARSE_HEADER_DONE) {
507
508 /* a whole header has been parsed successfully */
509
461 ngx_log_debug(r->connection->log, "HTTP header done"); 510 ngx_log_debug(r->connection->log, "HTTP header done");
462 511
463 if (r->headers_in.host) { 512 if (r->headers_in.host) {
464 for (len = 0; len < r->headers_in.host->value.len; len++) { 513 for (len = 0; len < r->headers_in.host->value.len; len++) {
465 if (r->headers_in.host->value.data[len] == ':') { 514 if (r->headers_in.host->value.data[len] == ':') {
470 519
471 } else { 520 } else {
472 if (r->http_version > NGX_HTTP_VERSION_10) { 521 if (r->http_version > NGX_HTTP_VERSION_10) {
473 ngx_http_header_parse_error(r, 522 ngx_http_header_parse_error(r,
474 NGX_HTTP_PARSE_NO_HOST_HEADER); 523 NGX_HTTP_PARSE_NO_HOST_HEADER);
475 return NGX_HTTP_BAD_REQUEST; 524 ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST);
525 return;
476 } 526 }
477 r->headers_in.host_name_len = 0; 527 r->headers_in.host_name_len = 0;
478 } 528 }
479 529
480 if (r->headers_in.content_length) { 530 if (r->headers_in.content_length) {
482 ngx_atoi(r->headers_in.content_length->value.data, 532 ngx_atoi(r->headers_in.content_length->value.data,
483 r->headers_in.content_length->value.len); 533 r->headers_in.content_length->value.len);
484 if (r->headers_in.content_length_n == NGX_ERROR) { 534 if (r->headers_in.content_length_n == NGX_ERROR) {
485 ngx_http_header_parse_error(r, 535 ngx_http_header_parse_error(r,
486 NGX_HTTP_PARSE_INVALID_CL_HEADER); 536 NGX_HTTP_PARSE_INVALID_CL_HEADER);
487 return NGX_HTTP_BAD_REQUEST; 537 ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST);
538 return;
488 } 539 }
489 } 540 }
490 541
491 r->state_handler = NULL; 542 ngx_http_handler(r);
492 return NGX_OK; 543 return;
493
494 /* there was error while a header line parsing */
495 544
496 } else if (rc != NGX_AGAIN) { 545 } else if (rc != NGX_AGAIN) {
546
547 /* there was error while a header line parsing */
548
497 ngx_http_header_parse_error(r, rc); 549 ngx_http_header_parse_error(r, rc);
498 return NGX_HTTP_BAD_REQUEST; 550 ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST);
551
552 return;
499 } 553 }
500 554
501 /* NGX_AGAIN: a header line parsing is still not complete */ 555 /* NGX_AGAIN: a header line parsing is still not complete */
502 556
503 if (r->header_in->last == r->header_in->end) { 557 if (r->header_in->last == r->header_in->end) {
509 offset = r->header_name_start - r->header_in->start; 563 offset = r->header_name_start - r->header_in->start;
510 564
511 if (offset == 0) { 565 if (offset == 0) {
512 ngx_http_header_parse_error(r, 566 ngx_http_header_parse_error(r,
513 NGX_HTTP_PARSE_TOO_LONG_HEADER); 567 NGX_HTTP_PARSE_TOO_LONG_HEADER);
514 return NGX_HTTP_BAD_REQUEST; 568 ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST);
569 return;
515 } 570 }
516 571
517 ngx_memcpy(r->header_in->start, r->header_name_start, 572 ngx_memcpy(r->header_in->start, r->header_name_start,
518 r->header_in->last - r->header_name_start); 573 r->header_in->last - r->header_name_start);
519 574
524 r->header_start -= offset; 579 r->header_start -= offset;
525 r->header_end -= offset; 580 r->header_end -= offset;
526 581
527 } else { 582 } else {
528 ngx_http_header_parse_error(r, NGX_HTTP_PARSE_TOO_LONG_HEADER); 583 ngx_http_header_parse_error(r, NGX_HTTP_PARSE_TOO_LONG_HEADER);
529 return NGX_HTTP_BAD_REQUEST; 584 ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST);
530 } 585 return;
531 586 }
587 }
588 }
589 }
590
591
592 static ssize_t ngx_http_read_request_header(ngx_http_request_t *r)
593 {
594 int event;
595 ssize_t n;
596 ngx_event_t *rev;
597
598 n = r->header_in->last - r->header_in->pos;
599
600 if (n > 0) {
601 return n;
602 }
603
604 n = ngx_event_recv(r->connection, r->header_in->last,
605 r->header_in->end - r->header_in->last);
606
607 if (n == NGX_AGAIN) {
608 if (!r->header_timeout_set) {
609 rev = r->connection->read;
610
611 if (rev->timer_set) {
612 ngx_del_timer(rev);
613 } else {
614 rev->timer_set = 1;
615 }
616
617 ngx_add_timer(rev, ngx_http_client_header_timeout);
618 r->header_timeout_set = 1;
619 }
620
621 if (!rev->active) {
622 if (ngx_event_flags & NGX_HAVE_CLEAR_EVENT) {
623 /* kqueue */
624 event = NGX_CLEAR_EVENT;
625
626 } else {
627 /* select, poll, /dev/poll */
628 event = NGX_LEVEL_EVENT;
629 }
630
631 if (ngx_add_event(rev, NGX_READ_EVENT, event) == NGX_ERROR) {
632 ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
633 ngx_http_close_connection(r->connection);
634 return NGX_ERROR;
635 }
532 } 636 }
533 637
534 return NGX_AGAIN; 638 return NGX_AGAIN;
535 } 639 }
536 } 640
537 641 if (n == 0) {
538 642 ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
539 static int ngx_http_process_request_header_line(ngx_http_request_t *r) 643 "client closed prematurely connection");
540 { 644 }
541 int i; 645
542 ngx_table_elt_t *h; 646 if (n == 0 || n == NGX_ERROR) {
543 647 ngx_http_close_request(r, NGX_HTTP_BAD_REQUEST);
544 ngx_test_null(h, ngx_push_table(r->headers_in.headers), NGX_ERROR); 648 ngx_http_close_connection(r->connection);
545 649 return NGX_ERROR;
546 h->key.len = r->header_name_end - r->header_name_start; 650 }
547 h->value.len = r->header_end - r->header_start; 651
548 652 r->header_in->last += n;
549 /* if the large client headers are enabled then 653
550 we need to copy the header name and value */ 654 return n;
551 655 }
552 if (ngx_http_large_client_header) { 656
553 ngx_test_null(h->key.data, ngx_palloc(r->pool, h->key.len + 1), 657
554 NGX_ERROR); 658 void ngx_http_finalize_request(ngx_http_request_t *r, int error)
555 ngx_test_null(h->value.data, ngx_palloc(r->pool, h->value.len + 1), 659 {
556 NGX_ERROR); 660 int rc, event;
557 ngx_cpystrn(h->key.data, r->header_name_start, h->key.len + 1); 661 ngx_msec_t timeout;
558 ngx_cpystrn(h->value.data, r->header_start, h->value.len + 1); 662 ngx_event_t *rev, *wev;
559
560 } else {
561 h->key.data = r->header_name_start;
562 h->key.data[h->key.len] = '\0';
563 h->value.data = r->header_start;
564 h->value.data[h->value.len] = '\0';
565 }
566
567 for (i = 0; headers_in[i].name.len != 0; i++) {
568 if (headers_in[i].name.len != h->key.len) {
569 continue;
570 }
571
572 if (ngx_strcasecmp(headers_in[i].name.data, h->key.data) == 0) {
573 *((ngx_table_elt_t **)
574 ((char *) &r->headers_in + headers_in[i].offset)) = h;
575 }
576 }
577
578 ngx_log_debug(r->connection->log, "HTTP header: '%s: %s'" _
579 h->key.data _ h->value.data);
580
581 return NGX_OK;
582 }
583
584
585 int ngx_http_finalize_request(ngx_http_request_t *r, int error)
586 {
587 int rc, event;
588 ngx_msec_t timeout;
589 ngx_event_t *rev, *wev;
590 ngx_http_core_loc_conf_t *lcf;
591 663
592 rc = error; 664 rc = error;
593 665
594 if (rc >= NGX_HTTP_SPECIAL_RESPONSE) { 666 if (rc >= NGX_HTTP_SPECIAL_RESPONSE) {
595 667
602 } 674 }
603 675
604 rc = ngx_http_special_response_handler(r, rc); 676 rc = ngx_http_special_response_handler(r, rc);
605 } 677 }
606 678
607 /* a handler has done its work completely */ 679 rev = r->connection->read;
608 680 if (rev->timer_set) {
609 if (rc == NGX_OK) { 681 ngx_del_timer(rev);
610 682 rev->timer_set = 0;
611 if (r->keepalive != 0) { 683 }
612 return ngx_http_set_keepalive(r); 684
613 } 685 wev = r->connection->write;
614 686 if (wev->timer_set) {
615 if (r->lingering_close) { 687 ngx_del_timer(wev);
616 return ngx_http_set_lingering_close(r); 688 wev->timer_set = 0;
617 } 689 }
618 690
619 return ngx_http_close_request(r, 0); 691 if (r->keepalive != 0) {
620 } 692 ngx_http_set_keepalive(r);
621 693
622 /* NGX_AGAIN: a handler has done its work 694 } else if (r->lingering_close) {
623 but the transfer is still not completed */ 695 ngx_http_set_lingering_close(r);
696
697 } else {
698 ngx_http_close_request(r, 0);
699 ngx_http_close_connection(r->connection);
700 }
701 }
702
703
704 void ngx_http_set_write_handler(ngx_http_request_t *r)
705 {
706 int event;
707 ngx_event_t *wev;
708 ngx_http_core_loc_conf_t *lcf;
624 709
625 wev = r->connection->write; 710 wev = r->connection->write;
626 wev->event_handler = ngx_http_writer; 711 wev->event_handler = ngx_http_writer;
627 712
628 if (wev->delayed && wev->ready) { 713 if (wev->delayed && wev->ready) {
629 return NGX_AGAIN; 714 return;
630 } 715 }
631 716
632 lcf = (ngx_http_core_loc_conf_t *) 717 lcf = (ngx_http_core_loc_conf_t *)
633 ngx_http_get_module_loc_conf(r->main ? r->main : r, 718 ngx_http_get_module_loc_conf(r->main ? r->main : r,
634 ngx_http_core_module_ctx); 719 ngx_http_core_module_ctx);
635 ngx_add_timer(wev, lcf->send_timeout); 720 ngx_add_timer(wev, lcf->send_timeout);
636 wev->timer_set = 1; 721 wev->timer_set = 1;
637 722
638 #if (USE_KQUEUE)
639
640 #if (HAVE_LOWAT_EVENT) /* kqueue's NOTE_LOWAT */
641 wev->lowat = lcf->send_lowat;
642 #endif
643
644 if (ngx_add_event(wev, NGX_WRITE_EVENT, NGX_CLEAR_EVENT) == NGX_ERROR) {
645 return ngx_http_close_request(r, 0);
646 }
647
648 return rc;
649
650 #else
651
652 /* aio, iocp, epoll */
653
654 if (ngx_event_flags & (NGX_HAVE_AIO_EVENT|NGX_HAVE_EDGE_EVENT)) { 723 if (ngx_event_flags & (NGX_HAVE_AIO_EVENT|NGX_HAVE_EDGE_EVENT)) {
655 return rc; 724 /* aio, iocp, epoll */
725 return;
656 } 726 }
657 727
658 #if (HAVE_LOWAT_EVENT) /* kqueue's NOTE_LOWAT */ 728 #if (HAVE_LOWAT_EVENT) /* kqueue's NOTE_LOWAT */
659 729
660 if (ngx_event_flags & NGX_HAVE_LOWAT_EVENT) { 730 if (ngx_event_flags & NGX_HAVE_LOWAT_EVENT) {
661 wev->lowat = lcf->send_lowat; 731 wev->lowat = lcf->send_lowat;
662 } 732 }
663 733
664 #endif 734 #endif
665 735
666 /* kqueue */
667
668 if (ngx_event_flags & NGX_HAVE_CLEAR_EVENT) { 736 if (ngx_event_flags & NGX_HAVE_CLEAR_EVENT) {
737 /* kqueue */
669 event = NGX_CLEAR_EVENT; 738 event = NGX_CLEAR_EVENT;
670 739
671 /* select, poll, /dev/poll */
672
673 } else { 740 } else {
741 /* select, poll, /dev/poll */
674 event = NGX_LEVEL_EVENT; 742 event = NGX_LEVEL_EVENT;
675 } 743 }
676 744
677 if (ngx_add_event(wev, NGX_WRITE_EVENT, event) == NGX_ERROR) { 745 if (ngx_add_event(wev, NGX_WRITE_EVENT, event) == NGX_ERROR) {
678 return ngx_http_close_request(r, 0); 746 ngx_http_close_request(r, 0);
679 } 747 ngx_http_close_connection(r->connection);
680 748 }
681 return rc; 749 }
682 750
683 #endif /* USE_KQUEUE */ 751
684 } 752 static void ngx_http_writer(ngx_event_t *wev)
685
686
687 static int ngx_http_writer(ngx_event_t *wev)
688 { 753 {
689 int rc; 754 int rc;
690 ngx_msec_t timeout; 755 ngx_msec_t timeout;
756 ngx_event_t *rev;
691 ngx_connection_t *c; 757 ngx_connection_t *c;
692 ngx_http_request_t *r; 758 ngx_http_request_t *r;
693 ngx_http_core_loc_conf_t *lcf; 759 ngx_http_core_loc_conf_t *lcf;
694 760
695 c = (ngx_connection_t *) wev->data; 761 c = (ngx_connection_t *) wev->data;
696 r = (ngx_http_request_t *) c->data; 762 r = (ngx_http_request_t *) c->data;
697 763
698 rc = ngx_http_output_filter(r, NULL); 764 rc = ngx_http_output_filter(r, NULL);
699 765
700 ngx_log_debug(c->log, "output filter in writer: %d" _ rc); 766 ngx_log_debug(c->log, "writer output filter: %d" _ rc);
701 767
702 if (rc == NGX_AGAIN) { 768 if (rc == NGX_AGAIN) {
703 769
704 lcf = (ngx_http_core_loc_conf_t *) 770 lcf = (ngx_http_core_loc_conf_t *)
705 ngx_http_get_module_loc_conf(r->main ? r->main : r, 771 ngx_http_get_module_loc_conf(r->main ? r->main : r,
710 wev->timer_set = 1; 776 wev->timer_set = 1;
711 } 777 }
712 778
713 ngx_add_timer(wev, lcf->send_timeout); 779 ngx_add_timer(wev, lcf->send_timeout);
714 780
715 return rc; 781 return;
716 } 782 }
717 783
718 if (rc == NGX_ERROR) 784 if (rc == NGX_ERROR) {
719 return rc; 785 ngx_http_close_request(r, 0);
786 ngx_http_close_connection(c);
787 return;
788 }
720 789
721 /* rc == NGX_OK */ 790 /* rc == NGX_OK */
722 791
723 ngx_log_debug(c->log, "http writer done"); 792 ngx_log_debug(c->log, "http writer done");
724 793
794 rev = r->connection->read;
795 if (rev->timer_set) {
796 ngx_del_timer(rev);
797 rev->timer_set = 0;
798 }
799
800 if (wev->timer_set) {
801 ngx_del_timer(wev);
802 wev->timer_set = 0;
803 }
804
725 if (r->keepalive != 0) { 805 if (r->keepalive != 0) {
726 return ngx_http_set_keepalive(r); 806 ngx_http_set_keepalive(r);
727 } 807 }
728 808
729 if (r->lingering_close) { 809 if (r->lingering_close) {
730 return ngx_http_set_lingering_close(r); 810 ngx_http_set_lingering_close(r);
731 } 811
732 812 } else {
733 return ngx_http_close_request(r, 0); 813 ngx_http_close_request(r, 0);
734 } 814 }
735
736
737 static ssize_t ngx_http_read_request_header(ngx_http_request_t *r)
738 {
739 ssize_t n;
740 ngx_event_t *rev;
741
742 n = r->header_in->last - r->header_in->pos;
743
744 if (n > 0) {
745 return n;
746 }
747
748 n = ngx_event_recv(r->connection, r->header_in->last,
749 r->header_in->end - r->header_in->last);
750
751 if (n == NGX_AGAIN) {
752 if (!r->header_timeout_set) {
753 rev = r->connection->read;
754
755 if (rev->timer_set) {
756 ngx_del_timer(rev);
757 } else {
758 rev->timer_set = 1;
759 }
760
761 ngx_add_timer(rev, ngx_http_client_header_timeout);
762 r->header_timeout_set = 1;
763 }
764
765 return NGX_AGAIN;
766 }
767
768 if (n == 0) {
769 ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
770 "client closed prematurely connection");
771
772 if (n == 0 || n == NGX_ERROR) {
773 ngx_http_close_request(r, NGX_HTTP_BAD_REQUEST);
774 ngx_http_close_connection(c);
775 return NGX_ERROR;
776 }
777
778 r->header_in->last += n;
779
780 return n;
781 } 815 }
782 816
783 817
784 static int ngx_http_block_read(ngx_event_t *ev) 818 static int ngx_http_block_read(ngx_event_t *ev)
785 { 819 {
803 837
804 #endif /* USE_KQUEUE */ 838 #endif /* USE_KQUEUE */
805 } 839 }
806 840
807 841
842 /* STUB */
843 int ngx_http_discard_body(ngx_http_request_t *r)
844 {
845 return NGX_OK;
846 }
847
848 #if 0
808 /* TODO */ 849 /* TODO */
809 int ngx_http_discard_body(ngx_http_request_t *r) 850 int ngx_http_discard_body(ngx_http_request_t *r)
810 { 851 {
811 ngx_event_t *ev; 852 ngx_event_t *ev;
812 853
872 913
873 r->headers_in.content_length_n -= n; 914 r->headers_in.content_length_n -= n;
874 /* XXX: what if r->client_content_length == 0 ? */ 915 /* XXX: what if r->client_content_length == 0 ? */
875 return NGX_OK; 916 return NGX_OK;
876 } 917 }
877 918 #endif
878 919
879 static int ngx_http_set_keepalive(ngx_http_request_t *r) 920
921 static void ngx_http_set_keepalive(ngx_http_request_t *r)
880 { 922 {
881 int len, blocked; 923 int len, blocked;
882 ngx_hunk_t *h; 924 ngx_hunk_t *h;
883 ngx_event_t *rev, *wev; 925 ngx_event_t *rev, *wev;
884 ngx_connection_t *c; 926 ngx_connection_t *c;
891 ctx->action = "closing request"; 933 ctx->action = "closing request";
892 ngx_http_close_request(r, 0); 934 ngx_http_close_request(r, 0);
893 935
894 if (rev->blocked && (ngx_event_flags & NGX_USE_LEVEL_EVENT)) { 936 if (rev->blocked && (ngx_event_flags & NGX_USE_LEVEL_EVENT)) {
895 if (ngx_add_event(rev, NGX_READ_EVENT, NGX_LEVEL_EVENT) == NGX_ERROR) { 937 if (ngx_add_event(rev, NGX_READ_EVENT, NGX_LEVEL_EVENT) == NGX_ERROR) {
896 return NGX_ERROR; 938 ngx_http_close_connection(c);
897 } 939 return;
940 }
941
898 blocked = 1; 942 blocked = 1;
899 rev->blocked = 0; 943 rev->blocked = 0;
900 944
901 } else { 945 } else {
902 blocked = 0; 946 blocked = 0;
920 h->last = h->start + len; 964 h->last = h->start + len;
921 } 965 }
922 966
923 c->pipeline = 1; 967 c->pipeline = 1;
924 ctx->action = "reading client pipelined request line"; 968 ctx->action = "reading client pipelined request line";
925 return ngx_http_init_request(rev); 969 ngx_http_init_request(rev);
970 return;
926 } 971 }
927 972
928 c->pipeline = 0; 973 c->pipeline = 0;
929 974
930 h->pos = h->last = h->start; 975 h->pos = h->last = h->start;
931 rev->event_handler = ngx_http_keepalive_handler; 976 rev->event_handler = ngx_http_keepalive_handler;
932 wev = c->write; 977 wev = c->write;
933 978
934 if (wev->active && (ngx_event_flags & NGX_USE_LEVEL_EVENT)) { 979 if (wev->active && (ngx_event_flags & NGX_USE_LEVEL_EVENT)) {
935 if (ngx_del_event(wev, NGX_WRITE_EVENT, 0) == NGX_ERROR) { 980 if (ngx_del_event(wev, NGX_WRITE_EVENT, 0) == NGX_ERROR) {
936 return NGX_ERROR; 981 ngx_http_close_connection(c);
982 return;
937 } 983 }
938 } 984 }
939 985
940 ctx->action = "keepalive"; 986 ctx->action = "keepalive";
941 987
942 #if (HAVE_AIO_EVENT) /* aio, iocp */
943
944 if ((ngx_event_flags & NGX_HAVE_AIO_EVENT) || blocked) { 988 if ((ngx_event_flags & NGX_HAVE_AIO_EVENT) || blocked) {
945 return ngx_http_keepalive_handler(rev); 989 ngx_http_keepalive_handler(rev);
946 } 990 }
947 991 }
948 #else 992
949 993
950 if (blocked) { 994 static void ngx_http_keepalive_handler(ngx_event_t *rev)
951 return ngx_http_keepalive_handler(rev);
952 }
953
954 #endif
955
956 return NGX_OK;
957 }
958
959
960 static int ngx_http_keepalive_handler(ngx_event_t *rev)
961 { 995 {
962 ssize_t n; 996 ssize_t n;
963 ngx_connection_t *c; 997 ngx_connection_t *c;
964 ngx_http_log_ctx_t *lctx; 998 ngx_http_log_ctx_t *lctx;
965 999
966 c = (ngx_connection_t *) rev->data; 1000 c = (ngx_connection_t *) rev->data;
967 1001
968 ngx_log_debug(c->log, "http keepalive handler"); 1002 ngx_log_debug(c->log, "http keepalive handler");
969 1003
970 if (rev->timedout) { 1004 if (rev->timedout) {
971 return NGX_ERROR; /* to close connection */ 1005 ngx_http_close_connection(c);
1006 return;
972 } 1007 }
973 1008
974 /* MSIE closes a keepalive connection with RST flag 1009 /* MSIE closes a keepalive connection with RST flag
975 so we ignore ECONNRESET here */ 1010 so we ignore ECONNRESET here */
976 1011
977 rev->ignore_econnreset = 1; 1012 rev->ignore_econnreset = 1;
978 ngx_set_socket_errno(0); 1013 ngx_set_socket_errno(0);
979 n = ngx_event_recv(c, c->buffer->last, c->buffer->end - c->buffer->last); 1014 n = ngx_event_recv(c, c->buffer->last, c->buffer->end - c->buffer->last);
980 rev->ignore_econnreset = 0; 1015 rev->ignore_econnreset = 0;
981 1016
982 if (n == NGX_AGAIN || n == NGX_ERROR) { 1017 if (n == NGX_AGAIN) {
983 return n; 1018 return;
1019 }
1020
1021 if (n == NGX_ERROR) {
1022 ngx_http_close_connection(c);
1023 return;
984 } 1024 }
985 1025
986 lctx = (ngx_http_log_ctx_t *) rev->log->data; 1026 lctx = (ngx_http_log_ctx_t *) rev->log->data;
987 rev->log->handler = NULL; 1027 rev->log->handler = NULL;
988 1028
989 if (n == 0) { 1029 if (n == 0) {
990 ngx_log_error(NGX_LOG_INFO, c->log, ngx_socket_errno, 1030 ngx_log_error(NGX_LOG_INFO, c->log, ngx_socket_errno,
991 "client %s closed keepalive connection", lctx->client); 1031 "client %s closed keepalive connection", lctx->client);
992 return NGX_ERROR; /* to close connection */ 1032 ngx_http_close_connection(c);
1033 return;
993 } 1034 }
994 1035
995 c->buffer->last += n; 1036 c->buffer->last += n;
996 rev->log->handler = ngx_http_log_error; 1037 rev->log->handler = ngx_http_log_error;
997 lctx->action = "reading client request line"; 1038 lctx->action = "reading client request line";
998 1039
999 return ngx_http_init_request(rev); 1040 ngx_http_init_request(rev);
1000 } 1041 }
1001 1042
1002 1043
1003 static int ngx_http_set_lingering_close(ngx_http_request_t *r) 1044 static void ngx_http_set_lingering_close(ngx_http_request_t *r)
1004 { 1045 {
1005 ngx_event_t *rev; 1046 ngx_event_t *rev;
1006 ngx_connection_t *c; 1047 ngx_connection_t *c;
1007 ngx_http_core_loc_conf_t *lcf; 1048 ngx_http_core_loc_conf_t *lcf;
1008 1049
1011 1052
1012 lcf = (ngx_http_core_loc_conf_t *) 1053 lcf = (ngx_http_core_loc_conf_t *)
1013 ngx_http_get_module_loc_conf(r, ngx_http_core_module_ctx); 1054 ngx_http_get_module_loc_conf(r, ngx_http_core_module_ctx);
1014 1055
1015 r->lingering_time = ngx_time() + lcf->lingering_time / 1000; 1056 r->lingering_time = ngx_time() + lcf->lingering_time / 1000;
1016 r->connection->read->event_handler = ngx_http_lingering_close_handler; 1057 rev->event_handler = ngx_http_lingering_close_handler;
1017 1058
1018 if (rev->timer_set) { 1059 if (rev->timer_set) {
1019 ngx_del_timer(rev); 1060 ngx_del_timer(rev);
1020 } else { 1061 } else {
1021 rev->timer_set = 1; 1062 rev->timer_set = 1;
1023 1064
1024 ngx_add_timer(rev, lcf->lingering_timeout); 1065 ngx_add_timer(rev, lcf->lingering_timeout);
1025 1066
1026 if (rev->blocked && (ngx_event_flags & NGX_USE_LEVEL_EVENT)) { 1067 if (rev->blocked && (ngx_event_flags & NGX_USE_LEVEL_EVENT)) {
1027 if (ngx_add_event(rev, NGX_READ_EVENT, NGX_LEVEL_EVENT) == NGX_ERROR) { 1068 if (ngx_add_event(rev, NGX_READ_EVENT, NGX_LEVEL_EVENT) == NGX_ERROR) {
1028 return ngx_http_close_request(r, 0); 1069 ngx_http_close_request(r, 0);
1070 ngx_http_close_connection(c);
1071 return;
1029 } 1072 }
1030 rev->blocked = 0; 1073 rev->blocked = 0;
1031 } 1074 }
1032
1033 #if !(USE_KQUEUE)
1034 1075
1035 if (c->write->active && (ngx_event_flags & NGX_USE_LEVEL_EVENT)) { 1076 if (c->write->active && (ngx_event_flags & NGX_USE_LEVEL_EVENT)) {
1036 if (ngx_del_event(c->write, NGX_WRITE_EVENT, 0) == NGX_ERROR) { 1077 if (ngx_del_event(c->write, NGX_WRITE_EVENT, 0) == NGX_ERROR) {
1037 return ngx_http_close_request(r, 0); 1078 ngx_http_close_request(r, 0);
1038 } 1079 ngx_http_close_connection(c);
1039 } 1080 return;
1040 1081 }
1041 #endif 1082 }
1042 1083
1043 if (ngx_shutdown_socket(c->fd, NGX_WRITE_SHUTDOWN) == -1) { 1084 if (ngx_shutdown_socket(c->fd, NGX_WRITE_SHUTDOWN) == -1) {
1044 ngx_log_error(NGX_LOG_CRIT, c->log, ngx_socket_errno, 1085 ngx_log_error(NGX_LOG_CRIT, c->log, ngx_socket_errno,
1045 ngx_shutdown_socket_n " failed"); 1086 ngx_shutdown_socket_n " failed");
1046 return ngx_http_close_request(r, 0); 1087 ngx_http_close_request(r, 0);
1047 } 1088 ngx_http_close_connection(c);
1048 1089 return;
1049 #if (USE_KQUEUE) 1090 }
1050
1051 if (rev->ready) {
1052 return ngx_http_lingering_close_handler(rev);
1053 }
1054
1055 #else
1056 1091
1057 if (rev->ready || (ngx_event_flags & NGX_HAVE_AIO_EVENT)) { 1092 if (rev->ready || (ngx_event_flags & NGX_HAVE_AIO_EVENT)) {
1058 return ngx_http_lingering_close_handler(rev); 1093 ngx_http_lingering_close_handler(rev);
1059 } 1094 }
1060 1095 }
1061 #endif 1096
1062 1097
1063 return NGX_OK; 1098 static void ngx_http_lingering_close_handler(ngx_event_t *rev)
1064 }
1065
1066
1067 static int ngx_http_lingering_close_handler(ngx_event_t *rev)
1068 { 1099 {
1069 ssize_t n; 1100 ssize_t n;
1070 ngx_msec_t timer; 1101 ngx_msec_t timer;
1071 ngx_connection_t *c; 1102 ngx_connection_t *c;
1072 ngx_http_request_t *r; 1103 ngx_http_request_t *r;
1076 r = (ngx_http_request_t *) c->data; 1107 r = (ngx_http_request_t *) c->data;
1077 1108
1078 ngx_log_debug(c->log, "http lingering close handler"); 1109 ngx_log_debug(c->log, "http lingering close handler");
1079 1110
1080 if (rev->timedout) { 1111 if (rev->timedout) {
1081 return ngx_http_close_request(r, 0); 1112 ngx_http_close_request(r, 0);
1113 ngx_http_close_connection(c);
1114 return;
1082 } 1115 }
1083 1116
1084 timer = r->lingering_time - ngx_time(); 1117 timer = r->lingering_time - ngx_time();
1085 if (timer <= 0) { 1118 if (timer <= 0) {
1086 return ngx_http_close_request(r, 0); 1119 ngx_http_close_request(r, 0);
1120 ngx_http_close_connection(c);
1121 return;
1087 } 1122 }
1088 1123
1089 lcf = (ngx_http_core_loc_conf_t *) 1124 lcf = (ngx_http_core_loc_conf_t *)
1090 ngx_http_get_module_loc_conf(r, ngx_http_core_module_ctx); 1125 ngx_http_get_module_loc_conf(r, ngx_http_core_module_ctx);
1091 1126
1098 if ((size_t)(r->header_in->end - r->header_in->last) 1133 if ((size_t)(r->header_in->end - r->header_in->last)
1099 >= lcf->discarded_buffer_size) { 1134 >= lcf->discarded_buffer_size) {
1100 r->discarded_buffer = r->header_in->last; 1135 r->discarded_buffer = r->header_in->last;
1101 1136
1102 } else { 1137 } else {
1103 ngx_test_null(r->discarded_buffer, 1138 r->discarded_buffer = ngx_palloc(c->pool,
1104 ngx_palloc(c->pool, lcf->discarded_buffer_size), 1139 lcf->discarded_buffer_size);
1105 ngx_http_close_request(r, 0)); 1140 if (r->discarded_buffer) {
1141 ngx_http_close_request(r, 0);
1142 ngx_http_close_connection(c);
1143 return;
1144 }
1106 } 1145 }
1107 } 1146 }
1108 1147
1109 do { 1148 do {
1110 n = ngx_event_recv(c, r->discarded_buffer, lcf->discarded_buffer_size); 1149 n = ngx_event_recv(c, r->discarded_buffer, lcf->discarded_buffer_size);
1111 1150
1112 ngx_log_debug(c->log, "lingering read: %d" _ n); 1151 ngx_log_debug(c->log, "lingering read: %d" _ n);
1113 1152
1114 if (n == NGX_ERROR || n == 0) { 1153 if (n == NGX_ERROR || n == 0) {
1115 return ngx_http_close_request(r, 0); 1154 ngx_http_close_request(r, 0);
1155 ngx_http_close_connection(c);
1156 return;
1116 } 1157 }
1117 1158
1118 } while (rev->ready); 1159 } while (rev->ready);
1119 1160
1120 timer *= 1000; 1161 timer *= 1000;
1127 } else { 1168 } else {
1128 rev->timer_set = 1; 1169 rev->timer_set = 1;
1129 } 1170 }
1130 ngx_add_timer(rev, timer); 1171 ngx_add_timer(rev, timer);
1131 1172
1132 return NGX_OK; 1173 return;
1133 } 1174 }
1134 1175
1135 1176
1136 static void ngx_http_close_connection(ngx_connection_t *c) 1177 void ngx_http_close_request(ngx_http_request_t *r, int error)
1178 {
1179 ngx_http_log_ctx_t *ctx;
1180
1181 ngx_log_debug(r->connection->log, "close http request");
1182
1183 if (r->pool == NULL) {
1184 ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0,
1185 "http already closed");
1186 return;
1187 }
1188
1189 if (error) {
1190 r->headers_out.status = error;
1191 }
1192
1193 ngx_http_log_handler(r);
1194
1195 if (r->file.fd != NGX_INVALID_FILE) {
1196 if (ngx_close_file(r->file.fd) == NGX_FILE_ERROR) {
1197 ngx_log_error(NGX_LOG_ALERT, r->connection->log, ngx_errno,
1198 ngx_close_file_n " \"%s\" failed", r->file.name.data);
1199 }
1200 }
1201
1202 /* ctx->url was allocated from r->pool */
1203 ctx = (ngx_http_log_ctx_t *) r->connection->log->data;
1204 ctx->url = NULL;
1205
1206 ngx_destroy_pool(r->pool);
1207 }
1208
1209
1210 void ngx_http_close_connection(ngx_connection_t *c)
1137 { 1211 {
1138 ngx_log_debug(c->log, "close connection: %d" _ c->fd); 1212 ngx_log_debug(c->log, "close connection: %d" _ c->fd);
1139 1213
1140 if (c->fd == -1) { 1214 if (c->pool == NULL) {
1141 ngx_log_error(NGX_LOG_ALERT, c->log, 0, "connection already closed"); 1215 ngx_log_error(NGX_LOG_ALERT, c->log, 0, "connection already closed");
1142 return; 1216 return;
1143 } 1217 }
1144 1218
1145 if (c->read->timer_set) { 1219 if (c->read->timer_set) {
1166 } 1240 }
1167 1241
1168 c->fd = -1; 1242 c->fd = -1;
1169 1243
1170 ngx_destroy_pool(c->pool); 1244 ngx_destroy_pool(c->pool);
1171
1172 return;
1173 }
1174
1175 static int ngx_http_close_connection0(ngx_event_t *ev)
1176 {
1177 return ngx_event_close_connection(ev);
1178 } 1245 }
1179 1246
1180 1247
1181 static void ngx_http_header_parse_error(ngx_http_request_t *r, int parse_err) 1248 static void ngx_http_header_parse_error(ngx_http_request_t *r, int parse_err)
1182 { 1249 {