comparison src/http/modules/ngx_http_proxy_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 54aabf2b0bc6
children d2ae1c9f1fd3
comparison
equal deleted inserted replaced
197:93658b91fad2 198:e6da4931e0e0
40 ngx_array_t *flushes; 40 ngx_array_t *flushes;
41 ngx_array_t *body_set_len; 41 ngx_array_t *body_set_len;
42 ngx_array_t *body_set; 42 ngx_array_t *body_set;
43 ngx_array_t *headers_set_len; 43 ngx_array_t *headers_set_len;
44 ngx_array_t *headers_set; 44 ngx_array_t *headers_set;
45 ngx_hash0_t *headers_set_hash; 45 ngx_hash_t headers_set_hash;
46 46
47 ngx_array_t *headers_source; 47 ngx_array_t *headers_source;
48 ngx_array_t *headers_names; 48 ngx_array_t *headers_names;
49 49
50 ngx_array_t *redirects; 50 ngx_array_t *redirects;
185 offsetof(ngx_http_proxy_loc_conf_t, upstream.redirect_errors), 185 offsetof(ngx_http_proxy_loc_conf_t, upstream.redirect_errors),
186 NULL }, 186 NULL },
187 187
188 { ngx_string("proxy_set_header"), 188 { ngx_string("proxy_set_header"),
189 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE2, 189 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE2,
190 ngx_conf_set_table_elt_slot, 190 ngx_conf_set_keyval_slot,
191 NGX_HTTP_LOC_CONF_OFFSET, 191 NGX_HTTP_LOC_CONF_OFFSET,
192 offsetof(ngx_http_proxy_loc_conf_t, headers_source), 192 offsetof(ngx_http_proxy_loc_conf_t, headers_source),
193 NULL }, 193 NULL },
194 194
195 { ngx_string("proxy_set_body"), 195 { ngx_string("proxy_set_body"),
295 ngx_conf_set_sec_slot, 295 ngx_conf_set_sec_slot,
296 NGX_HTTP_LOC_CONF_OFFSET, 296 NGX_HTTP_LOC_CONF_OFFSET,
297 offsetof(ngx_http_proxy_loc_conf_t, upstream.fail_timeout), 297 offsetof(ngx_http_proxy_loc_conf_t, upstream.fail_timeout),
298 NULL }, 298 NULL },
299 299
300 { ngx_string("proxy_pass_x_powered_by"), 300 { ngx_string("proxy_pass_header"),
301 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG, 301 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
302 ngx_conf_set_flag_slot, 302 ngx_conf_set_str_array_slot,
303 NGX_HTTP_LOC_CONF_OFFSET, 303 NGX_HTTP_LOC_CONF_OFFSET,
304 offsetof(ngx_http_proxy_loc_conf_t, upstream.pass_x_powered_by), 304 offsetof(ngx_http_proxy_loc_conf_t, upstream.pass_headers),
305 NULL }, 305 NULL },
306 306
307 { ngx_string("proxy_pass_server"), 307 { ngx_string("proxy_hide_header"),
308 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG, 308 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
309 ngx_conf_set_flag_slot, 309 ngx_conf_set_str_array_slot,
310 NGX_HTTP_LOC_CONF_OFFSET, 310 NGX_HTTP_LOC_CONF_OFFSET,
311 offsetof(ngx_http_proxy_loc_conf_t, upstream.pass_server), 311 offsetof(ngx_http_proxy_loc_conf_t, upstream.hide_headers),
312 NULL },
313
314 { ngx_string("proxy_pass_x_accel_expires"),
315 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
316 ngx_conf_set_flag_slot,
317 NGX_HTTP_LOC_CONF_OFFSET,
318 offsetof(ngx_http_proxy_loc_conf_t, upstream.pass_x_accel_expires),
319 NULL }, 312 NULL },
320 313
321 ngx_null_command 314 ngx_null_command
322 }; 315 };
323 316
354 347
355 348
356 static char ngx_http_proxy_version[] = " HTTP/1.0" CRLF; 349 static char ngx_http_proxy_version[] = " HTTP/1.0" CRLF;
357 350
358 351
359 static ngx_table_elt_t ngx_http_proxy_headers[] = { 352 static ngx_keyval_t ngx_http_proxy_headers[] = {
360 { 0, ngx_string("Host"), ngx_string("$proxy_host") }, 353 { ngx_string("Host"), ngx_string("$proxy_host") },
361 { 0, ngx_string("Connection"), ngx_string("close") }, 354 { ngx_string("Connection"), ngx_string("close") },
362 { 0, ngx_string("Keep-Alive"), ngx_string("") }, 355 { ngx_string("Keep-Alive"), ngx_string("") },
363 { 0, ngx_null_string, ngx_null_string } 356 { ngx_null_string, ngx_null_string }
357 };
358
359
360 static ngx_str_t ngx_http_proxy_hide_headers[] = {
361 ngx_string("Date"),
362 ngx_string("Server"),
363 ngx_string("X-Pad"),
364 ngx_string("X-Accel-Expires"),
365 ngx_string("X-Accel-Redirect"),
366 ngx_string("X-Accel-Limit-Rate"),
367 ngx_string("X-Accel-Buffer"),
368 ngx_null_string
364 }; 369 };
365 370
366 371
367 static ngx_http_variable_t ngx_http_proxy_vars[] = { 372 static ngx_http_variable_t ngx_http_proxy_vars[] = {
368 373
420 425
421 if (plcf->redirects) { 426 if (plcf->redirects) {
422 u->rewrite_redirect = ngx_http_proxy_rewrite_redirect; 427 u->rewrite_redirect = ngx_http_proxy_rewrite_redirect;
423 } 428 }
424 429
425 if (plcf->upstream.buffering) { 430 u->buffering = plcf->upstream.buffering;
426 431
427 u->pipe = ngx_pcalloc(r->pool, sizeof(ngx_event_pipe_t)); 432 u->pipe = ngx_pcalloc(r->pool, sizeof(ngx_event_pipe_t));
428 if (u->pipe == NULL) { 433 if (u->pipe == NULL) {
429 return NGX_HTTP_INTERNAL_SERVER_ERROR; 434 return NGX_HTTP_INTERNAL_SERVER_ERROR;
430 } 435 }
431 436
432 u->pipe->input_filter = ngx_event_pipe_copy_input_filter; 437 u->pipe->input_filter = ngx_event_pipe_copy_input_filter;
433 }
434 438
435 u->accel = 1; 439 u->accel = 1;
436 440
437 r->upstream = u; 441 r->upstream = u;
438 442
448 452
449 static ngx_int_t 453 static ngx_int_t
450 ngx_http_proxy_create_request(ngx_http_request_t *r) 454 ngx_http_proxy_create_request(ngx_http_request_t *r)
451 { 455 {
452 size_t len, loc_len, body_len; 456 size_t len, loc_len, body_len;
453 ngx_uint_t i, key, unparsed_uri;
454 uintptr_t escape; 457 uintptr_t escape;
455 ngx_buf_t *b; 458 ngx_buf_t *b;
456 ngx_str_t *hh, method; 459 ngx_str_t method;
460 ngx_uint_t i, unparsed_uri;
457 ngx_chain_t *cl, *body; 461 ngx_chain_t *cl, *body;
458 ngx_list_part_t *part; 462 ngx_list_part_t *part;
459 ngx_table_elt_t *header; 463 ngx_table_elt_t *header;
460 ngx_http_upstream_t *u; 464 ngx_http_upstream_t *u;
461 ngx_http_proxy_ctx_t *p; 465 ngx_http_proxy_ctx_t *p;
539 } 543 }
540 le.ip += sizeof(uintptr_t); 544 le.ip += sizeof(uintptr_t);
541 } 545 }
542 546
543 547
544 hh = (ngx_str_t *) plcf->headers_set_hash->buckets;
545
546 if (plcf->upstream.pass_request_headers) { 548 if (plcf->upstream.pass_request_headers) {
547 part = &r->headers_in.headers.part; 549 part = &r->headers_in.headers.part;
548 header = part->elts; 550 header = part->elts;
549 551
550 for (i = 0; /* void */; i++) { 552 for (i = 0; /* void */; i++) {
557 part = part->next; 559 part = part->next;
558 header = part->elts; 560 header = part->elts;
559 i = 0; 561 i = 0;
560 } 562 }
561 563
562 key = header[i].hash % plcf->headers_set_hash->hash_size; 564 if (ngx_hash_find(&plcf->headers_set_hash, header[i].hash,
563 565 header[i].lowcase_key, header[i].key.len))
564 if (hh[key].len == header[i].key.len
565 && ngx_strcasecmp(hh[key].data, header[i].key.data) == 0)
566 { 566 {
567 continue; 567 continue;
568 } 568 }
569 569
570 len += header[i].key.len + sizeof(": ") - 1 570 len += header[i].key.len + sizeof(": ") - 1
674 part = part->next; 674 part = part->next;
675 header = part->elts; 675 header = part->elts;
676 i = 0; 676 i = 0;
677 } 677 }
678 678
679 key = header[i].hash % plcf->headers_set_hash->hash_size; 679 if (ngx_hash_find(&plcf->headers_set_hash, header[i].hash,
680 680 header[i].lowcase_key, header[i].key.len))
681 if (hh[key].len == header[i].key.len
682 && ngx_strcasecmp(hh[key].data, header[i].key.data) == 0)
683 { 681 {
684 continue; 682 continue;
685 } 683 }
686 684
687 b->last = ngx_copy(b->last, header[i].key.data, header[i].key.len); 685 b->last = ngx_copy(b->last, header[i].key.data, header[i].key.len);
1053 1051
1054 static ngx_int_t 1052 static ngx_int_t
1055 ngx_http_proxy_process_header(ngx_http_request_t *r) 1053 ngx_http_proxy_process_header(ngx_http_request_t *r)
1056 { 1054 {
1057 ngx_int_t rc; 1055 ngx_int_t rc;
1058 ngx_uint_t key; 1056 ngx_uint_t i;
1059 ngx_table_elt_t *h; 1057 ngx_table_elt_t *h;
1060 ngx_http_upstream_header_t *hh; 1058 ngx_http_upstream_header_t *hh;
1061 ngx_http_upstream_main_conf_t *umcf; 1059 ngx_http_upstream_main_conf_t *umcf;
1062 1060
1063 umcf = ngx_http_get_module_main_conf(r, ngx_http_upstream_module); 1061 umcf = ngx_http_get_module_main_conf(r, ngx_http_upstream_module);
1064 hh = (ngx_http_upstream_header_t *) umcf->headers_in_hash.buckets;
1065 1062
1066 for ( ;; ) { 1063 for ( ;; ) {
1067 1064
1068 rc = ngx_http_parse_header_line(r, &r->upstream->buffer); 1065 rc = ngx_http_parse_header_line(r, &r->upstream->buffer);
1069 1066
1080 1077
1081 h->key.len = r->header_name_end - r->header_name_start; 1078 h->key.len = r->header_name_end - r->header_name_start;
1082 h->value.len = r->header_end - r->header_start; 1079 h->value.len = r->header_end - r->header_start;
1083 1080
1084 h->key.data = ngx_palloc(r->pool, 1081 h->key.data = ngx_palloc(r->pool,
1085 h->key.len + 1 + h->value.len + 1); 1082 h->key.len + 1 + h->value.len + 1 + h->key.len);
1086 if (h->key.data == NULL) { 1083 if (h->key.data == NULL) {
1087 return NGX_HTTP_INTERNAL_SERVER_ERROR; 1084 return NGX_HTTP_INTERNAL_SERVER_ERROR;
1088 } 1085 }
1089 1086
1090 h->value.data = h->key.data + h->key.len + 1; 1087 h->value.data = h->key.data + h->key.len + 1;
1088 h->lowcase_key = h->key.data + h->key.len + 1 + h->value.len + 1;
1091 1089
1092 ngx_cpystrn(h->key.data, r->header_name_start, h->key.len + 1); 1090 ngx_cpystrn(h->key.data, r->header_name_start, h->key.len + 1);
1093 ngx_cpystrn(h->value.data, r->header_start, h->value.len + 1); 1091 ngx_cpystrn(h->value.data, r->header_start, h->value.len + 1);
1094 1092
1095 key = h->hash % umcf->headers_in_hash.hash_size; 1093 if (h->key.len == r->lowcase_index) {
1096 1094 ngx_memcpy(h->lowcase_key, r->lowcase_header, h->key.len);
1097 if (hh[key].name.len == h->key.len 1095
1098 && ngx_strcasecmp(hh[key].name.data, h->key.data) == 0) 1096 } else {
1099 { 1097 for (i = 0; i < h->key.len; i++) {
1100 if (hh[key].handler(r, h, hh[key].offset) != NGX_OK) { 1098 h->lowcase_key[i] = ngx_tolower(h->lowcase_key[i]);
1101 return NGX_HTTP_INTERNAL_SERVER_ERROR;
1102 } 1099 }
1100 }
1101
1102 hh = ngx_hash_find(&umcf->headers_in_hash, h->hash,
1103 h->lowcase_key, h->key.len);
1104
1105 if (hh && hh->handler(r, h, hh->offset) != NGX_OK) {
1106 return NGX_HTTP_INTERNAL_SERVER_ERROR;
1103 } 1107 }
1104 1108
1105 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, 1109 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
1106 "http proxy header: \"%V: %V\"", 1110 "http proxy header: \"%V: %V\"",
1107 &h->key, &h->value); 1111 &h->key, &h->value);
1113 1117
1114 /* a whole header has been parsed successfully */ 1118 /* a whole header has been parsed successfully */
1115 1119
1116 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, 1120 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
1117 "http proxy header done"); 1121 "http proxy header done");
1122
1123 /*
1124 * if no "Server" and "Date" in header line,
1125 * then add the special empty headers
1126 */
1127
1128 if (r->upstream->headers_in.server == NULL) {
1129 h = ngx_list_push(&r->upstream->headers_in.headers);
1130 if (h == NULL) {
1131 return NGX_HTTP_INTERNAL_SERVER_ERROR;
1132 }
1133
1134 h->hash = ngx_hash(ngx_hash(ngx_hash(ngx_hash(
1135 ngx_hash('s', 'e'), 'r'), 'v'), 'e'), 'r');
1136
1137 h->key.len = sizeof("Server") - 1;
1138 h->key.data = (u_char *) "Server";
1139 h->value.len = 0;
1140 h->value.data = NULL;
1141 h->lowcase_key = (u_char *) "server";
1142 }
1143
1144 if (r->upstream->headers_in.date == NULL) {
1145 h = ngx_list_push(&r->upstream->headers_in.headers);
1146 if (h == NULL) {
1147 return NGX_HTTP_INTERNAL_SERVER_ERROR;
1148 }
1149
1150 h->hash = ngx_hash(ngx_hash(ngx_hash('d', 'a'), 't'), 'e');
1151
1152 h->key.len = sizeof("Date") - 1;
1153 h->key.data = (u_char *) "Date";
1154 h->value.len = 0;
1155 h->value.data = NULL;
1156 h->lowcase_key = (u_char *) "date";
1157 }
1118 1158
1119 return NGX_OK; 1159 return NGX_OK;
1120 } 1160 }
1121 1161
1122 if (rc == NGX_AGAIN) { 1162 if (rc == NGX_AGAIN) {
1404 * set by ngx_pcalloc(): 1444 * set by ngx_pcalloc():
1405 * 1445 *
1406 * conf->upstream.bufs.num = 0; 1446 * conf->upstream.bufs.num = 0;
1407 * conf->upstream.next_upstream = 0; 1447 * conf->upstream.next_upstream = 0;
1408 * conf->upstream.temp_path = NULL; 1448 * conf->upstream.temp_path = NULL;
1449 * conf->upstream.hide_headers_hash = { NULL, 0 };
1450 * conf->upstream.hide_headers = NULL;
1451 * conf->upstream.pass_headers = NULL;
1409 * conf->upstream.schema = { 0, NULL }; 1452 * conf->upstream.schema = { 0, NULL };
1410 * conf->upstream.uri = { 0, NULL }; 1453 * conf->upstream.uri = { 0, NULL };
1411 * conf->upstream.location = NULL; 1454 * conf->upstream.location = NULL;
1412 * 1455 *
1413 * conf->method = NULL; 1456 * conf->method = NULL;
1444 conf->upstream.redirect_errors = NGX_CONF_UNSET; 1487 conf->upstream.redirect_errors = NGX_CONF_UNSET;
1445 1488
1446 /* "proxy_cyclic_temp_file" is disabled */ 1489 /* "proxy_cyclic_temp_file" is disabled */
1447 conf->upstream.cyclic_temp_file = 0; 1490 conf->upstream.cyclic_temp_file = 0;
1448 1491
1449 conf->upstream.pass_x_powered_by = NGX_CONF_UNSET;
1450 conf->upstream.pass_server = NGX_CONF_UNSET;
1451 conf->upstream.pass_date = 0;
1452 conf->upstream.pass_x_accel_expires = NGX_CONF_UNSET;
1453
1454 conf->redirect = NGX_CONF_UNSET; 1492 conf->redirect = NGX_CONF_UNSET;
1493 conf->upstream.change_buffering = 1;
1455 1494
1456 return conf; 1495 return conf;
1457 } 1496 }
1458 1497
1459 1498
1464 ngx_http_proxy_loc_conf_t *conf = child; 1503 ngx_http_proxy_loc_conf_t *conf = child;
1465 1504
1466 u_char *p; 1505 u_char *p;
1467 size_t size; 1506 size_t size;
1468 uintptr_t *code; 1507 uintptr_t *code;
1469 ngx_str_t *name; 1508 ngx_str_t *header;
1470 ngx_uint_t i; 1509 ngx_uint_t i, j;
1471 ngx_table_elt_t *src, *s, *h; 1510 ngx_array_t hide_headers;
1511 ngx_keyval_t *src, *s, *h;
1512 ngx_hash_key_t *hk;
1513 ngx_hash_init_t hash;
1472 ngx_http_proxy_redirect_t *pr; 1514 ngx_http_proxy_redirect_t *pr;
1473 ngx_http_script_compile_t sc; 1515 ngx_http_script_compile_t sc;
1474 ngx_http_script_copy_code_t *copy; 1516 ngx_http_script_copy_code_t *copy;
1475 1517
1476 ngx_conf_merge_value(conf->upstream.buffering, 1518 ngx_conf_merge_value(conf->upstream.buffering,
1625 prev->upstream.pass_request_body, 1); 1667 prev->upstream.pass_request_body, 1);
1626 1668
1627 ngx_conf_merge_value(conf->upstream.redirect_errors, 1669 ngx_conf_merge_value(conf->upstream.redirect_errors,
1628 prev->upstream.redirect_errors, 0); 1670 prev->upstream.redirect_errors, 0);
1629 1671
1630 ngx_conf_merge_value(conf->upstream.pass_x_powered_by,
1631 prev->upstream.pass_x_powered_by, 1);
1632 ngx_conf_merge_value(conf->upstream.pass_server,
1633 prev->upstream.pass_server, 0);
1634 ngx_conf_merge_value(conf->upstream.pass_x_accel_expires,
1635 prev->upstream.pass_x_accel_expires, 0);
1636
1637
1638 ngx_conf_merge_value(conf->redirect, prev->redirect, 1); 1672 ngx_conf_merge_value(conf->redirect, prev->redirect, 1);
1639 1673
1640 if (conf->redirect) { 1674 if (conf->redirect) {
1641 1675
1642 if (conf->redirects == NULL) { 1676 if (conf->redirects == NULL) {
1660 pr->redirect = conf->upstream.url; 1694 pr->redirect = conf->upstream.url;
1661 pr->replacement.text = conf->upstream.location; 1695 pr->replacement.text = conf->upstream.location;
1662 } 1696 }
1663 } 1697 }
1664 1698
1699 if (conf->upstream.hide_headers == NULL
1700 && conf->upstream.pass_headers == NULL)
1701 {
1702 conf->upstream.hide_headers = prev->upstream.hide_headers;
1703 conf->upstream.pass_headers = prev->upstream.pass_headers;
1704 conf->upstream.hide_headers_hash = prev->upstream.hide_headers_hash;
1705
1706 if (conf->upstream.hide_headers_hash.buckets) {
1707 goto peers;
1708 }
1709
1710 } else {
1711 if (conf->upstream.hide_headers == NULL) {
1712 conf->upstream.hide_headers = prev->upstream.hide_headers;
1713 }
1714
1715 if (conf->upstream.pass_headers == NULL) {
1716 conf->upstream.pass_headers = prev->upstream.pass_headers;
1717 }
1718 }
1719
1720 if (ngx_array_init(&hide_headers, cf->temp_pool, 4, sizeof(ngx_hash_key_t))
1721 != NGX_OK)
1722 {
1723 return NGX_CONF_ERROR;
1724 }
1725
1726 for (header = ngx_http_proxy_hide_headers; header->len; header++) {
1727 hk = ngx_array_push(&hide_headers);
1728 if (hk == NULL) {
1729 return NGX_CONF_ERROR;
1730 }
1731
1732 hk->key = *header;
1733 hk->key_hash = ngx_hash_key_lc(header->data, header->len);
1734 hk->value = (void *) 1;
1735 }
1736
1737 if (conf->upstream.hide_headers) {
1738
1739 header = conf->upstream.hide_headers->elts;
1740
1741 for (i = 0; i < conf->upstream.hide_headers->nelts; i++) {
1742
1743 hk = hide_headers.elts;
1744
1745 for (j = 0; j < hide_headers.nelts; j++) {
1746 if (ngx_strcasecmp(header[i].data, hk[j].key.data) == 0) {
1747 goto exist;
1748 }
1749 }
1750
1751 hk = ngx_array_push(&hide_headers);
1752 if (hk == NULL) {
1753 return NGX_CONF_ERROR;
1754 }
1755
1756 hk->key = header[i];
1757 hk->key_hash = ngx_hash_key_lc(header[i].data, header[i].len);
1758 hk->value = (void *) 1;
1759
1760 exist:
1761
1762 continue;
1763 }
1764 }
1765
1766 if (conf->upstream.pass_headers) {
1767
1768 hk = hide_headers.elts;
1769 header = conf->upstream.pass_headers->elts;
1770
1771 for (i = 0; i < conf->upstream.pass_headers->nelts; i++) {
1772 for (j = 0; j < hide_headers.nelts; j++) {
1773
1774 if (hk[j].key.data == NULL) {
1775 continue;
1776 }
1777
1778 if (ngx_strcasecmp(header[i].data, hk[j].key.data) == 0) {
1779 hk[j].key.data = NULL;
1780 break;
1781 }
1782 }
1783 }
1784 }
1785
1786 hash.hash = &conf->upstream.hide_headers_hash;
1787 hash.key = ngx_hash_key_lc;
1788 hash.max_size = 512;
1789 hash.bucket_size = ngx_cacheline_size;
1790 hash.name = "proxy_hide_headers_hash";
1791 hash.pool = cf->pool;
1792 hash.temp_pool = NULL;
1793
1794 if (ngx_hash_init(&hash, hide_headers.elts, hide_headers.nelts) != NGX_OK) {
1795 return NGX_CONF_ERROR;
1796 }
1797
1798 peers:
1665 1799
1666 if (conf->peers == NULL) { 1800 if (conf->peers == NULL) {
1667 conf->peers = prev->peers; 1801 conf->peers = prev->peers;
1668 1802
1669 conf->host_header = prev->host_header; 1803 conf->host_header = prev->host_header;
1694 return NGX_CONF_ERROR; 1828 return NGX_CONF_ERROR;
1695 } 1829 }
1696 1830
1697 if (conf->headers_source == NULL) { 1831 if (conf->headers_source == NULL) {
1698 conf->headers_source = ngx_array_create(cf->pool, 4, 1832 conf->headers_source = ngx_array_create(cf->pool, 4,
1699 sizeof(ngx_table_elt_t)); 1833 sizeof(ngx_keyval_t));
1700 if (conf->headers_source == NULL) { 1834 if (conf->headers_source == NULL) {
1701 return NGX_CONF_ERROR; 1835 return NGX_CONF_ERROR;
1702 } 1836 }
1703 } 1837 }
1704 1838
1705 s = ngx_array_push(conf->headers_source); 1839 s = ngx_array_push(conf->headers_source);
1706 if (s == NULL) { 1840 if (s == NULL) {
1707 return NGX_CONF_ERROR; 1841 return NGX_CONF_ERROR;
1708 } 1842 }
1709 1843
1710 s->hash = 0;
1711 s->key.len = sizeof("Content-Length") - 1; 1844 s->key.len = sizeof("Content-Length") - 1;
1712 s->key.data = (u_char *) "Content-Length"; 1845 s->key.data = (u_char *) "Content-Length";
1713 s->value.len = sizeof("$proxy_internal_body_length") - 1; 1846 s->value.len = sizeof("$proxy_internal_body_length") - 1;
1714 s->value.data = (u_char *) "$proxy_internal_body_length"; 1847 s->value.data = (u_char *) "$proxy_internal_body_length";
1715 } 1848 }
1721 conf->headers_set = prev->headers_set; 1854 conf->headers_set = prev->headers_set;
1722 conf->headers_set_hash = prev->headers_set_hash; 1855 conf->headers_set_hash = prev->headers_set_hash;
1723 conf->headers_source = prev->headers_source; 1856 conf->headers_source = prev->headers_source;
1724 } 1857 }
1725 1858
1726 if (conf->headers_set_hash) { 1859 if (conf->headers_set_hash.buckets) {
1727 return NGX_CONF_OK; 1860 return NGX_CONF_OK;
1728 } 1861 }
1729 1862
1730 1863
1731 conf->headers_names = ngx_array_create(cf->pool, 4, sizeof(ngx_str_t)); 1864 conf->headers_names = ngx_array_create(cf->pool, 4, sizeof(ngx_hash_key_t));
1732 if (conf->headers_names == NULL) { 1865 if (conf->headers_names == NULL) {
1733 return NGX_CONF_ERROR; 1866 return NGX_CONF_ERROR;
1734 } 1867 }
1735 1868
1736 if (conf->headers_source == NULL) { 1869 if (conf->headers_source == NULL) {
1737 conf->headers_source = ngx_array_create(cf->pool, 4, 1870 conf->headers_source = ngx_array_create(cf->pool, 4,
1738 sizeof(ngx_table_elt_t)); 1871 sizeof(ngx_keyval_t));
1739 if (conf->headers_source == NULL) { 1872 if (conf->headers_source == NULL) {
1740 return NGX_CONF_ERROR; 1873 return NGX_CONF_ERROR;
1741 } 1874 }
1742 } 1875 }
1743 1876
1778 1911
1779 1912
1780 src = conf->headers_source->elts; 1913 src = conf->headers_source->elts;
1781 for (i = 0; i < conf->headers_source->nelts; i++) { 1914 for (i = 0; i < conf->headers_source->nelts; i++) {
1782 1915
1783 name = ngx_array_push(conf->headers_names); 1916 hk = ngx_array_push(conf->headers_names);
1784 if (name == NULL) { 1917 if (hk == NULL) {
1785 return NGX_CONF_ERROR; 1918 return NGX_CONF_ERROR;
1786 } 1919 }
1787 1920
1788 *name = src[i].key; 1921 hk->key = src[i].key;
1922 hk->key_hash = ngx_hash_key_lc(src[i].key.data, src[i].key.len);
1923 hk->value = (void *) 1;
1789 1924
1790 if (src[i].value.len == 0) { 1925 if (src[i].value.len == 0) {
1791 continue; 1926 continue;
1792 } 1927 }
1793 1928
1916 } 2051 }
1917 2052
1918 *code = (uintptr_t) NULL; 2053 *code = (uintptr_t) NULL;
1919 2054
1920 2055
2056 hash.hash = &conf->headers_set_hash;
2057 hash.key = ngx_hash_key_lc;
2058 hash.max_size = 512;
2059 hash.bucket_size = ngx_cacheline_size;
2060 hash.name = "proxy_set_header_hash";
2061 hash.pool = cf->pool;
2062 hash.temp_pool = NULL;
2063
2064 if (ngx_hash_init(&hash, conf->headers_names->elts,
2065 conf->headers_names->nelts)
2066 != NGX_OK)
2067 {
2068 return NGX_CONF_ERROR;
2069 }
2070
2071
2072 #if 0
1921 conf->headers_set_hash = ngx_pcalloc(cf->pool, sizeof(ngx_hash0_t)); 2073 conf->headers_set_hash = ngx_pcalloc(cf->pool, sizeof(ngx_hash0_t));
1922 if (conf->headers_set_hash == NULL) { 2074 if (conf->headers_set_hash == NULL) {
1923 return NGX_CONF_ERROR; 2075 return NGX_CONF_ERROR;
1924 } 2076 }
1925 2077
1938 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, cf->log, 0, 2090 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, cf->log, 0,
1939 "proxy_headers hash size: %ui, " 2091 "proxy_headers hash size: %ui, "
1940 "max buckets per entry: %ui", 2092 "max buckets per entry: %ui",
1941 conf->headers_set_hash->hash_size, 2093 conf->headers_set_hash->hash_size,
1942 conf->headers_set_hash->min_buckets); 2094 conf->headers_set_hash->min_buckets);
2095 #endif
1943 2096
1944 return NGX_CONF_OK; 2097 return NGX_CONF_OK;
1945 } 2098 }
1946 2099
1947 2100