Mercurial > hg > nginx-ranges
diff src/http/modules/ngx_http_proxy_module.c @ 635:e67b227c8dbb default tip
Merge with current.
author | Maxim Dounin <mdounin@mdounin.ru> |
---|---|
date | Mon, 25 Apr 2011 04:07:55 +0400 |
parents | bb20316269e4 |
children |
line wrap: on
line diff
--- a/src/http/modules/ngx_http_proxy_module.c +++ b/src/http/modules/ngx_http_proxy_module.c @@ -51,7 +51,6 @@ typedef struct { ngx_hash_t headers_set_hash; ngx_array_t *headers_source; - ngx_array_t *headers_names; ngx_array_t *proxy_lengths; ngx_array_t *proxy_values; @@ -78,20 +77,12 @@ typedef struct { typedef struct { - ngx_uint_t status; - ngx_uint_t status_count; - u_char *status_start; - u_char *status_end; - + ngx_http_status_t status; ngx_http_proxy_vars_t vars; - size_t internal_body_length; } ngx_http_proxy_ctx_t; -#define NGX_HTTP_PROXY_PARSE_NO_HEADER 20 - - static ngx_int_t ngx_http_proxy_eval(ngx_http_request_t *r, ngx_http_proxy_ctx_t *ctx, ngx_http_proxy_loc_conf_t *plcf); #if (NGX_HTTP_CACHE) @@ -100,8 +91,6 @@ static ngx_int_t ngx_http_proxy_create_k static ngx_int_t ngx_http_proxy_create_request(ngx_http_request_t *r); static ngx_int_t ngx_http_proxy_reinit_request(ngx_http_request_t *r); static ngx_int_t ngx_http_proxy_process_status_line(ngx_http_request_t *r); -static ngx_int_t ngx_http_proxy_parse_status_line(ngx_http_request_t *r, - ngx_http_proxy_ctx_t *ctx); static ngx_int_t ngx_http_proxy_process_header(ngx_http_request_t *r); static void ngx_http_proxy_abort_request(ngx_http_request_t *r); static void ngx_http_proxy_finalize_request(ngx_http_request_t *r, @@ -142,11 +131,6 @@ static char *ngx_http_proxy_cache_key(ng static char *ngx_http_proxy_lowat_check(ngx_conf_t *cf, void *post, void *data); -static char *ngx_http_proxy_upstream_max_fails_unsupported(ngx_conf_t *cf, - ngx_command_t *cmd, void *conf); -static char *ngx_http_proxy_upstream_fail_timeout_unsupported(ngx_conf_t *cf, - ngx_command_t *cmd, void *conf); - #if (NGX_HTTP_SSL) static ngx_int_t ngx_http_proxy_set_ssl(ngx_conf_t *cf, ngx_http_proxy_loc_conf_t *plcf); @@ -173,15 +157,6 @@ static ngx_conf_bitmask_t ngx_http_prox }; -static ngx_conf_bitmask_t ngx_http_proxy_ignore_headers_masks[] = { - { ngx_string("X-Accel-Redirect"), NGX_HTTP_UPSTREAM_IGN_XA_REDIRECT }, - { ngx_string("X-Accel-Expires"), NGX_HTTP_UPSTREAM_IGN_XA_EXPIRES }, - { ngx_string("Expires"), NGX_HTTP_UPSTREAM_IGN_EXPIRES }, - { ngx_string("Cache-Control"), NGX_HTTP_UPSTREAM_IGN_CACHE_CONTROL }, - { ngx_null_string, 0 } -}; - - ngx_module_t ngx_http_proxy_module; @@ -344,14 +319,14 @@ static ngx_command_t ngx_http_proxy_com #if (NGX_HTTP_CACHE) { ngx_string("proxy_cache"), - NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG, + NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, ngx_http_proxy_cache, NGX_HTTP_LOC_CONF_OFFSET, 0, NULL }, { ngx_string("proxy_cache_key"), - NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG, + NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, ngx_http_proxy_cache_key, NGX_HTTP_LOC_CONF_OFFSET, 0, @@ -364,6 +339,20 @@ static ngx_command_t ngx_http_proxy_com 0, &ngx_http_proxy_module }, + { ngx_string("proxy_cache_bypass"), + NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE, + ngx_http_set_predicate_slot, + NGX_HTTP_LOC_CONF_OFFSET, + offsetof(ngx_http_proxy_loc_conf_t, upstream.cache_bypass), + NULL }, + + { ngx_string("proxy_no_cache"), + NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE, + ngx_http_set_predicate_slot, + NGX_HTTP_LOC_CONF_OFFSET, + offsetof(ngx_http_proxy_loc_conf_t, upstream.no_cache), + NULL }, + { ngx_string("proxy_cache_valid"), NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE, ngx_http_file_cache_valid_set_slot, @@ -422,29 +411,15 @@ static ngx_command_t ngx_http_proxy_com offsetof(ngx_http_proxy_loc_conf_t, upstream.next_upstream), &ngx_http_proxy_next_upstream_masks }, - { ngx_string("proxy_upstream_max_fails"), + { ngx_string("proxy_pass_header"), NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, - ngx_http_proxy_upstream_max_fails_unsupported, - 0, - 0, - NULL }, - - { ngx_string("proxy_upstream_fail_timeout"), - NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, - ngx_http_proxy_upstream_fail_timeout_unsupported, - 0, - 0, - NULL }, - - { ngx_string("proxy_pass_header"), - NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG, ngx_conf_set_str_array_slot, NGX_HTTP_LOC_CONF_OFFSET, offsetof(ngx_http_proxy_loc_conf_t, upstream.pass_headers), NULL }, { ngx_string("proxy_hide_header"), - NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG, + NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, ngx_conf_set_str_array_slot, NGX_HTTP_LOC_CONF_OFFSET, offsetof(ngx_http_proxy_loc_conf_t, upstream.hide_headers), @@ -455,7 +430,7 @@ static ngx_command_t ngx_http_proxy_com ngx_conf_set_bitmask_slot, NGX_HTTP_LOC_CONF_OFFSET, offsetof(ngx_http_proxy_loc_conf_t, upstream.ignore_headers), - &ngx_http_proxy_ignore_headers_masks }, + &ngx_http_upstream_ignore_headers_masks }, #if (NGX_HTTP_SSL) @@ -544,21 +519,6 @@ static ngx_keyval_t ngx_http_proxy_cach { ngx_null_string, ngx_null_string } }; - -static ngx_str_t ngx_http_proxy_hide_cache_headers[] = { - ngx_string("Date"), - ngx_string("Server"), - ngx_string("X-Pad"), - ngx_string("X-Accel-Expires"), - ngx_string("X-Accel-Redirect"), - ngx_string("X-Accel-Limit-Rate"), - ngx_string("X-Accel-Buffering"), - ngx_string("X-Accel-Charset"), - ngx_string("Set-Cookie"), - ngx_string("P3P"), - ngx_null_string -}; - #endif @@ -612,7 +572,7 @@ ngx_http_proxy_handler(ngx_http_request_ u = r->upstream; - if (plcf->proxy_lengths == 0) { + if (plcf->proxy_lengths == NULL) { ctx->vars = plcf->vars; u->schema = plcf->vars.schema; #if (NGX_HTTP_SSL) @@ -637,6 +597,7 @@ ngx_http_proxy_handler(ngx_http_request_ u->process_header = ngx_http_proxy_process_status_line; u->abort_request = ngx_http_proxy_abort_request; u->finalize_request = ngx_http_proxy_finalize_request; + r->state = 0; if (plcf->redirects) { u->rewrite_redirect = ngx_http_proxy_rewrite_redirect; @@ -923,7 +884,7 @@ ngx_http_proxy_create_request(ngx_http_r loc_len = (r->valid_location && ctx->vars.uri.len) ? plcf->location.len : 0; - if (r->quoted_uri || r->internal) { + if (r->quoted_uri || r->space_in_uri || r->internal) { escape = 2 * ngx_escape_uri(NULL, r->uri.data + loc_len, r->uri.len - loc_len, NGX_ESCAPE_URI); } @@ -1192,12 +1153,13 @@ ngx_http_proxy_reinit_request(ngx_http_r return NGX_OK; } - ctx->status = 0; - ctx->status_count = 0; - ctx->status_start = NULL; - ctx->status_end = NULL; + ctx->status.code = 0; + ctx->status.count = 0; + ctx->status.start = NULL; + ctx->status.end = NULL; r->upstream->process_header = ngx_http_proxy_process_status_line; + r->state = 0; return NGX_OK; } @@ -1206,6 +1168,7 @@ ngx_http_proxy_reinit_request(ngx_http_r static ngx_int_t ngx_http_proxy_process_status_line(ngx_http_request_t *r) { + size_t len; ngx_int_t rc; ngx_http_upstream_t *u; ngx_http_proxy_ctx_t *ctx; @@ -1216,15 +1179,15 @@ ngx_http_proxy_process_status_line(ngx_h return NGX_ERROR; } - rc = ngx_http_proxy_parse_status_line(r, ctx); + u = r->upstream; + + rc = ngx_http_parse_status_line(r, &u->buffer, &ctx->status); if (rc == NGX_AGAIN) { return rc; } - u = r->upstream; - - if (rc == NGX_HTTP_PROXY_PARSE_NO_HEADER) { + if (rc == NGX_ERROR) { #if (NGX_HTTP_CACHE) @@ -1251,20 +1214,20 @@ ngx_http_proxy_process_status_line(ngx_h } if (u->state) { - u->state->status = ctx->status; + u->state->status = ctx->status.code; } - u->headers_in.status_n = ctx->status; - - u->headers_in.status_line.len = ctx->status_end - ctx->status_start; - u->headers_in.status_line.data = ngx_pnalloc(r->pool, - u->headers_in.status_line.len); + u->headers_in.status_n = ctx->status.code; + + len = ctx->status.end - ctx->status.start; + u->headers_in.status_line.len = len; + + u->headers_in.status_line.data = ngx_pnalloc(r->pool, len); if (u->headers_in.status_line.data == NULL) { return NGX_ERROR; } - ngx_memcpy(u->headers_in.status_line.data, ctx->status_start, - u->headers_in.status_line.len); + ngx_memcpy(u->headers_in.status_line.data, ctx->status.start, len); ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "http proxy status %ui \"%V\"", @@ -1277,214 +1240,6 @@ ngx_http_proxy_process_status_line(ngx_h static ngx_int_t -ngx_http_proxy_parse_status_line(ngx_http_request_t *r, - ngx_http_proxy_ctx_t *ctx) -{ - u_char ch; - u_char *p; - ngx_http_upstream_t *u; - enum { - sw_start = 0, - sw_H, - sw_HT, - sw_HTT, - sw_HTTP, - sw_first_major_digit, - sw_major_digit, - sw_first_minor_digit, - sw_minor_digit, - sw_status, - sw_space_after_status, - sw_status_text, - sw_almost_done - } state; - - u = r->upstream; - - state = r->state; - - for (p = u->buffer.pos; p < u->buffer.last; p++) { - ch = *p; - - switch (state) { - - /* "HTTP/" */ - case sw_start: - switch (ch) { - case 'H': - state = sw_H; - break; - default: - return NGX_HTTP_PROXY_PARSE_NO_HEADER; - } - break; - - case sw_H: - switch (ch) { - case 'T': - state = sw_HT; - break; - default: - return NGX_HTTP_PROXY_PARSE_NO_HEADER; - } - break; - - case sw_HT: - switch (ch) { - case 'T': - state = sw_HTT; - break; - default: - return NGX_HTTP_PROXY_PARSE_NO_HEADER; - } - break; - - case sw_HTT: - switch (ch) { - case 'P': - state = sw_HTTP; - break; - default: - return NGX_HTTP_PROXY_PARSE_NO_HEADER; - } - break; - - case sw_HTTP: - switch (ch) { - case '/': - state = sw_first_major_digit; - break; - default: - return NGX_HTTP_PROXY_PARSE_NO_HEADER; - } - break; - - /* the first digit of major HTTP version */ - case sw_first_major_digit: - if (ch < '1' || ch > '9') { - return NGX_HTTP_PROXY_PARSE_NO_HEADER; - } - - state = sw_major_digit; - break; - - /* the major HTTP version or dot */ - case sw_major_digit: - if (ch == '.') { - state = sw_first_minor_digit; - break; - } - - if (ch < '0' || ch > '9') { - return NGX_HTTP_PROXY_PARSE_NO_HEADER; - } - - break; - - /* the first digit of minor HTTP version */ - case sw_first_minor_digit: - if (ch < '0' || ch > '9') { - return NGX_HTTP_PROXY_PARSE_NO_HEADER; - } - - state = sw_minor_digit; - break; - - /* the minor HTTP version or the end of the request line */ - case sw_minor_digit: - if (ch == ' ') { - state = sw_status; - break; - } - - if (ch < '0' || ch > '9') { - return NGX_HTTP_PROXY_PARSE_NO_HEADER; - } - - break; - - /* HTTP status code */ - case sw_status: - if (ch == ' ') { - break; - } - - if (ch < '0' || ch > '9') { - return NGX_HTTP_PROXY_PARSE_NO_HEADER; - } - - ctx->status = ctx->status * 10 + ch - '0'; - - if (++ctx->status_count == 3) { - state = sw_space_after_status; - ctx->status_start = p - 2; - } - - break; - - /* space or end of line */ - case sw_space_after_status: - switch (ch) { - case ' ': - state = sw_status_text; - break; - case '.': /* IIS may send 403.1, 403.2, etc */ - state = sw_status_text; - break; - case CR: - state = sw_almost_done; - break; - case LF: - goto done; - default: - return NGX_HTTP_PROXY_PARSE_NO_HEADER; - } - break; - - /* any text until end of line */ - case sw_status_text: - switch (ch) { - case CR: - state = sw_almost_done; - - break; - case LF: - goto done; - } - break; - - /* end of status line */ - case sw_almost_done: - ctx->status_end = p - 1; - switch (ch) { - case LF: - goto done; - default: - return NGX_HTTP_PROXY_PARSE_NO_HEADER; - } - } - } - - u->buffer.pos = p; - r->state = state; - - return NGX_AGAIN; - -done: - - u->buffer.pos = p + 1; - - if (ctx->status_end == NULL) { - ctx->status_end = p; - } - - r->state = sw_start; - - return NGX_OK; -} - - -static ngx_int_t ngx_http_proxy_process_header(ngx_http_request_t *r) { ngx_int_t rc; @@ -1566,10 +1321,8 @@ ngx_http_proxy_process_header(ngx_http_r h->hash = ngx_hash(ngx_hash(ngx_hash(ngx_hash( ngx_hash('s', 'e'), 'r'), 'v'), 'e'), 'r'); - h->key.len = sizeof("Server") - 1; - h->key.data = (u_char *) "Server"; - h->value.len = 0; - h->value.data = NULL; + ngx_str_set(&h->key, "Server"); + ngx_str_null(&h->value); h->lowcase_key = (u_char *) "server"; } @@ -1581,10 +1334,8 @@ ngx_http_proxy_process_header(ngx_http_r h->hash = ngx_hash(ngx_hash(ngx_hash('d', 'a'), 't'), 'e'); - h->key.len = sizeof("Date") - 1; - h->key.data = (u_char *) "Date"; - h->value.len = 0; - h->value.data = NULL; + ngx_str_set(&h->key, "Date"); + ngx_str_null(&h->value); h->lowcase_key = (u_char *) "date"; } @@ -1780,16 +1531,14 @@ ngx_http_proxy_rewrite_redirect_text(ngx return NGX_DECLINED; } - len = prefix + pr->replacement.text.len + h->value.len - pr->redirect.len; + len = pr->replacement.text.len + h->value.len - pr->redirect.len; data = ngx_pnalloc(r->pool, len); if (data == NULL) { return NGX_ERROR; } - p = data; - - p = ngx_copy(p, h->value.data, prefix); + p = ngx_copy(data, h->value.data, prefix); if (pr->replacement.text.len) { p = ngx_copy(p, pr->replacement.text.data, pr->replacement.text.len); @@ -1827,7 +1576,7 @@ ngx_http_proxy_rewrite_redirect_vars(ngx e.ip = pr->replacement.vars.lengths; e.request = r; - len = prefix + h->value.len - pr->redirect.len; + len = h->value.len - pr->redirect.len; while (*(uintptr_t *) e.ip) { lcode = *(ngx_http_script_len_code_pt *) e.ip; @@ -1839,9 +1588,7 @@ ngx_http_proxy_rewrite_redirect_vars(ngx return NGX_ERROR; } - p = data; - - p = ngx_copy(p, h->value.data, prefix); + p = ngx_copy(data, h->value.data, prefix); e.ip = pr->replacement.vars.values; e.pos = p; @@ -1913,7 +1660,7 @@ ngx_http_proxy_create_loc_conf(ngx_conf_ * conf->body_set_len = NULL; * conf->body_set = NULL; * conf->body_source = { 0, NULL }; - * conf->rewrite_locations = NULL; + * conf->redirects = NULL; */ conf->upstream.store = NGX_CONF_UNSET; @@ -1938,6 +1685,8 @@ ngx_http_proxy_create_loc_conf(ngx_conf_ #if (NGX_HTTP_CACHE) conf->upstream.cache = NGX_CONF_UNSET_PTR; conf->upstream.cache_min_uses = NGX_CONF_UNSET_UINT; + conf->upstream.cache_bypass = NGX_CONF_UNSET_PTR; + conf->upstream.no_cache = NGX_CONF_UNSET_PTR; conf->upstream.cache_valid = NGX_CONF_UNSET_PTR; #endif @@ -1968,10 +1717,11 @@ ngx_http_proxy_merge_loc_conf(ngx_conf_t ngx_http_proxy_loc_conf_t *prev = parent; ngx_http_proxy_loc_conf_t *conf = child; + u_char *p; size_t size; - ngx_str_t *h; ngx_keyval_t *s; ngx_hash_init_t hash; + ngx_http_core_loc_conf_t *clcf; ngx_http_proxy_redirect_t *pr; ngx_http_script_compile_t sc; @@ -2162,6 +1912,18 @@ ngx_http_proxy_merge_loc_conf(ngx_conf_t |NGX_HTTP_UPSTREAM_FT_OFF; } + ngx_conf_merge_ptr_value(conf->upstream.cache_bypass, + prev->upstream.cache_bypass, NULL); + + ngx_conf_merge_ptr_value(conf->upstream.no_cache, + prev->upstream.no_cache, NULL); + + if (conf->upstream.no_cache && conf->upstream.cache_bypass == NULL) { + ngx_log_error(NGX_LOG_WARN, cf->log, 0, + "\"proxy_no_cache\" functionality has been changed in 0.8.46, " + "now it should be used together with \"proxy_cache_bypass\""); + } + ngx_conf_merge_ptr_value(conf->upstream.cache_valid, prev->upstream.cache_valid, NULL); @@ -2214,24 +1976,29 @@ ngx_http_proxy_merge_loc_conf(ngx_conf_t } pr->handler = ngx_http_proxy_rewrite_redirect_text; - pr->redirect = conf->url; if (conf->vars.uri.len) { + pr->redirect = conf->url; pr->replacement.text = conf->location; } else { - pr->replacement.text.len = 0; - pr->replacement.text.data = NULL; + pr->redirect.len = conf->url.len + sizeof("/") - 1; + + p = ngx_pnalloc(cf->pool, pr->redirect.len); + if (p == NULL) { + return NGX_CONF_ERROR; + } + + pr->redirect.data = p; + + p = ngx_cpymem(p, conf->url.data, conf->url.len); + *p = '/'; + + ngx_str_set(&pr->replacement.text, "/"); } } } - /* STUB */ - if (prev->proxy_lengths) { - conf->proxy_lengths = prev->proxy_lengths; - conf->proxy_values = prev->proxy_values; - } - #if (NGX_HTTP_SSL) if (conf->upstream.ssl == NULL) { conf->upstream.ssl = prev->upstream.ssl; @@ -2251,18 +2018,8 @@ ngx_http_proxy_merge_loc_conf(ngx_conf_t hash.bucket_size = conf->headers_hash_bucket_size; hash.name = "proxy_headers_hash"; -#if (NGX_HTTP_CACHE) - - h = conf->upstream.cache ? ngx_http_proxy_hide_cache_headers: - ngx_http_proxy_hide_headers; -#else - - h = ngx_http_proxy_hide_headers; - -#endif - if (ngx_http_upstream_hide_headers_hash(cf, &conf->upstream, - &prev->upstream, h, &hash) + &prev->upstream, ngx_http_proxy_hide_headers, &hash) != NGX_OK) { return NGX_CONF_ERROR; @@ -2273,6 +2030,18 @@ ngx_http_proxy_merge_loc_conf(ngx_conf_t conf->vars = prev->vars; } + if (conf->proxy_lengths == NULL) { + conf->proxy_lengths = prev->proxy_lengths; + conf->proxy_values = prev->proxy_values; + } + + if (conf->upstream.upstream || conf->proxy_lengths) { + clcf = ngx_http_conf_get_module_loc_conf(cf, ngx_http_core_module); + if (clcf->handler == NULL && clcf->lmt_excpt) { + clcf->handler = ngx_http_proxy_handler; + conf->location = prev->location; + } + } if (conf->body_source.data == NULL) { conf->body_source = prev->body_source; @@ -2309,10 +2078,8 @@ ngx_http_proxy_merge_loc_conf(ngx_conf_t return NGX_CONF_ERROR; } - s->key.len = sizeof("Content-Length") - 1; - s->key.data = (u_char *) "Content-Length"; - s->value.len = sizeof("$proxy_internal_body_length") - 1; - s->value.data = (u_char *) "$proxy_internal_body_length"; + ngx_str_set(&s->key, "Content-Length"); + ngx_str_set(&s->value, "$proxy_internal_body_length"); } if (ngx_http_proxy_merge_headers(cf, conf, prev) != NGX_OK) { @@ -2331,6 +2098,7 @@ ngx_http_proxy_merge_headers(ngx_conf_t size_t size; uintptr_t *code; ngx_uint_t i; + ngx_array_t headers_names; ngx_keyval_t *src, *s, *h; ngx_hash_key_t *hk; ngx_hash_init_t hash; @@ -2355,8 +2123,9 @@ ngx_http_proxy_merge_headers(ngx_conf_t } - conf->headers_names = ngx_array_create(cf->pool, 4, sizeof(ngx_hash_key_t)); - if (conf->headers_names == NULL) { + if (ngx_array_init(&headers_names, cf->temp_pool, 4, sizeof(ngx_hash_key_t)) + != NGX_OK) + { return NGX_ERROR; } @@ -2417,7 +2186,7 @@ ngx_http_proxy_merge_headers(ngx_conf_t src = conf->headers_source->elts; for (i = 0; i < conf->headers_source->nelts; i++) { - hk = ngx_array_push(conf->headers_names); + hk = ngx_array_push(&headers_names); if (hk == NULL) { return NGX_ERROR; } @@ -2565,14 +2334,7 @@ ngx_http_proxy_merge_headers(ngx_conf_t hash.pool = cf->pool; hash.temp_pool = NULL; - if (ngx_hash_init(&hash, conf->headers_names->elts, - conf->headers_names->nelts) - != NGX_OK) - { - return NGX_ERROR; - } - - return NGX_OK; + return ngx_hash_init(&hash, headers_names.elts, headers_names.nelts); } @@ -2707,6 +2469,7 @@ ngx_http_proxy_redirect(ngx_conf_t *cf, { ngx_http_proxy_loc_conf_t *plcf = conf; + u_char *p; ngx_str_t *value; ngx_array_t *vars_lengths, *vars_values; ngx_http_script_compile_t sc; @@ -2754,22 +2517,40 @@ ngx_http_proxy_redirect(ngx_conf_t *cf, } if (ngx_strcmp(value[1].data, "default") == 0) { + if (plcf->proxy_lengths) { + ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, + "\"proxy_redirect default\" may not be used " + "with \"proxy_pass\" directive with variables"); + return NGX_CONF_ERROR; + } + if (plcf->url.data == NULL) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, - "\"proxy_rewrite_location default\" must go " + "\"proxy_redirect default\" must go " "after the \"proxy_pass\" directive"); return NGX_CONF_ERROR; } pr->handler = ngx_http_proxy_rewrite_redirect_text; - pr->redirect = plcf->url; if (plcf->vars.uri.len) { + pr->redirect = plcf->url; pr->replacement.text = plcf->location; } else { - pr->replacement.text.len = 0; - pr->replacement.text.data = NULL; + pr->redirect.len = plcf->url.len + sizeof("/") - 1; + + p = ngx_pnalloc(cf->pool, pr->redirect.len); + if (p == NULL) { + return NGX_CONF_ERROR; + } + + pr->redirect.data = p; + + p = ngx_cpymem(p, plcf->url.data, plcf->url.len); + *p = '/'; + + ngx_str_set(&pr->replacement.text, "/"); } return NGX_CONF_OK; @@ -2958,32 +2739,6 @@ ngx_http_proxy_lowat_check(ngx_conf_t *c } -static char * -ngx_http_proxy_upstream_max_fails_unsupported(ngx_conf_t *cf, - ngx_command_t *cmd, void *conf) -{ - ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, - "\"proxy_upstream_max_fails\" is not supported, " - "use the \"max_fails\" parameter of the \"server\" directive ", - "inside the \"upstream\" block"); - - return NGX_CONF_ERROR; -} - - -static char * -ngx_http_proxy_upstream_fail_timeout_unsupported(ngx_conf_t *cf, - ngx_command_t *cmd, void *conf) -{ - ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, - "\"proxy_upstream_fail_timeout\" is not supported, " - "use the \"fail_timeout\" parameter of the \"server\" directive ", - "inside the \"upstream\" block"); - - return NGX_CONF_ERROR; -} - - #if (NGX_HTTP_SSL) static ngx_int_t @@ -3029,12 +2784,10 @@ ngx_http_proxy_set_vars(ngx_url_t *u, ng v->host_header = u->host; if (u->default_port == 80) { - v->port.len = sizeof("80") - 1; - v->port.data = (u_char *) "80"; + ngx_str_set(&v->port, "80"); } else { - v->port.len = sizeof("443") - 1; - v->port.data = (u_char *) "443"; + ngx_str_set(&v->port, "443"); } } else { @@ -3046,10 +2799,8 @@ ngx_http_proxy_set_vars(ngx_url_t *u, ng v->key_start.len += v->host_header.len; } else { - v->host_header.len = sizeof("localhost") - 1; - v->host_header.data = (u_char *) "localhost"; - v->port.len = 0; - v->port.data = (u_char *) ""; + ngx_str_set(&v->host_header, "localhost"); + ngx_str_null(&v->port); v->key_start.len += sizeof("unix:") - 1 + u->host.len + 1; }