htaccess one RewriteCond for multiple RewriteRules? - apache

I have trouble with redirects in .htaccess.
I have several domains (example.com, example.net, example.uk). I have set of RewriteRules for each domain. But for some reason, the redirects works for all domains. Following is my tried htaccess rules file.
RewriteCond %{HTTP_HOST} ^(www\.example\.com|example\.com) [NC]
RewriteRule ^1example$ / [R=302,L]
RewriteRule ^2example$ /example2 [R=302,L]
RewriteRule ^3example$ / [R=302,L]
RewriteRule ^4example$ /example4 [R=302,L]
RewriteCond %{HTTP_HOST} ^(www\.example\.net|example\.net) [NC]
RewriteRule ^5example$ /sgsg [R=302,L]
RewriteRule ^6example$ /example2 [R=302,L]
RewriteRule ^7example$ / [R=302,L]
RewriteRule ^8example$ /example44 [R=302,L]
RewriteCond %{HTTP_HOST} ^(www\.example\.uk|example\.uk) [NC]
RewriteRule ^9example$ / [R=302,L]
RewriteRule ^10example$ /example12 [R=302,L]
RewriteRule ^11example$ / [R=302,L]
RewriteRule ^12example$ /example41 [R=302,L]
Do you have any idea how to separate RewriteRules only for specific domain?

With your shown samples and attempts; please try following .htaccess rules file. As per anubhava's comments have added RewriteCond conditions before each RewriteRule.
Please make sure to clear your browser cache before testing your URLs.
RewriteEngine ON
RewriteCond %{HTTP_HOST} ^(?:www\.)?example\.com$ [NC]
RewriteRule ^(?:1|3)example$ / [R=302,L,NC]
RewriteCond %{HTTP_HOST} ^(?:www\.)?example\.com$ [NC]
RewriteRule ^(2|4)example$ /example$1 [R=302,L,NC]
RewriteCond %{HTTP_HOST} ^(?:www\.)?example\.net$ [NC]
RewriteRule ^5example$ /sgsg [R=302,L,NC]
RewriteCond %{HTTP_HOST} ^(?:www\.)?example\.net$ [NC]
RewriteRule ^6example$ /example2 [R=302,L,NC]
RewriteCond %{HTTP_HOST} ^(?:www\.)?example\.net$ [NC]
RewriteRule ^7example$ / [R=302,L,NC]
RewriteCond %{HTTP_HOST} ^(?:www\.)?example\.net$ [NC]
RewriteRule ^8example$ /example44 [R=302,L,NC]
RewriteCond %{HTTP_HOST} ^(?:www\.)?example\.uk$ [NC]
RewriteRule ^9example$ / [R=302,L,NC]
RewriteCond %{HTTP_HOST} ^(?:www\.)?example\.uk$ [NC]
RewriteRule ^10example$ /example12 [R=302,L,NC]
RewriteCond %{HTTP_HOST} ^(?:www\.)?example\.uk$ [NC]
RewriteRule ^11example$ / [R=302,L,NC]
RewriteCond %{HTTP_HOST} ^(?:www\.)?example\.uk$ [NC]
RewriteRule ^12example$ /example41 [R=302,L,NC]
Fixes applied to OP's attempts:
Attached 2 rules into 1 eg: RewriteRule ^(?:1|3)example$ / [R=302,L,NC] very first rule in above file.
Added NC flag in both RewriteCond and RewriteRule in all of the rules.
Made use of non-capturing group in RewriteCond to make www. optional eg: FROM ^(www\.example\.com|example\.com) TO ^(?:www\.)?example\.com$

As already mentioned, the RewriteCond (condition) directive itself applies only to the first RewriteRule that follows. The RewriteCond directive forms part of a single rule.
However, you can "workaround" this in various ways, without having to apply the same condition to multiple rules.
For example:
# Skip the following 4 rules when host is NOT "example.com"
RewriteCond %{HTTP_HOST} !^(www\.)?example\.com [NC]
RewriteRule ^ - [S=4]
# These rules only apply to "example.com"
RewriteRule ^1example$ / [R=302,L]
RewriteRule ^2example$ /example2 [R=302,L]
RewriteRule ^3example$ / [R=302,L]
RewriteRule ^4example$ /example4 [R=302,L]
# Skip the following 4 rules when host is NOT "example.net"
RewriteCond %{HTTP_HOST} !^(www\.)?example\.net [NC]
RewriteRule ^ - [S=4]
# These rules only apply to "example.net"
RewriteRule ^5example$ /sgsg [R=302,L]
RewriteRule ^6example$ /example2 [R=302,L]
RewriteRule ^7example$ / [R=302,L]
RewriteRule ^8example$ /example44 [R=302,L]
# Skip the following 4 rules when host is NOT "example.uk"
RewriteCond %{HTTP_HOST} !^(www\.)?example\.uk [NC]
RewriteRule ^ - [S=4]
# These rules only apply to "example.uk"
RewriteRule ^9example$ / [R=302,L]
RewriteRule ^10example$ /example12 [R=302,L]
RewriteRule ^11example$ / [R=302,L]
RewriteRule ^12example$ /example41 [R=302,L]
Alternatively, you could temporarily prefix the hostname to the URL-path and test for this directly in the RewriteRule directive.
For example:
# Prefix the hostname to the URL-path
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteCond %{HTTP_HOST} ^(?:www\.)?(example\.com|example\.net|example\.uk)
RewriteRule ^ %1%{REQUEST_URI}
RewriteRule ^example\.com/1example$ / [R=302,L]
RewriteRule ^example\.com/2example$ /example2 [R=302,L]
RewriteRule ^example\.com/3example$ / [R=302,L]
RewriteRule ^example\.com/4example$ /example4 [R=302,L]
RewriteRule ^example\.net/5example$ /sgsg [R=302,L]
RewriteRule ^example\.net/6example$ /example2 [R=302,L]
RewriteRule ^example\.net/7example$ / [R=302,L]
RewriteRule ^example\.net/8example$ /example44 [R=302,L]
RewriteRule ^example\.uk/9example$ / [R=302,L]
RewriteRule ^example\.uk/10example$ /example12 [R=302,L]
RewriteRule ^example\.uk/11example$ / [R=302,L]
RewriteRule ^example\.uk/12example$ /example41 [R=302,L]
# (OPTIONAL) Remove hostname prefix from URL-path
RewriteRule ^[^/]+/(.*) $1

Related

Apache .htaccess, subfolder

I have website on Phalcon and everything works fine (I have SSL) but now I would like to have an access to the forum (https://www.example.com/forum/) but I have a problem with the .htaccess configuration.
Phalcon have the specific config:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteCond %{HTTP_HOST} !^www.example.com [NC]
RewriteRule ^(.*)$ http://www.example.com%{REQUEST_URI} [R=301,L]
RewriteCond %{HTTPS} !=on
RewriteRule ^.*$ https://%{SERVER_NAME}%{REQUEST_URI} [R,L]
RewriteRule ^$ public/ [L]
RewriteRule (.*) public/$1 [L]
</IfModule>
What is the correct configuration for home domain and /forum/ folder?
RewriteEngine On
RewriteBase /
RewriteCond %{HTTP_HOST} !^www\.example\.com [NC]
RewriteRule ^ "http://www.example.com%{REQUEST_URI}" [R=301,L]
RewriteCond %{HTTPS} !=on
RewriteRule ^ "https://%{SERVER_NAME}%{REQUEST_URI}" [R,L]
RewriteCond %{REQUEST_URI} !^/forum/
RewriteRule ^.*$ public/$0 [L]
Phalcon's root .htaccess file redirects all traffic to /public folder.
What you need to do is add one more condition to your final rewrite rule. Here is portion of my .htaccess file:
<IfModule mod_rewrite.c>
RewriteEngine On
# Force www
RewriteCond %{HTTP_HOST} !^$
RewriteCond %{HTTP_HOST} !^www\. [NC]
RewriteCond %{HTTPS}s ^on(s)|
RewriteRule ^ http%1://www.%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
# Remove trailing slash
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} (.+)/$
RewriteRule ^ %1 [R=301,L]
# Forward to public/
RewriteRule ^(forum)($|/) - [L]
RewriteRule ^(.*)$ public/$1 [L]
</IfModule>
This RewriteRule ^(forum)($|/) - [L] is the important condition you need to add before RewriteRule ^.*$ public/$0 [L]
Also you can add as much as rules you want to allow multiple folders.
RewriteRule ^(forum)($|/) - [L]
RewriteRule ^(some-other-folder)($|/) - [L]
...

redirect to https url with get parameter

