nginx subdomain rewrite - regex

I need a nginx rewrite rule to rewrite from:
http://some-keyword.example.com to www.example.com/keyword.php?keyword=$some-keyword
while domain without www in front still rewrites to www.example.com and www isn't taken as a keyword.
Please could you help me to solve this problem, how to write these two rules?

If you meant redirect, then:
server {
server_name ~^(.*)\.example\.com$ ;
rewrite ^ http://www.example.com/keyword.php?keyword=$1 redirect;
}
In the case of rewrite then simply do
server {
server_name example.com ~^(.*)\.example\.com$ ;
rewrite ^ /keyword.php?keyword=$1 break;
# location /keyword.php {
# ....
# }
}

rewrite ^/list-c-([0-9]+)-k-(.+)-o-1\.html$ /index.php?module=Default&action=List&c=$1&k=$2&o=1 last;
rewrite ^/list-c-([0-9]+)-k-(.+)-o-1-p-(.+)\.html$ /index.php?module=Default&action=List&c=$1&k=$2&o=1&p=$3 last;
rewrite ^/list-c-([0-9]+)-k-(.+)-o-1-price-(.+)\.html$ /index.php?module=Default&action=List&c=$1&k=$2&o=1&price=$3 last;
rewrite ^/list-c-([0-9]+)-k-(.+)-o-(.+)-p-1\.html$ /index.php?module=Default&action=List&c=$1&k=$2&o=$3&p=1 last;
rewrite ^/list-c-([0-9]+)-k-(.+)-o-(.+)-p-(.+)\.html$ /index.php?module=Default&action=List&c=$1&k=$2&o=$3&p=$4 last;

If it's possible I'd only create 1 server(virtual host) which is the normal domain.com/www.domain.com and then use the conf to rewrite the rest to them
server {
server_name domain.com www.domain.com;
# normal handling for files
}
server {
server_name ~(?<subdomain>[^\.]*).domain.com;
location / {
try_files keyword.php?keyword=$subdomain =404;
}
}
please tell me if I missed something.

Related

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.

Nginx:Multiple Url redirection

I am new to Nginx..and need to setup some redirects
We are launching our latest code, and what to redirect all instance of the sites
for eg:-
https://woi.com/movies
https://woi.com/movies/Fear
https://woi.com/videos
https://woi.com/videos/Captain
to
https://woi.tv/#!/movies
https://woi.tv/#!/movies/Fear
https://woi.tv/#!/videos
https://woi.tv/#!/videos/Captain
I have made changes in Nginx.conf file:-
Http
{
...
location /movies {
rewrite ^.* https://$woi.tv/movies permanent;
}
location /movies/ {
rewrite ^.* https://$woi.tv/movies/ permanent;
}
location /videos {
rewrite ^.* https://$woi.tv/videos permanent;
}
location /videos/ {
rewrite ^.* https://$woi.tv/videos/ permanent;
}
}
I dont know if I am right. But the above is not working.
Please help me.
If you want to redirect all unconditionally you can try something like this, not sure if the # can be written in a redirect or not, but you can try.
server {
listen 443 ssl;
server_name example.com;
root /path/to/root;
index index.php; # or whatever index
# ssl settings
location = / {
# the non redirecting settings
try_files $uri $uri/;
}
location / {
# the remaining of the site, we should redirect here
return 301 $scheme://$http_host#!$request_uri;
}
}
EDIT:
On a second thought I think this would break the assets, so I think the redirect should be as a fall back
location / {
try_files $uri #redirect;
}
location #redirect {
return 301 $scheme://$http_host#!$request_uri;
}

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.

Nginx Rewrite URL Question

I would like to know how I can achieve the following using the nginx rewrite module, I do not have much experience with regex.
I would like to redirect a URL from
www.example.com/foo/1/bar/2/
rewrite to:
www.example.com:9000/foo/1/bar/2/
thanks
server {
listen 80;
server_name www.example.com;
rewrite ^(.*)$ $scheme://www.example.com:9000$1 redirect;
}

Add slash to the end of every url (need rewrite rule for nginx)

