comparison src/http/ngx_http_event.c @ 67:5a7d1aaa1618

nginx-0.0.1-2003-03-11-23:38:13 import
author Igor Sysoev <igor@sysoev.ru>
date Tue, 11 Mar 2003 20:38:13 +0000
parents 4876cd4a36bb
children d549fdc17d7e
comparison
equal deleted inserted replaced
66:4876cd4a36bb 67:5a7d1aaa1618
128 128
129 #endif 129 #endif
130 130
131 /* select, poll, /dev/poll */ 131 /* select, poll, /dev/poll */
132 132
133 ev->level = 1;
134 return ngx_add_event(ev, NGX_READ_EVENT, NGX_LEVEL_EVENT); 133 return ngx_add_event(ev, NGX_READ_EVENT, NGX_LEVEL_EVENT);
135 134
136 #endif /* USE_KQUEUE */ 135 #endif /* USE_KQUEUE */
137 } 136 }
138 137
188 } 187 }
189 188
190 189
191 static int ngx_http_process_request_header(ngx_event_t *ev) 190 static int ngx_http_process_request_header(ngx_event_t *ev)
192 { 191 {
193 int n, rc; 192 int n, rc, again;
194 ngx_connection_t *c; 193 ngx_connection_t *c;
195 ngx_http_request_t *r; 194 ngx_http_request_t *r;
196 ngx_http_log_ctx_t *ctx; 195 ngx_http_log_ctx_t *ctx;
197 196
198 c = (ngx_connection_t *) ev->data; 197 c = (ngx_connection_t *) ev->data;
199 r = (ngx_http_request_t *) c->data; 198 r = (ngx_http_request_t *) c->data;
200 199
201 ngx_log_debug(ev->log, "http process request"); 200 ngx_log_debug(ev->log, "http process request");
202 201
203 #if (HAVE_AIO_EVENT)
204 do { 202 do {
205 #endif
206 203
207 if (r->header_read) { 204 if (r->header_read) {
205 if (r->header_in->end - r->header_in->last == 0) {
206 again = 1;
207 } else {
208 again = 0;
209 }
210
208 r->header_read = 0; 211 r->header_read = 0;
209 ngx_log_debug(ev->log, "http preread %d" _ 212 ngx_log_debug(ev->log, "http preread %d" _
210 r->header_in->last.mem - r->header_in->pos.mem); 213 r->header_in->last - r->header_in->pos);
211 214
212 } else { 215 } else {
213 n = ngx_event_recv(c, r->header_in->last.mem, 216 n = ngx_event_recv(c, r->header_in->last,
214 r->header_in->end - r->header_in->last.mem); 217 r->header_in->end - r->header_in->last);
215 218
216 if (n == NGX_AGAIN) { 219 if (n == NGX_AGAIN) {
217 if (!r->header_timeout_set) { 220 if (!r->header_timeout_set) {
218 221
219 if (ev->timer_set) { 222 if (ev->timer_set) {
226 r->header_timeout_set = 1; 229 r->header_timeout_set = 1;
227 } 230 }
228 return NGX_AGAIN; 231 return NGX_AGAIN;
229 } 232 }
230 233
231 if (n == NGX_ERROR) 234 if (n == NGX_ERROR) {
232 return ngx_http_close_request(r); 235 return ngx_http_close_request(r);
236 }
233 237
234 ngx_log_debug(ev->log, "http read %d" _ n); 238 ngx_log_debug(ev->log, "http read %d" _ n);
235 239
236 if (n == 0) { 240 if (n == 0) {
237 ngx_log_error(NGX_LOG_INFO, c->log, 0, 241 ngx_log_error(NGX_LOG_INFO, c->log, 0,
238 "client has prematurely closed connection"); 242 "client has prematurely closed connection");
239 return ngx_http_close_request(r); 243 return ngx_http_close_request(r);
240 } 244 }
241 245
242 r->header_in->last.mem += n; 246 r->header_in->last += n;
247
248 if (ngx_http_large_client_header
249 && r->header_in->end == r->header_in->last) {
250 again = 1;
251 } else {
252 again = 0;
253 }
243 } 254 }
244 255
245 /* the state_handlers are called in the following order: 256 /* the state_handlers are called in the following order:
246 ngx_http_process_request_line(r) 257 ngx_http_process_request_line(r)
247 ngx_http_process_request_headers(r) */ 258 ngx_http_process_request_headers(r) */
248 259
249 do { 260 do {
250 /* state_handlers return NGX_OK when the whole header done */ 261 /* state_handlers return NGX_OK when the whole header done */
251 rc = (r->state_handler)(r); 262 rc = (r->state_handler)(r);
252 263
253 if (rc == NGX_ERROR) 264 if (rc == NGX_ERROR) {
254 return rc; 265 return rc;
255 266 }
256 } while (rc == NGX_AGAIN 267
257 && r->header_in->pos.mem < r->header_in->last.mem); 268 } while (rc == NGX_AGAIN && r->header_in->pos < r->header_in->last);
258 269
259 #if (HAVE_AIO_EVENT) /* aio, iocp */ 270 #if (HAVE_AIO_EVENT) /* aio, iocp */
260 } while (rc == NGX_AGAIN && ngx_event_flags & NGX_HAVE_AIO_EVENT); 271
272 if (ngx_event_flags & NGX_HAVE_AIO_EVENT) {
273 again = 1;
274 }
275
261 #endif 276 #endif
277
278 } while (rc == NGX_AGAIN && again);
262 279
263 if (rc == NGX_OK) { 280 if (rc == NGX_OK) {
264 /* HTTP header done */ 281 /* HTTP header done */
265 282
266 if (ev->timer_set) { 283 if (ev->timer_set) {
306 - r->uri_start; 323 - r->uri_start;
307 ngx_test_null(r->uri.data, ngx_palloc(r->pool, r->uri.len + 1), 324 ngx_test_null(r->uri.data, ngx_palloc(r->pool, r->uri.len + 1),
308 ngx_http_close_request(r)); 325 ngx_http_close_request(r));
309 ngx_cpystrn(r->uri.data, r->uri_start, r->uri.len + 1); 326 ngx_cpystrn(r->uri.data, r->uri_start, r->uri.len + 1);
310 327
311 /* if the large client headers is enabled then 328 /* if the large client headers are enabled then
312 we need to copy a request line */ 329 we need to copy a request line */
313 330
314 r->request_line.len = r->request_end - r->request_start; 331 r->request_line.len = r->request_end - r->request_start;
315 if (ngx_http_large_client_header) { 332 if (ngx_http_large_client_header) {
316 ngx_test_null(r->request_line.data, 333 ngx_test_null(r->request_line.data,
374 return ngx_http_header_parse_error(r, rc, NGX_HTTP_BAD_REQUEST); 391 return ngx_http_header_parse_error(r, rc, NGX_HTTP_BAD_REQUEST);
375 } 392 }
376 393
377 /* NGX_AGAIN: a request line parsing is still not complete */ 394 /* NGX_AGAIN: a request line parsing is still not complete */
378 395
379 if (r->header_in->last.mem == r->header_in->end) { 396 if (r->header_in->last == r->header_in->end) {
380 397
381 /* If it's a pipelined request and a request line is not complete 398 /* If it's a pipelined request and a request line is not complete
382 then we need to copy it to the start of r->header_in hunk. 399 then we need to copy it to the start of r->header_in hunk.
383 We need to copy it here only if the large client header 400 We need to copy it here only if the large client headers
384 is enabled otherwise a request line had been already copied 401 are enabled otherwise a request line had been already copied
385 to the start of r->header_in hunk in ngx_http_set_keepalive() */ 402 to the start of r->header_in hunk in ngx_http_set_keepalive() */
386 403
387 if (ngx_http_large_client_header) { 404 if (ngx_http_large_client_header) {
388 offset = r->request_start - r->header_in->start; 405 offset = r->request_start - r->header_in->start;
389 406
392 NGX_HTTP_PARSE_TOO_LONG_URI, 409 NGX_HTTP_PARSE_TOO_LONG_URI,
393 NGX_HTTP_REQUEST_URI_TOO_LARGE); 410 NGX_HTTP_REQUEST_URI_TOO_LARGE);
394 } 411 }
395 412
396 ngx_memcpy(r->header_in->start, r->request_start, 413 ngx_memcpy(r->header_in->start, r->request_start,
397 r->header_in->last.mem - r->request_start); 414 r->header_in->last - r->request_start);
398 415
399 r->header_in->pos.mem -= offset; 416 r->header_in->pos -= offset;
400 r->header_in->last.mem -= offset; 417 r->header_in->last -= offset;
401 r->request_start = r->header_in->start; 418 r->request_start = r->header_in->start;
402 r->request_end -= offset; 419 r->request_end -= offset;
403 r->uri_start -= offset; 420 r->uri_start -= offset;
404 r->uri_end -= offset; 421 r->uri_end -= offset;
405 if (r->uri_ext) { 422 if (r->uri_ext) {
435 return ngx_http_error(r, NGX_HTTP_INTERNAL_SERVER_ERROR); 452 return ngx_http_error(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
436 } 453 }
437 454
438 return NGX_AGAIN; 455 return NGX_AGAIN;
439 456
440 /* the whole header has been parsed successfully */ 457 /* a whole header has been parsed successfully */
441 } else if (rc == NGX_HTTP_PARSE_HEADER_DONE) { 458 } else if (rc == NGX_HTTP_PARSE_HEADER_DONE) {
442 ngx_log_debug(r->connection->log, "HTTP header done"); 459 ngx_log_debug(r->connection->log, "HTTP header done");
443 460
444 if (r->headers_in.host) { 461 if (r->headers_in.host) {
445 for (len = 0; len < r->headers_in.host->value.len; len++) { 462 for (len = 0; len < r->headers_in.host->value.len; len++) {
466 return ngx_http_header_parse_error(r, rc, NGX_HTTP_BAD_REQUEST); 483 return ngx_http_header_parse_error(r, rc, NGX_HTTP_BAD_REQUEST);
467 } 484 }
468 485
469 /* NGX_AGAIN: a header line parsing is still not complete */ 486 /* NGX_AGAIN: a header line parsing is still not complete */
470 487
471 if (r->header_in->last.mem == r->header_in->end) { 488 if (r->header_in->last == r->header_in->end) {
472 489
473 /* if the large client header is enabled then 490 /* if the large client headers are enabled then
474 we need to compact r->header_in hunk */ 491 we need to compact r->header_in hunk */
475 492
476 if (ngx_http_large_client_header) { 493 if (ngx_http_large_client_header) {
477 offset = r->header_name_start - r->header_in->start; 494 offset = r->header_name_start - r->header_in->start;
478 495
481 NGX_HTTP_PARSE_TOO_LONG_HEADER, 498 NGX_HTTP_PARSE_TOO_LONG_HEADER,
482 NGX_HTTP_BAD_REQUEST); 499 NGX_HTTP_BAD_REQUEST);
483 } 500 }
484 501
485 ngx_memcpy(r->header_in->start, r->header_name_start, 502 ngx_memcpy(r->header_in->start, r->header_name_start,
486 r->header_in->last.mem - r->header_name_start); 503 r->header_in->last - r->header_name_start);
487 504
488 r->header_in->last.mem -= offset; 505 r->header_in->last -= offset;
489 r->header_in->pos.mem -= offset; 506 r->header_in->pos -= offset;
490 r->header_name_start = r->header_in->start; 507 r->header_name_start = r->header_in->start;
491 r->header_name_end -= offset; 508 r->header_name_end -= offset;
492 r->header_start -= offset; 509 r->header_start -= offset;
493 r->header_end -= offset; 510 r->header_end -= offset;
494 511
510 int i; 527 int i;
511 ngx_table_elt_t *h; 528 ngx_table_elt_t *h;
512 529
513 ngx_test_null(h, ngx_push_table(r->headers_in.headers), NGX_ERROR); 530 ngx_test_null(h, ngx_push_table(r->headers_in.headers), NGX_ERROR);
514 531
515 /* if large client header is enabled then 532 /* if large client headers are enabled then
516 we need to copy header name and value */ 533 we need to copy header name and value */
517 534
518 h->key.len = r->header_name_end - r->header_name_start; 535 h->key.len = r->header_name_end - r->header_name_start;
519 h->value.len = r->header_end - r->header_start; 536 h->value.len = r->header_end - r->header_start;
520 537
629 if (ngx_event_flags & NGX_HAVE_CLEAR_EVENT) { 646 if (ngx_event_flags & NGX_HAVE_CLEAR_EVENT) {
630 event = NGX_CLEAR_EVENT; 647 event = NGX_CLEAR_EVENT;
631 648
632 } else { 649 } else {
633 event = NGX_LEVEL_EVENT; 650 event = NGX_LEVEL_EVENT;
634 wev->level = 1;
635 } 651 }
636 652
637 #else /* select, poll, /dev/poll */ 653 #else /* select, poll, /dev/poll */
638 654
639 event = NGX_LEVEL_EVENT; 655 event = NGX_LEVEL_EVENT;
640 wev->level = 1;
641 656
642 #endif 657 #endif
643 658
644 if (ngx_add_event(wev, NGX_WRITE_EVENT, event) == NGX_ERROR) { 659 if (ngx_add_event(wev, NGX_WRITE_EVENT, event) == NGX_ERROR) {
645 return ngx_http_close_request(r); 660 return ngx_http_close_request(r);
749 764
750 return NGX_OK; 765 return NGX_OK;
751 766
752 #else 767 #else
753 768
754 if (ev->level) { /* select, poll, /dev/poll */ 769 if (ngx_event_flags & NGX_USE_LEVEL_EVENT) { /* select, poll, /dev/poll */
755 ev->blocked = 1; 770 ev->blocked = 1;
756 return ngx_del_event(ev, NGX_READ_EVENT, 0); 771 return ngx_del_event(ev, NGX_READ_EVENT, 0);
757 772
758 } else { /* kqueue, epoll */ 773 } else { /* kqueue, epoll */
759 return NGX_OK; 774 return NGX_OK;
760 } 775 }
761 776
762 #endif /* USE_KQUEUE */ 777 #endif /* USE_KQUEUE */
763 } 778 }
829 } 844 }
830 845
831 846
832 static int ngx_http_set_keepalive(ngx_http_request_t *r) 847 static int ngx_http_set_keepalive(ngx_http_request_t *r)
833 { 848 {
834 int len; 849 int len, blocked;
835 ngx_hunk_t *h; 850 ngx_hunk_t *h;
836 ngx_event_t *rev, *wev; 851 ngx_event_t *rev, *wev;
837 ngx_connection_t *c; 852 ngx_connection_t *c;
838 ngx_http_log_ctx_t *ctx; 853 ngx_http_log_ctx_t *ctx;
839 854
840 c = (ngx_connection_t *) r->connection; 855 c = (ngx_connection_t *) r->connection;
841 rev = c->read; 856 rev = c->read;
842 wev = c->write; 857 wev = c->write;
843 858
844 if (rev->blocked && rev->level) {
845 if (ngx_add_event(rev, NGX_READ_EVENT, NGX_LEVEL_EVENT) == NGX_ERROR) {
846 return NGX_ERROR;
847 }
848 rev->blocked = 0;
849 }
850
851 ctx = (ngx_http_log_ctx_t *) c->log->data; 859 ctx = (ngx_http_log_ctx_t *) c->log->data;
852 ctx->action = "closing request"; 860 ctx->action = "closing request";
853 ngx_http_close_request(r); 861 ngx_http_close_request(r);
854 862
863 if (rev->blocked && (ngx_event_flags & NGX_USE_LEVEL_EVENT)) {
864 if (ngx_add_event(rev, NGX_READ_EVENT, NGX_LEVEL_EVENT) == NGX_ERROR) {
865 return NGX_ERROR;
866 }
867 blocked = 1;
868 rev->blocked = 0;
869
870 } else {
871 blocked = 0;
872 }
873
855 h = c->buffer; 874 h = c->buffer;
856 875
857 /* pipelined request */ 876 /* pipelined request */
858 if (h->pos.mem < h->last.mem) { 877 if (h->pos < h->last) {
859 878
860 /* We do not know here whether pipelined request is complete 879 /* We do not know here whether pipelined request is complete
861 so we need to copy it to the start of c->buffer if the large 880 so if large client headers are not enabled
862 client header is not enabled. This copy should be rare 881 we need to copy the data to the start of c->buffer.
863 because clients that support pipelined requests (Mozilla 1.x, 882 This copy should be rare because clients that support
864 Opera 6.x) are still rare */ 883 pipelined requests (Mozilla 1.x, Opera 6.x) are still rare */
865 884
866 if (!ngx_http_large_client_header) { 885 if (!ngx_http_large_client_header) {
867 len = h->last.mem - h->pos.mem; 886 len = h->last - h->pos;
868 ngx_memcpy(h->start, h->pos.mem, len); 887 ngx_memcpy(h->start, h->pos, len);
869 h->pos.mem = h->start; 888 h->pos = h->start;
870 h->last.mem = h->start + len; 889 h->last = h->start + len;
871 } 890 }
872 891
873 c->pipeline = 1; 892 c->pipeline = 1;
874 ctx->action = "reading client pipelined request line"; 893 ctx->action = "reading client pipelined request line";
875 return ngx_http_init_request(rev); 894 return ngx_http_init_request(rev);
876 } 895 }
877 896
878 c->pipeline = 0; 897 c->pipeline = 0;
879 898
880 h->pos.mem = h->last.mem = h->start; 899 h->pos = h->last = h->start;
881 rev->event_handler = ngx_http_keepalive_handler; 900 rev->event_handler = ngx_http_keepalive_handler;
882 901
883 if (wev->active && wev->level) { 902 if (wev->active && (ngx_event_flags & NGX_USE_LEVEL_EVENT)) {
884 if (ngx_del_event(wev, NGX_WRITE_EVENT, 0) == NGX_ERROR) { 903 if (ngx_del_event(wev, NGX_WRITE_EVENT, 0) == NGX_ERROR) {
885 return NGX_ERROR; 904 return NGX_ERROR;
886 } 905 }
887 } 906 }
888 907
889 ctx->action = "keepalive"; 908 ctx->action = "keepalive";
890 909
891 #if (HAVE_AIO_EVENT) /* aio, iocp */ 910 #if (HAVE_AIO_EVENT) /* aio, iocp */
892 911
893 if (ngx_event_flags & NGX_HAVE_AIO_EVENT) { 912 if ((ngx_event_flags & NGX_HAVE_AIO_EVENT) || blocked) {
913 return ngx_http_keepalive_handler(rev);
914 }
915
916 #else
917
918 if (blocked) {
894 return ngx_http_keepalive_handler(rev); 919 return ngx_http_keepalive_handler(rev);
895 } 920 }
896 921
897 #endif 922 #endif
898 923
911 ngx_log_debug(ev->log, "http keepalive handler"); 936 ngx_log_debug(ev->log, "http keepalive handler");
912 937
913 if (ev->timedout) 938 if (ev->timedout)
914 return NGX_DONE; 939 return NGX_DONE;
915 940
916 /* TODO: MSIE closes keepalive connection with ECONNRESET 941 /* MSIE closes keepalive connection with RST flag
917 so we need to handle here this error 942 so we ignore ECONNRESET here */
918 1) in INFO (not ERR) level, 2) with time elapsed */ 943
919 n = ngx_event_recv(c, c->buffer->last.mem, 944 ev->ignore_econnreset = 1;
920 c->buffer->end - c->buffer->last.mem); 945 ngx_set_socket_errno(0);
946 n = ngx_event_recv(c, c->buffer->last, c->buffer->end - c->buffer->last);
947 ev->ignore_econnreset = 0;
921 948
922 if (n == NGX_AGAIN || n == NGX_ERROR) 949 if (n == NGX_AGAIN || n == NGX_ERROR)
923 return n; 950 return n;
924 951
925 ctx = (ngx_http_log_ctx_t *) ev->log->data; 952 ctx = (ngx_http_log_ctx_t *) ev->log->data;
926 ev->log->handler = NULL; 953 ev->log->handler = NULL;
927 954
928 if (n == 0) { 955 if (n == 0) {
929 ngx_log_error(NGX_LOG_INFO, ev->log, 0, 956 ngx_log_error(NGX_LOG_INFO, ev->log, ngx_socket_errno,
930 "client %s closed keepalive connection", ctx->client); 957 "client %s closed keepalive connection", ctx->client);
931 return NGX_DONE; 958 return NGX_DONE;
932 } 959 }
933 960
934 c->buffer->last.mem += n; 961 c->buffer->last += n;
935 ev->log->handler = ngx_http_log_error; 962 ev->log->handler = ngx_http_log_error;
936 ctx->action = "reading client request line"; 963 ctx->action = "reading client request line";
937 964
938 return ngx_http_init_request(ev); 965 return ngx_http_init_request(ev);
939 } 966 }
940 967
941 968
942 static int ngx_http_set_lingering_close(ngx_http_request_t *r) 969 static int ngx_http_set_lingering_close(ngx_http_request_t *r)
943 { 970 {
944 ngx_event_t *ev; 971 int blocked;
945 ngx_connection_t *c; 972 ngx_event_t *rev, *wev;
973 ngx_connection_t *c;
946 ngx_http_core_loc_conf_t *lcf; 974 ngx_http_core_loc_conf_t *lcf;
947 975
948 c = r->connection; 976 c = r->connection;
949 ev = r->connection->read; 977 rev = c->read;
978 wev = c->write;
950 979
951 lcf = (ngx_http_core_loc_conf_t *) 980 lcf = (ngx_http_core_loc_conf_t *)
952 ngx_http_get_module_loc_conf(r, ngx_http_core_module_ctx); 981 ngx_http_get_module_loc_conf(r, ngx_http_core_module_ctx);
953 982
954 r->lingering_time = ngx_time() + lcf->lingering_time; 983 r->lingering_time = ngx_time() + lcf->lingering_time / 1000;
955 r->connection->read->event_handler = ngx_http_lingering_close_handler; 984 r->connection->read->event_handler = ngx_http_lingering_close_handler;
956 985
957 if (ev->timer_set) { 986 if (rev->timer_set) {
958 ngx_del_timer(ev); 987 ngx_del_timer(rev);
959 } else { 988 } else {
960 ev->timer_set = 1; 989 rev->timer_set = 1;
961 } 990 }
962 991
963 ngx_add_timer(ev, lcf->lingering_timeout); 992 ngx_add_timer(rev, lcf->lingering_timeout);
964 993
965 if (ev->blocked) { 994 if (rev->blocked && (ngx_event_flags & NGX_USE_LEVEL_EVENT)) {
966 if (ngx_event_flags & NGX_HAVE_LEVEL_EVENT) { 995 if (ngx_add_event(rev, NGX_READ_EVENT, NGX_LEVEL_EVENT) == NGX_ERROR) {
967 if (ngx_add_event(ev, NGX_READ_EVENT, NGX_LEVEL_EVENT) 996 return ngx_http_close_request(r);
968 == NGX_ERROR) { 997 }
969 return ngx_http_close_request(r); 998 blocked = 1;
970 } 999 rev->blocked = 0;
971 } 1000
972 } 1001 } else {
973 1002 blocked = 0;
974 if (ngx_shutdown_socket(r->connection->fd, NGX_WRITE_SHUTDOWN) == -1) { 1003 }
975 ngx_log_error(NGX_LOG_ERR, r->connection->log, ngx_socket_errno, 1004
1005 if (wev->active && (ngx_event_flags & NGX_USE_LEVEL_EVENT)) {
1006 if (ngx_del_event(wev, NGX_WRITE_EVENT, 0) == NGX_ERROR) {
1007 return ngx_http_close_request(r);
1008 }
1009 }
1010
1011 if (ngx_shutdown_socket(c->fd, NGX_WRITE_SHUTDOWN) == -1) {
1012 ngx_log_error(NGX_LOG_CRIT, c->log, ngx_socket_errno,
976 ngx_shutdown_socket_n " failed"); 1013 ngx_shutdown_socket_n " failed");
977 return ngx_http_close_request(r); 1014 return ngx_http_close_request(r);
978 } 1015 }
979 1016
980 #if (HAVE_AIO_EVENT) /* aio, iocp */ 1017 #if (HAVE_AIO_EVENT) /* aio, iocp */
981 if (ngx_event_flags & NGX_HAVE_AIO_EVENT) { 1018
982 return ngx_http_lingering_close_handler(ev); 1019 if ((ngx_event_flags & NGX_HAVE_AIO_EVENT) || blocked) {
983 } 1020 return ngx_http_lingering_close_handler(rev);
1021 }
1022
1023 #else
1024
1025 if (blocked) {
1026 return ngx_http_lingering_close_handler(rev);
1027 }
1028
984 #endif 1029 #endif
985 1030
986 #if (HAVE_CLEAR_EVENT) /* kqueue */ || (HAVE_EDGE_EVENT) /* epoll */ 1031 return NGX_OK;
987 if (ngx_event_flags & (NGX_HAVE_CLEAR_EVENT|NGX_HAVE_EDGE_EVENT)) {
988 return NGX_OK;
989 }
990 #endif
991
992 /* select, poll, /dev/poll */
993
994 return ngx_del_event(c->write, NGX_WRITE_EVENT, 0);
995 } 1032 }
996 1033
997 1034
998 static int ngx_http_lingering_close_handler(ngx_event_t *ev) 1035 static int ngx_http_lingering_close_handler(ngx_event_t *ev)
999 { 1036 {
1019 1056
1020 lcf = (ngx_http_core_loc_conf_t *) 1057 lcf = (ngx_http_core_loc_conf_t *)
1021 ngx_http_get_module_loc_conf(r, ngx_http_core_module_ctx); 1058 ngx_http_get_module_loc_conf(r, ngx_http_core_module_ctx);
1022 1059
1023 if (r->discarded_buffer == NULL) { 1060 if (r->discarded_buffer == NULL) {
1024 if ((size_t)(r->header_in->end - r->header_in->last.mem) 1061
1062 /* TODO: r->header_in->start (if large headers are enabled)
1063 or the end of parsed header (otherwise)
1064 instead of r->header_in->last */
1065
1066 if ((size_t)(r->header_in->end - r->header_in->last)
1025 >= lcf->discarded_buffer_size) { 1067 >= lcf->discarded_buffer_size) {
1026 r->discarded_buffer = r->header_in->last.mem; 1068 r->discarded_buffer = r->header_in->last;
1027 1069
1028 } else { 1070 } else {
1029 ngx_test_null(r->discarded_buffer, 1071 ngx_test_null(r->discarded_buffer,
1030 ngx_palloc(c->pool, lcf->discarded_buffer_size), 1072 ngx_palloc(c->pool, lcf->discarded_buffer_size),
1031 ngx_http_close_request(r)); 1073 ngx_http_close_request(r));