Mercurial > hg > nginx
comparison src/http/ngx_http_request.c @ 3427:612436ad775a stable-0.7
merge r3153, r3154, r3288, r3382:
request header processing fixes:
*) $host is always in low case:
*) move low case convertation from ngx_http_find_virtual_server()
to ngx_http_validate_host()
*) add in ngx_http_validate_host() capability to copy host name in the pool
allocated memory
*) fix segfault if there is single large_client_header_buffers
and a request line fills it completely
*) default large_client_header_buffers' buffer size should be 8K as compatible
with Apache's one
author | Igor Sysoev <igor@sysoev.ru> |
---|---|
date | Mon, 01 Feb 2010 14:16:45 +0000 |
parents | 616ff375a68f |
children | d65ba5392f59 |
comparison
equal
deleted
inserted
replaced
3426:eef19bd3c51e | 3427:612436ad775a |
---|---|
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 ngx_int_t ngx_http_set_write_handler(ngx_http_request_t *r); | 40 static ngx_int_t ngx_http_set_write_handler(ngx_http_request_t *r); |
621 | 622 |
622 int | 623 int |
623 ngx_http_ssl_servername(ngx_ssl_conn_t *ssl_conn, int *ad, void *arg) | 624 ngx_http_ssl_servername(ngx_ssl_conn_t *ssl_conn, int *ad, void *arg) |
624 { | 625 { |
625 size_t len; | 626 size_t len; |
627 u_char *host; | |
626 const char *servername; | 628 const char *servername; |
627 ngx_connection_t *c; | 629 ngx_connection_t *c; |
628 ngx_http_request_t *r; | 630 ngx_http_request_t *r; |
629 ngx_http_ssl_srv_conf_t *sscf; | 631 ngx_http_ssl_srv_conf_t *sscf; |
630 | 632 |
645 return SSL_TLSEXT_ERR_NOACK; | 647 return SSL_TLSEXT_ERR_NOACK; |
646 } | 648 } |
647 | 649 |
648 r = c->data; | 650 r = c->data; |
649 | 651 |
650 if (ngx_http_find_virtual_server(r, (u_char *) servername, len) != NGX_OK) { | 652 host = (u_char *) servername; |
653 | |
654 len = ngx_http_validate_host(r, &host, len, 1); | |
655 | |
656 if (len <= 0) { | |
657 return SSL_TLSEXT_ERR_NOACK; | |
658 } | |
659 | |
660 if (ngx_http_find_virtual_server(r, host, len) != NGX_OK) { | |
651 return SSL_TLSEXT_ERR_NOACK; | 661 return SSL_TLSEXT_ERR_NOACK; |
652 } | 662 } |
653 | 663 |
654 sscf = ngx_http_get_module_srv_conf(r, ngx_http_ssl_module); | 664 sscf = ngx_http_get_module_srv_conf(r, ngx_http_ssl_module); |
655 | 665 |
664 | 674 |
665 | 675 |
666 static void | 676 static void |
667 ngx_http_process_request_line(ngx_event_t *rev) | 677 ngx_http_process_request_line(ngx_event_t *rev) |
668 { | 678 { |
679 u_char *host; | |
669 ssize_t n; | 680 ssize_t n; |
670 ngx_int_t rc, rv; | 681 ngx_int_t rc, rv; |
671 ngx_connection_t *c; | 682 ngx_connection_t *c; |
672 ngx_http_request_t *r; | 683 ngx_http_request_t *r; |
673 ngx_http_core_srv_conf_t *cscf; | 684 ngx_http_core_srv_conf_t *cscf; |
795 | 806 |
796 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0, | 807 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0, |
797 "http exten: \"%V\"", &r->exten); | 808 "http exten: \"%V\"", &r->exten); |
798 | 809 |
799 if (r->host_start && r->host_end) { | 810 if (r->host_start && r->host_end) { |
800 n = ngx_http_validate_host(r->host_start, | 811 |
801 r->host_end - r->host_start); | 812 host = r->host_start; |
802 | 813 n = ngx_http_validate_host(r, &host, |
803 if (n <= 0) { | 814 r->host_end - r->host_start, 0); |
815 | |
816 if (n == 0) { | |
804 ngx_log_error(NGX_LOG_INFO, c->log, 0, | 817 ngx_log_error(NGX_LOG_INFO, c->log, 0, |
805 "client sent invalid host in request line"); | 818 "client sent invalid host in request line"); |
806 ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST); | 819 ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST); |
807 return; | 820 return; |
808 } | 821 } |
809 | 822 |
823 if (n < 0) { | |
824 ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR); | |
825 return; | |
826 } | |
827 | |
810 r->headers_in.server.len = n; | 828 r->headers_in.server.len = n; |
811 r->headers_in.server.data = r->host_start; | 829 r->headers_in.server.data = host; |
812 } | 830 } |
813 | 831 |
814 if (r->http_version < NGX_HTTP_VERSION_10) { | 832 if (r->http_version < NGX_HTTP_VERSION_10) { |
815 | 833 |
816 if (ngx_http_find_virtual_server(r, r->headers_in.server.data, | 834 if (ngx_http_find_virtual_server(r, r->headers_in.server.data, |
930 ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR); | 948 ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR); |
931 return; | 949 return; |
932 } | 950 } |
933 | 951 |
934 if (rv == NGX_DECLINED) { | 952 if (rv == NGX_DECLINED) { |
935 len = r->header_in->end - r->header_name_start; | |
936 p = r->header_name_start; | 953 p = r->header_name_start; |
954 | |
955 if (p == NULL) { | |
956 ngx_log_error(NGX_LOG_INFO, c->log, 0, | |
957 "client sent too large request"); | |
958 ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST); | |
959 return; | |
960 } | |
961 | |
962 len = r->header_in->end - p; | |
937 | 963 |
938 if (len > NGX_MAX_ERROR_STR - 300) { | 964 if (len > NGX_MAX_ERROR_STR - 300) { |
939 len = NGX_MAX_ERROR_STR - 300; | 965 len = NGX_MAX_ERROR_STR - 300; |
940 p[len++] = '.'; p[len++] = '.'; p[len++] = '.'; | 966 p[len++] = '.'; p[len++] = '.'; p[len++] = '.'; |
941 } | 967 } |
1306 | 1332 |
1307 static ngx_int_t | 1333 static ngx_int_t |
1308 ngx_http_process_host(ngx_http_request_t *r, ngx_table_elt_t *h, | 1334 ngx_http_process_host(ngx_http_request_t *r, ngx_table_elt_t *h, |
1309 ngx_uint_t offset) | 1335 ngx_uint_t offset) |
1310 { | 1336 { |
1311 ssize_t len; | 1337 u_char *host; |
1338 ssize_t len; | |
1312 | 1339 |
1313 if (r->headers_in.host == NULL) { | 1340 if (r->headers_in.host == NULL) { |
1314 r->headers_in.host = h; | 1341 r->headers_in.host = h; |
1315 } | 1342 } |
1316 | 1343 |
1317 len = ngx_http_validate_host(h->value.data, h->value.len); | 1344 host = h->value.data; |
1318 | 1345 len = ngx_http_validate_host(r, &host, h->value.len, 0); |
1319 if (len <= 0) { | 1346 |
1347 if (len == 0) { | |
1320 ngx_log_error(NGX_LOG_INFO, r->connection->log, 0, | 1348 ngx_log_error(NGX_LOG_INFO, r->connection->log, 0, |
1321 "client sent invalid host header"); | 1349 "client sent invalid host header"); |
1322 ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST); | 1350 ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST); |
1323 return NGX_ERROR; | 1351 return NGX_ERROR; |
1324 } | 1352 } |
1325 | 1353 |
1354 if (len < 0) { | |
1355 ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR); | |
1356 return NGX_ERROR; | |
1357 } | |
1358 | |
1326 if (r->headers_in.server.len) { | 1359 if (r->headers_in.server.len) { |
1327 return NGX_OK; | 1360 return NGX_OK; |
1328 } | 1361 } |
1329 | 1362 |
1330 r->headers_in.server.len = len; | 1363 r->headers_in.server.len = len; |
1331 r->headers_in.server.data = h->value.data; | 1364 r->headers_in.server.data = host; |
1332 | 1365 |
1333 return NGX_OK; | 1366 return NGX_OK; |
1334 } | 1367 } |
1335 | 1368 |
1336 | 1369 |
1582 ngx_http_run_posted_requests(c); | 1615 ngx_http_run_posted_requests(c); |
1583 } | 1616 } |
1584 | 1617 |
1585 | 1618 |
1586 static ssize_t | 1619 static ssize_t |
1587 ngx_http_validate_host(u_char *host, size_t len) | 1620 ngx_http_validate_host(ngx_http_request_t *r, u_char **host, size_t len, |
1588 { | 1621 ngx_uint_t alloc) |
1589 u_char ch; | 1622 { |
1590 size_t i, last; | 1623 u_char *h, ch; |
1591 ngx_uint_t dot; | 1624 size_t i, last; |
1625 ngx_uint_t dot; | |
1592 | 1626 |
1593 last = len; | 1627 last = len; |
1628 h = *host; | |
1594 dot = 0; | 1629 dot = 0; |
1595 | 1630 |
1596 for (i = 0; i < len; i++) { | 1631 for (i = 0; i < len; i++) { |
1597 ch = host[i]; | 1632 ch = h[i]; |
1598 | 1633 |
1599 if (ch == '.') { | 1634 if (ch == '.') { |
1600 if (dot) { | 1635 if (dot) { |
1601 return -1; | 1636 return 0; |
1602 } | 1637 } |
1603 | 1638 |
1604 dot = 1; | 1639 dot = 1; |
1605 continue; | 1640 continue; |
1606 } | 1641 } |
1611 last = i; | 1646 last = i; |
1612 continue; | 1647 continue; |
1613 } | 1648 } |
1614 | 1649 |
1615 if (ngx_path_separator(ch) || ch == '\0') { | 1650 if (ngx_path_separator(ch) || ch == '\0') { |
1616 return -1; | 1651 return 0; |
1652 } | |
1653 | |
1654 if (ch >= 'A' || ch < 'Z') { | |
1655 alloc = 1; | |
1617 } | 1656 } |
1618 } | 1657 } |
1619 | 1658 |
1620 if (dot) { | 1659 if (dot) { |
1621 last--; | 1660 last--; |
1622 } | 1661 } |
1623 | 1662 |
1663 if (alloc) { | |
1664 *host = ngx_pnalloc(r->pool, last) ; | |
1665 if (*host == NULL) { | |
1666 return -1; | |
1667 } | |
1668 | |
1669 ngx_strlow(*host, h, last); | |
1670 } | |
1671 | |
1624 return last; | 1672 return last; |
1625 } | 1673 } |
1626 | 1674 |
1627 | 1675 |
1628 static ngx_int_t | 1676 static ngx_int_t |
1629 ngx_http_find_virtual_server(ngx_http_request_t *r, u_char *host, size_t len) | 1677 ngx_http_find_virtual_server(ngx_http_request_t *r, u_char *host, size_t len) |
1630 { | 1678 { |
1631 u_char *server; | |
1632 ngx_uint_t hash; | |
1633 ngx_http_core_loc_conf_t *clcf; | 1679 ngx_http_core_loc_conf_t *clcf; |
1634 ngx_http_core_srv_conf_t *cscf; | 1680 ngx_http_core_srv_conf_t *cscf; |
1635 u_char buf[32]; | |
1636 | 1681 |
1637 if (r->virtual_names == NULL) { | 1682 if (r->virtual_names == NULL) { |
1638 return NGX_DECLINED; | 1683 return NGX_DECLINED; |
1639 } | 1684 } |
1640 | 1685 |
1641 if (len <= 32) { | 1686 cscf = ngx_hash_find_combined(&r->virtual_names->names, |
1642 server = buf; | 1687 ngx_hash_key(host, len), host, len); |
1643 | |
1644 } else { | |
1645 server = ngx_pnalloc(r->pool, len); | |
1646 if (server == NULL) { | |
1647 return NGX_ERROR; | |
1648 } | |
1649 } | |
1650 | |
1651 hash = ngx_hash_strlow(server, host, len); | |
1652 | |
1653 cscf = ngx_hash_find_combined(&r->virtual_names->names, hash, server, len); | |
1654 | 1688 |
1655 if (cscf) { | 1689 if (cscf) { |
1656 goto found; | 1690 goto found; |
1657 } | 1691 } |
1658 | 1692 |
1664 ngx_uint_t i; | 1698 ngx_uint_t i; |
1665 ngx_str_t name; | 1699 ngx_str_t name; |
1666 ngx_http_server_name_t *sn; | 1700 ngx_http_server_name_t *sn; |
1667 | 1701 |
1668 name.len = len; | 1702 name.len = len; |
1669 name.data = server; | 1703 name.data = host; |
1670 | 1704 |
1671 ncaptures = 0; | 1705 ncaptures = 0; |
1672 | 1706 |
1673 sn = r->virtual_names->regex; | 1707 sn = r->virtual_names->regex; |
1674 | 1708 |
1679 ncaptures = (NGX_HTTP_MAX_CAPTURES + 1) * 3; | 1713 ncaptures = (NGX_HTTP_MAX_CAPTURES + 1) * 3; |
1680 | 1714 |
1681 r->captures = ngx_palloc(r->pool, ncaptures * sizeof(int)); | 1715 r->captures = ngx_palloc(r->pool, ncaptures * sizeof(int)); |
1682 if (r->captures == NULL) { | 1716 if (r->captures == NULL) { |
1683 return NGX_ERROR; | 1717 return NGX_ERROR; |
1684 } | |
1685 | |
1686 if (server == buf) { | |
1687 server = ngx_pnalloc(r->pool, len); | |
1688 if (server == NULL) { | |
1689 return NGX_ERROR; | |
1690 } | |
1691 | |
1692 ngx_memcpy(server, buf, len); | |
1693 name.data = server; | |
1694 } | 1718 } |
1695 } | 1719 } |
1696 | 1720 |
1697 n = ngx_regex_exec(sn[i].regex, &name, r->captures, ncaptures); | 1721 n = ngx_regex_exec(sn[i].regex, &name, r->captures, ncaptures); |
1698 | 1722 |
1711 /* match */ | 1735 /* match */ |
1712 | 1736 |
1713 cscf = sn[i].core_srv_conf; | 1737 cscf = sn[i].core_srv_conf; |
1714 | 1738 |
1715 r->ncaptures = ncaptures; | 1739 r->ncaptures = ncaptures; |
1716 r->captures_data = server; | 1740 r->captures_data = host; |
1717 | 1741 |
1718 goto found; | 1742 goto found; |
1719 } | 1743 } |
1720 } | 1744 } |
1721 | 1745 |