.htaccess Apache on cPanel only working in some cases - apache

I'm using the Zend Framework, so I'm bootstrapping into a file called index.php. Naturally, I don't want images to be bootstrapped, so I've added a .htaccess file. Here's what it looks like
/application
/library
/public (this is the root of the site)
/images
/js
.htaccess
index.php
This is what's written in my .htaccess:
RewriteEngine on
RewriteRule !\.(js|ico|gif|jpg|png|mp3|mov|css)$ index.php
This is basically saying if it doesn't end in .js / .ico / etc, then send the request to index.php. It works just fine on my localhost, but when I get up to actually putting it online, it doesn't. It just routes everything to index.php, regardless of the ending of the request. When mywebsite.com/images/wizard.gif should just show the picture, it tries to load the images controller, which is not what I want it to do.
What could be going wrong? I know it's reading the .htaccess. Is it reading my regex wrong? Why would one apache server read it wrong, while another reads it correctly? Any help would be great.

Here is my .htaccess if you would like to give it a try:
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} -s [OR]
RewriteCond %{REQUEST_FILENAME} -l [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^.*$ - [NC,L]
RewriteRule ^.*$ /index.php [NC,L]
Basically it checks to make sure the request is not a directory, symlink or a real file, and then sends it to index.php. Otherwise it will provide direct access to the file/directory

Related

How to redirect any URL to my index.html using apache?

I want my website to point at my index.html no matter what the URL is.
http://localhost/WebsiteName/
http://localhost/WebsiteName/whatever
http://localhost/WebsiteName/whatever/whatever-1/whatever-2/whatever-3/etc
By using this rewrite code in my apache config:
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule . index.html [L]
My URL works correctly when URL is any of these:
http://localhost/WebsiteName/
http://localhost/WebsiteName/whatever
But breaks when it is like this or further extended:
http://localhost/WebsiteName/whatever/
http://localhost/WebsiteName/whatever/whatever-1/whatever-2/whatever-3/etc
It acts as if there was another folder "whatever" in the directory whenever I use one of the URLs that break.
I don't want the URL to change, I just want it to point at my index.html no matter what it is.
Based off what you have there, all of those url's should go to your index.html. The index.html is assumed to be at the DOCUMENT_ROOT.
I'm not sure what your problem is, but maybe instead of having a condition for rewriting non-files. Stop rewriting when it's a file. I notice any changes on my website, with either config, but maybe it can work for yours.
RewriteEngine on
### If a uri leads to an actual file or directory (presumably with it's own index.html), then don't rewrite any further
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} -f [OR]
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} -d
RewriteRule ^ - [L]
### everything else
RewriteRule . /index.html [L]

Problems redirecting from a 403 using .htaccess (Yourls)

I'm using a php app called Yourls. It's a self-hosted url shortener and it's pretty great, I'm happy with its overall functionality. Due to the nature of its development however there isn't much in the way of support. Let's pretend the base url is af.to, where a shortened url would be af.to/goo that might redirect to whatever url is defined by 'goo'. The problem I'm facing is that if someone goes to af.to, they end up on a 403-Forbidden. I'd rather the client is redirected to a specific url instead. I have already picked up a plugin for Yourls which redirects to a url when a shortlink is not found or mis-typed, but this does not cover the base of af.to
I attempted to put in a 403 redirect in the .htaccess, but that broke the whole yourls script resulting in a 500 server error.
Current .htaccess looks like this:
# BEGIN YOURLS
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^.*$ /yourls-loader.php [L]
</IfModule>
# END YOURLS
Any help on what I need to do?
Thank you.
The RewriteCond blocks tell the RewriteRule to skip existing files / folders. When you go to http://af.to/, the root folder exists : no redirection. The apache server doesn't find any index.html (or index.php) file, isn't allowed to list the content of the folder, give up and returns a 403 Forbidden.
You can create the index.html file to show some content or you can add these lines to redirect to an other url :
# just after RewriteEngine On
RewriteRule ^/$ http://my-compagny.com/ [L,R=301]

Incorrectly configured htaccess file that should direct to subdirectory

