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]

Reply via email to