stas 2002/11/19 16:36:39
Modified: src/docs/2.0/user/handlers filters.pod
Log:
- fix the FilterSnoop example to dump the sniffed data as soon as it's
available to
- update the output/explanations to reflect the reality, which changes
daily
Revision Changes Path
1.6 +77 -64 modperl-docs/src/docs/2.0/user/handlers/filters.pod
Index: filters.pod
===================================================================
RCS file: /home/cvs/modperl-docs/src/docs/2.0/user/handlers/filters.pod,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -r1.5 -r1.6
--- filters.pod 17 Nov 2002 05:29:11 -0000 1.5
+++ filters.pod 20 Nov 2002 00:36:38 -0000 1.6
@@ -240,10 +240,11 @@
use strict;
use warnings;
+ use APR::Bucket ();
+
use base qw(Apache::Filter);
use Apache::FilterRec ();
use APR::Brigade ();
- use APR::Bucket ();
use Apache::Const -compile => qw(OK DECLINED);
use APR::Const -compile => ':common';
@@ -259,45 +260,44 @@
my $stream = defined $mode ? "input" : "output";
# read the data and pass-through the bucket brigades unchanged
- my $ra_data = '';
if (defined $mode) {
# input filter
my $rv = $filter->next->get_brigade($bb, $mode, $block,
$readbytes);
return $rv unless $rv == APR::SUCCESS;
- $ra_data = bb_sniff($bb);
+ bb_dump($type, $stream, $bb);
}
else {
# output filter
- $ra_data = bb_sniff($bb);
+ bb_dump($type, $stream, $bb);
my $rv = $filter->next->pass_brigade($bb);
return $rv unless $rv == APR::SUCCESS;
}
- # send the sniffed info to STDERR so not to interfere with normal
- # output
- my $direction = $stream eq 'output' ? ">>>" : "<<<";
- print STDERR "\n$direction $type $stream filter\n";
- my $c = 1;
- while (my($btype, $data) = splice @$ra_data, 0, 2) {
- print STDERR " o bucket $c: $btype\n";
- print STDERR "[$data]\n";
- $c++;
- }
-
return Apache::OK;
}
- sub bb_sniff {
- my $bb = shift;
+ sub bb_dump {
+ my($type, $stream, $bb) = @_;
+
my @data;
for (my $b = $bb->first; $b; $b = $bb->next($b)) {
$b->read(my $bdata);
$bdata = '' unless defined $bdata;
push @data, $b->type->name, $bdata;
}
- return [EMAIL PROTECTED];
- }
+ # send the sniffed info to STDERR so not to interfere with normal
+ # output
+ my $direction = $stream eq 'output' ? ">>>" : "<<<";
+ print STDERR "\n$direction $type $stream filter\n";
+
+ my $c = 1;
+ while (my($btype, $data) = splice @data, 0, 2) {
+ print STDERR " o bucket $c: $btype\n";
+ print STDERR "[$data]\n";
+ $c++;
+ }
+ }
1;
This package provides two filter handlers, one for connection and
@@ -318,20 +318,18 @@
passed, whereas the arguments C<$mode>, C<$block>, and C<$readbytes>
are passed only to input filter handlers.
-If we are in the input mode, we retrieve the bucket brigade and
-immediately link it to C<$bb> which makes the brigade available to the
-next filter. When this filter handler returns, the next filter on the
-stack will get the brigade. If we forget to perform this linking our
-filter will become a black hole in which data simply disappears. Next
-we call C<bb_sniff()> which returns the type and the content of the
-buckets in the brigade.
-
-If we are in the output mode, C<$bb> already points to the current
-bucket brigade. Therefore we can read the contents of the brigade
-right away. After that we pass the brigade to the next filter.
-
-Finally we dump to STDERR the information about the type of the
-current mode, and the content of the bucket bridge.
+If we are in the input mode, in the same call we retrieve the bucket
+brigade from the previous filter on the input filters stack and
+immediately link it to the C<$bb> variable which makes the bucket
+brigade available to the next input filter when the filter handler
+returns. If we forget to perform this linking our filter will become a
+black hole in which data simply disappears. Next we call C<bb_dump()>
+which dumps the type of the filter and the contents of the bucket
+brigade to C<STDERR>, without influencing the normal data flow.
+
+If we are in the output mode, the C<$bb> variable already points to
+the current bucket brigade. Therefore we can read the contents of the
+brigade right away. After that we pass the brigade to the next filter.
Let's snoop on connection and request filter levels in both
directions by applying the following configuration:
@@ -439,13 +437,9 @@
filter is of type I<EOS>, meaning that all the input data from the
current request has been received.
-META: that's not true anymore, Apache now doesn't set CL header for
-dynamic content, so there is no setaside. Need to adjust the section
-for this change.
-
Next we can see that C<MyApache::Dump::handler> has generated its
-response. However only the request output filter is filtering it at
-this point:
+response. However we can see that only the request output filter gets
+run at this point:
>>> request output filter
o bucket 1: TRANSIENT
@@ -456,45 +450,66 @@
]
This happens because Apache hasn't sent yet the response HTTP headers
-to the client. Apache postpones the header sending so it can calculate
-and set the C<Content-Length> header. This time the brigade consists
-of a single bucket of type I<TRANSIENT> which is allocated from the
-stack memory, which will eventually be converted to the I<HEAP> type,
-before the body of the response is sent to the client.
-
-When the content handler returns Apache sends the HTTP headers through
-connection output filters (notice that the request output filters
-don't see it):
+to the client. The request filter sees a bucket brigade with a single
+bucket of type I<TRANSIENT> which is allocated from the stack memory.
+
+The moment the first bucket brigade of the response body has entered
+the connection output filters, Apache injects a bucket brigade with
+the HTTP headers. Therefore we can see that the connection output
+filter is filtering the bridage with HTTP headers (notice that the
+request output filters don't see it):
>>> connection output filter
o bucket 1: HEAP
[HTTP/1.1 200 OK
- Date: Wed, 14 Aug 2002 07:31:53 GMT
- Server: Apache/2.0.41-dev (Unix) mod_perl/1.99_05-dev
- Perl/v5.8.0 mod_ssl/2.0.41-dev OpenSSL/0.9.6d DAV/2
- Content-Length: 42
+ Date: Tue, 19 Nov 2002 15:59:32 GMT
+ Server: Apache/2.0.44-dev (Unix) mod_perl/1.99_08-dev
+ Perl/v5.8.0 mod_ssl/2.0.44-dev OpenSSL/0.9.6d DAV/2
Connection: close
+ Transfer-Encoding: chunked
Content-Type: text/plain; charset=ISO-8859-1
]
-Now the response body in the bucket of type I<HEAP> is passed through
-the connection output filter, followed by the I<EOS> bucket to mark
-the end of the request:
+and followed by the first response body's brigade:
>>> connection output filter
- o bucket 1: HEAP
+ o bucket 1: TRANSIENT
+ [2b
+ ]
+ o bucket 2: TRANSIENT
[args:
foo=1&bar=2
content:
mod_perl rules
+
+ ]
+ o bucket 3: IMMORTAL
+ [
]
- o bucket 2: EOS
- []
-Finally the output is flushed, to make sure that any buffered output
-is sent to the client:
+If the response is large, the request and connection filters will
+filter chunks of the response one by one.
+META: what's the size of the chunks? 8k?
+
+Finally, Apache sends a series of the bucket brigades to finish off
+the response, including the end of stream meta-bucket to tell filters
+that they shouldn't expect any more data, and flush buckets to flush
+the data, to make sure that any buffered output is sent to the client:
+
+ >>> connection output filter
+ o bucket 1: IMMORTAL
+ [0
+
+ ]
+ o bucket 2: EOS
+ []
+
+ >>> connection output filter
+ o bucket 1: FLUSH
+ []
+
>>> connection output filter
o bucket 1: FLUSH
[]
@@ -503,10 +518,8 @@
many time during each request and connection. It's called for each
bucket brigade.
-Also it's important to notice that the request input filter is called
-only if there is some POSTed data to read, if you run the same request
-without POSTing any data or simply running a GET request, the request
-input filter won't be called.
+Also it's important to notice that request input filters are called
+only if there is some POSTed data to read.
=head1 Input Filters
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]