Mercurial > hg > nginx-quic
comparison src/http/ngx_http_event.c @ 26:53cb81681040
nginx-0.0.1-2002-12-15-09:25:09 import
author | Igor Sysoev <igor@sysoev.ru> |
---|---|
date | Sun, 15 Dec 2002 06:25:09 +0000 |
parents | 77c7629a2627 |
children | 6a0b3d6e9c13 |
comparison
equal
deleted
inserted
replaced
25:a8b156554dfe | 26:53cb81681040 |
---|---|
11 #include <ngx_alloc.h> | 11 #include <ngx_alloc.h> |
12 #include <ngx_array.h> | 12 #include <ngx_array.h> |
13 #include <ngx_table.h> | 13 #include <ngx_table.h> |
14 #include <ngx_hunk.h> | 14 #include <ngx_hunk.h> |
15 #include <ngx_connection.h> | 15 #include <ngx_connection.h> |
16 #include <ngx_inet.h> | |
16 #include <ngx_http.h> | 17 #include <ngx_http.h> |
17 #include <ngx_http_config.h> | 18 #include <ngx_http_config.h> |
18 #include <ngx_http_core.h> | 19 #include <ngx_http_core.h> |
19 | 20 |
20 /* STUB */ | 21 /* STUB */ |
31 | 32 |
32 static int ngx_http_process_request_line(ngx_http_request_t *r); | 33 static int ngx_http_process_request_line(ngx_http_request_t *r); |
33 static int ngx_http_process_request_headers(ngx_http_request_t *r); | 34 static int ngx_http_process_request_headers(ngx_http_request_t *r); |
34 static int ngx_http_process_request_header_line(ngx_http_request_t *r); | 35 static int ngx_http_process_request_header_line(ngx_http_request_t *r); |
35 | 36 |
36 static int ngx_http_event_handler(ngx_http_request_t *r); | 37 static int ngx_http_event_request_handler(ngx_http_request_t *r); |
38 | |
39 static int ngx_http_writer(ngx_event_t *ev); | |
37 static int ngx_http_block_read(ngx_event_t *ev); | 40 static int ngx_http_block_read(ngx_event_t *ev); |
38 | |
39 | |
40 static int ngx_http_read_discarded_body(ngx_event_t *ev); | 41 static int ngx_http_read_discarded_body(ngx_event_t *ev); |
41 | 42 static int ngx_http_keepalive_handler(ngx_event_t *ev); |
42 int ngx_http_handler(ngx_http_request_t *r); | |
43 static int ngx_http_set_default_handler(ngx_http_request_t *r); | |
44 | |
45 static int ngx_http_writer(ngx_event_t *ev); | |
46 static int ngx_http_set_lingering_close(ngx_http_request_t *r); | 43 static int ngx_http_set_lingering_close(ngx_http_request_t *r); |
47 static int ngx_http_keepalive_handler(ngx_event_t *ev); | 44 static int ngx_http_lingering_close_handler(ngx_event_t *ev); |
48 static int ngx_http_lingering_close(ngx_event_t *ev); | |
49 | 45 |
50 #if 0 | 46 #if 0 |
51 int ngx_http_special_response(ngx_http_request_t *r, int error); | 47 int ngx_http_special_response(ngx_http_request_t *r, int error); |
52 int ngx_http_redirect(ngx_http_request_t *r, int redirect); | 48 int ngx_http_redirect(ngx_http_request_t *r, int redirect); |
53 int ngx_http_error(ngx_http_request_t *r, int error); | 49 int ngx_http_error(ngx_http_request_t *r, int error); |
68 | 64 |
69 | 65 |
70 static ngx_http_header_t headers_in[] = { | 66 static ngx_http_header_t headers_in[] = { |
71 { 4, "Host", offsetof(ngx_http_headers_in_t, host) }, | 67 { 4, "Host", offsetof(ngx_http_headers_in_t, host) }, |
72 { 10, "Connection", offsetof(ngx_http_headers_in_t, connection) }, | 68 { 10, "Connection", offsetof(ngx_http_headers_in_t, connection) }, |
69 { 17, "If-Modified-Since", | |
70 offsetof(ngx_http_headers_in_t,if_modified_since) }, | |
73 | 71 |
74 { 10, "User-Agent", offsetof(ngx_http_headers_in_t, user_agent) }, | 72 { 10, "User-Agent", offsetof(ngx_http_headers_in_t, user_agent) }, |
75 | 73 |
76 { 0, NULL, 0 } | 74 { 0, NULL, 0 } |
77 }; | 75 }; |
104 c->sockaddr = addr; | 102 c->sockaddr = addr; |
105 | 103 |
106 ngx_test_null(c->addr_text.data, ngx_palloc(c->pool, c->addr_text.len), | 104 ngx_test_null(c->addr_text.data, ngx_palloc(c->pool, c->addr_text.len), |
107 NGX_ERROR); | 105 NGX_ERROR); |
108 | 106 |
109 /* STUB: should be ngx_inet_ntop() */ | 107 ngx_test_null(c->addr_text.len, |
110 #if (WIN32) | 108 ngx_inet_ntop(c->family, |
111 c->addr_text.data = inet_ntoa((struct in_addr *) | 109 (char *)c->sockaddr + c->addr, |
112 ((char *)c->sockaddr + c->addr)); | 110 c->addr_text.data, c->addr_text.len), |
113 #else | 111 NGX_ERROR); |
114 inet_ntop(c->family, (char *)c->sockaddr + c->addr, | |
115 c->addr_text.data, c->addr_text.len); | |
116 #endif | |
117 /**/ | |
118 | 112 |
119 ngx_test_null(ctx, ngx_pcalloc(c->pool, sizeof(ngx_http_log_ctx_t)), | 113 ngx_test_null(ctx, ngx_pcalloc(c->pool, sizeof(ngx_http_log_ctx_t)), |
120 NGX_ERROR); | 114 NGX_ERROR); |
121 ctx->client = c->addr_text.data; | 115 ctx->client = c->addr_text.data; |
122 ctx->action = "reading client request line"; | 116 ctx->action = "reading client request line"; |
164 NGX_ERROR); | 158 NGX_ERROR); |
165 | 159 |
166 c->data = r; | 160 c->data = r; |
167 r->connection = c; | 161 r->connection = c; |
168 r->server = srv; | 162 r->server = srv; |
163 r->file.fd = NGX_INVALID_FILE; | |
169 | 164 |
170 /* STUB */ | 165 /* STUB */ |
171 r->srv_conf = ngx_srv_conf; | 166 r->srv_conf = ngx_srv_conf; |
172 r->loc_conf = ngx_loc_conf; | 167 r->loc_conf = ngx_loc_conf; |
173 /**/ | 168 /**/ |
186 ngx_test_null(r->pool, ngx_create_pool(srv->request_pool_size, ev->log), | 181 ngx_test_null(r->pool, ngx_create_pool(srv->request_pool_size, ev->log), |
187 ngx_http_close_request(r)); | 182 ngx_http_close_request(r)); |
188 | 183 |
189 ngx_test_null(r->ctx, ngx_pcalloc(r->pool, sizeof(void *) * ngx_max_module), | 184 ngx_test_null(r->ctx, ngx_pcalloc(r->pool, sizeof(void *) * ngx_max_module), |
190 ngx_http_close_request(r)); | 185 ngx_http_close_request(r)); |
186 | |
187 r->headers_out.headers = ngx_create_table(r->pool, 10); | |
188 r->headers_out.content_length = -1; | |
189 r->headers_out.last_modified_time = -1; | |
191 | 190 |
192 ev->event_handler = ngx_http_process_request_header; | 191 ev->event_handler = ngx_http_process_request_header; |
193 r->state_handler = ngx_http_process_request_line; | 192 r->state_handler = ngx_http_process_request_line; |
194 r->header_timeout = 1; | 193 r->header_timeout = 1; |
195 | 194 |
260 ngx_del_timer(ev); | 259 ngx_del_timer(ev); |
261 ngx_add_timer(ev, r->server->header_timeout); | 260 ngx_add_timer(ev, r->server->header_timeout); |
262 } | 261 } |
263 | 262 |
264 if (rc == NGX_OK) | 263 if (rc == NGX_OK) |
265 return ngx_http_event_handler(r); | 264 return ngx_http_event_request_handler(r); |
266 else | 265 else |
267 return rc; | 266 return rc; |
268 } | 267 } |
269 | 268 |
270 | 269 |
278 rc = ngx_read_http_request_line(r); | 277 rc = ngx_read_http_request_line(r); |
279 | 278 |
280 c = r->connection; | 279 c = r->connection; |
281 | 280 |
282 if (rc == NGX_OK) { | 281 if (rc == NGX_OK) { |
283 r->uri.len = r->uri_end - r->uri_start; | 282 r->uri.len = (r->args_start ? r->args_start - 1 : r->uri_end) |
283 - r->uri_start; | |
284 ngx_test_null(r->uri.data, ngx_palloc(r->pool, r->uri.len + 1), | 284 ngx_test_null(r->uri.data, ngx_palloc(r->pool, r->uri.len + 1), |
285 ngx_http_close_request(r)); | 285 ngx_http_close_request(r)); |
286 ngx_cpystrn(r->uri.data, r->uri_start, r->uri.len + 1); | 286 ngx_cpystrn(r->uri.data, r->uri_start, r->uri.len + 1); |
287 | 287 |
288 r->request_line.len = r->request_end - r->header_in->start; | 288 r->request_line.len = r->request_end - r->header_in->start; |
307 | 307 |
308 ngx_log_debug(c->log, "REQ: '%s'" _ *request); | 308 ngx_log_debug(c->log, "REQ: '%s'" _ *request); |
309 /* */ | 309 /* */ |
310 | 310 |
311 if (r->uri_ext) { | 311 if (r->uri_ext) { |
312 r->exten.len = r->uri_end - r->uri_ext; | 312 r->exten.len = (r->args_start ? r->args_start - 1 : r->uri_end) |
313 - r->uri_ext; | |
313 ngx_test_null(r->exten.data, | 314 ngx_test_null(r->exten.data, |
314 ngx_palloc(r->pool, r->exten.len + 1), | 315 ngx_palloc(r->pool, r->exten.len + 1), |
315 ngx_http_close_request(r)); | 316 ngx_http_close_request(r)); |
316 ngx_cpystrn(r->exten.data, r->uri_ext, r->exten.len + 1); | 317 ngx_cpystrn(r->exten.data, r->uri_ext, r->exten.len + 1); |
317 } | 318 } |
324 return NGX_OK; | 325 return NGX_OK; |
325 | 326 |
326 /* TODO: check too long URI - no space for header, compact buffer */ | 327 /* TODO: check too long URI - no space for header, compact buffer */ |
327 | 328 |
328 r->headers_in.headers = ngx_create_table(r->pool, 10); | 329 r->headers_in.headers = ngx_create_table(r->pool, 10); |
329 /* THINK: when to create out.headers ? */ | |
330 r->headers_out.headers = ngx_create_table(r->pool, 10); | |
331 | 330 |
332 r->state_handler = ngx_http_process_request_headers; | 331 r->state_handler = ngx_http_process_request_headers; |
333 ctx = r->connection->log->data; | 332 ctx = r->connection->log->data; |
334 ctx->action = "reading client request headers"; | 333 ctx->action = "reading client request headers"; |
335 | 334 |
370 if (ngx_http_process_request_header_line(r) == NGX_ERROR) | 369 if (ngx_http_process_request_header_line(r) == NGX_ERROR) |
371 return ngx_http_error(r, NGX_HTTP_BAD_REQUEST); | 370 return ngx_http_error(r, NGX_HTTP_BAD_REQUEST); |
372 | 371 |
373 } else if (rc == NGX_HTTP_PARSE_HEADER_DONE) { | 372 } else if (rc == NGX_HTTP_PARSE_HEADER_DONE) { |
374 ngx_log_debug(r->connection->log, "HTTP header done"); | 373 ngx_log_debug(r->connection->log, "HTTP header done"); |
375 return NGX_OK; | 374 |
375 if (r->http_version > NGX_HTTP_VERSION_10 | |
376 && r->headers_in.host == NULL) | |
377 { | |
378 return ngx_http_error(r, NGX_HTTP_BAD_REQUEST); | |
379 } else { | |
380 return NGX_OK; | |
381 } | |
376 | 382 |
377 } else if (rc == NGX_AGAIN) { | 383 } else if (rc == NGX_AGAIN) { |
378 return NGX_AGAIN; | 384 return NGX_AGAIN; |
379 | 385 |
380 } else if (rc == NGX_HTTP_PARSE_INVALID_HEADER) { | 386 } else if (rc == NGX_HTTP_PARSE_INVALID_HEADER) { |
420 | 426 |
421 return NGX_OK; | 427 return NGX_OK; |
422 } | 428 } |
423 | 429 |
424 | 430 |
425 static int ngx_http_event_handler(ngx_http_request_t *r) | 431 static int ngx_http_event_request_handler(ngx_http_request_t *r) |
426 { | 432 { |
427 int rc; | 433 int rc; |
428 ngx_msec_t timeout; | 434 ngx_msec_t timeout; |
429 | 435 |
430 ngx_del_timer(r->connection->read); | 436 ngx_del_timer(r->connection->read); |
492 = r->connection->buffer->start; | 498 = r->connection->buffer->start; |
493 r->connection->read->event_handler = ngx_http_keepalive_handler; | 499 r->connection->read->event_handler = ngx_http_keepalive_handler; |
494 } | 500 } |
495 | 501 |
496 | 502 |
497 static int ngx_http_block_read(ngx_event_t *ev) | |
498 { | |
499 ngx_log_debug(ev->log, "http read blocked"); | |
500 | |
501 ev->blocked = 1; | |
502 return ngx_del_event(ev, NGX_READ_EVENT); | |
503 } | |
504 | |
505 | |
506 | |
507 /* FIND PLACE ******************** */ | |
508 | |
509 void ngx_http_discard_body(ngx_http_request_t *r) | |
510 { | |
511 ngx_log_debug(r->connection->log, "set discard body"); | |
512 | |
513 ngx_del_timer(r->connection->read); | |
514 | |
515 if (r->client_content_length) | |
516 r->connection->read->event_handler = ngx_http_read_discarded_body; | |
517 } | |
518 | |
519 | |
520 static int ngx_http_read_discarded_body(ngx_event_t *ev) | |
521 { | |
522 size_t size; | |
523 ssize_t n; | |
524 ngx_connection_t *c; | |
525 ngx_http_request_t *r; | |
526 | |
527 c = (ngx_connection_t *) ev->data; | |
528 r = (ngx_http_request_t *) c->data; | |
529 | |
530 ngx_log_debug(ev->log, "http read discarded body"); | |
531 | |
532 if (ev->timedout) | |
533 return NGX_ERROR; | |
534 | |
535 if (r->discarded_buffer == NULL) | |
536 ngx_test_null(r->discarded_buffer, | |
537 ngx_palloc(r->pool, r->server->discarded_buffer_size), | |
538 NGX_ERROR); | |
539 | |
540 size = r->client_content_length; | |
541 if (size > r->server->discarded_buffer_size) | |
542 size = r->server->discarded_buffer_size; | |
543 | |
544 n = ngx_event_recv(c, r->discarded_buffer, size); | |
545 if (n == NGX_ERROR) | |
546 return NGX_ERROR; | |
547 | |
548 if (n == NGX_AGAIN) | |
549 return NGX_OK; | |
550 | |
551 r->client_content_length -= n; | |
552 /* XXX: what if r->client_content_length == 0 ? */ | |
553 return NGX_OK; | |
554 } | |
555 | |
556 | |
557 static int ngx_http_discarded_read(ngx_event_t *ev) | |
558 { | |
559 ssize_t n; | |
560 ngx_connection_t *c; | |
561 ngx_http_request_t *r; | |
562 | |
563 c = (ngx_connection_t *) ev->data; | |
564 r = (ngx_http_request_t *) c->data; | |
565 | |
566 ngx_log_debug(ev->log, "http discarded read"); | |
567 | |
568 if (ev->timedout) | |
569 return NGX_ERROR; | |
570 | |
571 if (r->discarded_buffer == NULL) | |
572 ngx_test_null(r->discarded_buffer, | |
573 ngx_palloc(r->pool, r->server->discarded_buffer_size), | |
574 NGX_ERROR); | |
575 | |
576 n = ngx_event_recv(c, r->discarded_buffer, | |
577 r->server->discarded_buffer_size); | |
578 | |
579 return n; | |
580 } | |
581 | |
582 /* ******************** */ | |
583 | |
584 | |
585 #if 0 | |
586 int ngx_http_handler(ngx_http_request_t *r) | |
587 { | |
588 int rc; | |
589 | |
590 r->connection->unexpected_eof = 0; | |
591 r->lingering_close = 1; | |
592 | |
593 /* STUB: should find handler */ | |
594 #if 1 | |
595 r->filter = NGX_HTTP_FILTER_NEED_IN_MEMORY; | |
596 #endif | |
597 rc = ngx_http_set_default_handler(r); | |
598 | |
599 if (rc >= NGX_HTTP_SPECIAL_RESPONSE) | |
600 return ngx_http_special_response(r, rc); | |
601 | |
602 rc = r->handler(r); | |
603 | |
604 return rc; | |
605 } | |
606 #endif | |
607 | |
608 | |
609 #if 0 | |
610 static int ngx_http_set_default_handler(ngx_http_request_t *r) | |
611 { | |
612 ngx_err_t err; | |
613 char *name, *loc, *file; | |
614 | |
615 #if 0 | |
616 /* STUB */ | |
617 r->handler = ngx_http_proxy_handler; | |
618 return NGX_OK; | |
619 #endif | |
620 | |
621 /* NO NEEDED | |
622 ngx_test_null(r->headers_out, | |
623 ngx_pcalloc(r->pool, sizeof(ngx_http_headers_out_t)), | |
624 NGX_HTTP_INTERNAL_SERVER_ERROR); | |
625 */ | |
626 | |
627 if (*(r->uri_end - 1) == '/') { | |
628 r->handler = ngx_http_index_handler; | |
629 return NGX_OK; | |
630 } | |
631 | |
632 /* 20 bytes is spare space for some index name, i.e. index.html */ | |
633 r->filename_len = r->uri_end - r->uri_start + r->server->doc_root_len + 20; | |
634 | |
635 ngx_test_null(r->filename, | |
636 ngx_palloc(r->pool, r->filename_len), | |
637 NGX_HTTP_INTERNAL_SERVER_ERROR); | |
638 | |
639 r->location = ngx_cpystrn(r->filename, r->server->doc_root, | |
640 r->server->doc_root_len); | |
641 file = ngx_cpystrn(r->location, r->uri_start, | |
642 r->uri_end - r->uri_start + 1); | |
643 | |
644 ngx_log_debug(r->connection->log, "HTTP filename: '%s'" _ r->filename); | |
645 | |
646 if (ngx_file_type(r->filename, &r->fileinfo) == -1) { | |
647 err = ngx_errno; | |
648 ngx_log_error(NGX_LOG_ERR, r->connection->log, err, | |
649 ngx_file_type_n " %s failed", r->filename); | |
650 | |
651 if (err == NGX_ENOENT) | |
652 return NGX_HTTP_NOT_FOUND; | |
653 else | |
654 return NGX_HTTP_INTERNAL_SERVER_ERROR; | |
655 } | |
656 | |
657 if (ngx_is_dir(r->fileinfo)) { | |
658 ngx_log_debug(r->connection->log, "HTTP DIR: '%s'" _ r->filename); | |
659 *file++ = '/'; | |
660 *file = '\0'; | |
661 r->headers_out.location = r->location; | |
662 return NGX_HTTP_MOVED_PERMANENTLY; | |
663 } | |
664 | |
665 r->handler = ngx_http_static_handler; | |
666 | |
667 return NGX_OK; | |
668 } | |
669 #endif | |
670 | |
671 | |
672 static int ngx_http_writer(ngx_event_t *ev) | 503 static int ngx_http_writer(ngx_event_t *ev) |
673 { | 504 { |
674 int rc; | 505 int rc; |
675 ngx_msec_t timeout; | 506 ngx_msec_t timeout; |
676 ngx_connection_t *c; | 507 ngx_connection_t *c; |
733 c->buffer->pos.mem = c->buffer->last.mem = c->buffer->start; | 564 c->buffer->pos.mem = c->buffer->last.mem = c->buffer->start; |
734 c->read->event_handler = ngx_http_keepalive_handler; | 565 c->read->event_handler = ngx_http_keepalive_handler; |
735 } | 566 } |
736 | 567 |
737 | 568 |
569 static int ngx_http_block_read(ngx_event_t *ev) | |
570 { | |
571 ngx_log_debug(ev->log, "http read blocked"); | |
572 | |
573 ev->blocked = 1; | |
574 return ngx_del_event(ev, NGX_READ_EVENT, 0); | |
575 } | |
576 | |
577 | |
578 int ngx_http_discard_body(ngx_http_request_t *r) | |
579 { | |
580 ngx_log_debug(r->connection->log, "set discard body"); | |
581 | |
582 ngx_del_timer(r->connection->read); | |
583 | |
584 if (r->client_content_length) | |
585 r->connection->read->event_handler = ngx_http_read_discarded_body; | |
586 | |
587 return NGX_OK; | |
588 } | |
589 | |
590 | |
591 static int ngx_http_read_discarded_body(ngx_event_t *ev) | |
592 { | |
593 size_t size; | |
594 ssize_t n; | |
595 ngx_connection_t *c; | |
596 ngx_http_request_t *r; | |
597 | |
598 c = (ngx_connection_t *) ev->data; | |
599 r = (ngx_http_request_t *) c->data; | |
600 | |
601 ngx_log_debug(ev->log, "http read discarded body"); | |
602 | |
603 if (ev->timedout) | |
604 return NGX_ERROR; | |
605 | |
606 if (r->discarded_buffer == NULL) | |
607 ngx_test_null(r->discarded_buffer, | |
608 ngx_palloc(r->pool, r->server->discarded_buffer_size), | |
609 NGX_ERROR); | |
610 | |
611 size = r->client_content_length; | |
612 if (size > r->server->discarded_buffer_size) | |
613 size = r->server->discarded_buffer_size; | |
614 | |
615 n = ngx_event_recv(c, r->discarded_buffer, size); | |
616 if (n == NGX_ERROR) | |
617 return NGX_ERROR; | |
618 | |
619 if (n == NGX_AGAIN) | |
620 return NGX_OK; | |
621 | |
622 r->client_content_length -= n; | |
623 /* XXX: what if r->client_content_length == 0 ? */ | |
624 return NGX_OK; | |
625 } | |
626 | |
627 | |
628 #if 0 | |
629 static int ngx_http_discarded_read(ngx_event_t *ev) | |
630 { | |
631 ssize_t n; | |
632 ngx_connection_t *c; | |
633 ngx_http_request_t *r; | |
634 | |
635 c = (ngx_connection_t *) ev->data; | |
636 r = (ngx_http_request_t *) c->data; | |
637 | |
638 ngx_log_debug(ev->log, "http discarded read"); | |
639 | |
640 if (ev->timedout) | |
641 return NGX_ERROR; | |
642 | |
643 if (r->discarded_buffer == NULL) | |
644 ngx_test_null(r->discarded_buffer, | |
645 ngx_palloc(r->pool, r->server->discarded_buffer_size), | |
646 NGX_ERROR); | |
647 | |
648 n = ngx_event_recv(c, r->discarded_buffer, | |
649 r->server->discarded_buffer_size); | |
650 | |
651 return n; | |
652 } | |
653 #endif | |
654 | |
655 | |
656 static int ngx_http_keepalive_handler(ngx_event_t *ev) | |
657 { | |
658 ssize_t n; | |
659 ngx_connection_t *c; | |
660 ngx_http_log_ctx_t *ctx; | |
661 | |
662 c = (ngx_connection_t *) ev->data; | |
663 | |
664 ngx_log_debug(ev->log, "http keepalive handler"); | |
665 | |
666 if (ev->timedout) | |
667 return NGX_DONE; | |
668 | |
669 n = ngx_event_recv(c, c->buffer->last.mem, | |
670 c->buffer->end - c->buffer->last.mem); | |
671 | |
672 if (n == NGX_AGAIN || n == NGX_ERROR) | |
673 return n; | |
674 | |
675 ctx = (ngx_http_log_ctx_t *) ev->log->data; | |
676 ev->log->handler = NULL; | |
677 | |
678 if (n == 0) { | |
679 ngx_log_error(NGX_LOG_INFO, ev->log, 0, | |
680 "client %s closed keepalive connection", ctx->client); | |
681 return NGX_DONE; | |
682 } | |
683 | |
684 c->buffer->last.mem += n; | |
685 ev->log->handler = ngx_http_log_error; | |
686 ctx->action = "reading client request line"; | |
687 | |
688 return ngx_http_init_request(ev); | |
689 } | |
690 | |
691 | |
738 static int ngx_http_set_lingering_close(ngx_http_request_t *r) | 692 static int ngx_http_set_lingering_close(ngx_http_request_t *r) |
739 { | 693 { |
740 r->lingering_time = ngx_time() + r->server->lingering_time; | 694 r->lingering_time = ngx_time() + r->server->lingering_time; |
741 r->connection->read->event_handler = ngx_http_lingering_close; | 695 r->connection->read->event_handler = ngx_http_lingering_close_handler; |
742 | 696 |
743 ngx_del_timer(r->connection->read); | 697 ngx_del_timer(r->connection->read); |
744 ngx_add_timer(r->connection->read, r->server->lingering_timeout); | 698 ngx_add_timer(r->connection->read, r->server->lingering_timeout); |
745 | 699 |
746 #if (HAVE_CLEAR_EVENT) | 700 #if (HAVE_CLEAR_EVENT) |
751 NGX_ONESHOT_EVENT) == NGX_ERROR) { | 705 NGX_ONESHOT_EVENT) == NGX_ERROR) { |
752 #endif | 706 #endif |
753 return ngx_http_close_request(r); | 707 return ngx_http_close_request(r); |
754 } | 708 } |
755 | 709 |
756 if (ngx_shutdown_socket(r->connection->fd, NGX_WRITE_SHUTDOWN) == NGX_ERROR) | 710 if (ngx_shutdown_socket(r->connection->fd, NGX_WRITE_SHUTDOWN) == -1) |
757 { | 711 { |
758 ngx_log_error(NGX_LOG_ERR, r->connection->log, ngx_socket_errno, | 712 ngx_log_error(NGX_LOG_ERR, r->connection->log, ngx_socket_errno, |
759 ngx_shutdown_socket_n " failed"); | 713 ngx_shutdown_socket_n " failed"); |
760 return ngx_http_close_request(r); | 714 return ngx_http_close_request(r); |
761 } | 715 } |
762 | 716 |
763 return NGX_OK; | 717 return NGX_OK; |
764 } | 718 } |
765 | 719 |
766 | 720 |
767 static int ngx_http_keepalive_handler(ngx_event_t *ev) | 721 static int ngx_http_lingering_close_handler(ngx_event_t *ev) |
768 { | 722 { |
769 ssize_t n; | 723 ssize_t n; |
770 ngx_connection_t *c; | 724 ngx_msec_t timer; |
771 ngx_http_log_ctx_t *ctx; | |
772 | |
773 c = (ngx_connection_t *) ev->data; | |
774 | |
775 ngx_log_debug(ev->log, "http keepalive"); | |
776 | |
777 if (ev->timedout) | |
778 return NGX_DONE; | |
779 | |
780 n = ngx_event_recv(c, c->buffer->last.mem, | |
781 c->buffer->end - c->buffer->last.mem); | |
782 | |
783 if (n == NGX_AGAIN || n == NGX_ERROR) | |
784 return n; | |
785 | |
786 ctx = (ngx_http_log_ctx_t *) ev->log->data; | |
787 ev->log->handler = NULL; | |
788 | |
789 if (n == 0) { | |
790 ngx_log_error(NGX_LOG_INFO, ev->log, 0, | |
791 "client %s closed keepalive connection", ctx->client); | |
792 return NGX_DONE; | |
793 } | |
794 | |
795 c->buffer->last.mem += n; | |
796 ev->log->handler = ngx_http_log_error; | |
797 ctx->action = "reading client request line"; | |
798 | |
799 return ngx_http_init_request(ev); | |
800 } | |
801 | |
802 | |
803 static int ngx_http_lingering_close(ngx_event_t *ev) | |
804 { | |
805 ssize_t n; | |
806 ngx_msec_t timer; | |
807 ngx_connection_t *c; | 725 ngx_connection_t *c; |
808 ngx_http_request_t *r; | 726 ngx_http_request_t *r; |
809 | 727 |
810 c = (ngx_connection_t *) ev->data; | 728 c = (ngx_connection_t *) ev->data; |
811 r = (ngx_http_request_t *) c->data; | 729 r = (ngx_http_request_t *) c->data; |
812 | 730 |
813 ngx_log_debug(ev->log, "http lingering close"); | 731 ngx_log_debug(ev->log, "http lingering close handler"); |
814 | 732 |
815 if (ev->timedout) | 733 if (ev->timedout) |
816 return NGX_DONE; | 734 return NGX_DONE; |
817 | 735 |
818 timer = r->lingering_time - ngx_time(); | 736 timer = r->lingering_time - ngx_time(); |