nginx rewrite url only with certain subdomain - regex

I am trying to make my nginx rewriting all the urls with certain subdomain (m.example.com) to add string: ?theme=XXX to the end of the file
In my nignx server configuration i have:
server{
server_name example.com m.example.com y.example.com
(...)
}
Now, I want to rewrite all http requests going ONLY through m.example.com to add to the end of the url ?theme=XXX
I have the following rewrite:
rewrite ^(.*)$ $1?theme=XXX? break;
but i don't know how to make rewriting only requests from m.example.com (not from all server names)

Related

Redirect old domain to new domain, including /en/

Little stuck but I'm trying to redirect an old domain name to a new domain, which is working to a point. However, we have a long list of URLs from our old website (using the old domain). Which have /en/ appended at the end.
So the issue is when I link olddomain.com/en/old-url to newdomain.com/new-url it throws a 404 as it's not picking up the '/en/'. I've compiled a long list of 301 redirects inside the Django admin, but they don't include the '/en/'. Which is where the issue is. Ideally, I want to add something to my nginx config that tells the domain to redirect even if the /en/ is included.
So Far I have something like this:
server {
listen 80;
server_name olddomain.co.uk www.olddomain.co.uk olddomain.co.uk/en/
return 301 https://www.newdomain.co.uk$request_uri;
}
server {
HTTPS
server_name olddomain.co.uk www.olddomain.co.uk olddomain.co.uk/en/;
#return 301 https://www.newdomain.co.uk$request_uri;
listen 443;
}
Thanks in advance.

Nginx rewriting Rules

I have the following url:
mywebsite.com/template/product.html
and I want to rewrite it as
mywebsite.com/product
location / {
alias /var/www/web/;
rewrite ^/(mywebsite.com/template/.*)\.html$ /$1 last;
}
Not sure if you want to handle the domain as a generic variabile.
Anyway, if you setup a server conf for mywebsite.com, this configuration should fit your case.
server {
error_log logs/mywebsite.com.log debug;
server_name mywebsite.com;
root /var/www/web/mywebsite.com;
# this directive handle the redirects from old name.html to new format
location /template/ {
rewrite ^/template/([^.]+)\.html$ /$1 redirect;
}
# given new new url format this directive match the name and
# read the file
location ~* ^/([^.]+)$ {
try_files /template/$1.html /template/notfound.html;
}
}
The regular expression you wrote did not match the product name. Now the group should fit your requirements. I have also modified the rewrite flag last in redirect because I suppose you want redirect a browser or a bot to the new urls.

301 Only Part of the URL in Nginx

Trying to 301 a url by matching just its post id. For example I just want to rewrite any url that ends in -158436, yet I can't seem to make it work out.
location /forum/this-stuff-does-not-matter-158436 {
rewrite ^ http://www.thegoodurl.com/whatever/ permanent;
}

(Nginx) Regex pattern to match everything but www

Basically, I'm trying to setup nginx with regex so that it:
Matches all subdomains for pyronexus.com & notoriouspyro.com but NOT www (www is redirected to pyronexus.com).
Gives me a variable I can use to determine what the subdomain and domain entered are (e.g. if someone enters space.pyronexus.com, I would like to have two variables $subdomain and $domain containing space and pyronexus).
So far, I have this: ~^(.*)\.(?:pyronexus|notoriouspyro)\.com$
But I just can't seem to figure out anything else! Any help would be greatly appreciated.
Edit: Perhaps it would help to show my nginx config file:
server {
server_name pyronexus.com notoriouspyro.com;
listen 127.0.0.1:80 default_server;
root /home/nginx/pyronexus.com/public;
index index.html index.php;
access_log /home/nginx/pyronexus.com/logs/access.log;
error_log /home/nginx/pyronexus.com/logs/error.log;
include php.conf;
}
server {
server_name ~^(www\.)?(.+)$;
listen 127.0.0.1:80;
return 301 $scheme://$2$request_uri;
}
The first part is the server which I need the regex for, the second part is to try and catch all domains landing on www and redirect them without www.
This is pretty easy, like #Melvyn said, you are over thinking this, you need a catch all server to handle all domains, then create a specific server for redirecting the www.
The best variable you want to know the host you are accessing is $http_host
server {
listen 80 default_server;
# here handle all subdomains, this will also match the non-www domains of
# the both domains
}
server {
listen 80;
server_name www.pyronexus.com;
return 301 http://pyronexus.com$request_uri;
}
server {
listen 80;
server_name www.notoriouspyro.com;
return 301 http://notoriouspyro.com$request_uri;
}
This pattern seems to do it:
^((?!www).+?)\.(?:pyronexus|notoriouspyro)\.com$
Courtesy of Regular expression to match a line that doesn't contain a word?
Tested here:
http://regex101.com/r/yK7oE2/1
In case you need the domain name, simply leave out the ?::
^((?!www).+?)\.(pyronexus|notoriouspyro)\.com$
Take a step back. The task is:
serve sites on pyronexus.com and notoriouspyro.com
redirect subdomains to their respective domains
redirect www subdomains to pyronexus.com
So instead of fiddling with an overly complex regular expression, make three server blocks. The second in the task list is the catch all.

