We are trying to solve language redirection "the right way" over at https://guestbell.com/. Some idioms first:
a) Each route has a starting URL parameter that identifies the language. e.g. https://guestbell.com/en for English and https://guestbell.com/es for Spanish. There are also https://guestbell.com/en/pricing etc.
b) You can also omit this parameter, e.g. https://guestbell.com/pricing . The language is then detected (cookie, browser-language, qs param or URL param) and added to the URL. Page is SPA in react, the detection is done by i18next library.
c) Every possible page is pre-rendered in HTML files that are served via static server.
Note that because the routes are pre-rendered, routes like https://guestbell.com/pricing doesn't in fact exist in the folder structure (because it's impossible to guess the language prior to front end detection)
What works so far:
You navigate to guestbell.com
You are redirected to https via htaccess
If the file is found, serve it.
If the file is not found, serve a PHP file that is written as follows:
<?php
$cookieName = "i18next";
$path = rtrim(strtok($_SERVER["REQUEST_URI"], '?'), '/');
$supportedLangs = [
'en',
'es',
];
$defaultLang = $supportedLangs[0];
$lang = substr($_SERVER['HTTP_ACCEPT_LANGUAGE'], 0, 2);
if(isset($_COOKIE[$cookieName])) {
$lang = $_COOKIE[$cookieName];
}
$finalLang = $lang;
if (!in_array($lang, $supportedLangs)) {
$finalLang = $defaultLang;
}
$newPath = $finalLang . $path . '.html';
if (file_exists($newPath) || empty($path)) {
$newPath = $finalLang . $path;
header("Location: $newPath", true, 302);
} else {
$newPath = $finalLang . '/404';
header("Location: $newPath", true, 302);
}
?>
As you can see, it attempts to detect via cookie or browser language (we know that by this point, the URL param is not present)
This approach works fine but there is one issue.
When navigating to guestbell.com (as most people would), this results into 2 redirects:
HTTP => HTTPS
/ => /en
Ideally, I would like to eliminate this added overhead and do it in one redirect. The only way (that I can imagine at the moment) is to do it via htaccess. The issue is I have no idea if this is possible.
This is the current htaccess for completion sake:
ErrorDocument 404 /404.html
#This is extremely important as it disables rewriting route from en => en/ and then 403-ing on directory
#https://stackoverflow.com/questions/28171874/mod-rewrite-how-to-prioritize-files-over-folders
DirectorySlash Off
# BEGIN WWW omit
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{HTTP_HOST} ^www\.(.*)$ [NC]
RewriteRule ^ %{REQUEST_SCHEME}://%1%{REQUEST_URI} [R=301,L]
</IfModule>
# END WWW omit
# BEGIN HTTPS redirect
<IfModule BEGIN HTTPS redirectfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteCond %{ENV:HTTPS} !=on
RewriteRule ^.*$ https://%{SERVER_NAME}%{REQUEST_URI} [R,L]
</IfModule>
# END HTTPS redirect
# BEGIN Omit extension
<ifModule mod_rewrite.c>
#remove html file extension-e.g. https://example.com/file.html will become https://example.com/file
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^([^\.]+)$ $1.html [NC,L]
</ifModule>
# END Omit extension
# BEGIN File detection
<ifModule mod_rewrite.c>
RewriteEngine On
# If an existing asset or directory is requested go to it as it is
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} -f [OR]
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} -d
RewriteRule ^ - [L]
# If the requested resource doesn't exist, use index.php - that file then takes care of language redirection
RewriteRule ^ /index.php
</ifModule>
# END File detection
# BEGIN Compress text files
<ifModule mod_deflate.c>
<filesMatch "\.(css|js|x?html?|php)$">
SetOutputFilter DEFLATE
</filesMatch>
</ifModule>
# END Compress text files
# BEGIN Cache
<ifModule mod_headers.c>
<filesMatch "\\.(ico|pdf|flv|jpg|jpeg|png|gif|swf|svg|mp4)$">
Header set Cache-Control "max-age=31536000, public"
</filesMatch>
<filesMatch "\\.(css)$">
Header set Cache-Control "max-age=31536000, public"
</filesMatch>
<filesMatch "\\.(js)$">
Header set Cache-Control "max-age=31536000, private"
</filesMatch>
<filesMatch "\\.(xml|txt)$">
Header set Cache-Control "max-age=2592000, public, must-revalidate"
</filesMatch>
<filesMatch "\\.(html|htm|php)$">
Header set Cache-Control "max-age=0, no-cache, no-store, must-revalidate"
</filesMatch>
<filesMatch "sw.js$">
Header set Cache-Control "max-age=0, no-cache, no-store, must-revalidate"
</filesMatch>
</ifModule>
# END Cache
An alternative would be to leave the language detection to front-end in such cases, and thus losing the prerendering altogether. I don't like this too much as majority of people would navigate to root of the page instead of /en and therefore lose performance. But what worries me is that the performance will be lost anyways due to multiple redirect.
My question stands:
Is it possible to do cookie and browser-language redirection combined with HTTP => HTTPS inside htaccess? If so, could you provide any help in achieving such functionality? If not, could you share the best way of achieving this, or optionally verify that our approach using PHP is "good enough"?
Many thanks.
Related
I am using the following code in .htaccess file to sort out canonical redirects in Apache server. This works very well and redirects example.com, example.com/index.html and www.example.com/index.html ALL to www.example.com :-
#Redirect to www location
#Redirect example.com to www.example.com
RewriteEngine on
RewriteBase /
RewriteCond %{HTTP_HOST} ^example.com [NC]
RewriteRule ^(.*)$ http://www.example.com/$1 [R=301,NC]
RewriteRule ^index\.(php|html?)$ http://www.example.com/ [L,R=301]
The above code works perfectly in .htaccess
I ALSO would like to have a ErrorDocument 404 rule to send visitors who arrive at non-existent pages to a specially designed page, namely: http://example.com/404/404.html
HOWEVER, when I add the following line to my .htaccess file, it does nothing. Ie navigating to a non-existent page (for example entering url www.example.com/asidhaskudhsadh just returns a standard 404 error page). The code I am trying to use is:
ErrorDocument 404 http://www.example.com/404/404.html
(Ps. this is not an absolute url address issue as is often the case, because I have tried it with
ErrorDocument 404 http://www.google.com
and it still doesn't work. Whether I include the ErrorDocument line or not, the canonical redirects continue to work. The ErrorDocument line basically seems to have no effect at all.
Any ideas? My whole .htaccess file code is reproduced below. The strange line at the bottom was put in by an external mobile website development team to check whether visitors are on mobile devices and should go to the mobile version of the website (namely, http://www.example.com/m). The index.php file that it refers to is also included below.
.htaccess file
AddType x-mapp-php5 .php
ErrorDocument 404 http://www.example.com/404/404.html
#Redirect example.com to www.example.com
#Redirect to www location
RewriteEngine on
RewriteBase /
RewriteCond %{HTTP_HOST} ^example.com [NC]
RewriteRule ^(.*)$ http://www.example.com/$1 [R=301,NC]
RewriteRule ^index\.(php|html?)$ http://www.example.com/ [L,R=301]
##### Speed Up Loading With Caching of Files #####
<IfModule mod_headers.c>
# YEAR
<FilesMatch "\.(ico|gif|jpg|jpeg|png|flv|pdf)$">
Header set Cache-Control "max-age=2419200"
</FilesMatch>
# WEEK
<FilesMatch "\.(js|css|swf)$">
Header set Cache-Control "max-age=604800"
</FilesMatch>
# 45 MIN
<FilesMatch "\.(html|htm|txt)$">
Header set Cache-Control "max-age=2700"
</FilesMatch>
</IfModule>
###### DO NOT REMOVE THIS LINE!!! ######
DirectoryIndex index.php
###### DO NOT REMOVE THIS LINE!!! ######
The desktop website loads using index.html
The index.php file code which is referenced in the last line of .htaccess file is as below:
<?php
ob_start( 'ob_gzhandler' );
$iphone = strpos($_SERVER['HTTP_USER_AGENT'],"iPhone");
$android = strpos($_SERVER['HTTP_USER_AGENT'],"Android");
$palmpre = strpos($_SERVER['HTTP_USER_AGENT'],"webOS");
$berry = strpos($_SERVER['HTTP_USER_AGENT'],"BlackBerry");
$ipod = strpos($_SERVER['HTTP_USER_AGENT'],"iPod");
/* recomment in for mobile activation */
//echo #file_get_contents("index.html");
if(isset($_GET["m"]) && $_GET["m"] == "off"){
$expire = time() + 60 * 60 * 24;
setcookie("mobile", "off", $expire);
echo #file_get_contents("index.html");
} else if (isset($_COOKIE["mobile"]) && $_COOKIE["mobile"] == "off"){
echo #file_get_contents("index.html");
} else if ($iphone || $android || $palmpre || $ipod || $berry == true){
header("Location: http://www.example.com/m/home.php");
} else {
echo #file_get_contents("index.html");
}
?>
We recently moved 2 websites to full SSL as we know Google ranks better for secure websites. But it's been over two months and our website is not getting indexed as SSL.
For example;
Within a week of putting ssl on our Joomla site all our urls have changed in Google as https:// which is what we want - this is because we set up a 301 redirect in the Joomla htaccess.
But on our Opencart website which has a differently configured htaccess file it's still displaying only non SSL results on Google. The SSL is working properly on our website and has been crawled dozens of time since by Google but for some reason Google won't index us as a https website.
I am thinking that there's not a proper 301 redirect set up in our htaccess. I have attached it below:
#gzip starts
<ifModule mod_deflate.c>
<filesMatch "\.(js|css|txt|woff)$">
SetOutputFilter DEFLATE
</filesMatch>
</ifModule>
#cache starts
<FilesMatch "\.(ico|jpg|jpeg|png|gif|js|css|swf|woff|txt)$">
<IfModule mod_expires.c>
ExpiresActive on
ExpiresDefault "access plus 14 days"
</IfModule>
Header unset ETag
FileETag None
</FilesMatch>
#domain rewrite starts
RewriteCond %{HTTP_HOST} !^(www\.|$) [NC]
RewriteRule ^ http://www.%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
RewriteCond %{SERVER_PORT} 80
RewriteRule ^(.*)$ https://www.gomobility.ie/$1 [R=301,L]
# 1.To use URL Alias you need to be running apache with mod_rewrite enabled.
# 2. In your opencart directory rename htaccess.txt to .htaccess.
# For any support issues please visit: http://www.opencart.com
Options +FollowSymlinks
# Prevent Directoy listing
Options -Indexes
# Prevent Direct Access to files
<FilesMatch "\.(tpl|ini|log)">
Order deny,allow
Deny from all
</FilesMatch>
# SEO URL Settings
RewriteEngine On
# If your opencart installation does not run on the main web folder make sure you folder it does run in ie. / becomes /shop/
RewriteBase /
RewriteRule ^sitemap.xml$ index.php?route=feed/google_sitemap [L]
RewriteRule ^googlebase.xml$ index.php?route=feed/google_base [L]
RewriteRule ^download/(.*) /index.php?route=error/not_found [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} !.*\.(ico|gif|jpg|jpeg|png|js|css)
RewriteRule ^([^?]*) index.php?_route_=$1 [L,QSA]
### Additional Settings that may need to be enabled for some servers
### Uncomment the commands by removing the # sign in front of it.
### If you get an "Internal Server Error 500" after enabling any of the following settings, restore the # as this means your host doesn't allow that.
# 1. If your cart only allows you to add one item at a time, it is possible register_globals is on. This may work to disable it:
# php_flag register_globals off
# 2. If your cart has magic quotes enabled, This may work to disable it:
# php_flag magic_quotes_gpc Off
# 3. Set max upload file size. Most hosts will limit this and not allow it to be overridden but you can try
# php_value upload_max_filesize 999M
# 4. set max post size. uncomment this line if you have a lot of product options or are getting errors where forms are not saving all fields
# php_value post_max_size 999M
# 5. set max time script can take. uncomment this line if you have a lot of product options or are getting errors where forms are not saving all fields
# php_value max_execution_time 200
# 6. set max time for input to be recieved. Uncomment this line if you have a lot of product options or are getting errors where forms are not saving all fields
# php_value max_input_time 200
# 7. disable open_basedir limitations
# php_admin_value open_basedir none
Any help would really be appreciated.
Your canonical links are still not ssl. OpenCart generates canonical links (view your source). These links are generated through OpenCart and won't be affected by your htaccess.
There are a couple ways to change this. First you could find each instance where you call the link function and add SSL as the 3rd argument.
Replace this:
$this->url->link('example/path');
With this:
$this->url->link('example/path', '', 'SSL');
Or you could change the link funciton to handle all links as SSL links by default. Go to system/library/url.php and change this line.
public function link($route, $args = '', $connection = 'NONSSL') {
To this:
public function link($route, $args = '', $connection = 'SSL') {
Your canonical tag is the http version, I would change that to https to avoid sending conflicting signals.
Just two points which you may of course know. First, make sure your sitemap is indexing https and not http. Second, you have to set up a new website in Google webmaster with the new https website address - do not delete the old one. You will then see the new site being indexed.
On my development server running xampp on windows my .htacess rewrite rules are working fine. Once we went to our live server which is running Linux core 3.8.0-21-generic #32-Ubuntu SMP Server version: Apache/2.2.22 (Ubuntu), our rules which do not contain parameters no longer work, yet rules which do have parameters are working.
Options -Indexes
<filesMatch "\.(html|htm|txt|js|htaccess)$">
FileETag None
<ifModule mod_headers.c>
Header unset ETag
Header set Cache-Control "max-age=0, no-cache, no-store, must-revalidate"
Header set Pragma "no-cache"
Header set Expires "Wed, 11 Jan 1984 05:00:00 GMT"
</ifModule>
</filesMatch>
ErrorDocument 404 /404.php
RewriteEngine On
#Main site rules
RewriteRule ^login/?$ login.php [NC,L]
RewriteRule ^contact/?$ contact.php [NC,L]
The above rules which go to contact.php and login.php do not work. But, this more complicated rule with parameters is working:
RewriteRule ^game/([a-zA-Z0-9]+)/?$ handles/handle-game-select.php?name=$1 [NC,L]
Is there differences between the two server environments which is causing this to occur?
Also, it appears that if we do something strange such as: RewriteRule ^contact.x contact.php [NC,L] we are able to reach contact.php...
Very confused on this one.
Thank you for any help.
I suspect that is due to enabling of MultiViews option. Add this line on top to disable it:
Options -MultiViews
Option MultiViews is used by Apache's content negotiation module that runs before mod_rewrite and and makes Apache server match extensions of files. So /file can be in URL but it will serve /file.php.
I have a (Drupal) website running in a subfolder, with another (Drupal) website running in the root. The website in the subfolder is a multilingual website. I need the subfolder name to change, depending on the language the site is being displayed in, but I'm not able to find or create a working rewrite rule for it.
The scenario is as follows:
The website is located in folder with the different languages showing urls like folder/folder, folder/dossier and folder/map. The language tags are handled by Drupal. The end result I desire is:
folder/folder >> folder/
folder/map >> map/
folder/dossier >> dossier/
This means that the subfolder is removed from the URL, and only the language urls remain.
Any idea how to solve this problem, using htaccess, prefably without redirects, and without having a negative influence on the root website?
Below is the Drupal htaccess being used. The same htaccess is used in the root, but then with the RewriteBase still commented.
#
# Apache/PHP/Drupal settings:
#
# Protect files and directories from prying eyes.
<FilesMatch "\.(engine|inc|info|install|make|module|profile|test|po|sh|.*sql|theme|tpl(\.php)?|xtmpl)(|~|\.sw[op]|\.bak|\.orig|\.save)?$|^(\..*|Entries.*|Repository|Root|Tag|Template)$|^#.*#$|\.php(~|\.sw[op]|\.bak|\.orig\.save)$">
Order allow,deny
</FilesMatch>
# Don't show directory listings for URLs which map to a directory.
Options -Indexes
# Follow symbolic links in this directory.
Options +FollowSymLinks
# Make Drupal handle any 404 errors.
ErrorDocument 404 /index.php
# Set the default handler.
DirectoryIndex index.php index.html index.htm
# Override PHP settings that cannot be changed at runtime. See
# sites/default/default.settings.php and drupal_environment_initialize() in
# includes/bootstrap.inc for settings that can be changed at runtime.
# PHP 5, Apache 1 and 2.
<IfModule mod_php5.c>
php_flag magic_quotes_gpc off
php_flag magic_quotes_sybase off
php_flag register_globals off
php_flag session.auto_start off
php_value mbstring.http_input pass
php_value mbstring.http_output pass
php_flag mbstring.encoding_translation off
</IfModule>
# Requires mod_expires to be enabled.
<IfModule mod_expires.c>
# Enable expirations.
ExpiresActive On
# Cache all files for 2 weeks after access (A).
ExpiresDefault A1209600
<FilesMatch \.php$>
# Do not allow PHP scripts to be cached unless they explicitly send cache
# headers themselves. Otherwise all scripts would have to overwrite the
# headers set by mod_expires if they want another caching behavior. This may
# fail if an error occurs early in the bootstrap process, and it may cause
# problems if a non-Drupal PHP file is installed in a subdirectory.
ExpiresActive Off
</FilesMatch>
</IfModule>
# Various rewrite rules.
<IfModule mod_rewrite.c>
RewriteEngine on
# Set "protossl" to "s" if we were accessed via https://. This is used later
# if you enable "www." stripping or enforcement, in order to ensure that
# you don't bounce between http and https.
RewriteRule ^ - [E=protossl]
RewriteCond %{HTTPS} on
RewriteRule ^ - [E=protossl:s]
# Block access to "hidden" directories whose names begin with a period. This
# includes directories used by version control systems such as Subversion or
# Git to store control files. Files whose names begin with a period, as well
# as the control files used by CVS, are protected by the FilesMatch directive
# above.
#
# NOTE: This only works when mod_rewrite is loaded. Without mod_rewrite, it is
# not possible to block access to entire directories from .htaccess, because
# <DirectoryMatch> is not allowed here.
#
# If you do not have mod_rewrite installed, you should remove these
# directories from your webroot or otherwise protect them from being
# downloaded.
RewriteRule "(^|/)\." - [F]
# If your site can be accessed both with and without the 'www.' prefix, you
# can use one of the following settings to redirect users to your preferred
# URL, either WITH or WITHOUT the 'www.' prefix. Choose ONLY one option:
#
# To redirect all users to access the site WITH the 'www.' prefix,
# (http://example.com/... will be redirected to http://www.example.com/...)
# uncomment the following:
# RewriteCond %{HTTP_HOST} .
# RewriteCond %{HTTP_HOST} !^www\. [NC]
# RewriteRule ^ http%{ENV:protossl}://www.%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
#
# To redirect all users to access the site WITHOUT the 'www.' prefix,
# (http://www.example.com/... will be redirected to http://example.com/...)
# uncomment the following:
# RewriteCond %{HTTP_HOST} ^www\.(.+)$ [NC]
# RewriteRule ^ http%{ENV:protossl}://%1%{REQUEST_URI} [L,R=301]
# Modify the RewriteBase if you are using Drupal in a subdirectory or in a
# VirtualDocumentRoot and the rewrite rules are not working properly.
# For example if your site is at http://example.com/drupal uncomment and
# modify the following line:
# RewriteBase /drupal
#
# If your site is running in a VirtualDocumentRoot at http://example.com/,
# uncomment the following line:
RewriteBase /folder/
# Pass all requests not referring directly to files in the filesystem to
# index.php. Clean URLs are handled in drupal_environment_initialize().
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} !=/favicon.ico
RewriteRule ^ index.php [L]
# Rules to correctly serve gzip compressed CSS and JS files.
# Requires both mod_rewrite and mod_headers to be enabled.
<IfModule mod_headers.c>
# Serve gzip compressed CSS files if they exist and the client accepts gzip.
RewriteCond %{HTTP:Accept-encoding} gzip
RewriteCond %{REQUEST_FILENAME}\.gz -s
RewriteRule ^(.*)\.css $1\.css\.gz [QSA]
# Serve gzip compressed JS files if they exist and the client accepts gzip.
RewriteCond %{HTTP:Accept-encoding} gzip
RewriteCond %{REQUEST_FILENAME}\.gz -s
RewriteRule ^(.*)\.js $1\.js\.gz [QSA]
# Serve correct content types, and prevent mod_deflate double gzip.
RewriteRule \.css\.gz$ - [T=text/css,E=no-gzip:1]
RewriteRule \.js\.gz$ - [T=text/javascript,E=no-gzip:1]
<FilesMatch "(\.js\.gz|\.css\.gz)$">
# Serve correct encoding type.
Header set Content-Encoding gzip
# Force proxies to cache gzipped & non-gzipped css/js files separately.
Header append Vary Accept-Encoding
</FilesMatch>
</IfModule>
</IfModule>
1 - Use this rule in your DOCUMENT_ROOT/.htaccess file as first rule:
RewriteEngine On
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteRule ^(map|dossier)(/|$) /folder%{REQUEST_URI} [L,NC]
2 - Use this rule in your DOCUMENT_ROOT/folder/.htaccess file as first rule:
RewriteEngine On
RewriteBase /folder/
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteRule !^(map|dossier|folder)(/|$) folder%{REQUEST_URI} [L,NC]
I am using a standard web hosting service with for my own projects.
It used the main domain wwwand several subdomains. I didn't need to use any Apache ReWrite rules in my .htaccess files, and the only thing I had to do was make sure that I had my CNAME records updated. All worked fine, I just used permissions to limit access to files and folders..
I recently installed Elgg at the main wwwlevel and now all my subdomains, which remain unchanged, give a 403error. The message points to my htaccess file being the culprit.
I would like to know how I can configure the htaccess file to allow subdomains like gadgets.mydomain.com to work again but not allow access to other folders under the same domain? None of the permissions were changed they remain as 755.
This is the standard Elgg htaccess file. How would I edit it?
# Elgg htaccess directives
<Files "htaccess_dist">
order allow,deny
deny from all
</Files>
# Don't allow listing directories
Options -Indexes
# Follow symbolic links
Options +FollowSymLinks
# Default handler
DirectoryIndex index.php
############################
# BROWSER CACHING
# The expires module controls the Expires and Cache-Control headers. Elgg sets
# these for dynamically generated files so this is just for static files.
<IfModule mod_expires.c>
ExpiresActive On
ExpiresDefault "access plus 1 year"
</IfModule>
# Conditional requests are controlled through Last-Modified and ETag headers.
# Elgg sets these on dynamically generated cacheable files so this is just for
# static files. Note: Apache sends Last-Modified by default on static files so
# I don't think we need to be sending ETag for these files.
<FilesMatch "\.(jpg|jpeg|gif|png|mp3|flv|mov|avi|3pg|html|htm|swf|js|css|ico)$">
FileETag MTime Size
</FilesMatch>
############################
# PHP SETTINGS
<IfModule mod_php5.c>
# limit the maximum memory consumed by the php script to 64 MB
php_value memory_limit 64M
# register_globals is deprecated as of PHP 5.3.0 - disable it for security reasons.
php_value register_globals 0
# post_max_size is the maximum size of ALL the data that is POST'ed to php at a time (8 MB)
php_value post_max_size 8388608
# upload_max_filesize is the maximum size of a single uploaded file (5 MB)
php_value upload_max_filesize 5242880
# on development servers, set to 1 to display errors. Set to 0 on production servers.
php_value display_errors 0
</IfModule>
############################
# COMPRESSION
# Turn on mod_gzip if available
<IfModule mod_gzip.c>
mod_gzip_on yes
mod_gzip_dechunk yes
mod_gzip_keep_workfiles No
mod_gzip_minimum_file_size 1000
mod_gzip_maximum_file_size 1000000
mod_gzip_maximum_inmem_size 1000000
mod_gzip_item_include mime ^text/.*
mod_gzip_item_include mime ^application/javascript$
mod_gzip_item_include mime ^application/x-javascript$
# Exclude old browsers and images since IE has trouble with this
mod_gzip_item_exclude reqheader "User-Agent: .*Mozilla/4\..*\["
mod_gzip_item_exclude mime ^image/.*
</IfModule>
## Apache2 deflate support if available
##
## Important note: mod_headers is required for correct functioning across proxies.
##
<IfModule mod_deflate.c>
AddOutputFilterByType DEFLATE text/html text/plain text/xml text/css text/javascript application/javascript application/x-javascript
BrowserMatch ^Mozilla/4 gzip-only-text/html
BrowserMatch ^Mozilla/4\.[0678] no-gzip
BrowserMatch \bMSIE !no-gzip
<IfModule mod_headers.c>
Header append Vary User-Agent env=!dont-vary
</IfModule>
# The following is to disable compression for actions. The reason being is that these
# may offer direct downloads which (since the initial request comes in as text/html and headers
# get changed in the script) get double compressed and become unusable when downloaded by IE.
SetEnvIfNoCase Request_URI action\/* no-gzip dont-vary
SetEnvIfNoCase Request_URI actions\/* no-gzip dont-vary
</IfModule>
############################
# REWRITE RULES
<IfModule mod_rewrite.c>
RewriteEngine on
# If Elgg is in a subdirectory on your site, you might need to add a RewriteBase line
# containing the path from your site root to elgg's root. e.g. If your site is
# http://example.com/ and Elgg is in http://example.com/sites/elgg/, you might need
#
#RewriteBase /sites/elgg/
#
# here, only without the # in front.
#
# If you're not running Elgg in a subdirectory on your site, but still getting lots
# of 404 errors beyond the front page, you could instead try:
#
#RewriteBase /
# If your users receive the message "Sorry, logging in from a different domain is not permitted"
# you must make sure your login form is served from the same hostname as your site pages.
# See http://docs.elgg.org/wiki/Login_token_mismatch_error for more info.
#
# If you must add RewriteRules to change hostname, add them directly below (above all the others)
# In for backwards compatibility
RewriteRule ^pg\/([A-Za-z0-9\_\-]+)$ engine/handlers/page_handler.php?handler=$1&%{QUERY_STRING} [L]
RewriteRule ^pg\/([A-Za-z0-9\_\-]+)\/(.*)$ engine/handlers/page_handler.php?handler=$1&page=$2&%{QUERY_STRING} [L]
RewriteRule ^tag\/(.+)\/?$ engine/handlers/page_handler.php?handler=search&page=$1 [L]
RewriteRule ^action\/([A-Za-z0-9\_\-\/]+)$ engine/handlers/action_handler.php?action=$1&%{QUERY_STRING} [L]
RewriteRule ^cache\/(.*)$ engine/handlers/cache_handler.php?request=$1&%{QUERY_STRING} [L]
RewriteRule ^services\/api\/([A-Za-z0-9\_\-]+)\/(.*)$ engine/handlers/service_handler.php?handler=$1&request=$2&%{QUERY_STRING} [L]
RewriteRule ^export\/([A-Za-z]+)\/([0-9]+)\/?$ engine/handlers/export_handler.php?view=$1&guid=$2 [L]
RewriteRule ^export\/([A-Za-z]+)\/([0-9]+)\/([A-Za-z]+)\/([A-Za-z0-9\_]+)\/$ engine/handlers/export_handler.php?view=$1&guid=$2&type=$3&idname=$4 [L]
RewriteRule xml-rpc.php engine/handlers/xml-rpc_handler.php [L]
RewriteRule mt/mt-xmlrpc.cgi engine/handlers/xml-rpc_handler.php [L]
# rule for rewrite module test during install - can be removed after installation
RewriteRule ^rewrite.php$ install.php [L]
# Everything else that isn't a file gets routed through the page handler
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^([A-Za-z0-9\_\-]+)$ engine/handlers/page_handler.php?handler=$1 [QSA,L]
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^([A-Za-z0-9\_\-]+)\/(.*)$ engine/handlers/page_handler.php?handler=$1&page=$2 [QSA,L]
</IfModule>
OK I worked out what had cause the problem.
It was this line
# Default handler
DirectoryIndex index.php
Basically unless your directory uses a file called index.phpby default, the subdomain doesn't work. I commented this line. Another option would be to make sure all my index files had the .phpextension.