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