I got a server which serves Data to a client ( in my case MP3s ). The
MP3s are saved in a storage directory in the form Artist - Title.mp3
I’m using X-Accel-Redirect to serve the files from the storage dir to
the user. This workes fine for most cases but fails for special chars
like the question mark. I already tried encoding it - but the char
always gets stripped like in Query strings. But since it’s not an url
I’m providing no stripping should take place. Here are my results:
Example Filename is: /ext/53665/Katy Perry - Who Am I Living
For?.mp3
Plain:
open() “/ext/53665/Katy Perry - Who Am I Living For” failed (2: No such
file or directory)
urlencoded:
open()
“/usr/local/nginx/html%2Fdl%2F53665%2FKaty+Perry±+Who+Am+I+Living+For%253F.mp3”
failed (2: No such file or directory)
Rawurlencoded:
open()
“/usr/local/nginx/html%2Fdl%2F53665%2FKaty%20Perry%20-%20Who%20Am%20I%20Living%20For%3F.mp3”
failed (2: No such file or directory)
Replaced ? with ?
open() "/ext/53665/Katy Perry - Who Am I Living For" failed (2: No such
file or directory)
Escaped ? to %3F
open() “/ext/53665/Katy Perry - Who Am I Living For%3F.mp3” failed (2:
No such file or directory)
It seems like X-Accel-Redirect treats the path as url instead of a
realpath - or even doesn’t apply any decoding on the subrequest.
Hi,
I created a small patch for that issue which works for me. But it needs
to be reviewed by Igor or someone who knows C better than me.
It checks the static request from X-Accel-Redirect for ‘%’ and escapes
them if found.
Hi,
you cannot use the presence of a character as an indicator to determine
if
a string is encoded or not. After all “%” is a perfectly legitimate
character that can be used for a filename or directory.
The question is whether path.data represents the raw encoded version of
the
path in which case it must always be decoded or if this variable
already
represents the decoded version of the path in which case it should never
be decoded a second time.
On Wed, Sep 08, 2010 at 09:53:14AM -0400, rovervr wrote:
Hi everyone,
I got a server which serves Data to a client ( in my case MP3s ). The
MP3s are saved in a storage directory in the form Artist - Title.mp3
I’m using X-Accel-Redirect to serve the files from the storage dir to
the user. This workes fine for most cases but fails for special chars
like the question mark. I already tried encoding it - but the char
always gets stripped like in Query strings. But since it’s not an url
I’m providing no stripping should take place. Here are my results:
X-Accel-Redirects expects URI, but unescaped one. This was
last discussed yesterday:
X-Accel-Redirect expected to contain non-encoded URI. This isn’t
really right, but it’s how it currently works.
In particular this makes impossible to (normally) serve resources
with ‘?’ in name as you see in your tests, as anything after ‘?’
is treated as query string.
Correct fix would be to change X-Accel-Redirect to accept escaped
URI instead. I believe patches are welcome.
Don’t get me wrong … but isn’t X-Accel-Redirect for serving static
files without the overhead of php-fpm/fastcgi? Can you provide an
example where X-Accel-Redirect is used for dynamic files?
The patch works for me because I just use nginx to serve download files,
but I’d like to provide a patch that fixes the wrong behaviour of
X-Accel-Redirect for everyone.
On Thu, Sep 09, 2010 at 08:03:07AM -0400, rovervr wrote:
I created a small patch for that issue which works for me. But it needs
to be reviewed by Igor or someone who knows C better than me.
It checks the static request from X-Accel-Redirect for ‘%’ and escapes
them if found.
This patch is wrong, it breaks access to normal files with ‘%’.
Additionally, it doesn’t change X-Accel-Redirect behaviour for
non-static files.
Instead X-Accel-Redirect value should be unescaped when it got
from upstream, somewhere before ngx_http_internal_redirect() call.
I personally believe ngx_http_parse_unsafe_uri() should be changed
to unescape uri (note that it will also affect ssi and dav
modules). Though I haven’t investigated this carefully enough.
On Thu, Sep 09, 2010 at 02:19:55PM -0400, rovervr wrote:
example where X-Accel-Redirect is used for dynamic files?
With X-Accel-Redirect you may redirect request to anything you
want, e.g. to appropriate backend.
On Thu, Sep 09, 2010 at 02:29:04PM -0400, rovervr wrote:
This code fixes the double encoding issue while serving static files
without X-Accel-Redirect as stated by Maxim
This one is wrong as well. It won’t solve the problem even for
static files when original request happened to contain escaped
chars.
And, as I already said, there is no sense to guess anything in
static module. The problem should be solved elsewere, preserving
invariant of r->uri being unescaped uri without args.
The escaping takes place at ngx_http_parse_unsafe_uri() as Maxim
suggested.
s/escaping/unescaping/
This patch is wrong. It will unescape query string as well, which
is expected to remain escaped. Additionaly, at least “…/” unsafe
check should be reconsidered after unescaping.
Maxim D.
This forum is not affiliated to the Ruby language, Ruby on Rails framework, nor any Ruby applications discussed here.