Mercurial > hg > nginx
comparison src/http/ngx_http_request.c @ 160:e7e094d34162
nginx-0.0.1-2003-10-27-11:53:49 import
author | Igor Sysoev <igor@sysoev.ru> |
---|---|
date | Mon, 27 Oct 2003 08:53:49 +0000 |
parents | 981e4af2a425 |
children | 88abd07d9f62 |
comparison
equal
deleted
inserted
replaced
159:981e4af2a425 | 160:e7e094d34162 |
---|---|
21 static void ngx_http_keepalive_handler(ngx_event_t *ev); | 21 static void ngx_http_keepalive_handler(ngx_event_t *ev); |
22 static void ngx_http_set_lingering_close(ngx_http_request_t *r); | 22 static void ngx_http_set_lingering_close(ngx_http_request_t *r); |
23 static void ngx_http_lingering_close_handler(ngx_event_t *ev); | 23 static void ngx_http_lingering_close_handler(ngx_event_t *ev); |
24 static void ngx_http_empty_handler(ngx_event_t *wev); | 24 static void ngx_http_empty_handler(ngx_event_t *wev); |
25 | 25 |
26 static void ngx_http_header_parse_error(ngx_http_request_t *r, | 26 static void ngx_http_client_error(ngx_http_request_t *r, |
27 int parse_err, int error); | 27 int client_error, int error); |
28 static size_t ngx_http_log_error(void *data, char *buf, size_t len); | 28 static size_t ngx_http_log_error(void *data, char *buf, size_t len); |
29 | 29 |
30 | 30 |
31 /* NGX_HTTP_PARSE_ ... errors */ | 31 /* NGX_HTTP_PARSE_... errors */ |
32 | 32 |
33 static char *header_errors[] = { | 33 static char *client_header_errors[] = { |
34 "client %s sent invalid method", | 34 "client %s sent invalid method", |
35 "client %s sent invalid request", | 35 "client %s sent invalid request", |
36 "client %s sent too long URI", | 36 "client %s sent too long URI", |
37 "client %s sent invalid method in HTTP/0.9 request", | 37 "client %s sent invalid method in HTTP/0.9 request", |
38 | 38 |
64 | 64 |
65 { ngx_null_string, 0 } | 65 { ngx_null_string, 0 } |
66 }; | 66 }; |
67 | 67 |
68 | 68 |
69 static void ngx_http_dummy(ngx_event_t *wev) | |
70 { | |
71 return; | |
72 } | |
73 | |
74 | |
69 void ngx_http_init_connection(ngx_connection_t *c) | 75 void ngx_http_init_connection(ngx_connection_t *c) |
70 { | 76 { |
71 ngx_event_t *rev; | 77 ngx_event_t *rev; |
72 ngx_http_log_ctx_t *lctx; | 78 ngx_http_log_ctx_t *lctx; |
73 | 79 |
115 | 121 |
116 if (ngx_handle_read_event(rev) == NGX_ERROR) { | 122 if (ngx_handle_read_event(rev) == NGX_ERROR) { |
117 ngx_http_close_connection(c); | 123 ngx_http_close_connection(c); |
118 return; | 124 return; |
119 } | 125 } |
126 | |
127 #if 0 | |
128 c->write->ready = 0; | |
129 c->write->event_handler = ngx_http_dummy; | |
130 | |
131 if (ngx_handle_write_event(c->write, 0) == NGX_ERROR) { | |
132 ngx_http_close_connection(c); | |
133 return; | |
134 } | |
135 #endif | |
120 } | 136 } |
121 | 137 |
122 | 138 |
123 static void ngx_http_init_request(ngx_event_t *rev) | 139 static void ngx_http_init_request(ngx_event_t *rev) |
124 { | 140 { |
133 ngx_http_core_srv_conf_t *cscf; | 149 ngx_http_core_srv_conf_t *cscf; |
134 ngx_http_core_loc_conf_t *clcf; | 150 ngx_http_core_loc_conf_t *clcf; |
135 | 151 |
136 c = rev->data; | 152 c = rev->data; |
137 | 153 |
154 if (rev->timedout) { | |
155 ngx_log_error(NGX_LOG_INFO, c->log, NGX_ETIMEDOUT, "client timed out"); | |
156 ngx_http_close_connection(c); | |
157 return; | |
158 } | |
159 | |
138 if (c->data) { | 160 if (c->data) { |
139 r = c->data; | 161 r = c->data; |
140 ngx_memzero(r, sizeof(ngx_http_request_t)); | 162 ngx_memzero(r, sizeof(ngx_http_request_t)); |
141 | 163 |
142 } else { | 164 } else { |
279 r = c->data; | 301 r = c->data; |
280 | 302 |
281 ngx_log_debug(rev->log, "http process request line"); | 303 ngx_log_debug(rev->log, "http process request line"); |
282 | 304 |
283 if (rev->timedout) { | 305 if (rev->timedout) { |
284 ngx_http_close_request(r, NGX_HTTP_REQUEST_TIME_OUT); | 306 ngx_http_client_error(r, 0, NGX_HTTP_REQUEST_TIME_OUT); |
285 ngx_http_close_connection(c); | |
286 return; | 307 return; |
287 } | 308 } |
288 | 309 |
289 n = ngx_http_read_request_header(r); | 310 n = ngx_http_read_request_header(r); |
290 | 311 |
302 if (r->complex_uri || r->unusual_uri) { | 323 if (r->complex_uri || r->unusual_uri) { |
303 r->request_line.len = r->request_end - r->request_start; | 324 r->request_line.len = r->request_end - r->request_start; |
304 r->request_line.data = r->request_start; | 325 r->request_line.data = r->request_start; |
305 r->request_line.data[r->request_line.len] = '\0'; | 326 r->request_line.data[r->request_line.len] = '\0'; |
306 | 327 |
307 ngx_http_header_parse_error(r, NGX_HTTP_PARSE_INVALID_REQUEST, | 328 ngx_http_client_error(r, NGX_HTTP_PARSE_INVALID_REQUEST, |
308 NGX_HTTP_BAD_REQUEST); | 329 NGX_HTTP_BAD_REQUEST); |
309 return; | 330 return; |
310 } | 331 } |
311 | 332 |
312 cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module); | 333 cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module); |
313 | 334 |
315 && cscf->large_client_header == 0 | 336 && cscf->large_client_header == 0 |
316 && r->header_in->pos == r->header_in->end) | 337 && r->header_in->pos == r->header_in->end) |
317 { | 338 { |
318 /* no space for "\r\n" at the end of the header */ | 339 /* no space for "\r\n" at the end of the header */ |
319 | 340 |
320 ngx_http_header_parse_error(r, NGX_HTTP_PARSE_TOO_LONG_URI, | 341 ngx_http_client_error(r, NGX_HTTP_PARSE_TOO_LONG_URI, |
321 NGX_HTTP_REQUEST_URI_TOO_LARGE); | 342 NGX_HTTP_REQUEST_URI_TOO_LARGE); |
322 return; | 343 return; |
323 } | 344 } |
324 | 345 |
325 | 346 |
326 /* copy URI */ | 347 /* copy URI */ |
445 | 466 |
446 } else if (rc != NGX_AGAIN) { | 467 } else if (rc != NGX_AGAIN) { |
447 | 468 |
448 /* there was error while a request line parsing */ | 469 /* there was error while a request line parsing */ |
449 | 470 |
450 ngx_http_header_parse_error(r, rc, NGX_HTTP_BAD_REQUEST); | 471 ngx_http_client_error(r, rc, NGX_HTTP_BAD_REQUEST); |
451 | 472 |
452 return; | 473 return; |
453 } | 474 } |
454 | 475 |
455 /* NGX_AGAIN: a request line parsing is still not complete */ | 476 /* NGX_AGAIN: a request line parsing is still not complete */ |
468 | 489 |
469 if (cscf->large_client_header) { | 490 if (cscf->large_client_header) { |
470 offset = r->request_start - r->header_in->start; | 491 offset = r->request_start - r->header_in->start; |
471 | 492 |
472 if (offset == 0) { | 493 if (offset == 0) { |
473 ngx_http_header_parse_error(r, NGX_HTTP_PARSE_TOO_LONG_URI, | 494 ngx_http_client_error(r, NGX_HTTP_PARSE_TOO_LONG_URI, |
474 NGX_HTTP_REQUEST_URI_TOO_LARGE); | 495 NGX_HTTP_REQUEST_URI_TOO_LARGE); |
475 return; | 496 return; |
476 } | 497 } |
477 | 498 |
478 ngx_memcpy(r->header_in->start, r->request_start, | 499 ngx_memcpy(r->header_in->start, r->request_start, |
479 r->header_in->last - r->request_start); | 500 r->header_in->last - r->request_start); |
490 if (r->args_start) { | 511 if (r->args_start) { |
491 r->args_start -= offset; | 512 r->args_start -= offset; |
492 } | 513 } |
493 | 514 |
494 } else { | 515 } else { |
495 ngx_http_header_parse_error(r, NGX_HTTP_PARSE_TOO_LONG_URI, | 516 ngx_http_client_error(r, NGX_HTTP_PARSE_TOO_LONG_URI, |
496 NGX_HTTP_REQUEST_URI_TOO_LARGE); | 517 NGX_HTTP_REQUEST_URI_TOO_LARGE); |
497 } | 518 } |
498 } | 519 } |
499 | 520 |
500 return; | 521 return; |
501 } | 522 } |
514 r = c->data; | 535 r = c->data; |
515 | 536 |
516 ngx_log_debug(rev->log, "http process request header line"); | 537 ngx_log_debug(rev->log, "http process request header line"); |
517 | 538 |
518 if (rev->timedout) { | 539 if (rev->timedout) { |
519 ngx_http_close_request(r, NGX_HTTP_REQUEST_TIME_OUT); | 540 ngx_http_client_error(r, 0, NGX_HTTP_REQUEST_TIME_OUT); |
520 ngx_http_close_connection(c); | |
521 return; | 541 return; |
522 } | 542 } |
523 | 543 |
524 cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module); | 544 cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module); |
525 | 545 |
603 ngx_log_debug(r->connection->log, "HTTP header done"); | 623 ngx_log_debug(r->connection->log, "HTTP header done"); |
604 | 624 |
605 rc = ngx_http_process_request_header(r); | 625 rc = ngx_http_process_request_header(r); |
606 | 626 |
607 if (rc != NGX_OK) { | 627 if (rc != NGX_OK) { |
608 ngx_http_header_parse_error(r, rc, NGX_HTTP_BAD_REQUEST); | 628 ngx_http_client_error(r, rc, NGX_HTTP_BAD_REQUEST); |
609 return; | 629 return; |
610 } | 630 } |
611 | 631 |
612 if (r->header_timeout_set) { | 632 if (r->header_timeout_set) { |
613 ngx_del_timer(rev); | 633 ngx_del_timer(rev); |
619 | 639 |
620 } else if (rc != NGX_AGAIN) { | 640 } else if (rc != NGX_AGAIN) { |
621 | 641 |
622 /* there was error while a header line parsing */ | 642 /* there was error while a header line parsing */ |
623 | 643 |
624 ngx_http_header_parse_error(r, rc, NGX_HTTP_BAD_REQUEST); | 644 ngx_http_client_error(r, rc, NGX_HTTP_BAD_REQUEST); |
625 return; | 645 return; |
626 } | 646 } |
627 | 647 |
628 /* NGX_AGAIN: a header line parsing is still not complete */ | 648 /* NGX_AGAIN: a header line parsing is still not complete */ |
629 | 649 |
634 | 654 |
635 if (cscf->large_client_header) { | 655 if (cscf->large_client_header) { |
636 offset = r->header_name_start - r->header_in->start; | 656 offset = r->header_name_start - r->header_in->start; |
637 | 657 |
638 if (offset == 0) { | 658 if (offset == 0) { |
639 ngx_http_header_parse_error(r, | 659 ngx_http_client_error(r, NGX_HTTP_PARSE_TOO_LONG_HEADER, |
640 NGX_HTTP_PARSE_TOO_LONG_HEADER, | 660 NGX_HTTP_BAD_REQUEST); |
641 NGX_HTTP_BAD_REQUEST); | |
642 return; | 661 return; |
643 } | 662 } |
644 | 663 |
645 ngx_memcpy(r->header_in->start, r->header_name_start, | 664 ngx_memcpy(r->header_in->start, r->header_name_start, |
646 r->header_in->last - r->header_name_start); | 665 r->header_in->last - r->header_name_start); |
651 r->header_name_end -= offset; | 670 r->header_name_end -= offset; |
652 r->header_start -= offset; | 671 r->header_start -= offset; |
653 r->header_end -= offset; | 672 r->header_end -= offset; |
654 | 673 |
655 } else { | 674 } else { |
656 ngx_http_header_parse_error(r, NGX_HTTP_PARSE_TOO_LONG_HEADER, | 675 ngx_http_client_error(r, NGX_HTTP_PARSE_TOO_LONG_HEADER, |
657 NGX_HTTP_BAD_REQUEST); | 676 NGX_HTTP_BAD_REQUEST); |
658 return; | 677 return; |
659 } | 678 } |
660 } | 679 } |
661 } | 680 } |
662 } | 681 } |
796 } | 815 } |
797 | 816 |
798 | 817 |
799 void ngx_http_finalize_request(ngx_http_request_t *r, int rc) | 818 void ngx_http_finalize_request(ngx_http_request_t *r, int rc) |
800 { | 819 { |
820 /* r can be already destroyed when rc == NGX_DONE */ | |
821 | |
822 if (rc == NGX_DONE || r->main) { | |
823 return; | |
824 } | |
825 | |
801 ngx_log_debug(r->connection->log, "finalize http request"); | 826 ngx_log_debug(r->connection->log, "finalize http request"); |
802 | |
803 if (rc == NGX_DONE || r->main || r->closed) { | |
804 return; | |
805 } | |
806 | 827 |
807 if (rc >= NGX_HTTP_SPECIAL_RESPONSE) { | 828 if (rc >= NGX_HTTP_SPECIAL_RESPONSE) { |
808 | 829 |
809 if (r->connection->read->timer_set) { | 830 if (r->connection->read->timer_set) { |
810 ngx_del_timer(r->connection->read); | 831 ngx_del_timer(r->connection->read); |
883 ngx_http_request_t *r; | 904 ngx_http_request_t *r; |
884 ngx_http_core_loc_conf_t *clcf; | 905 ngx_http_core_loc_conf_t *clcf; |
885 | 906 |
886 c = wev->data; | 907 c = wev->data; |
887 r = c->data; | 908 r = c->data; |
909 | |
910 #if 0 /* TODO: THINK */ | |
911 if (wev->delayed) { | |
912 return; | |
913 } | |
914 #endif | |
915 | |
916 if (wev->timedout) { | |
917 ngx_http_client_error(r, 0, NGX_HTTP_REQUEST_TIME_OUT); | |
918 return; | |
919 } | |
888 | 920 |
889 rc = ngx_http_output_filter(r, NULL); | 921 rc = ngx_http_output_filter(r, NULL); |
890 | 922 |
891 ngx_log_debug(c->log, "writer output filter: %d" _ rc); | 923 ngx_log_debug(c->log, "writer output filter: %d" _ rc); |
892 | 924 |
1354 ctx = r->connection->log->data; | 1386 ctx = r->connection->log->data; |
1355 ctx->url = NULL; | 1387 ctx->url = NULL; |
1356 | 1388 |
1357 ngx_destroy_pool(r->pool); | 1389 ngx_destroy_pool(r->pool); |
1358 | 1390 |
1359 r->closed = 1; | |
1360 | |
1361 return; | 1391 return; |
1362 } | 1392 } |
1363 | 1393 |
1364 | 1394 |
1365 void ngx_http_close_connection(ngx_connection_t *c) | 1395 void ngx_http_close_connection(ngx_connection_t *c) |
1403 | 1433 |
1404 return; | 1434 return; |
1405 } | 1435 } |
1406 | 1436 |
1407 | 1437 |
1408 static void ngx_http_header_parse_error(ngx_http_request_t *r, | 1438 static void ngx_http_client_error(ngx_http_request_t *r, |
1409 int parse_err, int error) | 1439 int client_error, int error) |
1410 { | 1440 { |
1411 ngx_http_log_ctx_t *ctx; | 1441 ngx_http_log_ctx_t *ctx; |
1412 | 1442 |
1413 ctx = r->connection->log->data; | 1443 ctx = r->connection->log->data; |
1444 | |
1445 if (error == NGX_HTTP_REQUEST_TIME_OUT) { | |
1446 ngx_log_error(NGX_LOG_INFO, r->connection->log, NGX_ETIMEDOUT, | |
1447 "client timed out"); | |
1448 ngx_http_close_request(r, error); | |
1449 ngx_http_close_connection(r->connection); | |
1450 return; | |
1451 } | |
1452 | |
1414 r->connection->log->handler = NULL; | 1453 r->connection->log->handler = NULL; |
1415 | 1454 |
1416 if (ctx->url) { | 1455 if (ctx->url) { |
1417 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, | 1456 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, |
1418 header_errors[parse_err - NGX_HTTP_PARSE_INVALID_METHOD], | 1457 client_header_errors[client_error - NGX_HTTP_CLIENT_ERROR], |
1419 ctx->client, ctx->url); | 1458 ctx->client, ctx->url); |
1420 | 1459 |
1421 } else { | 1460 } else { |
1422 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, | 1461 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, |
1423 header_errors[parse_err - NGX_HTTP_PARSE_INVALID_METHOD], | 1462 client_header_errors[client_error - NGX_HTTP_CLIENT_ERROR], |
1424 ctx->client); | 1463 ctx->client); |
1425 } | 1464 } |
1426 | 1465 |
1427 r->connection->log->handler = ngx_http_log_error; | 1466 r->connection->log->handler = ngx_http_log_error; |
1428 | 1467 |
1429 ngx_http_finalize_request(r, error); | 1468 ngx_http_finalize_request(r, error); |