In .htaccess to prioritize DirectoryIndex to a RewriteRule - apache

I want files to be accessed when they are available as specified in the DirectoryIndex line. E.g. when someone types in www.mywebsite.com/mydir/ it will redirect correctly. For this I have in my .htaccess the line:
DirectoryIndex index.html default.php
When a filename or directory does not exist I want it to redirect to a file (target_handler.php) which is located in the same directory as my .htaccess file. For this I have placed several lines after the DirectoryIndex:
RewriteEngine On
RewriteCond %{ENV:URI} ^$
RewriteRule ^(.*)$ - [ENV=URI:$1]
RewriteCond %{ENV:BASE} ^$
RewriteCond %{ENV:URI}::%{REQUEST_URI} ^(.*)::(.*?)\1$
RewriteRule ^ - [ENV=BASE:%2]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ %{ENV:BASE}target_handler.php [L,QSA]
What I want is for Apache to first check to see if there is an index.html or default.php available, and only upon unavailability perform a rewrite. Currently the behaviour seems random(?), so if someone types www.mywebsite.com/mydir/ then Apache sometimes does the rewrite first without checking if there is an index.html in the specified folder.
Help appreciated
PS: I am testing using: xampp
Apache/2.4.17 (Win32) OpenSSL/1.0.2d PHP/5.6.15

You can omit DirectoryIndex and do it all using mod_rewrite itself:
RewriteEngine On
RewriteCond %{REQUEST_URI}::$1 ^(.*?/)(.*)::\2$
RewriteRule ^(.*)$ - [E=BASE:%1]
RewriteCond %{DOCUMENT_ROOT}%{ENV:BASE}index\.html -f
RewriteRule ^ index.html [L]
RewriteCond %{DOCUMENT_ROOT}%{ENV:BASE}default\.php -f
RewriteRule ^ default.php [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule !^target_handler\.php$ target_handler.php [L,NC]

Related

DirectorySlash Off Configuration

The site is html, I have 3 .html files that have 3 directories with the same name. BTW its apache2 on ubuntu 18
So......
file1.html
/file1
file2.html
/file2 an so on.
No problem if you don't turn off file extensions in your .htaccess file. But when doing that the directory is served up and you get a error. So here is my .htaccess config trying to use DirectorySlash Off. There is some other stuff going on in this file but I thought I'd leave it all in in case there are related cause/effect things going on here.
# BEGIN
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
Options +MultiViews
DirectorySlash Off
# Rewrite to file when file and directory both exist with the same name
RewriteCond %{DOCUMENT_ROOT}/$1.html -f
RewriteRule ^([^.]+)$ $1.html [L]
# Allows files to be loaded without extensions
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}\.html -f
RewriteRule ^(.*)$ $1.html [NC,L]
# Removes the file extensions
RewriteCond %{THE_REQUEST} /([^.]+)\.html [NC]
RewriteRule ^ /%1 [NC,L,R]
RewriteCond %{REQUEST_FILENAME}.html -f
RewriteRule ^ %{REQUEST_URI}.html [NC,L]
Redirects from products to product directory
RewriteRule ^products/(.*)$ /product/$1 [R=301,NC,L]
</IfModule>
# END
You could be able to give a priority to file when it request comes without / with same name with directory as well as removing file extension , html , like this :
DirectorySlash Off
RewriteEngine on
RewriteCond %{THE_REQUEST} \s/+(.*?/)?(?:index)?(.*?)\.(html)[\s?/] [NC]
RewriteRule ^ /%1%2 [R=302,L,NE]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME}\.html -f
RewriteRule ^(.*) /$1.html [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_URI} !\/$
RewriteRule ^(.*) %{REQUEST_URI}/ [L,R=302]
Then add your rest rules:
RewriteRule ^products/(.*)$ /product/$1 [R=301,NC,L]
So , by the code above , HTML extension will be removed then server will check first if there is an HTML file match this request then,if there is a directory match this request .
Clear browser cache then test it , if it is Ok , change 302 to 301 to get permanent redirection
For more info , you can also refer to my previous answer :
Remove .php and .html extensions AND have directories with same name?

Hide folder in path using .htaccess file

I'm looking to hide the folder called contents in the URL path http://example.com/contents/folder-1/
My folder structure looks like:
/
--contents/
----folder-1/
------index.php
----folder-2/
------index.php
----folder-3/
------index.php
index.php
I have full root access to the server, enabled a2enmod rewrite, restarted apache. I then put the following .htaccess file in the / directory.
Options +FollowSymLinks -MultiViews
# Turn mod_rewrite on
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteCond %{REQUEST_URI} !/$
RewriteRule (.*) $1\.php [L]
RewriteCond %{THE_REQUEST} ^[A-Z]{3,}\s/+contents/([^\s]+) [NC]
RewriteRule ^ %1 [R=301,L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule (?!^contents/)^(.*)$ /contents/$1 [L,NC]
However, when I go to http://example.com/folder-1/ it just gives me a 404 page error.

All subdirectories to use root index.php file

My existing .htaccess file looks like this:
Options -Indexes
RewriteEngine On
RewriteBase /
RewriteRule ^(.+/)?posts/(.*)/(.*).html$ index.php?content=blog&postid=$2&kwd=$3
RewriteRule ^(.+/)?aposts/(.*)/(.*).html$ index.php?content=autopost&postid=$2&kwd=$3
RewriteRule ^(.+/)?category/(.*)/(.*).html$ index.php?content=category&cat=$2&otext=$3
RewriteRule ^(.+/)?content/(.*).html$ index.php?content=$2
RewriteRule ^(.+/)?searching/(.*).html$ index.php?content=search&k=$2
RewriteRule ^(.+/)?related/(.*).html$ index.php?content=related&k=$2
RewriteRule ^(.+/)?blog/(.*)/(.*).html$ index.php?content=blog&postid=$2&kwd=$3
RewriteRule ^(.+/)?posts$ index.php?content=blog
RewriteRule ^(.+/)?sitemap\.xml$ sitemap.php [L]
RewriteRule ^(.+/)?robots\.txt$ robots.php [L]
ErrorDocument 404 /404.php
I would like to add the ability for all subdirectories to use the root index.php file. For example, if a visitor goes to the root directory:
example.com
They get served the root index.php file.
I want it so that if anybody goes to any other subdirectories eg:
example.com/sub1
example.com/sub1/sub2/sub3/etc..
They get served the index.php file from the root directory BUT the browser address bar still shows the subdirectories, eg:
example.com/sub1
example.com/sub1/sub2/sub3/etc..
Being shown how to add exceptions to this rule would be great too.
Thanks for any help.
Right under RewriteBase / add:
RewriteCond %{REQUEST_FILENAME} -d
RewriteCond $1 !^index\.php
RewriteRule ^(.+)$ /index.php [L]
To add exceptions, just add more RewriteCond lines. For example, to make it so /foo/ doesn't get routed to index.php, add:
RewriteCond %{REQUEST_FILENAME} -d
RewriteCond $1 !^foo/
RewriteCond $1 !^index\.php
RewriteRule ^(.+)$ /index.php [L]

htaccess RewriteRule issues - something wrong with my syntax?

I want my sites to redirect following this protocol :
/weddings/ >> ?q=weddings
/editorial/one/ >> ?q=editorial&z=one
so I made the following rewrite rule :
RewriteEngine on
RewriteRule ^([^/.]+)/$? /?z=$1&q=$2 [nocase]
which when implemented totally screwed everything up.
what simple thing am i doing wrong!?
my current .htaccess
DirectoryIndex index.html.var index.htm index.html index.shtml index.xhtml index.wml index.perl index.pl index.plx index.ppl index.cgi index.jsp index.js index.jp index.php4 index.php3 index.php index.phtml default.htm default.html home.htm index.php5 Default.html Default.htm home.html
RewriteEngine on
RewriteCond %{HTTP_HOST} ^elijahhoffman\.com$ [OR]
RewriteCond %{HTTP_HOST} ^www\.elijahhoffman\.com$
RewriteRule ^journal$ "http\:\/\/elijahj\.tumblr\.com\/" [R=301,L]
RewriteCond %{HTTP_HOST} ^elijahhoffman\.com$ [OR]
RewriteCond %{HTTP_HOST} ^www\.elijahhoffman\.com$
RewriteRule ^blog\/?$ "http\:\/\/elijahj\.tumblr\.com\/" [R=301,L]
To prevent a rewrite loop, you'll need to guard against real files or directories (such as your index) being rewritten. Append a [L] flag to stop on the first match.
RewriteEngine On
# First do your journal/blog rewrites
# Only need one condition to match both domains
RewriteCond %{HTTP_HOST} ^(www\.)?elijahhoffman\.com$
# Combine these into one rule (dots & slashes don't need escaping on the rewrite side)
RewriteRule ^(journal|blog)/?$ http://elijahj.tumblr.com/ [R=301,L]
# Then the generic one...
# If it isn't a real file or directory...
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
# Rewrite those with only one component up to /
RewriteRule ^([^/.]+)/?$ index.php?q=$1 [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
# Rewrite those with 2 components
RewriteRule ^([^/]+)/([^./]+)/?$ index.php?q=$1&z=$2 [L]

htaccess remove index.php from url

I have a problem whereby google has indexed some pages with the wrong url.
The url they are indexing is:
http://www.example.com/index.php/section1/section2
I need it to redirect to:
http://www.example.com/section1/section2
.htaccess isn't my forte, so any help would be much appreciated.
The original answer is actually correct, but lacks explanation. I would like to add some explanations and modifications.
I suggest reading this short introduction https://httpd.apache.org/docs/2.4/rewrite/intro.html (15mins) and reference these 2 pages while reading.
https://httpd.apache.org/docs/2.4/mod/mod_rewrite.html
https://httpd.apache.org/docs/2.4/rewrite/flags.html
This is the basic rule to hide index.php from the URL. Put this in your root .htaccess file.
mod_rewrite must be enabled with PHP and this will work for the PHP version higher than 5.2.6.
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule (.*) /index.php/$1 [L]
Think %{REQUEST_FILENAME} as the the path after host.
E.g. https://www.example.com/index.html, %{REQUEST_FILENAME} is /index.html
So the last 3 lines means, if it's not a regular file !-f and not a directory !-d, then do the RewriteRule.
As for RewriteRule formats:
So RewriteRule (.*) /index.php/$1 [L] means, if the 2 RewriteCond are satisfied, it (.*) would match everything after the hostname. . matches any single character , .* matches any characters and (.*) makes this a variables can be references with $1, then replace with /index.php/$1. The final effect is to add a preceding index.php to the whole URL path.
E.g. for https://www.example.com/hello, it would produce, https://www.example.com/index.php/hello internally.
Another key problem is that this indeed solve the question. Internally, (I guess) it always need https://www.example.com/index.php/hello, but with rewriting, you could visit the site without index.php, apache adds that for you internally.
Btw, making an extra .htaccess file is not very recommended by the Apache doc.
Rewriting is typically configured in the main server configuration
setting (outside any <Directory> section) or inside <VirtualHost>
containers. This is the easiest way to do rewriting and is recommended
To remove index.php from the URL, and to redirect the visitor to the non-index.php version of the page:
RewriteCond %{THE_REQUEST} ^GET.*index\.php [NC]
RewriteRule (.*?)index\.php/*(.*) /$1$2 [R=301,NE,L]
This will cleanly redirect /index.php/myblog to simply /myblog.
Using a 301 redirect will preserve Google search engine rankings.
RewriteEngine On
RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /(.*)index\.php($|\ |\?)
RewriteRule ^ /%1 [R=301,L]
Assuming the existent url is
http://example.com/index.php/foo/bar
and we want to convert it into
http://example.com/foo/bar
You can use the following rule :
RewriteEngine on
#1) redirect the client from "/index.php/foo/bar" to "/foo/bar"
RewriteCond %{THE_REQUEST} /index\.php/(.+)\sHTTP [NC]
RewriteRule ^ /%1 [NE,L,R]
#2)internally map "/foo/bar" to "/index.php/foo/bar"
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.+)$ /index.php/$1 [L]
In the spep #1 we first match against the request string and capture everything after the /index.php/ and the captured value is saved in %1 var. We then send the browser to a new url.
The #2 processes the request internally. When the browser arrives at /foo/bar , #2rule rewrites the new url to the orignal location.
Steps to remove index.php from url for your wordpress website.
Check you should have mod_rewrite enabled at your server.
To check whether it's enabled or not - Create 1 file phpinfo.php at your root folder with below command.
<?php
phpinfo?();
?>
Now run this file - www.yoursite.com/phpinfo.php and it will show mod_rewrite at Load modules section.
If not enabled then perform below commands at your terminal.
sudo a2enmod rewrite
sudo service apache2 restart
Make sure your .htaccess is existing in your WordPress root folder, if not create one .htaccess file
Paste this code at your .htaccess file :-
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>
Further make permission of .htaccess to 666 so that it become writable and now you can do changes in your wordpress permalinks.
Now go to Settings -> permalinks -> and change to your needed url format.
Remove this code /index.php/%year%/%monthnum%/%day%/%postname%/
and insert this code on Custom Structure: /%postname%/
If still not succeeded then check your hosting, mine was digitalocean server, so I cleared it myself
Edited the file /etc/apache2/sites-enabled/000-default.conf
Added this line after DocumentRoot /var/www/html
<Directory /var/www/html>
AllowOverride All
</Directory>
Restart your apache server
Note: /var/www/html will be your document root
Do the following steps
1. Make sure that the hosting / your pc mod_rewrite module is active. if not active then try to activate in a way, open the httpd.conf file. You can check this in the phpinfo.php to find out.
change this setting :
#LoadModule rewrite_module modules/mod_rewrite.so
to be and restart wamp
LoadModule rewrite_module modules/mod_rewrite.so
2. Then go to .htaccess file, and try to modify to be:
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)\?*$ index.php/$1 [L,QSA]
if above does not work try with this:
RewriteEngine on
# if a directory or a file exists, use it directly
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
# otherwise forward it to index.php
RewriteRule . index.php
3. Move .htaccess file to root directory, where is index.php there.
www OR root folder
- index.php
- .htaccess
Some may get a 403 with the method listed above using mod_rewrite. Another solution to rewite index.php out is as follows:
<IfModule mod_rewrite.c>
RewriteEngine On
# Put your installation directory here:
RewriteBase /
# Do not enable rewriting for files or directories that exist
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /index.php/$1 [L]
</IfModule>
I have used many codes from the above mentioned sections for removing index.php form the base url. But it was not working from my end. So, you can use this code which I have used and its working properly.
If you really need to remove index.php from the base URL then just put this code in your htaccess.
RewriteCond %{THE_REQUEST} ^GET.*index\.php [NC]
RewriteRule (.*?)index\.php/*(.*) /$1$2 [R=301,NE,L]
This will work, use the following code in .htaccess file
RewriteEngine On
# Send would-be 404 requests to Craft
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} !^/(favicon\.ico|apple-touch-icon.*\.png)$ [NC]
RewriteRule (.+) index.php?p=$1 [QSA,L]
I don't have to many bulky code to give out just a little snippet solved the issue for me.
i have https://example.com/entitlements/index.php rather i want anyone that types it to get error on request event if you type https://example.com/entitlements/index
you will still get error since there's this word "index" is contained there will always be an error thrown back though the content of index.php will still be displayed properly
cletus post on "https://stackoverflow.com/a/1055655/12192635" which
solved it
Edit your .htaccess file with the below
to redirect people visiting https://example.com/entitlements/index.php to 404 page
RewriteCond %{THE_REQUEST} \.php[\ /?].*HTTP/
RewriteRule ^.*$ - [R=404,L]
to redirect people visiting https://example.com/entitlements/index to 404 page
RewriteCond %{THE_REQUEST} \index[\ /?].*HTTP/
RewriteRule ^.*$ - [R=404,L]
Not withstanding we have already known that the above code works with already existing codes on stack see where i applied the code above just below the all codes at it end.
# The following will allow you to use URLs such as the following:
#
# example.com/anything
# example.com/anything/
#
# Which will actually serve files such as the following:
#
# example.com/anything.html
# example.com/anything.php
#
# But *only if they exist*, otherwise it will report the usual 404 error.
Options +FollowSymLinks
RewriteEngine On
# Remove trailing slashes.
# e.g. example.com/foo/ will redirect to example.com/foo
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.+)/$ /$1 [R=permanent,QSA]
# Redirect to HTML if it exists.
# e.g. example.com/foo will display the contents of example.com/foo.html
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}.html -f
RewriteRule ^(.+)$ $1.html [L,QSA]
# Redirect to PHP if it exists.
# e.g. example.com/foo will display the contents of example.com/foo.php
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteRule ^(.+)$ $1.php [L,QSA]
RewriteCond %{THE_REQUEST} \.php[\ /?].*HTTP/
RewriteRule ^.*$ - [R=404,L]
RewriteCond %{THE_REQUEST} \index[\ /?].*HTTP/
RewriteRule ^.*$ - [R=404,L]
try this, it work for me
<IfModule mod_rewrite.c>
# Enable Rewrite Engine
# ------------------------------
RewriteEngine On
RewriteBase /
# Redirect index.php Requests
# ------------------------------
RewriteCond %{THE_REQUEST} ^GET.*index\.php [NC]
RewriteCond %{THE_REQUEST} !/system/.*
RewriteRule (.*?)index\.php/*(.*) /$1$2 [R=301,L]
# Standard ExpressionEngine Rewrite
# ------------------------------
RewriteCond $1 !\.(css|js|gif|jpe?g|png) [NC]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /index.php/$1 [L]
</IfModule>
For more detail
create .htaccess file on project root directory and put below code for remove index.php
RewriteEngine on
RewriteCond $1 !^(index.php|resources|robots.txt)
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php/$1 [L,QSA]