diff options
author | Igor Sysoev <igor@sysoev.ru> | 2006-05-11 13:26:14 +0000 |
---|---|---|
committer | Jonathan Kolb <jon@b0g.us> | 2006-05-11 13:26:14 +0000 |
commit | 25b0050338e2e4dc504342da58826a5b4a1aade1 (patch) | |
tree | 4f87057942279cec072dfb99f2db4f1485faa41f /src/http/ngx_http_upstream.c | |
parent | deefb18a9f79746c80970bdafbc099d1429e171e (diff) | |
download | nginx-25b0050338e2e4dc504342da58826a5b4a1aade1.tar.gz |
Changes with nginx 0.3.46 11 May 2006v0.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.
Diffstat (limited to 'src/http/ngx_http_upstream.c')
-rw-r--r-- | src/http/ngx_http_upstream.c | 157 |
1 files changed, 93 insertions, 64 deletions
diff --git a/src/http/ngx_http_upstream.c b/src/http/ngx_http_upstream.c index 45e586f9d..5eaad79d6 100644 --- a/src/http/ngx_http_upstream.c +++ b/src/http/ngx_http_upstream.c @@ -47,10 +47,9 @@ static ngx_int_t ngx_http_upstream_ignore_header_line(ngx_http_request_t *r, ngx_table_elt_t *h, ngx_uint_t offset); static ngx_int_t ngx_http_upstream_process_limit_rate(ngx_http_request_t *r, ngx_table_elt_t *h, ngx_uint_t offset); -static ngx_int_t ngx_http_upstream_copy_header_line(ngx_http_request_t *r, +static ngx_int_t ngx_http_upstream_process_buffering(ngx_http_request_t *r, ngx_table_elt_t *h, ngx_uint_t offset); -static ngx_int_t - ngx_http_upstream_conditional_copy_header_line(ngx_http_request_t *r, +static ngx_int_t ngx_http_upstream_copy_header_line(ngx_http_request_t *r, ngx_table_elt_t *h, ngx_uint_t offset); static ngx_int_t ngx_http_upstream_copy_multi_header_lines(ngx_http_request_t *r, @@ -103,7 +102,7 @@ ngx_http_upstream_header_t ngx_http_upstream_headers_in[] = { { ngx_string("Status"), ngx_http_upstream_process_header_line, offsetof(ngx_http_upstream_headers_in_t, status), - /* STUB */ ngx_http_upstream_ignore_header_line, 0, 0 }, + ngx_http_upstream_copy_header_line, 0, 0 }, { ngx_string("Content-Type"), ngx_http_upstream_process_header_line, @@ -118,14 +117,14 @@ ngx_http_upstream_header_t ngx_http_upstream_headers_in[] = { { ngx_string("Date"), ngx_http_upstream_process_header_line, offsetof(ngx_http_upstream_headers_in_t, date), - ngx_http_upstream_conditional_copy_header_line, - offsetof(ngx_http_upstream_conf_t, pass_date), 0 }, + ngx_http_upstream_copy_header_line, + offsetof(ngx_http_headers_out_t, date), 0 }, { ngx_string("Server"), ngx_http_upstream_process_header_line, offsetof(ngx_http_upstream_headers_in_t, server), - ngx_http_upstream_conditional_copy_header_line, - offsetof(ngx_http_upstream_conf_t, pass_server), 0 }, + ngx_http_upstream_copy_header_line, + offsetof(ngx_http_headers_out_t, server), 0 }, { ngx_string("WWW-Authenticate"), ngx_http_upstream_process_header_line, @@ -174,20 +173,14 @@ ngx_http_upstream_header_t ngx_http_upstream_headers_in[] = { ngx_http_upstream_ignore_header_line, 0, ngx_http_upstream_ignore_header_line, 0, 0 }, - { ngx_string("X-Pad"), - ngx_http_upstream_ignore_header_line, 0, - ngx_http_upstream_ignore_header_line, 0, 0 }, - { ngx_string("X-Powered-By"), ngx_http_upstream_ignore_header_line, 0, - ngx_http_upstream_conditional_copy_header_line, - offsetof(ngx_http_upstream_conf_t, pass_x_powered_by), 0 }, + ngx_http_upstream_copy_header_line, 0, 0 }, { ngx_string("X-Accel-Expires"), ngx_http_upstream_process_header_line, offsetof(ngx_http_upstream_headers_in_t, x_accel_expires), - ngx_http_upstream_conditional_copy_header_line, - offsetof(ngx_http_upstream_conf_t, pass_x_accel_expires), 0 }, + ngx_http_upstream_copy_header_line, 0, 0 }, { ngx_string("X-Accel-Redirect"), ngx_http_upstream_process_header_line, @@ -198,6 +191,10 @@ ngx_http_upstream_header_t ngx_http_upstream_headers_in[] = { ngx_http_upstream_process_limit_rate, 0, ngx_http_upstream_ignore_header_line, 0, 0 }, + { ngx_string("X-Accel-Buffering"), + ngx_http_upstream_process_buffering, 0, + ngx_http_upstream_ignore_header_line, 0, 0 }, + #if (NGX_HTTP_GZIP) { ngx_string("Content-Encoding"), ngx_http_upstream_process_header_line, @@ -881,7 +878,7 @@ ngx_http_upstream_process_header(ngx_event_t *rev) ssize_t n; ngx_int_t rc; ngx_str_t *uri, args; - ngx_uint_t i, key, flags; + ngx_uint_t i, flags; ngx_list_part_t *part; ngx_table_elt_t *h; ngx_connection_t *c; @@ -1089,7 +1086,6 @@ ngx_http_upstream_process_header(ngx_event_t *rev) ngx_http_upstream_finalize_request(r, u, NGX_DECLINED); umcf = ngx_http_get_module_main_conf(r, ngx_http_upstream_module); - hh = (ngx_http_upstream_header_t *) umcf->headers_in_hash.buckets; part = &r->upstream->headers_in.headers.part; h = part->elts; @@ -1106,18 +1102,15 @@ ngx_http_upstream_process_header(ngx_event_t *rev) i = 0; } - key = h[i].hash % umcf->headers_in_hash.hash_size; + hh = ngx_hash_find(&umcf->headers_in_hash, h[i].hash, + h[i].lowcase_key, h[i].key.len); - if (hh[key].redirect - && hh[key].name.len == h[i].key.len - && ngx_strcasecmp(hh[key].name.data, h[i].key.data) == 0) - { - if (hh[key].copy_handler(r, &h[i], hh[key].conf) != NGX_OK) { + if (hh && hh->redirect) { + if (hh->copy_handler(r, &h[i], hh->conf) != NGX_OK) { ngx_http_upstream_finalize_request(r, u, NGX_HTTP_INTERNAL_SERVER_ERROR); return; } - } } @@ -1149,7 +1142,7 @@ ngx_http_upstream_send_response(ngx_http_request_t *r, ngx_http_upstream_t *u) int tcp_nodelay; ssize_t size; ngx_int_t rc; - ngx_uint_t i, key; + ngx_uint_t i; ngx_list_part_t *part; ngx_table_elt_t *h; ngx_event_pipe_t *p; @@ -1161,7 +1154,6 @@ ngx_http_upstream_send_response(ngx_http_request_t *r, ngx_http_upstream_t *u) ngx_http_upstream_main_conf_t *umcf; umcf = ngx_http_get_module_main_conf(r, ngx_http_upstream_module); - hh = (ngx_http_upstream_header_t *) umcf->headers_in_hash.buckets; part = &r->upstream->headers_in.headers.part; h = part->elts; @@ -1178,12 +1170,17 @@ ngx_http_upstream_send_response(ngx_http_request_t *r, ngx_http_upstream_t *u) i = 0; } - key = h[i].hash % umcf->headers_in_hash.hash_size; - - if (hh[key].name.len == h[i].key.len - && ngx_strcasecmp(hh[key].name.data, h[i].key.data) == 0) + if (ngx_hash_find(&u->conf->hide_headers_hash, h[i].hash, + h[i].lowcase_key, h[i].key.len)) { - if (hh[key].copy_handler(r, &h[i], hh[key].conf) != NGX_OK) { + continue; + } + + hh = ngx_hash_find(&umcf->headers_in_hash, h[i].hash, + h[i].lowcase_key, h[i].key.len); + + if (hh) { + if (hh->copy_handler(r, &h[i], hh->conf) != NGX_OK) { ngx_http_upstream_finalize_request(r, u, NGX_HTTP_INTERNAL_SERVER_ERROR); return; @@ -1199,6 +1196,14 @@ ngx_http_upstream_send_response(ngx_http_request_t *r, ngx_http_upstream_t *u) } } + if (r->headers_out.server && r->headers_out.server->value.data == NULL) { + r->headers_out.server->hash = 0; + } + + if (r->headers_out.date && r->headers_out.date->value.data == NULL) { + r->headers_out.date->hash = 0; + } + r->headers_out.status = u->headers_in.status_n; r->headers_out.status_line = u->headers_in.status_line; @@ -1236,7 +1241,7 @@ ngx_http_upstream_send_response(ngx_http_request_t *r, ngx_http_upstream_t *u) clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); - if (u->pipe == NULL) { + if (!u->buffering) { if (u->input_filter == NULL) { u->input_filter_init = ngx_http_upstream_non_buffered_filter_init; @@ -2054,21 +2059,30 @@ ngx_http_upstream_process_limit_rate(ngx_http_request_t *r, ngx_table_elt_t *h, static ngx_int_t -ngx_http_upstream_copy_header_line(ngx_http_request_t *r, ngx_table_elt_t *h, +ngx_http_upstream_process_buffering(ngx_http_request_t *r, ngx_table_elt_t *h, ngx_uint_t offset) { - ngx_table_elt_t *ho, **ph; + u_char c0, c1, c2; - ho = ngx_list_push(&r->headers_out.headers); - if (ho == NULL) { - return NGX_ERROR; - } + if (r->upstream->conf->change_buffering) { - *ho = *h; + if (h->value.len == 2) { + c0 = ngx_tolower(h->value.data[0]); + c1 = ngx_tolower(h->value.data[1]); - if (offset) { - ph = (ngx_table_elt_t **) ((char *) &r->headers_out + offset); - *ph = ho; + if (c0 == 'n' && c1 == 'o') { + r->upstream->buffering = 0; + } + + } else if (h->value.len == 3) { + c0 = ngx_tolower(h->value.data[0]); + c1 = ngx_tolower(h->value.data[1]); + c2 = ngx_tolower(h->value.data[2]); + + if (c0 == 'y' && c1 == 'e' && c2 == 's') { + r->upstream->buffering = 1; + } + } } return NGX_OK; @@ -2076,17 +2090,10 @@ ngx_http_upstream_copy_header_line(ngx_http_request_t *r, ngx_table_elt_t *h, static ngx_int_t -ngx_http_upstream_conditional_copy_header_line(ngx_http_request_t *r, - ngx_table_elt_t *h, ngx_uint_t offset) +ngx_http_upstream_copy_header_line(ngx_http_request_t *r, ngx_table_elt_t *h, + ngx_uint_t offset) { - ngx_flag_t *f; - ngx_table_elt_t *ho; - - f = (ngx_flag_t *) ((char *) r->upstream->conf + offset); - - if (*f == 0) { - return NGX_OK; - } + ngx_table_elt_t *ho, **ph; ho = ngx_list_push(&r->headers_out.headers); if (ho == NULL) { @@ -2095,6 +2102,11 @@ ngx_http_upstream_conditional_copy_header_line(ngx_http_request_t *r, *ho = *h; + if (offset) { + ph = (ngx_table_elt_t **) ((char *) &r->headers_out + offset); + *ph = ho; + } + return NGX_OK; } @@ -2554,22 +2566,39 @@ ngx_http_core_init_main_conf(ngx_conf_t *cf, void *conf) { ngx_http_upstream_main_conf_t *umcf = conf; - umcf->headers_in_hash.max_size = 100; - umcf->headers_in_hash.bucket_limit = 1; - umcf->headers_in_hash.bucket_size = sizeof(ngx_http_upstream_header_t); - umcf->headers_in_hash.name = "upstream_headers_in"; + ngx_array_t headers_in; + ngx_hash_key_t *hk; + ngx_hash_init_t hash; + ngx_http_upstream_header_t *header; - if (ngx_hash0_init(&umcf->headers_in_hash, cf->pool, - ngx_http_upstream_headers_in, 0) != NGX_OK) + if (ngx_array_init(&headers_in, cf->temp_pool, 32, sizeof(ngx_hash_key_t)) + != NGX_OK) { return NGX_CONF_ERROR; } - ngx_log_debug2(NGX_LOG_DEBUG_HTTP, cf->log, 0, - "http upstream headers_in hash size: %ui, " - "max buckets per entry: %ui", - umcf->headers_in_hash.hash_size, - umcf->headers_in_hash.min_buckets); + for (header = ngx_http_upstream_headers_in; header->name.len; header++) { + hk = ngx_array_push(&headers_in); + if (hk == NULL) { + return NGX_CONF_ERROR; + } + + hk->key = header->name; + hk->key_hash = ngx_hash_key_lc(header->name.data, header->name.len); + hk->value = header; + } + + hash.hash = &umcf->headers_in_hash; + hash.key = ngx_hash_key_lc; + hash.max_size = 512; + hash.bucket_size = ngx_cacheline_size; + hash.name = "upstream_headers_in_hash"; + hash.pool = cf->pool; + hash.temp_pool = NULL; + + if (ngx_hash_init(&hash, headers_in.elts, headers_in.nelts) != NGX_OK) { + return NGX_CONF_ERROR; + } return NGX_CONF_OK; } |