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