mod_rewrite: hierarchical sub-domains into hierarchical sub-directories - mod-rewrite

Consider the following problem, please. I have got domain.tld with hierarchical sub-domains like the following:
a.domain.tld
b.a.domain.tld
c.b.a.domain.tld
... etc.
There is also hypothetical directory structure in the web-root:
/foo
/a.
/a./b.
/a./b./bar
/a./b./c.
... etc.
I would like to achieve such rewrite that would cause Apache to serve directories in a way you see below.
a.domain.tld --> /a.
b.a.domain.tld --> /a./b.
c.b.a.domain.tld --> /a./b./c.
... etc.
Directories without trailing dot character would behave as normal sub-directories.
domain.tld/foo/ --> /foo
a.b.domain.tld/bar --> /a./b./bar
I can not use mod_vhost_alias and would be glad if the solution was achievable using mod_rewrite only. Is it possible to achieve such rewrite?
Thank's for all your advices.
--
nkd

Possible solution for 4 levels of sub-domains:
RewriteCond %{HTTP_HOST} ^([^\.]+)\.domain\.tld
RewriteRule (.*) %1./$1 [R,L]
RewriteCond %{HTTP_HOST} ^([^\.]+)\.([^\.]+)\.domain\.tld
RewriteRule (.*) %2./%1./$1 [R,L]
RewriteCond %{HTTP_HOST} ^([^\.]+)\.([^\.]+)\.([^\.]+)\.domain\.tld
RewriteRule (.*) %3./%2./%1./$1 [R,L]
RewriteCond %{HTTP_HOST} ^([^\.]+)\.([^\.]+)\.([^\.]+)\.([^\.]+)\.domain\.tld
RewriteRule (.*) %4./%3./%2./%1./$1 [R,L]
Thank you.
--
nkd

The previous solution ends in very funny infinite redirect loop. Here's a solution I got now (not very elegant, but it works; but with a huge 'but'):
# Working solution for five levels of sub-domains
RewriteEngine on
RewriteCond %{HTTP_HOST} ^([^\.]+)\.DOMAIN\.TLD [NC,OR]
RewriteCond %{HTTP_HOST} ^([^\.]+)\.([^\.]+)\.DOMAIN\.TLD [NC,OR]
RewriteCond %{HTTP_HOST} ^([^\.]+)\.([^\.]+)\.([^\.]+)\.DOMAIN\.TLD [NC,OR]
RewriteCond %{HTTP_HOST} ^([^\.]+)\.([^\.]+)\.([^\.]+)\.([^\.]+)\.DOMAIN\.TLD [NC,OR]
RewriteCond %{HTTP_HOST} ^([^\.]+)\.([^\.]+)\.([^\.]+)\.([^\.]+)\.([^\.]+)\.DOMAIN\.TLD [NC]
RewriteRule (.*) http://DOMAIN.TLD/%5./%4./%3./%2./%1./$1 [R,L]
Can somebody explain to me why (the hell) it works? It really does work, I tested it extensively. But why does it work actually? If I look at the RewriteRule line I doubt it should work... Thank you for your explanations.
BTW: If the above five rewrite conditions and rule work, it looks like it could be re-written in some sort of 'two-liner' (one condition plus one rule). I tried that already, by using the above rule and the following condition instead of the five conditions given above:
RewriteCond %{HTTP_HOST} ^(([^\.]+)\.)+DOMAIN\.TLD [NC]
and played with it a little but with no real success. Thanks for all ideas how to simplify
the rewrite stuff and make it more 'sane' (if possible).
--
nkd

It is possible if you send the part to be reversed to an external script via RewriteMap and have that handle it.

Related

How To Rewriting URLs with Mod-Rewrite

How would I rewrite:
http://mydomain.com/?v=service
http://mydomain.com/?v=pfolio
To
http://mydomain.com/service
http://mydomain.com/pfolio
I am have tried many ways but have not figured it out. Please give a suggestion.
I already use
RewriteRule ^/?v=(.*)$ /v/$1 [R=301,L]
This would be the version for the server configuration:
RewriteEngine on
RewriteCond %{QUERY_STRING} ^v=(.*)$
RewriteRule ^/$ /%1 [R=301,L]
Or, if there might occur more query parameters something like this:
RewriteEngine on
RewriteCond %{QUERY_STRING} ^v=([^&]*)
RewriteRule ^/$ /%1 [R=301,L,QSA]
When placed inside a .htaccess style file you have to remove the / from the pattern in the RewriteRule (so just ^$).
But I am skeptical what this really is what you are really looking for. Usually people want to do the opposite of this... Maybe you should also explain what is the idea behind your attempt. So your situation, what you want to happen, not how.

Mod Rewrite won't redirect subdomains to new URL format

