You are viewing a plain text version of this content. The canonical link for it is here.
Posted to modperl@perl.apache.org by Bj�rn Ola Smievoll <b....@usit.uio.no> on 2000/09/28 13:17:53 UTC

NOT_FOUND from a PerlHandler causing problems with ErrorDocument

[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__

Re: NOT_FOUND from a PerlHandler causing problems with ErrorDocument

Posted by darren chamberlain <da...@boston.com>.
Bjørn Ola Smievoll (b.o.smievoll@usit.uio.no) said something to this effect:
> [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].

Why are you so averse to handling it in the translation phase? I think it
makes the content handler much cleaner.

> 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 

You don't mention how you are setting the error document handler. Are you
using

    $r->internal_redirect('/http_err');

or

    $r->push_handler(PerlHandler => \&UiO::ErrDoc::handler);
    return DECLINED;

or some other method? How you are setting it might be significant.

I think that Apache does the file stating and such during the translation
phase, so returning NOT_FOUND from the content phase might be too late for
Apache to step in and take over with the sending of the ErrorDocument. In
other words, its too late for Apache to do the Alias translation. Of course,
I may be wrong about this as well.

> and hogging memory.

As an aside, especially during development (when things like this are likely
to happen), see these documents:

http://perl.apache.org/guide/performance.html#Limiting_the_Size_of_the_Process
http://perl.apache.org/guide/performance.html#Limiting_Other_Resources_Used_by

(darren)

--
There are trivial truths and there are great Truths. The opposite of a
trival truth is obviously false. The opposite of a great Truth is also true.
    -- Neils Bohr