i am trying to use .htaccess file in my project but when i add my htaccess its giving me 500 internal server error this is my htaccess file
RewriteEngine On
RewriteRule ^abc?$ index.php
RewriteRule ^index/2/([a-z0-9]+) index.php?folder=aboutus&file=$1
RewriteRule ^index/3/([a-z0-9]+)
index.php?folder=blog&file=$1
RewriteRule ^index/4/([a-z0-9]+) index.php?folder=contactus&file=$1
RewriteRule ^index/5/([a-z0-9]+) index.php?folder=courses&file=$1
RewriteRule ^index/6/([a-z0-9]+) index.php?folder=gallery&file=$1
RewriteRule ^index/7/([a-z0-9]+)
index.php?folder=home&file=$1
RewriteRule ^index/8/([a-z0-9]+) index.php?folder=courses&file=$1
RewriteRule ^index/9/([a-z0-9]+) index.php?folder=login&file=$1
RewriteRule ^index/3/([a-z0-9]+)
index.php?folder=blog&file=$1
If your file is really formatted like this, ie. splitting directives on two lines, then this will certainly result in a 500 Internal Server Error, as it is syntactically invalid.
Whenever you get a 500 Error then you need to check your server's error log for the specifics of the error. In the case of the above then you will get something like: RewriteRule: bad argument line.
The above should be formatted like all your other directives, on one line:
RewriteRule ^index/3/([a-z0-9]+) index.php?folder=blog&file=$1
Aside: Since you are rewriting a URL that simply omits the file extension (ie. .php) that would otherwise directly map to a filesystem file then you should make sure that MultiViews is disabled, otherwise you can get unexpected conflicts. In other words, add the following directive to the top of your .htaccess file:
Options -MultiViews
Related
Aapche2 htaccess RewriteCond
i found some wondering Condition that works , but i dont know why :)
Files
/error.php
/donate.php
/test/index.php
in a htaccess file i use
ErrorDocument 404 /error.php
RewriteEngine On
# WHY THIS LINE NEEDED TO GET IT WORKS
RewriteCond %{REQUEST_FILENAME} ^$
#
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule (.*) $1.php [L]
this .
http://localhost/donate calls internal http://localhost/donate.php
while
http://localhost/donate1 calls internal http://localhost/error.php
and
http://localhost/test/ call internal http://localhost/test/index.php
so far so good
but when i comment it out
#RewriteCond %{REQUEST_FILENAME} ^$
then i get internal server error while call
/donate1 and not the /error.php
can someone explain the steps , why this happens ?
#RewriteCond %{REQUEST_FILENAME} ^$
Because your directives are not actually doing what you think they are doing. In fact, with that "hacky" condition uncommented they are not doing anything at all, except to prevent the 500 Internal Server Error (which is due to an internal rewrite loop because the rule is strictly incorrect).
That condition checks if the REQUEST_FILENAME server variable is empty. It is never empty, so always fails, so the RewriteRule directive that follows is never triggered.
You could remove your mod_rewrite directives entirely and you'll get the same results.
http://localhost/donate calls internal http://localhost/donate.php
It's most probably MultiViews (mod_negotiation) that is rewriting /donate to /donate.php. Not the directives you posted (which, as I mentioned, don't actually do anything).
http://localhost/test/ call internal http://localhost/test/index.php
This is caused by mod_dir (DirectoryIndex). Again, nothing to do with the directives you posted.
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule (.*) $1.php [L]
then i get internal server error while call /donate1 and not the /error.php
Because when you request /donate1 the above directives trigger an internal rewrite loop (which results in a 500 Internal Server Error response). /donate1 to /donate1.php to /donate1.php.php to /donate1.php.php.php etc. (see below).
MultiViews does not apply here because there is no file that /donate1 can perceivably map to, eg. /donate1.php or /donate1.html or some other recognised resource, with a different file extension, that returns a text/html mime-type.
When you request /donate1 the following happens.
/donate1 does not map to a directory (1st condition) or a file (2nd condition) so is internally rewritten by this rule to donate1.php. Which is incorrect (but that is what this rule does).
The L flag then causes the current round of processing to stop and the rewrite engine starts over, passing the rewritten URL, ie. donate1.php back into the mix.
/donate1.php does not map to a directory or file so is rewritten to donate1.php.php.
The rewrite engine starts over...
/donate1.php.php does not map to a directory or file so is rewritten to donate1.php.php.php.
The rewrite engine starts over...
etc.
This repeats until 10 (default) internal rewrites are reached and the server "breaks" with a 500 error response. The server error log would contain the details of this error, for example:
AH00124: Request exceeded the limit of 10 internal redirects due to probable configuration error. Use 'LimitInternalRecursion' to increase the limit if necessary. Use 'LogLevel debug' to get a backtrace.
(Although very rarely would you ever need to change this internal redirect limit - it nearly always indicates an error in your script.)
Solution
You either remove your mod_rewrite directives entirely and just let MultiViews do its thing, OR you disable MultiViews and "correct" your mod_rewrite directives.
For example:
Options -MultiViews
ErrorDocument 404 /error.php
RewriteEngine On
# Rewrite extensionless URLs to ".php" if they exist
RewriteCond %{DOCUMENT_ROOT}/$1.php -f
RewriteRule (.+) $1.php [L]
An optimisation... if your URLs (that map to .php files) don't contain dots then you could simply exclude URLs that contain dots so you don't unnecessarily test requests for your static resources (eg. image.jpg, styles.css, etc.) that already include a file extension (which naturally contain a dot before the file extension):
RewriteRule ([^.]+) $1.php [L]
Reference:
https://httpd.apache.org/docs/2.4/content-negotiation.html
I am trying to use .htaccess to redirect all url requests of a certain subpath ("URL/somefolders/main/..") to one basefile named "_index.php". So I implemented the following .htaccess to the "folder" URL/somefolders/main/ :
<IfModule mod_rewrite.c>
DirectoryIndex index.php
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([^?]*)$ /main/_index.php?oldpath=$1 [NC,L,QSA]
</IfModule>
The redirection works fine for all non-existant files, but if the file exists then it is called without redirection. I suppose this is because I ordered to do so by the "!" in the RewriteCond, but all my tries to change it failed.
How do I have to change the above code to redirect all files (existant or not) ?
Edit:
All my tries still end up uneffective or erroneous.
The latter with the Apache log error:
Request exceeded the limit of 10 internal redirects due to probable configuration error. Use 'LimitInternalRecursion' to increase the limit if necessary. Use 'LogLevel debug' to get a backtrace.
Currently I fear that in fact I did correctly allow non-existant files in most of my before tries but get me a problem with an endless loop due to included files - is this possible? And if so can the .htaccess distinguish between "internal" and "external" file requests?
Your original rules are the most common implementation you'll see, where REQUEST_FILENAME is checked for existing files or directories to prevent things like CSS and images from being rewritten. But that's not what you want.
So you correctly attempted to remove the RewriteCond directives but ended up with an infinite rewrite loop. That is likely because the subsequent RewriteRule is also attempting to rewrite _index.php back to itself.
You can fix that by adding a RewriteCond which specifically matches _index.php to prevent it from looping on itself.
<IfModule mod_rewrite.c>
DirectoryIndex index.php
RewriteEngine on
# Don't apply the rewrite to _index.php to prevent looping
RewriteCond %{REQUEST_URI} !main/_index\.php
RewriteRule ^([^?]*)$ /main/_index.php?oldpath=$1 [NC,L,QSA]
</IfModule>
I'll also simplify the matched group in RewriteRule. ([^?]*) captures everything up to the first ?, but the expression received by RewriteRule will never include the query string or ? anyway. You may instead simply use (.*) to capture whatever is present.
RewriteRule (.*) /main/_index.php?oldpath=$1 [NC,L,QSA]
I've zeroed my problem and I've specific question.
With only the following code in the .httaccess why index2.php gets called if I type in my URL as www.mysite.com/url2 ?
RewriteEngine On
RewriteCond %{REQUEST_URI} (.html|.htm|.feed|.pdf|.raw)$ [NC]
RewriteRule (.*) index2.php [L]
I've also tested it at http://www.regextester.com and should not replace it with index2.php:
In the end I want this rule to skip any URL starting with /url2 or /url2/*.
EDIT: I've made screen recording of this problem: http://screenr.com/BBBN
You have this in your .htaccess:
RewriteEngine On
RewriteCond %{REQUEST_URI} (.html|.htm|.feed|.pdf|.raw)$ [NC]
RewriteRule (.*) index2.php [L]
What it does? it rewrites anything that ends with html, htm, feed , pdf , raw to index2.php. So, if you are getting results as your URL is ends with those extensions, then there are two possible answers:
There is another rewrite rule in an .htaccess in upper directories (or in server config files) that causes the URL to be rewritten.
Your URL actually ends with those extensions. have in mind, what you enter in your address bar, will be edited and rewritten. For example, if you enter www.mysite.com/url2 in your address bar and that file doesn't exist on server, your server will try to load the proper error document. So, if your error document is /404.html, it will be rewritten to index2.php at the end.
Update:
I think it's the case. create a file named 404.php in your document root. Inside your main .htaccess (in your document root), put this:
ErrorDocument 404 /404.php
delete all other ErrorDocument directives.
inside 404.php , put this:
<?php
echo 'From 404.php file';
?>
Logic behind it:
When you have a weird behavior in mod_rewrite, the best solution in my experience is using rewrite log. to enable rewrite log put this in your virtualhost or other server config directives you may choose:
RewriteLogLevel 9
RewriteLog "logs/RewriteLog.log"
be careful: the code above will enable rewrite log and start logging at highest level possible (logging everything). It will decrease your server speed and the log file will become huge very quickly. Do this only on your dev server.
Explanation: When you try to access www.mysite.com/url2, Apache gives your URL to rewrite module. Rewrite module checks if any of RewriteRules applies to your URL. Because you have one rule and it doesn't apply to your URL, it tries to load the normal file. But this file does not exit. So, Apache will do the next step which is showing the proper error message. When you set a custom error file, Apache will run the test against the new address. For example if error document is /404.html, Apache checks whether your rule applies to /404.html or not. Since it does, it will rewrite it.
The point to remember is apache will do this every time there is change in URL, whether the change is made by rewrite module or not!
The rule you list should work as you expect if this is the only rule. Fact is that theory is fun, but apparently it doesn't work as expected. Please note that . will match ANY CHARACTER. If you want to match the full stop/period character, you'll need to escape it. That's why I use \.(html|htm|feed|pdf|raw)$ instead of (.html|.htm|.feed|.pdf|.raw)$ below.
You can add another RewriteCond that simply doesn't match if the url starts with /url2, like below. This might not be a viable solution if there are lots of urls that shouldn't be matched.
RewriteCond %{REQUEST_URI} !^/url2
RewriteCond %{REQUEST_URI} \.(html|htm|feed|pdf|raw)$ [NC]
RewriteRule (.*) index2.php [L]
To get a better understanding of what is happening you can alter the rule to something like this. Now simply enter the urls you dont want to be matched in the url bar and inspect the url bar after the redirect happens. In the url-parameter you now see what url actually triggered this rule to match. This screencast shows you a similar version working with a sneaky rewriterule that is working away on the url.
#A way of finding out what is -actually- matched
RewriteCond %{REQUEST_URI} \.(html|htm|feed|pdf|raw)$ [NC]
RewriteCond %{REQUEST_URI} !/foo
RewriteRule (.*) /foo?url=$1 [R,L]
You can decide to match the %{THE_REQUEST} variable instead. This will always contain the request itself. If something else is rewriting the url, this variable doesn't change, meaning you can use this to overwrite any changes. Make sure the url won't be matching itself. You would get something like below. An example screencast can be found here.
#If it doesn't end on .html/htm/feed etc, this one won't match
RewriteCond %{THE_REQUEST} ^(GET|POST)\ /.*\.(html|htm|feed|pdf|raw)\ HTTP [NC]
RewriteCond %{REQUEST_URI} !^/index2\.php$
RewriteRule (.*) /index2.php [L]
Can't find this for the life of me. We have the indexes protected so if someone goes to CDNdomain.com/1/ they won't see anything unless they do CDNdomain.com/1/something.jpg. When they visit /1/ they are presented with a 403 Forbidden error. What I would like to do is when they are shown a 403 Forbidden error to instead redirect them to ourRealdomain.com.
Any ideas?
You can try something like this in the htaccess file in the document root of CDNdomain.com:
RewriteEngine On
# make sure this is the right host
RewriteCond %{HTTP_HOST} cdndomain.com$ [NC]
# make sure this is a request for an existing directory
RewriteCond %{REQUEST_FILENAME} -d
# redirect
RewriteRule ^(.*)$ http://ourRealdomain.com/ [L,R=301]
Note that this will also redirect /: http://CDNdomain.com/ to http://ourRealdomain.com/. If you want to avoid that, change the regex match from ^(.*)$ to ^(.+)$. If you want to put these rules in the vhost config for the CDNdomain.com, add a slash after the ^: ^/(.+)$.
The commented out google redirect is working but the rest of the rules dont work at all.
it automatically gives me a 500 internal server error. This only happens on the 1and1 server.
RewriteEngine On
Options FollowSymLinks
# RewriteRule ^(.*)$ http://www.google.com/$1 [r=301,nc]
RewriteRule ^(ajax)/([a-zA-Z0-9-z\-]+)$ http://mysite.com/index.php?ajax=$2 [r=301,nc]
RewriteRule ^([a-zA-Z0-9-z\-]+)/([a-zA-Z0-9-z\-]+)$ http://mysite.com/index.php?page=$1&subPage=$2
RewriteRule ^([a-zA-Z0-9-z\-]+)/([a-zA-Z0-9-z\-]+)/$ http://mysite.com/index.php?page=$1&subPage=$2
RewriteRule ^repairs/([a-zA-Z0-9-z\-]+)/([a-zA-Z0-9-z\-]*)$ http://mysite.com/repairs-engine.php?page=repairs&subPage=$1&pitem=$2
RewriteRule ^([a-zA-Z0-9-z\-]+)$ http://mysite.com/index.php?page=$1
RewriteRule ^([a-zA-Z0-9-z\-]+)/$ http://mysite.com/index.php?page=$1
Any thoughts?
Thanks
For exact error description you should check the Apache's error log.
What this pattern supposed to mean [a-zA-Z0-9-z\-] ?? It is definitely wrong. It should be [a-zA-Z0-9\-] -- I'm pretty sure that this is the reason for error.
NOTES:
If using [NC] flag, then no need to have a-zA-Z -- just a-z will be enough.
If doing rewrite (internal redirect, when URL changes in browser's address bar) and not proper redirect (301, 302 etc), then no need to use full domain name.
In any case, I suggest adding [L] flag to all rules -- it will speed up processing by tiny bit.
have you tried not to escape the last dash in the char class block?
like this:
^([a-zA-Z0-9-]+)$