stas        2003/05/06 01:26:53

  Modified:    src/docs/2.0/user config.cfg
               src/docs/2.0/user/handlers filters.pod
  Added:       src/docs/2.0/user/handlers filter_life_camera.jpg
                        filter_life_cigarrette.jpg filter_life_coffee.jpg
                        filter_life_goggles.jpg filter_life_mask.jpg
                        filter_life_player.jpg filter_life_shower.jpg
  Log:
  add an introduction section on filters, including some images to spice
  things up
  
  Revision  Changes    Path
  1.23      +1 -0      modperl-docs/src/docs/2.0/user/config.cfg
  
  Index: config.cfg
  ===================================================================
  RCS file: /home/cvs/modperl-docs/src/docs/2.0/user/config.cfg,v
  retrieving revision 1.22
  retrieving revision 1.23
  diff -u -r1.22 -r1.23
  --- config.cfg        11 Apr 2003 03:20:09 -0000      1.22
  +++ config.cfg        6 May 2003 08:26:53 -0000       1.23
  @@ -56,6 +56,7 @@
   
       copy_glob => [qw(
           handlers/*.gif
  +        handlers/*.jpg
       )],
   
       changes => 'Changes.pod',
  
  
  
  1.25      +190 -0    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.24
  retrieving revision 1.25
  diff -u -r1.24 -r1.25
  --- filters.pod       10 Apr 2003 02:50:14 -0000      1.24
  +++ filters.pod       6 May 2003 08:26:53 -0000       1.25
  @@ -7,6 +7,196 @@
   This chapter discusses mod_perl's input and output filter handlers.
   
   
  +=head1 Your First Filter
  +
  +You certainly already know how filters work. That's because you
  +encounter filters so often in the real life. If you are unfortunate to
  +live in smog-filled cities like Saigon or Bangkok you are probably
  +used to wear a dust filter mask:
  +
  +=for html
  +<img src="filter_life_mask.jpg" width="150" height="159"
  + align="center" valign="middle" alt="dust mask"><br><br>
  +
  +If you are smoker, chances are that you smoke cigarettes with filters:
  +
  +=for html
  +<img src="filter_life_cigarrette.jpg" width="95" height="116"
  + align="center" valign="middle" alt="cigarrette filter"><br><br>
  +
  +If you are a coffee gourmand, you have certainly tried a filter coffee:
  +
  +=for html
  +<img src="filter_life_coffee.jpg" width="179" height="190" 
  + align="center" valign="middle" alt="coffee machine"><br><br>
  +
  +The shower that you use, may have a water filter:
  +
  +=for html
  +<img src="filter_life_shower.jpg" width="180" height="168"
  + align="center" valign="middle" alt="shower filter"><br><br>
  +
  +When the sun is too bright, you protect your eyes by wearing sun
  +goggles with UV filter:
  +
  +=for html
  +<img src="filter_life_goggles.jpg" width="200" height="86" 
  + align="center" valign="middle" alt="sun goggles"><br><br>
  +
  +If are a photographer you can't go a step without using filter lenses:
  +
  +=for html
  +<img src="filter_life_camera.jpg" width="191" height="160"
  + align="center" valign="middle" alt="photo camera"><br><br>
  +
  +If you love music, you might be unaware of it, but your super-modern
  +audio system is literally loaded with various electronic filters:
  +
  +=for html
  +<img src="filter_life_player.jpg" width="277" height="150" 
  + align="center" valign="middle" alt="LP player"><br><br>
  +
  +There are many more places in our lives where filters are used. The
  +purpose of all filters is to apply some transformation to what's
  +coming into the filter, letting something different out of the
  +filter. Certainly in some cases it's possible to modify the source
  +itself, but that makes things unflexible, and but most of the time we
  +have no control over the source. The advantage of using filters to
  +modify something is that they can be replaced when requirements change
  +Filters also can be stacked, which allows us to make each filter do
  +simple transformations. For example by combining several different
  +filters, we can apply multiple transformations. In certain situations
  +combining several filters of the same kind let's us achieve a better
  +quality output.
  +
  +The mod_perl filters are not any different, they receive some data,
  +modify it and send it out. In the case of filtering the output of the
  +response handler, we could certainly change the response handler's
  +logic to do something different, since we control the response
  +handler. But this may make the code unnecessary complex. If we can
  +apply transformations to the response handler's output, it certainly
  +gives us more flexibility and simplifies things. For example if a
  +response needs to be compressed before sent out, it'd be very
  +inconvenient and inefficient to code in the response handler
  +itself. Using a filter for that purpose is a perfect
  +solution. Similarly, in certain cases, using an input filter to
  +transform the incoming request data is the most wise solution. Think
  +of the same example of having the incoming data coming compressed.
  +
  +Just like with real life filters, you can pipe several filters to
  +modify each other's output. You can also customize a selection of
  +different filters at run time.
  +
  +Without much further ado, let's write a simple but useful obfuscation
  +filter for our HTML documents.
  +
  +We are going to use a very simple obfuscation -- turn the document
  +into a one liner, which will make it harder to read the source
  +code. To accomplish that we are going to remove characters \012
  +(C<\n>) and \015 (C<\r>).
  +
  +And here is the code:
  +
  +  #file:MyApache/FilterObfuscate.pm
  +  #--------------------------
  +  package MyApache::FilterObfuscate;
  +  
  +  use strict;
  +  use warnings;
  +  
  +  use Apache::Filter ();
  +  
  +  use Apache::Const -compile => qw(OK);
  +  
  +  use constant BUFF_LEN => 1024;
  +  
  +  sub handler {
  +      my $f = shift;
  +  
  +      unless ($f->ctx) {
  +          $f->r->headers_out->unset('Content-Length');
  +          $f->ctx(1);
  +      }
  +  
  +      while ($f->read(my $buffer, BUFF_LEN)) {
  +          $buffer =~ s/[\r\n]//g;
  +          $f->print($buffer);
  +      }
  +  
  +      Apache::OK;
  +  }
  +  1;
  +
  +Next we add it to the configuration file:
  +
  +  <Files ~ "\.html">
  +      PerlOutputFilterHandler MyApache::FilterObfuscate
  +  </Files>
  +
  +restart the server, and now whenever a file with an I<".html">
  +extension is requested, its content will be passed through the
  +C<MyApache::FilterObfuscate> filter.
  +
  +The filter handler is similar to HTTP handlers, as it's expected to
  +return C<Apache::OK> or C<Apache::DECLINED>, but it receives the
  +filter object C<$f> as the first argument and not the request object
  +C<$r> as is the case with HTTP handlers.
  +
  +The core of this filter is the read-modify-print expression which
  +happens in the while loop. The logic is very simple: read at most
  +C<BUFF_LEN> characters of data into C<$buffer>, apply the regex to
  +remove any occurences of C<\n> and C<\r> in it, and print the
  +resulting data out. The input data may come from a response handler,
  +or from an upstream filter. The output data goes to the next filter in
  +the output chain. Even though in this example we haven't configured
  +any more filters, internally Apache by itself uses several core
  +filters to manipulate the data and send it out to the client.
  +
  +The second important chunk of logic is the unsetting of the
  +C<Content-Length> response header. Since the
  +C<MyApache::FilterObfuscate> filter modifies the length of the data
  +(shrinks it), if the response handler has set the C<Content-Length>
  +header the client may have problems receiving the data since it'd
  +expect more data then we have sent.
  +
  +As we are going to explain in great detail in the next sections, the
  +same filter may be called many times during a single requests, every
  +time receiving a chunk of data. For example if the HTML page is 64k
  +long, a filter could be invoked 4 times, each time receiving 16k of
  +data. The while loop that we just saw is going to read these 16k in 16
  +calls, since it requests 1k on every read() call. Since it's enough to
  +unset the C<Content-Length> header when the filter is called the first
  +time, we need to have some flag telling us whether we have done the
  +job. The method C<ctx> provides this functionality:
  +
  +      unless ($f->ctx) {
  +          $f->r->headers_out->unset('Content-Length');
  +          $f->ctx(1);
  +      }
  +
  +the unset() call will be made only on the first filter call for each
  +request. Of course you can store any perl data structures in
  +C<$f-E<gt>ctx> and retrieve it later in future filter invocations. We
  +will show plenty of examples using this method in the following
  +sections.
  +
  +Of course the C<MyApache::FilterObfuscate> filter logic should take
  +into account situations where removing new line characters will break
  +the correct rendering, as is the case if there are multi-line
  +C<E<lt>preE<gt>>...C<E<lt>/preE<gt>> entries, but since it escalates
  +the complexity of the filter, we will disregard this requirement for
  +now. A positive side effect of this obfuscation algorithm is in
  +shrinking the length of the data sent to the client. If you want to
  +look at the production ready implementation, which takes into account
  +the HTML markup specifics, the C<Apache::Clean> module, available from
  +CPAN, does just that.
  +
  +mod_perl I/O filtering follows the Perl's principle of making simple
  +things easy and difficult things possible. You have seen that it's
  +trivial to write simple filters. As you read through this tutorial you
  +will see that much more difficult things are possible, even though a
  +more elaborated code will be needed.
  +
   =head1 I/O Filtering Concepts
   
   Before introducing the APIs, mod_perl provides for Apache Filtering,
  
  
  
  1.1                  
modperl-docs/src/docs/2.0/user/handlers/filter_life_camera.jpg
  
        <<Binary file>>
  
  
  1.1                  
modperl-docs/src/docs/2.0/user/handlers/filter_life_cigarrette.jpg
  
        <<Binary file>>
  
  
  1.1                  
modperl-docs/src/docs/2.0/user/handlers/filter_life_coffee.jpg
  
        <<Binary file>>
  
  
  1.1                  
modperl-docs/src/docs/2.0/user/handlers/filter_life_goggles.jpg
  
        <<Binary file>>
  
  
  1.1                  
modperl-docs/src/docs/2.0/user/handlers/filter_life_mask.jpg
  
        <<Binary file>>
  
  
  1.1                  
modperl-docs/src/docs/2.0/user/handlers/filter_life_player.jpg
  
        <<Binary file>>
  
  
  1.1                  
modperl-docs/src/docs/2.0/user/handlers/filter_life_shower.jpg
  
        <<Binary file>>
  
  

---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to