I have .htaccess file and code gives only https on pages of woocommerce shop and works perfectly. So how can I add rule that let https on page with GET parameter 'yandex_money=check' for example https://example.com/?yandex_money=check
RewriteEngine On
# Force HTTPS for /(cart|checkout|my-account|product-category|shop|product)
RewriteCond %{HTTPS} !=on
RewriteCond %{THE_REQUEST} ^[A-Z]+\s/(cart|checkout|my-account|product-category|shop|product) [NC]
RewriteRule ^(cart|checkout|my-account|product-category|shop|product) https://%{HTTP_HOST}%{REQUEST_URI} [NC,R=301,L]
# Force HTTP for anything which isn't /(cart|checkout|my-account|product-category|shop|product)
RewriteCond %{HTTPS} =on
RewriteCond %{THE_REQUEST} !^[A-Z]+\s/(cart|checkout|my-account|product-category|shop|product) [NC]
RewriteRule !^(cart|checkout|my-account|product-category|shop|product) http://%{HTTP_HOST}%{REQUEST_URI} [NC,R=301,L]
So the solution is
adding RewriteCond about %{REQUEST_URI} with [OR]
replace RewriteRule [L] with RewriteRule [N] and RewriteRule [L].
[N] key allows to check Next RewriteRule
[L] last is RewriteRule.
fixed .htaccess file:
RewriteEngine On
# RewriteCond %{HTTPS} on
# RewriteRule (.*) http://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
# Force HTTPS for /(cart|checkout|my-account|product-category|shop|product|wp-admin|wp-login) GET[yandex_money]
RewriteCond %{THE_REQUEST} ^[A-Z]+\s/(cart|checkout|my-account|product-category|shop|product|wp-admin|wp-login) [OR,NC]
#RewriteCond %{QUERY_STRING} ^yandex_money=check [NC]
RewriteCond %{HTTPS} !=on
RewriteRule ^(cart|checkout|my-account|product-category|shop|product|wp-admin|wp-login) https://%{HTTP_HOST}%{REQUEST_URI}?%{QUERY_STRING}[NC,R=301,N]
RewriteRule ^(yandex_money) https://%{HTTP_HOST}%{REQUEST_URI}?%{QUERY_STRING}[NC,R=301,L]
# Force HTTP for anything which isn't /(cart|checkout|my-account|product-category|shop|product|wp-admin|wp-login)
RewriteCond %{HTTPS} =on
RewriteCond %{THE_REQUEST} !^[A-Z]+\s/(cart|checkout|my-account|product-category|shop|product|wp-admin|wp-login) [NC]
RewriteCond %{QUERY_STRING} !^yandex_money=check [NC]
RewriteRule !^(cart|checkout|my-account|product-category|shop|product|wp-admin|wp-login) http://%{HTTP_HOST}%{REQUEST_URI}?%{QUERY_STRING}

Exclude one url from rewrite condition

I have following mod_rewrite rule to redirect from site.com to www.site.com:
RewriteCond %{HTTP_HOST} ^example\.com [NC]
RewriteRule ^(.*)$ http://example.com/$1 [R=permanent,L] .
I need to exclude from this rule urls starting with /yandex_market
RewriteCond %{HTTP_HOST} ^example\.com [NC]
RewriteCond %{REQUEST_URI} !^/yandex_market.*$ [NC]
RewriteRule ^(.*)$ http://example.com/$1 [R=permanent,L] .
But rule still works on urls starting with /yandex_market How to fix it?
Problem is that your 2nd rule rewrites /yandex_market/foo URI to /index.php?module=YandexPurchaseView&type=foo and thus making RewriteCond %{REQUEST_URI} !^/yandex_market.*$ [NC] condition succeed. You will need to use %{THE_REQUEST} variable for your condition which doesn't change with application of rewrite rules.
Keep your rules like this:
RewriteEngine On
RewriteCond %{HTTP_HOST} ^example\.com [NC]
RewriteCond %{THE_REQUEST} !/yandex_market [NC]
RewriteRule ^(.*)$ http://www.example.com/$1 [R=301,NE,L]
RewriteRule ^yandex_market/(.+)$ index.php?module=YandexPurchaseView&type=$1 [L,NC,QSA]

combination of rewrite rules not working

