HTTP reverse proxy redirect internally
To me, this seems like a simple scenario:
- Client makes request to reverse proxy at server
X
(http://proxy.example.com
) - Server
X
forwards request to backend serverY
(http://internal1.example.com:8000
) - Backend server
Y
responds with3xx
redirect to another backend serverZ
(http://internal2.example.com:8000
) - Proxy server
X
intercepts the 3xx redirect and makes the request again to backend serverZ
. It does not return the 3xx redirect back to the client. - Proxy server
X
responds to the client with the result of the redirected request from backend serverZ
.
I need this because some clients do not seem to handle the redirection (especially when doing PUT), so I would like the redirection to happen invisibly and internally on the proxy server. (I am actually running a WebDAV server on the backend, so my clients are Cyberduck, Nautilus, OSX Finder, etc).
I've searched a huge amount for an existing answer to this, but had no luck (this question is basically what I want, but there are no satisfactory answers and it's been inactive for a year. Hopefully things have changed since then).
I would like to use an existing soluion for this if possible. Is it possible with Apache/Nginx?
Solution 1:
So after much more googling, and a chat with the apache guys on IRC, it seems to be impossible with apache. So I took a look at nginx, and managed to find a solution using X-Accel-Redirect
with a configuration like the one at the end of this answer.
See the relevant blog posts:
- http://kovyrin.net/2010/07/24/nginx-fu-x-accel-redirect-remote/
-
http://kovyrin.net/2006/11/01/nginx-x-accel-redirect-php-rails/
server { listen 80; server_name example.com; location / { proxy_pass http://localhost:8000/; proxy_redirect http://localhost:8001 http://$host:8001; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } # Proxy download location ~* ^/internal_redirect/(.*?)/(.*) { # Do not allow people to mess with this location directly # Only internal redirects are allowed internal; # Location-specific logging access_log internal_redirect.access.log main; error_log internal_redirect.error.log debug; # Extract download url from the request set $download_uri $2; set $download_host $1; # Compose download url set $download_url http://$download_host/$download_uri?$args; # Set download request headers proxy_set_header Host $download_host; proxy_set_header Authorization ''; # The next two lines could be used if your storage # backend does not support Content-Disposition # headers used to specify file name browsers use # when save content to the disk # proxy_hide_header Content-Disposition; # add_header Content-Disposition 'attachment; filename="$args"'; # Do not touch local disks when proxying # content to clients proxy_max_temp_file_size 0; # Download the file and send it to client # This is where the magic happens proxy_pass $download_url; } }