The BackgroundI run a university club website which has multiple domains, let's say meow.co.uk, foo.uni.ac.uk/bar/meow/ as two relevant cases. (When I upload files using an FTP client, it's the latter that I navigate to.) With my htaccess file, I'm trying to:Redirect from all other domains to meow.co.uk, the preferred domain, e.g. foo.uni.ac.uk/bar/meow/page.html --> meow.co.uk/page.htmlRemove a trailing slash from files that aren't directories, otherwise the user will get an internal server error, e.g. meow.co.uk/page/ --> meow.co.uk/pageClean the URLs:Display the contents of the html file if the .html extension is left out, e.g. navigating to meow.co.uk/page shows the same page as navigating to meow.co.uk/page.htmlRemove the .html extension from the address bar, e.g. meow.co.uk/page.html --> meow.co.uk/pageThe .htaccessErrorDocument 404 /errors/404.html#redirect from the other domains to meow.co.ukRewriteCond %{HTTP_HOST} !^(www\.)?meow\.co\.uk$ [NC]RewriteRule ^(.*)$ http://meow.co.uk/$1 [R=302]#remove trailing slash if not a directoryRewriteCond %{REQUEST_FILENAME} !-dRewriteRule ^(.+)/$ /$1 [R=302]#meow.co.uk/page will display the contents of meow.co.uk/page.htmlRewriteCond %{REQUEST_FILENAME} !-fRewriteCond %{REQUEST_FILENAME} !-dRewriteCond %{REQUEST_FILENAME}.html -fRewriteRule ^(.+)$ $1.html [L,QSA]#302 from meow.co.uk/page.html to meow.co.uk/pageRewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /.*\.html\ HTTP/RewriteRule ^(.*)\.html$ /$1 [R=302,L]What worksfoo.uni.ac.uk/bar/meow/page --> meow.co.uk/pagemeow.co.uk/page/ --> meow.co.uk/pagemeow.co.uk/page shows page.html and meow.co.uk/page.html --> meow.co.uk/pageWhat doesn't workExpected: foo.uni.ac.uk/bar/meow/page/ --> meow.co.uk/pageActual: --> foo.uni.ac.uk/http://meow.co.uk/page/Expected: foo.uni.ac.uk/bar/meow/page.html --> meow.co.uk/pageActual: --> foo.uni.ac.uk/http://meow.co.uk/pageWhy don't these work?
Conflicting mod_rewrite rules
htaccess;mod rewrite
tl;dr You need the L flag on your redirects, ie. [R=302,L].RewriteRule ^(.*)$ http://meow.co.uk/$1 [R=302]Bit of an aside, but... the RewriteRule pattern should be ^bar/meow/(.*) (as mentioned in my answer on your other question), otherwise you won't get the working redirects that you've stated.For external redirects you generally want to use the L (LAST) flag (briefly mentioned in comments on the other question). Since when you redirect you normally want the rewrite processing to stop and redirect immediately.This would seem to be the problem here, without the L flag, the rewriting continues and matches the next RewriteRule which further rewrites the request, resulting in a malformed redirect.This is what's happening in the cases that do not work:Request: http://foo.uni.ac.uk/bar/meow/page/The first RewriteRule matches against the URL-path (less the directory prefix, which is simply the / - slash)bar/meow/page/ >>> http://meow.co.uk/page/ (should stop here)But the second RewriteRule matches the result of the previous rewrite:http://meow.co.uk/page/ >>> foo.uni.ac.uk/http://meow.co.uk/page/Request: http://foo.uni.ac.uk/bar/meow/page.htmlbar/meow/page.html >>> http://meow.co.uk/page.html (should stop here)But the last RewriteRule now matches...http://meow.co.uk/page.html >>> foo.uni.ac.uk/http://meow.co.uk/pageSo, both your earlier redirects need the L flag ie. [R=302,L]. Ironically, the only place you don't need the L flag is where you have used it - in your last redirect! But it is good practise to include it anyway.Note also, that generally, external redirects should always come before internal rewrites. Whilst your rules work ok, they would be slightly more efficient (and more logical) if you had your internal rewrite last. Currently the last RewriteRule will always match, but the RewriteCond directive prevents it being triggered.If you reverse these rules then the RewriteRule will only match when needed:#302 from meow.co.uk/page.html to meow.co.uk/pageRewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /.*\.html\ HTTP/RewriteRule ^(.*)\.html$ /$1 [R=302,L]#meow.co.uk/page will display the contents of meow.co.uk/page.htmlRewriteCond %{REQUEST_FILENAME} !-fRewriteCond %{REQUEST_FILENAME} !-dRewriteCond %{REQUEST_FILENAME}.html -fRewriteRule (.+) $1.html [L]#redirect from the other domains to meow.co.ukRewriteCond %{HTTP_HOST} !^(www\.)?meow\.co\.uk$ [NC]RewriteRule ^(.*)$ http://meow.co.uk/$1 [R=302]Another slight problem is that your site would seem to still be accessible by both www.meow.co.uk and meow.co.uk. You should probably have a second rule to resolve this and redirect one to the other:RewriteCond %{HTTP_HOST} =www.meow.co.uk [NC]RewriteRule (.*) http://meow.co.uk/$1 [R=302,L]The = prefix on the CondPattern makes it an exact string match, it is no longer a regex (which is why the dots are not escaped).