mod_rewrite multiple RewriteCond conflict - apache

I have a Problem with mod-rewrite.
<IfModule mod_rewrite.c>
Options +FollowSymLinks
RewriteEngine On
RewriteCond %{HTTP_HOST} ^example\.com$ [NC]
RewriteRule ^(.*)$ http://www.example.com/$1 [R=permanent]
# For all files not found in the file system, reroute the request to the
# "index.php" front controller, keeping the query string intact
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^ index.php [L]
</IfModule>
# IE Cache fix?
ExpiresActive On
ExpiresDefault A1
Header append Cache-Control must-revalidate
Redirecting doesn't work and no Styles or Images are showing.
If those three lines are comment out, it works:
#RewriteCond %{REQUEST_FILENAME} !-f
#RewriteCond %{REQUEST_FILENAME} !-d
#RewriteRule ^ index.php [L]
But I need those to redirect any wrong entery to the root. How does this work together? Or why it doesen't work like this?

Try adding a L flag to your redirect. If you don't have one, the request will get flagged as a redirect and mod_rewrite will continue to run the rest of your rules. So this line needs an L:
RewriteRule ^(.*)$ http://www.example.com/$1 [R=permanent,L]
If you have relative URL issues with your images or styles, try adding this to the header of your pages:
<base href="/" />

Related

Permanent redirect removal of file extensions in URL

When a page is visited using a URL that ends with .html, I'd like the URL to change to having no extension and report 301 permanently redirected. I'm having serious difficulty. After reading a lot of documentation and tutorials, and searching Stack Overflow for hours, the closest I've achieved is the opposite (URLs with no extension having one added) with this code:
<Location />
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME}\.html -f
RewriteCond %{REQUEST_URI} !/$
RewriteCond %{REQUEST_URI} !\.html$
RewriteRule ^(.*)$ https://%{HTTP:Host}%{REQUEST_URI}.html [L,R=permanent]
</Location>
This can be done in two steps, with a REDIRECT_LOOP environment variable to prevent looping, with the directives in a Directory section for the web root (or .htaccess in the web root) so the matched string in the RewriteRule can be used for the permanent Redirect.
<Directory "/var/www/html">
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-d # if the request is not a directory
RewriteCond %{REQUEST_FILENAME} !-f # if the request is not a file
RewriteCond %{REQUEST_FILENAME}\.html -f # if adding .html it is a file
RewriteCond %{REQUEST_URI} !\.html$ # if the request doesn't end in .html
RewriteCond %{REQUEST_URI} !/$ # if the request doesn't end in /
RewriteRule ^(.*)$ $1.html [L,E=LOOP:1] # then return the request as if it ended with .html and set the loop variable
RewriteCond %{ENV:REDIRECT_LOOP} !1 # if we didn't just added .html
RewriteRule ^(.*)\.html$ https://%{HTTP:Host}/$1 [L,R=permanent] # then 301 redirect the request to the request without the .html
</Directory>
This will make it so that if you have example.html and example/index.html then example.html will never be loaded.

htaccess RewriteRule rewrite to subfolder

I am trying to rewrite the url 'test' to a subdirectory in /public. This is a Laravel App end I want to run the content in public/test independend of Laravel so I should be prevented to go through the Laravel router.
/test/whatever should be invisbly forwarded to /public/test/whatever (The url should stay /test/whatever).
I now have this:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{REQUEST_URI} ^/test/ [NC]
RewriteRule ^(.*)$ public/test/$1 [L]
RewriteRule ^(.*)$ public/$1 [L]
</IfModule>
So far this is forwarding to: /public/test/test/(index.php)
I think I am close...
Update:
In the public directory is also a .htaccess file (Original, from Laravel 5.4):
<IfModule mod_rewrite.c>
<IfModule mod_negotiation.c>
Options -MultiViews
</IfModule>
RewriteEngine On
# Redirect Trailing Slashes If Not A Folder...
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)/$ /$1 [L,R=301]
# Handle Front Controller...
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.php [L]
# Handle Authorization Header
RewriteCond %{HTTP:Authorization} .
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
</IfModule>
You only need the last rule
RewriteRule ^(.*)$ public/$1 [L]
for the root dir .htaccess file. This will rewrite everything to the public/.htaccess, including requests starting with /test.
As long as public/test/ is a directory, and any requested URLs starting with /test/ are real files inside public/test, this will be sufficient, because the conditions
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
will prevent existing files and directories to be handled by index.php.
If test is not an existing directory, or the requests for /test/... are not real files, you need additional rules. Possibly in /public/.htaccess or in /public/test/.htaccess.
The reason for /test being rewritten to /public/test/test was the combination of
# /.htaccess
RewriteRule ^(.*)$ public/test/$1 [L]
where (.*) already includes test, which becomes public/test/test, and then
# /public/.htaccess
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.php [L]
because public/test/test is not an existing file or directory (-> RewriteCond), and is therefore handled by this rule.

