Home > Enterprise >  Matching all subdomains except some from list in htaccess
Matching all subdomains except some from list in htaccess

Time:11-22

How to mach all subdomain for example.com (ex. 123.example.com, abc.example.com etc.) except subdomains in this list:

  • main1
  • main2
  • main3

This rule in .htaccess would help to change robots.txt to robots_sub.txt if a subdomain matched. Here is an example:

RewriteCond %{HTTP_HOST} ^(?<!main1|main2|main3). \.example\.com$ [NC]
RewriteRule ^robots\.txt$ /robots_sub.txt [L]

As a result it should be:

123.example.com - match
abc.example.com - match
main1.example.com - exclusion
zyx.example.com - match
main2.example.com - exclusion
main3.example.com - exclusion
sub.example.com - match

CodePudding user response:

RewriteCond %{HTTP_HOST} ^(?<!main1|main2|main3). \.example\.com$ [NC]

Use a negative lookahead, rather than a negative lookbehind * here. For example:

RewriteCond %{HTTP_HOST} ^(?!(main1|main2|main3)\.)[^.] \.example\.com$ [NC]
:

Only subdomains that are exactly equal to main1 or main2 or main3 are excluded. Subdomains that have a partial match (eg. abcmain1 or main1xyz) are permitted.

Or, use a separate condition. For example:

RewriteCond %{HTTP_HOST} !^(main1|main2|main3)\.
RewriteCond %{HTTP_HOST} \.example\.com$ [NC]
:

The ! prefix on the CondPattern in the first condition negates the expression so it is successful when it does not match (ie. when the Host header does not start main1., main2. or main3.). The second condition then confirms that it is a subdomain being requested and not the domain apex.


Additional explanation:

RewriteCond %{HTTP_HOST} ^(?<!main1|main2|main3). \.example\.com$ [NC]

* In attempting to use a negative lookbehind in this way, you are trying to assert that the string main1 (or main2 or main3) does not exist before the start of the string (ie. before the Host header), which is not possible in this context, so is always going to be successful. In order to use a negative lookbehind you need to first match something that the stated string can come before. For example:

^. (?<!^(main1|main2|main3))\.mywebsite\.com$

But this is less efficient than the negative lookahead used above.

  • Related