Mercurial > hg > nginx-vendor-0-8
comparison src/http/modules/ngx_http_fastcgi_module.c @ 356:b743d290eb3b NGINX_0_6_22
nginx 0.6.22
*) Change: now all ngx_http_perl_module methods return values copied to
perl's allocated memory.
*) Bugfix: if nginx was built with ngx_http_perl_module, the perl
before 5.8.6 was used, and perl supported threads, then during
reconfiguration the master process aborted; bug appeared in
0.5.9.
Thanks to Boris Zhmurov.
*) Bugfix: the ngx_http_perl_module methods may get invalid values of
the regex captures.
*) Bugfix: a segmentation fault occurred in worker process, if the
$r->has_request_body() method was called for a request whose small
request body was already received.
*) Bugfix: large_client_header_buffers did not freed before going to
keep-alive state.
Thanks to Olexander Shtepa.
*) Bugfix: the last address was missed in the $upstream_addr variable;
bug appeared in 0.6.18.
*) Bugfix: the "fastcgi_catch_stderr" directive did return error code;
now it returns 502 code, that can be rerouted to a next server using
the "fastcgi_next_upstream invalid_header" directive.
*) Bugfix: a segmentation fault occurred in master process if the
"fastcgi_catch_stderr" directive was used; bug appeared in
0.6.10.
Thanks to Manlio Perillo.
author | Igor Sysoev <http://sysoev.ru> |
---|---|
date | Wed, 19 Dec 2007 00:00:00 +0300 |
parents | 583decdb82a4 |
children | a39aab45a53f |
comparison
equal
deleted
inserted
replaced
355:3ac45897a61c | 356:b743d290eb3b |
---|---|
885 umcf = ngx_http_get_module_main_conf(r, ngx_http_upstream_module); | 885 umcf = ngx_http_get_module_main_conf(r, ngx_http_upstream_module); |
886 | 886 |
887 if (f == NULL) { | 887 if (f == NULL) { |
888 f = ngx_pcalloc(r->pool, sizeof(ngx_http_fastcgi_ctx_t)); | 888 f = ngx_pcalloc(r->pool, sizeof(ngx_http_fastcgi_ctx_t)); |
889 if (f == NULL) { | 889 if (f == NULL) { |
890 return NGX_HTTP_INTERNAL_SERVER_ERROR; | 890 return NGX_ERROR; |
891 } | 891 } |
892 | 892 |
893 ngx_http_set_ctx(r, f, ngx_http_fastcgi_module); | 893 ngx_http_set_ctx(r, f, ngx_http_fastcgi_module); |
894 } | 894 } |
895 | 895 |
993 | 993 |
994 line.data[line.len - 1] = '\0'; | 994 line.data[line.len - 1] = '\0'; |
995 | 995 |
996 for (i = 0; i < flcf->catch_stderr->nelts; i++) { | 996 for (i = 0; i < flcf->catch_stderr->nelts; i++) { |
997 if (ngx_strstr(line.data, pattern[i].data)) { | 997 if (ngx_strstr(line.data, pattern[i].data)) { |
998 return NGX_HTTP_BAD_GATEWAY; | 998 return NGX_HTTP_UPSTREAM_INVALID_HEADER; |
999 } | 999 } |
1000 } | 1000 } |
1001 } | 1001 } |
1002 | 1002 |
1003 if (u->buffer.pos == u->buffer.last) { | 1003 if (u->buffer.pos == u->buffer.last) { |
1061 | 1061 |
1062 /* a header line has been parsed successfully */ | 1062 /* a header line has been parsed successfully */ |
1063 | 1063 |
1064 h = ngx_list_push(&u->headers_in.headers); | 1064 h = ngx_list_push(&u->headers_in.headers); |
1065 if (h == NULL) { | 1065 if (h == NULL) { |
1066 return NGX_HTTP_INTERNAL_SERVER_ERROR; | 1066 return NGX_ERROR; |
1067 } | 1067 } |
1068 | 1068 |
1069 if (f->split_parts && f->split_parts->nelts) { | 1069 if (f->split_parts && f->split_parts->nelts) { |
1070 | 1070 |
1071 part = f->split_parts->elts; | 1071 part = f->split_parts->elts; |
1075 size += part[i].end - part[i].start; | 1075 size += part[i].end - part[i].start; |
1076 } | 1076 } |
1077 | 1077 |
1078 p = ngx_palloc(r->pool, size); | 1078 p = ngx_palloc(r->pool, size); |
1079 if (p == NULL) { | 1079 if (p == NULL) { |
1080 return NGX_HTTP_INTERNAL_SERVER_ERROR; | 1080 return NGX_ERROR; |
1081 } | 1081 } |
1082 | 1082 |
1083 buf.pos = p; | 1083 buf.pos = p; |
1084 | 1084 |
1085 for (i = 0; i < f->split_parts->nelts; i++) { | 1085 for (i = 0; i < f->split_parts->nelts; i++) { |
1103 h->value.data = r->header_start; | 1103 h->value.data = r->header_start; |
1104 h->value.data[h->value.len] = '\0'; | 1104 h->value.data[h->value.len] = '\0'; |
1105 | 1105 |
1106 h->lowcase_key = ngx_palloc(r->pool, h->key.len); | 1106 h->lowcase_key = ngx_palloc(r->pool, h->key.len); |
1107 if (h->lowcase_key == NULL) { | 1107 if (h->lowcase_key == NULL) { |
1108 return NGX_HTTP_INTERNAL_SERVER_ERROR; | 1108 return NGX_ERROR; |
1109 } | 1109 } |
1110 | 1110 |
1111 } else { | 1111 } else { |
1112 | 1112 |
1113 h->key.len = r->header_name_end - r->header_name_start; | 1113 h->key.len = r->header_name_end - r->header_name_start; |
1115 | 1115 |
1116 h->key.data = ngx_palloc(r->pool, | 1116 h->key.data = ngx_palloc(r->pool, |
1117 h->key.len + 1 + h->value.len + 1 | 1117 h->key.len + 1 + h->value.len + 1 |
1118 + h->key.len); | 1118 + h->key.len); |
1119 if (h->key.data == NULL) { | 1119 if (h->key.data == NULL) { |
1120 return NGX_HTTP_INTERNAL_SERVER_ERROR; | 1120 return NGX_ERROR; |
1121 } | 1121 } |
1122 | 1122 |
1123 h->value.data = h->key.data + h->key.len + 1; | 1123 h->value.data = h->key.data + h->key.len + 1; |
1124 h->lowcase_key = h->key.data + h->key.len + 1 | 1124 h->lowcase_key = h->key.data + h->key.len + 1 |
1125 + h->value.len + 1; | 1125 + h->value.len + 1; |
1143 | 1143 |
1144 hh = ngx_hash_find(&umcf->headers_in_hash, h->hash, | 1144 hh = ngx_hash_find(&umcf->headers_in_hash, h->hash, |
1145 h->lowcase_key, h->key.len); | 1145 h->lowcase_key, h->key.len); |
1146 | 1146 |
1147 if (hh && hh->handler(r, h, hh->offset) != NGX_OK) { | 1147 if (hh && hh->handler(r, h, hh->offset) != NGX_OK) { |
1148 return NGX_HTTP_INTERNAL_SERVER_ERROR; | 1148 return NGX_ERROR; |
1149 } | 1149 } |
1150 | 1150 |
1151 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, | 1151 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, |
1152 "http fastcgi header: \"%V: %V\"", | 1152 "http fastcgi header: \"%V: %V\"", |
1153 &h->key, &h->value); | 1153 &h->key, &h->value); |
1172 status_line = &u->headers_in.status->value; | 1172 status_line = &u->headers_in.status->value; |
1173 | 1173 |
1174 status = ngx_atoi(status_line->data, 3); | 1174 status = ngx_atoi(status_line->data, 3); |
1175 | 1175 |
1176 if (status == NGX_ERROR) { | 1176 if (status == NGX_ERROR) { |
1177 return NGX_HTTP_INTERNAL_SERVER_ERROR; | 1177 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, |
1178 "upstream sent invalid status \"%V\"", | |
1179 status_line); | |
1180 return NGX_HTTP_UPSTREAM_INVALID_HEADER; | |
1178 } | 1181 } |
1179 | 1182 |
1180 u->headers_in.status_n = status; | 1183 u->headers_in.status_n = status; |
1181 u->headers_in.status_line = *status_line; | 1184 u->headers_in.status_line = *status_line; |
1182 | 1185 |
1233 | 1236 |
1234 if (f->split_parts == NULL) { | 1237 if (f->split_parts == NULL) { |
1235 f->split_parts = ngx_array_create(r->pool, 1, | 1238 f->split_parts = ngx_array_create(r->pool, 1, |
1236 sizeof(ngx_http_fastcgi_split_part_t)); | 1239 sizeof(ngx_http_fastcgi_split_part_t)); |
1237 if (f->split_parts == NULL) { | 1240 if (f->split_parts == NULL) { |
1238 return NGX_HTTP_INTERNAL_SERVER_ERROR; | 1241 return NGX_ERROR; |
1239 } | 1242 } |
1240 } | 1243 } |
1241 | 1244 |
1242 part = ngx_array_push(f->split_parts); | 1245 part = ngx_array_push(f->split_parts); |
1243 | 1246 |
1638 * | 1641 * |
1639 * conf->upstream.bufs.num = 0; | 1642 * conf->upstream.bufs.num = 0; |
1640 * conf->upstream.next_upstream = 0; | 1643 * conf->upstream.next_upstream = 0; |
1641 * conf->upstream.temp_path = NULL; | 1644 * conf->upstream.temp_path = NULL; |
1642 * conf->upstream.hide_headers_hash = { NULL, 0 }; | 1645 * conf->upstream.hide_headers_hash = { NULL, 0 }; |
1643 * conf->upstream.hide_headers = NULL; | |
1644 * conf->upstream.pass_headers = NULL; | |
1645 * conf->upstream.schema = { 0, NULL }; | 1646 * conf->upstream.schema = { 0, NULL }; |
1646 * conf->upstream.uri = { 0, NULL }; | 1647 * conf->upstream.uri = { 0, NULL }; |
1647 * conf->upstream.location = NULL; | 1648 * conf->upstream.location = NULL; |
1648 * conf->upstream.store_lengths = NULL; | 1649 * conf->upstream.store_lengths = NULL; |
1649 * conf->upstream.store_values = NULL; | 1650 * conf->upstream.store_values = NULL; |
1669 conf->upstream.temp_file_write_size_conf = NGX_CONF_UNSET_SIZE; | 1670 conf->upstream.temp_file_write_size_conf = NGX_CONF_UNSET_SIZE; |
1670 | 1671 |
1671 conf->upstream.pass_request_headers = NGX_CONF_UNSET; | 1672 conf->upstream.pass_request_headers = NGX_CONF_UNSET; |
1672 conf->upstream.pass_request_body = NGX_CONF_UNSET; | 1673 conf->upstream.pass_request_body = NGX_CONF_UNSET; |
1673 | 1674 |
1675 conf->upstream.hide_headers = NGX_CONF_UNSET_PTR; | |
1676 conf->upstream.pass_headers = NGX_CONF_UNSET_PTR; | |
1677 | |
1674 conf->upstream.intercept_errors = NGX_CONF_UNSET; | 1678 conf->upstream.intercept_errors = NGX_CONF_UNSET; |
1675 | 1679 |
1676 /* "fastcgi_cyclic_temp_file" is disabled */ | 1680 /* "fastcgi_cyclic_temp_file" is disabled */ |
1677 conf->upstream.cyclic_temp_file = 0; | 1681 conf->upstream.cyclic_temp_file = 0; |
1678 | 1682 |
1689 ngx_http_fastcgi_loc_conf_t *conf = child; | 1693 ngx_http_fastcgi_loc_conf_t *conf = child; |
1690 | 1694 |
1691 u_char *p; | 1695 u_char *p; |
1692 size_t size; | 1696 size_t size; |
1693 uintptr_t *code; | 1697 uintptr_t *code; |
1694 ngx_str_t *header; | 1698 ngx_uint_t i; |
1695 ngx_uint_t i, j; | |
1696 ngx_array_t hide_headers; | |
1697 ngx_keyval_t *src; | 1699 ngx_keyval_t *src; |
1698 ngx_hash_key_t *hk; | |
1699 ngx_hash_init_t hash; | 1700 ngx_hash_init_t hash; |
1700 ngx_http_script_compile_t sc; | 1701 ngx_http_script_compile_t sc; |
1701 ngx_http_script_copy_code_t *copy; | 1702 ngx_http_script_copy_code_t *copy; |
1702 | 1703 |
1703 if (conf->upstream.store != 0) { | 1704 if (conf->upstream.store != 0) { |
1855 ngx_conf_merge_ptr_value(conf->catch_stderr, prev->catch_stderr, NULL); | 1856 ngx_conf_merge_ptr_value(conf->catch_stderr, prev->catch_stderr, NULL); |
1856 | 1857 |
1857 | 1858 |
1858 ngx_conf_merge_str_value(conf->index, prev->index, ""); | 1859 ngx_conf_merge_str_value(conf->index, prev->index, ""); |
1859 | 1860 |
1860 if (conf->upstream.hide_headers == NULL | 1861 hash.max_size = 512; |
1861 && conf->upstream.pass_headers == NULL) | 1862 hash.bucket_size = ngx_align(64, ngx_cacheline_size); |
1862 { | 1863 hash.name = "fastcgi_hide_headers_hash"; |
1863 conf->upstream.hide_headers = prev->upstream.hide_headers; | 1864 |
1864 conf->upstream.pass_headers = prev->upstream.pass_headers; | 1865 if (ngx_http_upstream_hide_headers_hash(cf, &conf->upstream, |
1865 conf->upstream.hide_headers_hash = prev->upstream.hide_headers_hash; | 1866 &prev->upstream, |
1866 | 1867 ngx_http_fastcgi_hide_headers, |
1867 if (conf->upstream.hide_headers_hash.buckets) { | 1868 &hash) |
1868 goto peers; | |
1869 } | |
1870 | |
1871 } else { | |
1872 if (conf->upstream.hide_headers == NULL) { | |
1873 conf->upstream.hide_headers = prev->upstream.hide_headers; | |
1874 } | |
1875 | |
1876 if (conf->upstream.pass_headers == NULL) { | |
1877 conf->upstream.pass_headers = prev->upstream.pass_headers; | |
1878 } | |
1879 } | |
1880 | |
1881 if (ngx_array_init(&hide_headers, cf->temp_pool, 4, sizeof(ngx_hash_key_t)) | |
1882 != NGX_OK) | 1869 != NGX_OK) |
1883 { | 1870 { |
1884 return NGX_CONF_ERROR; | 1871 return NGX_CONF_ERROR; |
1885 } | 1872 } |
1886 | |
1887 for (header = ngx_http_fastcgi_hide_headers; header->len; header++) { | |
1888 hk = ngx_array_push(&hide_headers); | |
1889 if (hk == NULL) { | |
1890 return NGX_CONF_ERROR; | |
1891 } | |
1892 | |
1893 hk->key = *header; | |
1894 hk->key_hash = ngx_hash_key_lc(header->data, header->len); | |
1895 hk->value = (void *) 1; | |
1896 } | |
1897 | |
1898 if (conf->upstream.hide_headers) { | |
1899 | |
1900 header = conf->upstream.hide_headers->elts; | |
1901 | |
1902 for (i = 0; i < conf->upstream.hide_headers->nelts; i++) { | |
1903 | |
1904 hk = hide_headers.elts; | |
1905 | |
1906 for (j = 0; j < hide_headers.nelts; j++) { | |
1907 if (ngx_strcasecmp(header[i].data, hk[j].key.data) == 0) { | |
1908 goto exist; | |
1909 } | |
1910 } | |
1911 | |
1912 hk = ngx_array_push(&hide_headers); | |
1913 if (hk == NULL) { | |
1914 return NGX_CONF_ERROR; | |
1915 } | |
1916 | |
1917 hk->key = header[i]; | |
1918 hk->key_hash = ngx_hash_key_lc(header[i].data, header[i].len); | |
1919 hk->value = (void *) 1; | |
1920 | |
1921 exist: | |
1922 | |
1923 continue; | |
1924 } | |
1925 } | |
1926 | |
1927 if (conf->upstream.pass_headers) { | |
1928 | |
1929 hk = hide_headers.elts; | |
1930 header = conf->upstream.pass_headers->elts; | |
1931 | |
1932 for (i = 0; i < conf->upstream.pass_headers->nelts; i++) { | |
1933 | |
1934 for (j = 0; j < hide_headers.nelts; j++) { | |
1935 | |
1936 if (hk[j].key.data == NULL) { | |
1937 continue; | |
1938 } | |
1939 | |
1940 if (ngx_strcasecmp(header[i].data, hk[j].key.data) == 0) { | |
1941 hk[j].key.data = NULL; | |
1942 break; | |
1943 } | |
1944 } | |
1945 } | |
1946 } | |
1947 | |
1948 hash.hash = &conf->upstream.hide_headers_hash; | |
1949 hash.key = ngx_hash_key_lc; | |
1950 hash.max_size = 512; | |
1951 hash.bucket_size = ngx_align(64, ngx_cacheline_size); | |
1952 hash.name = "fastcgi_hide_headers_hash"; | |
1953 hash.pool = cf->pool; | |
1954 hash.temp_pool = NULL; | |
1955 | |
1956 if (ngx_hash_init(&hash, hide_headers.elts, hide_headers.nelts) != NGX_OK) { | |
1957 return NGX_CONF_ERROR; | |
1958 } | |
1959 | |
1960 peers: | |
1961 | 1873 |
1962 if (conf->upstream.upstream == NULL) { | 1874 if (conf->upstream.upstream == NULL) { |
1963 conf->upstream.upstream = prev->upstream.upstream; | 1875 conf->upstream.upstream = prev->upstream.upstream; |
1964 conf->upstream.schema = prev->upstream.schema; | 1876 conf->upstream.schema = prev->upstream.schema; |
1965 } | 1877 } |