Mercurial > hg > nginx
comparison src/http/ngx_http_request.c @ 3152:8bf534c7c998
$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
author | Igor Sysoev <igor@sysoev.ru> |
---|---|
date | Thu, 24 Sep 2009 13:15:50 +0000 |
parents | 9160a117a46a |
children | 90d6b878481f |
comparison
equal
deleted
inserted
replaced
3151:ad3ddfd06e7d | 3152:8bf534c7c998 |
---|---|
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); |
625 | 626 |
626 int | 627 int |
627 ngx_http_ssl_servername(ngx_ssl_conn_t *ssl_conn, int *ad, void *arg) | 628 ngx_http_ssl_servername(ngx_ssl_conn_t *ssl_conn, int *ad, void *arg) |
628 { | 629 { |
629 size_t len; | 630 size_t len; |
631 u_char *host; | |
630 const char *servername; | 632 const char *servername; |
631 ngx_connection_t *c; | 633 ngx_connection_t *c; |
632 ngx_http_request_t *r; | 634 ngx_http_request_t *r; |
633 ngx_http_ssl_srv_conf_t *sscf; | 635 ngx_http_ssl_srv_conf_t *sscf; |
634 | 636 |
649 return SSL_TLSEXT_ERR_NOACK; | 651 return SSL_TLSEXT_ERR_NOACK; |
650 } | 652 } |
651 | 653 |
652 r = c->data; | 654 r = c->data; |
653 | 655 |
654 if (ngx_http_find_virtual_server(r, (u_char *) servername, len) != NGX_OK) { | 656 host = (u_char *) servername; |
657 | |
658 len = ngx_http_validate_host(r, &host, len, 1); | |
659 | |
660 if (len <= 0) { | |
661 return SSL_TLSEXT_ERR_NOACK; | |
662 } | |
663 | |
664 if (ngx_http_find_virtual_server(r, host, len) != NGX_OK) { | |
655 return SSL_TLSEXT_ERR_NOACK; | 665 return SSL_TLSEXT_ERR_NOACK; |
656 } | 666 } |
657 | 667 |
658 sscf = ngx_http_get_module_srv_conf(r, ngx_http_ssl_module); | 668 sscf = ngx_http_get_module_srv_conf(r, ngx_http_ssl_module); |
659 | 669 |
668 | 678 |
669 | 679 |
670 static void | 680 static void |
671 ngx_http_process_request_line(ngx_event_t *rev) | 681 ngx_http_process_request_line(ngx_event_t *rev) |
672 { | 682 { |
683 u_char *host; | |
673 ssize_t n; | 684 ssize_t n; |
674 ngx_int_t rc, rv; | 685 ngx_int_t rc, rv; |
675 ngx_connection_t *c; | 686 ngx_connection_t *c; |
676 ngx_http_request_t *r; | 687 ngx_http_request_t *r; |
677 ngx_http_core_srv_conf_t *cscf; | 688 ngx_http_core_srv_conf_t *cscf; |
799 | 810 |
800 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0, | 811 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0, |
801 "http exten: \"%V\"", &r->exten); | 812 "http exten: \"%V\"", &r->exten); |
802 | 813 |
803 if (r->host_start && r->host_end) { | 814 if (r->host_start && r->host_end) { |
804 n = ngx_http_validate_host(r->host_start, | 815 |
805 r->host_end - r->host_start); | 816 host = r->host_start; |
806 | 817 n = ngx_http_validate_host(r, &host, |
807 if (n <= 0) { | 818 r->host_end - r->host_start, 0); |
819 | |
820 if (n == 0) { | |
808 ngx_log_error(NGX_LOG_INFO, c->log, 0, | 821 ngx_log_error(NGX_LOG_INFO, c->log, 0, |
809 "client sent invalid host in request line"); | 822 "client sent invalid host in request line"); |
810 ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST); | 823 ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST); |
811 return; | 824 return; |
812 } | 825 } |
813 | 826 |
827 if (n < 0) { | |
828 ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR); | |
829 return; | |
830 } | |
831 | |
814 r->headers_in.server.len = n; | 832 r->headers_in.server.len = n; |
815 r->headers_in.server.data = r->host_start; | 833 r->headers_in.server.data = host; |
816 } | 834 } |
817 | 835 |
818 if (r->http_version < NGX_HTTP_VERSION_10) { | 836 if (r->http_version < NGX_HTTP_VERSION_10) { |
819 | 837 |
820 if (ngx_http_find_virtual_server(r, r->headers_in.server.data, | 838 if (ngx_http_find_virtual_server(r, r->headers_in.server.data, |
1310 | 1328 |
1311 static ngx_int_t | 1329 static ngx_int_t |
1312 ngx_http_process_host(ngx_http_request_t *r, ngx_table_elt_t *h, | 1330 ngx_http_process_host(ngx_http_request_t *r, ngx_table_elt_t *h, |
1313 ngx_uint_t offset) | 1331 ngx_uint_t offset) |
1314 { | 1332 { |
1315 ssize_t len; | 1333 u_char *host; |
1334 ssize_t len; | |
1316 | 1335 |
1317 if (r->headers_in.host == NULL) { | 1336 if (r->headers_in.host == NULL) { |
1318 r->headers_in.host = h; | 1337 r->headers_in.host = h; |
1319 } | 1338 } |
1320 | 1339 |
1321 len = ngx_http_validate_host(h->value.data, h->value.len); | 1340 host = h->value.data; |
1322 | 1341 len = ngx_http_validate_host(r, &host, h->value.len, 0); |
1323 if (len <= 0) { | 1342 |
1343 if (len == 0) { | |
1324 ngx_log_error(NGX_LOG_INFO, r->connection->log, 0, | 1344 ngx_log_error(NGX_LOG_INFO, r->connection->log, 0, |
1325 "client sent invalid host header"); | 1345 "client sent invalid host header"); |
1326 ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST); | 1346 ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST); |
1327 return NGX_ERROR; | 1347 return NGX_ERROR; |
1328 } | 1348 } |
1329 | 1349 |
1350 if (len < 0) { | |
1351 ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR); | |
1352 return NGX_ERROR; | |
1353 } | |
1354 | |
1330 if (r->headers_in.server.len) { | 1355 if (r->headers_in.server.len) { |
1331 return NGX_OK; | 1356 return NGX_OK; |
1332 } | 1357 } |
1333 | 1358 |
1334 r->headers_in.server.len = len; | 1359 r->headers_in.server.len = len; |
1335 r->headers_in.server.data = h->value.data; | 1360 r->headers_in.server.data = host; |
1336 | 1361 |
1337 return NGX_OK; | 1362 return NGX_OK; |
1338 } | 1363 } |
1339 | 1364 |
1340 | 1365 |
1586 ngx_http_run_posted_requests(c); | 1611 ngx_http_run_posted_requests(c); |
1587 } | 1612 } |
1588 | 1613 |
1589 | 1614 |
1590 static ssize_t | 1615 static ssize_t |
1591 ngx_http_validate_host(u_char *host, size_t len) | 1616 ngx_http_validate_host(ngx_http_request_t *r, u_char **host, size_t len, |
1592 { | 1617 ngx_uint_t alloc) |
1593 u_char ch; | 1618 { |
1594 size_t i, last; | 1619 u_char *p, *h, ch; |
1595 ngx_uint_t dot; | 1620 size_t i, last; |
1621 ngx_uint_t dot; | |
1596 | 1622 |
1597 last = len; | 1623 last = len; |
1624 h = *host; | |
1598 dot = 0; | 1625 dot = 0; |
1599 | 1626 |
1600 for (i = 0; i < len; i++) { | 1627 for (i = 0; i < len; i++) { |
1601 ch = host[i]; | 1628 ch = h[i]; |
1602 | 1629 |
1603 if (ch == '.') { | 1630 if (ch == '.') { |
1604 if (dot) { | 1631 if (dot) { |
1605 return -1; | 1632 return 0; |
1606 } | 1633 } |
1607 | 1634 |
1608 dot = 1; | 1635 dot = 1; |
1609 continue; | 1636 continue; |
1610 } | 1637 } |
1615 last = i; | 1642 last = i; |
1616 continue; | 1643 continue; |
1617 } | 1644 } |
1618 | 1645 |
1619 if (ngx_path_separator(ch) || ch == '\0') { | 1646 if (ngx_path_separator(ch) || ch == '\0') { |
1620 return -1; | 1647 return 0; |
1648 } | |
1649 | |
1650 if (ch >= 'A' || ch < 'Z') { | |
1651 alloc = 1; | |
1621 } | 1652 } |
1622 } | 1653 } |
1623 | 1654 |
1624 if (dot) { | 1655 if (dot) { |
1625 last--; | 1656 last--; |
1626 } | 1657 } |
1627 | 1658 |
1659 if (alloc) { | |
1660 p = ngx_pnalloc(r->pool, last) ; | |
1661 if (p == NULL) { | |
1662 return -1; | |
1663 } | |
1664 | |
1665 *host = p; | |
1666 | |
1667 for (i = 0; i < last; i++) { | |
1668 *p++ = ngx_tolower(h[i]); | |
1669 } | |
1670 } | |
1671 | |
1628 return last; | 1672 return last; |
1629 } | 1673 } |
1630 | 1674 |
1631 | 1675 |
1632 static ngx_int_t | 1676 static ngx_int_t |
1633 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) |
1634 { | 1678 { |
1635 u_char *server; | |
1636 ngx_uint_t hash; | |
1637 ngx_http_core_loc_conf_t *clcf; | 1679 ngx_http_core_loc_conf_t *clcf; |
1638 ngx_http_core_srv_conf_t *cscf; | 1680 ngx_http_core_srv_conf_t *cscf; |
1639 u_char buf[32]; | |
1640 | 1681 |
1641 if (r->virtual_names == NULL) { | 1682 if (r->virtual_names == NULL) { |
1642 return NGX_DECLINED; | 1683 return NGX_DECLINED; |
1643 } | 1684 } |
1644 | 1685 |
1645 if (len <= 32) { | 1686 cscf = ngx_hash_find_combined(&r->virtual_names->names, |
1646 server = buf; | 1687 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 | 1688 |
1659 if (cscf) { | 1689 if (cscf) { |
1660 goto found; | 1690 goto found; |
1661 } | 1691 } |
1662 | 1692 |
1668 ngx_uint_t i; | 1698 ngx_uint_t i; |
1669 ngx_str_t name; | 1699 ngx_str_t name; |
1670 ngx_http_server_name_t *sn; | 1700 ngx_http_server_name_t *sn; |
1671 | 1701 |
1672 name.len = len; | 1702 name.len = len; |
1673 name.data = server; | 1703 name.data = host; |
1674 | 1704 |
1675 ncaptures = 0; | 1705 ncaptures = 0; |
1676 | 1706 |
1677 sn = r->virtual_names->regex; | 1707 sn = r->virtual_names->regex; |
1678 | 1708 |
1683 ncaptures = (NGX_HTTP_MAX_CAPTURES + 1) * 3; | 1713 ncaptures = (NGX_HTTP_MAX_CAPTURES + 1) * 3; |
1684 | 1714 |
1685 r->captures = ngx_palloc(r->pool, ncaptures * sizeof(int)); | 1715 r->captures = ngx_palloc(r->pool, ncaptures * sizeof(int)); |
1686 if (r->captures == NULL) { | 1716 if (r->captures == NULL) { |
1687 return NGX_ERROR; | 1717 return NGX_ERROR; |
1688 } | |
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 } | 1718 } |
1699 } | 1719 } |
1700 | 1720 |
1701 n = ngx_regex_exec(sn[i].regex, &name, r->captures, ncaptures); | 1721 n = ngx_regex_exec(sn[i].regex, &name, r->captures, ncaptures); |
1702 | 1722 |
1715 /* match */ | 1735 /* match */ |
1716 | 1736 |
1717 cscf = sn[i].core_srv_conf; | 1737 cscf = sn[i].core_srv_conf; |
1718 | 1738 |
1719 r->ncaptures = ncaptures; | 1739 r->ncaptures = ncaptures; |
1720 r->captures_data = server; | 1740 r->captures_data = host; |
1721 | 1741 |
1722 goto found; | 1742 goto found; |
1723 } | 1743 } |
1724 } | 1744 } |
1725 | 1745 |