I'm in the process of converting some old software from mod_perl1 to
mod_perl2, and I'm finding that $r->bytes_sent() doesn't work as it used
to.

The code is written in a very out-moded style: it is compatible with
mod_cgi, runs via ModPerl::Registry (formerly Apache::Registry), and
produces all its output via explicit print() statements scattered left,
right and centre, including a print() statement to send the response
headers. An error-handling subroutine calls $r->bytes_sent() to find out
if anything has been sent yet, so that it knows whether or not it needs
to send response headers before sending an error page (it could be
invoked either before or after the headers have been sent in the normal
course of events).

This works fine under mod_perl1, but under mod_perl2 I find that the
error-handler always emits response headers itself (i.e. it always
thinks that nothing has been sent yet). Therefore, in those cases where
response headers have already been sent, I now have a second set being
sent, which the user ends up seeing in the web browser. The code in
question is simply:

unless (exists $ENV{MOD_PERL}
                ? Apache2::RequestUtil->request()->bytes_sent()
                : tell STDOUT)
{
#... send response headers
}
#... send error page

There is a suggestion in

http://perl.apache.org/docs/2.0/api/Apache2/RequestRec.html#C_bytes_sent
_

that bytes_sent() doesn't work quite like it used to, so I assume that
this is a known problem / intended functionality. There is mention there
of buffering issues, so I've tried calling $r->rflush() first but
$r->bytes_sent() still returns 0. Setting $|=1 on STDOUT also doesn't
help.

Is there any way to get this to work under mod_perl2? If the data is
indeed buffered somewhere then is there any way to test whether or not
the buffer is empty?

(I see that CGI::Carp::fatalsToBrowser() uses a similar test itself, so
presumably it is not just my code that is affected.)

Reply via email to