RewriteCond file exists - regex

Such a simple problem but htaccess and I have never got along.
Serve the file if it exists.
If the URI is just / and if index.html exists then serve index.html
Otherwise serve app.php
Here is .htaccess:
# Disable the directory processing, Apache 2.4
DirectoryIndex disabled xxx
RewriteEngine On
# Serve existing files
RewriteCond %{REQUEST_FILENAME} -f
RewriteRule .? - [L]
# For / serve index.html if it exists
RewriteCond %{REQUEST_URI} ^/$
RewriteCond index.html -f
RewriteRule .? index.html [L]
# Otherwise use front controller
RewriteRule .? app.php [L]
It works if I comment out the RewriteCond index.html -f line as long as index.html does in fact exists. But I also want to check for index.php so I need the file exists check. And if nothing else I'd like to understand why the posted lines do not work.

This should work:
# Disable the directory processing, Apache 2.4
DirectoryIndex disabled xxx
RewriteEngine On
# Serve existing files
RewriteCond %{REQUEST_FILENAME} -f
RewriteRule ^ - [L]
# For / serve index.html if it exists
RewriteCond %{DOCUMENT_ROOT}/index.html -f [NC]
RewriteRule ^/?$ index.html [L]
# Otherwise use front controller
RewriteRule ^ app.php [L]
Remember that RewriteCond with -f or -d needs full path to the file or directory that's why you need to prefix the filename with %{DOCUMENT_ROOT}/. No need to escape dots here.

Related

.htaccess how to remove file extensions and index files

I'm trying to achieve a few things through .htaccess ,but keep running into issues. Before you tell me I need to research better and there's already a solution on this or a different forum, please know I've already done that. I always try and figure out things on my own before coming here, but this one is truly stumping me. Everything I've tried has only partially worked. Any help or education here would be truly appreciated.
My site has the following simple structure:
(root)
| index.html
| .htaccess
|
|___portal-folder
| index.php
| home.php
|
|_____admin-folder
| index.php
I'm looking to achieve the following:
When a user navigates to any base directory, for instance site.com or site.com/portal-folder/ they don't see the index file name index.html or index.php in their browser.
Same holds true if the user navigates to the full URL site.com/index.html or site.com/portal-folder/index.php I would like the user to see site.com or site.com/portal-folder/ respectively in their browser.
Strip the file extension off all files in the browser. So for instance navigating to site.com/portal-folder/home.php would show as site.com/portal-folder/home in the browser
The following code I'm using kind of works, but I'm getting strange behavior. For instance:
navigating to site.com/portal-folder/index doesn't remove the index file name and show up as site.com/portal-folder/index instead of site.com/portal-folder/ in the browser
navigating to site.com/portal-folder/ doesn't remove the index file name and shows up as site.com/portal-folder/index.php in the browser.
navigating to site.com/portal-folder/index.php takes the user back to the root site.com
navigating to site.com/portal-folder/home works correctly, but navigating to site.com/portal-folder/home.php doesn't strip the .php extension off.
navigating to site.com works correctly, but navigating to site.com/index.html doesn't remove the index file name.
RewriteEngine On
DirectoryIndex index.html index.php
# remove trailing slash
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{THE_REQUEST} \s(.+?)/+[?\s]
RewriteRule ^(.+?)/$ /$1 [R=301,L]
# To internally forward /dir/file to /dir/file.php
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{DOCUMENT_ROOT}/$1.php -f
RewriteRule ^(.+?)/?$ /$1.php [L]
Server Information: Apache Version 2.4.46
Have it this way:
DirectoryIndex index.html index.php
RewriteEngine On
# To externally redirect /dir/file.php to /dir/file and optionally remove index
RewriteCond %{THE_REQUEST} \s/+(.*?/)?(?:index|(\S+?))(?:\.php|\.html)?[/\s?] [NC]
RewriteRule ^ /%1%2 [R=301,L,NE]
# remove trailing slash
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} ^(.+)/+$
RewriteRule ^ %1 [R=301,NE,L]
# To internally forward /dir/file to /dir/file.php
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{DOCUMENT_ROOT}/$1.php -f
RewriteRule ^(.+?)/?$ $1.php [L]

