Home > front end >  htaccess redirecting to files available in the public directory
htaccess redirecting to files available in the public directory

Time:02-22

[ Background ]
This is the structure to my application:

app/
    controllers/
        ...
    modules/
        ...
    views/
        ...
public/
    css/
        main.css
    images/
        ...
    js/
        ...
    index.php 
.htaccess

For various reasons (security, organization, etc.) the public application (website) is loaded and displayed by public/index.php At the "root" of my server I have the following .htaccess file:

<IfModule mod_rewrite.c>
    RewriteEngine On
    RewriteBase /BU/cs-602/developer-story/
    RewriteRule ^(\/||index\.*)$ public/index.php [L,QSA]
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteCond %{REQUEST_FILENAME} !-l
    RedirectMatch ^(/BU/cs-602/developer-story.)([\w\d\s\/\-\:\_%\ ]*\.css)$ $1public/$2 [L]
    RewriteRule ^([\w\d\-\_\/\ ]*)$ public/index.php?p=$1 [L,QSA]
</IfModule>

These rules should rewrite/ redirect all requests from the server "root" to public/index.php Since I am developing locally on my development server this project is not actually at the root of my server but is located at /BU/cs-602/developer-story/ This is why I added the RewriteBase rule.

If I remove the RedirectMatch rule everything from an MVC standpoint works:

URLs like http://localhost/BU/cs-602/developer-story or http://localhost/BU/cs-602/developer-story/ become http://localhost/BU/cs-602/developer-story/public/index.php AND URLs like http://localhost/BU/cs-602/developer-story/user/id become http://localhost/BU/cs-602/developer-story/public/index.php?p=user/id.

Here is a live htaccess test.

[ Question ]
How can I fix the .htaccess file or the RedirectMatch rule to redirect request to resources like CSS or JS files? The current rule works in the tester but not on my server unless I remove the RedirectMatch rule.

I would like a URL like http://localhost/BU/cs-602/developer-story/css/main.css to become http://localhost/BU/cs-602/developer-story/public/css/main.css that way in my HTML I do something like:

<img src="images/logo.png">

The server actually loads:

<img src="public/images/logo.png">

This way I do not have to prefix all my resources with public/.

[ Disclosure ]
This question is for help with a final project at my University, but this type question is allowed and not violating academic policies. Making a project with htaccess and MVC is not a requirement, just something I'm doing to challenge myself.

UPDATE:
Here is my original RedirectMacth rule. Anything that is not a PHP or HTML file is redirected:

RedirectMatch ([\w\d\s\/\-\:\_%\ ]*\.(?!php|htm|html)) $1 [L]

CodePudding user response:

I found the solution after reviewing the error logs on my server. My various attempts were causing redirect loops. Here is my working .htaccess file in case it helps anyone trying to do something similar.

The key is to short circuit the .htaccess file when necessary so it doesn't keep rewriting your URLs infinitely. I added inline comments to explain the process:

# Redirect all requests to the public directory.
<IfModule mod_rewrite.c>
    RewriteEngine On
    # Only needing for local develoment in my case.
    RewriteBase /BU/cs-602/developer-story/
    # If nothing or an index page is requested go to `public/index.php` and stop processing.
    RewriteRule ^(\/||.*index\..*)$ public/index.php [L,QSA]
    # If the URL already contains the `public/` directory go to URL and stop processing.
    RewriteRule ^(.*public\/.*)$ $1 [L,QSA]
    # If it appears this URL is for a resource (JS, CSS, etc.) prefix with `public/`.
    RewriteCond %{REQUEST_URI} ^([\w\d\s\-\_\/\%]*)\.(?!php|htm|html).*$
    # Go to the modified URL if the last rule triggered and stop processing.
    RewriteRule ^(.*)$ public/$1 [L,QSA]
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteCond %{REQUEST_FILENAME} !-l
    # Rewrite all remaing URLs to our apps MVC structure.
    RewriteRule ^([\w\d\s\-\_\/\%]*)$ public/index.php?p=$1 [L,QSA]
</IfModule>
  • Related