comparison src/http/ngx_http_request.c @ 506:b9fdcaf2062b NGINX_0_7_65

nginx 0.7.65 *) Security: now nginx/Windows ignores trailing spaces in URI. Thanks to Dan Crowley, Core Security Technologies. *) Security: now nginx/Windows ignores short files names. Thanks to Dan Crowley, Core Security Technologies. *) Change: now the "009" status code is written to an access log for proxied HTTP/0.9 responses. *) Change: now the default buffer size of the "large_client_header_buffers" directive is 8K. Thanks to Andrew Cholakian. *) Change: now default SSL ciphers are "HIGH:!ADH:!MD5". *) Change: now SSLv2 protocol is disabled by default. *) Change: now $host variable value is always low case. *) Feature: the conf/fastcgi.conf for simple FastCGI configurations. *) Feature: now URI part is not required a "proxy_pass" directive if variables are used. *) Feature: the $ssl_session_id variable. *) Bugfix: if a proxied or FastCGI request was internally redirected to another proxied or FastCGI location, then $upstream_response_time variable may have abnormally large value; the bug had appeared in 0.7.63. *) Bugfix: if the "expires modified" set date in the past, then a negative number was set in the "Cache-Control" response header line. Thanks to Alex Kapranoff. *) Bugfix: nginx closed a connection if a cached response had an empty body. Thanks to Piotr Sikora. *) Bugfix: nginx cached a 304 response if there was the "If-None-Match" header line in a proxied request. Thanks to Tim Dettrick and David Kostal. *) Bugfix: nginx did not treat a comma as separator in the "Cache-Control" backend response header line. *) Bugfix: cached HTTP/0.9 responses were handled incorrectly. *) Bugfix: nginx sent gzipped responses to clients those do not support gzip, if "gzip_static on" and "gzip_vary off"; the bug had appeared in 0.8.16. *) Bugfix: nginx always added "Content-Encoding: gzip" response header line in 304 responses sent by ngx_http_gzip_static_module. *) Bugfix: the "!-x" operator did not work. Thanks to Maxim Dounin. *) Bugfix: a segmentation fault might occur in a worker process, if limit_rate was used in HTTPS server. Thanks to Maxim Dounin. *) Bugfix: a segmentation fault might occur in a worker process while $limit_rate logging. Thanks to Maxim Dounin. *) Bugfix: nginx did not support dates in 2038 year on 32-bit platforms; *) Bugfix: nginx/Windows tried to delete a temporary file twice if the file should replace an already existent file. *) Bugfix: nginx/Windows tried to rename a temporary file twice if the file should replace an already existent file. *) Bugfix: nginx/Windows might not create temporary file, a cache file, or "proxy/fastcgi_store"d file if a worker had no enough access rights for top level directories. *) Bugfix: in UTF-8 encoding support by "try_files" directive in nginx/Windows. *) Bugfix: UTF-8 encoding usage in the ngx_http_autoindex_module. Thanks to Maxim Dounin. *) Bugfix: the ngx_http_autoindex_module did not show the trailing slash in links to a directory; the bug had appeared in 0.7.15. *) Bugfix: nginx did not close a log file set by the --error-log-path configuration option; the bug had appeared in 0.7.53. *) Bugfix: "addition_types" directive was incorrectly named "addtion_types". *) Bugfix: invalid request line in $request variable was written in access_log only if error_log was set to "info" or "debug" level.
author Igor Sysoev <http://sysoev.ru>
date Mon, 01 Feb 2010 00:00:00 +0000
parents 706fef7f4dcc
children 68c0ae0a4959
comparison
equal deleted inserted replaced
505:c62da3dcc544 506:b9fdcaf2062b
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;
771 { 782 {
772 u_char *p; 783 u_char *p;
773 784
774 p = r->uri.data + r->uri.len - 1; 785 p = r->uri.data + r->uri.len - 1;
775 786
776 if (*p == '.') { 787 if (*p == '.' || *p == ' ') {
777 788
778 while (--p > r->uri.data && *p == '.') { /* void */ } 789 while (--p > r->uri.data && (*p == '.' || *p == ' ')) {
790 /* void */
791 }
779 792
780 r->uri.len = p + 1 - r->uri.data; 793 r->uri.len = p + 1 - r->uri.data;
781 794
782 ngx_http_set_exten(r); 795 ngx_http_set_exten(r);
783 } 796 }
795 808
796 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0, 809 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0,
797 "http exten: \"%V\"", &r->exten); 810 "http exten: \"%V\"", &r->exten);
798 811
799 if (r->host_start && r->host_end) { 812 if (r->host_start && r->host_end) {
800 n = ngx_http_validate_host(r->host_start, 813
801 r->host_end - r->host_start); 814 host = r->host_start;
802 815 n = ngx_http_validate_host(r, &host,
803 if (n <= 0) { 816 r->host_end - r->host_start, 0);
817
818 if (n == 0) {
804 ngx_log_error(NGX_LOG_INFO, c->log, 0, 819 ngx_log_error(NGX_LOG_INFO, c->log, 0,
805 "client sent invalid host in request line"); 820 "client sent invalid host in request line");
806 ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST); 821 ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST);
807 return; 822 return;
808 } 823 }
809 824
825 if (n < 0) {
826 ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
827 return;
828 }
829
810 r->headers_in.server.len = n; 830 r->headers_in.server.len = n;
811 r->headers_in.server.data = r->host_start; 831 r->headers_in.server.data = host;
812 } 832 }
813 833
814 if (r->http_version < NGX_HTTP_VERSION_10) { 834 if (r->http_version < NGX_HTTP_VERSION_10) {
815 835
816 if (ngx_http_find_virtual_server(r, r->headers_in.server.data, 836 if (ngx_http_find_virtual_server(r, r->headers_in.server.data,
930 ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR); 950 ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
931 return; 951 return;
932 } 952 }
933 953
934 if (rv == NGX_DECLINED) { 954 if (rv == NGX_DECLINED) {
935 len = r->header_in->end - r->header_name_start;
936 p = r->header_name_start; 955 p = r->header_name_start;
956
957 if (p == NULL) {
958 ngx_log_error(NGX_LOG_INFO, c->log, 0,
959 "client sent too large request");
960 ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST);
961 return;
962 }
963
964 len = r->header_in->end - p;
937 965
938 if (len > NGX_MAX_ERROR_STR - 300) { 966 if (len > NGX_MAX_ERROR_STR - 300) {
939 len = NGX_MAX_ERROR_STR - 300; 967 len = NGX_MAX_ERROR_STR - 300;
940 p[len++] = '.'; p[len++] = '.'; p[len++] = '.'; 968 p[len++] = '.'; p[len++] = '.'; p[len++] = '.';
941 } 969 }
1306 1334
1307 static ngx_int_t 1335 static ngx_int_t
1308 ngx_http_process_host(ngx_http_request_t *r, ngx_table_elt_t *h, 1336 ngx_http_process_host(ngx_http_request_t *r, ngx_table_elt_t *h,
1309 ngx_uint_t offset) 1337 ngx_uint_t offset)
1310 { 1338 {
1311 ssize_t len; 1339 u_char *host;
1340 ssize_t len;
1312 1341
1313 if (r->headers_in.host == NULL) { 1342 if (r->headers_in.host == NULL) {
1314 r->headers_in.host = h; 1343 r->headers_in.host = h;
1315 } 1344 }
1316 1345
1317 len = ngx_http_validate_host(h->value.data, h->value.len); 1346 host = h->value.data;
1318 1347 len = ngx_http_validate_host(r, &host, h->value.len, 0);
1319 if (len <= 0) { 1348
1349 if (len == 0) {
1320 ngx_log_error(NGX_LOG_INFO, r->connection->log, 0, 1350 ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
1321 "client sent invalid host header"); 1351 "client sent invalid host header");
1322 ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST); 1352 ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST);
1323 return NGX_ERROR; 1353 return NGX_ERROR;
1324 } 1354 }
1325 1355
1356 if (len < 0) {
1357 ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
1358 return NGX_ERROR;
1359 }
1360
1326 if (r->headers_in.server.len) { 1361 if (r->headers_in.server.len) {
1327 return NGX_OK; 1362 return NGX_OK;
1328 } 1363 }
1329 1364
1330 r->headers_in.server.len = len; 1365 r->headers_in.server.len = len;
1331 r->headers_in.server.data = h->value.data; 1366 r->headers_in.server.data = host;
1332 1367
1333 return NGX_OK; 1368 return NGX_OK;
1334 } 1369 }
1335 1370
1336 1371
1582 ngx_http_run_posted_requests(c); 1617 ngx_http_run_posted_requests(c);
1583 } 1618 }
1584 1619
1585 1620
1586 static ssize_t 1621 static ssize_t
1587 ngx_http_validate_host(u_char *host, size_t len) 1622 ngx_http_validate_host(ngx_http_request_t *r, u_char **host, size_t len,
1588 { 1623 ngx_uint_t alloc)
1589 u_char ch; 1624 {
1590 size_t i, last; 1625 u_char *h, ch;
1591 ngx_uint_t dot; 1626 size_t i, last;
1627 ngx_uint_t dot;
1592 1628
1593 last = len; 1629 last = len;
1630 h = *host;
1594 dot = 0; 1631 dot = 0;
1595 1632
1596 for (i = 0; i < len; i++) { 1633 for (i = 0; i < len; i++) {
1597 ch = host[i]; 1634 ch = h[i];
1598 1635
1599 if (ch == '.') { 1636 if (ch == '.') {
1600 if (dot) { 1637 if (dot) {
1601 return -1; 1638 return 0;
1602 } 1639 }
1603 1640
1604 dot = 1; 1641 dot = 1;
1605 continue; 1642 continue;
1606 } 1643 }
1611 last = i; 1648 last = i;
1612 continue; 1649 continue;
1613 } 1650 }
1614 1651
1615 if (ngx_path_separator(ch) || ch == '\0') { 1652 if (ngx_path_separator(ch) || ch == '\0') {
1616 return -1; 1653 return 0;
1654 }
1655
1656 if (ch >= 'A' || ch < 'Z') {
1657 alloc = 1;
1617 } 1658 }
1618 } 1659 }
1619 1660
1620 if (dot) { 1661 if (dot) {
1621 last--; 1662 last--;
1622 } 1663 }
1623 1664
1665 if (alloc) {
1666 *host = ngx_pnalloc(r->pool, last) ;
1667 if (*host == NULL) {
1668 return -1;
1669 }
1670
1671 ngx_strlow(*host, h, last);
1672 }
1673
1624 return last; 1674 return last;
1625 } 1675 }
1626 1676
1627 1677
1628 static ngx_int_t 1678 static ngx_int_t
1629 ngx_http_find_virtual_server(ngx_http_request_t *r, u_char *host, size_t len) 1679 ngx_http_find_virtual_server(ngx_http_request_t *r, u_char *host, size_t len)
1630 { 1680 {
1631 u_char *server;
1632 ngx_uint_t hash;
1633 ngx_http_core_loc_conf_t *clcf; 1681 ngx_http_core_loc_conf_t *clcf;
1634 ngx_http_core_srv_conf_t *cscf; 1682 ngx_http_core_srv_conf_t *cscf;
1635 u_char buf[32];
1636 1683
1637 if (r->virtual_names == NULL) { 1684 if (r->virtual_names == NULL) {
1638 return NGX_DECLINED; 1685 return NGX_DECLINED;
1639 } 1686 }
1640 1687
1641 if (len <= 32) { 1688 cscf = ngx_hash_find_combined(&r->virtual_names->names,
1642 server = buf; 1689 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 1690
1655 if (cscf) { 1691 if (cscf) {
1656 goto found; 1692 goto found;
1657 } 1693 }
1658 1694
1664 ngx_uint_t i; 1700 ngx_uint_t i;
1665 ngx_str_t name; 1701 ngx_str_t name;
1666 ngx_http_server_name_t *sn; 1702 ngx_http_server_name_t *sn;
1667 1703
1668 name.len = len; 1704 name.len = len;
1669 name.data = server; 1705 name.data = host;
1670 1706
1671 ncaptures = 0; 1707 ncaptures = 0;
1672 1708
1673 sn = r->virtual_names->regex; 1709 sn = r->virtual_names->regex;
1674 1710
1679 ncaptures = (NGX_HTTP_MAX_CAPTURES + 1) * 3; 1715 ncaptures = (NGX_HTTP_MAX_CAPTURES + 1) * 3;
1680 1716
1681 r->captures = ngx_palloc(r->pool, ncaptures * sizeof(int)); 1717 r->captures = ngx_palloc(r->pool, ncaptures * sizeof(int));
1682 if (r->captures == NULL) { 1718 if (r->captures == NULL) {
1683 return NGX_ERROR; 1719 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 } 1720 }
1695 } 1721 }
1696 1722
1697 n = ngx_regex_exec(sn[i].regex, &name, r->captures, ncaptures); 1723 n = ngx_regex_exec(sn[i].regex, &name, r->captures, ncaptures);
1698 1724
1711 /* match */ 1737 /* match */
1712 1738
1713 cscf = sn[i].core_srv_conf; 1739 cscf = sn[i].core_srv_conf;
1714 1740
1715 r->ncaptures = ncaptures; 1741 r->ncaptures = ncaptures;
1716 r->captures_data = server; 1742 r->captures_data = host;
1717 1743
1718 goto found; 1744 goto found;
1719 } 1745 }
1720 } 1746 }
1721 1747