I have three domains all pointing to the same hosting space, mirrored using A
records:
example.org
example.org.uk
example.co.uk
I have a website on the root (/
), and a MediaWiki installation at example.org/members/wiki
. I'd like all requests to redirect to HTTPS and to the .org
domain.
I've managed this with the website using .htaccess
in the root:
RewriteEngine On
RewriteBase /
RewriteCond %{HTTP_HOST} !example.org$ [NC]
RewriteRule (.*) https://www.example.org/$1 [R=301,L]
but I can't get it to work with the wiki -- requests to the .org.uk
or .co.uk
domains are not redirected.
I have this .htaccess
in /members
:
Options -Indexes
RewriteEngine On
RewriteRule ^example.org.uk(/.*)?$ https://www.example.org/$1
RewriteRule ^example.co.uk(/.*)?$ https://www.example.org/$1
# MediaWiki pretty URL rewrites
RewriteRule ^/?members/wiki(/.*)?$ %{DOCUMENT_ROOT}/members/wiki/index.php [L]
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} !-f
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} !-d
RewriteRule ^(.*)$ %{DOCUMENT_ROOT}/members/wiki/index.php [L]
I want, for example, example.co.uk/members/wiki/My_Page
to seamlessly redirect to https://www.example.org/members/wiki/My_Page
.
Can anyone tell me what's wrong?
Your problem is that mod_rewrite directives are not inherited by default. The mod_rewrite directives in your
/members/.htaccess
file are completely overriding the mod_rewrite directives in the parent.htaccess
file. The mod_rewrite directives in the parent.htaccess
file are not being executed when your wiki is accessed.You can enable mod_rewrite inheritance from the
/members/.htaccess
file (usingRewriteOptions Inherit
), however, the current directives in the parent.htaccess
file are still not going to work if they are inherited. (Directives are inherited as if they are literally copied into the subdirectories.htaccess
file.)To use mod_rewrite inheritance, you would need to change the following directives in the parent
.htaccess
file:to read:
The
RewriteBase
directive is superfluous here. (Unless you have other directives?) TheREQUEST_URI
server variable contains the full URL-path, regardless of where is it used, unlike the captured URL-path from theRewriteRule
pattern which notably has the directory prefix removed in a directory/.htaccess
context. TheNC
flag should also be removed on this negated CondPattern, since you also want to redirect malformed requests.Aside: However, this still doesn't canonicalise the www subdomain and nor will it redirect non-HTTPS requests to
example.org
- is this a requirement? For that you would need something like the following instead:Note the start of string anchor (
^
) on the CondPattern (!^example\.org$
). And the additional check against theHTTPS
server variable (which is OR'd).And then in
/members/.htaccess
, you replace the first part (which would never work anyway, since theRewriteRule
pattern matches against the URL-path only, not the hostname):With the following:
Alternatively, you forget inheritance and simply copy the parent mod_rewrite directives into the
/members/.htaccess
file:Aside: However, these directives would not work in a
/members/.htaccess
file either?! These directives are intended for the server config (or VirtualHost) context.In per-directory
.htaccess
files, theRewriteRule
pattern matches against the URL-path less the directory-prefix. So, a pattern that starts^/?members/
will never match when the.htaccess
file itself is in the/members
subdirectory. (However, this would work in a server/VirtualHost context since the pattern matches against the full URL-path.)Also, in per-directory
.htaccess
files you cannot rewrite to an absolute filesystem path, it must be a document-root relative URL-path. (However, you could do this in a server/VirtualHost context.)Also,
%{DOCUMENT_ROOT}%{REQUEST_URI}
is more typical of a directive used in the server config. It is simpler to just use%{REQUEST_FILENAME}
in.htaccess
.For this to work in
/members/.htaccess
you would need to change these directives to read something more like the following: