apache.htaccessurl-rewritinglitespeed

Rewrite options InheritDown* behave weirdly in subdirectories and subdomains on LiteSpeed server


I was trying to host two separate sites, using the main domain like [www.]example.com and one subdomain sub.example.com, on a shared hosting environment powered by LiteSpeed. The document root of the subdomain is public_html/sub/ but its contents should not be accessed through example.com/sub/....

Initially I wrote a rule with RewriteCond %{HTTP_HOST} !^sub\.example\.com$ [NC] in public_html/sub/.htaccess to forbid wrong requests, which seemed to work.
But obviously, I will have to repeat this rule for each subdomain when there are more. Besides, the directories of the main domain were mixed with the subdomains. Therefore, I moved the files of the main domain to public_html/www/ directory, added the following lines in the following .htaccess files and removed the rule wrote before.

In public_html/.htaccess:

RewriteEngine On
RewriteOptions InheritDownBefore

RewriteRule ^ /www%{REQUEST_URI} [END]

In public_html/www/.htaccess:

RewriteEngine On
RewriteOptions IgnoreInherit
...

According to the doc, I supposed the rule would "change" the document root of the main domain to public_html/www/ as it is evaluated first and stops rewriting in any directory (as long as subdirectories do not turn off rewrite engine or ignore inheritance), while subdomains would not inherit rules from directories outside their document roots (public_html/.htaccess), thus not affected.

However, after changing example.com/sub/... actually are still accessible, just like InheritDown* are not supported by LiteSpeed. Even more strangely, valid URLs in sub.example.com will get not-found error, indicating they might be rewritten becaused of the inherited rule. I'm not sure if it is LiteSpeed's bug and should I report a problem. Or, did I misunderstand the option?

By the way, is there any alternative solution to implement the same function?


Solution

  • After trying more rules and comparing them with a standard Apache server, I'm basically sure the inherit feature is very buggy in LiteSpeed, and also I found a workaround to meet my needs. I'll just answer my question, but I think there're still better solutions (and expect new answers).

    First, I found that rewrite option InheritBefore behaves just like Inherit in LiteSpeed (inherited rules are still placed at last). And instead of preventing inheritance, IgnoreInherit actually also does like Inherit in LiteSpeed. InheritDown* randomly worked sometimes, but most of time it did not.
    Considering these weird problems, maybe it's better to just avoid using inheritance on LiteSpeed servers.

    Subdomains would not inherit rules from directories outside their document roots, thus not affected.

    Besides I have to clarify Inherit* in fact make sense for subdomains on both servers. Because of that, rewrite conditions should be added to public_html/.htaccess to avoid affecting subdomains:
    (For standard Apache servers, this will be enough to separate the main domain.)

    RewriteEngine On
    RewriteOptions InheritDownBefore
    
    # added
    RewriteCond %{IS_SUBREQ} false
    RewriteCond %{HTTP_HOST} ^(?:www\.)?example\.com$ [NC]
    RewriteRule ^ /www%{REQUEST_URI} [L]
    

    And as InheritDown* may not work in subdirectories containing .htaccess, one line still needs to be added to the .htaccess of each subdirectory:

    RewriteOptions InheritBefore
    

    However, since this workaround is not neat either, it might be better to keep the previous practice before finding better ones.