Mercurial > hg > nginx-quic
comparison src/http/modules/ngx_http_proxy_module.c @ 1990:c7757ce0ae97 stable-0.5
r1699, r1700, r1701, r1702, r1707 merge:
upstream parse_header fix and optimization,
fix fastcgi_catch_stderr segfault merged in r1524:
*) return NGX_HTTP_UPSTREAM_INVALID_HEADER for invalid status
*) return NGX_ERROR instead of NGX_HTTP_INTERNAL_SERVER_ERROR
in u->parse_header()
*) return NGX_HTTP_UPSTREAM_INVALID_HEADER instead of NGX_HTTP_BAD_GATEWAY
to go to a next upstream on invalid_header condition
*) now ngx_conf_set_str_array_slot() tests NGX_CONF_UNSET_PTR
this fixes fastcgi_catch_stderr segfault
*) ngx_http_upstream_hide_headers_hash()
*) proxy/fastcgi pass_header/hide_header use
ngx_http_upstream_hide_headers_hash()
author | Igor Sysoev <igor@sysoev.ru> |
---|---|
date | Sun, 04 May 2008 09:29:43 +0000 |
parents | 1e6101aca4bb |
children |
comparison
equal
deleted
inserted
replaced
1989:0ba9a893dd1a | 1990:c7757ce0ae97 |
---|---|
836 ngx_http_proxy_ctx_t *p; | 836 ngx_http_proxy_ctx_t *p; |
837 | 837 |
838 p = ngx_http_get_module_ctx(r, ngx_http_proxy_module); | 838 p = ngx_http_get_module_ctx(r, ngx_http_proxy_module); |
839 | 839 |
840 if (p == NULL) { | 840 if (p == NULL) { |
841 return NGX_HTTP_INTERNAL_SERVER_ERROR; | 841 return NGX_ERROR; |
842 } | 842 } |
843 | 843 |
844 rc = ngx_http_proxy_parse_status_line(r, p); | 844 rc = ngx_http_proxy_parse_status_line(r, p); |
845 | 845 |
846 if (rc == NGX_AGAIN) { | 846 if (rc == NGX_AGAIN) { |
871 | 871 |
872 u->headers_in.status_line.len = p->status_end - p->status_start; | 872 u->headers_in.status_line.len = p->status_end - p->status_start; |
873 u->headers_in.status_line.data = ngx_palloc(r->pool, | 873 u->headers_in.status_line.data = ngx_palloc(r->pool, |
874 u->headers_in.status_line.len); | 874 u->headers_in.status_line.len); |
875 if (u->headers_in.status_line.data == NULL) { | 875 if (u->headers_in.status_line.data == NULL) { |
876 return NGX_HTTP_INTERNAL_SERVER_ERROR; | 876 return NGX_ERROR; |
877 } | 877 } |
878 | 878 |
879 ngx_memcpy(u->headers_in.status_line.data, p->status_start, | 879 ngx_memcpy(u->headers_in.status_line.data, p->status_start, |
880 u->headers_in.status_line.len); | 880 u->headers_in.status_line.len); |
881 | 881 |
1115 | 1115 |
1116 /* a header line has been parsed successfully */ | 1116 /* a header line has been parsed successfully */ |
1117 | 1117 |
1118 h = ngx_list_push(&r->upstream->headers_in.headers); | 1118 h = ngx_list_push(&r->upstream->headers_in.headers); |
1119 if (h == NULL) { | 1119 if (h == NULL) { |
1120 return NGX_HTTP_INTERNAL_SERVER_ERROR; | 1120 return NGX_ERROR; |
1121 } | 1121 } |
1122 | 1122 |
1123 h->hash = r->header_hash; | 1123 h->hash = r->header_hash; |
1124 | 1124 |
1125 h->key.len = r->header_name_end - r->header_name_start; | 1125 h->key.len = r->header_name_end - r->header_name_start; |
1126 h->value.len = r->header_end - r->header_start; | 1126 h->value.len = r->header_end - r->header_start; |
1127 | 1127 |
1128 h->key.data = ngx_palloc(r->pool, | 1128 h->key.data = ngx_palloc(r->pool, |
1129 h->key.len + 1 + h->value.len + 1 + h->key.len); | 1129 h->key.len + 1 + h->value.len + 1 + h->key.len); |
1130 if (h->key.data == NULL) { | 1130 if (h->key.data == NULL) { |
1131 return NGX_HTTP_INTERNAL_SERVER_ERROR; | 1131 return NGX_ERROR; |
1132 } | 1132 } |
1133 | 1133 |
1134 h->value.data = h->key.data + h->key.len + 1; | 1134 h->value.data = h->key.data + h->key.len + 1; |
1135 h->lowcase_key = h->key.data + h->key.len + 1 + h->value.len + 1; | 1135 h->lowcase_key = h->key.data + h->key.len + 1 + h->value.len + 1; |
1136 | 1136 |
1148 | 1148 |
1149 hh = ngx_hash_find(&umcf->headers_in_hash, h->hash, | 1149 hh = ngx_hash_find(&umcf->headers_in_hash, h->hash, |
1150 h->lowcase_key, h->key.len); | 1150 h->lowcase_key, h->key.len); |
1151 | 1151 |
1152 if (hh && hh->handler(r, h, hh->offset) != NGX_OK) { | 1152 if (hh && hh->handler(r, h, hh->offset) != NGX_OK) { |
1153 return NGX_HTTP_INTERNAL_SERVER_ERROR; | 1153 return NGX_ERROR; |
1154 } | 1154 } |
1155 | 1155 |
1156 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, | 1156 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, |
1157 "http proxy header: \"%V: %V\"", | 1157 "http proxy header: \"%V: %V\"", |
1158 &h->key, &h->value); | 1158 &h->key, &h->value); |
1173 */ | 1173 */ |
1174 | 1174 |
1175 if (r->upstream->headers_in.server == NULL) { | 1175 if (r->upstream->headers_in.server == NULL) { |
1176 h = ngx_list_push(&r->upstream->headers_in.headers); | 1176 h = ngx_list_push(&r->upstream->headers_in.headers); |
1177 if (h == NULL) { | 1177 if (h == NULL) { |
1178 return NGX_HTTP_INTERNAL_SERVER_ERROR; | 1178 return NGX_ERROR; |
1179 } | 1179 } |
1180 | 1180 |
1181 h->hash = ngx_hash(ngx_hash(ngx_hash(ngx_hash( | 1181 h->hash = ngx_hash(ngx_hash(ngx_hash(ngx_hash( |
1182 ngx_hash('s', 'e'), 'r'), 'v'), 'e'), 'r'); | 1182 ngx_hash('s', 'e'), 'r'), 'v'), 'e'), 'r'); |
1183 | 1183 |
1189 } | 1189 } |
1190 | 1190 |
1191 if (r->upstream->headers_in.date == NULL) { | 1191 if (r->upstream->headers_in.date == NULL) { |
1192 h = ngx_list_push(&r->upstream->headers_in.headers); | 1192 h = ngx_list_push(&r->upstream->headers_in.headers); |
1193 if (h == NULL) { | 1193 if (h == NULL) { |
1194 return NGX_HTTP_INTERNAL_SERVER_ERROR; | 1194 return NGX_ERROR; |
1195 } | 1195 } |
1196 | 1196 |
1197 h->hash = ngx_hash(ngx_hash(ngx_hash('d', 'a'), 't'), 'e'); | 1197 h->hash = ngx_hash(ngx_hash(ngx_hash('d', 'a'), 't'), 'e'); |
1198 | 1198 |
1199 h->key.len = sizeof("Date") - 1; | 1199 h->key.len = sizeof("Date") - 1; |
1500 * | 1500 * |
1501 * conf->upstream.bufs.num = 0; | 1501 * conf->upstream.bufs.num = 0; |
1502 * conf->upstream.next_upstream = 0; | 1502 * conf->upstream.next_upstream = 0; |
1503 * conf->upstream.temp_path = NULL; | 1503 * conf->upstream.temp_path = NULL; |
1504 * conf->upstream.hide_headers_hash = { NULL, 0 }; | 1504 * conf->upstream.hide_headers_hash = { NULL, 0 }; |
1505 * conf->upstream.hide_headers = NULL; | |
1506 * conf->upstream.pass_headers = NULL; | |
1507 * conf->upstream.schema = { 0, NULL }; | 1505 * conf->upstream.schema = { 0, NULL }; |
1508 * conf->upstream.uri = { 0, NULL }; | 1506 * conf->upstream.uri = { 0, NULL }; |
1509 * conf->upstream.location = NULL; | 1507 * conf->upstream.location = NULL; |
1510 * conf->upstream.store_lengths = NULL; | 1508 * conf->upstream.store_lengths = NULL; |
1511 * conf->upstream.store_values = NULL; | 1509 * conf->upstream.store_values = NULL; |
1538 conf->upstream.temp_file_write_size_conf = NGX_CONF_UNSET_SIZE; | 1536 conf->upstream.temp_file_write_size_conf = NGX_CONF_UNSET_SIZE; |
1539 | 1537 |
1540 conf->upstream.pass_request_headers = NGX_CONF_UNSET; | 1538 conf->upstream.pass_request_headers = NGX_CONF_UNSET; |
1541 conf->upstream.pass_request_body = NGX_CONF_UNSET; | 1539 conf->upstream.pass_request_body = NGX_CONF_UNSET; |
1542 | 1540 |
1541 conf->upstream.hide_headers = NGX_CONF_UNSET_PTR; | |
1542 conf->upstream.pass_headers = NGX_CONF_UNSET_PTR; | |
1543 | |
1543 conf->upstream.intercept_errors = NGX_CONF_UNSET; | 1544 conf->upstream.intercept_errors = NGX_CONF_UNSET; |
1544 | 1545 |
1545 /* "proxy_cyclic_temp_file" is disabled */ | 1546 /* "proxy_cyclic_temp_file" is disabled */ |
1546 conf->upstream.cyclic_temp_file = 0; | 1547 conf->upstream.cyclic_temp_file = 0; |
1547 | 1548 |
1562 ngx_http_proxy_loc_conf_t *conf = child; | 1563 ngx_http_proxy_loc_conf_t *conf = child; |
1563 | 1564 |
1564 u_char *p; | 1565 u_char *p; |
1565 size_t size; | 1566 size_t size; |
1566 uintptr_t *code; | 1567 uintptr_t *code; |
1567 ngx_str_t *header; | 1568 ngx_uint_t i; |
1568 ngx_uint_t i, j; | |
1569 ngx_array_t hide_headers; | |
1570 ngx_keyval_t *src, *s, *h; | 1569 ngx_keyval_t *src, *s, *h; |
1571 ngx_hash_key_t *hk; | 1570 ngx_hash_key_t *hk; |
1572 ngx_hash_init_t hash; | 1571 ngx_hash_init_t hash; |
1573 ngx_http_proxy_redirect_t *pr; | 1572 ngx_http_proxy_redirect_t *pr; |
1574 ngx_http_script_compile_t sc; | 1573 ngx_http_script_compile_t sc; |
1773 prev->headers_hash_bucket_size, 64); | 1772 prev->headers_hash_bucket_size, 64); |
1774 | 1773 |
1775 conf->headers_hash_bucket_size = ngx_align(conf->headers_hash_bucket_size, | 1774 conf->headers_hash_bucket_size = ngx_align(conf->headers_hash_bucket_size, |
1776 ngx_cacheline_size); | 1775 ngx_cacheline_size); |
1777 | 1776 |
1778 if (conf->upstream.hide_headers == NULL | 1777 hash.max_size = conf->headers_hash_max_size; |
1779 && conf->upstream.pass_headers == NULL) | 1778 hash.bucket_size = conf->headers_hash_bucket_size; |
1780 { | 1779 hash.name = "proxy_headers_hash"; |
1781 conf->upstream.hide_headers = prev->upstream.hide_headers; | 1780 |
1782 conf->upstream.pass_headers = prev->upstream.pass_headers; | 1781 if (ngx_http_upstream_hide_headers_hash(cf, &conf->upstream, |
1783 conf->upstream.hide_headers_hash = prev->upstream.hide_headers_hash; | 1782 &prev->upstream, |
1784 | 1783 ngx_http_proxy_hide_headers, &hash) |
1785 if (conf->upstream.hide_headers_hash.buckets) { | |
1786 goto peers; | |
1787 } | |
1788 | |
1789 } else { | |
1790 if (conf->upstream.hide_headers == NULL) { | |
1791 conf->upstream.hide_headers = prev->upstream.hide_headers; | |
1792 } | |
1793 | |
1794 if (conf->upstream.pass_headers == NULL) { | |
1795 conf->upstream.pass_headers = prev->upstream.pass_headers; | |
1796 } | |
1797 } | |
1798 | |
1799 if (ngx_array_init(&hide_headers, cf->temp_pool, 4, sizeof(ngx_hash_key_t)) | |
1800 != NGX_OK) | 1784 != NGX_OK) |
1801 { | 1785 { |
1802 return NGX_CONF_ERROR; | 1786 return NGX_CONF_ERROR; |
1803 } | 1787 } |
1804 | |
1805 for (header = ngx_http_proxy_hide_headers; header->len; header++) { | |
1806 hk = ngx_array_push(&hide_headers); | |
1807 if (hk == NULL) { | |
1808 return NGX_CONF_ERROR; | |
1809 } | |
1810 | |
1811 hk->key = *header; | |
1812 hk->key_hash = ngx_hash_key_lc(header->data, header->len); | |
1813 hk->value = (void *) 1; | |
1814 } | |
1815 | |
1816 if (conf->upstream.hide_headers) { | |
1817 | |
1818 header = conf->upstream.hide_headers->elts; | |
1819 | |
1820 for (i = 0; i < conf->upstream.hide_headers->nelts; i++) { | |
1821 | |
1822 hk = hide_headers.elts; | |
1823 | |
1824 for (j = 0; j < hide_headers.nelts; j++) { | |
1825 if (ngx_strcasecmp(header[i].data, hk[j].key.data) == 0) { | |
1826 goto exist; | |
1827 } | |
1828 } | |
1829 | |
1830 hk = ngx_array_push(&hide_headers); | |
1831 if (hk == NULL) { | |
1832 return NGX_CONF_ERROR; | |
1833 } | |
1834 | |
1835 hk->key = header[i]; | |
1836 hk->key_hash = ngx_hash_key_lc(header[i].data, header[i].len); | |
1837 hk->value = (void *) 1; | |
1838 | |
1839 exist: | |
1840 | |
1841 continue; | |
1842 } | |
1843 } | |
1844 | |
1845 if (conf->upstream.pass_headers) { | |
1846 | |
1847 hk = hide_headers.elts; | |
1848 header = conf->upstream.pass_headers->elts; | |
1849 | |
1850 for (i = 0; i < conf->upstream.pass_headers->nelts; i++) { | |
1851 for (j = 0; j < hide_headers.nelts; j++) { | |
1852 | |
1853 if (hk[j].key.data == NULL) { | |
1854 continue; | |
1855 } | |
1856 | |
1857 if (ngx_strcasecmp(header[i].data, hk[j].key.data) == 0) { | |
1858 hk[j].key.data = NULL; | |
1859 break; | |
1860 } | |
1861 } | |
1862 } | |
1863 } | |
1864 | |
1865 hash.hash = &conf->upstream.hide_headers_hash; | |
1866 hash.key = ngx_hash_key_lc; | |
1867 hash.max_size = conf->headers_hash_max_size; | |
1868 hash.bucket_size = conf->headers_hash_bucket_size; | |
1869 hash.name = "proxy_headers_hash"; | |
1870 hash.pool = cf->pool; | |
1871 hash.temp_pool = NULL; | |
1872 | |
1873 if (ngx_hash_init(&hash, hide_headers.elts, hide_headers.nelts) != NGX_OK) { | |
1874 return NGX_CONF_ERROR; | |
1875 } | |
1876 | |
1877 peers: | |
1878 | 1788 |
1879 if (conf->upstream.upstream == NULL) { | 1789 if (conf->upstream.upstream == NULL) { |
1880 conf->upstream.upstream = prev->upstream.upstream; | 1790 conf->upstream.upstream = prev->upstream.upstream; |
1881 | 1791 |
1882 conf->host_header = prev->host_header; | 1792 conf->host_header = prev->host_header; |