stas 2004/06/03 23:40:16
Modified: src/docs/2.0/user/handlers protocols.pod
Log:
more examples
Revision Changes Path
1.22 +67 -2 modperl-docs/src/docs/2.0/user/handlers/protocols.pod
Index: protocols.pod
===================================================================
RCS file: /home/cvs/modperl-docs/src/docs/2.0/user/handlers/protocols.pod,v
retrieving revision 1.21
retrieving revision 1.22
diff -u -u -r1.21 -r1.22
--- protocols.pod 3 Jun 2004 08:43:12 -0000 1.21
+++ protocols.pod 4 Jun 2004 06:40:16 -0000 1.22
@@ -356,6 +356,7 @@
my $bb_in = APR::Brigade->new($c->pool, $c->bucket_alloc);
my $bb_out = APR::Brigade->new($c->pool, $c->bucket_alloc);
+ my $last = 0;
while (1) {
my $rc = $c->input_filters->get_brigade($bb_in,
Apache::MODE_GETLINE);
@@ -379,7 +380,7 @@
my $data = $bucket->read;
if (length $data) {
- last if $data =~ /^[\r\n]+$/;
+ $last++ if $data =~ /^[\r\n]+$/;
# could do some transformation on data here
$bucket = APR::Bucket->new($data);
}
@@ -388,8 +389,9 @@
}
my $fb = APR::Bucket::flush_create($c->bucket_alloc);
- $bb->insert_tail($fb);
+ $bb_out->insert_tail($fb);
$c->output_filters->pass_brigade($bb_out);
+ last if $last;
}
$bb_in->destroy;
@@ -492,6 +494,62 @@
last;
}
+ last if $bb->is_empty;
+
+ $c->output_filters->fflush($bb);
+ }
+
+ $bb->destroy;
+
+ Apache::OK;
+ }
+
+Since the simplified handler no longer has the condition:
+
+ $last++ if $data =~ /^[\r\n]+$/;
+
+which was used to know when to break from the external C<while(1)>
+loop, it will not work in the interactive mode, because when telnet is
+used we always end the line with C</[\r\n]/>, which will always send
+data back to the protocol handler and the condition:
+
+ last if $bb->is_empty;
+
+will never be true. However, this latter version works fine when the
+client is a script and when it stops sending data, our shorter handler
+breaks out of the loop.
+
+So let's do one more tweak and make the last version work in the
+interactive telnet mode without manipulating each bucket separately.
+This time we will use
+C<L<flatten()|docs::2.0::api::APR::Brigade/C_flatten_>> to slurp all
+the data from all the buckets, which saves us the explicit loop over
+the buckets in the brigade. The handler now becomes:
+
+ sub handler {
+ my $c = shift;
+
+ $c->client_socket->opt_set(APR::SO_NONBLOCK => 0);
+
+ my $bb = APR::Brigade->new($c->pool, $c->bucket_alloc);
+
+ while (1) {
+ my $rc = $c->input_filters->get_brigade($bb,
+ Apache::MODE_GETLINE);
+ if ($rc != APR::SUCCESS && $rc != APR::EOF) {
+ my $error = APR::Error::strerror($rc);
+ warn __PACKAGE__ . ": get_brigade: $error\n";
+ last;
+ }
+
+ my $data = $bb->flatten;
+ $bb->cleanup;
+ last if $data =~ /^[\r\n]+$/;
+
+ # could transform data here
+ my $bucket = APR::Bucket->new($data);
+ $bb->insert_tail($bucket);
+
$c->output_filters->fflush($bb);
}
@@ -499,6 +557,13 @@
Apache::OK;
}
+
+Notice, that once we slurped the data in the buckets, we had to strip
+the brigade of its buckets, since we re-used the same brigade to send
+the data out. We used
+C<L<cleanup()|docs::2.0::api::APR::Brigade/C_cleanup_>> to get rid of
+the buckets.
+
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]