Nginx Redirect via Proxy, Rewrite and Preserve URL

nginxPROXYredirectrewrite

In Nginx we have been trying to redirect a URL as follows:

http://example.com/some/path -> http://192.168.1.24

where the user still sees the original URL in their browser. Once the user is redirected, say they click on the link to /section/index.html, we would want this to make a request that leads to the redirect

http://example.com/some/path/section/index.html -> http://192.168.1.24/section/index.html

and again still preserve the original URL.

Our attempts have involved various solutions using proxies and rewrite rules, and below shows the configuration that has brought us closest to a solution (note that this is the web server configuration for the example.com web server). However, there are still two problems with this:

  • It does not perform the rewrite properly, in that the request URL received by the web server http://192.168.1.24 includes /some/path and therefore fails to serve the required page.
  • When you hover on a link once a page has been served, /some/path is missing from the URL

    server {
        listen          80;
        server_name     www.example.com;
    
        location /some/path/ {
            proxy_pass http://192.168.1.24;
            proxy_redirect http://www.example.com/some/path http://192.168.1.24;
            proxy_set_header Host $host;
        }
    
        location / {
            index index.html;
            root  /var/www/example.com/htdocs;
        }
    }
    

We are looking for a solution that only involves changing the web server configuration on example.com. We are able to change the config on 192.168.1.24 (also Nginx), however we want to try and avoid this because we will need to repeat this setup for hundreds of different servers whose access is proxied through example.com.

Best Answer

First, you shouldn't use root directive inside the location block, it is a bad practice. In this case it doesn't matter though.

Try adding a second location block:

location ~ /some/path/(?<section>.+)/index.html {
    proxy_pass http://192.168.1.24/$section/index.html;
    proxy_set_header Host $host;
}

This captures the part after /some/path/ and before index.html to a $section variable, which is then used to set the proxy_pass destination. You can make the regex more specific if you require.