I try to get an / to every urls end:
example.com/art
should
example.com/art/
I use nginx as webserver.
I need the rewrite rule for this..
For better understanding check this:
http://3much.schnickschnack.info/art/projekte
If u press on a small thumbnail under the big picture it reloads and shows this url:
http://3much.schnickschnack.info/art/projekte/#0
If i now have a slash on all urls (on the end) it would work without a reload of the site.
Right now i have this settings in nginx-http.conf:
server {
listen *:80;
server_name 3much.schnickschnack.info;
access_log /data/plone/deamon/var/log/main-plone-access.log;
rewrite ^/(.*)$ /VirtualHostBase/http/3much.schnickschnack.info:80/2much/VirtualHostRoot/$1 last;
location / {
proxy_pass http://cache;
}
}
How do I configure nginx to add a slash? (I think i should a rewrite rule?)
More likely I think you would want something like this:
rewrite ^([^.]*[^/])$ $1/ permanent;
The Regular Expression translates to:
"rewrite all URIs without any '.' in them that don't end with a '/' to the URI + '/'"
Or simply:
"If the URI doesn't have a period and does not end with a slash, add a slash to the end"
The reason for only rewriting URI's without dots in them makes it so any file with a file extension doesn't get rewritten. For example your images, css, javascript, etc and prevent possible redirect loops if using some php framework that does its own rewrites also
Another common rewrite to accompany this would be:
rewrite ^([^.]*)$ /index.php;
This very simply rewrites all URI's that don't have periods in them to your index.php (or whatever file you would execute your controller from).
rewrite ^([^.\?]*[^/])$ $1/ permanent;
to avoid querystrings of a rest url getting a / tagged on.
e.g.
/myrest/do?d=12345
For nginx:
rewrite ^(.*[^/])$ $1/ permanent;
Odd that this is the first result in Google, but doesn't have a satisfactory answer. There are two good ways to do this I know of. The first is to straight-up check if the request will hit a file and only apply a rewrite condition if not. E.g.
server {
# ...
if (!-f $request_filename) {
rewrite [^/]$ $uri/ permanent;
}
location / {
# CMS logic, e.g. try_files $uri $uri /index.php$request_uri;
}
# ...
}
The second, which many prefer as they'd rather avoid any use of if that isn't 100% necessary, is to use try_files to send the request to a named location block when it won't hit a file. E.g.
server {
# ...
location / {
try_files $uri $uri/ #cms;
}
location #cms {
rewrite [^/]$ $uri/ permanent;
# CMS logic, e.g. rewrite ^ /index.php$request_uri;
}
# ...
}
it's too late but I want to share my solution, I've met issue with trailing slash and nginx.
#case :
# 1. abc.com/xyz => abc.com/xyz/
# 2. abc.com/xyz/ => abc.com/xyz/
# 3. abc.com/xyz?123&how=towork => abc.com/xyz/?123&how=towork
# 4. abc.com/xyz/?123&ho=towork => abc.com/xyz/?123&how=towork
and this is my solution
server {
....
# check if request isn't static file
if ($request_filename !~* .(gif|html|jpe?g|png|json|ico|js|css|flv|swf|pdf|xml)$ ) {
rewrite (^[^?]+[^/?])([^/]*)$ $1/$2 permanent;
}
....
location / {
....
}
}
server {
# ... omissis ...
# put this before your locations
rewrite ^(/.*[^/])$ $1/ permanent;
# ... omissis ...
}
If you want some kind of requests (say other than GET ones) to be prevented from doing this (usually it's about POST requests, as rewrite turns any request method into GET, which may break some of your site's dynamic functionality), add an if clause:
server {
# ... omissis ...
# put this before your locations
if ($request_method = "GET" ) {
rewrite ^(/.*[^/])$ $1/ permanent;
}
# ... omissis ...
}
You can also put the rewrite in a location block (if too), to make it more specific.
using the rewrites from anthonysomerset in a Wordpress, I experimented problems accesing to /wp-admin dashboard due to reirection loop. But i solve this problem using the above conditional:
if ($request_uri !~ "^/wp-admin")
{
rewrite ^([^.]*[^/])$ $1/ permanent;
rewrite ^([^.]*)$ /index.php;
}
If nginx behind proxy with https, this snippet do correct redirect for $scheme
map $http_x_forwarded_proto $upstream_scheme {
"https" "https";
default "http";
}
server {
...
location / {
rewrite ^([^.\?]*[^/])$ $upstream_scheme://$http_host$1/ permanent;
}
...
}
And on the upstream proxy pass the X-Forwarded-Proto header like:
location / {
proxy_set_header X-Forwarded-Proto $scheme;
...
}
This rule solves query string case too:
location ~ ^/([^.]*[^/])$ {
if ($query_string) {
return 301 $scheme://$host/$1/?$query_string;
}
return 301 $scheme://$host/$1/;
}
The regex has taken from #marc's answer:
rewrite ^([^.\?]*[^/])$ $1/ permanent;
The extra slash ^/ in regex is added to improve readability
Try this: ^(.*)$ http://domain.com/$1/ [L,R=301]
This redirects (Status code 301) everything ($1) without a "/" to "$1/"