Using Wild Card Subdomains With Mod Rewrite? - 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]

Related

htaccess to remove index.php, with multiple domains

This seems so basic, and there's a plethora of questions regarding .htaccess online, but after two days of research, I still can't make mine work the way I want.
What I want is:
Force https on all requests
Always use the "www" version of the url.
Work on multiple domains (but not redirect them all to a master domain). All my domains point to the same folder (so they'd use the same codebase), and in its root is the .htaccess file.
Remove the "index.php" part of the url, to make it human and SEO friendly.
This is what I have so far:
Start with the basic .htaccess code for CodeIgniter, as shown in the userguide:
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php/$1
Originally, the last line had the [L] flag, but I omitted it, so it will continue to the following rules.
(Am I correct in assuming that it takes the url output in the previous RewriteRule, and perform the following matches on it?)
# for non www urls, add www and force https:
RewriteCond %{HTTP_HOST}(.*) !^www\. [NC]
RewriteRule ^(.*)$ https://www.%{HTTP_HOST}/$1 [R,L]
# for www urls, just force https:
RewriteRule ^(.*)$ https://%{HTTP_HOST}/$1 [R,L]
The above code is achieving tasks 1-3 of my list above, but the index.php is still showing in the address bar.
How do I remove it?
Well, I (partially) gave up on .htaccess, and solved my problem in a different way:
I'm now using CodeIgniter hook to deal with forcing https, and leave htaccess to deal only with forcing www and removing index.php
So I removed the last line (RewriteRule ^(.*)$ https://%{HTTP_HOST}/$1 [R,L]), and added an ssl hook to my application, and all is working now.
The hook function, in case anyone is interested, is this:
function force_ssl()
{
if ($_SERVER['HTTP_HOST']!='localhost' && $_SERVER['HTTP_HOST']!='10.0.2.2')
{
$CI =& get_instance();
$CI->config->config['base_url'] = str_replace('http://', 'https://', $CI->config->config['base_url']);
if ($_SERVER['SERVER_PORT'] != 443) redirect($CI->uri->uri_string());
}
}

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.

Rewrite Rule(s) for domain aliases

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.

RewriteEngine: subdomain to index.php, how?

Days later I asked about redirecting dynamic directories to index.php, and I got this code that works perfect (it's the only code I have in .htaccess):
RewriteEngine On
RewriteCond %{SCRIPT_FILENAME} !-d
RewriteCond %{SCRIPT_FILENAME} !-f
RewriteRule (.*) index.php
This translates urls like http://mydomain.example/dynamicdir/ to http://mydomain.example/index.php
Now I want to translate subdomains like http://dynamicdir.mydomain.example to http://mydomain.example/index.php?dir=dynamicdir
From examples I found in Internet I tried adding this line:
RewriteRule ^(.*)\.mydomain\.example index.php?dir=$1
But it doesn't work. I don't have enough experience with mod-rewrite to tell what's missing or wrong. Could you please help me to find a way to keep the dynamic directory translation, and add the catch-all subdomain rule?
Regards!
The mod_rewrite rules use the request path, which is relative to the virtual host. Try having different rewrite rules for each virtual host, but placing their documents in the same directory.
With RewriteRule you can only test the URL path. For the host name, you need to use %{HTTP_HOST} in a RewriteCond:
RewriteCond %{HTTP_HOST} ^(.+)\.example\.example$
RewriteRule ^ index.php?dir=%1

Resources