I've got a CMS installed in a sub-directory of my webspace and I'm having a little trouble figuring out how to configure the htaccess file.
mysite.com contains a splash page that should stay there for now. The idea is that mysite.com/dev should open the index page of the CMS. I suppose I could go with a subdomain but I'll have to research what to do in this case. Either way all of this is just temporary so whatever works is good.
You can see from the below code I've been messing around and I've commented out a lot of stuff. (I've also not bothered to copy more that I think is probably nonsense.)
#Display PHP Errors
php_flag display_errors Off
RewriteEngine On
RewriteBase /
#RewriteCond %{HTTP_HOST} .
#RewriteCond %{HTTP_HOST} !^www\.mysite\.com\dev [NC]
# For Friendly URLs
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /dev/index.php?q=$1 [L,QSA]
I should note that I'm with a hosting company any my root path is something like
/content/hosting/l/u/mysite.com/web
I've tried to add this (and truncated versions) to my htaccess file but without success.
If dev is your CMS and you want site/dev to open index.php in dev, your htaccess file for dev only needs this line:
DirectoryIndex index.php

Redirect all to index.php using htaccess

I am writing a simple PHP-based MVC-ish framework. I want this framework to be able to be installed in any directory.
My PHP script grabs the request uri and breaks it off into segments. It makes segment 1 the controller and segment 2 the action. This goes all fine when I do this:
http://www.example.com/mvc/module/test/
It will go to the specific module controller and method. Now I have a default controller, the home controller, which is in folder home.
Now when I access this folder directly http://www.example.com/mvc/home/
It will display a 403 forbidden , because this folder does exist, instead it should also go back to http://www.example.com/mvc/index.php
If I would have installed the framework in a different folder, lets say folder framework it has to redirect back to http://www.example.com/framework/index.php
I would like to redirect every folder and php file back to the index.php, leaving everything else the way it is.
My first problem I encountered was it never redirects to the right folder, always to the domain root folder.
This is what I tried :
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule . index.php [L]
Your rewrite rule looks almost ok.
First make sure that your .htaccess file is in your document root (the same place as index.php) or it'll only affect the sub-folder it's in (and any sub-folders within that - recursively).
Next make a slight change to your rule so it looks something like:
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /index.php?path=$1 [NC,L,QSA]
At the moment you're just matching on . which is one instance of any character, you need at least .* to match any number of instances of any character.
The $_GET['path'] variable will contain the fake directory structure, so /mvc/module/test for instance, which you can then use in index.php to determine the Controller and actions you want to perform.
If you want the whole shebang installed in a sub-directory, such as /mvc/ or /framework/ the least complicated way to do it is to change the rewrite rule slightly to take that into account.
RewriteRule ^(.*)$ /mvc/index.php?path=$1 [NC,L,QSA]
And ensure that your index.php is in that folder whilst the .htaccess file is in the document root.
Alternative to $_GET['path'] (updated Feb '18 and Jan '19)
It's not actually necessary (nor even common now) to set the path as a $_GET variable, many frameworks will rely on $_SERVER['REQUEST_URI'] to retrieve the same information - normally to determine which Controller to use - but the principle is exactly the same.
This does simplify the RewriteRule slightly as you don't need to create the path parameter (which means the OP's original RewriteRule will now work):
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^.*$ /index.php [L,QSA]
However, the rule about installing in a sub-directory still applies, e.g.
RewriteRule ^.*$ /mvc/index.php [L,QSA]
The flags:
NC = No Case (not case sensitive, not really necessary since there are no characters in the pattern)
L = Last (it'll stop rewriting at after this Rewrite so make sure it's the last thing in your list of rewrites)
QSA = Query String Append, just in case you've got something like ?like=penguins on the end which you want to keep and pass to index.php.
To redirect everything that doesnt exist to index.php , you can also use the FallBackResource directive
FallbackResource /index.php
It works same as the ErrorDocument , when you request a non-existent path or file on the server, the directive silently forwords the request to index.php .
If you want to redirect everything (including existant files or folders ) to index.php , you can use something like the following :
RewriteEngine on
RewriteRule ^((?!index\.php).+)$ /index.php [L]
Note the pattern ^((?!index\.php).+)$ matches any uri except index.php we have excluded the destination path to prevent infinite looping error.
There is one "trick" for this problem that fits all scenarios, a so obvious solution that you will have to try it to believe it actually works... :)
Here it is...
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ index.php [L,QSA]
</IfModule>
Basically, you are asking MOD_REWRITE to forward to index.php the URI request always when a file exists AND always when the requested file doesn't exist!
When investigating the source code of MOD-REWRITE to understand how it works I realized that all its checks always happen after the verification if the referenced file exists or not. Only then the RegEx are processed. Even when your URI points to a folder, Apache will enforce the check for the index files listed in its configuration file.
Based on that simple discovery, turned obvious a simple file validation would be enough for all possible calls, as far as we double-tap the file presence check and route both results to the same end-point, covering 100% of the possibilities.
IMPORTANT: Notice there is no "/" in index.php. By default, MOD_REWRITE will use the folder it is set as "base folder" for the forwarding. The beauty of it is that it doesn't necessarily need to be the "root folder" of the site, allowing this solution work for localhost/ and/or any subfolder you apply it.
Ultimately, some other solutions I tested before (the ones that appeared to be working fine) broke the PHP ability to "require" a file via its relative path, which is a bummer. Be careful.
Some people may say this is an inelegant solution. It may be, actually, but as far as tests, in several scenarios, several servers, several different Apache versions, etc., this solution worked 100% on all cases!
You can use something like this:
RewriteEngine on
RewriteRule ^.+$ /index.php [L]
This will redirect every query to the root directory's index.php. Note that it will also redirect queries for files that exist, such as images, javascript files or style sheets.
Silly answer but if you can't figure out why its not redirecting check that the following is enabled for the web folder ..
AllowOverride All
This will enable you to run htaccess which must be running! (there are alternatives but not on will cause problems https://httpd.apache.org/docs/2.4/mod/core.html#allowoverride)
just in case you were still wondering how to redirect all request either if the directory exists (for core framework folders and files) to the framework index handler, after some error/success attempts just noticed I just needed to change the RewriteCond in the .htaccess file
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
the above condition states "not found files" and "not found directories", ok, what if just remove "not found" (!-d) line, and ended with something like the below:
RewriteEngine on
RewriteBase /framework/
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ /framework/index.php [L,QSA]
It worked for me like a charm
I just had to face the same kind of issue with my Laravel 7 project, in Debian 10 shared hosting. I have to add RewriteBase / to my .htaccess within /public/ directory. So the .htaccess looks a like
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^.*$ /index.php [L,QSA]
After doing that don't forget to change your href in,
home
Example:
.htaccess file
RewriteEngine On
RewriteRule ^about/$ /about.php
PHP file:
about

Apache mod_rewrite usually works, but won't work in this folder -- what's wrong?

I have an Apache web server that usually handles mod_rewrite fine. I have a directory called /communications/q/ and I want to rewrite any URI to insert "index.php" before the rest of the entered URI.
For example, /communications/q/something/else should actually serve communications/q/index.php/something/else. It's the standard PHP CodeIgniter setup.
I placed a .htaccess file in the /q/ directory and put the following in it:
RewriteEngine On
RewriteCond $1 !^(index\.php|images|robots\.txt)
RewriteRule ^(.*)$ /index.php/$1 [L]
When I even try to go to /communications/q/, I get a 404 Not Found error. Which makes no sense at all because if I comment the .htaccess stuff out, I get the index.php page if I go to /communications/q/, but with the code, I get 404 Not Found.
Anyone spot what I'm doing wrong?
FYI I have a controller called hello, so technically /communications/q/hello should work, but it's a 404, also. But with .htaccess commented out, /communications/q/index.php/hello works fine.
..
==== ADDED NOTE #1 ====
Using CodeIgniter, I should be able to call controllers and functions using the URI structure. So I have a controller called welcome, actually, and then a function called index() which is the default, and a function called hello().
The way CI works, I would write /communications/q/index.php/welcome and I would get the output of the index() function from the welcome controller. And in fact, this works perfectly right now.
Unfortunately, having that weird index.php in the URI is unwieldy and unnecessary, so CI suggests using .htaccess to allow the URI to omit that section of the URI and silently reenter it in the background, using mod_rewrite.
When I add the RewriteRule above, however, it doesn't work. So:
/controller/q/welcome returns a 404 error when it should return exactly the same thing as /controller/q/index.php/welcome. That's the problem. Shouldn't the RewriteRule above make that work?
..
The substitution in a RewriteRule is relative to the DocumentRoot. Based on this, I'd suggest you try:
RewriteEngine On
RewriteCond $1 !^(index\.php|images|robots\.txt)
RewriteRule ^(.*)$ /communications/q/index.php/$1 [L]
The answer was in the CodeIgniter wiki, in the end. I replaced my .htaccess code with the following:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /communications/q/
# Removes access to the system folder by users.
# Additionally this will allow you to create a System.php controller,
# previously this would not have been possible.
# 'system' can be replaced if you have renamed your system folder.
RewriteCond %{REQUEST_URI} ^system.*
RewriteRule ^(.*)$ /index.php?/$1 [L]
# When your application folder isn't in the system folder
# This snippet prevents user access to the application folder
# Submitted by: Fabdrol
# Rename 'application' to your applications folder name.
RewriteCond %{REQUEST_URI} ^application.*
RewriteRule ^(.*)$ /index.php?/$1 [L]
# Checks to see if the user is attempting to access a valid file,
# such as an image or css document, if this isn't true it sends the
# request to index.php
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php?/$1 [L]
</IfModule>
<IfModule !mod_rewrite.c>
# If we don't have mod_rewrite installed, all 404's
# can be sent to index.php, and everything works as normal.
# Submitted by: ElliotHaughin
ErrorDocument 404 /index.php
</IfModule>
And everything worked perfectly. The major relevant change, I think, was adding a ? to the RewriteRule after index.php -- does anyone understand why that's necessary?
Source: http://codeigniter.com/wiki/mod_rewrite/