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