Rewrite Rule(s) for domain aliases - mod-rewrite

Situation: I have a single (main) domain, which has several aliased domains, each of which are pointing at the same Plesk-based server (for instance, I have example.com as main, with something.net, anotherone.co.uk, and several others all as aliases of the main domain account). This means that whenever I enter the domain name into my address bar of any of the aliases, it goes directly to the account of the main domain (example.com).
Problem: Based on the domain name of the alias(es), I have an index.php that redirects each domain differently (for instance, requests to domain A redirects to a corporate site, domain b goes to a thanks site etc.) Which works great, but if a directory is added after the domain URL (i.e. somealias.com/something) then it gives a 404 not found error.
What I would really appreciate, if someone can help me out, is a (single if possible) rewrite ruleset that would essentially strip off ALL trailing directories and/or GET requests, and only leave the typed-in base URL, so then the php script sitting in the main domain document root can take over and deal with the request appropriately.
Strangely enough, I've not been able to find a (simple) solution for this anywhere. Is it a case of having to define a rule for each of the aliased domains individually?

Try the following,
#Options +FollowSymLinks
RewriteEngine on
RewriteCond %{HTTP_HOST} ^www.olddomain.com$[OR]
RewriteCond %{HTTP_HOST} ^olddomain.com$
RewriteRule ^(.*)$ http://www.newdomain.com/$1 [R=301,L]

RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_URI} !=/
RewriteCond %{REQUEST_URI} !=/index.php
RewriteRule .* http://%{HTTP_HOST}/? [L]
This will take ALL requests except root folder / (e.g. http://example.com/) or index file (e.g. http://example.com/index.php) and redirect them to the root folder (e.g. http://example.com/some-url will be redirected to http://example.com/).
You may need to replace index.php by the file that is get executed when you hit the root folder (Apache will silently rewrite http://example.com/ to http://example.com/index.php (depending on your actual settings) as it needs to have a file to execute otherwise it may show an error).
Alternatively (possibly even better -- depends on your actual setup and requirements) you may use these rules -- this will redirect only non-existing URLs. So if you have an image meow.png on your site, these rules will allow you to access it (http://example.com/meow.png):
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule .* http://%{HTTP_HOST}/? [L]
UPDATE:
If you going to place this into config file (httpd-vhost.conf or httpd.conf) then use these rules:
RewriteEngine On
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} !-f
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} !-d
RewriteCond %{REQUEST_URI} !=/index.php
RewriteRule .* http://%{HTTP_HOST}/? [L]

It seems to me that all the sites are hosted on the same server (probably using the same code base).
If your index.php is a front controller you can redirect everything to your index.php and decide in the first lines of index.php what front controller to load (like backend.php).
If you don't mind having to maintain a list of the aliases you can define a hash of [alias] => path-to-front-controller.
In the front controller of you main domain you check the alias name (using $_SERVER['SERVER_NAME'] for example) against the hash and load the appropriate file.
You will have to add and entry to the hash each time you add anew alias. If they are not generated dynamically maintaining this hash is not a lot of hassle.

Related

Apache rewrite : how avoid to display url parameter when the url final slash is omitted?

In my .htacess of my domain, I must point subdomain to the 1rst GET parameter of the domain. The subdomain represents the language (for example en., fr, etc...).
In order to achieve this aim, here the rewrite code in the .htaccess :
Options +FollowSymLinks
RewriteEngine On
RewriteBase /
RewriteCond %{HTTP_HOST} ^(.*)\.example\.com$ [NC]
RewriteRule ^(.*)$ $1?lang=%1 [NC,L]
I create a directory named test. This directory contains just index.html file.
So when you type in the url bar of a browser en.example.com/test/,
the rewrite code works.
But if you type en.example.com/test without the final slash, it redirects to en.example.com/test/?lang=en => it's a problem.
So have you an idea to correct that ?
Thank you in advance, cordially.
When specifying xx.example.com/test/, an internal redirect
occurs to xx.example.com/test/?lang=xx. The client never sees the ?lang=xx.
However, when specifying xx.example.com/test, where test is a directory,
mod_dir steps in and rewrites the URL to xx.example.com/test/, but in
such a way that the rewrite rule for the ?lang=xx redirect becomes public,
having the client see xx.example.com/test/?lang=xx as the URL - which is unwanted.
In order to keep the '?lang=' redirect local (hidden from the client)
place this in the .htaccess, BEFORE the original rewrite rules:
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^(.+[^/])$ $1/ [R,L]
The condition checks whether the requested filename is a directory,
and the rule forces a client-side redirect [R], so that a client requesting xx.example.com/test will be redirected to xx.example.com/test/.
The key however is the [L], which makes this rule the Last, preventing the following rules from executing. Without this L flag, the entire redirect from xx.example.com/test to xx.example.com/test/?lang=xx becomes public.
After the client is forcefully redirected to the proper URL with a terminating /, the rewrite rules doing the internal redirect adding the lang GET parameter are executed as normal.
Here's the entire .htaccess:
Options +FollowSymLinks
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^(.+[^/])$ $1/ [R,L]
RewriteCond %{HTTP_HOST} ^(.*)\.example\.com$ [NC]
RewriteRule ^(.*)$ $1?lang=%1 [NC,L]
There is however another way to achieve this without using Apache config and internal redirect, and that is to examine $_SERVER['SERVER_NAME']:
<?php
list( $lang ) = explode('.', $_REQUEST['SERVER_NAME'] );

Mod_Rewrite for URL

I have been looking through questions and answer for days trying to figure out how to make this work.
So far I can get my URL to change, but it won't load the page.
I have to take
http://www.mysite.com/index.php?mode=about
And have it show up as
http://www.mysite.com/about/
So far I have the following code:
RewriteEngine on
RewriteCond %{QUERY_STRING} ^mode=(.*)
RewriteRule ^ http\:\/\/\www.mysite.com\/%1? [R=301,L]
RewriteRule /(.*) /index.php?mode=%1 [L]
I have changed things multiple times and nothing. Most site seem to tell me I don't need the 301 redirect but then I can't get anything to work.
For (your) example, once you've properly routed from mysite.com/index.php?mode=about to mysite.com/about, it's now going to look at mysite.com/about/ to find what comes next (index.py/index.html/etc).
Because there is nothing at /about/, you're getting a 404 error.
I don't think you can use mod_rewrite to do exactly what you're trying to achieve, without having some handling within /about/ to actually display the page you want once you get there.
http://www.noupe.com/php/10-mod_rewrite-rules-you-should-know.html
Remember the Filesystem Always Takes Precedence
The filesystem on your server will always take precedence over the
rewritten URL. For example, if you have a directory named “services”
and within that directory is a file called “design.html”, you can’t
have the URL redirect to “http://domain.com/services”. What happens is
that Apache goes into the “services” directory and doesn’t see the
rewrite instructions.
To fix this, simply rename your directory (adding an underscore to the
beginning or end is a simple way to do that).
I have to take
http://www.mysite.com/index.php?mode=about
And have it show up as
http://www.mysite.com/about/
There are two very common types of rules that people want and your statement can be interpreted two ways which require different rules. I'm going to interpret your statement that you have a real, operational script at http://www.mysite.com/index.php?mode=about, but instead of having the user enter that "ugly" URL, you want them to be served that URL when they enter http://www.mysite.com/about/. To accomplish this, you would do the following:
RewriteRule ^about/?$ /index.php?mode=about [L]
Because of the potential for misunderstanding, it's best to state what you want as (1) What the user will enter into their browser and (2) what real file you want to serve them.
I don't believe you need lines #2 & 3 & you seem to have % instead of $, try:
RewriteEngine on
RewriteRule ^([^\/]+) /index.php?mode=$1 [L]
Solved the problem. Thanks for all the help.
#< IfModule mod_rewrite.c>
# RewriteEngine on
# RewriteCond %{REQUEST_FILENAME} !-f
# RewriteCond %{REQUEST_FILENAME} !-d
#< /IfModule>
Options +FollowSymLinks
RewriteEngine on
RewriteRule ^([a-zA-Z0-9_-]+)$ index.php?mode=$1
RewriteRule ^([a-zA-Z0-9_-]+)/$ index.php?mode=$1
You can use this:
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^.*$ - [L]
RewriteRule ^([^/]+)/$ /index.php?mode=$1 [L]
Where the beginning still allows for other folders to be accessible.

Rewrite link rule, conflicting files and folders

Been trying to resolve this problem with a rewrite rule that assigns a subdomain to a root directory of the same name, for example.
ddd.example.com will link to "/_projects/ddd" directory, that works fine and I have no trouble with it, the issue is that any files or directories I have in the root directory "/" can be accessed from the subdomain ddd.example.com.
Here is an example directory structure
example.com = "/"
"index.php"
ddd.example.com = "/_projects/ddd"
no files
So if for instance I access ddd.example.com/index.php, it will resolve to using the file located example.com/index.php which is located a directory below.
Here is the rewrite rule for .htaccess
# Skip rewrite if subdomain is www
RewriteCond %{HTTP_HOST} !^www\. [NC]
# Extract (required) subdomain to %1
RewriteCond %{HTTP_HOST} ^([^.]+)\.example\.com(:80)?$
# Redirect to domain if requested URL does not resolve to existing subdirectory path
RewriteCond %{DOCUMENT_ROOT}/_projects/%1 !-d
RewriteRule (.*) http://example.com/ [NC,R=301]
# Skip rewrite if subdomain is www
RewriteCond %{HTTP_HOST} !^www\. [NC]
# Extract (required) subdomain to %1
RewriteCond %{HTTP_HOST} ^([^.]+)\.example\.com(:80)?$
# Skip rewrite if requested URL does not resolve to existing subdirectory path or file
RewriteCond %{DOCUMENT_ROOT}/_projects/%1/$1 -f [OR]
RewriteCond %{DOCUMENT_ROOT}/_projects/%1/$1 -d
RewriteRule (.*) /_projects/%1/$1 [NC,L]
What if your RewriteConds fail? Then the URL falls through and is not rewritten. And so it accesses the document root. I would just create separate VirtualHost entries for every single supported subdomain. (How many are there?)
Suppose the client asks for http://sub.example.com/index.php.
Suppose that there exists an /_projects/sub/index.php.
Your RewriteCond-s will see that /_projects/sub/index.php exists as a file, and then skip the rewrite. But if the rewrite is skipped, then there is no redirect to /_projects/sub/. So what document is fetched in that case? You guessed it, /index.php.
You should unconditionally redirect these subdomains to their proper places (subject only to checks against looping).
Why did you split the rewrite into two, one doing an internal redirect? The internal redirect isn't rewriting the whole URL to example.com, and so it stays in the subdomain. It looks like you can get into a loop there.
My attempt at rewriting was to do this essentially.
Pseudo Code:
if (subdomain-directory != exists)
redirect them to the home page
else
rewrite the request for the subdomain
I could only accomplish that using two rules, I haven't found any other way to accomplish this, so this was my attempt.
The condition in question actually works fine, if I have an index.php in the /_projects/sub directory then it will use that file and the same for any other file I put in there.
I have absolutely no idea how I can accomplish this with mod_rewrite, I have played around with it for the best part of a few weeks to no avail, searched endlessly for possible solutions and have not made any progress.
Resolved the problem, seems that there was a looping problem that was breaking the rewrite.
##### Subdomain to subfolder
# Fix missing trailing slashes.
#RewriteCond %{HTTP_HOST} !^(www\.)?example\.com$ [NC]
#RewriteCond %{HTTP_HOST} ^(www\.)?([^\.]+)\.example\.com$ [NC]
#RewriteCond %{DOCUMENT_ROOT}/%2%{REQUEST_URI}/ -d
#RewriteRule [^/]$ %{REQUEST_URI}/ [R=301,L]
# Rewrite sub domains.
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteCond %{HTTP_HOST} !^(www\.)?example\.com$ [NC]
RewriteCond %{HTTP_HOST} ^(www\.)?([^\.]+)\.example\.com$ [NC]
RewriteRule ^(.*)$ /projects/%2/$1 [QSA,L]

How to make complex conditions in mod_rewrite?

I need to deny access to the whole site for everyone except some IPs.
Also, I need to permit access to one folder of site for everyone:
Options +FollowSymLinks
Options +Indexes
RewriteEngine on
# Allow access only for devs
RewriteCond %{REMOTE_ADDR} !10.10.10.10 [NC] # First dev id
RewriteCond %{REMOTE_ADDR} !11.11.11.11 [NC] # Second dev id
# Allow direct access to files
RewriteCond %{REQUEST_FILENAME} !-f
# Redirecting guests
RewriteRule (.*) /coming/soon/index.html [R=307]
# But where to place this condition?
RewriteRule ^/?preview/?$ /preview/index.html [NC]
# Other rules for main site structure
# ...
So, I need the whole site loading only for devs. Other users (guests) will see the /coming/soon/ page
And also guests are allowed to see /preview/ page of the site.
How to do this?
If your /preview/ rewrite is suitable for all users and does not depend on subsequent rewrite rules, the simplest way is to put this RewriteRule first with the [L] flag, so that subsequent rewrites will not be applied.
Otherwise, exceptions for RewriteRule may be specified as RewriteCond matching with %{REQUEST_URI}:
RewriteCond %{REQUEST_URI} !^/?preview/?$ [NC]
Also note that your suggested rule would rewrite both /preview and /preview/ into /preview/index.html, and the first of these rewrites may break relative links unless a redirect is performed.

Using Wild Card Subdomains With Mod Rewrite?

I have Wild Card Subdomains on, however I just do not know mod_rewrite to the extent that is required to write this. Can anyone tell me how to make it so anything other than www and nothing go to the main site but any subdomain other than that go to /script/index.php?username=$username?
Where does the $username variable supposed to come from??
Supposing the URL of the main site is http://www.example.com/main_site.php and that you are using this outside Directory context (ie, not in .htaccess nor in a <Directory> directive). If it is in .htaccess remove the leading / (make it just main_site.php, for example).
I reckon this will not work right away because there are many non clear variables (where does username come from?, what to do about the rest of the request, pass it as a parameter?, is this htaccess or main config?), but hopefully will get you an idea:
#Turn on the rewrite engine
RewriteEngine On
#Check accessed domain, if it's either www.example.com or
RewriteCond %{HTTP_HOST} ^www.example.com$ [NC,OR]
#example.com
RewriteCond %{HTTP_HOST} ^example.com$ [NC]
#and the requested URL does not contain script you'll be accessing to avoid looping
RewriteCond %{REQUEST_URI} !main_site.php
#Then we tell that everything matching the above will go to main_site.php
RewriteRule ^ /main_site.php [L]
#If the request is not asking for main_site.php nor index.php
RewriteCond %{REQUEST_URI} !main_site.php
RewriteCond %{REQUEST_URI} !index.php
#We go to /script/index.php (username will be empty, becase we don't know
#where to get it from)
RewriteRule ^ /script/index.php?username=$username [L]

Resources