Mercurial > hg > nginx
comparison src/http/ngx_http_event.c @ 59:e8cdc2989cee
nginx-0.0.1-2003-02-06-20:21:13 import
author | Igor Sysoev <igor@sysoev.ru> |
---|---|
date | Thu, 06 Feb 2003 17:21:13 +0000 |
parents | a499e0d1f16e |
children | 50186b49f2ad |
comparison
equal
deleted
inserted
replaced
58:6b13b1cadabe | 59:e8cdc2989cee |
---|---|
13 #include <ngx_event_timer.h> | 13 #include <ngx_event_timer.h> |
14 #include <ngx_inet.h> | 14 #include <ngx_inet.h> |
15 #include <ngx_http.h> | 15 #include <ngx_http.h> |
16 #include <ngx_http_config.h> | 16 #include <ngx_http_config.h> |
17 #include <ngx_http_core_module.h> | 17 #include <ngx_http_core_module.h> |
18 | 18 #include <ngx_http_output_filter.h> |
19 | 19 |
20 int ngx_http_init_connection(ngx_connection_t *c); | |
21 | 20 |
22 static int ngx_http_init_request(ngx_event_t *ev); | 21 static int ngx_http_init_request(ngx_event_t *ev); |
23 static int ngx_http_process_request_header(ngx_event_t *ev); | 22 static int ngx_http_process_request_header(ngx_event_t *ev); |
24 | 23 |
25 static int ngx_http_process_request_line(ngx_http_request_t *r); | 24 static int ngx_http_process_request_line(ngx_http_request_t *r); |
87 ctx->action = "reading client request line"; | 86 ctx->action = "reading client request line"; |
88 c->log->data = ctx; | 87 c->log->data = ctx; |
89 c->log->handler = ngx_http_log_error; | 88 c->log->handler = ngx_http_log_error; |
90 | 89 |
91 #if (HAVE_DEFERRED_ACCEPT) | 90 #if (HAVE_DEFERRED_ACCEPT) |
91 | |
92 if (ev->ready) { | 92 if (ev->ready) { |
93 return ngx_http_init_request(ev); | 93 return ngx_http_init_request(ev); |
94 } | 94 } |
95 | |
95 #endif | 96 #endif |
96 | 97 |
97 ngx_add_timer(ev, c->post_accept_timeout); | 98 ngx_add_timer(ev, c->post_accept_timeout); |
98 ev->timer_set = 1; | 99 ev->timer_set = 1; |
99 | 100 |
101 | 102 |
102 return ngx_add_event(ev, NGX_READ_EVENT, NGX_CLEAR_EVENT); | 103 return ngx_add_event(ev, NGX_READ_EVENT, NGX_CLEAR_EVENT); |
103 | 104 |
104 #else | 105 #else |
105 | 106 |
106 #if (HAVE_CLEAR_EVENT) | 107 #if (HAVE_CLEAR_EVENT) /* kqueue */ |
108 | |
107 if (ngx_event_flags & NGX_HAVE_CLEAR_EVENT) { | 109 if (ngx_event_flags & NGX_HAVE_CLEAR_EVENT) { |
108 return ngx_add_event(ev, NGX_READ_EVENT, NGX_CLEAR_EVENT); | 110 return ngx_add_event(ev, NGX_READ_EVENT, NGX_CLEAR_EVENT); |
109 } | 111 } |
110 #endif | 112 |
111 | 113 #endif |
112 #if (HAVE_EDGE_EVENT) | 114 |
115 #if (HAVE_EDGE_EVENT) /* epoll */ | |
116 | |
113 if (ngx_event_flags & NGX_HAVE_EDGE_EVENT) { | 117 if (ngx_event_flags & NGX_HAVE_EDGE_EVENT) { |
114 if (ngx_add_event(ev, NGX_READ_EVENT, NGX_EDGE_EVENT) == NGX_ERROR) { | 118 if (ngx_add_event(ev, NGX_READ_EVENT, NGX_EDGE_EVENT) == NGX_ERROR) { |
115 return NGX_ERROR; | 119 return NGX_ERROR; |
116 } | 120 } |
117 return ngx_http_init_request(ev); | 121 return ngx_http_init_request(ev); |
118 } | 122 } |
119 #endif | 123 |
120 | 124 #endif |
121 #if (HAVE_AIO_EVENT) | 125 |
126 #if (HAVE_AIO_EVENT) /* aio, iocp */ | |
127 | |
122 if (ngx_event_flags & NGX_HAVE_AIO_EVENT) { | 128 if (ngx_event_flags & NGX_HAVE_AIO_EVENT) { |
123 return ngx_http_init_request(ev); | 129 return ngx_http_init_request(ev); |
124 } | 130 } |
125 #endif | 131 |
132 #endif /* HAVE_AIO_EVENT */ | |
133 | |
134 /* select, poll, /dev/poll */ | |
126 | 135 |
127 return ngx_add_event(ev, NGX_READ_EVENT, NGX_LEVEL_EVENT); | 136 return ngx_add_event(ev, NGX_READ_EVENT, NGX_LEVEL_EVENT); |
128 | 137 |
129 #endif /* USE_KQUEUE */ | 138 #endif /* USE_KQUEUE */ |
130 } | 139 } |
180 } | 189 } |
181 | 190 |
182 | 191 |
183 static int ngx_http_process_request_header(ngx_event_t *ev) | 192 static int ngx_http_process_request_header(ngx_event_t *ev) |
184 { | 193 { |
185 int n, rc; | 194 int n, rc; |
186 ngx_connection_t *c; | 195 ngx_connection_t *c; |
187 ngx_http_request_t *r; | 196 ngx_http_request_t *r; |
188 | 197 |
189 c = (ngx_connection_t *) ev->data; | 198 c = (ngx_connection_t *) ev->data; |
190 r = (ngx_http_request_t *) c->data; | 199 r = (ngx_http_request_t *) c->data; |
191 | 200 |
192 ngx_log_debug(ev->log, "http process request"); | 201 ngx_log_debug(ev->log, "http process request"); |
193 | 202 |
194 if (r->header_read) { | 203 #if (HAVE_AIO_EVENT) |
195 r->header_read = 0; | 204 do { |
196 ngx_log_debug(ev->log, "http preread %d" _ | 205 #endif |
197 r->header_in->last.mem - r->header_in->pos.mem); | 206 |
198 | 207 if (r->header_read) { |
199 } else { | 208 r->header_read = 0; |
200 n = ngx_event_recv(c, r->header_in->last.mem, | 209 ngx_log_debug(ev->log, "http preread %d" _ |
201 r->header_in->end - r->header_in->last.mem); | 210 r->header_in->last.mem - r->header_in->pos.mem); |
202 | 211 |
203 if (n == NGX_AGAIN) { | 212 } else { |
204 if (!r->header_timeout_set) { | 213 n = ngx_event_recv(c, r->header_in->last.mem, |
205 | 214 r->header_in->end - r->header_in->last.mem); |
206 if (ev->timer_set) { | 215 |
207 ngx_del_timer(ev); | 216 if (n == NGX_AGAIN) { |
208 } else { | 217 if (!r->header_timeout_set) { |
209 ev->timer_set = 1; | 218 |
219 if (ev->timer_set) { | |
220 ngx_del_timer(ev); | |
221 } else { | |
222 ev->timer_set = 1; | |
223 } | |
224 | |
225 ngx_add_timer(ev, ngx_http_client_header_timeout); | |
226 r->header_timeout_set = 1; | |
210 } | 227 } |
211 | 228 return NGX_AGAIN; |
212 ngx_add_timer(ev, ngx_http_client_header_timeout); | |
213 r->header_timeout_set = 1; | |
214 } | 229 } |
215 return NGX_AGAIN; | 230 |
216 } | 231 if (n == NGX_ERROR) |
217 | 232 return ngx_http_close_request(r); |
218 if (n == NGX_ERROR) | 233 |
219 return ngx_http_close_request(r); | 234 ngx_log_debug(ev->log, "http read %d" _ n); |
220 | 235 |
221 ngx_log_debug(ev->log, "http read %d" _ n); | 236 if (n == 0) { |
222 | 237 ngx_log_error(NGX_LOG_INFO, c->log, 0, |
223 if (n == 0) { | 238 "client has prematurely closed connection"); |
224 ngx_log_error(NGX_LOG_INFO, c->log, 0, | 239 return ngx_http_close_request(r); |
225 "client has prematurely closed connection"); | 240 } |
226 return ngx_http_close_request(r); | 241 |
227 } | 242 r->header_in->last.mem += n; |
228 | 243 } |
229 r->header_in->last.mem += n; | 244 |
230 } | 245 /* state_handlers are called in following order: |
231 | 246 ngx_http_process_request_line(r) |
232 /* state_handlers are called in following order: | 247 ngx_http_process_request_headers(r) */ |
233 ngx_http_process_request_line(r) | 248 |
234 ngx_http_process_request_headers(r) */ | 249 do { |
235 | 250 rc = (r->state_handler)(r); |
236 do { | 251 |
237 rc = (r->state_handler)(r); | 252 if (rc == NGX_ERROR) |
238 | 253 return rc; |
239 if (rc == NGX_ERROR) | 254 |
240 return rc; | 255 } while (rc == NGX_AGAIN |
241 | 256 && r->header_in->pos.mem < r->header_in->last.mem); |
242 } while (rc == NGX_AGAIN && r->header_in->pos.mem < r->header_in->last.mem); | 257 |
258 #if (HAVE_AIO_EVENT) /* aio, iocp */ | |
259 } while (rc == NGX_AGAIN && ngx_event_flags & NGX_HAVE_AIO_EVENT); | |
260 #endif | |
243 | 261 |
244 if (rc == NGX_OK) { | 262 if (rc == NGX_OK) { |
245 /* HTTP header done */ | 263 /* HTTP header done */ |
246 | 264 |
247 if (ev->timer_set) { | 265 if (ev->timer_set) { |
343 } | 361 } |
344 | 362 |
345 | 363 |
346 static int ngx_http_process_request_headers(ngx_http_request_t *r) | 364 static int ngx_http_process_request_headers(ngx_http_request_t *r) |
347 { | 365 { |
348 int rc, len; | 366 int rc; |
367 size_t len; | |
349 ngx_http_log_ctx_t *ctx; | 368 ngx_http_log_ctx_t *ctx; |
350 | 369 |
351 for ( ;; ) { | 370 for ( ;; ) { |
352 rc = ngx_read_http_header_line(r, r->header_in); | 371 rc = ngx_read_http_header_line(r, r->header_in); |
353 | 372 |
430 } | 449 } |
431 | 450 |
432 | 451 |
433 static int ngx_http_event_request_handler(ngx_http_request_t *r) | 452 static int ngx_http_event_request_handler(ngx_http_request_t *r) |
434 { | 453 { |
435 int rc; | 454 int rc, event; |
436 ngx_msec_t timeout; | 455 ngx_msec_t timeout; |
437 ngx_event_t *rev, *wev; | 456 ngx_event_t *rev, *wev; |
438 | 457 |
439 rev = r->connection->read; | 458 rev = r->connection->read; |
440 wev = r->connection->write; | 459 wev = r->connection->write; |
451 | 470 |
452 /* handler is still busy */ | 471 /* handler is still busy */ |
453 if (rc == NGX_WAITING) | 472 if (rc == NGX_WAITING) |
454 return rc; | 473 return rc; |
455 | 474 |
456 /* handler has done its work but transfer is not completed */ | 475 /* handler has done its work but transfer is still not completed */ |
457 if (rc == NGX_AGAIN) { | 476 if (rc == NGX_AGAIN) { |
458 #if (HAVE_CLEAR_EVENT) | |
459 if (ngx_add_event(wev, NGX_WRITE_EVENT, | |
460 NGX_CLEAR_EVENT) == NGX_ERROR) { | |
461 #else | |
462 if (ngx_add_event(wev, NGX_WRITE_EVENT, | |
463 NGX_ONESHOT_EVENT) == NGX_ERROR) { | |
464 #endif | |
465 return ngx_http_close_request(r); | |
466 } | |
467 | 477 |
468 if (r->connection->sent > 0) { | 478 if (r->connection->sent > 0) { |
469 ngx_log_debug(r->connection->log, "sent: " QD_FMT _ | 479 ngx_log_debug(r->connection->log, "sent: " OFF_FMT _ |
470 r->connection->sent); | 480 r->connection->sent); |
471 timeout = (ngx_msec_t) (r->connection->sent * 10); | 481 timeout = (ngx_msec_t) (r->connection->sent * 10); |
472 ngx_log_debug(r->connection->log, "timeout: %d" _ timeout); | 482 ngx_log_debug(r->connection->log, "timeout: %d" _ timeout); |
473 ngx_add_timer(wev, timeout); | 483 ngx_add_timer(wev, timeout); |
474 | 484 |
475 } else { | 485 } else { |
476 ngx_add_timer(wev, 10000); | 486 ngx_add_timer(wev, 10000); |
477 } | 487 } |
478 | 488 |
479 wev->event_handler = ngx_http_writer; | 489 wev->event_handler = ngx_http_writer; |
490 | |
491 #if (USE_KQUEUE) | |
492 | |
493 if (ngx_add_event(wev, NGX_WRITE_EVENT, NGX_CLEAR_EVENT) == NGX_ERROR) { | |
494 return ngx_http_close_request(r); | |
495 } | |
496 | |
480 return rc; | 497 return rc; |
498 | |
499 #else | |
500 | |
501 #if (HAVE_AIO_EVENT) /* aio, iocp */ | |
502 | |
503 if (ngx_event_flags & NGX_HAVE_AIO_EVENT) { | |
504 return rc; | |
505 } | |
506 | |
507 #endif | |
508 | |
509 #if (HAVE_CLEAR_EVENT) /* kqueue */ | |
510 | |
511 if (ngx_event_flags & NGX_HAVE_CLEAR_EVENT) { | |
512 event = NGX_CLEAR_EVENT; | |
513 | |
514 } else { | |
515 event = NGX_ONESHOT_EVENT; | |
516 } | |
517 | |
518 #elif (HAVE_EDGE_EVENT) /* epoll */ | |
519 | |
520 if (ngx_event_flags & NGX_HAVE_EDGE_EVENT) { | |
521 event = NGX_EDGE_EVENT; | |
522 | |
523 } else { | |
524 event = NGX_ONESHOT_EVENT; | |
525 } | |
526 | |
527 #elif (HAVE_DEVPOLL_EVENT) /* /dev/poll */ | |
528 | |
529 if (ngx_event_flags & NGX_HAVE_LEVEL_EVENT) { | |
530 event = NGX_LEVEL_EVENT; | |
531 | |
532 } else { | |
533 event = NGX_ONESHOT_EVENT; | |
534 } | |
535 | |
536 #else /* select, poll */ | |
537 | |
538 event = NGX_ONESHOT_EVENT; | |
539 | |
540 #endif | |
541 | |
542 if (ngx_add_event(wev, NGX_WRITE_EVENT, event) == NGX_ERROR) { | |
543 return ngx_http_close_request(r); | |
544 } | |
545 | |
546 return rc; | |
547 | |
548 | |
549 #endif /* USE_KQUEUE */ | |
550 | |
481 } | 551 } |
482 | 552 |
483 if (rc == NGX_ERROR) { | 553 if (rc == NGX_ERROR) { |
484 /* log http request */ | 554 /* log http request */ |
485 return ngx_http_close_request(r); | 555 return ngx_http_close_request(r); |
499 } | 569 } |
500 } | 570 } |
501 | 571 |
502 /* keepalive */ | 572 /* keepalive */ |
503 | 573 |
504 ngx_http_close_request(r); | |
505 r->connection->buffer->pos.mem = r->connection->buffer->last.mem | 574 r->connection->buffer->pos.mem = r->connection->buffer->last.mem |
506 = r->connection->buffer->start; | 575 = r->connection->buffer->start; |
507 rev->event_handler = ngx_http_keepalive_handler; | 576 rev->event_handler = ngx_http_keepalive_handler; |
577 | |
578 ngx_http_close_request(r); | |
579 | |
580 return NGX_OK; | |
508 } | 581 } |
509 | 582 |
510 | 583 |
511 static int ngx_http_writer(ngx_event_t *ev) | 584 static int ngx_http_writer(ngx_event_t *ev) |
512 { | 585 { |
530 ngx_http_get_module_loc_conf(r->main ? r->main : r, | 603 ngx_http_get_module_loc_conf(r->main ? r->main : r, |
531 ngx_http_core_module_ctx); | 604 ngx_http_core_module_ctx); |
532 | 605 |
533 timeout = (ngx_msec_t) (c->sent * conf->send_timeout); | 606 timeout = (ngx_msec_t) (c->sent * conf->send_timeout); |
534 | 607 |
535 ngx_log_debug(ev->log, "sent: " QD_FMT _ c->sent); | 608 ngx_log_debug(ev->log, "sent: " OFF_FMT _ c->sent); |
536 ngx_log_debug(ev->log, "timeout: %d" _ timeout); | 609 ngx_log_debug(ev->log, "timeout: %d" _ timeout); |
537 | 610 |
538 if (ev->timer_set) { | 611 if (ev->timer_set) { |
539 ngx_del_timer(ev); | 612 ngx_del_timer(ev); |
540 } else { | 613 } else { |
542 } | 615 } |
543 | 616 |
544 ngx_add_timer(ev, timeout); | 617 ngx_add_timer(ev, timeout); |
545 } | 618 } |
546 | 619 |
620 /* TODO: /dev/poll, epoll, aio_write */ | |
621 | |
547 if (ev->oneshot) | 622 if (ev->oneshot) |
548 if (ngx_add_event(ev, NGX_WRITE_EVENT, | 623 if (ngx_add_event(ev, NGX_WRITE_EVENT, NGX_ONESHOT_EVENT) |
549 NGX_ONESHOT_EVENT) == NGX_ERROR) { | 624 == NGX_ERROR) { |
550 return ngx_http_close_request(r); | 625 return ngx_http_close_request(r); |
551 } | 626 } |
552 | 627 |
553 return rc; | 628 return rc; |
554 } | 629 } |
569 } | 644 } |
570 } | 645 } |
571 | 646 |
572 /* keepalive */ | 647 /* keepalive */ |
573 | 648 |
574 ngx_http_close_request(r); | |
575 c->buffer->pos.mem = c->buffer->last.mem = c->buffer->start; | 649 c->buffer->pos.mem = c->buffer->last.mem = c->buffer->start; |
576 c->read->event_handler = ngx_http_keepalive_handler; | 650 c->read->event_handler = ngx_http_keepalive_handler; |
651 | |
652 ngx_http_close_request(r); | |
653 | |
654 return NGX_OK; | |
577 } | 655 } |
578 | 656 |
579 | 657 |
580 static int ngx_http_block_read(ngx_event_t *ev) | 658 static int ngx_http_block_read(ngx_event_t *ev) |
581 { | 659 { |
582 ngx_log_debug(ev->log, "http read blocked"); | 660 ngx_log_debug(ev->log, "http read blocked"); |
583 | 661 |
662 /* aio does not call this handler */ | |
663 | |
664 #if (USE_KQUEUE) | |
665 | |
666 return NGX_OK; | |
667 | |
668 #else | |
669 | |
670 #if (HAVE_CLEAR_EVENT) /* kqueue */ | |
671 | |
672 if (ngx_event_flags & NGX_HAVE_CLEAR_EVENT) { | |
673 return NGX_OK; | |
674 } | |
675 | |
676 #endif | |
677 | |
678 #if (HAVE_EDGE_EVENT) /* epoll */ | |
679 | |
680 if (ngx_event_flags & NGX_HAVE_EDGE_EVENT) { | |
681 return NGX_OK; | |
682 } | |
683 | |
684 #endif | |
685 | |
686 /* select, poll, /dev/poll */ | |
687 | |
584 ev->blocked = 1; | 688 ev->blocked = 1; |
689 | |
585 return ngx_del_event(ev, NGX_READ_EVENT, 0); | 690 return ngx_del_event(ev, NGX_READ_EVENT, 0); |
691 | |
692 #endif /* USE_KQUEUE */ | |
586 } | 693 } |
587 | 694 |
588 | 695 |
589 int ngx_http_discard_body(ngx_http_request_t *r) | 696 int ngx_http_discard_body(ngx_http_request_t *r) |
590 { | 697 { |
597 if (ev->timer_set) { | 704 if (ev->timer_set) { |
598 ngx_del_timer(ev); | 705 ngx_del_timer(ev); |
599 ev->timer_set = 0; | 706 ev->timer_set = 0; |
600 } | 707 } |
601 | 708 |
602 if (r->client_content_length) | 709 if (r->client_content_length) { |
603 ev->event_handler = ngx_http_read_discarded_body; | 710 ev->event_handler = ngx_http_read_discarded_body; |
711 /* if blocked - read */ | |
712 /* else add timer */ | |
713 } | |
604 | 714 |
605 return NGX_OK; | 715 return NGX_OK; |
606 } | 716 } |
607 | 717 |
608 | 718 |
750 | 860 |
751 lcf = (ngx_http_core_loc_conf_t *) | 861 lcf = (ngx_http_core_loc_conf_t *) |
752 ngx_http_get_module_loc_conf(r, ngx_http_core_module_ctx); | 862 ngx_http_get_module_loc_conf(r, ngx_http_core_module_ctx); |
753 | 863 |
754 if (r->discarded_buffer == NULL) { | 864 if (r->discarded_buffer == NULL) { |
755 if (r->header_in->end - r->header_in->last.mem | 865 if ((size_t)(r->header_in->end - r->header_in->last.mem) |
756 >= lcf->discarded_buffer_size) { | 866 >= lcf->discarded_buffer_size) { |
757 r->discarded_buffer = r->header_in->last.mem; | 867 r->discarded_buffer = r->header_in->last.mem; |
758 | 868 |
759 } else { | 869 } else { |
760 ngx_test_null(r->discarded_buffer, | 870 ngx_test_null(r->discarded_buffer, |
787 } | 897 } |
788 | 898 |
789 | 899 |
790 static int ngx_http_close_connection(ngx_event_t *ev) | 900 static int ngx_http_close_connection(ngx_event_t *ev) |
791 { | 901 { |
792 ngx_connection_t *c = (ngx_connection_t *) ev->data; | |
793 | |
794 return ngx_event_close_connection(ev); | 902 return ngx_event_close_connection(ev); |
795 } | 903 } |
796 | 904 |
797 | 905 |
798 static size_t ngx_http_log_error(void *data, char *buf, size_t len) | 906 static size_t ngx_http_log_error(void *data, char *buf, size_t len) |