I'm changing all my subdomains to a single domains.
However, in order no to lose all my SEO I need to do some 301 redirections. My problem is that I have about 10.000 subdomains (it's a website about cities and each city is a subdomain) so I need to make a generic rewrite rule in order to make the new URLs (otherwise my htaccess will be too big).
I tried doing it myself but for some reason, it's doing what it wants to (so I guess I'm doing something wrong). Here is my code:
RewriteCond %{HTTP_HOST} ^(.*)\.domain\.com/b/^(.*)
RewriteRule ^(.*) http://domain.com/city/$1/b/$2 [R=301,L]
RewriteCond %{HTTP_HOST} ^(.*)\.domain\.com
RewriteRule ^(.*) http://domain.com/?multi_city=$1 [R=301,L]
This is what happens with these two rules.
city.domain.com --> domain.com/?multi_city=/
city.domain.com/b/place --> domain.com/?multi_city=/b/place
What am I doing wrong?
Thanks in advance.
So, after many hours, I finally fixed it doing this:
RewriteCond %{HTTP_HOST} ^(.+)\.mydomain\.(.*)
RewriteCond %{REQUEST_URI} ^/b
RewriteRule ^(.*)$ http://mydomain.%2/city/%1/$1 [R=301,L]
RewriteCond %{HTTP_HOST} ^(.+)\.mydomain\.(.*)
RewriteCond %{REQUEST_URI} ^/event
RewriteRule ^(.*)$ http://mydomain.%2/city/%1/$1 [R=301,L]
RewriteCond %{HTTP_HOST} ^(.+)\.mydomain\.com
RewriteRule ^(.*)$ http://mydomain.com/?multi_city=%1 [R=301,L]
This way I can redirect places and events first and if the URL is not in that format then it will go to the different format URL. It's probably not the most efficient solution but it works for me. Hope this helps to someone else.
I think the first RewriteCond it's wrong:
RewriteCond %{HTTP_HOST} ^(.*)\.domain\.com/b/^(.*)
The '^' symbol says that the string start, it's not part of the group, so I think that you will try:
RewriteCond %{HTTP_HOST} ^(.*)\.domain\.com/b/(.*)
Maybe, it will be better:
RewriteCond %{HTTP_HOST} ^(.*)\.domain\.com/b/([a-zA-Z0-9\-]+)
I'm doing it without testing, if it doesn't work I will make tests later and I'll answer you.

How can I use mod_rewrite to do this

I would like to take a url at my site:
http://mysite.com/jk/drawing
but operationally drop the "jk" dir and have my users see this:
http://mysite.com/drawing
Is this possible? If so can someone give me an example of how it is done?
thanks,
The first thing you need to do is go and change all of your links from looking like this: http://mysite.com/jk/drawing to looking like this: http://mysite.com/drawing. Without doing this, people will still see all the /jk/ URLs everywhere, the only thing you can do about it is to make sure you've changed all your links. Then add these rules to the htaccess file in your document root:
RewriteEngine On
RewriteCond %{HTTP_HOST} mysite.com [NC]
RewriteCond %{REQUEST_URI} !^/jk/
RewriteRule ^(.*)$ /jk/$1 [L]
In order to correct for all the links still pointing to /jk/ that you don't have any control over:
RewriteCond %{HTTP_HOST} mysite.com [NC]
RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /jk/([^\ ]*)
RewriteRule ^ /%1 [R=301,L]

RewriteCond variable back-referencing of %2

this is htaccess file on the server
RewriteEngine On
RewriteBase /
RewriteCond %{HTTP_HOST} !^www.
RewriteCond %{HTTP_HOST} ^([a-z0-9]+)\.domain.com(.*)$
RewriteRule ^(.*)$ http://domain.com/test\.php?user=%1&path=%2 [R]
According to my understanding of the above code if i request asher.domain.com/user it should rewrite to http://domain.com/test.php?user=asher&path=/user right?
Instead i get http://domain.com/test.php?user=asher&path= The %2 is empty. but if i use $1 instead of %2 i seem to get the right result.
I might be doing the silliest mistake ever but I am not sure where I my mistake is. Help me out here guys? where is the mistake in the rewrite rules that %2 is not working for me?
Using the $ syntax gives you RewriteRule backreferences, while the % will give you RewriteCond backreferences. The mod_rewrite documentation covers this.
In your case, your RewriteRule should look like:
RewriteRule ^(.*)$ http://domain.com/test\.php?user=%1&path=$1 [R]
Because you want the first group match from the previous RewriteCond and the first group match from the current RewriteRule.

Nested subdomain URL rewrite

I have a sight that is of the following form:
nested_subdomain1.nested_subdomain2.domain.com
It might be something like test.users.domain.com and I would like to be able to rewrite this URL to something like test.users.domain2.com.
So far, my luck has not proven well and I have not been able to successfully implement a working solution from examples found online. I have tried some things like the following:
RewriteCond %{HTTP_HOST} ^domain\.com
RewriteRule (.*) http://domain2.com/$1 [R=301,L]
Or this one...
RewriteCond %{HTTP_HOST} !^fully\.qualified\.domain\.name$ [NC]
RewriteCond %{HTTP_HOST} !^$
RewriteRule ^/(.*) http://fully.qualified.domain.name/$1 [L,R]
I am not sure what I am doing wrong and feel like I am missing something really obvious.
Try this
#match anything1.anything2.domain.com
RewriteCond %{HTTP_HOST} ^([^.]+\.[^.]+)\.domain\.com$ [NC]
#redirect to anything1.anything2.domain2.com
RewriteRule ^ http://%1.domain2.com%{REQUEST_URI} [R=301,L]
RewriteCond %{HTTP_HOST} domain\.com$
RewriteRule (*.).mydomain.com mydomain.com/$1
This will trasnfer xx.yy.mydomain.com to mydomain.com/xx.yy
To replace with slashes, try
RewriteCond %{HTTP_HOST} domain\.com$
RewriteRule (*.\.).mydomain.com mydomain.com/$1/$2/$3
To transfer to another domain ,try
RewriteCond %{HTTP_HOST} domain\.com$
RewriteRule (*.).mydomain.com $1.mydomain.com [R=301,L]
This will transfer the subdomains upto a level of three. Frankly, you will have to analyze the host in your index.php to determine which subdomain is caled, so might as well use the first one

Resources