RewriteEngine On
RewriteCond %{HTTP_HOST} !.com$ //redirect from .net and .org to .com
RewriteRule .* http://www.domain.com%{REQUEST_URI} [R=301]
RewriteCond %{HTTP_HOST} !^www\. [NC] //Always use www.
RewriteRule ^/(.*)$ http://www.%1/$1 [R=301]
RewriteRule ^/?article-(.*)$ article.php?id=$1 [L,QSA,NC] // redirect article-x to article.php?id=x
RewriteRule ^/?page-(.*)$ page?p=$1 [L,QSA,NC]// redirect page-x to page.php?p=x
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}\.php -f
RewriteRule ^(.*)$ $1.php [L] // add the .php to every request if the file type is missing
all the rules work fine except for adding www. to url. for example http://domain.com/page-1
doesn't get redirected to http://www.domain.com/page-1
%1 refers to a pattern captured with () in the preceding RewriteCond. You haven't captured any patterns in RewriteCond. Instead, you can just use %{HTTP_HOST} in the RewriteRule.
If these rules reside in .htaccess, RewriteRule will not contain a leading /, and will therefore never match if your pattern does. Remove the / and match on ^(.*)$
RewriteCond %{HTTP_HOST} !^www\. [NC]
RewriteRule ^(.*)$ http://www.%{HTTP_HOST}/$1 [R=301]
Side note: don't forget to escape the . in .com. It will work unescaped, but the expression doesn't mean what you literally intend it to mean.
RewriteCond %{HTTP_HOST} !\.com$
The full set of rewrites all together should look like the following (I have removed all the leading / and /? expressions). I have tested all of this as working on my own system.
RewriteEngine On
RewriteCond %{HTTP_HOST} !\.com$ [NC]
#Use a capture group here, add [L]
RewriteRule (.*) http://www.example.com/$1 [L,R=301]
RewriteCond %{HTTP_HOST} !^www\. [NC]
RewriteRule ^(.*)$ http://www.%{HTTP_HOST}/$1 [L,R=301]
RewriteRule ^article-(.*)$ article.php?id=$1 [L,QSA,NC]
RewriteRule ^page-(.*)$ page?p=$1 [L,QSA,NC]
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}\.php -f
RewriteRule ^(.*)$ $1.php [L]

Apache .hatccess rewrites not working for legacy URLS

I'm trying to rewrite some legacy Joomla URLs on a site that's now using ExpressionEngine as its CMS but they're not working.
The ExpressionEngine URL rewrites, i.e. removing index.php from the URL work fine though.
This is what I've got:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{HTTPS} !=on
# This is the one that's not working
RewriteRule /index.php?option=com_chronocontact&Itemid=54 /contact/ [R=301,L]
# Force www
RewriteCond %{HTTP_HOST} !^www\..+$ [NC]
RewriteCond %{HTTP_HOST} (.+)$ [NC]
RewriteRule ^(.*)$ http://www.%1/$1 [R=301,L]
# Redirect index.php Requests
RewriteCond %{THE_REQUEST} ^[^/]*/index\.php [NC]
RewriteCond %{THE_REQUEST} ^GET
RewriteRule ^index\.php(.+) $1 [R=301,L]
# Standard ExpressionEngine Rewrite
RewriteCond %{REQUEST_URI} ^/
RewriteCond %{QUERY_STRING} ^(gclid=.*)
RewriteRule ^(.+) /index.php?/ [L,PT]
RewriteCond $1 !\.(css|js|gif|jpe?g|png) [NC]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond $1 !^(assets|css|images|tinymce|js|min|cms|themes|index\.php|admin\.php|favicon\.ico|index\.php|path\.php|php\.ini) [NC]
RewriteRule ^(.+) /index.php?/ [L]
</IfModule>
Can anyone spot what I'm doing wrong?
The first thing is the stray RewriteCond %{HTTPS} !=on that you have at the top. It looks like it belongs to the rule under it, as in:
RewriteCond %{HTTPS} !=on
RewriteCond %{HTTP_HOST} !^www\..+$ [NC]
RewriteCond %{HTTP_HOST} (.+)$ [NC]
RewriteRule ^(.*)$ http://www.%1/$1 [R=301,L]
As far as the rule that you have commented that doesn't work, the ? is a reserved character for regular expressions, and your pattern actually says that the second p in /index.php is "optional". Additionally, you can't match against the query string in a rewrite rule, you need to use a rewrite condition and match against the %{QUERY_STRING} variable:
RewriteCond %{QUERY_STRING} ^option=com_chronocontact&Itemid=54$
RewriteRule ^(index.php)?$ /contact/? [R=301,L]
is probably more along the lines of what you're looking for.