Nginx Rewrite to another path on the server - nginx

Is it possible to do a rewrite rule in nginx to rewrite to another location on the server, outside of the current account?
For example, I want to rewrite image123.jpg to location on the server /dev/shm/123.jpg. Is this possible?
I could grab the image with a PHP script and rewrite to that, but I'd rather it was done more efficiently.

yes it's possible: have a look at the alias-directive

Related

nginx rewrite Issue, why does it just replaces one matched string?

I want to replace my url via Nginx's rewrite directive. For instance, the client side requests http://127.0.0.1/user/user_id/, and I want to let Nginx rewrite the url to http://127.0.0.1/person/person_id/.
My Nginx configuration is like this:
rewrite (.*)user(.*) $1person$2;
But I fount the Nginx changes the url to .../user/person_id/
Could someone tell me how to change the user to person via rewrite directive?
Assuming that the first instances of user and personare constant and that there is always a slash after the second item, you can try:
rewrite ^/user/user_([^/]+)/(.*)$ /person/person_$1/$2 ;
well this single case you are talking about can be solved simple:
rewrite ^/user/user_id/(.*)$ /person/person_id/$1 ;

Rewrite a url and rerun the server block

I'm trying to rewrite a url like the following but without sending a 301 to the client (change the url and then restart processing of the server block with the new url).
rewrite ^/a/b/$ /a/c/d permanent;
I would normally just reorder the lines but it's a really convoluted config and also really large.
permanent always means redirect, replace it with last
check the last flag in the reference page

Nginx rewrite rule guide

I am totally newbie on NGINX reverse proxy solution and its seems to getting hard to understand all the terminology. I am looking for a solution as follows. I would really appreciate anybody's help to configure the same.
We have an internal web server which we would like to publish at WWW site but don't want customer to see internal server URL. As example:
Customer access www.mycompany.com/track --> NGINX read the track and then redirect URL to internal server.com.au/tracker . We dont want customer to see this address.
Any suggestion?
Cheers,
Sandy
It is much better in this case to use the proxy. Rewrites are meant for URLs within the same domain or to redirect the client (which would show in the url).
Try this:
location / {
proxy_pass http://internal.example.com/;
proxy_set_header Host $host;
}
Rewriting on nginx is quite the same than on Apache :) The syntax varies.
When Apache uses RewriteRule, nginx uses rewrite. May I suggest you this reference http://wiki.nginx.org/HttpRewriteModule ? Check 2.4 and 2.5 for rewriting-specific documentation. You'll find information about the rewrite syntax, and rewriting options.
There is a quick example from above, if you just need the basic syntax :
rewrite ^(/download/.*)/media/(.*)\..*$ $1/mp3/$2.mp3 break;
By the way, if you want to work from examples, you can transform your Apache .htaccess file into a piece of nginx configuration, using this tool : http://winginx.com/htaccess

Remove www. from host name using Nginx Rewrite

I am trying to configure my Nginx to strip out www. from hostname.
I am looking for generic rule that handle possible subdomain cases.
E.g. If http://www.foo1.sample.com and http://www.fooX2.sample.com are two domains.
Then I want to strip any www. before such subdomains, and redirect them to http://foo1.sample.com and http://fooX2.sample.com respectively (WITHOUT knowing the exact subdomain in the rule.)
Thanks.
Best Practice:
The best practice, as well as the most efficient way, would be to use a separate server definition for this.
This will not only ensure that the config is automatically applied to every single one of the websites that are hosted on your nginx instance, but it'll also makes sure that you don't end up running regular expressions on the hostname from multiple instances in your code.
The following is the simplest form:
server {
listen 80;
server_name ~^www\.(?<domain>.+)$;
return 301 $scheme://$domain$request_uri;
}
If you do use https, then things get more complicated, because you'd have to ensure that the certificates don't mismatch. Unless you have a single certificate for all of your domains, it would be the best practice to simply hardcode everything, as it's already hardcoded in the certificate anyways, and a solution like above simply isn't possible due to the certificate requirements.
Alternative:
Note that the other answer to the question, which uses rewrite ^(.*) http://…$1 …, is incorrect, and will cause you to lose $query_string, as well as potentially mangle the encoding of the request as per Nginx pass_proxy subdirectory without url decoding.
If you require an if-based approach and no hardcoding, neither of which are recommended, e.g., like the other answer, then at least use the correct paradigm, to avoid the bloat and the loss of the $query_string; note that as per nginx server name regex when "Host" header has a trailing dot, the $host variable is already normalised by nginx (trailing dot removed, whole thing brought to lower case), so, you don't need to worry about doing a case-insensitive comparison like in the other answer, either:
if ($host ~ ^www\.(?<domain>.+)$) {
return 301 $scheme://$domain$request_uri;
}
References:
http://nginx.org/r/listen
http://nginx.org/r/server_name
http://nginx.org/r/return
http://nginx.org/en/docs/http/server_names.html
I think adding following If block in your Nginx conf file should work for you. It also takes care of subdomain case you mentioned.
if ($host ~* ^www\.(.*)) {
set $host_without_www $1;
rewrite ^(.*) http://$host_without_www$1 permanent;
}

nginx multi-stage 404 handling

We just moved to a new site, and want to redirect old links where necessary - however, some still work. For instance,
/holidays/sku.html
still works, while
/holidays/christmas/
no longer works. I'd like to be able to allow the site to attempt to serve a page, and when a 404 is reached, THEN try to pass it through a series of regex redirects, that may look like:
location ~* /holidays/(.*)+$ { set $args ""; rewrite ^ /holidays.html?r=1 redirect; }
I'm using a ~* location directive instead of doing a direct rewrite because we're moving from a Windows-based ASPX site to Magento with php-fpm behind nginx, so we suddenly have to worry about case sensitivity.
Without using nested location directives (which are actively discouraged by nginx documentation) with an #handler of some sort, what's the best way to allow nginx to attempt to serve the page first, THEN pass it across redirects if it fails?
Thanks!
http://wiki.nginx.org/NginxHttpCoreModule#try_files

Resources