Mercurial > hg > nginx-ranges
comparison src/http/ngx_http_request.c @ 542:4c5d2c627a6c NGINX_0_8_17
nginx 0.8.17
*) Security: now "/../" are disabled in "Destination" request header
line.
*) Change: now $host variable value is always low case.
*) Feature: the $ssl_session_id variable.
*) Bugfix: socket leak; the bug had appeared in 0.8.11.
author | Igor Sysoev <http://sysoev.ru> |
---|---|
date | Mon, 28 Sep 2009 00:00:00 +0400 |
parents | 005a70f9573b |
children | f7ec98e3caeb |
comparison
equal
deleted
inserted
replaced
541:b8ac674b0ec9 | 542:4c5d2c627a6c |
---|---|
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 *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 *host = ngx_pnalloc(r->pool, last) ; | |
1661 if (*host == NULL) { | |
1662 return -1; | |
1663 } | |
1664 | |
1665 ngx_strlow(*host, h, last); | |
1666 } | |
1667 | |
1628 return last; | 1668 return last; |
1629 } | 1669 } |
1630 | 1670 |
1631 | 1671 |
1632 static ngx_int_t | 1672 static ngx_int_t |
1633 ngx_http_find_virtual_server(ngx_http_request_t *r, u_char *host, size_t len) | 1673 ngx_http_find_virtual_server(ngx_http_request_t *r, u_char *host, size_t len) |
1634 { | 1674 { |
1635 u_char *server; | |
1636 ngx_uint_t hash; | |
1637 ngx_http_core_loc_conf_t *clcf; | 1675 ngx_http_core_loc_conf_t *clcf; |
1638 ngx_http_core_srv_conf_t *cscf; | 1676 ngx_http_core_srv_conf_t *cscf; |
1639 u_char buf[32]; | |
1640 | 1677 |
1641 if (r->virtual_names == NULL) { | 1678 if (r->virtual_names == NULL) { |
1642 return NGX_DECLINED; | 1679 return NGX_DECLINED; |
1643 } | 1680 } |
1644 | 1681 |
1645 if (len <= 32) { | 1682 cscf = ngx_hash_find_combined(&r->virtual_names->names, |
1646 server = buf; | 1683 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 | 1684 |
1659 if (cscf) { | 1685 if (cscf) { |
1660 goto found; | 1686 goto found; |
1661 } | 1687 } |
1662 | 1688 |
1668 ngx_uint_t i; | 1694 ngx_uint_t i; |
1669 ngx_str_t name; | 1695 ngx_str_t name; |
1670 ngx_http_server_name_t *sn; | 1696 ngx_http_server_name_t *sn; |
1671 | 1697 |
1672 name.len = len; | 1698 name.len = len; |
1673 name.data = server; | 1699 name.data = host; |
1674 | 1700 |
1675 ncaptures = 0; | 1701 ncaptures = 0; |
1676 | 1702 |
1677 sn = r->virtual_names->regex; | 1703 sn = r->virtual_names->regex; |
1678 | 1704 |
1683 ncaptures = (NGX_HTTP_MAX_CAPTURES + 1) * 3; | 1709 ncaptures = (NGX_HTTP_MAX_CAPTURES + 1) * 3; |
1684 | 1710 |
1685 r->captures = ngx_palloc(r->pool, ncaptures * sizeof(int)); | 1711 r->captures = ngx_palloc(r->pool, ncaptures * sizeof(int)); |
1686 if (r->captures == NULL) { | 1712 if (r->captures == NULL) { |
1687 return NGX_ERROR; | 1713 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 } | 1714 } |
1699 } | 1715 } |
1700 | 1716 |
1701 n = ngx_regex_exec(sn[i].regex, &name, r->captures, ncaptures); | 1717 n = ngx_regex_exec(sn[i].regex, &name, r->captures, ncaptures); |
1702 | 1718 |
1715 /* match */ | 1731 /* match */ |
1716 | 1732 |
1717 cscf = sn[i].core_srv_conf; | 1733 cscf = sn[i].core_srv_conf; |
1718 | 1734 |
1719 r->ncaptures = ncaptures; | 1735 r->ncaptures = ncaptures; |
1720 r->captures_data = server; | 1736 r->captures_data = host; |
1721 | 1737 |
1722 goto found; | 1738 goto found; |
1723 } | 1739 } |
1724 } | 1740 } |
1725 | 1741 |