Send 404 when requesting index.php through .htaccess? - .htaccess

I've recently refactored an existing CodeIgniter application to use url segments instead of query strings, and I'm using a rewriterule in htaccess to rewrite stuff to index.php:
RewriteRule ^(.*)$ /index.php/$1 [L]
My problem right now is that a lot of this website's pages are indexed by google with a link to index.php. Since I made the change to use url segments instead, I don't care about these google results anymore and I want to send a 404 (no need to use 301 Move permanently, there have been enough changes, it'll just have to recrawl everything).
To get to the point: How do I redirect requests to /index.php?whatever to a 404 page? I was thinking of rewriting to a non-existent file that would cause apache to send a 404. Would this be an acceptable solution? How would the rewriterule for that look like?
edit:
Currently, existing google results will just cause the following error:
An Error Was Encountered
The URI you submitted has disallowed
characters.
I tried something like:
RewriteRule ^index\.php?(.*)$ /no-exist.html [R=404,L]
But it caused an internal server error.
edit2:
CodeIgniter is already sending '400' errors, will this be sufficient to get my pages removed from google?

RewriteRule's R[=code] flag allows code only from range 300-400.
Don't use redirect R flag - just try to rewrite to an unexciting page:
UPDATED:
Two redirects are apposed to each other - use RewriteConds to escape the interference.
Complete .htaccess:
RewriteEngine on
RewriteCond %{REQUEST_URI} ^/index.php.*
RewriteCond %{QUERY_STRING} !^$
RewriteRule ^(.*)$ /no-exist.html [L]
RewriteCond %{REQUEST_URI} !^/index.php.*
RewriteCond %{REQUEST_URI} !^/no-exist.html.*
RewriteRule ^(.*)$ /index.php/$1 [L]
Note: /no-exist.html actualy doesn't exist. Suppose, it will help you.

There is a special HTTP status code 410 GONE to tell the World to remove resource:
The requested resource
/index.php
is no longer available on this server and there is no forwarding address. Please remove all references to this resource.
To send this code use [G|gone] flag in rewrite rule:
RewriteEngine on
RewriteCond %{REQUEST_URI} ^/index.php.*
RewriteCond %{QUERY_STRING} !^$
RewriteRule ^(.*)$ / [G,L]
RewriteCond %{REQUEST_URI} !^/index.php.*
RewriteRule ^(.*)$ /index.php/$1 [L]

Related

Redirect loop while looking for uri that does NOT contain specific string

I have an site lets say https://example.com/ and I would like to redirect every url that doesn't begins with /something to https://example.com/something/
I'm using Apache 2.4.29 (hosting) and my .htaccess looks like this.
RewriteEngine On
RewriteCond %{REQUEST_URI} !^/something(.*)$ [NC]
RewriteRule ^(.*)$ /something/ [R=302,NC,L]
My problem is that when I'm on homepage (/) or any other page I'm redirected to /something/ which is correct but when I'm on /something/ I'm still beeing redirected to /something/ and it loops until ERR_TOO_MANY_REDIRECTS error shows up.
Here is a link to htaccess tester which shows that this should work and should not redirect me to /something/ when I'm already here but it is not the case on my hosting.
I was following this and this question but without success.
With your shown attempts, please try following set of rules. Please place them on top of htaccess rules file in case you already have existing rules.
Please make sure to clear your browser cache before testing your URLs.
RewriteEngine On
RewriteCond %{REQUEST_URI} !^/?$
RewriteCond %{THE_REQUEST} !something [NC]
RewriteRule ^ /something? [R=302,NC,L]
You can try this rule with THE_REQUEST variable:
RewriteEngine On
RewriteCond %{THE_REQUEST} !\s/something [NC]
RewriteRule ^ /something/ [R=302,L]
Make sure to test it after completely clearing browser cache.
THE_REQUEST variable represents original request received by Apache from your browser and it doesn't get overwritten after execution of other rewrite directives. Example value of this variable is GET /index.php?id=123 HTTP/1.1

Simple rewritecond in htaccess doesn't work as expected

This is super simple but it's driving me crazy! I have a website at http://example.org/ and a subdirectory at http://example.org/ccc/
I want to redirect anything outside of the /ccc/ directory to a different website.
RewriteEngine on
RewriteCond %{REQUEST_URI} !^/ccc/?.*
RewriteRule ^(.*)$ https://new-website.com/$1 [L]
But this code doesn't work, it redirects the /ccc/ directory. According to my research and testing with this htaccess tester, it should not redirect because the RewriteCond is checking against /ccc with optional slash and other characters after it.
What is happening? Does this look correct?
Edit: This method from this answer is also not working, the CCC domain is being redirected:
RewriteEngine on
RewriteRule ^ccc index.php [L]
RewriteRule (.*) https://new-website.com/$1 [R=301,L]
PHP 5.4.45, Apache/2.2.31
Assuming ccc/ directory doesn't have a separate .htaccess, you may use this rule:
RewriteEngine on
RewriteCond %{THE_REQUEST} !\s/ccc[/?\s] [NC]
RewriteRule ^ https://new-website.com%{REQUEST_URI} [L,R=301,NE]
THE_REQUEST variable represents original request received by Apache from your browser and it doesn't get overwritten after execution of other rewrite directives. An example value of this variable is GET /index.php?id=123 HTTP/1.1
It looks like [L] isn't behaving normally and I'm guessing it's the old version of Apache (2.2.31) because these rules worked on a separate website. I found this solution which seemed to work for this case, the third line below:
RewriteEngine on
RewriteRule ^ccc/? index.php [L]
RewriteCond %{ENV:REDIRECT_STATUS} != 200
RewriteRule ^(.*)$ https://new-website.com/$1 [L]
Explanation from that question:
The problem is that once the [L] flag is processed, all the next RewriteRules are indeed ignored, however, the file gets processed AGAIN from the begin, now with the new url.
This magic Condition will not process the catch all if the file was already redirected.

Forced SSL in htaccess going to only the home page

I have recently added an SSL to my sites. I have added the code to the .htaccess file to force the https. The issue is that my external links that go to pages within the site are now being redirected to the homepage. The code I am using is:
RewriteEngine On
RewriteBase /
RewriteCond %{ENV:HTTPS} !on [NC]
RewriteRule ^(.*)$ https://www.watsonelec.com%1 [R,L]
I think the issue is in the last line, as the rule is telling it to redirect to the homepage. What I can't seem to find is a rule that will say for it to go to the URL provided in the link but give it an https instead of the HTTP.
I did do a search for this topic, but all the code I found was similar to what I already had. Thank you for all your help.
Update
I have two sites I am trying to work this out for, watsonenerysolutions.com and watsonelec.com.
When I tried
RewriteOptions InheritDownBefore
RewriteCond %{ENV:HTTPS} !on [NC]
RewriteRule ^(.*)$ https://www.watsonenergysolutions.com/$1 [R,L]
It still sent to the homepage
When I tried
RewriteOptions InheritDownBefore
RewriteCond %{ENV:HTTPS} !on [NC]
RewriteRule ^ https://www.watsonenergysolution.com%{REQUEST_URI} [R,L]
I received an error message that said Safari can't open the page "https://www.watsonenergysolutions.com/index.php" because Safari can't find server "www.watsonenergysolutions.com"
%N backreferences are what you match in RewriteCond's. In your case, it is empty. That's why anything is going to the homepage.
You need to use $1 or %{REQUEST_URI}, both rules below are equivalent (the second may be faster because you don't -re-match unnecessarily)
RewriteRule ^(.*)$ https://www.watsonelec.com/$1 [R,L]
RewriteRule ^ https://www.watsonelec.com%{REQUEST_URI} [R,L]
Note 1: %{REQUEST_URI} value always begins with a leading /, while what you can match in a RewriteRule never begins with a leading /
Note 2: R flag uses a 302 redirect by default. Maybe you'll want to use a 301 ([R=301,L])

Set up of conditional redirect in htaccess

I've been asked to make an existing web site multi-language.
In preparation for this I have had to move all existing pages from /path/page to /en/path/page
To maintain any existing incoming links I now need to set up an htaccess redirect to send any requests from their original urls to the new /en/path/page urls but I'm having trouble getting this to work.
This is what I currently have;
RewriteCond %{REQUEST_URI} !^/en$
RewriteRule ^(.*)$ /en/$1 [R=301,L]
Which I think is meant to check the requested URI and if it doesn't begin with /en then prepend /en onto the requested URI... but I'm obviously mistaken since it doesn't work.
Any help appreciated. Thank you.
UPDATE.
Since this is an ExpressionEngine site and there is an additional rule to remove the index.php portion of the URL here are both rules
# Rewrite for new language based urls
# This is to try and get all current pages going to /en/(old url) with a 301 redirect
RewriteCond %{REQUEST_URI} !^/en(/.*)?$
RewriteRule ^(.*)$ /en/$1 [R=301,L]
# Removes index.php
RewriteCond $1 !\.(gif|jpe?g|png|ico)$ [NC]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /index.php/$1 [L]
I have also tried this with the language rewrite after the index.php one. I'm still getting stuck in loops.
What it does is, checking whether the URI is not exactly /en, since the $ indicates the end of the string right after en.
Try this, it checks whether the URI is not exactly /en or /en/ or doesn't start with /en/, and if that's the case it will prepend /en/:
RewriteCond %{REQUEST_URI} !^/en(/.*)?$
RewriteRule ^(.*)$ /en/$1 [R=301,L]
update Considering the other rules you have in your .htaccess file, it is necessary to have the language rule not match again for the following internal redirect to /index.php..., otherwise you'll end up with an endless loop.
There may be better ways to prevent this, however the first thing that comes to my mind would be checking for index.php in the first condition:
RewriteCond %{REQUEST_URI} !^/(index\.php|en)(/.*)?$
So this will cause the rule not to apply after the internal redirect. But be careful, this solves the problem for this specific case only in which the internal redirect goes to index.php!

Htaccess single page redirect problems

I'm having some issues setting up single page redirects using htaccess. Currently I have a htaccess file with:
RewriteCond %{SCRIPT_FILENAME} !-s
RewriteRule (.*) index.php?path=$1 [QSA,L]
Then a set of redirects e.g.
Redirect 301 /oldpage.htm http://www.mydomain.com/new-page
But the problem I am having is that when I go into a browser and type in the old URL, I get redirected to URL with a parameter attached, e.g:
"http://www.mydomain.com/new-page?path=oldpage.htm"
For some of my redirects this seems to work anyway, for some it produces a 404 error. I've also tried using RewriteCond and Rewrite Rule to write more generic catch all redirects for those pages that I can, and I'm having the same issue.
I'm thinking that some other rule must be interfering with my redirects - the only one I can see which might do so is the rule above, but if that was the case shouldn't the URL I am redirected to end up being
"http://www.mydomain.com/index.php?path=oldpage.htm"
Can anyone explain why parameters are being appended to the URLs and how I can stop this happening so that my redirects work?
Cheers!
This is because mod_alias (the Redirect directive) and mod_rewrite (the Rewrite* directives) are both being applied to the same URI in the URL-file mapping processing pipeline. In order to keep this from happening, you need to stick with one or the other in this case.
You also want the redirect to get applied first:
RewriteRule ^/?oldpage.htm$ http://www.mydomain.com/new-page [L,R=301]
RewriteCond %{SCRIPT_FILENAME} !-s
RewriteRule (.*) index.php?path=$1 [QSA,L]
Your index.php rule is going to catch all requests that aren't CGI scripts that are symlinks, so, pretty much everything if that's really your intention. Otherwise you can let legit requests get by unscathed by including:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
Above the last rule.
because your $1 in rewrite rule
RewriteRule (.*) index.php [QSA,L] try this

Resources