Mercurial > hg > nginx
comparison src/http/ngx_http_event.c @ 13:2aba961a1d34
nginx-0.0.1-2002-09-16-19:01:44 import
author | Igor Sysoev <igor@sysoev.ru> |
---|---|
date | Mon, 16 Sep 2002 15:01:44 +0000 |
parents | 055ed05235ae |
children | 8dd06e2844f5 |
comparison
equal
deleted
inserted
replaced
12:055ed05235ae | 13:2aba961a1d34 |
---|---|
1 /* | 1 /* |
2 TODO Win32 inet_ntoa | 2 TODO: Win32 inet_ntoa |
3 ngx_inet_ntop | 3 ngx_inet_ntop |
4 */ | 4 */ |
5 | 5 |
6 #include <ngx_config.h> | 6 #include <ngx_config.h> |
7 #include <ngx_core.h> | 7 #include <ngx_core.h> |
8 #include <ngx_string.h> | 8 #include <ngx_string.h> |
11 #include <ngx_alloc.h> | 11 #include <ngx_alloc.h> |
12 #include <ngx_hunk.h> | 12 #include <ngx_hunk.h> |
13 #include <ngx_connection.h> | 13 #include <ngx_connection.h> |
14 #include <ngx_http.h> | 14 #include <ngx_http.h> |
15 #include <ngx_http_config.h> | 15 #include <ngx_http_config.h> |
16 #include <ngx_http_core.h> | |
16 | 17 |
17 /* STUB */ | 18 /* STUB */ |
18 #include <ngx_http_output_filter.h> | 19 #include <ngx_http_output_filter.h> |
19 int ngx_http_static_handler(ngx_http_request_t *r); | 20 int ngx_http_static_handler(ngx_http_request_t *r); |
20 int ngx_http_index_handler(ngx_http_request_t *r); | 21 int ngx_http_index_handler(ngx_http_request_t *r); |
21 /* */ | 22 /* */ |
22 | 23 |
23 /* STUB */ | |
24 #define LINGERING_TIMEOUT 2 | |
25 #define SOME_LINGERING_TIME 30 | |
26 | |
27 int ngx_http_init_connection(ngx_connection_t *c); | 24 int ngx_http_init_connection(ngx_connection_t *c); |
28 | 25 |
29 static int ngx_http_init_request(ngx_event_t *ev); | 26 static int ngx_http_init_request(ngx_event_t *ev); |
30 static int ngx_http_process_request(ngx_event_t *ev); | 27 static int ngx_http_process_request(ngx_event_t *ev); |
31 | 28 |
34 static int ngx_http_process_request_header_line(ngx_http_request_t *r); | 31 static int ngx_http_process_request_header_line(ngx_http_request_t *r); |
35 | 32 |
36 static int ngx_http_block_read(ngx_event_t *ev); | 33 static int ngx_http_block_read(ngx_event_t *ev); |
37 static int ngx_http_read_discarded_body(ngx_event_t *ev); | 34 static int ngx_http_read_discarded_body(ngx_event_t *ev); |
38 | 35 |
36 static int ngx_http_event_handler(ngx_http_request_t *r); | |
39 static int ngx_http_handler(ngx_http_request_t *r); | 37 static int ngx_http_handler(ngx_http_request_t *r); |
40 static int ngx_http_set_default_handler(ngx_http_request_t *r); | 38 static int ngx_http_set_default_handler(ngx_http_request_t *r); |
41 | 39 |
42 static int ngx_http_writer(ngx_event_t *ev); | 40 static int ngx_http_writer(ngx_event_t *ev); |
41 static int ngx_http_set_lingering_close(ngx_http_request_t *r); | |
43 static int ngx_http_keepalive_handler(ngx_event_t *ev); | 42 static int ngx_http_keepalive_handler(ngx_event_t *ev); |
44 static int ngx_http_lingering_close(ngx_event_t *ev); | 43 static int ngx_http_lingering_close(ngx_event_t *ev); |
45 | 44 |
46 static int ngx_http_special_response(ngx_http_request_t *r, int error); | 45 static int ngx_http_special_response(ngx_http_request_t *r, int error); |
47 static int ngx_http_redirect(ngx_http_request_t *r, int redirect); | 46 static int ngx_http_redirect(ngx_http_request_t *r, int redirect); |
63 | 62 |
64 int ngx_http_init_connection(ngx_connection_t *c) | 63 int ngx_http_init_connection(ngx_connection_t *c) |
65 { | 64 { |
66 ngx_event_t *ev; | 65 ngx_event_t *ev; |
67 struct sockaddr *addr; | 66 struct sockaddr *addr; |
67 ngx_http_server_t *srv; | |
68 ngx_http_log_ctx_t *ctx; | 68 ngx_http_log_ctx_t *ctx; |
69 | 69 |
70 ev = c->read; | 70 ev = c->read; |
71 ev->event_handler = ngx_http_init_request; | 71 ev->event_handler = ngx_http_init_request; |
72 srv = (ngx_http_server_t *) c->server; | |
72 | 73 |
73 ngx_test_null(c->pool, | 74 ngx_test_null(c->pool, |
74 ngx_create_pool(srv->connection_pool_size, ev->log), | 75 ngx_create_pool(srv->connection_pool_size, ev->log), |
75 NGX_ERROR); | 76 NGX_ERROR); |
76 | 77 |
79 c->sockaddr = addr; | 80 c->sockaddr = addr; |
80 | 81 |
81 ngx_test_null(c->addr_text, ngx_palloc(c->pool, c->addr_textlen), | 82 ngx_test_null(c->addr_text, ngx_palloc(c->pool, c->addr_textlen), |
82 NGX_ERROR); | 83 NGX_ERROR); |
83 #if (WIN32) | 84 #if (WIN32) |
84 c->addr_text = inet_ntoa((struct in_addr) ((char *)c->sockaddr + c->addr)); | 85 c->addr_text = inet_ntoa((struct in_addr *) |
86 ((char *)c->sockaddr + c->addr)); | |
85 #else | 87 #else |
86 inet_ntop(c->family, (char *)c->sockaddr + c->addr, | 88 inet_ntop(c->family, (char *)c->sockaddr + c->addr, |
87 c->addr_text, c->addr_textlen); | 89 c->addr_text, c->addr_textlen); |
88 #endif | 90 #endif |
89 | 91 |
128 ngx_http_request_t *r; | 130 ngx_http_request_t *r; |
129 | 131 |
130 c = (ngx_connection_t *) ev->data; | 132 c = (ngx_connection_t *) ev->data; |
131 srv = (ngx_http_server_t *) c->server; | 133 srv = (ngx_http_server_t *) c->server; |
132 | 134 |
135 ngx_test_null(r, ngx_pcalloc(c->pool, sizeof(ngx_http_request_t)), | |
136 NGX_ERROR); | |
137 | |
138 c->data = r; | |
139 r->connection = c; | |
140 r->server = srv; | |
141 | |
142 r->srv_conf = ngx_srv_conf; | |
143 r->loc_conf = ngx_loc_conf; | |
144 | |
133 if (c->buffer == NULL) { | 145 if (c->buffer == NULL) { |
134 ngx_test_null(c->buffer, | 146 ngx_test_null(c->buffer, |
135 ngx_create_temp_hunk(c->pool, srv->header_buffer_size, | 147 ngx_create_temp_hunk(c->pool, srv->header_buffer_size, |
136 0, 0), | 148 0, 0), |
137 NGX_ERROR); | 149 NGX_ERROR); |
138 } else { | 150 } else { |
139 c->buffer->pos.mem = c->buffer->last.mem = c->buffer->start; | 151 r->header_read = 1; |
140 } | 152 } |
141 | 153 |
142 ngx_test_null(r, ngx_pcalloc(c->pool, sizeof(ngx_http_request_t)), | |
143 NGX_ERROR); | |
144 | |
145 c->data = r; | |
146 r->connection = c; | |
147 r->server = srv; | |
148 r->header_in = c->buffer; | 154 r->header_in = c->buffer; |
149 | |
150 r->srv_conf = ngx_srv_conf; | |
151 r->loc_conf = ngx_loc_conf; | |
152 | 155 |
153 ngx_test_null(r->pool, ngx_create_pool(srv->request_pool_size, ev->log), | 156 ngx_test_null(r->pool, ngx_create_pool(srv->request_pool_size, ev->log), |
154 ngx_http_close_request(r)); | 157 ngx_http_close_request(r)); |
155 | 158 |
156 ngx_test_null(r->ctx, ngx_pcalloc(r->pool, sizeof(void *) * ngx_max_module), | 159 ngx_test_null(r->ctx, ngx_pcalloc(r->pool, sizeof(void *) * ngx_max_module), |
175 c = (ngx_connection_t *) ev->data; | 178 c = (ngx_connection_t *) ev->data; |
176 r = (ngx_http_request_t *) c->data; | 179 r = (ngx_http_request_t *) c->data; |
177 | 180 |
178 ngx_log_debug(ev->log, "http process request"); | 181 ngx_log_debug(ev->log, "http process request"); |
179 | 182 |
180 n = ngx_event_recv(c, r->header_in->last.mem, | 183 if (r->header_read) { |
181 r->header_in->end - r->header_in->last.mem); | 184 r->header_read = 0; |
182 | 185 ngx_log_debug(ev->log, "http preread %d" _ |
183 if (n == NGX_AGAIN) { | 186 r->header_in->last.mem - r->header_in->pos.mem); |
184 if (r->header_timeout) { | 187 |
185 r->header_timeout = 0; | 188 } else { |
186 ngx_del_timer(ev); | 189 n = ngx_event_recv(c, r->header_in->last.mem, |
187 ngx_add_timer(ev, r->server->header_timeout); | 190 r->header_in->end - r->header_in->last.mem); |
188 } | 191 |
189 return NGX_AGAIN; | 192 if (n == NGX_AGAIN) { |
190 } | 193 if (r->header_timeout) { |
191 | 194 r->header_timeout = 0; |
192 if (n == NGX_ERROR) | 195 ngx_del_timer(ev); |
193 return ngx_http_close_request(r); | 196 ngx_add_timer(ev, r->server->header_timeout); |
194 | 197 } |
195 ngx_log_debug(ev->log, "http read %d" _ n); | 198 return NGX_AGAIN; |
196 | 199 } |
197 if (n == 0) { | 200 |
198 if (c->unexpected_eof) | 201 if (n == NGX_ERROR) |
199 ngx_log_error(NGX_LOG_INFO, c->log, 0, | 202 return ngx_http_close_request(r); |
200 "client prematurely closed connection"); | 203 |
201 return ngx_http_close_request(r); | 204 ngx_log_debug(ev->log, "http read %d" _ n); |
202 } | 205 |
203 | 206 if (n == 0) { |
204 r->header_in->last.mem += n; | 207 if (c->unexpected_eof) |
208 ngx_log_error(NGX_LOG_INFO, c->log, 0, | |
209 "client prematurely closed connection"); | |
210 return ngx_http_close_request(r); | |
211 } | |
212 | |
213 r->header_in->last.mem += n; | |
214 } | |
205 | 215 |
206 /* state_handlers are called in following order: | 216 /* state_handlers are called in following order: |
207 ngx_http_process_request_line(r) | 217 ngx_http_process_request_line(r) |
208 ngx_http_process_request_header(r) */ | 218 ngx_http_process_request_header(r) */ |
209 | 219 |
239 ngx_test_null(r->uri, | 249 ngx_test_null(r->uri, |
240 ngx_palloc(r->pool, r->uri_end - r->uri_start + 1), | 250 ngx_palloc(r->pool, r->uri_end - r->uri_start + 1), |
241 ngx_http_close_request(r)); | 251 ngx_http_close_request(r)); |
242 ngx_cpystrn(r->uri, r->uri_start, r->uri_end - r->uri_start + 1); | 252 ngx_cpystrn(r->uri, r->uri_start, r->uri_end - r->uri_start + 1); |
243 | 253 |
244 ngx_log_debug(r->connection->log, "HTTP: %d, %d, %s" _ | 254 if (r->uri_ext) { |
245 r->method _ r->http_version _ r->uri); | 255 ngx_test_null(r->exten, |
256 ngx_palloc(r->pool, r->uri_end - r->uri_ext + 1), | |
257 ngx_http_close_request(r)); | |
258 ngx_cpystrn(r->exten, r->uri_ext, r->uri_end - r->uri_ext + 1); | |
259 } | |
260 | |
261 ngx_log_debug(r->connection->log, "HTTP: %d, %d, %s %s" _ | |
262 r->method _ r->http_version _ r->uri _ r->exten); | |
246 | 263 |
247 if (r->http_version == 9) | 264 if (r->http_version == 9) |
248 return ngx_http_handler(r); | 265 return ngx_http_event_handler(r); |
249 | 266 |
250 /* TODO: check too long URI - no space for header, compact buffer */ | 267 /* TODO: check too long URI - no space for header, compact buffer */ |
251 | 268 |
252 r->state_handler = ngx_http_process_request_header; | 269 r->state_handler = ngx_http_process_request_header; |
253 ctx = r->connection->log->data; | 270 ctx = r->connection->log->data; |
290 if (ngx_http_process_request_header_line(r) == NGX_ERROR) | 307 if (ngx_http_process_request_header_line(r) == NGX_ERROR) |
291 return ngx_http_error(r, NGX_HTTP_BAD_REQUEST); | 308 return ngx_http_error(r, NGX_HTTP_BAD_REQUEST); |
292 | 309 |
293 } else if (rc == NGX_HTTP_PARSE_HEADER_DONE) { | 310 } else if (rc == NGX_HTTP_PARSE_HEADER_DONE) { |
294 ngx_log_debug(r->connection->log, "HTTP header done"); | 311 ngx_log_debug(r->connection->log, "HTTP header done"); |
295 return ngx_http_handler(r); | 312 return ngx_http_event_handler(r); |
296 | 313 |
297 } else if (rc == NGX_AGAIN) { | 314 } else if (rc == NGX_AGAIN) { |
298 return NGX_AGAIN; | 315 return NGX_AGAIN; |
299 | 316 |
300 } else if (rc == NGX_HTTP_PARSE_INVALID_HEADER) { | 317 } else if (rc == NGX_HTTP_PARSE_INVALID_HEADER) { |
395 return n; | 412 return n; |
396 } | 413 } |
397 | 414 |
398 /* ******************** */ | 415 /* ******************** */ |
399 | 416 |
400 static int ngx_http_handler(ngx_http_request_t *r) | 417 |
401 { | 418 static int ngx_http_event_handler(ngx_http_request_t *r) |
402 int rc; | 419 { |
420 int rc; | |
403 ngx_msec_t timeout; | 421 ngx_msec_t timeout; |
404 | 422 |
405 ngx_del_timer(r->connection->read); | 423 rc = ngx_http_handler(r); |
406 r->header_timeout = 0; | |
407 | |
408 r->process_header = 0; | |
409 r->state_handler = NULL; | |
410 r->connection->unexpected_eof = 0; | |
411 r->lingering_close = 1; | |
412 | |
413 r->connection->read->event_handler = ngx_http_block_read; | |
414 | |
415 /* STUB: should find handler */ | |
416 r->filter = NGX_HTTP_FILTER_NEED_IN_MEMORY; | |
417 rc = ngx_http_set_default_handler(r); | |
418 | |
419 if (rc >= NGX_HTTP_SPECIAL_RESPONSE) | |
420 return ngx_http_special_response(r, rc); | |
421 | |
422 rc = r->handler(r); | |
423 | 424 |
424 /* transfer not completed */ | 425 /* transfer not completed */ |
425 if (rc == NGX_AGAIN) { | 426 if (rc == NGX_AGAIN) { |
426 #if (HAVE_CLEAR_EVENT) | 427 #if (HAVE_CLEAR_EVENT) |
427 if (ngx_add_event(r->connection->write, NGX_WRITE_EVENT, | 428 if (ngx_add_event(r->connection->write, NGX_WRITE_EVENT, |
458 | 459 |
459 /* rc == NGX_OK */ | 460 /* rc == NGX_OK */ |
460 | 461 |
461 if (!r->keepalive) { | 462 if (!r->keepalive) { |
462 if (r->lingering_close) { | 463 if (r->lingering_close) { |
463 r->lingering_time = ngx_time() + SOME_LINGERING_TIME; | 464 return ngx_http_set_lingering_close(r); |
464 r->connection->read->event_handler = ngx_http_lingering_close; | 465 |
465 ngx_del_timer(r->connection->read); | |
466 ngx_add_timer(r->connection->read, LINGERING_TIMEOUT * 1000); | |
467 if (ngx_add_event(r->connection->read, NGX_READ_EVENT, | |
468 NGX_ONESHOT_EVENT) == NGX_ERROR) { | |
469 return ngx_http_close_request(r); | |
470 } | |
471 if (ngx_shutdown_socket(r->connection->fd, NGX_WRITE_SHUTDOWN) | |
472 == NGX_ERROR) | |
473 { | |
474 ngx_log_error(NGX_LOG_ERR, r->connection->log, ngx_socket_errno, | |
475 ngx_shutdown_socket_n " failed"); | |
476 return ngx_http_close_request(r); | |
477 } | |
478 } else { | 466 } else { |
479 return ngx_http_close_request(r); | 467 return ngx_http_close_request(r); |
480 } | 468 } |
481 } | 469 } |
470 | |
471 /* keepalive */ | |
472 | |
473 ngx_http_close_request(r); | |
474 r->connection->buffer->pos.mem = r->connection->buffer->last.mem | |
475 = r->connection->buffer->start; | |
476 r->connection->read->event_handler = ngx_http_keepalive_handler; | |
477 } | |
478 | |
479 static int ngx_http_handler(ngx_http_request_t *r) | |
480 { | |
481 int rc; | |
482 | |
483 ngx_del_timer(r->connection->read); | |
484 r->header_timeout = 0; | |
485 | |
486 r->process_header = 0; | |
487 r->state_handler = NULL; | |
488 r->connection->unexpected_eof = 0; | |
489 r->lingering_close = 1; | |
490 | |
491 r->connection->read->event_handler = ngx_http_block_read; | |
492 | |
493 /* STUB: should find handler */ | |
494 #if 0 | |
495 r->filter = NGX_HTTP_FILTER_NEED_IN_MEMORY; | |
496 #endif | |
497 rc = ngx_http_set_default_handler(r); | |
498 | |
499 if (rc >= NGX_HTTP_SPECIAL_RESPONSE) | |
500 return ngx_http_special_response(r, rc); | |
501 | |
502 rc = r->handler(r); | |
503 | |
504 return rc; | |
482 } | 505 } |
483 | 506 |
484 int ngx_http_internal_redirect(ngx_http_request_t *r, char *uri) | 507 int ngx_http_internal_redirect(ngx_http_request_t *r, char *uri) |
485 { | 508 { |
486 ngx_log_debug(r->connection->log, "internal redirect: '%s'" _ uri); | 509 ngx_log_debug(r->connection->log, "internal redirect: '%s'" _ uri); |
546 | 569 |
547 static int ngx_http_block_read(ngx_event_t *ev) | 570 static int ngx_http_block_read(ngx_event_t *ev) |
548 { | 571 { |
549 ngx_log_debug(ev->log, "http read blocked"); | 572 ngx_log_debug(ev->log, "http read blocked"); |
550 | 573 |
551 ngx_del_event(ev, NGX_READ_EVENT); | |
552 ev->blocked = 1; | 574 ev->blocked = 1; |
575 return ngx_del_event(ev, NGX_READ_EVENT); | |
553 } | 576 } |
554 | 577 |
555 | 578 |
556 static int ngx_http_writer(ngx_event_t *ev) | 579 static int ngx_http_writer(ngx_event_t *ev) |
557 { | 580 { |
558 int rc; | 581 int rc; |
559 unsigned int timeout; | 582 ngx_msec_t timeout; |
560 ngx_connection_t *c; | 583 ngx_connection_t *c; |
561 ngx_http_request_t *r; | 584 ngx_http_request_t *r; |
585 ngx_http_core_conf_t *conf; | |
562 | 586 |
563 c = (ngx_connection_t *) ev->data; | 587 c = (ngx_connection_t *) ev->data; |
564 r = (ngx_http_request_t *) c->data; | 588 r = (ngx_http_request_t *) c->data; |
565 | 589 |
566 c->sent = 0; | 590 c->sent = 0; |
567 | 591 |
568 rc = ngx_http_output_filter(r, NULL); | 592 rc = ngx_http_output_filter(r, NULL); |
569 | 593 |
570 ngx_log_debug(ev->log, "output_filter: %d" _ rc); | 594 ngx_log_debug(ev->log, "output filter in writer: %d" _ rc); |
571 | 595 |
572 if (rc == NGX_AGAIN) { | 596 if (rc == NGX_AGAIN) { |
573 | 597 |
574 if (c->sent > 0) { | 598 if (c->sent > 0) { |
599 conf = (ngx_http_core_conf_t *) | |
600 ngx_get_module_loc_conf(r->main ? r->main : r, | |
601 ngx_http_core_module); | |
602 | |
603 timeout = (ngx_msec_t) (c->sent * conf->send_timeout); | |
604 | |
575 ngx_log_debug(ev->log, "sent: " QD_FMT _ c->sent); | 605 ngx_log_debug(ev->log, "sent: " QD_FMT _ c->sent); |
576 timeout = (ngx_msec_t) (c->sent * 10); | |
577 ngx_log_debug(ev->log, "timeout: %d" _ timeout); | 606 ngx_log_debug(ev->log, "timeout: %d" _ timeout); |
607 | |
578 ngx_del_timer(ev); | 608 ngx_del_timer(ev); |
579 ngx_add_timer(ev, timeout); | 609 ngx_add_timer(ev, timeout); |
580 } | 610 } |
581 | 611 |
582 if (ev->oneshot) | 612 if (ev->oneshot) |
583 if (ngx_add_event(r->connection->write, NGX_WRITE_EVENT, | 613 if (ngx_add_event(r->connection->write, NGX_WRITE_EVENT, |
584 NGX_ONESHOT_EVENT) == NGX_ERROR) { | 614 NGX_ONESHOT_EVENT) == NGX_ERROR) { |
585 /* log http request */ | |
586 return ngx_http_close_request(r); | 615 return ngx_http_close_request(r); |
587 } | 616 } |
588 | 617 |
589 return rc; | 618 return rc; |
590 } | 619 } |
592 if (rc == NGX_ERROR) | 621 if (rc == NGX_ERROR) |
593 return rc; | 622 return rc; |
594 | 623 |
595 /* rc == NGX_OK */ | 624 /* rc == NGX_OK */ |
596 | 625 |
597 ngx_log_debug(ev->log, "ngx_http_writer done"); | 626 ngx_log_debug(ev->log, "http writer done"); |
598 | 627 |
599 if (!r->keepalive) { | 628 if (!r->keepalive) { |
600 if (r->lingering_close) { | 629 if (r->lingering_close) { |
601 r->lingering_time = ngx_time() + SOME_LINGERING_TIME; | 630 ngx_http_set_lingering_close(r); |
602 r->connection->read->event_handler = ngx_http_lingering_close; | 631 |
603 ngx_del_timer(r->connection->read); | |
604 ngx_add_timer(r->connection->read, LINGERING_TIMEOUT * 1000); | |
605 if (ngx_add_event(r->connection->read, NGX_READ_EVENT, | |
606 NGX_ONESHOT_EVENT) == NGX_ERROR) { | |
607 return ngx_http_close_request(r); | |
608 } | |
609 if (ngx_shutdown_socket(r->connection->fd, NGX_WRITE_SHUTDOWN) | |
610 == NGX_ERROR) | |
611 { | |
612 ngx_log_error(NGX_LOG_ERR, r->connection->log, ngx_socket_errno, | |
613 ngx_shutdown_socket_n " failed"); | |
614 return ngx_http_close_request(r); | |
615 } | |
616 } else { | 632 } else { |
617 return ngx_http_close_request(r); | 633 return ngx_http_close_request(r); |
618 } | 634 } |
619 } | 635 } |
620 | 636 |
621 /* keepalive */ | 637 /* keepalive */ |
622 ev = r->connection->read; | 638 |
623 ngx_http_close_request(r); | 639 ngx_http_close_request(r); |
624 ev->event_handler = ngx_http_init_request; | 640 c->buffer->pos.mem = c->buffer->last.mem = c->buffer->start; |
625 } | 641 c->read->event_handler = ngx_http_keepalive_handler; |
626 | 642 } |
627 #if 0 | 643 |
644 static int ngx_http_set_lingering_close(ngx_http_request_t *r) | |
645 { | |
646 r->lingering_time = ngx_time() + r->server->lingering_time; | |
647 r->connection->read->event_handler = ngx_http_lingering_close; | |
648 | |
649 ngx_del_timer(r->connection->read); | |
650 ngx_add_timer(r->connection->read, r->server->lingering_timeout); | |
651 | |
652 #if (HAVE_CLEAR_EVENT) | |
653 if (ngx_add_event(r->connection->read, NGX_READ_EVENT, | |
654 NGX_CLEAR_EVENT) == NGX_ERROR) { | |
655 #else | |
656 if (ngx_add_event(r->connection->read, NGX_READ_EVENT, | |
657 NGX_ONESHOT_EVENT) == NGX_ERROR) { | |
658 #endif | |
659 return ngx_http_close_request(r); | |
660 } | |
661 | |
662 if (ngx_shutdown_socket(r->connection->fd, NGX_WRITE_SHUTDOWN) == NGX_ERROR) | |
663 { | |
664 ngx_log_error(NGX_LOG_ERR, r->connection->log, ngx_socket_errno, | |
665 ngx_shutdown_socket_n " failed"); | |
666 return ngx_http_close_request(r); | |
667 } | |
668 | |
669 return NGX_OK; | |
670 } | |
671 | |
628 | 672 |
629 static int ngx_http_keepalive_handler(ngx_event_t *ev) | 673 static int ngx_http_keepalive_handler(ngx_event_t *ev) |
630 { | 674 { |
675 ssize_t n; | |
631 ngx_connection_t *c; | 676 ngx_connection_t *c; |
632 ngx_http_log_ctx_t *ctx; | 677 ngx_http_log_ctx_t *ctx; |
633 | 678 |
679 c = (ngx_connection_t *) ev->data; | |
680 | |
634 ngx_log_debug(ev->log, "http keepalive"); | 681 ngx_log_debug(ev->log, "http keepalive"); |
635 | 682 |
636 if (ev->timedout) | 683 if (ev->timedout) |
637 return NGX_DONE; | 684 return NGX_DONE; |
638 | 685 |
639 if (closed) | 686 n = ngx_event_recv(c, c->buffer->last.mem, |
640 /* NGX_LOG_INFO or even silent */ | 687 c->buffer->end - c->buffer->last.mem); |
641 return NGX_ERROR; | 688 |
642 | 689 if (n == NGX_AGAIN || n == NGX_ERROR) |
643 c = (ngx_connection_t *) ev->data; | 690 return n; |
644 | 691 |
645 ctx = (ngx_http_log_ctx_t *) c->log->data; | 692 ctx = (ngx_http_log_ctx_t *) ev->log->data; |
693 ev->log->handler = NULL; | |
694 | |
695 if (n == 0) { | |
696 ngx_log_error(NGX_LOG_INFO, ev->log, 0, | |
697 "client %s closed keepalive connection", ctx->client); | |
698 return NGX_DONE; | |
699 } | |
700 | |
701 c->buffer->last.mem += n; | |
702 ev->log->handler = ngx_http_log_error; | |
646 ctx->action = "reading client request line"; | 703 ctx->action = "reading client request line"; |
647 c->log->handler = ngx_http_log_error; | |
648 | 704 |
649 return ngx_http_init_request(ev); | 705 return ngx_http_init_request(ev); |
650 } | 706 } |
651 | 707 |
652 #endif | |
653 | 708 |
654 static int ngx_http_lingering_close(ngx_event_t *ev) | 709 static int ngx_http_lingering_close(ngx_event_t *ev) |
655 { | 710 { |
656 ssize_t n; | 711 ssize_t n; |
657 ngx_msec_t timer; | 712 ngx_msec_t timer; |
664 ngx_log_debug(ev->log, "http lingering close"); | 719 ngx_log_debug(ev->log, "http lingering close"); |
665 | 720 |
666 if (ev->timedout) | 721 if (ev->timedout) |
667 return NGX_DONE; | 722 return NGX_DONE; |
668 | 723 |
669 /* STUB */ | |
670 timer = r->lingering_time - ngx_time(); | 724 timer = r->lingering_time - ngx_time(); |
671 if (timer <= 0) | 725 if (timer <= 0) |
672 return NGX_DONE; | 726 return NGX_DONE; |
673 | 727 |
674 if (r->discarded_buffer == NULL) | 728 if (r->discarded_buffer == NULL) { |
675 ngx_test_null(r->discarded_buffer, | 729 if (r->header_in->end - r->header_in->last.mem |
676 ngx_palloc(r->pool, r->server->discarded_buffer_size), | 730 >= r->server->discarded_buffer_size) { |
677 NGX_ERROR); | 731 r->discarded_buffer = r->header_in->last.mem; |
732 | |
733 } else { | |
734 ngx_test_null(r->discarded_buffer, | |
735 ngx_palloc(c->pool, r->server->discarded_buffer_size), | |
736 NGX_ERROR); | |
737 } | |
738 } | |
678 | 739 |
679 n = ngx_event_recv(c, r->discarded_buffer, | 740 n = ngx_event_recv(c, r->discarded_buffer, |
680 r->server->discarded_buffer_size); | 741 r->server->discarded_buffer_size); |
681 | 742 |
682 if (n == NGX_ERROR) | 743 if (n == NGX_ERROR) |
683 return NGX_ERROR; | 744 return NGX_ERROR; |
684 | 745 |
685 if (n == 0) | 746 if (n == 0) |
686 return NGX_DONE; | 747 return NGX_DONE; |
687 | 748 |
688 if (timer > LINGERING_TIMEOUT) | 749 timer *= 1000; |
689 timer = LINGERING_TIMEOUT; | 750 if (timer > r->server->lingering_timeout) |
751 timer = r->server->lingering_timeout; | |
690 | 752 |
691 ngx_del_timer(ev); | 753 ngx_del_timer(ev); |
692 ngx_add_timer(ev, timer * 1000); | 754 ngx_add_timer(ev, timer); |
693 | 755 |
694 return NGX_OK; | 756 return NGX_OK; |
695 } | 757 } |
696 | 758 |
697 | 759 |
698 static int ngx_http_special_response(ngx_http_request_t *r, int error) | 760 static int ngx_http_special_response(ngx_http_request_t *r, int error) |
699 { | 761 { |
700 return ngx_http_error(r, error); | 762 return ngx_http_error(r, error); |
701 } | 763 } |
702 | 764 |
765 | |
703 static int ngx_http_redirect(ngx_http_request_t *r, int redirect) | 766 static int ngx_http_redirect(ngx_http_request_t *r, int redirect) |
704 { | 767 { |
705 /* STUB */ | 768 /* STUB */ |
706 | 769 |
707 /* log request */ | 770 /* log request */ |
708 | 771 |
709 return ngx_http_close_request(r); | 772 return ngx_http_close_request(r); |
710 } | 773 } |
774 | |
711 | 775 |
712 static int ngx_http_error(ngx_http_request_t *r, int error) | 776 static int ngx_http_error(ngx_http_request_t *r, int error) |
713 { | 777 { |
714 /* STUB */ | 778 /* STUB */ |
715 ngx_log_debug(r->connection->log, "http error: %d" _ error); | 779 ngx_log_debug(r->connection->log, "http error: %d" _ error); |