X-Accel-Redirect is urlencoding my already urlencoded request

W. Andrew Loe III andrew at andrewloe.com
Tue Dec 2 00:58:03 MSK 2008


I use X-Accel-Redirect to proxy requests from my application to
Amazon's S3 while retaining more control over caching and expiration.
To do this, I generate an authenticated S3 URL which looks something
like this:

https://s3.amazonaws.com/MY_BUCKET/KEY_NAME?Signature=GENERATED_SIGNATURE&Expires=TIMESTAMP&AWSAccessKeyId=MY_SECRET_KEY

An example from my applicaiton:
https://s3.amazonaws.com/dev-Andrew.onehub.com/public%2FDATA%2F95%2Fpreview?Signature=Agg5KzsZxKS6XXXXX&Expires=1228XXXXX&AWSAccessKeyId=XXXXXXX

The 'key' (or path as far as nginx is concerned) is already a
urlencoded string, because Amazon's keys are allowed to have spaces,
slashes, dashes etc.

For my use, I strip off the host and tack on an internal address which
then proxies to S3,

location /AWSS3/ {
  proxy_pass http://s3.amazonaws.com/;
  internal;
}

https://s3.amazonaws.com/dev-Andrew.onehub.com/public%2FDATA%2F95%2Fpreview?Signature=Agg5KzsZxKS6XXXXX&Expires=1228XXXXX&AWSAccessKeyId=XXXXXXX

becomes (done by my Rails application)

/AWSS3/dev-Andrew.onehub.com/public%2FDATA%2F95%2Fpreview?Signature=Agg5KzsZxKS6XXXXX&Expires=1228XXXXX&AWSAccessKeyId=XXXXXXX

The signature is computed from the method, the size of the key and the
key name, so changing the hostname or path has no negative
consequences. Here is my problem, when nginx requests this URL on the
user's behalf it requests it as:
/dev-Andrew.onehub.com/public%252FDATA%252F95%252Fpreview?Signature=Agg5KzsZxKS6XXXXX&Expires=1228XXXXX&AWSAccessKeyId=XXXXXXX

It has encoded the % signs in the path as %25 so the already encoded /
(%2F) becomes %252F which doesn't decode properly into the key on
Amazon's side and I get an error that the Signature does not match.

One solution is to not url encode the path name when I generate my
signature (i.e. make something like
/dev-Andrew.onehub.com/public/DATA/95/preview?Signature=Agg5KzsZxKS6XXXXX&Expires=1228XXXXX&AWSAccessKeyId=XXXXXXX
), but this doesn't let me use keys with special characters which I
want.

Is there a way to have nginx NOT change the X-Accel-Redirected request
in anyway?





More information about the nginx mailing list