In a project that I use with nginx, I have an proxied upstream that returns a redirect to another url.

The new destination is not available to the end user, and anyway I want this to be transparent to the end user. How can I configure nginx in order to handle this ?

There are many resources online that offer help on this, but I had mixed results. What worked for me was a configuration as follows.

Let’s say that I want to serve url of the type https://example.com/item/:id, where :id can be any number. Any request to such an url should be forwarded to https://upstream.com/someservice?item=:id. My issue is that for a number of reason such service will respond with a redirect to https://upstream.com/someservice/item/:id?token=sometoken, which cannot be reached by the end users, so I need nginx to handle it for me.

I finally found a solution that works for me, and it is something as follows:

server_name example.com;

# ...

location ~ ^/item/(.*)$ {
    proxy_pass https://upstream.com/someservice?item=$1;
	proxy_intercept_errors on;
	recursive_error_pages on;
	error_page 301 302 303 307 308 = @handle_redirect;
}

location @handle_redirect {
    # For some reasons, directly using the variable doesn't work
	set $saved_redirect_location '$upstream_http_location';
    proxy_intercept_errors on;
    recursive_error_pages on;
    error_page 301 302 303 307 308 = @handle_redirect;
}

In other words, you tell nginx to handle redirects result with a virtual location that handles the redirect properly.

What I couldn’t find online is that if there are multiple redirects involved (like it was my case), you need to explicitly handle them in the virtual location too (hence the proxy_intercept_errors, recursive_error_pages and error_page directives in the virtual location too).