How can I rewrite an uri without returning a redirect in the process in Nginx ?
The rewrite result is in the same host.
Exemple: rewrite "mysite.com/foo" returning the same result as "mysite.com/bar", but we dont change the uri in the process.
It's kinda like a proxy_pass but for the same host.
You can proxy_pass to host+uri.
location ~ ^/foo/(.*)$ {
include proxy_params;
proxy_pass http://127.0.0.1/bar/$1;
}
Or rewrite and proxy_pass should work:
location ~ ^/foo {
rewrite ^foo(.*) /bar$1
proxy_pass http://example.com;
}
I hope any of those 2 works for you.
Related
I would like to rebuild a URL and redirect from https://test.com/info/schoolName/detail to https://test.com/school-info?name=schoolName with Nginx.
I have tried
location ~ ^/(school-info)(?:/(.*))?$ {
include /etc/nginx/servers/platform/shared/headers_proxy.conf;
proxy_set_header Host $backend_netlify_main;
proxy_ssl_server_name on;
proxy_pass https://$backend_netlify_main/$1/$2;
}
...
...
location ~* ^/(info|info/)$ {
include /etc/nginx/servers/platform/shared/headers_proxy.conf;
rewrite ^/info/(.?)/(.*)$ /school-info?school=$1 permanent;
proxy_pass $backend_cms;
}
however, if I visit https://test.com/info/byu/detail it's not doing a redirect at all.
EDIT: The /detail at the end is not important at all, so regardless of what is at the end of the URL the /schoolName/ is the most important part to be passed as a query parameter.
I think you need something like
location / { # "default" location
# do redirection for '/info/...' URIs
rewrite ^/info/([^/])* /school-info/$1 permanent;
# otherwise pass request to the default backend
proxy_pass $backend_cms;
}
location /school-info {
include /etc/nginx/servers/platform/shared/headers_proxy.conf;
proxy_set_header Host $backend_netlify_main;
proxy_ssl_server_name on;
proxy_pass https://$backend_netlify_main;
}
if you need to pass a request as /school-info/schoolName, or
location / { # "default" location
# do redirection for '/info/...' URIs
rewrite ^/info/([^/])* /school-info?name=$1 permanent;
# otherwise pass request to the default backend
proxy_pass $backend_cms;
}
location /school-info {
include /etc/nginx/servers/platform/shared/headers_proxy.conf;
proxy_set_header Host $backend_netlify_main;
proxy_ssl_server_name on;
proxy_pass https://$backend_netlify_main/school-info$is_args$args;
}
if you need to pass a request as /school-info?name=schoolName.
If i go to site https://example.com/media/https://google.com/imageurl
I want that the url openes the site after /media.
So i want to open https://google.com/imageurl but not a complete redirect.
It must stay on my domain, is that working?
I tried something like that, but not working :/
rewrite ^/media/(.*).(png|jpg|gif) $1.$2 ;
So everything after /media/ i will display show on my own domain, is something that working?
What you want to do is calling "transparent proxying". You cannot do this with simple rewrite. You can try this:
location ~ ^/media/(?<proto>https?:)/+(?<domain>[^/]+)(?<subreq>/.+\.(?:png|jpg|gif))$ {
proxy_ssl_server_name on;
proxy_set_header Host $domain;
proxy_pass $proto//$domain$subreq;
}
or this:
location ~ ^/media/(?<proto>https?:)/+(?<domain>[^/]+)(?<subreq>/.+\.(?:png|jpg|gif))$ {
proxy_ssl_server_name on;
proxy_set_header Host $domain;
rewrite .* $subreq break;
proxy_pass $proto//$domain;
}
You will also need a resolver directive in your config to use this.
Only need to proxy pass remaining url when match to location
location /blog { proxy_pass http://example.com }
i.e if somebody requests /blog/page1/temp.html they are getting proxy passed to example.com/blog/page1/temp.html
I want to change it to example.com/page1/temp.html
I want to change example.com/blog/page1/temp.html to example.com/page1/temp.html
Specify uri into proxy pass directive (/ after hostname in this case):
location /blog/ {
proxy_pass http://example.com/;
}
Or use rewrite like this:
location /blog {
rewrite /blog/([^/]+) $1;
proxy_pass http://example.com
}
Looking through the error.log file of Nginx, we can see requests coming as one of two incorrect patterns:
http://www.example.com/app-contextmoduleA/controller1 -> should be http://www.example.com/app-context/moduleA/controller1
http://www.example.com/app-contextcontroller2 -> should be http://www.example.com/app-context/moduleB/controller2
The current Nginx configuration looks like this:
server {
listen 8080;
location /app-context/ {
proxy_redirect off;
proxy_set_header Host $host;
proxy_pass http://localhost:8888/app-context/;
}
}
The challenge is inserting the missing / after app-context (for the first wrong URL) or missing /moduleB/ (for the second wrong URL). It doesn't look like try_files would support that, and I have not found a way to do it with rewrite.
Is there a way for Nginx to rewrite the URLs for both use cases? In particular, I would prefer not to have to know all the name of the modules or controllers in advance. There are many, so "hard-coding" them in the rewrite rule would be onerous.
These should handle your example case:
location /app-context {
rewrite ^(/app-contextmoduleA)/(.*)$ /app-context/moduleA/$2 permanent;
rewrite ^(/app-contextcontroller2) /app-context/moduleB/controller2 permanent;
...
}
Check the ngx_http_rewrite_module for more info.
Looking through quite a few online resources and through trial and error, I was able to come to a good-enough solution:
location /app-context {
location ~ (moduleA|moduleB) {
# inserts a forward slash after app-context if not there,
# e.g. /app-contextmoduleA/foo/bar to /app-context/moduleA/foo/bar
rewrite ^(/app-context(?!/))(.*) $1/$2 break;
try_files $uri #proxy;
}
# inserts /defaultModule/ after app-context
# e.g. /app-context/controller1 to /app-context/defaultModule/controller1
rewrite ^(/app-context(?!/defaultModule/))(.*) $1/defaultModule/$2 break;
try_files $uri #proxy;
}
location #proxy {
proxy_redirect off;
proxy_set_header Host $host;
proxy_pass http://localhost:8888;
}
I have my nginx conf like :
location ^~ /mount_points/mount_point1 {
internal;
alias /repos/mount_point_one;
}
location ^~ /to_proxy {
internal;
proxy_pass http://myproxy:5000;
}
When I request for 'http://localhost/mount_points/mount_point1/myfile.zip' I get "/repos/mount_point_one/myfile.zip" as expected.
While request for 'http://localhost/to_proxy/myfile2.html', I get "http://myproxy:5000/to_proxy/myfile2.html".
In the first case, the "/mount_points/mount_point1" part was removed, and in the second case, the "/to_proxy" part still there, I have to fake a "/to_proxy" address in the upstream server to find out this.
Did I missed something? If I just have to rewrite the url, how can I delete the "/to_proxy" part issue to the upstream server?
Thank you.
The proxy_pass directive can perform an aliasing function, but only if an optional URI is provided.
location ^~ /to_proxy/ {
internal;
proxy_pass http://myproxy:5000/;
}
To make the alias mapping work correctly, a trailing / is also added to the location parameter.
See this document for details.
If the trailing / on the location parameter causes problems, you can use a rewrite ... break instead:
location ^~ /to_proxy {
internal;
rewrite ^/to_proxy(?:/(.*))?$ /$1 break;
proxy_pass http://myproxy:5000;
}