.htaccess ignore directory but include subdirectory with the same name

I have a directory called 'success-centers' (i dont want to go here)
I have a subdirectory called 'portal-pages/success-centers'
How do I ignore the first one but have my URL be:
local.com/success-centers/ OR local.com/success-centers/index.html through .htaccess?
this is my current htaccess file in the ROOT. it works fine but when I go to local.com/success-centers/ it goes to the directory that I do NOT want to go to.
Any help would be great. thanks.
RewriteEngine On
# add a trailing slash if portal-pages/$1 is a directory
RewriteCond %{DOCUMENT_ROOT}/portal-pages/$1 -d
RewriteRule ^(.*[^/])$ %{REQUEST_URI}/ [L,R=301,NE]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(?!portal-pages/)(.*)$ portal-pages/$1 [L,NC]
Have it like this:
RewriteEngine On
# add a trailing slash if portal-pages/$1 is a directory
RewriteCond %{DOCUMENT_ROOT}/portal-pages/$1 -d
RewriteRule ^(.*[^/])$ %{REQUEST_URI}/ [L,R=301,NE]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(?!portal-pages/)(.*)$ portal-pages/$1 [L,NC]
There is no need to check for -f or -d as you want portal-pages/success-centers/ when URI in browser is /success-centers/.
If I've understood your question correctly and you want the browser to point to a different page, but you don't want the URL of that different page to show up in the URL bar, you will need something along the lines of:
RewriteEngine On
RewriteRule ^success-centers(.*) /portal-pages/success-centers$1 [L]

.htaccess Rewrite Engine, folder-structure,

