comparison src/http/ngx_http_request.c @ 578:f3a9e57d2e17

Merge with current.
author Maxim Dounin <mdounin@mdounin.ru>
date Thu, 11 Mar 2010 21:27:17 +0300
parents 7fa8dc2315bd
children 01f2313e34f1
comparison
equal deleted inserted replaced
539:5f4de8cf0d9d 578:f3a9e57d2e17
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);
378 } 379 }
379 380
380 r->virtual_names = addr_conf->virtual_names; 381 r->virtual_names = addr_conf->virtual_names;
381 382
382 /* the default server configuration for the address:port */ 383 /* the default server configuration for the address:port */
383 cscf = addr_conf->core_srv_conf; 384 cscf = addr_conf->default_server;
384 385
385 r->main_conf = cscf->ctx->main_conf; 386 r->main_conf = cscf->ctx->main_conf;
386 r->srv_conf = cscf->ctx->srv_conf; 387 r->srv_conf = cscf->ctx->srv_conf;
387 r->loc_conf = cscf->ctx->loc_conf; 388 r->loc_conf = cscf->ctx->loc_conf;
388 389
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;
775 { 786 {
776 u_char *p; 787 u_char *p;
777 788
778 p = r->uri.data + r->uri.len - 1; 789 p = r->uri.data + r->uri.len - 1;
779 790
780 if (*p == '.') { 791 if (*p == '.' || *p == ' ') {
781 792
782 while (--p > r->uri.data && *p == '.') { /* void */ } 793 while (--p > r->uri.data && (*p == '.' || *p == ' ')) {
794 /* void */
795 }
783 796
784 r->uri.len = p + 1 - r->uri.data; 797 r->uri.len = p + 1 - r->uri.data;
785 798
786 ngx_http_set_exten(r); 799 ngx_http_set_exten(r);
787 } 800 }
799 812
800 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0, 813 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0,
801 "http exten: \"%V\"", &r->exten); 814 "http exten: \"%V\"", &r->exten);
802 815
803 if (r->host_start && r->host_end) { 816 if (r->host_start && r->host_end) {
804 n = ngx_http_validate_host(r->host_start, 817
805 r->host_end - r->host_start); 818 host = r->host_start;
806 819 n = ngx_http_validate_host(r, &host,
807 if (n <= 0) { 820 r->host_end - r->host_start, 0);
821
822 if (n == 0) {
808 ngx_log_error(NGX_LOG_INFO, c->log, 0, 823 ngx_log_error(NGX_LOG_INFO, c->log, 0,
809 "client sent invalid host in request line"); 824 "client sent invalid host in request line");
810 ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST); 825 ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST);
811 return; 826 return;
812 } 827 }
813 828
829 if (n < 0) {
830 ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
831 return;
832 }
833
814 r->headers_in.server.len = n; 834 r->headers_in.server.len = n;
815 r->headers_in.server.data = r->host_start; 835 r->headers_in.server.data = host;
816 } 836 }
817 837
818 if (r->http_version < NGX_HTTP_VERSION_10) { 838 if (r->http_version < NGX_HTTP_VERSION_10) {
819 839
820 if (ngx_http_find_virtual_server(r, r->headers_in.server.data, 840 if (ngx_http_find_virtual_server(r, r->headers_in.server.data,
934 ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR); 954 ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
935 return; 955 return;
936 } 956 }
937 957
938 if (rv == NGX_DECLINED) { 958 if (rv == NGX_DECLINED) {
939 len = r->header_in->end - r->header_name_start;
940 p = r->header_name_start; 959 p = r->header_name_start;
960
961 if (p == NULL) {
962 ngx_log_error(NGX_LOG_INFO, c->log, 0,
963 "client sent too large request");
964 ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST);
965 return;
966 }
967
968 len = r->header_in->end - p;
941 969
942 if (len > NGX_MAX_ERROR_STR - 300) { 970 if (len > NGX_MAX_ERROR_STR - 300) {
943 len = NGX_MAX_ERROR_STR - 300; 971 len = NGX_MAX_ERROR_STR - 300;
944 p[len++] = '.'; p[len++] = '.'; p[len++] = '.'; 972 p[len++] = '.'; p[len++] = '.'; p[len++] = '.';
945 } 973 }
1310 1338
1311 static ngx_int_t 1339 static ngx_int_t
1312 ngx_http_process_host(ngx_http_request_t *r, ngx_table_elt_t *h, 1340 ngx_http_process_host(ngx_http_request_t *r, ngx_table_elt_t *h,
1313 ngx_uint_t offset) 1341 ngx_uint_t offset)
1314 { 1342 {
1315 ssize_t len; 1343 u_char *host;
1344 ssize_t len;
1316 1345
1317 if (r->headers_in.host == NULL) { 1346 if (r->headers_in.host == NULL) {
1318 r->headers_in.host = h; 1347 r->headers_in.host = h;
1319 } 1348 }
1320 1349
1321 len = ngx_http_validate_host(h->value.data, h->value.len); 1350 host = h->value.data;
1322 1351 len = ngx_http_validate_host(r, &host, h->value.len, 0);
1323 if (len <= 0) { 1352
1353 if (len == 0) {
1324 ngx_log_error(NGX_LOG_INFO, r->connection->log, 0, 1354 ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
1325 "client sent invalid host header"); 1355 "client sent invalid host header");
1326 ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST); 1356 ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST);
1327 return NGX_ERROR; 1357 return NGX_ERROR;
1328 } 1358 }
1329 1359
1360 if (len < 0) {
1361 ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
1362 return NGX_ERROR;
1363 }
1364
1330 if (r->headers_in.server.len) { 1365 if (r->headers_in.server.len) {
1331 return NGX_OK; 1366 return NGX_OK;
1332 } 1367 }
1333 1368
1334 r->headers_in.server.len = len; 1369 r->headers_in.server.len = len;
1335 r->headers_in.server.data = h->value.data; 1370 r->headers_in.server.data = host;
1336 1371
1337 return NGX_OK; 1372 return NGX_OK;
1338 } 1373 }
1339 1374
1340 1375
1410 if (!r->headers_in.msie && !r->headers_in.opera) { 1445 if (!r->headers_in.msie && !r->headers_in.opera) {
1411 1446
1412 if (ngx_strstrn(user_agent, "Gecko/", 6 - 1)) { 1447 if (ngx_strstrn(user_agent, "Gecko/", 6 - 1)) {
1413 r->headers_in.gecko = 1; 1448 r->headers_in.gecko = 1;
1414 1449
1450 } else if (ngx_strstrn(user_agent, "Chrome/", 7 - 1)) {
1451 r->headers_in.chrome = 1;
1452
1453 } else if (ngx_strstrn(user_agent, "Safari/", 7 - 1)) {
1454 r->headers_in.safari = 1;
1455
1415 } else if (ngx_strstrn(user_agent, "Konqueror", 9 - 1)) { 1456 } else if (ngx_strstrn(user_agent, "Konqueror", 9 - 1)) {
1416 r->headers_in.konqueror = 1; 1457 r->headers_in.konqueror = 1;
1417 } 1458 }
1418 } 1459 }
1419 1460
1586 ngx_http_run_posted_requests(c); 1627 ngx_http_run_posted_requests(c);
1587 } 1628 }
1588 1629
1589 1630
1590 static ssize_t 1631 static ssize_t
1591 ngx_http_validate_host(u_char *host, size_t len) 1632 ngx_http_validate_host(ngx_http_request_t *r, u_char **host, size_t len,
1592 { 1633 ngx_uint_t alloc)
1593 u_char ch; 1634 {
1594 size_t i, last; 1635 u_char *h, ch;
1595 ngx_uint_t dot; 1636 size_t i, last;
1637 ngx_uint_t dot;
1596 1638
1597 last = len; 1639 last = len;
1640 h = *host;
1598 dot = 0; 1641 dot = 0;
1599 1642
1600 for (i = 0; i < len; i++) { 1643 for (i = 0; i < len; i++) {
1601 ch = host[i]; 1644 ch = h[i];
1602 1645
1603 if (ch == '.') { 1646 if (ch == '.') {
1604 if (dot) { 1647 if (dot) {
1605 return -1; 1648 return 0;
1606 } 1649 }
1607 1650
1608 dot = 1; 1651 dot = 1;
1609 continue; 1652 continue;
1610 } 1653 }
1615 last = i; 1658 last = i;
1616 continue; 1659 continue;
1617 } 1660 }
1618 1661
1619 if (ngx_path_separator(ch) || ch == '\0') { 1662 if (ngx_path_separator(ch) || ch == '\0') {
1620 return -1; 1663 return 0;
1664 }
1665
1666 if (ch >= 'A' || ch < 'Z') {
1667 alloc = 1;
1621 } 1668 }
1622 } 1669 }
1623 1670
1624 if (dot) { 1671 if (dot) {
1625 last--; 1672 last--;
1626 } 1673 }
1627 1674
1675 if (alloc) {
1676 *host = ngx_pnalloc(r->pool, last) ;
1677 if (*host == NULL) {
1678 return -1;
1679 }
1680
1681 ngx_strlow(*host, h, last);
1682 }
1683
1628 return last; 1684 return last;
1629 } 1685 }
1630 1686
1631 1687
1632 static ngx_int_t 1688 static ngx_int_t
1633 ngx_http_find_virtual_server(ngx_http_request_t *r, u_char *host, size_t len) 1689 ngx_http_find_virtual_server(ngx_http_request_t *r, u_char *host, size_t len)
1634 { 1690 {
1635 u_char *server;
1636 ngx_uint_t hash;
1637 ngx_http_core_loc_conf_t *clcf; 1691 ngx_http_core_loc_conf_t *clcf;
1638 ngx_http_core_srv_conf_t *cscf; 1692 ngx_http_core_srv_conf_t *cscf;
1639 u_char buf[32];
1640 1693
1641 if (r->virtual_names == NULL) { 1694 if (r->virtual_names == NULL) {
1642 return NGX_DECLINED; 1695 return NGX_DECLINED;
1643 } 1696 }
1644 1697
1645 if (len <= 32) { 1698 cscf = ngx_hash_find_combined(&r->virtual_names->names,
1646 server = buf; 1699 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 1700
1659 if (cscf) { 1701 if (cscf) {
1660 goto found; 1702 goto found;
1661 } 1703 }
1662 1704
1663 #if (NGX_PCRE) 1705 #if (NGX_PCRE)
1664 1706
1665 if (r->virtual_names->nregex) { 1707 if (len && r->virtual_names->nregex) {
1666 size_t ncaptures;
1667 ngx_int_t n; 1708 ngx_int_t n;
1668 ngx_uint_t i; 1709 ngx_uint_t i;
1669 ngx_str_t name; 1710 ngx_str_t name;
1670 ngx_http_server_name_t *sn; 1711 ngx_http_server_name_t *sn;
1671 1712
1672 name.len = len; 1713 name.len = len;
1673 name.data = server; 1714 name.data = host;
1674
1675 ncaptures = 0;
1676 1715
1677 sn = r->virtual_names->regex; 1716 sn = r->virtual_names->regex;
1678 1717
1679 for (i = 0; i < r->virtual_names->nregex; i++) { 1718 for (i = 0; i < r->virtual_names->nregex; i++) {
1680 1719
1681 if (sn[i].captures && r->captures == NULL) { 1720 n = ngx_http_regex_exec(r, sn[i].regex, &name);
1682 1721
1683 ncaptures = (NGX_HTTP_MAX_CAPTURES + 1) * 3; 1722 if (n == NGX_OK) {
1684 1723 cscf = sn[i].server;
1685 r->captures = ngx_palloc(r->pool, ncaptures * sizeof(int)); 1724 goto found;
1686 if (r->captures == NULL) { 1725 }
1687 return NGX_ERROR; 1726
1688 } 1727 if (n == NGX_DECLINED) {
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 }
1699 }
1700
1701 n = ngx_regex_exec(sn[i].regex, &name, r->captures, ncaptures);
1702
1703 if (n == NGX_REGEX_NO_MATCHED) {
1704 continue; 1728 continue;
1705 } 1729 }
1706 1730
1707 if (n < 0) { 1731 return NGX_ERROR;
1708 ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0,
1709 ngx_regex_exec_n
1710 " failed: %d on \"%V\" using \"%V\"",
1711 n, &name, &sn[i].name);
1712 return NGX_ERROR;
1713 }
1714
1715 /* match */
1716
1717 cscf = sn[i].core_srv_conf;
1718
1719 r->ncaptures = ncaptures;
1720 r->captures_data = server;
1721
1722 goto found;
1723 } 1732 }
1724 } 1733 }
1725 1734
1726 #endif 1735 #endif
1727 1736
1991 &r->uri, &r->args); 2000 &r->uri, &r->args);
1992 return; 2001 return;
1993 } 2002 }
1994 2003
1995 r->done = 1; 2004 r->done = 1;
2005 r->write_event_handler = ngx_http_request_empty_handler;
1996 2006
1997 if (!r->post_action) { 2007 if (!r->post_action) {
1998 r->request_complete = 1; 2008 r->request_complete = 1;
1999 } 2009 }
2000 2010
2029 2039
2030 mr = r->main; 2040 mr = r->main;
2031 2041
2032 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, 2042 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
2033 "http terminate request count:%d", mr->count); 2043 "http terminate request count:%d", mr->count);
2044
2045 if (rc > 0 && (mr->headers_out.status == 0 || mr->connection->sent == 0)) {
2046 mr->headers_out.status = rc;
2047 }
2034 2048
2035 cln = mr->cleanup; 2049 cln = mr->cleanup;
2036 mr->cleanup = NULL; 2050 mr->cleanup = NULL;
2037 2051
2038 while (cln) { 2052 while (cln) {
2079 static void 2093 static void
2080 ngx_http_finalize_connection(ngx_http_request_t *r) 2094 ngx_http_finalize_connection(ngx_http_request_t *r)
2081 { 2095 {
2082 ngx_http_core_loc_conf_t *clcf; 2096 ngx_http_core_loc_conf_t *clcf;
2083 2097
2098 clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
2099
2084 if (r->main->count != 1) { 2100 if (r->main->count != 1) {
2101
2102 if (r->discard_body) {
2103 r->read_event_handler = ngx_http_discarded_request_body_handler;
2104
2105 if (r->lingering_time == 0) {
2106 r->lingering_time = ngx_time()
2107 + (time_t) (clcf->lingering_time / 1000);
2108 ngx_add_timer(r->connection->read, clcf->lingering_timeout);
2109 }
2110 }
2111
2085 ngx_http_close_request(r, 0); 2112 ngx_http_close_request(r, 0);
2086 return; 2113 return;
2087 } 2114 }
2088
2089 clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
2090 2115
2091 if (!ngx_terminate 2116 if (!ngx_terminate
2092 && !ngx_exiting 2117 && !ngx_exiting
2093 && r->keepalive 2118 && r->keepalive
2094 && clcf->keepalive_timeout > 0) 2119 && clcf->keepalive_timeout > 0)
2111 ngx_event_t *wev; 2136 ngx_event_t *wev;
2112 ngx_http_core_loc_conf_t *clcf; 2137 ngx_http_core_loc_conf_t *clcf;
2113 2138
2114 r->http_state = NGX_HTTP_WRITING_REQUEST_STATE; 2139 r->http_state = NGX_HTTP_WRITING_REQUEST_STATE;
2115 2140
2116 r->read_event_handler = ngx_http_test_reading; 2141 r->read_event_handler = r->discard_body ?
2142 ngx_http_discarded_request_body_handler:
2143 ngx_http_test_reading;
2117 r->write_event_handler = ngx_http_writer; 2144 r->write_event_handler = ngx_http_writer;
2118 2145
2119 wev = r->connection->write; 2146 wev = r->connection->write;
2120 2147
2121 if (wev->ready && wev->delayed) { 2148 if (wev->ready && wev->delayed) {
2212 return; 2239 return;
2213 } 2240 }
2214 2241
2215 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, wev->log, 0, 2242 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, wev->log, 0,
2216 "http writer done: \"%V?%V\"", &r->uri, &r->args); 2243 "http writer done: \"%V?%V\"", &r->uri, &r->args);
2244
2245 r->write_event_handler = ngx_http_request_empty_handler;
2217 2246
2218 ngx_http_finalize_request(r, rc); 2247 ngx_http_finalize_request(r, rc);
2219 } 2248 }
2220 2249
2221 2250
2388 2417
2389 hc->busy[0] = b; 2418 hc->busy[0] = b;
2390 hc->nbusy = 1; 2419 hc->nbusy = 1;
2391 } 2420 }
2392 } 2421 }
2422
2423 r->keepalive = 0;
2393 2424
2394 ngx_http_free_request(r, 0); 2425 ngx_http_free_request(r, 0);
2395 2426
2396 c->data = hc; 2427 c->data = hc;
2397 2428
2818 } 2849 }
2819 2850
2820 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, 2851 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
2821 "post action: \"%V\"", &clcf->post_action); 2852 "post action: \"%V\"", &clcf->post_action);
2822 2853
2854 r->main->count--;
2855
2823 r->http_version = NGX_HTTP_VERSION_9; 2856 r->http_version = NGX_HTTP_VERSION_9;
2824 r->header_only = 1; 2857 r->header_only = 1;
2825 r->post_action = 1; 2858 r->post_action = 1;
2826 2859
2827 r->read_event_handler = ngx_http_block_reading; 2860 r->read_event_handler = ngx_http_block_reading;