rewritten redirect with relative url
Dave Bailey
dave at daveb.net
Wed Feb 1 01:37:22 UTC 2012
Hi,
On Tue, Jan 31, 2012 at 5:13 PM, Maxim Dounin <mdounin at mdounin.ru> wrote:
> Hello!
>
> On Tue, Jan 31, 2012 at 03:39:03PM -0800, Dave Bailey wrote:
>
> > Hi,
> >
> > In ngx_http_upstream_rewrite_location(), r->upstream->rewrite_redirect
> may
> > replace the Location header value with a new value. This value ends up
> > going through ngx_http_header_filter(), and if it's a relative URL, the
> > header filter adds a scheme and host to it. However, if
> > r->upstream->rewrite_redirect declines (rc = NGX_DECLINED) to rewrite the
> > redirect, the value does not go through ngx_http_header_filter() even if
> it
> > is a relative URL.
> >
> > Is this intended behavior? If it is not, I attached a patch that sets
> > r->headers_out.location consistently.
>
> I believe the intended behaviour is:
>
> 1. If we got relative redirect from a backend and are going to pass it
> to a client - don't touch it. It's backend which breaks RFC, so
> we don't care.
>
> In the code path without upstream->rewrite_redirect set you may even see
> special code to protect such redirects:
>
> if (ho->value.data[0] != '/') {
> r->headers_out.location = ho;
> }
>
> /*
> * we do not set r->headers_out.location here to avoid the handling
> * the local redirects without a host name by ngx_http_header_filter()
> */
>
> return NGX_OK;
>
> 2. If we are about to produce our own relative redirect - make
> sure it will be properly converted to absolute one by the header
> filter.
>
OK, thank you. So this is intended.
The problem I am having is that the conversion to an absolute URL always
uses a scheme of http:// unless the connection is an actual SSL
connection. This means that if SSL is terminated at a load balancer and
nginx listens on a non-SSL port, rewritten redirects are converted to
absolute with a scheme of http:// even though the actual request was
https://.
I can work around it by having my callback emit an absolute URL with the
correct scheme. But, any interest in providing a way for nginx to do the
same? e.g.
server {
# SSL terminated elsewhere
listen 444;
# force https scheme on rewritten redirects converted to absolute urls
scheme_https on;
}
> The code looks correct here.
>
> The problem I see is that if rewrite_redirect() returns
> NGX_DECLINED, the r->headers_out.location won't be set and it
> won't be possible to clear it in case we'll need to.
>
> The same applies to relative redirects from a backend though, and
> requires reconsidering of the "don't set r->headers_out.location
> to avoid handling by ngx_http_header_filter()" policy to make
> mentioned clearing indeed possible.
>
> Maxim Dounin
>
> _______________________________________________
> nginx-devel mailing list
> nginx-devel at nginx.org
> http://mailman.nginx.org/mailman/listinfo/nginx-devel
>
-dave
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mailman.nginx.org/pipermail/nginx-devel/attachments/20120131/62789bd5/attachment.html>
More information about the nginx-devel
mailing list