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);