Using mod_rewrite for subdomains - php

I wan't people to be able to register their own sections within my site, and have those sections be their own subdomain of my site. so someone can register 'test' and have 'test.example.com' refer to their site which would be at say /site.php?id=1 So how would i go about writing a mod_rewrite rule for this?

mod_rewrite might not be the best tool for this. RewriteRules are great for mapping a file to something else, but it was not really meant for domain matching.
The best you can do using mod_rewrite is the following:
RewriteEngine On
# Skip www.domain.com
RewriteCond %{HTTP_HOST} !^www\.
RewriteCond %{HTTP_HOST} ^([^.]+)\.domain\.com
RewriteRule ^/(.*)$ site.php?domain=%1&file=$1 [L]
Which is not really useful. What I would recommend to do instead if programmatically check the value of HTTP_HOST as such:
function get_subdomain() {
if(preg_match('/^([^.]+)\.domain\.com/i', $_SERVER['HTTP_HOST'], $matches))
return $matches[1];
}

You can configure apache to claim the "special" domains in the apache configuration (e.g. www.mydomain.com, etc), in your virtual host containers and have the others default to your first virtual host. You can then rewrite the base url to a dispatch application that inspects the URL and sends the user off to their correct area.
From Apache 2.0 docs:
Almost any Apache directive may go
into a VirtualHost container. The
first VirtualHost section is used for
requests without a known server name.
Put the code to handle *.mydomain.com in the first virtual host:
<VirtualHost *:80>
Servername custom.mydomain.com
DocumentRoot /var/www/html/custom
RewriteEngine on
RewriteRule ^/$ /var/www/cgi-bin/dispatch.cgi [R]
# more configs here
</VirtualHost>
<VirtualHost *:80>
Servername www.mydomain.com
DocumentRoot /var/www/html/homepage
# more configs here
</VirtualHost>
In dispatch.cgi, inspect the calling url to determine where the user should go. Make sure you set up your DNS to accept all subdomains.
Hope that helps!

Actually, we've been using this technique without much problem for the past year. Our mod_rewrite config looks like:
RewriteEngine On
RewriteBase /
RewriteCond %{HTTP_HOST} !www.mydomain.com
RewriteCond %{HTTP_HOST} ^([^.]+)\.mydomain\.com
RewriteCond %{REQUEST_URI} !admin
RewriteRule (.*) /admin/ [R=301,L]
RewriteRule ^admin(.*)$ hosted/admin/$1 [QSA,L]
What happens, is that users are directed to theiraccount.mydomain.com/admin.
We then use PHP to identify the account portion of the domain name. Using something like $_SERVER['SERVER_NAME'] or some method of getting the domain name and parsing it works very well.
Keep these configs in the httpd.conf though, this will become a cpu problem in higher traffic sites if it's kept as .htaccess.

Related

Redirect different domains pointing to same server to different version of same website

I have different domains say like (fictious names) "plumbers.org" and "cleaning.org"
pointing to the same folder in my apache2 conf.
and the main domain is "workers.org"
what i want to obtain is basically to have plumbers.org pointing to workers.org/index.php?version=1
and to have cleaning.org pointing to workers.org/index.php?version=2
is something I set in my .htacess? what's best practice?
You can try to add a permanent redirect in the original httpd / apache conf file, e.g.:
<VirtualHost ...>
ServerName plumbers.org
Redirect 301 / http://workers.org/index.php?version=1
</VirtualHost>
...
<VirtualHost ...>
ServerName cleaning.org
Redirect 301 / http://workers.org/index.php?version=2
</VirtualHost>
Technically, it should also work if you put these changes in the corresponding .htaccess files (if .htaccess files are not prohibited by the "parent" conf). Without <VirtualHost> section, of course, then.
Assuming all 3 domains point to the same DocumentRoot folder, you can use this code in your DOCUMENT_ROOT/.htaccess file:
RewriteEngine On
RewriteCond %{HTTP_HOST} ^(?:www\.)plumbers\.org$ [NC]
RewriteRule ^/?$ index.php?version=1 [L,QSA]
RewriteCond %{HTTP_HOST} ^(?:www\.)cleaning\.org$ [NC]
RewriteRule ^/?$ index.php?version=2 [L,QSA]

mod_rewrite rules to force www and https over main domain, ignoring 1 folder and 1 other domain

I've tried tons (probably in excess of 250) different rewrite rules but none of them are having the desired effect.
Rules for maindomain.com which is a wordpress website with SSL & should run with the prefix www.
Check and force www. to the entire domain/folders/subfolders...etc (not just wordpress) EXCEPT the folder testfolder
Check and force https. to the entire domain/folders/subfolders...etc (not just wordpress) EXCEPT the folder testfolder
Rules for test.otherwebsite.com which is a custom set of pages hosted in /testfolder/ on the server
Check and forcefully remove www. from the domain test.otherwebsite.com
Check and forcefully changed https to http from the domain test.otherwebsite.com
These rules shouldn't be needed I don't think... if the first set of rules work correctly.
No need to use rewrite engine if you have access to main configuration files.
(1) Redirect non www to www. A simpler solution is using VirtualHost directive instead of rewrite engine.
<VirtualHost *:80>
ServerName maindomain.com
Redirect permanent / http://www.maindomain.com/
</VirtualHost>
<VirtualHost *:80>
ServerName www.maindomain.com
# ... Your www served here
</VirtualHost>
For https, you could just simply copy them and replace the port to 443.
(2) Serve /testfolder in a separate VirtualHost directive
<VirtualHost *:80>
ServerName test.otherwebsite.com
# ... anything else
</VirtualHost>
For https, change port to 443.
Note that those won't make exception to /testfolder if accessed from www.maindomain.com/testfolder.
A solution is to move the testfolder outside directory served by www.maindomain.com. For example
/var/www/maindomain <--- directory for www.maindomain.com
/var/www/testfolder <--- directory for test.otherwebsite.com
There is a <DirectoryMatch> directive to prevent that as explained here https://stackoverflow.com/a/214908/779320. But I'm afraid it apply globally and so can't be served in any VirtualHost. But you can test it anyway.
1) You can use this code in your DOCUMENT_ROOT/.htaccess file:
RewriteEngine On
RewriteCond %{HTTPS} off [OR]
RewriteCond %{HTTP_HOST} !^www\. [NC]
RewriteRule !^testfolder/ https://www.maindomain.com%{REQUEST_URI} [NE,NC,R=301,L]
2) Then you can use this code in your /testfolder/.htaccess file:
RewriteEngine On
RewriteCond %{HTTPS} on [OR]
RewriteCond %{HTTP_HOST} ^www\. [NC]
RewriteRule ^ http://test.otherwebsite.com%{REQUEST_URI} [NE,R=301,L]

