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 }