Remove or add trailing slash from CakePHP 2.x on Apache using .htaccess

I am trying to enforce the removal or add of trailing slashes to my CakePHP 2.x app using the following inside the .htaccess located at /app/webroot.
#<IfModule mod_rewrite.c>
# RewriteEngine On
# RewriteCond %{REQUEST_FILENAME} !-d
# RewriteCond %{REQUEST_FILENAME} !-f
# RewriteRule ^ index.php [L]
#</IfModule>
<IfModule mod_rewrite.c>
# Add trailing slash
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_URI} !(\.[a-zA-Z0-9]{1,5}|)$
RewriteRule ^(.*)$ http://www.domain.com/$1 [L,R=301]
</IfModule>
or the following for add the trailing slash.
RewriteCond %{REQUEST_URI} !(/$|\.)
RewriteRule (.*) %{REQUEST_URI}/ [R=301,L]
But I don't want to enforce the domain as it could be running locally or inside a subfolder. How do I fix this? All the docs I've read online seem to enforce the FULL url of the app.
In fact even if I use the FULL url it still doesn't work. Has anyone managed to get this working with CakePHP? Seems you MUST run it through the index.php file
To clarify I'm looking for a solution for ADDING and REMOVING trailing slashes in CakePHP without having to hardcode the url into the .htaccess file.
This is usually not a complicated thing.
What about this ?
<IfModule mod_rewrite.c>
RewriteEngine On
# if this is an existing folder/file then leave
RewriteCond %{REQUEST_FILENAME} -d [OR]
RewriteCond %{REQUEST_FILENAME} -f
RewriteRule . - [L]
# if trailing slash then redirect to url without trailing slash
RewriteRule ^/?(.+)/$ /$1 [R=301,L]
# internal rewrite to controller/dispatcher index.php
RewriteRule ^.*$ /index.php [L,QSA]
</IfModule>
If this one is not working, well this could be a problem on your side.
Did you already use mod_rewrite before ? Is it enabled ?
EDIT: if your website is not in root folder (DOCUMENT_ROOT) you have 2 options. You could put your htaccess in application folder or in root folder.
I suggest you to put your htaccess in your application folder (dedicated for your website only). Otherwise, the code would not be exactly the same. Here's the code in this case:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /application/
# if this is an existing folder/file then leave
RewriteCond %{REQUEST_FILENAME} -d [OR]
RewriteCond %{REQUEST_FILENAME} -f
RewriteRule . - [L]
# if trailing slash then redirect to url without trailing slash
RewriteRule ^/?(.+)/$ $1 [R=301,L]
# internal rewrite to controller/dispatcher index.php
RewriteRule ^.*$ index.php [L,QSA]
</IfModule>
Your second question:
Also what would be the code for ENFORCING a trailing slash?
You could handle that with this code (only one line changed)
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /application/
# if this is an existing folder/file then leave
RewriteCond %{REQUEST_FILENAME} -d [OR]
RewriteCond %{REQUEST_FILENAME} -f
RewriteRule . - [L]
# if no trailing slash then redirect to url with trailing slash
RewriteRule ^/?(.+)([^/])$ $1$2/ [R=301,L]
# internal rewrite to controller/dispatcher index.php
RewriteRule ^.*$ index.php [L,QSA]
</IfModule>
Try this :
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_URI} !(\.[a-zA-Z0-9]{1,5}|)$
RewriteRule ^(.*)$ http://%{HTTP_HOST}/$1 [L,R=301]
</IfModule>
Try this (bakery):
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} !(\.[a-zA-Z0-9]{1,5}|/)$
#RewriteRule ^(.*)$ http://%{HTTP_HOST}/$1/ [L,R=301]
RewriteRule ^(.*)$ http://%{HTTP_HOST}/$1/ [L,R=301]
If you want to do it for SEO you always have an option to use canonical links and stop bother about redirects:
<link rel="canonical" href="/your_controller/action/"/>

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

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]