URI escaping for X-Accel-Redirect and proxy_pass in 1.4.7 and 1.6.0

We are updating Nginx from 1.4.7 and 1.6.0 and noticed an error in our
app
likely related to the 1.5.9 change: now nginx expects escaped URIs in
“X-Accel-Redirect” headers.

We have an internal location for proxying content from a backend HTTP
system
(Swift, actually). The location block looks like this:

location ~
^/protected/swift/(http|https)/([A-Za-z0-9.-]+)/([1-9][0-9]+)/([A-Za-z0-9_]+)/(.*)
{
internal;
proxy_set_header X-Auth-Token $4;
proxy_pass $1://$2:$3/$5;
proxy_hide_header Content-Type;
}

Nginx 1.4.7 functions as expected when sending X-Accel-Redirect:
/protected/swift/http/HOST/PORT/TOKEN/v1/AUTH_test/content/image%20with%20spaces.jpg

Under 1.6.0 this fails. It produces a GET request to the backend decoded
into spaces and so becomes an invalid HTTP request.

The workaround is to double encode so as to send back
“image%2520with%2520spaces.jpg” to Nginx but we can’t roll this out
until
Nginx 1.6 because it breaks 1.4… but we can’t roll out 1.6 until the
code
is there.

Is there a solution that works for both?

Posted at Nginx Forum:

Jonathan M. Wrote:

header containing the nginx version to your backend, and get it to
switch its X-Accel-Redirect response based on this value?

J

This was the only clean, cross-version solution I could think of too and
would recommend to others. We didn’t end up going with it though as we
ended
up having to fast track the 1.6 rollout for other reasons, so we took a
brief window of errors on the chin and cleaned them up later.

Thanks, though.

Posted at Nginx Forum:

On 17 June 2014 07:49, gwilym [email protected] wrote:

The workaround is to double encode so as to send back
“image%2520with%2520spaces.jpg” to Nginx but we can’t roll this out until
Nginx 1.6 because it breaks 1.4… but we can’t roll out 1.6 until the code
is there.

I don’t have a nice fix for you I’m afraid! However, as a way to get
out of your chicken-and-egg upgrade problem, could you pass a static
header containing the nginx version to your backend, and get it to
switch its X-Accel-Redirect response based on this value?

J