With the current htaccess, my site doesn't work and I get "Internal Server Error":
RewriteEngine on
# Disable Directory Browsing
# Options All -Indexes
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php?/$1 [L]
This is solved by deleting these lines from the syntax:
# Disable Directory Browsing
# Options All -Indexes
As you notice, they are already commented, so deleting them should not make any difference, then why it does matter?
[Tue Jan 05 09:06:42 2016] [alert] [client 5.28.177.182] /home/my_account/my_site/.htaccess: RewriteEngine must be On or Off
The value passed to RewriteEngine is not case-sensitive, so on (as in your code) and On should both work OK. It would seem the parser is reading something different to what we are seeing as the code you have posted should not result in this error.
It is possible that there are some strange/hidden characters or possibly corrupt line endings resulting in this error. Try retyping it, creating a new document (or exposing hidden characters in your editor)?
Related
Context
I'm using mod_rewrite to make my links better for SEO. I made the following rule for my page expanded_debate.php:
Options -MultiViews
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}\.php -f
RewriteRule ^poll/([0-9a-zA-Z_-]+)/([0-9]+) expanded_debate.php?poll_title=$1&pollid=$2 [NC,QSA,L]
When I input this format in the URL (poll/filename/10, for example) I get a 404 error:
Object not found!
The requested URL was not found on this server. If you entered the URL manually please check your spelling and try again.
If you think this is a server error, please contact the webmaster.
Error 404
localhost
Apache/2.4.46 (Unix) OpenSSL/1.1.1h PHP/7.4.12 mod_perl/2.0.11 Perl/v5.32.0
However, when I change the first folder name to certain words, such as "debate" and "expanded_debate" (but not "expandedebate"), the file loads after page refresh. For example:
RewriteRule ^debate/([0-9a-zA-Z_-]+)/([0-9]+) expanded_debate.php?poll_title=$1&pollid=$2 [NC,QSA,L]
works fine.
I have an older .htaccess file, titled ".htaccess11", with the following info, in case it's of any use:
#forbids users from going to forbidden pages
IndexIgnore *
Options -Indexes
RewriteEngine On
RewriteCond %{SERVER_PORT} !^443$
RewriteCond %{REQUEST_URI} !^/\.well-known/acme-challenge/[0-9a-zA-Z_-]+$
RewriteCond %{REQUEST_URI} !^/\.well-known/cpanel-dcv/[0-9a-zA-Z_-]+$
RewriteCond %{REQUEST_URI} !^/\.well-known/pki-validation/(?:\ Ballot169)?
RewriteCond %{REQUEST_URI} !^/\.well-known/pki-validation/[A-F0-9]{32}\.txt(?:\ Comodo\ DCV)?$
RewriteRule ^(.*)$ https://%{SERVER_NAME}%{REQUEST_URI} [R=301,L]
#404 error directions
ErrorDocument 404 /404.php
Question
Any idea why only certain terms in the first folder position ("^debate" in example above) work when using mod_rewrite?
There are no "poll" folders in my project, if that's of any interest.
Let me know if there are any questions.
The line
RewriteCond %{REQUEST_FILENAME}\.php -f
Means "Take the requested URL, map it to a full local path in the normal way, append .php to the resulting path, and then process the following rewrite rule only if there is an existing regular file at the modified path".
For example, the URL "poll/filename/10" will be rewritten only if there is a file called "poll/filename/10.php" in the relevant location.
Since the value of the AcceptPathInfo directive is evidently set to On, this condition will also be met if there is an existing file called "poll.php" or "poll/filename.php". That is why the rewrite rule works when you change "poll" to "debate" or "expanded_debate" – there are existing files called "debate.php" and "expanded_debate.php".
In any case, it sounds like this behavior is not what was intended. Removing the -f condition should give the desired result. Or, to prevent the rewrite rule from making existing files inaccessible, you could replace it with:
RewriteCond %{REQUEST_FILENAME} !-f
The exclamation point negates the -f test: "continue only if this file does not exist"
If you are using the %{REQUEST_FILENAME} server variable (anywhere), you should be aware of how the AcceptPathInfo directive will affect this, and consider setting that directive explicitly in the same .htaccess file.
If Options +MultiViews is in effect, then %{REQUEST_FILENAME} will match existing files whether or not the extension is included in the request (GET /foo will match an existing file "foo.php", "foo.html", etc.). And GET /foo.php will match in any case. So, omit the string "\.php" from the original rule.
Other configuration may also have an effect, too. The important point is that, unlike %{REQUEST_URI}, %{REQUEST_FILENAME} invokes all the processing that Apache would otherwise do to translate a URL into a local path.
(source)
NB: although I don't think it was the intention here, you actually might want to test for the existence of a local file as part of this rule. You could use a RewriteCond to check whether the back-end data file for a given poll has been manually created, and return 404 by default if it has not. That would be a simple way to prevent users from making up their own poll URLs at will.
I have a website which depends on htaccess rewrite rules, i rewrite my URL's with a sequence like this:
www.example.com/games/car/play/123
Actually there is no directories for:
games
car
play
Everyday i see my error log show tons of error line(s) says:
File does not exist: /home/example.com/public_html/games
File does not exist: /home/example.com/public_html/car
File does not exist: /home/example.com/public_html/play
I don't know why Apache consider these fake directories as an actual real directories? i have in my htaccess these lines of rewrite code:
RewriteEngine On
RewriteBase /
RewriteRule ^games/([a-zA-Z0-9-/]+)/play/(.*)$ details.php?slug=$1&id=$2
Now Apache consider: games/slug/play/id as directories and it's not just a fake URL sequence. Also when i go down for lower page:
www.example.com/games/car
And
www.example.com/games
It's already exists as URL but not a directory i see an error log says:
File does not exist: /home/example.com/public_html/games/car
File does not exist: /home/example.com/public_html/games
How i can resolve this issue? I have tried everything poosible but still get tons of lines of errors in my error log.
Many thanks (and sorry for my bad English).
Try turning off MultiViews and also add some condition checks.
Options -MultiViews
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^games/([a-zA-Z0-9-/]+)/play/(.*)$ details.php?slug=$1&id=$2 [L]
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 have a vanilla 2.0.18b2 installation on my webserver in a subfolder. Forum works, but I can't sign in. When I click a link "sign in" the page goes blank. I think that this is a problem with .htaccess file cause I had a working solution but I wanted to change something and broken the file.
Another thing is that, when I am typing forum.mysite.com it says:
Fatal error: Class 'Gdn' not found in /bootstrap.php on line 47
when I type mysite.com/forum it view the website but with no styling, and when I click a link it goes 500 Internal Error.
Only when I type mysite.com/forum/index.php it looks normal.
My .htaccess file looks like that:
# Modified
# If you modify this file then change the above line to: # Modified
<IfModule mod_rewrite.c>
RewriteEngine On
# Certain hosts may require the following line.
# If vanilla is in a subfolder then you need to specify it after the /.
# (ex. You put Vanilla in /forum so change the next line to: RewriteBase /forum)
RewriteBase /forum/
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ index.php\?p=$1 [QSA,L]
#RewriteRule ^$ index.php/$1
</IfModule>
Try clearing the cache by deleting all the files and folders inside the cache folder.
Was facing the exact same problem and clearing the cache solved the issue!
Try changing the RewriteRule to this
RewriteRule ^(.*)$ index.php?p=$1 [QSA,L]
I'm using Iirf v2.0.
I have the following directory structure:
/
/library
/library/index.php
/webroot
/webroot/images
/Iirf.ini
Where I have a library folder which contains my application, a webroot folder (which contains images, stylesheets etc) and an Iirf.ini config file.
I'm wanting to redirect all requests to /library/index.php if the file doesn't exist under webroot.
eg:
Request Response
/images/blah.png -> /webroot/images/blah.png
/news -> /library/index.php
My Iirf.ini config has:
RewriteEngine ON
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ /library/index.php [L]
Which redirects everything to /library/index.php but I'm having trouble working out how to check if the REQUEST_FILENAME exists under webroot.
I've looked at this question but I don't have access to DOCUMENT_ROOT. It gives me the following (taken from the log):
Thu Jul 15 11:46:21 - 760 - ReplaceServerVariables: VariableName='REQUEST_FILENAME' Value='C:\web\favicon.ico'
Thu Jul 15 11:46:21 - 760 - ReplaceServerVariables: in='%{DOCUMENT_ROOT}/webroot/%{REQUEST_FILENAME}' out='DOCUMENT_ROOT/webroot/C:\web\favicon.ico'
Any help would be greatly appreciated.
--- EDIT --
I've updated my config after more reading and the suggestions of Tim to be:
RewriteCond $0 !^/webroot
RewriteRule ^.*$ /webroot$0 [I]
RewriteCond $0 !-f
RewriteRule ^/webroot/(.*)$ /library/index.php [I,L,QSA]
And it passes to /library/index.php correctly but it still doesn't check for an existing file (even though it seems to say that it does).
Thu Jul 15 14:47:30 - 3444 - EvalCondition: checking '/webroot/images/buttons/submit.gif' against pattern '!-f'
Thu Jul 15 14:47:30 - 3444 - EvalCondition: cond->SpecialConditionType= 'f'
Thu Jul 15 14:47:30 - 3444 - EvalCondition: Special: it is not a file
I think I'm going to have to contact the author of the Filter.
Hmm...I hadn't heard about IIRF before, cool stuff. After browsing through the documentation to see what the differences between it and mod_rewrite are, I have two things you could try.
The first is to swap out %{DOCUMENT_ROOT} for %{APPL_PHYSICAL_PATH} in the answer that you found. DOCUMENT_ROOT is an Apache server variable, and from what I can tell the corresponding IIS variable should be APPL_PHYSICAL_PATH. I know based on the IIRF documentation that this variable is available, but admittedly I'm not 100% sure whether or not it points to your site root.
The other is to do the following, which again may or may not work based upon whether I understood the documentation correctly, how your index.php file gets the relevant path information to process the request, and a host of other things. Admittedly I think this is a less than ideal solution (compared to what I had originally thought to do based on how mod_rewrite does things), but maybe it'll work:
RewriteEngine ON
# This should rewrite to /webroot/whatever then restart the ruleset,
# apparently...On Apache in a per-dir context, this would alter the
# %{REQUEST_FILENAME} for the next run-through. I'm assume it does
# here too, but I might be wrong.
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_URI} !^/webroot
RewriteRule ^.*$ /webroot/$0
# The file still doesn't exist, rewrite it back to its original form,
# but move on to the next rule instead of restarting processing. This
# may not even be necessary, but I was hoping this rewrite would have
# side-effects that would make it as if the above rewrite didn't happen.
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(/webroot/)?(.*)$ $0 [NI]
# Now, if it still doesn't exist, we'll rewrite it to our
# /library/index.php file, but this may not work based on how you
# get the original request information. Adding the [U] flag will
# create a new header that preserves the "original" URL (I'm not
# sure what it takes the value from if the URL has already been
# rewritten in a previous step), which might be useful.
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^.*$ /library/index.php
I ended up having to swap to using the Helicon Tech ISAPI_Rewrite 3 filter.
The htaccess file I ended up using was:
RewriteEngine On
# Check whether the file exists and if not, check whether the request starts
# with webroot. Prepend webroot if it doesn't.
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_URI} !^webroot
RewriteRule ^.*$ webroot/$0 [NI]
# Check whether the file exists, if not, send the request off to library/index.php
RewriteCond %{DOCUMENT_ROOT}/$0 !-f
RewriteRule ^(webroot/)?(.*)$ library/index.php [I,L,QSA]