Re: nginx подменяет заголовок Location: в проксированом ответе
Maxim Dounin
mdounin на mdounin.ru
Пт Фев 26 18:39:08 MSK 2010
Hello!
On Fri, Feb 26, 2010 at 02:04:13PM +0300, Vladimir Rusinov wrote:
> Либо это фича, либо баг - не понимаю.
[...]
> location / {
> proxy_pass http://wrike;
> }
[...]
> Как видно, вместо Location: http://wrikerobot.appspot.com/ отдается
> Location: robot.appspot.com.
Это багофича proxy_redirect default при использовании proxy_pass
без uri. Workaround:
proxy_redirect off;
Патч прилагается.
Maxim Dounin
-------------- next part --------------
# HG changeset patch
# User Maxim Dounin <mdounin at mdounin.ru>
# Date 1267197892 -10800
# Node ID ab19ddd5811ce36fbcf3bd0f8a9119e9e3879080
# Parent dd5526e935d256a3f8c55e5ffde9890d1e1e4a8d
Proxy: fix proxy_redirect default and proxy_pass without uri.
This fixes redirect returned if domain in Location header returned by backend
starts with backend name as written in nginx config. E.g. with config
location / {
proxy_pass http://server;
}
if backend returns "Location: http://server.example.com/" resulting redirect
was to ".example.com/" which is obviously wrong.
diff --git a/src/http/modules/ngx_http_proxy_module.c b/src/http/modules/ngx_http_proxy_module.c
--- a/src/http/modules/ngx_http_proxy_module.c
+++ b/src/http/modules/ngx_http_proxy_module.c
@@ -1968,6 +1968,7 @@ 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;
@@ -2214,14 +2215,26 @@ 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 = '/';
+
+ pr->replacement.text.len = sizeof("/") - 1;
+ pr->replacement.text.data = (u_char *) "/";
}
}
}
@@ -2707,6 +2720,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;
@@ -2762,14 +2776,26 @@ ngx_http_proxy_redirect(ngx_conf_t *cf,
}
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 = '/';
+
+ pr->replacement.text.len = sizeof("/") - 1;
+ pr->replacement.text.data = (u_char *) "/";
}
return NGX_CONF_OK;
Подробная информация о списке рассылки nginx-ru