How to use mod_rewrite to only allow files without .php extension - apache

i am using this code in the .htaccess-File to rewrite for example /home to /home.php
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^([^\.]+)$ $1.php [NC,L]
but how can i do this and at the same time when the server gets a request for /home.php
rewrite it so the file will not be found. I only want to allow access with /home and
not with /home.php but still use the file with it's extension.
Using this .htaccess works in general:
ErrorDocument 404 /404_error.php
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^([^\.]+)$ $1.php [NC,L]
RewriteCond %{THE_REQUEST} \.php[\s?/] [NC]
RewriteRule \.php$ - [NC,R=404,L]
But when a request that should throw 404 uses for example /whatever the custom 404 error page gets loaded. But with /whatever.php i get this:
The requested URL /test/whatever.php was not found on this server.
Additionally, a 500 Internal Server Error error was encountered while trying to use an
ErrorDocument to handle the request.
Any idea how to solve this 500 error?
P.S.: Same thing without php-extension "ErrorDocument 404 /404_error"

You can use this rule to block .php requests:
RewriteCond %{THE_REQUEST} \.php[\s?/] [NC]
RewriteRule \.php$ - [NC,R=404,L]

Related

htaccess error page file is not working with condition of rewrite

I have written a condition to auto add the path in the URL and it is working perfectly but now I want to add error pages but it is giving no response instead giving a 500 error. ErrorDocument with text is working fine but it is not adding file I have already checked all possible paths but still no response.
This is my code in .htaccess file.
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /crud/views/pages/$1 [L]
</IfModule>
ErrorDocument 500 /404.html
ErrorDocument 404 /404.html
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /crud/views/pages/$1 [L]
This will result in a rewrite loop (500 error) if you request a file (or directory) that does not exist when prefixed with /crud/views/pages/.
Note that defining the 500 ErrorDocument in .htaccess is too late for most 500 errors - this ErrorDocument would need to be defined early in the server config to catch this particular error.
You could resolve this rewrite-loop by first checking that the resource at the desired location exists before rewriting, instead of checking that the current request does not map to a file (or directory). This also involves just one filesystem check rather than two.
For example:
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteCond %{DOCUMENT_ROOT}/crud/views/pages/$1 -f
RewriteRule (.*) crud/views/pages/$1 [L]
The first condition that checks against the REDIRECT_STATUS environment variable just makes sure that only direct requests are check and not rewritten requests by the rule itself.

htaccess rewrite rule if file exists else go to PHP file

I'm trying to write a rewrite rule in my .htaccess that redirects all traffic except one domain to https. Then if the file it is trying to go to does not exist, then run the last block that follows, going to loader.php, but if the file goes exist go to it.
Here's one of the iterations I have so far:
RewriteEngine on
RewriteCond %{HTTPS} off
RewriteCond %{HTTP_HOST} !^(www\.)?(korle\.tt) [NC]
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [NE,L,R=301]
<If "-f %{DOCUMENT_ROOT} . '/'">
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^.*$ /loader.php [L]
</If>
<Else>
RewriteEngine On
RewriteRule ^ /404.html [R=404,L]
</Else>
What I am trying to do is if the user goes to korlett.org or korlett.net or korelett.com or any file within, it redirects to https://. But not http://korle.tt or other domains pointing to this dir (for now not specified), they'll stay HTTP.
Then after that, if the file does not exist or if the URL returns a 404 then run this:
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^.*$ /loader.php [L]
then if not sent it to loader.php to check if there is a long url pairs with that fragment/"dir" and if that fails then serve a 404 page.
This 404 response would need to be managed by loader.php - ie. in your PHP script. Because once the request has been passed to loader.php (any request that does not map to a file or directory) then .htaccess has effectively finished with the request and you can no longer get Apache to handle the 404 response.
It should serve a 404 if loader.php isn't found
However, this can indeed be managed in .htaccess, by setting an ErrorDocument and removing the slash prefix on the RewriteRule substitution (which was probably the intention anyway, since you have included a RewriteBase directive). Removing the slash prefix prevents a rewrite loop (from repeatedly rewriting to loader.php). In other words, instead of this:
RewriteRule ^.*$ /loader.php [L]
It should be this:
RewriteRule ^ loader.php [L]
The regex ^ has the same net result as ^.*$ in this example, and simply serves to match anything (like you have in your HTTP to HTTPS redirect).
This prevents a rewrite loop because when rewriting to loader.php (relative path, no slash prefix) the rewrite engine detects that you are rewriting to the same URL and prevents further rewrites. Allowing the Apache 404 ErrorDocument to be served. (Whereas /loader.php is technically a different URL - as far as mod_rewrite is concerned - so the rewriting would continue.)
So, your complete .htaccess file becomes:
ErrorDocument 404 /404.html
RewriteEngine on
RewriteBase /
RewriteCond %{HTTPS} off
RewriteCond %{HTTP_HOST} !^(www\.)?(korle\.tt) [NC]
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [NE,L,R=301]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^ loader.php [L]
Another way to prevent a rewrite loop is to include a specific exception for loader.php. In fact, this can be used together with the above, in order to make the rewrite fail early, rather than waiting for the rewrite engine to detect the no-change. For example, change the last block above to read:
RewriteRule ^loader\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^ loader.php [L]

