mod_rewrite check public folder before passing to php - apache

What I am trying to achieve (with mod_rewrite) is on request check if a file/directory exists in the public folder, if it does, serve it, if not, route the request to the index.php file. Also if no extension provided in the URL then default to .html.
Below is my folder structure:
/.htaccess
/index.php
/public
/test.html
/test.xml
/a_folder
/index.html
/test.html
So for example here are a few requests and responses:
example.com/test.xml >>> /public/test.xml
example.com/a_folder/ >>> /public/a_folder/index.html
example.com/a_folder/test >>> /public/a_folder/test.html
example.com/not_in_public >>> /index.php
Any pointers on this would be amazing, thanks in advance.

Something like this: (Heavily cribbed from my WordPress .htaccess file)
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)^(\.\w+) $1.html [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>
The $1.html line is off the top of my head and may need some tweaking. Note that this is a dumb check that the requested URL ends in a dot followed by one or more word characters.

<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^(|index\.php)$ - [L]
RewriteRule ^public/(.*)$ - [L]
RewriteRule ^(.*)$ public/$1
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . index.php [R]
</IfModule>
This should do the trick.
Basically, if it's / or /index.php it won't do anything, if it's /public/whateveryouwant it won't do anything, if it's anything else it will rewrite to /public/whateveryouwant and check if it's either a file or a directory. If it's not it will redirect to index.php.

Thanks to #jxpx777 and #N1xx1 after a bit of juggling made it work.
Options -Indexes
RewriteEngine On
RewriteBase /
RewriteRule ^public/(.*)$ - [L]
# Check public cache
RewriteRule ^(.*)$ public/$1
RewriteRule (.*)/$ $1/index
# Add .html if not extension provided
RewriteCond %{REQUEST_URI} !\..*$
RewriteRule ^(.*)$ $1.html
# Push through stack in not in cache
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . index.php [L]

Related

Non-www RewriteRule not working on request URI

I need a website to have all URLs NOT have www in front of it. For this, I have found some useful bits of code here that have helped me out a lot. However, nowhere can I find how to properly do it for ALL request URIs. Currently it only works on the domains homepage.
# BEGIN WordPress
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
RewriteCond %{HTTP_HOST} ^www\.domain\.nl [NC]
RewriteRule ^(.*)$ https://domain.nl%{REQUEST_URI} [L,R=301]
</IfModule>
# END WordPress
Right now www.domain.nl gets rewritten into domain.nl. However, any other like www.domain.nl/anything_else do not get rewritten (also tried adding a / before the %{REQUEST_URI}, did not work).
Any help is appreciated!
With www rule before:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteCond %{HTTP_HOST} ^www\.domain\.nl [NC]
RewriteRule ^ https://domain.nl%{REQUEST_URI} [NE,L,R=301]
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>

strange redirect with url rewrite

My .htaccess file is:
RewriteEngine on
RewriteRule (.*) index.php?_url=$1 [QSA,L]
It works perfectly in most cases. But if the requested url exists as a real folder, it goes crazy.
For example when i request /random it is rewritten to index.php?_url=random with status code 200, but for /static (which is an existing directory on the web server) it gives a 301 redirect to /static/?_url=static
use this below code for .htaccess
<IfModule mod_rewrite.c>
Options -MultiViews
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.+)/$ http://%{HTTP_HOST}/$1 [R=301,L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.php [L]
</IfModule>
If you want to exclude existing files and directories from being rewritten, do so with a RewriteCond
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /index.php?_url=$1 [QSA,L]

wordpress: mod_rewrite first "folder" name as a get parameter

I set the wordpress permalink-structure to just use the articlename and got a .htaccess that looks like this
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>
works fine.
but I want to distinguish between different locations (i.e. berlin, hamburg or muenchen) in my various template files. so I thought I'd add the location to the URL like this:
http://myurl.com/berlin/articlename
and now I need to rewrite this to
http://myurl.com/articlename?location=berlin
but
http://myurl.com/articlename
or
http://myurl.com/category/articlename
should still work. just look for predefined locations (berlin|hamburg|muenchen).
how do I need to adjust the RewriteRule above to accomplish this?
So basically if what you're asking for is that http://myurl.com/(word1)/(word2)/ (i.e. only matches exactly two words, no less no more) gets internally rewritten on the server side to http://myurl.com/(word2)?location=(word1) then here it is:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule /([^/]+)/([^/]+)/$ /$2?location=$1 [QSA,L]
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>
i fixed this with the following additions to the .htaccess file:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteCond %{QUERY_STRING} !location
RewriteRule ^(muenchen|berlin)/$ /index.php?location=$1 [NC,QSA,P]
RewriteCond %{QUERY_STRING} !location
RewriteRule ^(muenchen|berlin)/(.*)$ /$2?location=$1 [NC,QSA,P]
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>

