Reputation: 15112
We have a couple of backends sitting behind our nginx front ends.
Is it possible to intercept 301 / 302 redirects sent by these backends and have nginx handle them?
We were thinging something alone the lines of:
error_page 302 = @target;
But I doubt 301/302 redirects can be handled the same as 404's etc etc... I mean, error_page probably doesnt apply to 200, etc error codes?
So to summarize:
Our backends send back 301/302s once in a while. We would like to have nginx intercept these, and rewrite them to another location block, where we could do any number of other things with them.
Possible?
Thanks!
Upvotes: 28
Views: 61821
Reputation: 401
You could use proxy_redirect
directive (documentation).
Nginx will still return 301/302 to the client but proxy_redirect
will modify Location
header and the client should make a new request to the URL given in the Location
header.
Something like this should make the subsequent request back to nginx:
proxy_redirect http://upstream:port/ http://$http_host/;
Upvotes: 28
Reputation: 776
If you need to follow multiple redirects, modify Vlad's solution as follows:
Add
recursive_error_pages on;
to location /
.
Add
proxy_intercept_errors on;
error_page 301 302 307 = @handle_redirects;
to the location @handle_redirects
section.
Upvotes: 12
Reputation: 12627
More on proxy_redirect
, for relative locations
location /api/ {
proxy_pass http://${API_HOST}:${API_PORT}/;
}
/api/
prefixlocation /api/ {
proxy_pass http://${API_HOST}:${API_PORT}/;
proxy_redirect ~^/(.*) http://$http_host/api/$1;
}
Upvotes: 8
Reputation: 7756
I succeeded in solving a more generic case when a redirect location can be any external URL.
server {
...
location / {
proxy_pass http://backend;
# You may need to uncomment the following line if your redirects are relative, e.g. /foo/bar
#proxy_redirect / /;
proxy_intercept_errors on;
error_page 301 302 307 = @handle_redirects;
}
location @handle_redirects {
set $saved_redirect_location '$upstream_http_location';
proxy_pass $saved_redirect_location;
}
}
Alternative approach, which is closer to what you describe, is covered in ServerFault answer to this question: https://serverfault.com/questions/641070/nginx-302-redirect-resolve-internally
Upvotes: 16