I am writing an Nginx configurations for Crystal-Lang based application to send all the traffic http://example.com/videos/
to http://0.0.0.0:3000
via reverse proxy.
I have written the following config which is not working and I’m heading over the internet but no luck.
When I go to http://example.com/videos/
, application internally performing a redirect from http://example.com/
to http://example.com/feed/popular
which is the problem, it redirects to http://example.com/feed/popular
which is wrong, I need /videos/
part to always concatenated with URL like http://example.com/videos/xxxx
always but after redirect the /videos/
part is being chopped out.
So the application should consider http://example.com/videos/
as host.
Here is my config:
server {
listen 80;
server_name elearn.com.pk default_server localhost;
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
location /videos/ {
proxy_pass http://0.0.0.0:3000/;
proxy_http_version 1.1;
rewrite /videos/(.*) /$1 break;
proxy_redirect off;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host/videos/;
proxy_set_header X-NginX-Proxy true;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
}
Can someone please help me to resolve this issue please? Thanks.
3
Answers
Assuming the redirect comes from the proxied application, you need to rewrite the
Location
header to match the prefix path on the proxy server.proxy_redirect off
is causing this error. You need to set it todefault
or configure a custom rewrite (default
should work fine for your purpose, though).You should define
upstream
inhttp
directive.Then use it in the
server
scope inlocation
like this:You can use
proxy_redirect
to force change the header ofLocation
the upstream returned redirect.If I want nginx to dispatch the path
foo
to an upstream app with listen port is 7001, the simplest configure:However, for my situation, this reverse proxied upstream app will return a redirect of
301 Moved Permanently
with headerLocation:/bar/
when user successfully login. (You can know how the redirect works by tracing network activity via DevTools of a browser.)I want
xxx.com/foo/bar
=>localhost:7001/bar
, but because the incorrectLocation
of its redirect, by combing thehost
header it will returnxxx.com/bar
to clients. The problem is, it will require nginx to look locationlocation /bar/ {...}
, which is not configured at all.Naturally, one brutal way in my head is to use another redirect to correct the url:
After thinking, I realize a more favorable solution is to just change the Location of the returned redirect package directly. Fortunately, the
proxy_redirect
of nginx provides this function to allow us change the Location of proxied redirect.from: http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_redirect.
OK, here is the solution:
A simply way to replace the wrong Location from
/bar/
to/foo/bar/
theLocation
field fixed my problem.PS: a trick of debuggin nginx and network activity is to use new “Incognito window” every time. Or the browser cache will give you misleading reaction.