Mercurial > hg > nginx-ranges
comparison src/http/modules/ngx_http_fastcgi_module.c @ 198:e6da4931e0e0 NGINX_0_3_46
nginx 0.3.46
*) Feature: the "proxy_hide_header", "proxy_pass_header",
"fastcgi_hide_header", and "fastcgi_pass_header" directives.
*) Change: the "proxy_pass_x_powered_by", "fastcgi_x_powered_by", and
"proxy_pass_server" directives were canceled.
*) Feature: the "X-Accel-Buffering" response header line is supported
in proxy mode.
*) Bugfix: the reconfiguration bug and memory leaks in the
ngx_http_perl_module.
author | Igor Sysoev <http://sysoev.ru> |
---|---|
date | Thu, 11 May 2006 00:00:00 +0400 |
parents | af37b7cb6698 |
children | d2ae1c9f1fd3 |
comparison
equal
deleted
inserted
replaced
197:93658b91fad2 | 198:e6da4931e0e0 |
---|---|
244 ngx_conf_set_flag_slot, | 244 ngx_conf_set_flag_slot, |
245 NGX_HTTP_LOC_CONF_OFFSET, | 245 NGX_HTTP_LOC_CONF_OFFSET, |
246 offsetof(ngx_http_fastcgi_loc_conf_t, upstream.redirect_errors), | 246 offsetof(ngx_http_fastcgi_loc_conf_t, upstream.redirect_errors), |
247 NULL }, | 247 NULL }, |
248 | 248 |
249 { ngx_string("fastcgi_x_powered_by"), | |
250 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG, | |
251 ngx_conf_set_flag_slot, | |
252 NGX_HTTP_LOC_CONF_OFFSET, | |
253 offsetof(ngx_http_fastcgi_loc_conf_t, upstream.pass_x_powered_by), | |
254 NULL }, | |
255 | |
256 { ngx_string("fastcgi_read_timeout"), | 249 { ngx_string("fastcgi_read_timeout"), |
257 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, | 250 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, |
258 ngx_conf_set_msec_slot, | 251 ngx_conf_set_msec_slot, |
259 NGX_HTTP_LOC_CONF_OFFSET, | 252 NGX_HTTP_LOC_CONF_OFFSET, |
260 offsetof(ngx_http_fastcgi_loc_conf_t, upstream.read_timeout), | 253 offsetof(ngx_http_fastcgi_loc_conf_t, upstream.read_timeout), |
316 offsetof(ngx_http_fastcgi_loc_conf_t, upstream.fail_timeout), | 309 offsetof(ngx_http_fastcgi_loc_conf_t, upstream.fail_timeout), |
317 NULL }, | 310 NULL }, |
318 | 311 |
319 { ngx_string("fastcgi_param"), | 312 { ngx_string("fastcgi_param"), |
320 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE2, | 313 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE2, |
321 ngx_conf_set_table_elt_slot, | 314 ngx_conf_set_keyval_slot, |
322 NGX_HTTP_LOC_CONF_OFFSET, | 315 NGX_HTTP_LOC_CONF_OFFSET, |
323 offsetof(ngx_http_fastcgi_loc_conf_t, params_source), | 316 offsetof(ngx_http_fastcgi_loc_conf_t, params_source), |
317 NULL }, | |
318 | |
319 { ngx_string("fastcgi_pass_header"), | |
320 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG, | |
321 ngx_conf_set_str_array_slot, | |
322 NGX_HTTP_LOC_CONF_OFFSET, | |
323 offsetof(ngx_http_fastcgi_loc_conf_t, upstream.pass_headers), | |
324 NULL }, | |
325 | |
326 { ngx_string("fastcgi_hide_header"), | |
327 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG, | |
328 ngx_conf_set_str_array_slot, | |
329 NGX_HTTP_LOC_CONF_OFFSET, | |
330 offsetof(ngx_http_fastcgi_loc_conf_t, upstream.hide_headers), | |
324 NULL }, | 331 NULL }, |
325 | 332 |
326 ngx_null_command | 333 ngx_null_command |
327 }; | 334 }; |
328 | 335 |
356 NULL, /* exit master */ | 363 NULL, /* exit master */ |
357 NGX_MODULE_V1_PADDING | 364 NGX_MODULE_V1_PADDING |
358 }; | 365 }; |
359 | 366 |
360 | 367 |
368 static ngx_str_t ngx_http_fastcgi_hide_headers[] = { | |
369 ngx_string("Status"), | |
370 ngx_string("X-Accel-Expires"), | |
371 ngx_string("X-Accel-Redirect"), | |
372 ngx_string("X-Accel-Limit-Rate"), | |
373 ngx_string("X-Accel-Buffer"), | |
374 ngx_null_string | |
375 }; | |
376 | |
377 | |
361 static ngx_int_t | 378 static ngx_int_t |
362 ngx_http_fastcgi_handler(ngx_http_request_t *r) | 379 ngx_http_fastcgi_handler(ngx_http_request_t *r) |
363 { | 380 { |
364 ngx_int_t rc; | 381 ngx_int_t rc; |
365 ngx_http_upstream_t *u; | 382 ngx_http_upstream_t *u; |
387 u->create_request = ngx_http_fastcgi_create_request; | 404 u->create_request = ngx_http_fastcgi_create_request; |
388 u->reinit_request = ngx_http_fastcgi_reinit_request; | 405 u->reinit_request = ngx_http_fastcgi_reinit_request; |
389 u->process_header = ngx_http_fastcgi_process_header; | 406 u->process_header = ngx_http_fastcgi_process_header; |
390 u->abort_request = ngx_http_fastcgi_abort_request; | 407 u->abort_request = ngx_http_fastcgi_abort_request; |
391 u->finalize_request = ngx_http_fastcgi_finalize_request; | 408 u->finalize_request = ngx_http_fastcgi_finalize_request; |
409 | |
410 u->buffering = 1; | |
392 | 411 |
393 u->pipe = ngx_pcalloc(r->pool, sizeof(ngx_event_pipe_t)); | 412 u->pipe = ngx_pcalloc(r->pool, sizeof(ngx_event_pipe_t)); |
394 if (u->pipe == NULL) { | 413 if (u->pipe == NULL) { |
395 return NGX_HTTP_INTERNAL_SERVER_ERROR; | 414 return NGX_HTTP_INTERNAL_SERVER_ERROR; |
396 } | 415 } |
794 ngx_http_fastcgi_process_header(ngx_http_request_t *r) | 813 ngx_http_fastcgi_process_header(ngx_http_request_t *r) |
795 { | 814 { |
796 u_char *start, *last; | 815 u_char *start, *last; |
797 ngx_str_t *status_line, line; | 816 ngx_str_t *status_line, line; |
798 ngx_int_t rc, status; | 817 ngx_int_t rc, status; |
799 ngx_uint_t key; | 818 ngx_uint_t i; |
800 ngx_table_elt_t *h; | 819 ngx_table_elt_t *h; |
801 ngx_http_upstream_t *u; | 820 ngx_http_upstream_t *u; |
802 ngx_http_fastcgi_ctx_t *f; | 821 ngx_http_fastcgi_ctx_t *f; |
803 ngx_http_upstream_header_t *hh; | 822 ngx_http_upstream_header_t *hh; |
804 ngx_http_upstream_main_conf_t *umcf; | 823 ngx_http_upstream_main_conf_t *umcf; |
805 | 824 |
806 f = ngx_http_get_module_ctx(r, ngx_http_fastcgi_module); | 825 f = ngx_http_get_module_ctx(r, ngx_http_fastcgi_module); |
807 | 826 |
808 umcf = ngx_http_get_module_main_conf(r, ngx_http_upstream_module); | 827 umcf = ngx_http_get_module_main_conf(r, ngx_http_upstream_module); |
809 hh = (ngx_http_upstream_header_t *) umcf->headers_in_hash.buckets; | |
810 | 828 |
811 if (f == NULL) { | 829 if (f == NULL) { |
812 f = ngx_pcalloc(r->pool, sizeof(ngx_http_fastcgi_ctx_t)); | 830 f = ngx_pcalloc(r->pool, sizeof(ngx_http_fastcgi_ctx_t)); |
813 if (f == NULL) { | 831 if (f == NULL) { |
814 return NGX_HTTP_INTERNAL_SERVER_ERROR; | 832 return NGX_HTTP_INTERNAL_SERVER_ERROR; |
978 | 996 |
979 h->key.len = r->header_name_end - r->header_name_start; | 997 h->key.len = r->header_name_end - r->header_name_start; |
980 h->value.len = r->header_end - r->header_start; | 998 h->value.len = r->header_end - r->header_start; |
981 | 999 |
982 h->key.data = ngx_palloc(r->pool, | 1000 h->key.data = ngx_palloc(r->pool, |
983 h->key.len + 1 + h->value.len + 1); | 1001 h->key.len + 1 + h->value.len + 1 + h->key.len); |
984 if (h->key.data == NULL) { | 1002 if (h->key.data == NULL) { |
985 return NGX_HTTP_INTERNAL_SERVER_ERROR; | 1003 return NGX_HTTP_INTERNAL_SERVER_ERROR; |
986 } | 1004 } |
987 | 1005 |
988 h->value.data = h->key.data + h->key.len + 1; | 1006 h->value.data = h->key.data + h->key.len + 1; |
1007 h->lowcase_key = h->key.data + h->key.len + 1 | |
1008 + h->value.len + 1; | |
989 | 1009 |
990 ngx_cpystrn(h->key.data, r->header_name_start, h->key.len + 1); | 1010 ngx_cpystrn(h->key.data, r->header_name_start, h->key.len + 1); |
991 ngx_cpystrn(h->value.data, r->header_start, h->value.len + 1); | 1011 ngx_cpystrn(h->value.data, r->header_start, h->value.len + 1); |
992 | 1012 |
993 key = h->hash % umcf->headers_in_hash.hash_size; | 1013 if (h->key.len == r->lowcase_index) { |
994 | 1014 ngx_memcpy(h->lowcase_key, r->lowcase_header, h->key.len); |
995 if (hh[key].name.len == h->key.len | 1015 |
996 && ngx_strcasecmp(hh[key].name.data, h->key.data) == 0) | 1016 } else { |
997 { | 1017 for (i = 0; i < h->key.len; i++) { |
998 if (hh[key].handler(r, h, hh[key].offset) != NGX_OK) { | 1018 h->lowcase_key[i] = ngx_tolower(h->lowcase_key[i]); |
999 return NGX_HTTP_INTERNAL_SERVER_ERROR; | |
1000 } | 1019 } |
1020 } | |
1021 | |
1022 hh = ngx_hash_find(&umcf->headers_in_hash, h->hash, | |
1023 h->lowcase_key, h->key.len); | |
1024 | |
1025 if (hh && hh->handler(r, h, hh->offset) != NGX_OK) { | |
1026 return NGX_HTTP_INTERNAL_SERVER_ERROR; | |
1001 } | 1027 } |
1002 | 1028 |
1003 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, | 1029 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, |
1004 "http fastcgi header: \"%V: %V\"", | 1030 "http fastcgi header: \"%V: %V\"", |
1005 &h->key, &h->value); | 1031 &h->key, &h->value); |
1472 | 1498 |
1473 /* | 1499 /* |
1474 * set by ngx_pcalloc(): | 1500 * set by ngx_pcalloc(): |
1475 * | 1501 * |
1476 * conf->upstream.bufs.num = 0; | 1502 * conf->upstream.bufs.num = 0; |
1477 * conf->upstream.path = NULL; | |
1478 * conf->upstream.next_upstream = 0; | 1503 * conf->upstream.next_upstream = 0; |
1479 * conf->upstream.temp_path = NULL; | 1504 * conf->upstream.temp_path = NULL; |
1505 * conf->upstream.hide_headers_hash = { NULL, 0 }; | |
1506 * conf->upstream.hide_headers = NULL; | |
1507 * conf->upstream.pass_headers = NULL; | |
1480 * conf->upstream.schema = { 0, NULL }; | 1508 * conf->upstream.schema = { 0, NULL }; |
1481 * conf->upstream.uri = { 0, NULL }; | 1509 * conf->upstream.uri = { 0, NULL }; |
1482 * conf->upstream.location = NULL; | 1510 * conf->upstream.location = NULL; |
1483 * | 1511 * |
1484 * conf->index.len = 0; | 1512 * conf->index.len = 0; |
1508 conf->upstream.redirect_errors = NGX_CONF_UNSET; | 1536 conf->upstream.redirect_errors = NGX_CONF_UNSET; |
1509 | 1537 |
1510 /* "fastcgi_cyclic_temp_file" is disabled */ | 1538 /* "fastcgi_cyclic_temp_file" is disabled */ |
1511 conf->upstream.cyclic_temp_file = 0; | 1539 conf->upstream.cyclic_temp_file = 0; |
1512 | 1540 |
1513 conf->upstream.pass_x_powered_by = NGX_CONF_UNSET; | |
1514 | |
1515 /* the hardcoded values */ | |
1516 conf->upstream.pass_server = 1; | |
1517 conf->upstream.pass_date = 1; | |
1518 | |
1519 return conf; | 1541 return conf; |
1520 } | 1542 } |
1521 | 1543 |
1522 | 1544 |
1523 static char * | 1545 static char * |
1527 ngx_http_fastcgi_loc_conf_t *conf = child; | 1549 ngx_http_fastcgi_loc_conf_t *conf = child; |
1528 | 1550 |
1529 u_char *p; | 1551 u_char *p; |
1530 size_t size; | 1552 size_t size; |
1531 uintptr_t *code; | 1553 uintptr_t *code; |
1532 ngx_uint_t i; | 1554 ngx_str_t *header; |
1533 ngx_table_elt_t *src; | 1555 ngx_uint_t i, j; |
1556 ngx_array_t hide_headers; | |
1557 ngx_keyval_t *src; | |
1558 ngx_hash_key_t *hk; | |
1559 ngx_hash_init_t hash; | |
1534 ngx_http_script_compile_t sc; | 1560 ngx_http_script_compile_t sc; |
1535 ngx_http_script_copy_code_t *copy; | 1561 ngx_http_script_copy_code_t *copy; |
1536 | 1562 |
1537 ngx_conf_merge_value(conf->upstream.buffering, | 1563 ngx_conf_merge_value(conf->upstream.buffering, |
1538 prev->upstream.buffering, 1); | 1564 prev->upstream.buffering, 1); |
1680 prev->upstream.pass_request_body, 1); | 1706 prev->upstream.pass_request_body, 1); |
1681 | 1707 |
1682 ngx_conf_merge_value(conf->upstream.redirect_errors, | 1708 ngx_conf_merge_value(conf->upstream.redirect_errors, |
1683 prev->upstream.redirect_errors, 0); | 1709 prev->upstream.redirect_errors, 0); |
1684 | 1710 |
1685 ngx_conf_merge_value(conf->upstream.pass_x_powered_by, | |
1686 prev->upstream.pass_x_powered_by, 1); | |
1687 | |
1688 | 1711 |
1689 ngx_conf_merge_str_value(conf->index, prev->index, ""); | 1712 ngx_conf_merge_str_value(conf->index, prev->index, ""); |
1713 | |
1714 if (conf->upstream.hide_headers == NULL | |
1715 && conf->upstream.pass_headers == NULL) | |
1716 { | |
1717 conf->upstream.hide_headers = prev->upstream.hide_headers; | |
1718 conf->upstream.pass_headers = prev->upstream.pass_headers; | |
1719 conf->upstream.hide_headers_hash = prev->upstream.hide_headers_hash; | |
1720 | |
1721 if (conf->upstream.hide_headers_hash.buckets) { | |
1722 goto peers; | |
1723 } | |
1724 | |
1725 } else { | |
1726 if (conf->upstream.hide_headers == NULL) { | |
1727 conf->upstream.hide_headers = prev->upstream.hide_headers; | |
1728 } | |
1729 | |
1730 if (conf->upstream.pass_headers == NULL) { | |
1731 conf->upstream.pass_headers = prev->upstream.pass_headers; | |
1732 } | |
1733 } | |
1734 | |
1735 if (ngx_array_init(&hide_headers, cf->temp_pool, 4, sizeof(ngx_hash_key_t)) | |
1736 != NGX_OK) | |
1737 { | |
1738 return NGX_CONF_ERROR; | |
1739 } | |
1740 | |
1741 for (header = ngx_http_fastcgi_hide_headers; header->len; header++) { | |
1742 hk = ngx_array_push(&hide_headers); | |
1743 if (hk == NULL) { | |
1744 return NGX_CONF_ERROR; | |
1745 } | |
1746 | |
1747 hk->key = *header; | |
1748 hk->key_hash = ngx_hash_key_lc(header->data, header->len); | |
1749 hk->value = (void *) 1; | |
1750 } | |
1751 | |
1752 if (conf->upstream.hide_headers) { | |
1753 | |
1754 header = conf->upstream.hide_headers->elts; | |
1755 | |
1756 for (i = 0; i < conf->upstream.hide_headers->nelts; i++) { | |
1757 | |
1758 hk = hide_headers.elts; | |
1759 | |
1760 for (j = 0; j < hide_headers.nelts; j++) { | |
1761 if (ngx_strcasecmp(header[i].data, hk[j].key.data) == 0) { | |
1762 goto exist; | |
1763 } | |
1764 } | |
1765 | |
1766 hk = ngx_array_push(&hide_headers); | |
1767 if (hk == NULL) { | |
1768 return NGX_CONF_ERROR; | |
1769 } | |
1770 | |
1771 hk->key = header[i]; | |
1772 hk->key_hash = ngx_hash_key_lc(header[i].data, header[i].len); | |
1773 hk->value = (void *) 1; | |
1774 | |
1775 exist: | |
1776 | |
1777 continue; | |
1778 } | |
1779 } | |
1780 | |
1781 if (conf->upstream.pass_headers) { | |
1782 | |
1783 hk = hide_headers.elts; | |
1784 header = conf->upstream.pass_headers->elts; | |
1785 | |
1786 for (i = 0; i < conf->upstream.pass_headers->nelts; i++) { | |
1787 | |
1788 for (j = 0; j < hide_headers.nelts; j++) { | |
1789 | |
1790 if (hk[j].key.data == NULL) { | |
1791 continue; | |
1792 } | |
1793 | |
1794 if (ngx_strcasecmp(header[i].data, hk[j].key.data) == 0) { | |
1795 hk[j].key.data = NULL; | |
1796 break; | |
1797 } | |
1798 } | |
1799 } | |
1800 } | |
1801 | |
1802 hash.hash = &conf->upstream.hide_headers_hash; | |
1803 hash.key = ngx_hash_key_lc; | |
1804 hash.max_size = 512; | |
1805 hash.bucket_size = ngx_cacheline_size; | |
1806 hash.name = "fastcgi_hide_headers_hash"; | |
1807 hash.pool = cf->pool; | |
1808 hash.temp_pool = NULL; | |
1809 | |
1810 if (ngx_hash_init(&hash, hide_headers.elts, hide_headers.nelts) != NGX_OK) { | |
1811 return NGX_CONF_ERROR; | |
1812 } | |
1813 | |
1814 peers: | |
1690 | 1815 |
1691 if (conf->peers == NULL) { | 1816 if (conf->peers == NULL) { |
1692 conf->peers = prev->peers; | 1817 conf->peers = prev->peers; |
1693 conf->upstream.schema = prev->upstream.schema; | 1818 conf->upstream.schema = prev->upstream.schema; |
1694 } | 1819 } |