Add Trailing Slash for MVC Application - apache

I'm building an application based on the MVC design pattern, and I want my URLS to be like: http://example.com/page/action/. I successfully got it to work with the code below, but if the URL doesn't end with a slash, the application breaks. I've searched all over, mostly Stack Overflow, but I haven't found a good answer that works with my code. I've tried to modify many of the answers others got, but that didn't work either.
Here is my latest code (that doesn't include things I've tried):
# Turn on Rewrite Engine
Options +FollowSymLinks
RewriteEngine On
RewriteRule ^(.*) /$1/ [R=301,L]
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)/(.*)/$ ./index.php?p=$1&a=$2 [PT]
I got a few ideas from:
Simple MVC mod-rewrite
I am new to mod_rewrite, but I don't understand why I can't get the code to add a trailing slash. It looks correct. Can someone help me out? Thanks!

RewriteEngine on
RewriteBase /
RewriteCond %{REQUEST_URI} !/$
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule (.*) $1/ [R=301,L,QSA]

Related

Adding exceptions to mod_rewrite

I got my basic redirects work with the mod_rewrite module. When requesting pages e.g. localhost/home it's correctly redirecting to localhost/index.php?page=home, but I have a problem with exceptions.
I created a folder api where I store files by category e.g. api/auth/register.php and api/customer/create.php. I tried to make rewrite rule that contains 2 params (in this example auth and customer) so basically it just drops the .php off from the url.
The rule that I made is following
RewriteRule ^api/(.*)/(.*)/?$ api/$1/$2.php [L]
After adding that line to my .htaccess, problems started to occur. For example my .css and .js files started to redirect. So maybe I need to make some exeption for the apis? Have you some other ideas to improve my rewrite rules?
.htaccess
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^api/(.*)/(.*)/?$ api/$1/$2.php [L] # problems started to occur after adding this line
RewriteRule (.*) index.php?page=$1 [L,QSA]
Thanks in advance.
RewriteCond will affect only the first following RewriteRule so you need the keep them next to your initial Rule, and move the added one above them (with its own conditions).
Also, your /api rule is not strict enough ((.*) will pick anything, including the slashes), which might not matter in you case, but still. I sugest you try with this:
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^api/([^/]*)/([^/]*)/?$ api/$1/$2.php [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule (.*) index.php?page=$1 [L,QSA]

htaccess to route all requests through index add add trailing slash

This probably seems like quite a simple question to most of you, but i'm having a real hard time getting my site to route all requests through the index file whilst also enforcing trailing slashes. I've searched high and low and not found an appropriate solution. My .htaccess so far is as follows:
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php/$1 [QSA,L]
RewriteCond %{REQUEST_URI} /+[^\.]+$
RewriteRule ^(.+[^/])$ %{REQUEST_URI}/ [R=301,L]
This is as far as i have managed to get and works apart from it adds the index.php into the url, for example if a user goes to;
www.example.com/about-us
I would like it to route through index and become;
www.example.com/about-us/
However my above htaccess file produces;
www.example.com/index.php/about-us/
Seems so close yet so far, anything i do to the htaccess file to try and remove the index.php just stops it from working entirely. I am aware my solution is far from perfect, it still allows access to directories and files however its the best i've been able to come up with (would ideally like to deny directory listing!)
Any help is greatly appreciated!
The ordering of rules is quite important in these cases. Switch the two rules order, and you should be getting the desired behaviour:
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_URI} /+[^.]+$
RewriteRule ^(.+[^/])$ %{REQUEST_URI}/ [R=301,L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php/$1 [QSA,L]

Remove periods from url using .htaccess

I've seen variations of this question around, but I couldnt make it work for me.
My problem is: I have many urls indexed at google where the address has one ore more periods. Ex: http://partiturapara.com.br/15-sheets/809-some-music-enc.4.5
Of course the URL does not work, because Apache thinks it is a extension, so I have to strip them, to leave something like this:
http://partiturapara.com.br/15-sheets/809-some-music-enc45
I have a few .htacces lines that make things work (I use joomla) that I will show them bellow.
I´ve tried the following:
RewriteRule ^([^/]*)\.([^/]*)\.$ /$1$2 [L,R=301] - But it just keep loading for ever
and also tried:
RewriteRule ^([^/]*)\.$ /$1 [NC] - This almost works, but gets terrible slow and url will not finish loading.
If you could at least point me in the right direction it would be amazing, cause I already spent lots and lots of hours trying to figure out how all these lines works together and its been very frustrating.
My actual rewrite at the .htaccess file:
RewriteEngine On
RewriteCond %{QUERY_STRING} base64_encode[^(]*\([^)]*\) [OR]
RewriteCond %{QUERY_STRING} (|%3E) [NC,OR]
RewriteCond %{QUERY_STRING} GLOBALS(=|\[|\%[0-9A-Z]{0,2}) [OR]
RewriteCond %{QUERY_STRING} _REQUEST(=|\[|\%[0-9A-Z]{0,2})
RewriteRule .* index.php [F]
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
RewriteCond %{REQUEST_URI} !^/index\.php
RewriteCond %{REQUEST_URI} /component/|(/[^.]*|\.(php|html?|feed|pdf|vcf|raw))$ [NC]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
# ----- The line I inserted ------
RewriteRule ^([^/]*)\.$ /$1 [NC]
#-------My edit end --------------
RewriteRule .* index.php [L]
EDIT 1
----------------- UPDATE AFTER JON´S SUGGESTION (it didnt work)----------------------
Hi,
After Jon suggestion, I am trying to figure out yet how my htaccess files works. This way I removed all lines in a way the website still works. The Line Jon suggested seems to be ignored. This is minimum .htaccess I got:
RewriteEngine On
------ this is the line Jon suggested me -----
RewriteRule ^(.*)\.([^/]*)\.$ /$1$2 [L,R=301]
------ end line Jon sugested -----------------
RewriteCond %{REQUEST_URI} /component/|(/[^.]*|\.(php|html?|feed|pdf|vcf|raw))$ [NC]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule .* index.php [L]
As I said, the website navigates normally, except when it finds the "dot" in the URL, so it returns the error:
Not Found
The requested URL /15-partituras/1046-sentimental-o.d.m-v-choro was not found on this server.
Additionally, a 404 Not Found error was encountered while trying to use an ErrorDocument to handle the request.
Perhaps I misunderstood something?
Thanks again!
You don't want to insert that rule there. You've completely usurped the very necessary conditions that need to be applied to the index.php routing rule. RewriteCond's only apply to the immediately following rule.
Try adding this right below RewriteEngine On:
RewriteRule ^(.*)\.([^/]*)\.$ /$1$2 [L,R=301]

CodeIgniter index.php removal htaccess causing mis-redirection

I'm using following htaccess rule which is proposed all over internet for removing index.php in codeigniter urls. And there are some of the redirection rules i added above it.
RewriteEngine On
RewriteBase /
RewriteCond %{HTTP_HOST} !^www\.
RewriteRule ^(.*)$ https://www.%{HTTP_HOST}/$1 [R=301,L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /index.php?$1 [L]
The problem is:
I'm getting some odd http request, which i think is caused by htaccess rules above.
Here are some of them :
https://www.sitename.com/index.php/favicon.ico
which ought to be .com/favicon.ico
https://www.sitename.com/index.php/scripts/jquery.js
which ought to be .com/public/jquery.js
as a side note im using base tag to redirect assets to /public/
strange thing is i couldnt find where the second redirection happens
i tested whole site and javascript & css files load correctly
i handled this redirections by making my controller ignore those requests but a while ago
a strange error happened. which i asked here:
https://stackoverflow.com/questions/11775849/htaccess-didnt-work-until-renaming-and-then-renaming-back
my guess is that, even though i ignore misredirected request, hosting company receives them and probably it was causing some trouble for them which led to the problem i shared in linked question by a maintenance of hosting company.
Anyway, Question is:
How can i make htaccess rule only redirect requests that doesnt have file extension at the end?
You're missing a line before the REQUEST_FILENAME line:
RewriteCond $1 !^(index\.php|assets|something|fav\.ico|robots\.txt)
You can modify this to suit your needs. I've got my JS/CSS etc in the assets folder so it's not affected by the rewrite.
so the full .htaccess will look like this:
RewriteEngine On
RewriteBase /
RewriteCond %{HTTP_HOST} !^www\.
RewriteRule ^(.*)$ https://www.%{HTTP_HOST}/$1 [R=301,L]
RewriteCond $1 !^(index\.php|assets|something|fav\.ico|robots\.txt)
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /index.php?$1 [L]

RewriteRule in .htaccess showing rewritten url in address bar

Apologies if this has been asked before but I've searched all over for an answer to this but I haven't been able to find a satisfactory solution.
I've got the following .htaccess file in my httpdocs:
Options +FollowSymlinks
RewriteEngine on
RewriteBase /
RewriteCond %{HTTP_HOST} ^(www.)?example.com$
RewriteCond %{REQUEST_URI} !^/users/
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.+)$ users/$1 [L]
This correctly maps "www.example.com/joebloggs" to "www.example.com/users/jobloggs" and the appropriate index page is correctly shown.
The problem is "www.example.com/users/jobloggs" is shown in the address bar instead of the original (short) url. Would really appreciate any help on this.
If you're saying it's loading a DirectoryIndex file (e.g. index.html / index.php), then I'd say the lack of a trailing slash in your RewriteRule substitution is the problem. Try something like:
RewriteRule ^(.+?)/?$ users/$1/ [L]