comparison src/http/modules/ngx_http_fastcgi_module.c @ 332:2eea67ed0bc2 NGINX_0_5_36

nginx 0.5.36 *) Bugfix: the "sub_filter" directive might set text to change into output. *) Bugfix: a segmentation fault occurred in worker process, if empty stub block was used second time in SSI. *) Bugfix: the "proxy_store" and "fastcgi_store" directives did not check a response length. *) Bugfix: nginx issued the bogus error message "SSL_shutdown() failed (SSL: )"; bug appeared in 0.5.35. *) Bugfix: in HTTPS mode requests might fail with the "bad write retry" error; bug appeared in 0.5.35. *) 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.5.32. Thanks to Manlio Perillo.
author Igor Sysoev <http://sysoev.ru>
date Sun, 04 May 2008 00:00:00 +0400
parents 26ff8d6b618d
children
comparison
equal deleted inserted replaced
331:27fb10cee3fd 332:2eea67ed0bc2
883 umcf = ngx_http_get_module_main_conf(r, ngx_http_upstream_module); 883 umcf = ngx_http_get_module_main_conf(r, ngx_http_upstream_module);
884 884
885 if (f == NULL) { 885 if (f == NULL) {
886 f = ngx_pcalloc(r->pool, sizeof(ngx_http_fastcgi_ctx_t)); 886 f = ngx_pcalloc(r->pool, sizeof(ngx_http_fastcgi_ctx_t));
887 if (f == NULL) { 887 if (f == NULL) {
888 return NGX_HTTP_INTERNAL_SERVER_ERROR; 888 return NGX_ERROR;
889 } 889 }
890 890
891 ngx_http_set_ctx(r, f, ngx_http_fastcgi_module); 891 ngx_http_set_ctx(r, f, ngx_http_fastcgi_module);
892 } 892 }
893 893
991 991
992 line.data[line.len - 1] = '\0'; 992 line.data[line.len - 1] = '\0';
993 993
994 for (i = 0; i < flcf->catch_stderr->nelts; i++) { 994 for (i = 0; i < flcf->catch_stderr->nelts; i++) {
995 if (ngx_strstr(line.data, pattern[i].data)) { 995 if (ngx_strstr(line.data, pattern[i].data)) {
996 return NGX_HTTP_BAD_GATEWAY; 996 return NGX_HTTP_UPSTREAM_INVALID_HEADER;
997 } 997 }
998 } 998 }
999 } 999 }
1000 1000
1001 if (u->buffer.pos == u->buffer.last) { 1001 if (u->buffer.pos == u->buffer.last) {
1059 1059
1060 /* a header line has been parsed successfully */ 1060 /* a header line has been parsed successfully */
1061 1061
1062 h = ngx_list_push(&u->headers_in.headers); 1062 h = ngx_list_push(&u->headers_in.headers);
1063 if (h == NULL) { 1063 if (h == NULL) {
1064 return NGX_HTTP_INTERNAL_SERVER_ERROR; 1064 return NGX_ERROR;
1065 } 1065 }
1066 1066
1067 if (f->split_parts && f->split_parts->nelts) { 1067 if (f->split_parts && f->split_parts->nelts) {
1068 1068
1069 part = f->split_parts->elts; 1069 part = f->split_parts->elts;
1073 size += part[i].end - part[i].start; 1073 size += part[i].end - part[i].start;
1074 } 1074 }
1075 1075
1076 p = ngx_palloc(r->pool, size); 1076 p = ngx_palloc(r->pool, size);
1077 if (p == NULL) { 1077 if (p == NULL) {
1078 return NGX_HTTP_INTERNAL_SERVER_ERROR; 1078 return NGX_ERROR;
1079 } 1079 }
1080 1080
1081 buf.pos = p; 1081 buf.pos = p;
1082 1082
1083 for (i = 0; i < f->split_parts->nelts; i++) { 1083 for (i = 0; i < f->split_parts->nelts; i++) {
1101 h->value.data = r->header_start; 1101 h->value.data = r->header_start;
1102 h->value.data[h->value.len] = '\0'; 1102 h->value.data[h->value.len] = '\0';
1103 1103
1104 h->lowcase_key = ngx_palloc(r->pool, h->key.len); 1104 h->lowcase_key = ngx_palloc(r->pool, h->key.len);
1105 if (h->lowcase_key == NULL) { 1105 if (h->lowcase_key == NULL) {
1106 return NGX_HTTP_INTERNAL_SERVER_ERROR; 1106 return NGX_ERROR;
1107 } 1107 }
1108 1108
1109 } else { 1109 } else {
1110 1110
1111 h->key.len = r->header_name_end - r->header_name_start; 1111 h->key.len = r->header_name_end - r->header_name_start;
1113 1113
1114 h->key.data = ngx_palloc(r->pool, 1114 h->key.data = ngx_palloc(r->pool,
1115 h->key.len + 1 + h->value.len + 1 1115 h->key.len + 1 + h->value.len + 1
1116 + h->key.len); 1116 + h->key.len);
1117 if (h->key.data == NULL) { 1117 if (h->key.data == NULL) {
1118 return NGX_HTTP_INTERNAL_SERVER_ERROR; 1118 return NGX_ERROR;
1119 } 1119 }
1120 1120
1121 h->value.data = h->key.data + h->key.len + 1; 1121 h->value.data = h->key.data + h->key.len + 1;
1122 h->lowcase_key = h->key.data + h->key.len + 1 1122 h->lowcase_key = h->key.data + h->key.len + 1
1123 + h->value.len + 1; 1123 + h->value.len + 1;
1141 1141
1142 hh = ngx_hash_find(&umcf->headers_in_hash, h->hash, 1142 hh = ngx_hash_find(&umcf->headers_in_hash, h->hash,
1143 h->lowcase_key, h->key.len); 1143 h->lowcase_key, h->key.len);
1144 1144
1145 if (hh && hh->handler(r, h, hh->offset) != NGX_OK) { 1145 if (hh && hh->handler(r, h, hh->offset) != NGX_OK) {
1146 return NGX_HTTP_INTERNAL_SERVER_ERROR; 1146 return NGX_ERROR;
1147 } 1147 }
1148 1148
1149 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, 1149 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
1150 "http fastcgi header: \"%V: %V\"", 1150 "http fastcgi header: \"%V: %V\"",
1151 &h->key, &h->value); 1151 &h->key, &h->value);
1170 status_line = &u->headers_in.status->value; 1170 status_line = &u->headers_in.status->value;
1171 1171
1172 status = ngx_atoi(status_line->data, 3); 1172 status = ngx_atoi(status_line->data, 3);
1173 1173
1174 if (status == NGX_ERROR) { 1174 if (status == NGX_ERROR) {
1175 return NGX_HTTP_INTERNAL_SERVER_ERROR; 1175 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
1176 "upstream sent invalid status \"%V\"",
1177 status_line);
1178 return NGX_HTTP_UPSTREAM_INVALID_HEADER;
1176 } 1179 }
1177 1180
1178 u->headers_in.status_n = status; 1181 u->headers_in.status_n = status;
1179 u->headers_in.status_line = *status_line; 1182 u->headers_in.status_line = *status_line;
1180 1183
1231 1234
1232 if (f->split_parts == NULL) { 1235 if (f->split_parts == NULL) {
1233 f->split_parts = ngx_array_create(r->pool, 1, 1236 f->split_parts = ngx_array_create(r->pool, 1,
1234 sizeof(ngx_http_fastcgi_split_part_t)); 1237 sizeof(ngx_http_fastcgi_split_part_t));
1235 if (f->split_parts == NULL) { 1238 if (f->split_parts == NULL) {
1236 return NGX_HTTP_INTERNAL_SERVER_ERROR; 1239 return NGX_ERROR;
1237 } 1240 }
1238 } 1241 }
1239 1242
1240 part = ngx_array_push(f->split_parts); 1243 part = ngx_array_push(f->split_parts);
1241 1244
1636 * 1639 *
1637 * conf->upstream.bufs.num = 0; 1640 * conf->upstream.bufs.num = 0;
1638 * conf->upstream.next_upstream = 0; 1641 * conf->upstream.next_upstream = 0;
1639 * conf->upstream.temp_path = NULL; 1642 * conf->upstream.temp_path = NULL;
1640 * conf->upstream.hide_headers_hash = { NULL, 0 }; 1643 * conf->upstream.hide_headers_hash = { NULL, 0 };
1641 * conf->upstream.hide_headers = NULL;
1642 * conf->upstream.pass_headers = NULL;
1643 * conf->upstream.schema = { 0, NULL }; 1644 * conf->upstream.schema = { 0, NULL };
1644 * conf->upstream.uri = { 0, NULL }; 1645 * conf->upstream.uri = { 0, NULL };
1645 * conf->upstream.location = NULL; 1646 * conf->upstream.location = NULL;
1646 * conf->upstream.store_lengths = NULL; 1647 * conf->upstream.store_lengths = NULL;
1647 * conf->upstream.store_values = NULL; 1648 * conf->upstream.store_values = NULL;
1667 conf->upstream.temp_file_write_size_conf = NGX_CONF_UNSET_SIZE; 1668 conf->upstream.temp_file_write_size_conf = NGX_CONF_UNSET_SIZE;
1668 1669
1669 conf->upstream.pass_request_headers = NGX_CONF_UNSET; 1670 conf->upstream.pass_request_headers = NGX_CONF_UNSET;
1670 conf->upstream.pass_request_body = NGX_CONF_UNSET; 1671 conf->upstream.pass_request_body = NGX_CONF_UNSET;
1671 1672
1673 conf->upstream.hide_headers = NGX_CONF_UNSET_PTR;
1674 conf->upstream.pass_headers = NGX_CONF_UNSET_PTR;
1675
1672 conf->upstream.intercept_errors = NGX_CONF_UNSET; 1676 conf->upstream.intercept_errors = NGX_CONF_UNSET;
1673 1677
1674 /* "fastcgi_cyclic_temp_file" is disabled */ 1678 /* "fastcgi_cyclic_temp_file" is disabled */
1675 conf->upstream.cyclic_temp_file = 0; 1679 conf->upstream.cyclic_temp_file = 0;
1676 1680
1687 ngx_http_fastcgi_loc_conf_t *conf = child; 1691 ngx_http_fastcgi_loc_conf_t *conf = child;
1688 1692
1689 u_char *p; 1693 u_char *p;
1690 size_t size; 1694 size_t size;
1691 uintptr_t *code; 1695 uintptr_t *code;
1692 ngx_str_t *header; 1696 ngx_uint_t i;
1693 ngx_uint_t i, j;
1694 ngx_array_t hide_headers;
1695 ngx_keyval_t *src; 1697 ngx_keyval_t *src;
1696 ngx_hash_key_t *hk;
1697 ngx_hash_init_t hash; 1698 ngx_hash_init_t hash;
1698 ngx_http_script_compile_t sc; 1699 ngx_http_script_compile_t sc;
1699 ngx_http_script_copy_code_t *copy; 1700 ngx_http_script_copy_code_t *copy;
1700 1701
1701 if (conf->upstream.store != 0) { 1702 if (conf->upstream.store != 0) {
1853 ngx_conf_merge_ptr_value(conf->catch_stderr, prev->catch_stderr, NULL); 1854 ngx_conf_merge_ptr_value(conf->catch_stderr, prev->catch_stderr, NULL);
1854 1855
1855 1856
1856 ngx_conf_merge_str_value(conf->index, prev->index, ""); 1857 ngx_conf_merge_str_value(conf->index, prev->index, "");
1857 1858
1858 if (conf->upstream.hide_headers == NULL 1859 hash.max_size = 512;
1859 && conf->upstream.pass_headers == NULL) 1860 hash.bucket_size = ngx_align(64, ngx_cacheline_size);
1860 { 1861 hash.name = "fastcgi_hide_headers_hash";
1861 conf->upstream.hide_headers = prev->upstream.hide_headers; 1862
1862 conf->upstream.pass_headers = prev->upstream.pass_headers; 1863 if (ngx_http_upstream_hide_headers_hash(cf, &conf->upstream,
1863 conf->upstream.hide_headers_hash = prev->upstream.hide_headers_hash; 1864 &prev->upstream,
1864 1865 ngx_http_fastcgi_hide_headers,
1865 if (conf->upstream.hide_headers_hash.buckets) { 1866 &hash)
1866 goto peers;
1867 }
1868
1869 } else {
1870 if (conf->upstream.hide_headers == NULL) {
1871 conf->upstream.hide_headers = prev->upstream.hide_headers;
1872 }
1873
1874 if (conf->upstream.pass_headers == NULL) {
1875 conf->upstream.pass_headers = prev->upstream.pass_headers;
1876 }
1877 }
1878
1879 if (ngx_array_init(&hide_headers, cf->temp_pool, 4, sizeof(ngx_hash_key_t))
1880 != NGX_OK) 1867 != NGX_OK)
1881 { 1868 {
1882 return NGX_CONF_ERROR; 1869 return NGX_CONF_ERROR;
1883 } 1870 }
1884
1885 for (header = ngx_http_fastcgi_hide_headers; header->len; header++) {
1886 hk = ngx_array_push(&hide_headers);
1887 if (hk == NULL) {
1888 return NGX_CONF_ERROR;
1889 }
1890
1891 hk->key = *header;
1892 hk->key_hash = ngx_hash_key_lc(header->data, header->len);
1893 hk->value = (void *) 1;
1894 }
1895
1896 if (conf->upstream.hide_headers) {
1897
1898 header = conf->upstream.hide_headers->elts;
1899
1900 for (i = 0; i < conf->upstream.hide_headers->nelts; i++) {
1901
1902 hk = hide_headers.elts;
1903
1904 for (j = 0; j < hide_headers.nelts; j++) {
1905 if (ngx_strcasecmp(header[i].data, hk[j].key.data) == 0) {
1906 goto exist;
1907 }
1908 }
1909
1910 hk = ngx_array_push(&hide_headers);
1911 if (hk == NULL) {
1912 return NGX_CONF_ERROR;
1913 }
1914
1915 hk->key = header[i];
1916 hk->key_hash = ngx_hash_key_lc(header[i].data, header[i].len);
1917 hk->value = (void *) 1;
1918
1919 exist:
1920
1921 continue;
1922 }
1923 }
1924
1925 if (conf->upstream.pass_headers) {
1926
1927 hk = hide_headers.elts;
1928 header = conf->upstream.pass_headers->elts;
1929
1930 for (i = 0; i < conf->upstream.pass_headers->nelts; i++) {
1931
1932 for (j = 0; j < hide_headers.nelts; j++) {
1933
1934 if (hk[j].key.data == NULL) {
1935 continue;
1936 }
1937
1938 if (ngx_strcasecmp(header[i].data, hk[j].key.data) == 0) {
1939 hk[j].key.data = NULL;
1940 break;
1941 }
1942 }
1943 }
1944 }
1945
1946 hash.hash = &conf->upstream.hide_headers_hash;
1947 hash.key = ngx_hash_key_lc;
1948 hash.max_size = 512;
1949 hash.bucket_size = ngx_align(64, ngx_cacheline_size);
1950 hash.name = "fastcgi_hide_headers_hash";
1951 hash.pool = cf->pool;
1952 hash.temp_pool = NULL;
1953
1954 if (ngx_hash_init(&hash, hide_headers.elts, hide_headers.nelts) != NGX_OK) {
1955 return NGX_CONF_ERROR;
1956 }
1957
1958 peers:
1959 1871
1960 if (conf->upstream.upstream == NULL) { 1872 if (conf->upstream.upstream == NULL) {
1961 conf->upstream.upstream = prev->upstream.upstream; 1873 conf->upstream.upstream = prev->upstream.upstream;
1962 conf->upstream.schema = prev->upstream.schema; 1874 conf->upstream.schema = prev->upstream.schema;
1963 } 1875 }