How to use Mod Rewrite to access non-document-root folder files?
I have the following structure for my website codes at /var/www/html
-- files
---- test.txt
-- app
---- SomePhpCodes.php
---- SomePhpCodes.php
-- public
---- index.php
---- .htaccess
The document root is set to be "/var/www/html/public" but I also want to have files accessible via path "http://mywebsite/files/test.txt".
I think this must be possible using mod_rewrite in the .htaccess
file inside public
but I am struggling to do so.
I tried to add a rule to the default .htaccess
that is provided by the Laravel framework. The current .htaccess
looks like the following:
<IfModule mod_rewrite.c>
<IfModule mod_negotiation.c>
Options -MultiViews -Indexes
</IfModule>
RewriteEngine On
# Handle Authorization Header
RewriteCond %{HTTP:Authorization} .
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
# Redirect Trailing Slashes If Not A Folder...
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} (.+)/$
RewriteRule ^ %1 [L,R=301]
# The following rule is added by me
RewriteRule files/(.*\.txt) /var/www/html/files/$1 [L]
# Send Requests To Front Controller...
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.php [L]
</IfModule>
The current result is Internal Server Error
when trying to access "http://mywebsite/files/test.txt". I have a feeling I might have missed some settings to make the "files" folder public but I don't have any idea how to do so.
I am stuck and if anyone can help me I will appreciate.
You can create a symlink
ln -s /var/www/html/files /var/www/html/public/files
You will need Options +FollowSymLinks
for this to work. Please note that this option adds a security risk as it allows accessing files outside of DocumentRoot
.
Alternatively you can add Alias /files /var/www/html/files
to your VirtualHost
configuration for this site. It is a more secure option but you can't do it with .htaccess
.
In addition to @AlexD's answer...
think this must be possible using mod_rewrite in the
.htaccess
file
This IS possible using mod_rewrite, but not in .htaccess
. You would need to do this directly in the main server config (or VirtualHost container).
In a directory (or .htaccess
) context you are restricted to rewriting to a URL-path only. However, in a server (or virtualhost) context you can rewrite to a URL-path or an absolute filesystem path.
However, this is not the cause of your Internal Server Error
...
RewriteRule files/(.*\.txt) /var/www/html/files/$1 [L]
This is most probably resulting in a rewrite-loop (hence 500 Internal Server Error response) because the unanchored RewriteRule
pattern also matches the substitution string (a root-relative URL-path) and so the rewritten URL-path is rewritten again and again...
In a server context, you could write it like this:
RewriteRule ^/files/(.+\.txt)$ /var/www/html/files/$1 [L]
(If you are not expecting subdirectories of the /files
directory then the regex should be made more restrictive, eg. ([^/]+\.txt)
)