stas        2002/08/30 10:24:49

  Modified:    src/docs/2.0/user/handlers handlers.pod
  Log:
  PerlTypeHandler, PerlFixupHandler, PerlResponseHandler examples
  
  Revision  Changes    Path
  1.17      +176 -6    modperl-docs/src/docs/2.0/user/handlers/handlers.pod
  
  Index: handlers.pod
  ===================================================================
  RCS file: /home/cvs/modperl-docs/src/docs/2.0/user/handlers/handlers.pod,v
  retrieving revision 1.16
  retrieving revision 1.17
  diff -u -r1.16 -r1.17
  --- handlers.pod      28 Aug 2002 18:05:42 -0000      1.16
  +++ handlers.pod      30 Aug 2002 17:24:49 -0000      1.17
  @@ -1536,7 +1536,32 @@
   The handler's configuration scope is
   C<L<DIR|docs::2.0::user::config::config/item_DIR>>.
   
  -Example:
  +The most important thing to remember when overriding the default
  +I<type_checker> handler, which is usually the mod_mime handler, is
  +that you have to set the handler that will take care of the response
  +phase and the response callback function or the code won't
  +work. mod_mime does that based on C<SetHandler> and C<AddHandler>
  +directives, and file extensions. So if you want the content handler to
  +be run by mod_perl, set either:
  +
  +  $r->handler('perl-script');
  +  $r->set_handlers(PerlResponseHandler => \&handler);
  +
  +or:
  +
  +  $r->handler('modperl');
  +  $r->set_handlers(PerlResponseHandler => \&handler);
  +
  +depending on which type of response handler is wanted.
  +
  +Writing a C<PerlTypeHandler> handler which sets the content-type value
  +and returns C<Apache::DECLINED> so that the default handler will do
  +the rest of the work, is not a good idea, because mod_mime will
  +probably override this and other settings.
  +
  +Therefore it's the easiest to leave this stage alone and do any
  +desired settings in the I<fixups> phase.
  +
   
   
   
  @@ -1553,7 +1578,102 @@
   The handler's configuration scope is
   C<L<DIR|docs::2.0::user::config::config/item_DIR>>.
   
  -Example:
  +The following fixup handler example tells Apache at run time which
  +handler and callback should be used to process the request based on
  +the file extension of the request's URI.
  +
  +  file:MyApache/FileExtDispatch.pm
  +  --------------------------------
  +  package MyApache::FileExtDispatch;
  +  
  +  use Apache::Const -compile => 'OK';
  +  
  +  use constant HANDLER  => 0;
  +  use constant CALLBACK => 1;
  +  
  +  my %exts = (
  +      cgi => ['perl-script',     \&cgi_handler],
  +      pl  => ['modperl',         \&pl_handler ],
  +      tt  => ['perl-script',     \&tt_handler ],
  +      txt => ['default-handler', undef        ],
  +  );
  +  
  +  sub handler {
  +      my $r = shift;
  +  
  +      my ($ext) = $r->uri =~ /\.(\w+)$/;
  +      $ext = 'txt' unless defined $ext and exists $exts{$ext};
  +  
  +      $r->handler($exts{$ext}->[HANDLER]);
  +  
  +      if (defined $exts{$ext}->[CALLBACK]) {
  +          $r->set_handlers(PerlHandler => $exts{$ext}->[CALLBACK]);
  +      }
  +  
  +      return Apache::OK;
  +  }
  +  
  +  sub cgi_handler { content_handler($_[0], 'cgi') }
  +  sub pl_handler  { content_handler($_[0], 'pl')  }
  +  sub tt_handler  { content_handler($_[0], 'tt')  }
  +  
  +  sub content_handler {
  +      my($r, $type) = @_;
  +  
  +      $r->content_type('text/plain');
  +      $r->print("A handler of type '$type' was called");
  +  
  +      return Apache::OK;
  +  }
  +  
  +  1;
  +
  +In the example we have used the following mapping.
  +
  +  my %exts = (
  +      cgi => ['perl-script',     \&cgi_handler],
  +      pl  => ['modperl',         \&pl_handler ],
  +      tt  => ['perl-script',     \&tt_handler ],
  +      txt => ['default-handler', undef        ],
  +  );
  +
  +So that I<.cgi> requests will be handled by the C<perl-script> handler
  +and the C<cgi_handler()> callback, I<.pl> requests by C<modperl> and
  +C<pl_handler()>, I<.tt> (template toolkit) by C<perl-script> and the
  +C<tt_handler()>, finally I<.txt> request by the C<default-handler>
  +handler, which requires no callback.
  +
  +Moreover the handler assumes that if the request's URI has no file
  +extension or it does, but it's not in its mapping, the
  +C<default-handler> will be used, as if the I<txt> extension was used.
  +
  +After doing the mapping, the handler assigns the handler:
  +
  +      $r->handler($exts{$ext}->[HANDLER]);
  +
  +and the callback if needed:
  +
  +      if (defined $exts{$ext}->[CALLBACK]) {
  +          $r->set_handlers(PerlHandler => $exts{$ext}->[CALLBACK]);
  +      }
  +
  +In this simple example the callback functions don't do much but
  +calling the same content handler which simply prints the name of the
  +extension if handled by mod_perl, otherwise Apache will serve the
  +other files using the default handler. In real world you will use
  +callbacks to real content handlers that do real things.
  +
  +Here is how this handler is configured:
  +
  +  Alias /dispatch/ /home/httpd/dispatch/
  +  <Location /dispatch/>
  +      PerlFixupHandler MyApache::FileExtDispatch
  +  </Location>
  +
  +Notice that there is no need to specify anything, but the fixup
  +handler. It applies the rest of the settings dynamically at run-time.
  +
  +
   
   
   =head2 PerlResponseHandler
  @@ -1570,16 +1690,66 @@
        PerlResponseHandler Apache::Registry
     </Location>
   
  -C<SetHandler> tells Apache that mod_perl is going to handle the
  -response generation. C<PerlResponseHandler> tells mod_perl which
  -handler is going to do the job.
  +C<SetHandler> set to
  +L<C<perl-script>|docs::2.0::user::config::config/perl_script> or
  +L<C<modperl>|docs::2.0::user::config::config/modperl> tells Apache
  +that mod_perl is going to handle the response
  +generation. C<PerlResponseHandler> tells mod_perl which callback is
  +going to do the job.
   
   This phase is of type C<L<RUN_FIRST|/item_RUN_FIRST>>.
   
   The handler's configuration scope is
   C<L<DIR|docs::2.0::user::config::config/item_DIR>>.
   
  -Example:
  +Most of the C<Apache::> modules on CPAN are dealing with this
  +phase. In fact most of the developers spend the majority of their time
  +working on handlers that generate response content.
  +
  +Let's write a simple response handler, that just generates some
  +content. This time let's do something more interesting than printing
  +I<Hello world". Let's write a handler that prints itself:
  +
  +  file:MyApache/Deparse.pm
  +  ------------------------
  +  package MyApache::Deparse;
  +  
  +  use Apache::RequestRec ();
  +  use Apache::RequestIO ();
  +  use B::Deparse ();
  +  
  +  use Apache::Const -compile => 'OK';
  +  
  +  sub handler {
  +      my $r = shift;
  +  
  +      $r->content_type('text/plain');
  +      $r->print('sub handler ', B::Deparse->new->coderef2text(\&handler));
  +  
  +      return Apache::OK;
  +  }
  +  1;
  +
  +To enable this handler add to I<httpd.conf>:
  +
  +  <Location /deparse>
  +      SetHandler modperl
  +      PerlResponseHandler MyApache::Deparse
  +  </Location>
  +
  +Now when the server is restarted and we issue a request to
  +I<http://localhost/deparse> we get the following response:
  +
  +  sub handler {
  +      package MyApache::Deparse;
  +      my $r = shift @_;
  +      $r->content_type('text/plain');
  +      $r->print('sub handler ', 'B::Deparse'->new->coderef2text(\&handler));
  +      return 0;
  +  }
  +
  +if you compare it to the source code, it's pretty much the
  +same. C<B::Deparse> is fun to play with!
   
   
   
  
  
  

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

Reply via email to