Redirecting a subdomain with a regular expression in nginx

The nginx documentation says that the server_name directive supports regular expressions. I've been banging my head against the wall trying to get even a trivial regex working.
I want http://subdomain.mydomain.com to redirect to http://mydomain.com/subdomain
Here is my code.
server {
server_name "~^subdomain\.mydomain\.com$";
rewrite ^ http://mydomain.com/subdomain;
}
Also, potentially noteworthy. Further down in the nginx config file there is a rule:
server {
server_name *.mydomain.com
...
}
What am I doing wrong?
UPDATE:
It has been suggested that I not use regex for this... to offer a little more clarity: the trivial regex was simply for purposes of troubleshooting. The real regex will look more like...
server {
server_name "~^.*(cvg|cincinnati)\.fakeairport(app)?\.(org|com)$";
rewrite ^ http://fakeairport.com/cincinnati;
}
server {
server_name "~^.*(lex|lexington)\.fakeairport(app)?\.(org|com)$";
rewrite ^ http://fakeairport.com/lexington;
}
So it would be preferable to use regex.
To answer an old question to help others
using nginx 1.1.19 you can do the following:
server {
server_name ~^(?<subdomain>\w+)\.domainA\.com$;
location / {
rewrite ^ https://$subdomain.domainB.com$request_uri permanent;
}
}
The subdomain before domainA.com is matched and stored in variable $subdomain which then can be used in the rewrite.
This rewrites url like xxx.domainA.com to xxx.domainB.com with only one server directive.
Gotta love regex with NGINX!
As I often work with multiple domain-names and I like to keep my configs as clean and rock solid as possible I almost always use regex with nginx.
In this case I've solved it with the following regex:
server {
listen 80;
server_name ~^((?<subdomain>.*)\.)(?<domain>[^.]+)\.(?<tld>[^.]+)$;
return 301 $scheme://${domain}.${tld};
}
What this does is the following: every subdomain.domain-name.tld that points to this server (ip address) is automatically redirected to domain-name.tld.
So for instance www.myexampledomain.com is redirected to myexampledomain.com.
To answer the question, what you could also do is the following:
server {
listen 80;
server_name ~^((?<subdomain>.*)\.)(?<domain>[^.]+)\.(?<tld>[^.]+)$;
return 301 $scheme://${domain}.${tld}/${subdomain};
}
Now mysubdomain.myexampledomain.com is converted into myexampledomain.com/mysubdomain.
Above regex is great as you can throw anything at it that you like and it will convert it for you.
If you read the server_name matching rules, you'll see that prefix and suffix server_names are checked before regex names, but after exact hostnames. Since *.mydomain.com matches, the regex isn't tested. The fact that it's listed earlier in the config makes no difference. Since you're just trying to match a single hostname with your regex, a simple:
server {
server_name subdomain.mydomain.com;
rewrite ^ http://mydomain.com/subdomain$request_uri?;
}
server {
server_name *.mydomain.com;
# stuff
}
will work for you.
I know everyone is saying if is evil in nginx config files, but sometimes you can't get around any other way.
server {
server_name .mydomain.com;
if ( $host ~ subdomain.mydomain.com ) {
rewrite ^(.*) http://mydomain.com/subdomain$1;
}
}
Just as a comment. If you want to redirect all subdomain levels to first subdomain level, util when you use a wildcard SSL certificate for example, you could use:
server {
listen 80;
server_name ~^(.*)\.(?<subdomain>\w+).mydomain\.com$;
return 301 https://$subdomain.mydomain.com$request_uri;
}
server {
listen 80;
server_name ~^(?<subdomain>\w+).mydomain\.com$;
return 301 https://$subdomain.mydomain.com$request_uri;
}
The first is for redirect an http multiple level subdomain to the first subdomain level in https. And the next is for redirect the first level subdomain in http to the same subdomain in https.