Mercurial > hg > nginx-mail
comparison src/http/ngx_http_request.c @ 665:0b460e61bdcd default tip
Merge with nginx 1.0.0.
author | Maxim Dounin <mdounin@mdounin.ru> |
---|---|
date | Mon, 25 Apr 2011 04:22:17 +0400 |
parents | b9763778e212 |
children |
comparison
equal
deleted
inserted
replaced
572:06419a2298a9 | 665:0b460e61bdcd |
---|---|
29 static ngx_int_t ngx_http_process_cookie(ngx_http_request_t *r, | 29 static ngx_int_t ngx_http_process_cookie(ngx_http_request_t *r, |
30 ngx_table_elt_t *h, ngx_uint_t offset); | 30 ngx_table_elt_t *h, ngx_uint_t offset); |
31 | 31 |
32 static ngx_int_t ngx_http_process_request_header(ngx_http_request_t *r); | 32 static ngx_int_t ngx_http_process_request_header(ngx_http_request_t *r); |
33 static void ngx_http_process_request(ngx_http_request_t *r); | 33 static void ngx_http_process_request(ngx_http_request_t *r); |
34 static ssize_t ngx_http_validate_host(u_char *host, size_t len); | 34 static ssize_t ngx_http_validate_host(ngx_http_request_t *r, u_char **host, |
35 size_t len, ngx_uint_t alloc); | |
35 static ngx_int_t ngx_http_find_virtual_server(ngx_http_request_t *r, | 36 static ngx_int_t ngx_http_find_virtual_server(ngx_http_request_t *r, |
36 u_char *host, size_t len); | 37 u_char *host, size_t len); |
37 | 38 |
38 static void ngx_http_request_handler(ngx_event_t *ev); | 39 static void ngx_http_request_handler(ngx_event_t *ev); |
39 static void ngx_http_terminate_request(ngx_http_request_t *r, ngx_int_t rc); | 40 static void ngx_http_terminate_request(ngx_http_request_t *r, ngx_int_t rc); |
83 { ngx_string("Connection"), offsetof(ngx_http_headers_in_t, connection), | 84 { ngx_string("Connection"), offsetof(ngx_http_headers_in_t, connection), |
84 ngx_http_process_connection }, | 85 ngx_http_process_connection }, |
85 | 86 |
86 { ngx_string("If-Modified-Since"), | 87 { ngx_string("If-Modified-Since"), |
87 offsetof(ngx_http_headers_in_t, if_modified_since), | 88 offsetof(ngx_http_headers_in_t, if_modified_since), |
89 ngx_http_process_unique_header_line }, | |
90 | |
91 { ngx_string("If-Unmodified-Since"), | |
92 offsetof(ngx_http_headers_in_t, if_unmodified_since), | |
88 ngx_http_process_unique_header_line }, | 93 ngx_http_process_unique_header_line }, |
89 | 94 |
90 { ngx_string("User-Agent"), offsetof(ngx_http_headers_in_t, user_agent), | 95 { ngx_string("User-Agent"), offsetof(ngx_http_headers_in_t, user_agent), |
91 ngx_http_process_user_agent }, | 96 ngx_http_process_user_agent }, |
92 | 97 |
378 } | 383 } |
379 | 384 |
380 r->virtual_names = addr_conf->virtual_names; | 385 r->virtual_names = addr_conf->virtual_names; |
381 | 386 |
382 /* the default server configuration for the address:port */ | 387 /* the default server configuration for the address:port */ |
383 cscf = addr_conf->core_srv_conf; | 388 cscf = addr_conf->default_server; |
384 | 389 |
385 r->main_conf = cscf->ctx->main_conf; | 390 r->main_conf = cscf->ctx->main_conf; |
386 r->srv_conf = cscf->ctx->srv_conf; | 391 r->srv_conf = cscf->ctx->srv_conf; |
387 r->loc_conf = cscf->ctx->loc_conf; | 392 r->loc_conf = cscf->ctx->loc_conf; |
388 | 393 |
552 | 557 |
553 return; | 558 return; |
554 } | 559 } |
555 | 560 |
556 if (n == 1) { | 561 if (n == 1) { |
557 if (buf[0] == 0x80 /* SSLv2 */ || buf[0] == 0x16 /* SSLv3/TLSv1 */) { | 562 if (buf[0] & 0x80 /* SSLv2 */ || buf[0] == 0x16 /* SSLv3/TLSv1 */) { |
558 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, rev->log, 0, | 563 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, rev->log, 0, |
559 "https ssl handshake: 0x%02Xd", buf[0]); | 564 "https ssl handshake: 0x%02Xd", buf[0]); |
560 | 565 |
561 rc = ngx_ssl_handshake(c); | 566 rc = ngx_ssl_handshake(c); |
562 | 567 |
625 | 630 |
626 int | 631 int |
627 ngx_http_ssl_servername(ngx_ssl_conn_t *ssl_conn, int *ad, void *arg) | 632 ngx_http_ssl_servername(ngx_ssl_conn_t *ssl_conn, int *ad, void *arg) |
628 { | 633 { |
629 size_t len; | 634 size_t len; |
635 u_char *host; | |
630 const char *servername; | 636 const char *servername; |
631 ngx_connection_t *c; | 637 ngx_connection_t *c; |
632 ngx_http_request_t *r; | 638 ngx_http_request_t *r; |
633 ngx_http_ssl_srv_conf_t *sscf; | 639 ngx_http_ssl_srv_conf_t *sscf; |
634 | 640 |
649 return SSL_TLSEXT_ERR_NOACK; | 655 return SSL_TLSEXT_ERR_NOACK; |
650 } | 656 } |
651 | 657 |
652 r = c->data; | 658 r = c->data; |
653 | 659 |
654 if (ngx_http_find_virtual_server(r, (u_char *) servername, len) != NGX_OK) { | 660 host = (u_char *) servername; |
661 | |
662 len = ngx_http_validate_host(r, &host, len, 1); | |
663 | |
664 if (len <= 0) { | |
665 return SSL_TLSEXT_ERR_NOACK; | |
666 } | |
667 | |
668 if (ngx_http_find_virtual_server(r, host, len) != NGX_OK) { | |
655 return SSL_TLSEXT_ERR_NOACK; | 669 return SSL_TLSEXT_ERR_NOACK; |
656 } | 670 } |
657 | 671 |
658 sscf = ngx_http_get_module_srv_conf(r, ngx_http_ssl_module); | 672 sscf = ngx_http_get_module_srv_conf(r, ngx_http_ssl_module); |
659 | 673 |
668 | 682 |
669 | 683 |
670 static void | 684 static void |
671 ngx_http_process_request_line(ngx_event_t *rev) | 685 ngx_http_process_request_line(ngx_event_t *rev) |
672 { | 686 { |
687 u_char *host; | |
673 ssize_t n; | 688 ssize_t n; |
674 ngx_int_t rc, rv; | 689 ngx_int_t rc, rv; |
675 ngx_connection_t *c; | 690 ngx_connection_t *c; |
676 ngx_http_request_t *r; | 691 ngx_http_request_t *r; |
677 ngx_http_core_srv_conf_t *cscf; | 692 ngx_http_core_srv_conf_t *cscf; |
743 | 758 |
744 | 759 |
745 r->unparsed_uri.len = r->uri_end - r->uri_start; | 760 r->unparsed_uri.len = r->uri_end - r->uri_start; |
746 r->unparsed_uri.data = r->uri_start; | 761 r->unparsed_uri.data = r->uri_start; |
747 | 762 |
763 r->valid_unparsed_uri = r->space_in_uri ? 0 : 1; | |
748 | 764 |
749 r->method_name.len = r->method_end - r->request_start + 1; | 765 r->method_name.len = r->method_end - r->request_start + 1; |
750 r->method_name.data = r->request_line.data; | 766 r->method_name.data = r->request_line.data; |
751 | 767 |
752 | 768 |
775 { | 791 { |
776 u_char *p; | 792 u_char *p; |
777 | 793 |
778 p = r->uri.data + r->uri.len - 1; | 794 p = r->uri.data + r->uri.len - 1; |
779 | 795 |
780 if (*p == '.') { | 796 while (p > r->uri.data) { |
781 | 797 |
782 while (--p > r->uri.data && *p == '.') { /* void */ } | 798 if (*p == ' ') { |
783 | 799 p--; |
800 continue; | |
801 } | |
802 | |
803 if (*p == '.') { | |
804 p--; | |
805 continue; | |
806 } | |
807 | |
808 if (ngx_strncasecmp(p - 6, (u_char *) "::$data", 7) == 0) { | |
809 p -= 7; | |
810 continue; | |
811 } | |
812 | |
813 break; | |
814 } | |
815 | |
816 if (p != r->uri.data + r->uri.len - 1) { | |
784 r->uri.len = p + 1 - r->uri.data; | 817 r->uri.len = p + 1 - r->uri.data; |
785 | |
786 ngx_http_set_exten(r); | 818 ngx_http_set_exten(r); |
787 } | 819 } |
820 | |
788 } | 821 } |
789 #endif | 822 #endif |
790 | 823 |
791 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0, | 824 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0, |
792 "http request line: \"%V\"", &r->request_line); | 825 "http request line: \"%V\"", &r->request_line); |
799 | 832 |
800 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0, | 833 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0, |
801 "http exten: \"%V\"", &r->exten); | 834 "http exten: \"%V\"", &r->exten); |
802 | 835 |
803 if (r->host_start && r->host_end) { | 836 if (r->host_start && r->host_end) { |
804 n = ngx_http_validate_host(r->host_start, | 837 |
805 r->host_end - r->host_start); | 838 host = r->host_start; |
806 | 839 n = ngx_http_validate_host(r, &host, |
807 if (n <= 0) { | 840 r->host_end - r->host_start, 0); |
841 | |
842 if (n == 0) { | |
808 ngx_log_error(NGX_LOG_INFO, c->log, 0, | 843 ngx_log_error(NGX_LOG_INFO, c->log, 0, |
809 "client sent invalid host in request line"); | 844 "client sent invalid host in request line"); |
810 ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST); | 845 ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST); |
811 return; | 846 return; |
812 } | 847 } |
813 | 848 |
849 if (n < 0) { | |
850 ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR); | |
851 return; | |
852 } | |
853 | |
814 r->headers_in.server.len = n; | 854 r->headers_in.server.len = n; |
815 r->headers_in.server.data = r->host_start; | 855 r->headers_in.server.data = host; |
816 } | 856 } |
817 | 857 |
818 if (r->http_version < NGX_HTTP_VERSION_10) { | 858 if (r->http_version < NGX_HTTP_VERSION_10) { |
819 | 859 |
820 if (ngx_http_find_virtual_server(r, r->headers_in.server.data, | 860 if (ngx_http_find_virtual_server(r, r->headers_in.server.data, |
934 ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR); | 974 ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR); |
935 return; | 975 return; |
936 } | 976 } |
937 | 977 |
938 if (rv == NGX_DECLINED) { | 978 if (rv == NGX_DECLINED) { |
939 len = r->header_in->end - r->header_name_start; | |
940 p = r->header_name_start; | 979 p = r->header_name_start; |
980 | |
981 r->lingering_close = 1; | |
982 | |
983 if (p == NULL) { | |
984 ngx_log_error(NGX_LOG_INFO, c->log, 0, | |
985 "client sent too large request"); | |
986 ngx_http_finalize_request(r, | |
987 NGX_HTTP_REQUEST_HEADER_TOO_LARGE); | |
988 return; | |
989 } | |
990 | |
991 len = r->header_in->end - p; | |
941 | 992 |
942 if (len > NGX_MAX_ERROR_STR - 300) { | 993 if (len > NGX_MAX_ERROR_STR - 300) { |
943 len = NGX_MAX_ERROR_STR - 300; | 994 len = NGX_MAX_ERROR_STR - 300; |
944 p[len++] = '.'; p[len++] = '.'; p[len++] = '.'; | 995 p[len++] = '.'; p[len++] = '.'; p[len++] = '.'; |
945 } | 996 } |
946 | 997 |
947 ngx_log_error(NGX_LOG_INFO, c->log, 0, | 998 ngx_log_error(NGX_LOG_INFO, c->log, 0, |
948 "client sent too long header line: \"%*s\"", | 999 "client sent too long header line: \"%*s\"", |
949 len, r->header_name_start); | 1000 len, r->header_name_start); |
950 ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST); | 1001 |
1002 ngx_http_finalize_request(r, | |
1003 NGX_HTTP_REQUEST_HEADER_TOO_LARGE); | |
951 return; | 1004 return; |
952 } | 1005 } |
953 } | 1006 } |
954 | 1007 |
955 n = ngx_http_read_request_header(r); | 1008 n = ngx_http_read_request_header(r); |
1310 | 1363 |
1311 static ngx_int_t | 1364 static ngx_int_t |
1312 ngx_http_process_host(ngx_http_request_t *r, ngx_table_elt_t *h, | 1365 ngx_http_process_host(ngx_http_request_t *r, ngx_table_elt_t *h, |
1313 ngx_uint_t offset) | 1366 ngx_uint_t offset) |
1314 { | 1367 { |
1315 ssize_t len; | 1368 u_char *host; |
1369 ssize_t len; | |
1316 | 1370 |
1317 if (r->headers_in.host == NULL) { | 1371 if (r->headers_in.host == NULL) { |
1318 r->headers_in.host = h; | 1372 r->headers_in.host = h; |
1319 } | 1373 } |
1320 | 1374 |
1321 len = ngx_http_validate_host(h->value.data, h->value.len); | 1375 host = h->value.data; |
1322 | 1376 len = ngx_http_validate_host(r, &host, h->value.len, 0); |
1323 if (len <= 0) { | 1377 |
1378 if (len == 0) { | |
1324 ngx_log_error(NGX_LOG_INFO, r->connection->log, 0, | 1379 ngx_log_error(NGX_LOG_INFO, r->connection->log, 0, |
1325 "client sent invalid host header"); | 1380 "client sent invalid host header"); |
1326 ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST); | 1381 ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST); |
1327 return NGX_ERROR; | 1382 return NGX_ERROR; |
1328 } | 1383 } |
1329 | 1384 |
1385 if (len < 0) { | |
1386 ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR); | |
1387 return NGX_ERROR; | |
1388 } | |
1389 | |
1330 if (r->headers_in.server.len) { | 1390 if (r->headers_in.server.len) { |
1331 return NGX_OK; | 1391 return NGX_OK; |
1332 } | 1392 } |
1333 | 1393 |
1334 r->headers_in.server.len = len; | 1394 r->headers_in.server.len = len; |
1335 r->headers_in.server.data = h->value.data; | 1395 r->headers_in.server.data = host; |
1336 | 1396 |
1337 return NGX_OK; | 1397 return NGX_OK; |
1338 } | 1398 } |
1339 | 1399 |
1340 | 1400 |
1410 if (!r->headers_in.msie && !r->headers_in.opera) { | 1470 if (!r->headers_in.msie && !r->headers_in.opera) { |
1411 | 1471 |
1412 if (ngx_strstrn(user_agent, "Gecko/", 6 - 1)) { | 1472 if (ngx_strstrn(user_agent, "Gecko/", 6 - 1)) { |
1413 r->headers_in.gecko = 1; | 1473 r->headers_in.gecko = 1; |
1414 | 1474 |
1475 } else if (ngx_strstrn(user_agent, "Chrome/", 7 - 1)) { | |
1476 r->headers_in.chrome = 1; | |
1477 | |
1478 } else if (ngx_strstrn(user_agent, "Safari/", 7 - 1)) { | |
1479 r->headers_in.safari = 1; | |
1480 | |
1415 } else if (ngx_strstrn(user_agent, "Konqueror", 9 - 1)) { | 1481 } else if (ngx_strstrn(user_agent, "Konqueror", 9 - 1)) { |
1416 r->headers_in.konqueror = 1; | 1482 r->headers_in.konqueror = 1; |
1417 } | 1483 } |
1418 } | 1484 } |
1419 | 1485 |
1586 ngx_http_run_posted_requests(c); | 1652 ngx_http_run_posted_requests(c); |
1587 } | 1653 } |
1588 | 1654 |
1589 | 1655 |
1590 static ssize_t | 1656 static ssize_t |
1591 ngx_http_validate_host(u_char *host, size_t len) | 1657 ngx_http_validate_host(ngx_http_request_t *r, u_char **host, size_t len, |
1592 { | 1658 ngx_uint_t alloc) |
1593 u_char ch; | 1659 { |
1594 size_t i, last; | 1660 u_char *h, ch; |
1595 ngx_uint_t dot; | 1661 size_t i, last; |
1662 ngx_uint_t dot; | |
1596 | 1663 |
1597 last = len; | 1664 last = len; |
1665 h = *host; | |
1598 dot = 0; | 1666 dot = 0; |
1599 | 1667 |
1600 for (i = 0; i < len; i++) { | 1668 for (i = 0; i < len; i++) { |
1601 ch = host[i]; | 1669 ch = h[i]; |
1602 | 1670 |
1603 if (ch == '.') { | 1671 if (ch == '.') { |
1604 if (dot) { | 1672 if (dot) { |
1605 return -1; | 1673 return 0; |
1606 } | 1674 } |
1607 | 1675 |
1608 dot = 1; | 1676 dot = 1; |
1609 continue; | 1677 continue; |
1610 } | 1678 } |
1615 last = i; | 1683 last = i; |
1616 continue; | 1684 continue; |
1617 } | 1685 } |
1618 | 1686 |
1619 if (ngx_path_separator(ch) || ch == '\0') { | 1687 if (ngx_path_separator(ch) || ch == '\0') { |
1620 return -1; | 1688 return 0; |
1689 } | |
1690 | |
1691 if (ch >= 'A' || ch < 'Z') { | |
1692 alloc = 1; | |
1621 } | 1693 } |
1622 } | 1694 } |
1623 | 1695 |
1624 if (dot) { | 1696 if (dot) { |
1625 last--; | 1697 last--; |
1626 } | 1698 } |
1627 | 1699 |
1700 if (alloc) { | |
1701 *host = ngx_pnalloc(r->pool, last) ; | |
1702 if (*host == NULL) { | |
1703 return -1; | |
1704 } | |
1705 | |
1706 ngx_strlow(*host, h, last); | |
1707 } | |
1708 | |
1628 return last; | 1709 return last; |
1629 } | 1710 } |
1630 | 1711 |
1631 | 1712 |
1632 static ngx_int_t | 1713 static ngx_int_t |
1633 ngx_http_find_virtual_server(ngx_http_request_t *r, u_char *host, size_t len) | 1714 ngx_http_find_virtual_server(ngx_http_request_t *r, u_char *host, size_t len) |
1634 { | 1715 { |
1635 u_char *server; | |
1636 ngx_uint_t hash; | |
1637 ngx_http_core_loc_conf_t *clcf; | 1716 ngx_http_core_loc_conf_t *clcf; |
1638 ngx_http_core_srv_conf_t *cscf; | 1717 ngx_http_core_srv_conf_t *cscf; |
1639 u_char buf[32]; | |
1640 | 1718 |
1641 if (r->virtual_names == NULL) { | 1719 if (r->virtual_names == NULL) { |
1642 return NGX_DECLINED; | 1720 return NGX_DECLINED; |
1643 } | 1721 } |
1644 | 1722 |
1645 if (len <= 32) { | 1723 cscf = ngx_hash_find_combined(&r->virtual_names->names, |
1646 server = buf; | 1724 ngx_hash_key(host, len), host, len); |
1647 | |
1648 } else { | |
1649 server = ngx_pnalloc(r->pool, len); | |
1650 if (server == NULL) { | |
1651 return NGX_ERROR; | |
1652 } | |
1653 } | |
1654 | |
1655 hash = ngx_hash_strlow(server, host, len); | |
1656 | |
1657 cscf = ngx_hash_find_combined(&r->virtual_names->names, hash, server, len); | |
1658 | 1725 |
1659 if (cscf) { | 1726 if (cscf) { |
1660 goto found; | 1727 goto found; |
1661 } | 1728 } |
1662 | 1729 |
1663 #if (NGX_PCRE) | 1730 #if (NGX_PCRE) |
1664 | 1731 |
1665 if (r->virtual_names->nregex) { | 1732 if (len && r->virtual_names->nregex) { |
1666 size_t ncaptures; | |
1667 ngx_int_t n; | 1733 ngx_int_t n; |
1668 ngx_uint_t i; | 1734 ngx_uint_t i; |
1669 ngx_str_t name; | 1735 ngx_str_t name; |
1670 ngx_http_server_name_t *sn; | 1736 ngx_http_server_name_t *sn; |
1671 | 1737 |
1672 name.len = len; | 1738 name.len = len; |
1673 name.data = server; | 1739 name.data = host; |
1674 | |
1675 ncaptures = 0; | |
1676 | 1740 |
1677 sn = r->virtual_names->regex; | 1741 sn = r->virtual_names->regex; |
1678 | 1742 |
1679 for (i = 0; i < r->virtual_names->nregex; i++) { | 1743 for (i = 0; i < r->virtual_names->nregex; i++) { |
1680 | 1744 |
1681 if (sn[i].captures && r->captures == NULL) { | 1745 n = ngx_http_regex_exec(r, sn[i].regex, &name); |
1682 | 1746 |
1683 ncaptures = (NGX_HTTP_MAX_CAPTURES + 1) * 3; | 1747 if (n == NGX_OK) { |
1684 | 1748 cscf = sn[i].server; |
1685 r->captures = ngx_palloc(r->pool, ncaptures * sizeof(int)); | 1749 goto found; |
1686 if (r->captures == NULL) { | 1750 } |
1687 return NGX_ERROR; | 1751 |
1688 } | 1752 if (n == NGX_DECLINED) { |
1689 | |
1690 if (server == buf) { | |
1691 server = ngx_pnalloc(r->pool, len); | |
1692 if (server == NULL) { | |
1693 return NGX_ERROR; | |
1694 } | |
1695 | |
1696 ngx_memcpy(server, buf, len); | |
1697 name.data = server; | |
1698 } | |
1699 } | |
1700 | |
1701 n = ngx_regex_exec(sn[i].regex, &name, r->captures, ncaptures); | |
1702 | |
1703 if (n == NGX_REGEX_NO_MATCHED) { | |
1704 continue; | 1753 continue; |
1705 } | 1754 } |
1706 | 1755 |
1707 if (n < 0) { | 1756 return NGX_ERROR; |
1708 ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0, | |
1709 ngx_regex_exec_n | |
1710 " failed: %d on \"%V\" using \"%V\"", | |
1711 n, &name, &sn[i].name); | |
1712 return NGX_ERROR; | |
1713 } | |
1714 | |
1715 /* match */ | |
1716 | |
1717 cscf = sn[i].core_srv_conf; | |
1718 | |
1719 r->ncaptures = ncaptures; | |
1720 r->captures_data = server; | |
1721 | |
1722 goto found; | |
1723 } | 1757 } |
1724 } | 1758 } |
1725 | 1759 |
1726 #endif | 1760 #endif |
1727 | 1761 |
1991 &r->uri, &r->args); | 2025 &r->uri, &r->args); |
1992 return; | 2026 return; |
1993 } | 2027 } |
1994 | 2028 |
1995 r->done = 1; | 2029 r->done = 1; |
2030 r->write_event_handler = ngx_http_request_empty_handler; | |
1996 | 2031 |
1997 if (!r->post_action) { | 2032 if (!r->post_action) { |
1998 r->request_complete = 1; | 2033 r->request_complete = 1; |
1999 } | 2034 } |
2000 | 2035 |
2029 | 2064 |
2030 mr = r->main; | 2065 mr = r->main; |
2031 | 2066 |
2032 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, | 2067 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, |
2033 "http terminate request count:%d", mr->count); | 2068 "http terminate request count:%d", mr->count); |
2069 | |
2070 if (rc > 0 && (mr->headers_out.status == 0 || mr->connection->sent == 0)) { | |
2071 mr->headers_out.status = rc; | |
2072 } | |
2034 | 2073 |
2035 cln = mr->cleanup; | 2074 cln = mr->cleanup; |
2036 mr->cleanup = NULL; | 2075 mr->cleanup = NULL; |
2037 | 2076 |
2038 while (cln) { | 2077 while (cln) { |
2079 static void | 2118 static void |
2080 ngx_http_finalize_connection(ngx_http_request_t *r) | 2119 ngx_http_finalize_connection(ngx_http_request_t *r) |
2081 { | 2120 { |
2082 ngx_http_core_loc_conf_t *clcf; | 2121 ngx_http_core_loc_conf_t *clcf; |
2083 | 2122 |
2123 clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); | |
2124 | |
2084 if (r->main->count != 1) { | 2125 if (r->main->count != 1) { |
2126 | |
2127 if (r->discard_body) { | |
2128 r->read_event_handler = ngx_http_discarded_request_body_handler; | |
2129 | |
2130 if (r->lingering_time == 0) { | |
2131 r->lingering_time = ngx_time() | |
2132 + (time_t) (clcf->lingering_time / 1000); | |
2133 ngx_add_timer(r->connection->read, clcf->lingering_timeout); | |
2134 } | |
2135 } | |
2136 | |
2085 ngx_http_close_request(r, 0); | 2137 ngx_http_close_request(r, 0); |
2086 return; | 2138 return; |
2087 } | 2139 } |
2088 | |
2089 clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); | |
2090 | 2140 |
2091 if (!ngx_terminate | 2141 if (!ngx_terminate |
2092 && !ngx_exiting | 2142 && !ngx_exiting |
2093 && r->keepalive | 2143 && r->keepalive |
2094 && clcf->keepalive_timeout > 0) | 2144 && clcf->keepalive_timeout > 0) |
2111 ngx_event_t *wev; | 2161 ngx_event_t *wev; |
2112 ngx_http_core_loc_conf_t *clcf; | 2162 ngx_http_core_loc_conf_t *clcf; |
2113 | 2163 |
2114 r->http_state = NGX_HTTP_WRITING_REQUEST_STATE; | 2164 r->http_state = NGX_HTTP_WRITING_REQUEST_STATE; |
2115 | 2165 |
2116 r->read_event_handler = ngx_http_test_reading; | 2166 r->read_event_handler = r->discard_body ? |
2167 ngx_http_discarded_request_body_handler: | |
2168 ngx_http_test_reading; | |
2117 r->write_event_handler = ngx_http_writer; | 2169 r->write_event_handler = ngx_http_writer; |
2118 | 2170 |
2119 wev = r->connection->write; | 2171 wev = r->connection->write; |
2120 | 2172 |
2121 if (wev->ready && wev->delayed) { | 2173 if (wev->ready && wev->delayed) { |
2212 return; | 2264 return; |
2213 } | 2265 } |
2214 | 2266 |
2215 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, wev->log, 0, | 2267 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, wev->log, 0, |
2216 "http writer done: \"%V?%V\"", &r->uri, &r->args); | 2268 "http writer done: \"%V?%V\"", &r->uri, &r->args); |
2269 | |
2270 r->write_event_handler = ngx_http_request_empty_handler; | |
2217 | 2271 |
2218 ngx_http_finalize_request(r, rc); | 2272 ngx_http_finalize_request(r, rc); |
2219 } | 2273 } |
2220 | 2274 |
2221 | 2275 |
2389 hc->busy[0] = b; | 2443 hc->busy[0] = b; |
2390 hc->nbusy = 1; | 2444 hc->nbusy = 1; |
2391 } | 2445 } |
2392 } | 2446 } |
2393 | 2447 |
2448 r->keepalive = 0; | |
2449 | |
2394 ngx_http_free_request(r, 0); | 2450 ngx_http_free_request(r, 0); |
2395 | 2451 |
2396 c->data = hc; | 2452 c->data = hc; |
2397 | 2453 |
2398 ngx_add_timer(rev, clcf->keepalive_timeout); | 2454 ngx_add_timer(rev, clcf->keepalive_timeout); |
2536 /* if ngx_http_request_t was freed then we need some other place */ | 2592 /* if ngx_http_request_t was freed then we need some other place */ |
2537 r->http_state = NGX_HTTP_KEEPALIVE_STATE; | 2593 r->http_state = NGX_HTTP_KEEPALIVE_STATE; |
2538 #endif | 2594 #endif |
2539 | 2595 |
2540 c->idle = 1; | 2596 c->idle = 1; |
2597 ngx_reusable_connection(c, 1); | |
2541 | 2598 |
2542 if (rev->ready) { | 2599 if (rev->ready) { |
2543 ngx_post_event(rev, &ngx_posted_events); | 2600 ngx_post_event(rev, &ngx_posted_events); |
2544 } | 2601 } |
2545 } | 2602 } |
2645 | 2702 |
2646 c->log->handler = ngx_http_log_error; | 2703 c->log->handler = ngx_http_log_error; |
2647 c->log->action = "reading client request line"; | 2704 c->log->action = "reading client request line"; |
2648 | 2705 |
2649 c->idle = 0; | 2706 c->idle = 0; |
2707 ngx_reusable_connection(c, 0); | |
2650 | 2708 |
2651 ngx_http_init_request(rev); | 2709 ngx_http_init_request(rev); |
2652 } | 2710 } |
2653 | 2711 |
2654 | 2712 |