mrbean007
mrbean007

Reputation: 37

Nginx reverse proxy redirect

I have a Nginx reverse proxy. How can I redirect it to the real server URL when I download mp3 files in the reverse proxy.

Thanks.

Upvotes: 0

Views: 2364

Answers (2)

randomsock
randomsock

Reputation: 1014

To send to multiple backends, declare an upstream first and proxy to that.

Edit: As you pointed out, that will only work with a proxy. If you specifically want to redirect, you need to pick one. You could write some Lua or NJS to choose one at random, or get close to the same behaviour with a map driven by any built-in variable that has some randomness to it, such as $msec. The example below isn't going to give you strictly uniform distribution, but it does the job and it's really simple to do.

Secondly, a word of caution about using 301 Moved Permanently: This tells the client to remember the redirection and to go to that address instead in future. That's great so long as you get that address right, and it's never - ever - going to change. That becomes a problem if you do ever need to change it, because you would have to get every client to clear their caches first.

To avoid that, consider adding an expiry. How long for is up to you, but the point is it gives you a get-out clause by forcing clients to revalidate with the server occasionally in case it has changed. In the meantime, they still get the benefit of faster client-side redirection.

Edit: Better still, for something like this where you are effectively load balancing, use 302 so the same client will always come back and may choose a different upstream each time.

map $msec $mp3server {
    ~[0-2]$ 10.10.1.1:8080;
    ~[3-5]$ 10.10.1.2:8080;
    ~[6-9]$ 10.10.1.3:8080;
}

server {
    listen 6777; 

    location ~ \.(mp3|wav)$ {
        #expires 1h;
        #return 301 http://$mp3server$request_uri;
        # or
        return 302 http://$mp3server$request_uri;
    }

    location / {
        proxy_pass http://example.com/;
        proxy_http_version 1.1;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Host $host;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "Upgrade";
    }
}

Testing that seemed to work as well as can be hoped (check the Locations):

$ curl -I http://127.0.0.1:6777/foo.mp3
HTTP/1.1 301 Moved Permanently
Server: nginx/1.18.0
Date: Wed, 12 Aug 2020 15:08:40 GMT
Content-Type: text/html
Content-Length: 169
Connection: keep-alive
Location: http://10.10.1.1:8080/foo.mp3
Expires: Wed, 12 Aug 2020 16:08:40 GMT
Cache-Control: max-age=3600

$ curl -I http://127.0.0.1:6777/foo.mp3
HTTP/1.1 301 Moved Permanently
Server: nginx/1.18.0
Date: Wed, 12 Aug 2020 15:08:41 GMT
Content-Type: text/html
Content-Length: 169
Connection: keep-alive
Location: http://10.10.1.2:8080/foo.mp3
Expires: Wed, 12 Aug 2020 16:08:41 GMT
Cache-Control: max-age=3600

$ curl -I http://127.0.0.1:6777/foo.mp3
HTTP/1.1 301 Moved Permanently
Server: nginx/1.18.0
Date: Wed, 12 Aug 2020 15:08:42 GMT
Content-Type: text/html
Content-Length: 169
Connection: keep-alive
Location: http://10.10.1.3:8080/foo.mp3
Expires: Wed, 12 Aug 2020 16:08:42 GMT
Cache-Control: max-age=3600

Upvotes: 2

mrbean007
mrbean007

Reputation: 37

server {
            listen 6777; 
                location ~ \.(mp3|wav)$ {
                return 301 http://10.10.1.1:8080$request_uri;
                }
             
                location / {
                proxy_pass http://backend;
                proxy_http_version 1.1;
                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
                proxy_set_header Host $host;
                proxy_set_header Upgrade $http_upgrade;
                proxy_set_header Connection "Upgrade";
               }

}

Upvotes: 0

Related Questions