[Sorry for being so verbose, hope somebody still have the time and
patience to read it all].

I have a setup where a PerlTransHandler registers a PerlContentHandler
based simply on whether $r->uri ends with '.html' or not.  The
TransHandler does no verifying of the existence of the file, that
doesn't happen until the ContentHandler kicks in.  For an unsuccessful
'-e' test, NOT_FOUND is returned from the ContentHandler.  All this
worked fine until I added an perl-based handler for the 404 using the
ErrorDocument parameter in httpd.conf[1].

Now, when a request for a non-existent document is sent the httpd
child starts looping, writing file not found errors (for the
ErrorDocument handler) in the log, repeatedly returning the error from
the ErrorDocument handler to the client and hogging memory.

What I get in the error_log is this:

[Thu Sep 28 11:56:24 2000] [error] [client 129.240.148.10] File does not exist: 
/local/www/htdocs/http_error


To me that seems like an indication that the location setup for
/http_err isn't read and the loop follows quite naturally after that.
Still the code is actually run, as seen from the time stamps I've
added to the output (see the example below).  The code for UiO:ErrDoc
is in the bottom of this mail[2].

Another point is that returning NOT_FOUND from the TransHandler does
not yield this problem.  Moving the check to the TransHandler is of
course the logical work around and probably the right way to do it
anyways, but I'd still like to get an explanation for this.

Well, thats about as far as I've gotten tracking this problem; not
very far and I really don't know where to look next.  Any help and/or
hints will be greatly appreciated.


I'll include an example request to fill out any blanks in the above
description:

$ telnet host 80
Trying xxx.xxx.xxx.xxx....
Connected to host.
Escape character is '^]'.
GET /h.html HTTP/1.0

HTTP/1.1 404 Not Found
Date: Thu, 28 Sep 2000 09:56:24 GMT
Server: Apache/1.3.12 (Unix) PHP/3.0.16 mod_perl/1.22
Connection: close
Content-Type: text/plain

404 - Not found

[ ... ]

HTTP/1.1 404 Not Found
Date: Thu, 28 Sep 2000 10:27:19 GMT
Server: Apache/1.3.12 (Unix) PHP/3.0.16 mod_perl/1.22
Connection: close
Content-Type: text/plain

404 - Not found - Thu Sep 28 12:27:21 2000

HTTP/1.1 404 Not Found
Date: Thu, 28 Sep 2000 10:27:19 GMT
Server: Apache/1.3.12 (Unix) PHP/3.0.16 mod_perl/1.22
Connection: close
Content-Type: text/plain

404 - Not found - Thu Sep 28 12:27:22 2000

^]
telnet> close
Connection closed.

After the first burst of about 50-60 repetitions, the output frq drops
but does not seem to stop completely.  The httpd child, using all
available cpu time, gradually increases in size (the largest I've had
before killing it was about 135 MB).


The error_log looks like this, the second line is from the content
handler (UiO::Profile) just before it returns NOT_FOUND.


[Thu Sep 28 11:56:24 2000] [debug] /local/www/site/perl/lib/UHTML/Identifier.pm(21): 
[client 129.240.148.10] Adding UiO::Profile as handler for /local/www/htdocs/h.html
[Thu Sep 28 11:56:24 2000] [error] Document file do not exist: /local/www/htdocs/h.html
[Thu Sep 28 11:56:24 2000] [error] [client 129.240.148.10] File does not exist: 
/local/www/htdocs/http_error
[Thu Sep 28 11:56:24 2000] [error] [client 129.240.148.10] File does not exist: 
/local/www/htdocs/http_error

And so on.



[1]  My setup looks like this:

PerlTransHandler UiO:Identifier

<Location /http_err>
    SetHandler perl-script
    PerlHandler UiO::ErrDoc
</Location>

ErrorDocument 404 /http_err


[2] The code of UiO::ErrDoc:

package UiO::ErrDoc;

use strict;
use Apache::Constants qw(OK);
use vars qw($VERSION $REVISION);

$VERSION = '0.01';
$REVISION = q/$Id$/;

sub handler {
    my $r = shift;
    my %status_lines = (200 => 'OK',
                        400 => 'Bad Request',
                        401 => 'Unauthorized',
                        403 => 'Forbidden',
                        404 => 'Not found',
                        500 => 'Internal Server Error');

    my $output = $r->status .' - '. $status_lines{$r->status} .' - '.
        scalar localtime;

    $r->send_http_header;
    return OK if $r->header_only;

    $r->print("$output\n\n");
    return OK;
}

1;
__END__

Reply via email to