Hi.

It is quite certain that the basic reason for my troubles is my own lack of expertise, but I suppose that others may stumble into the same issue at some point, and this may help them avoid the loss of time involved.

Basically, I had an Apache (2.2) configuration section as follows :

<Location /login>
  PerlAccessHandler my::module->access
  PerlFixupHandler my::module->fixup
  SetHandler modperl
  PerlResponseHandler my::module->login
  PerlSetVar my_login_form "/login.html"
</Location>

As you can probably guess, this is part of a self-written authentication mechanism derived from Apache::AuthCookie, and the login form that is used is the document at (DocumentRoot)/login.html.

Now this has worked fine on dozens of servers so far, for several years.

But then unexpectedly on this new similar webserver that I just set up, it didn't work anymore, in a quite peculiar way :

- the above PerlAccessHandler was run fine, and logged everything as normally
- but neither the PerlFixupHandler nor the PerlResponseHandler were being run, without any error or trace at all in the logs. Instead, all I got was the login document in the browser, but in a way that showed that it was delivered straight from the disk, without going through the response-handler at all (which it normally does).

It was also quite puzzling because how could it respond with "/login.html" when I requested "/login", and how could it nevertheless show a POST to "/login", with a response code 200 OK in the access log. Did Apache somehow start behaving like hateful end-user software, divining what was good for me, instead of what I explicitly said I wanted ?

To make a long story shorter (by 2 days), I finally realised that it was because in this particular server, there was a unique coincidence of two elements :

- the DocumentRoot directory of the server had a "Options MultiViews" added to 
it
- my login document was "/login.html"

And why the problem happened was this stanza in the Apache on-line documentation of the Options directive (and/or mod_negociation) :

quote

MultiViews

A MultiViews search is enabled by the MultiViews Options. If the server receives a request for /some/dir/foo and /some/dir/foo does not exist, then the server reads the directory looking for all files named foo.*, and effectively fakes up a type map which names all those files, assigning them the same media types and content-encodings it would have if the client had asked for one of them by name. It then chooses the best match to the client's..

unquote

So what happened here was :
- the PerlAccessHandler was run normally, as it happens quite early in the Apache cycle, before Apache even starts to map the URL to a file on disk
- then somewhere mod_negociation takes over.
It looks at the requested URL (/login), and does not find a corresponding directory "(DocumentRoot)/login".
So then, it looks in the directory "/", trying to find anything that looks like 
"login.*".
In this case, it finds "/login.html".
So it sets things up to return "/login.html" as the response. Predictable and fair enough, one could say. Except that in the process it *disables* the other configuration lines which should have invoked the fixup handler and mod_perl as the response handler, and these are never run.
Instead, it seemingly runs the Apache default handler, which just returns the 
file.

Removing the MultiViews option made things get back to normal.
Changing the name of the login form to something not matching "/login" so closely also does the trick.

But it took me close to two days to figure this out, mainly because I have dozens of other servers which have exactly the same <Location> section and are doing fine, and I just never realised that this MultiViews Option, inherited from way back up there in the configuration, could have such a drastic effect.

HTH someone some day.







Reply via email to