Forum Moderators: phranque
I've made it pretty basic for testing and the pages open as they should, without the redirects:
D:\Website\www
D:\Website\www\.htaccess
D:\Website\www\index.html
D:\Website\www\cgi-bin
D:\Website\www\cgi-bin\index.cgi
.htaccess:
-----------------------
Options +FollowSymLinks
RewriteEngine On
#The following were used for trial and error testing
#Options All Indexes
#IndexOptions FancyIndexing
#RewriteBase /
#RewriteRule ^(.*)$ /cgi-bin/index.cgi [L]
-----------------------
So if I uncomment the RewriteRule, all hell breaks loose. I get the following error message in my error log:
Options FollowSymLinks or SymLinksIfOwnerMatch is off which implies that RewriteRule directive is forbidden
And the browser displays a 403 Forbidden, with this message:
You don't have permission to access /cgi-bin/index.cgi on this server.
So it looks like it's being read, but just can't go there. There's no .htaccess in cgi-bin blocking users. Note, I've also tried it with RewriteMatch and other sorts (RewriteCond), to no success.
All file and folder permissions are set up as they should be, after all without the .htacess I can access each file correctly. For reference, here's the server config file.
httpd.conf:
-----------------------
ServerRoot "D:/Program Files/Apache Software Foundation/Apache2.2"
Listen 80
LoadModule actions_module modules/mod_actions.so
LoadModule alias_module modules/mod_alias.so
LoadModule asis_module modules/mod_asis.so
LoadModule auth_basic_module modules/mod_auth_basic.so
LoadModule authn_default_module modules/mod_authn_default.so
LoadModule authn_file_module modules/mod_authn_file.so
LoadModule authz_default_module modules/mod_authz_default.so
LoadModule authz_groupfile_module modules/mod_authz_groupfile.so
LoadModule authz_host_module modules/mod_authz_host.so
LoadModule authz_user_module modules/mod_authz_user.so
LoadModule autoindex_module modules/mod_autoindex.so
LoadModule cgi_module modules/mod_cgi.so
LoadModule deflate_module modules/mod_deflate.so
LoadModule dir_module modules/mod_dir.so
LoadModule env_module modules/mod_env.so
LoadModule expires_module modules/mod_expires.so
LoadModule include_module modules/mod_include.so
LoadModule isapi_module modules/mod_isapi.so
LoadModule log_config_module modules/mod_log_config.so
LoadModule mime_module modules/mod_mime.so
LoadModule negotiation_module modules/mod_negotiation.so
LoadModule rewrite_module modules/mod_rewrite.so
LoadModule setenvif_module modules/mod_setenvif.so
<IfModule !mpm_netware_module>
<IfModule !mpm_winnt_module>
User daemon
Group daemon
</IfModule>
</IfModule>
ServerAdmin myemail@website.com
ServerName localhost:80
DocumentRoot "D:/Website/www"
AccessFIleName ht .acl .htaccess
<Directory />
Options FollowSymLinks
AllowOverride None
Order deny,allow
Deny from all
</Directory>
<Directory "D:/Website/www">
#Options Indexes FollowSymLinks MultiViews Includes ExecCGI
#AllowOverride None
Options Indexes FollowSymLinks
AllowOverride All
Order allow,deny
Allow from all
</Directory>
<IfModule dir_module>
DirectoryIndex index.html
</IfModule>
<FilesMatch "^\.ht">
Order allow,deny
Deny from all
Satisfy All
</FilesMatch>
ErrorLog "logs/error.log"
LogLevel warn
<IfModule log_config_module>
LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined
LogFormat "%h %l %u %t \"%r\" %>s %b" common
<IfModule logio_module>
LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\" %I %O" combinedio
</IfModule>
CustomLog "logs/access.log" common
</IfModule>
<IfModule alias_module>
#ScriptAlias /cgi-bin/ "D:/Program Files/Apache Software Foundation/Apache2.2/cgi-bin/"
ScriptAlias /cgi-bin/ "D:/Website/www/cgi-bin/"
</IfModule>
<IfModule cgid_module>
</IfModule>
<Directory "D:/Website/www/cgi-bin">
#AllowOverride All
#Options All FollowSymLinks
AllowOverride None
Options None
Order allow,deny
Allow from all
</Directory>
DefaultType text/plain
<IfModule mime_module>
TypesConfig conf/mime.types
AddType application/x-compress .Z
AddType application/x-gzip .gz .tgz
</IfModule>
<IfModule ssl_module>
SSLRandomSeed startup builtin
SSLRandomSeed connect builtin
</IfModule>
-----------------------
Basically the default with my path changes and some modules uncommented (deflate and rewrite).
I appreciate any help you can give me,
vol7ron
You'll also want to check your directory and file permissions if you have any further 'permission' problems, as these can be "non-intuitive" when trying to use Apache on Windows.
Also, please note that this is not instant messaging. We have a very small number of contributors here, and if you ask someone to review your entire httpd.conf file, then it may be awhile before someone has the time to do so (in any studious, useful manner). Also, those contributors are all over the world, and may not even wake up until ten hours after you post... :)
Jim
Unfortunately, as you can see, I've tried AllowOverride All (instead of None) in the httpd.conf. I believe I tried it for <Directory /> as well, but I didn't keep it commented in. As I recall the Options statement is not default for the <Directory />. Anyhow, this .htaccess is in the root directory (/www/) so I'm not sure I even need to mess with anything in <Directory /> or <Directory /cgi-bin/>
I know it might have seemed like a lot to read, but it really wasn't, just a few descriptional lines - the config file took up the majority and I took out all the commented lines (besides what I've tested). As I said, it works w/o the rewrite, so I'd think that permissions are fine; when in doubt, setting it to 775 should cause no errors (XP or Linux).
I totally forgot about the other side of the world :) I wasn't trying to be rude about the PM, it's just that this is a more technical question and I tried looking at another forum, but when in doubt stick to WebmasterWorld. Other people seem to get similar error messages, but their problems seem to be with mod_perl, so I don't know what I'm missing. Since this was more technical, I was curious if someone knows of an Apache specific user community that might know. I might check out the IRC room later.
It's a fresh install of Windows and I sure appreciate the help!
vol7ron
If the request does go to a named <Directory> path and AllowOverride Options isn't set for that path, then again, your Options setting in .htaccess will be irrelevant.
The server has told you what is wrong, and fairly precisely... It's a hierarchical thing, with httpd.conf (and any other server config files) at the top, and .htaccess files at the bottom. Somewhere, something is turning off the FollowSymLinks option, or setting AllowOverride to disallow Options in .htaccess, or not enabling AllowOverride to allow Options +FollowSymLinks (or +SymLinksIfOwnerMatch) in .htaccess; The error message is explicit.
As for the scripts working when invoked by direct URL, I did say that permissions on Windows were "weird." :)
The easiest way to proceed may be to remove all restrictive access controls and permissions settings and then explicitly set AllowOverride to allow Options (and other overrides such as FileInfo needed by other modules), and then prove to yourself that the server "works." Then you can revert to the more-secure default config and set the overrides and options to the most restrictive setting that will still work, using the knowledge gained in the process.
Jim
I'm trying to mirror the Linux machine, so I don't want to change too many things in .htaccess . That being said, I'm still unsure of what to try, I'm open to suggestions and will try everything again. My first thought was that it's Windows and Windows doesn't typically have symbolic links, however, I do have Junctions, so it might treat the same way -- I'm not using Junctions in this setup, yet.
Permissions don't affect anything, I've set them to 777 (the Windows equivalent).
AllowOverride will default to "None" if not otherwise specified. So if your request doesn't go to a directory-path named in one of the <Directory> containers enclosing an "AllowOverride All" or "AllowOverride Options" directive, then your Options setting in .htaccess will be irrelevant.If the request does go to a named <Directory> path and AllowOverride Options isn't set for that path, then again, your Options setting in .htaccess will be irrelevant.
Is that unclear?
Jim
I cannot navigate to [localhost...] when the following setting is turned on:
/www/.htaccess - RewriteEngine On
I tested this yesterday in IE and FF, they must have just been stored in the cache. I can hardcode the address in the browser with FollowSymLinks on and if I comment out that setting above (with all RewriteRules commented out).
This is something I'm going to look into, since mod_rewrite should be installed (it comes with apache) and I uncommented the line to include it in the directive.
No that's not unclear, however you were talking about how "The error message is explicit." Indeed it is a little more than other programs, but it is not explicit. If anything, it is misleading. I would consider explicit to tell me what line/condition is causing the problem and how it can be fixed. This does neither, it is better than "Server Error" and less vague than "500 - Internal Server Error" or 403, or whatever; but it is still ambiguous.
So I was confused on why this error would be popping up if I had set Option to All and Override to All.
-------------------------
I should also explain that yes, I feel I have a better understanding than most about these settings. I also understand that there are other ways of doing this; however, I'm trying to mirror the online web host -- I don't have access to the httpd.conf there, so changes to local machine should reflect those I have control of on the web.
The hardcode was working yesterday because I had
<Directory "D:/Website/www/cgi-bin">
[...]
Options All
AllowOverride All
I set that again and again the error only comes when I uncomment the RewriteRule.... sigh
Oddly enough there is a new error description that I didn't see yesterday, so I must have changed something today:
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.
I'm not sure what's causing the loop, my paths point to the correct directories and this is a basic RewriteRule that I've used before. Again, thank you for your help.
RewriteCond $1 !^cgi-bin/index\.cgi$
RewriteRule ^(.*)$ /cgi-bin/index.cgi [L]
Jim
I still don't understand how the infinite loop is created.
.* = anything/everything « got that
So let's say I enter [localhost...] -or- [localhost,...] I would think it would go to [localhost...] ~ Oh wait, you're saying it does get there and when it does it re-runs the .htaccess in the root directory and sees [localhost...] - the bold is now the (.*), causing the loop.
If that's the case, a little more advanced question is, would that still occur if cgi-bin was not in a subdirectory of the root. Is it calling the RewriteRule (the recursion) based on the filesystem, or based on the webaddress? (ask if that's unclear)
So you know, I'm not going to use the (.*). I used it because in the Perl RegEx world it is the easiest pattern to match ~ I didn't think it'd cause a problem here - another thing learned, that I'll probably forget again, once things are set up.
Super happy,
vol7ron
jdMorgan++
Only after a complete pass through all the rules in the file, with no further rewrites being applied, is the resulting "action" actually taken.
So, basically if you rewrite "anything" to "something," but "something" still matches the pattern for "anything," then the rule will effectively "just sit there and loop."
This description is of course greatly over-simplified, but it serves our purpose: The solution is to rewrite "anything except "something" to "something," which explicitly prevents the loop. And this exactly describes the coded solution I presented above: "Rewrite anything except /cgi-bin/index.cgi to /cgi-bin/index.cgi
This problem would occur regardless of where this .htaccess file was located, if the 'target' path traversed through the directory in which the .htaccess file was located. It would not occur if this code were to be modified for use in a server configuration file such as httpd.conf, because the described re-processing does not occur (it's not needed in that context).
[is the recursion] based on the filesystem ["filepath"] or on the Webaddress ["URL-path"]?
That's a good question, and although there is probably a more-accurate answer if you want to dig into the code and use the more-detailed-and-correct descriptive terms, I will simply say "neither" -- in that after the first rewrite is applied, the "path" exists as a sort of quasi-filepath and as a quasi-URL which must be converted (as a last step after all recursion ends) into one or the other, as specified by the rule's syntax (rewrite, redirect, or proxy through-put). Remember that mod_rewrite's "job" is to participate in the URL-to-filepath translation function of the server, or to generate redirects or proxy through-puts based on the "path", so it "sits right at the border" between URL-paths and filepaths.
I have a bit of a reputation as a devoted "hater" of the ".*" pattern. It is "easy" -- But it's also ambiguous, primiscuous, and --in cases where it is used multiple times within a pattern-- very inefficient. Its use often leads to "unpleasant surprises," as it did here. Therefore, to paraphrase a very famous physicist named Albert, it's a good idea to make your regex patterns as specific as possible, but no more so.
If you think you'll "forget all this," then do the right thing: Document it thoroughly. You may well be very grateful to yourself later. ;)
Jim
[is the recursion] based on the filesystem ["filepath"] ["physical path"] or on the Webaddress ["URL-path"]["logical URL path"]?
I get the fact that it was not actually reached, I was implying that the path was going to be followed, but it just didn't get there because of the recursive loop. The URL was reading correct:
Step 1 : http://localhost/ -> \www\.htaccess
Step 2 : http://localhost/cgi-bin/index.cgi -> \www\.htaccess
Step 3 : ... same as step 2 ...
...
Step n : ... same as step 2 ... -whereas what i wanted was-
Step 1 : http://localhost/ -> \www\.htaccess
Step 2 : http://localhost/cgi-bin/index.cgi -> \www\.htaccess
Step 3 : http://localhost/cgi-bin/index.cgi -> \www\cgi-bin\.htaccess
It was never getting past the \www\.htaccess is what I was saying, however the path would have been followed if it didn't reach that infinite loop.
-------
Generally, .htaccess is one of those things that doesn't change once set up. The Rewrite[Cond/Rule]s are generally easy to remember, but over time the server processing might be one of those things that you forget about. It's a set it and forget it kinda thing :)
I tried to use your Rewrite[Cond/Rule] above, but it didn't work. However, all the ones I need for my site are working correctly.
Thank you again for all your help.
I think the most beneficial advice was, the reaffirmation to keep the AllowOverride and to make sure the .htaccess is correct.
Thx,
vol7ron
[edited by: vol7ron at 3:39 am (utc) on Sep. 11, 2009]
RewriteRule ^$ /cgi-bin/index.cgi [L]
DirectoryIndex /cgi-bin/index.cgi
However, this DirectoryIndex will apply to requests for the index of *any* subdirectory level, unless overridden by another directive in each of those subdirectories, so in this form, it is more-precisely equivalent to
RewriteRule ([^/]+/)*$ /cgi-bin/index.cgi [L]