Dynamic Proxy Pass - is there a more elegant solution?

W. Andrew Loe III andrew at andrewloe.com
Wed Oct 17 17:33:15 UTC 2012

I'm X-Accel-Redirecting URLs that look like:


Right now my location that handles these and requests from S3 looks like this:

location ~ /AWSS3/(.*) {
  # Store our ETag value.
  set $rails_etag $upstream_http_etag;

  # Prevent Amazon from overwriting our Headers.
  proxy_hide_header Content-Type;
  proxy_hide_header ETag;

  # Hide Amazon Headers
  proxy_hide_header X-Amz-Id-2;
  proxy_hide_header X-Amz-Request-Id;

  # Set the HTTP Host header to S3.
  proxy_set_header Host 's3.amazonaws.com';

  # Force Amazon to do the heavy lifting.
  proxy_max_temp_file_size 0;

  # Ensure tight timeouts, we'll retry the requests to a different backend in
  # the event of failures.
  proxy_connect_timeout 5;
  proxy_send_timeout 10;
  proxy_read_timeout 10;

  # Retry if Amazon freaks out.
  proxy_next_upstream error timeout http_500 http_502 http_503 http_504;

  # Ensure the requests are always gets.
  proxy_method GET;
  proxy_set_header Method 'GET';
  proxy_set_header Content-Length "";
  proxy_set_header Cookie "";
  proxy_set_header Content-Type "";

  # Clear any CloudFront headers.
  proxy_set_header X-Amz-Cf-Id "";

  # We use the query string for Authorization, clear headers that the client
  # may have sent.
  proxy_set_header Authorization "";

  # Resolver, for dynamically proxied requests.

  # Proxy to S3.
  set $s3 "s3-external-2.amazonaws.com";
  proxy_pass https://$s3/$1$is_args$args;

  # Add back our own ETag.
  add_header ETag $rails_etag;


Is there a way to avoid having to capture the path in the location
block and reconstruct it with $is_args$args?

I would like something more like:

location /AWSS3/ {
  proxy_pass https://$s3/;

which does work when passing to an upstream block (https://s3/ with
upstream s3 defined).

I prefer this method as it re-resolves the DNS periodically.

More information about the nginx mailing list