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 }