Mercurial > hg > nginx-vendor-0-7
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 |