Havin following folder-structure
http://somesite.somename.com/
...
public
...
.htaccess
index.php
...
...
And .htaccess structure as following
RewriteEngine On
# The following rule tells Apache that if the requested filename
# exists, simply serve it.
RewriteCond %{REQUEST_FILENAME} -s [OR]
RewriteCond %{REQUEST_FILENAME} -l [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^.*$ - [NC,L]
# The following rewrites all other queries to index.php. The
# condition ensures that if you are using Apache aliases to do
# mass virtual hosting, the base path will be prepended to
# allow proper resolution of the index.php file; it will work
# in non-aliased environments as well, providing a safe, one-size
# fits all solution.
RewriteCond %{REQUEST_URI}::$1 ^(/.+)(.+)::\2$
RewriteRule ^(.*) - [E=BASE:%1]
RewriteRule ^(.*)$ %{ENV:BASE}index.php [NC,L]
Problem when accessing http://somesite.somename.com/ it shows folder structure to make it work i need to access http://somesite.somename.com/public
Question How to make http://somesite.somename.com/public be accessed as http://somesite.somename.com/?
You need to have .htaccess at root level (a level above public) to forward all traffic to public:
RewriteEngine On
RewriteBase /
RewriteRule ^(.*)$ public/$1 [L]
No change is needed in /public/.htaccess

.htaccess file blocks css, js but how?

I have a .htaccess file inside an existing project folder. The code for the .htaccess file is below.
# Use PHP54 Single php.ini as default
#Options +FollowSymLinks
#Options +Indexes
RewriteEngine On
RewriteBase /
#RewriteRule ^users/([A-Za-z0-9_]+)$ users/index.php [NC,L]
#RewriteRule ^([A-Za-z0-9_]+)$ users/$1 [NC,L]
#RewriteRule ^ - [L]
#RewriteCond %{DOCUMENT_ROOT}/users/$1 -f
#RewriteRule .* users/$1 [L]
#Options -Indexes
#RewriteEngine On
#RewriteRule ^[!/.]*([A-Za-z0-9]+)/?$ /index.php?id=$1 [NC,L]
#<FilesMatch "\.(?i:vcf)$">
# ForceType application/octet-stream
# Header set Content-Disposition attachment
#</FilesMatch>
# If requested resource exists as a file or directory, skip next two rules
RewriteCond %{DOCUMENT_ROOT}/$1 -f [OR]
RewriteCond %{DOCUMENT_ROOT}/$1 -d
RewriteRule (.*) - [S=2]
#
# Requested resource does not exist, do rewrite if it exists in /users
RewriteCond %{DOCUMENT_ROOT}/users/$1 -f [OR]
RewriteCond %{DOCUMENT_ROOT}/users/$1 -d
RewriteRule (.*) users/$1 [L]
#
# Else rewrite requests for non-existent resources to /index.php
RewriteRule (.*) users/index.php?q=$1 [L]
So what happens it, when I try to open the project in url at localhost
http://localhost/projectfolder
it opens the index file without any javascript and css. Also the links to other pages do not open and the error message shows as -"Object not found". So I can only view index.php with out css and js files.
But when I remove / rename the .htaccess file, all works fine. So there must be something in this file which blocks all css, js files. So I am not asking for all the rules of writing a .htaccess file, I just need to know which line of code is blocking the files and how can I edit them, so it will not block any file wile working in localhost.
Note:- This question I am asking only for my knowledge. As I have written, if I remove the file then its working fine. But still I want to know which line of code is blocking the access to files. Thanks.
I suspect this rule is not doing what you think it should be doing:
RewriteCond %{DOCUMENT_ROOT}/$1 -f [OR]
RewriteCond %{DOCUMENT_ROOT}/$1 -d
RewriteRule (.*) - [S=2]
Replace this with:
RewriteCond %{REQUEST_FILENAME} -d [OR]
RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -l
RewriteRule ^ - [L]
Also you might be using relative links for css/js/images which will also cause 404 after rewriting to /users/. You have 2 options to fix that:
use absolute path in your css, js, images files rather than a relative one. Which means you have to make sure path of these files start either with http:// or a slash /.
You can try adding this in your page's HTML header:
<base href="/" />

.htaccess redirection of index.php

The below illustrates the .htaccess code for a generating SEF url when joomla SEF is on in the backend.
## Begin - Joomla! core SEF Section.
#
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
#
# If the requested path and file is not /index.php and the request
# has not already been internally rewritten to the index.php script
RewriteCond %{REQUEST_URI} !^/index\.php
# and the request is for something within the component folder,
# or for the site root, or for an extensionless URL, or the
# requested URL ends with one of the listed extensions
RewriteCond %{REQUEST_URI} /component/|(/[^.]*|\.(php|html?|feed|pdf|vcf|raw))$ [NC]
# and the requested path and file doesn't directly match a physical file
RewriteCond %{REQUEST_FILENAME} !-f
# and the requested path and file doesn't directly match a physical folder
RewriteCond %{REQUEST_FILENAME} !-d
# internally rewrite the request to the index.php script
RewriteRule .* index.php [L]
I have a simple problem which I'm not able to get my head around into.
I put this condition so that if the url is domain.com/index.php then it should go to domain.com and this should happen only if the pattern matches exactly as index.php.
However this happens for all urls.
RewriteCond %{THE_REQUEST} [^.]*|/(index.php)$
RewriteRule ^index.php$ / [R=301,L]
it should go to domain.com and this should happen only if the pattern matches exactly as index.php. However this happens for all urls.
It is due to the wrong regex you're using. Use this rule to remove index.php from URIs:
RewriteCond %{REQUEST_URI} !/administrator [NC]
RewriteCond %{THE_REQUEST} /index\.php [NC]
RewriteRule ^(.*?)index\.php$ /$1 [L,R=302,NC,NE]