Score:1

How to use Mod Rewrite to access non-document-root folder files?

tr flag

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.

Score:2
jp flag

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.

Score:1
kz flag

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))

mangohost

Post an answer

Most people don’t grasp that asking a lot of questions unlocks learning and improves interpersonal bonding. In Alison’s studies, for example, though people could accurately recall how many questions had been asked in their conversations, they didn’t intuit the link between questions and liking. Across four studies, in which participants were engaged in conversations themselves or read transcripts of others’ conversations, people tended not to realize that question asking would influence—or had influenced—the level of amity between the conversationalists.