Mercurial > hg > nginx-quic
comparison src/http/modules/ngx_http_proxy_module.c @ 649:1e720b0be7ec release-0.3.46
nginx-0.3.46-RELEASE import
*) 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 <igor@sysoev.ru> |
---|---|
date | Thu, 11 May 2006 14:43:47 +0000 |
parents | e60fe4cf1d4e |
children | 39b7d7b33c91 |
comparison
equal
deleted
inserted
replaced
648:e60de1d1cdb2 | 649:1e720b0be7ec |
---|---|
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 |