-->

VirtualDocumentRoot handling non-existent folders

2019-07-23 15:22发布

问题:

Using Apache, I have set up the VirtualDocumentRoot and it works this way:

<VirtualHost *:80>
    UseCanonicalName Off
    ServerName app.example.com
    ServerAlias *.example.com
    VirtualDocumentRoot "/home/domains/example.com/%1"
    <Directory "/home/domains/example.com/*">
        Options Indexes FollowSymLinks
        AllowOverride All
        Order Allow,Deny
        Allow from all
    </Directory>
</VirtualHost>

If I put the URL of http://mail.example.com, the DocRoot becomes /home/domains/example.com/mail, if it is http://www.example.com, the DocRoot becomes /home/domains/example.com/www, and so on.

Now I would like to check for the folder if it exists, like when the user requests a domain like http://myusername.example.com, the DocRoot checks /home/domains/example.com/myusername and it doesn't exist, so it should refer to /home/domains/example.com/404. Is this possible?

I have referred the following questions but no good:

  • VirtualDocumentRoot Domains and Subdomains
  • Apache VirtualDocumentRoot redirect non-existing domains

回答1:

If you have virtual subdomains that are mapped to folders then couldn't you just check for the existance of the document root? If not exists redirect to the 404 subdomain which in turn should use /home/domains/example.com/404 perhaps like this.

<VirtualHost *:80>
    UseCanonicalName Off
    ServerName app.example.com
    ServerAlias *.example.com
    VirtualDocumentRoot "/home/domains/example.com/%1"
    <Directory "/home/domains/example.com/*">
        Options Indexes FollowSymLinks
        AllowOverride All
        Order Allow,Deny
        Allow from all
        RewriteEngine On
        RewriteCond %{DOCUMENT_ROOT} !-d
        RewriteRule ^(.*) http://404.example.com/ [R=301,L]
    </Directory>
</VirtualHost>

Or if the full virtualdocumentroot path is not being picked up by %{DOCUMENT_ROOT} variable because of the dynamic assignment, maybe try it this way by assiging subdomain to a env variable then use it to check the path.

  <VirtualHost *:80>
        UseCanonicalName Off
        ServerName app.example.com
        ServerAlias *.example.com
        VirtualDocumentRoot "/home/domains/example.com/%1"
        <Directory "/home/domains/example.com/*">
            Options Indexes FollowSymLinks
            AllowOverride All
            Order Allow,Deny
            Allow from all
            RewriteEngine On
            RewriteCond %{HTTP_HOST} ^(.+)\.example\.com [NC]
            RewriteRule ^(.*)$ - [E=virt_path:%1,N,NS]

            RewriteCond %{DOCUMENT_ROOT}/%{ENV:virt_path} !-d
            RewriteRule ^(.*) http://404.example.com/ [R=301,L]
        </Directory>
    </VirtualHost>


回答2:

Interesting problem indeed. You need to handle it by placing a custom 404 handler in <VirtualHost> section.

Add this line just below <VirtualHost *:80>:

ErrorDocument 404 http://www.example.com/404.html

This will try to open /home/domains/example.com/www/404.html when you visit:

http://myusername.example.com

And corresponding folder doesn't exist in your filesystem.