I revisited the issue of 404 handling in CGI and Apache::Registry today and 
here's 
what I found. For illustration, here's a minimal CGI script which can 
illustrate the issue:

#!/usr/bin/perl
print "Status: 404\r\nContent-Type: text/html\r\n\r\nHello";

You can review the status codes being returned by accessing the script with LWP:

lwp-request -sS http://server.com/t.cgi | less

What I would like to have happen is for ErrorDocument to be triggered and
deliver the standard 404 page.

When the script runs in CGI, it does cause Apache to return a proper 404 status
code, but is apparently too late to trigger ErrorDocument, so just "Hello" is
printed instead.

When the script runs under Apache::Registry, the 404 status code is also set
correctly, but Apache prints my "Hello" output *and* sends the ErrorDocument
content.

This interplay is mentioned some mod_perl documentation, with the suggestion to
suppress the ErrorDocument content by returning a "200" code later on:

http://search.cpan.org/~gozer/mod_perl-1.31/faq/mod_perl_faq.pod#So_how_do_I_use_mod_perl_in_conjunction_with_ErrorDocument?

The good news that it at least that I think there's a way to have 404 handling
code that works in both CGI and Apache::Registry. The method would be to send
our own full HTML page and then suppress the ErrorDocument output under
mod_perl, perhaps using a method like those docs suggest.

It's tempting to considering patching CGI.pm or another toolkit module to
address this: CGI.pm could automatically call $r->status(200); after
$r->send_cgi_headers to suppress ErrorDocument sending. OTOH, there are
probably a number of people that now expect the current behavior, even if it
can result and in the unexpected and undesirable result of having ErrorDocument
content appended to your own content.

Another alternative would be write my own "404" routine that always sets 404,
but returns nothing in mod_perl (so the ErrorDocument is displayed) but returns
the full error document under CGI.

I would love for this be solved at a toolkit level so folks don't have to keep
re-inventing solutions for this.

Have I missed a better way to handle this?

    Mark


Reply via email to