SocialEngine - Redirects in .htaccess

I've completed a fresh install of SocialEngine PHP in my private server.
I also need now to install Moodle, and access in the following way to it:
http://www.example.com/moodle
SocialEngine creates its own .htaccess file, so every time I try to access the moodle directory, I got a "Page Not Found. The page you have attempted to access could not be found." because the redirection forces it to search moodle inside SocialEngine plugins, and I want it to redirect to a /moodle/ directory inside /httpdocs.
I am very noob with .htaccess options, I need a hint about what can I do.
The .htaccess content is the following:
<IfModule mod_rewrite.c>
Options +FollowSymLinks
RewriteEngine On
# Get rid of index.php
RewriteCond %{REQUEST_URI} /index\.php
RewriteRule (.*) index.php?rewrite=2 [L,QSA]
# Rewrite all directory-looking urls
RewriteCond %{REQUEST_URI} /$
RewriteRule (.*) index.php?rewrite=1 [L,QSA]
# Try to route missing files
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} public\/ [OR]
RewriteCond %{REQUEST_FILENAME} \.(jpg|gif|png|ico|flv|htm|html|php|css|js)$
RewriteRule . - [L]
# If the file doesn't exist, rewrite to index
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php?rewrite=1 [L,QSA]
</IfModule>
# sends requests /index.php/path/to/module/ to "index.php"
# AcceptPathInfo On
# #todo This may not be effective in some cases
FileETag Size
Any suggestion or tip, please?
Thank you very much in advance!
Regards.
I would exclude the moodle-folder in every rewrite and check if it works. After it is working I would remove it in every rule where you don't really need it.
<IfModule mod_rewrite.c>
Options +FollowSymLinks
RewriteEngine On
# Get rid of index.php
RewriteCond %{REQUEST_URI} !^/moodle
RewriteCond %{REQUEST_URI} /index\.php
RewriteRule (.*) index.php?rewrite=2 [L,QSA]
# Rewrite all directory-looking urls
RewriteCond %{REQUEST_URI} !^/moodle
RewriteCond %{REQUEST_URI} /$
RewriteRule (.*) index.php?rewrite=1 [L,QSA]
# Try to route missing files
RewriteCond %{REQUEST_URI} !^/moodle
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} public\/ [OR]
RewriteCond %{REQUEST_FILENAME} \.(jpg|gif|png|ico|flv|htm|html|php|css|js)$
RewriteRule . - [L]
# If the file doesn't exist, rewrite to index
RewriteCond %{REQUEST_URI} !^/moodle
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php?rewrite=1 [L,QSA]
</IfModule>
# sends requests /index.php/path/to/module/ to "index.php"
# AcceptPathInfo On
# #todo This may not be effective in some cases
FileETag Size

Apache mod rewrite .htaccess problem

My site is a php based site, but I've added wordpress in a /blog/ folder. The .htaccess file below should allow the /blog/ folder to be accessed, but I get a 404 error saying that blog.php doesn't exist.
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{SCRIPT_FILENAME} !\.(gif|jpg|png)$
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)/(.*)/$ /$1_$2.php [L]
RewriteRule ^(.*)/$ /$1.php [L]
</IfModule>
Anybody able to help at all?
The last RewriteRule is redirecting your request to /blog/ to index.php, you should add a RewriteCond to check if the request is on the blog folder.
RewriteCond %{REQUEST_URI} !^/blog/.*
I managed this using the code below, for some reason the conditionals that were suggested don't work (I HATE .htaccess)
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteRule ^(blog) - [L]
RewriteCond %{SCRIPT_FILENAME} !\.(gif|jpg|png)$
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)/(.*)/$ /$1_$2.php [L]
RewriteRule ^(.*)/$ /$1.php [L]
</IfModule>
Adding
RewriteRule ^(blog) - [L]
to public_html/.htaccess after
RewriteEngine On
worked for me as well on a fresh Wordpress installation with Fantastico on a Hostgator account, with a blog.example.com subdomain.