Custom domains for one site

I have a php web application on Apache that supports multiple users identified by dist_id in the query string. So https://main.com/login?dist_id=21 shows a differently styled page from https://main.com/login?dist_id=26
What I want to do is register a domain name for each user and keep the URLs clean so that https://brandx.com/login invisibly points to https://main.com/login?dist_id=21. After the login I don't need dist_id anymore but I want to keep the user's domain so that https://brandx.com/products?show=1 etc. still works.
Is this possible and what's the best way to do it (mod_write, DNS, in PHP)?
Note I already have a rewrite rule to add index.php which is the entry point for all requests.
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ index.php [QSA,L]
I think I've gotten close with:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ index.php?dist_id=26 [QSA,L]
After logging in this works: https://brandx.com/categories but this gives a 404 error: https://brandx.com/categories?parent_id=12329
Presumably all of these "sites" would share an identical URL structures (minus query parameters)? In that case, it'd probably be simplest to set up a definition for your main.com site, and then add all of your brandx.com domains as aliases, e.g.
<virtualhost *:80>
ServerName main.com
ServerAlias brandx.com brandy.com brandz.com etc...
</virtualhost>
Then you use mod_rewrite to test the HTTP 'Host:` header to see which domain the users are hitting, and re-write as appropriate.

Redirect from subdomain to primary domain without rewriting URL

I've been searching similar solutions but none of them seems working on my server.
What I'm trying to do is set redirect from yyy.zzz.com (subdomain) to zzz.com (primary domain) without rewriting url. So both yyy.zzz.com and zzz.com actually pointing at same directory and same files in it.
Currently I have this .htaccess:
RewriteEngine on
RewriteBase /
RewriteCond %{HTTP_HOST} ^yyy\.zzz\.com$ [NC]
RewriteRule ^(.*)$ http://zzz.com [L,NC]
Which, of course, just redirects straight on, and url actually changes.
Just for information, I want to set such subdomain url for CMS, so if user wants to enter CMS he does it from subdomain, while actually only $_SERVER['HTTP_HOST'] is changing.
Any help would be appreciated.
You should set up a ServerAlias in your apache config. Setting yyy.zzz.com as an alias for zzz.com
<VirtualHost *>
ServerName zzz.com
ServerAlias yyy.zzz.com
# ...
</VirtualHost>
http://httpd.apache.org/docs/2.2/mod/core.html#serveralias

virtual subdomain: one subdomain per user

On my website i'm using virtual host so my users can have virtual domain like 'user1.mydomain.com', 'user2.mydomain.com',...
The problem is that on virtual domains like 'user1.domain.com' the index page is always the same as on my index page 'http://mydomain.com'.
What i want to do is to have two different index pages for the domain and for subdomains. My question, how to have subdomains redirected to 'index2.php' (for example) and still have the subdomains to look like 'user1.mydomain.com'?
Ideally, you would set up completely separate document directories for each subdomain. vhost in apache is the way to go. If you however want to do it your way (subdomains redirecting to individual files), then it's a bit more work, but is still doable. First, define the mod_vhost with wildcard:
<VirtualHost 111.22.33.55>
DocumentRoot /www/subdomain
ServerName www.mydomain.com
ServerAlias *.mydomain.com
...
</VirtualHost>
Then inside this VirtualHost setup rewrite rules using mod_rewrite:
<Location "/">
RewriteCond %{HTTP_HOST} ^user1.mydomain.com$
RewriteRule ^\/$ http://www.mydomain.com/index2.php [R=301,L]
RewriteRule ^\/index.php$ http://www.mydomain.com/index2.php [R=301,L]
RewriteCond %{HTTP_HOST} ^user2.mydomain.com$
RewriteRule ^\/$ http://www.mydomain.com/index3.php [R=301,L]
RewriteRule ^\/index.php$ http://www.mydomain.com/index3.php [R=301,L]
...
</Location>
Note however that this will only work properly for / and /index.php requests to subdomains. You are much better off setting up separate document root directories for each subdomain if you intend to do anything more than this.
Maybe you are interested in this.
http://httpd.apache.org/docs/2.2/mod/mod_vhost_alias.html#virtualdocumentroot
This allow, in Apache server, to automatically use a document root based in the subdomain
I would use php to check the url.
If it is a subdomain include index2.php else include index1.php
Without knowing the servers you are running on it is the only method I could think of.

Categories