Nginx 302 redirect – resolve internally

nginxredirect

Currently, we have a server that implements a 302 redirect to server some content. For example, the user request:

http://origin1.example.com/m3ugen/segsrc/jet480.mp4

And this server responds with 302 and serves:

http://origin1.example.com/Segments/HLS_TS/segsrc/jet480.mp4-20140831-142558.m3u8`

This is problematic for us and we would like to let Nginx handle this to be more user friendly and to work with some players that does not handle 302 redirection.

What we want is:

  1. User request http://frontend.example.com/hls/jet480.mp4.m3u8 and received by nginx.

  2. Nginx make request to http://origin1.example.com/m3ugen/segsrc/jet480.mp4

  3. Nginx receive redirect code 302 http://origin1.example.com/Segments/HLS_TS/segsrc/jet480.mp4-20140831-142558.m3u8

  4. Nginx make request to http://origin1.example.com/Segments/HLS_TS/segsrc/jet480.mp4-20140831-142558.m3u8 and serve the response directly to the user without any 302 redirection.

I think that this could be done with Nginx but we have no much experience about it. Any help will be very appreciated.

P.D. We can't configure the origin server. It uses Helix Server and when serves the m3u8 playlist it adds a timestamp that changes for every file.

Best Answer

This is not ideal and it would be far better to have a clean workflow instead of doing this. But for curiosity, this could be informative to people that would wonder if it's possible.

Yes it is, using a combination of error_page, rewrite, map, proxy_intercept_errors and proxy_redirect directives and $upstream_http var pattern.

Keep in mind that it's going far off the path nginx is designed to be driven on.

map $upstream_http_location $redirect_uri {
    "~http://[^/]+/(?<location_uri>.*)$" "$location_uri";
}

upstream origin {
    server origin1.com;
}

server {

    listen 80;
    server_name nginx-front.com;

    proxy_set_header Host "origin1.com";
    proxy_redirect http://origin1.com/ /;

    location ~ ^/hls/(\w+)\.mp4\.m3u8$ {
        proxy_pass http://origin/m3ugen/segsrc/$1.mp4;
        proxy_intercept_errors on;
        error_page 301 302 = @handler;    
    }

    location @handler {
        rewrite ^ /$redirect_uri break;
        proxy_pass http://origin;
    }

}
Related Topic