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