URL Rewriting on Apache server causes 404 error page

A few weeks ago I was trying url rewriting on my shared host. It was working for a while, but nowadays it seems to be broke. I don't know what the problem is and I can't solve it by myself. Hope you could help, guys.
This is the plan. I want to delete the extension in the url (e.g. 'file.html' or 'file.php') to only the filename (e.g. 'file'). My code is the following:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteRule ^index/(.*)/$ index.php?page=$1
RewriteRule ^([^\.]+)$ $1.php [NC,L]
RewriteRule ^([^\.]+)$ $1.html [NC,L]
ErrorDocument 404 404.php
ErrorDocument 403 403.php
ErrorDocument 401 401.php
</IfModule>
One extended note: this .htcaccess file is in the directory 'portfolio'. The root has another .htcaccess file which is the following:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . index.php [L]
</IfModule>
Maybe it is something obvious, but I couldn't find what the problem is. I did try 'RewriteBase /website/', 'RewriteBase /', 'RewriteCond %{REQUEST_FILENAME} !-f' and 'RewriteCond %{REQUEST_FILENAME} !-d' in the first .htaccess file, but that doesn't work.
You can have these rules in /portfolio/.htaccess
ErrorDocument 404 404.php
ErrorDocument 403 403.php
ErrorDocument 401 401.php
RewriteEngine On
RewriteBase /portfolio/
RewriteRule ^index/(.+?)/$ index.php?page=$1 [L,QSA]
RewriteCond %{DOCUMENT_ROOT}/portfolio/$1\.html -f [NC]
RewriteRule ^([^.]+)$ $1.html [L]
RewriteRule ^([^.]+)$ $1.php [L]
Your rules for adding .php or .html need to have a RewriteCond to check whether corresponding files exist in your portfolio directory.

Remove trailing .html rewriterule creates 404 error

I have modified .htaccess to remove trailing .html from my pages. htaccess looks like this:
RewriteEngine on
RewriteBase /
RewriteCond %{http://www.mydomain.co.uk} !(\.[^./]+)$
RewriteCond %{REQUEST_fileNAME} !-d
RewriteCond %{REQUEST_fileNAME} !-f
RewriteRule (.*) /$1.html [L]
RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /([^.]+)\.html\ HTTP
RewriteRule ^([^.]+)\.html$ http://www.mydomain.co.uk/$1 [R=301,L]
I also added the following at the top of the .htaccess to set up a custom 404 page and stop indexing:
ErrorDocument 404 /notfound.html
Options -Indexes
The rewrite rule works perfectly. So does the anti-indexing. However the 404 page gives me this error:
Internal Server Error
The server encountered an internal error or misconfiguration and was unable to complete your request.
Please contact the server administrator, webmaster#mydomain.co.uk and inform them of the time the error occurred, and anything you might have done that may have caused the error.
More information about this error may be available in the server error log.
Additionally, a 500 Internal Server Error error was encountered while trying to use an ErrorDocument to handle the request.
If I remove the rewriterule then the 404 page works fine. I don't know a lot about this kind of stuff and was wondering what to do to be able to get both aspects to work correctly? Can anyone help please?
(PS: I read this answer and think it might apply to me - but didn't understand it at all.)
Just wanted to let you know I found a solution for this:
ErrorDocument 404 /notfound.html
Options -Indexes
RewriteEngine on
RewriteBase /
RewriteCond %{THE_REQUEST} ^[A-Z]+\ /([^/\ ]+/)*[^.\ ]+\.htm\ HTTP/
RewriteCond %{REQUEST_FILENAME} -f
RewriteRule ^(([^/]+/)*[^.]+)\.htm$ http://www.example.com/$1 [R=301,L]
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.+)/$ http://www.example.com/$1 [R=301,L]
RewriteCond %{REQUEST_FILENAME}.html -f
RewriteRule ^(([^/]+/)*[^./]+)$ /$1.html [L]
Works great!

Code Ignighter - 404 showing, but correct response

i'm working on a website at work and recenctly move it via svn to my localserver so i can work from home...
The setup went okay, no majors... but code ignighter sends 404 Not Found on pages along with the correct response...
For example i can load 'localhost/home' and it fires my controller and i get correct view, but CI also send 404 in headers for the page....!!
this also happens on my js files...
I can force it to send "200 OK", but doing this on every page seams silly..
Has anyone come accross this problem before...?
I'm using;
Code Ignighter: 2.1.0
Apache : 2.0.63
PHP: 5.1.6
this is my .htaccess
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_URI} ^system.*
RewriteRule ^(.*)$ /index.php/$1 [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond $1 !^(index\.php|images|robots\.txt|css|js)
RewriteRule ^(.*)$ index.php/$1 [L]
</IfModule>
<IfModule !mod_rewrite.c>
ErrorDocument 404 /index.php
</IfModule>
Give the .htaccess example from the documentation a try:
RewriteEngine on
RewriteCond $1 !^(index\.php|images|robots\.txt)
RewriteRule ^(.*)$ /index.php/$1 [L]
The following line could be responsible for your 404 response:
ErrorDocument 404 /index.php