You are viewing a plain text version of this content. The canonical link for it is here.
Posted to docs-cvs@perl.apache.org by st...@apache.org on 2002/01/09 19:09:49 UTC

cvs commit: modperl-docs/src/docs/2.0/user/overview overview.pod

stas        02/01/09 10:09:49

  Modified:    src/docs/2.0/devel/help help.pod
               src/docs/2.0/user/config config.pod
               src/docs/2.0/user/design design.pod
               src/docs/2.0/user/overview overview.pod
  Log:
  - lots of typos and pod markup fixes
  
  Revision  Changes    Path
  1.4       +2 -1      modperl-docs/src/docs/2.0/devel/help/help.pod
  
  Index: help.pod
  ===================================================================
  RCS file: /home/cvs/modperl-docs/src/docs/2.0/devel/help/help.pod,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- help.pod	31 Dec 2001 10:33:02 -0000	1.3
  +++ help.pod	9 Jan 2002 18:09:49 -0000	1.4
  @@ -147,6 +147,7 @@
   
   =item *
   
  +=back
   
   =head2 Apache Portable Runtime (APR)
   
  @@ -211,7 +212,7 @@
   
   =back
   
  -
  +=cut
   
   
   
  
  
  
  1.3       +1 -1      modperl-docs/src/docs/2.0/user/config/config.pod
  
  Index: config.pod
  ===================================================================
  RCS file: /home/cvs/modperl-docs/src/docs/2.0/user/config/config.pod,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- config.pod	27 Dec 2001 11:51:54 -0000	1.2
  +++ config.pod	9 Jan 2002 18:09:49 -0000	1.3
  @@ -154,7 +154,7 @@
   
   =item GlobalRequest
   
  -Setup the global request_rec for use with Apache->request
  +Setup the global request_rec for use with Apache-E<gt>request
   
   =item ParseHeaders
   
  
  
  
  1.2       +7 -7      modperl-docs/src/docs/2.0/user/design/design.pod
  
  Index: design.pod
  ===================================================================
  RCS file: /home/cvs/modperl-docs/src/docs/2.0/user/design/design.pod,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- design.pod	27 Dec 2001 12:02:47 -0000	1.1
  +++ design.pod	9 Jan 2002 18:09:49 -0000	1.2
  @@ -73,7 +73,7 @@
   At request time, If any Perl*Handlers are configured, an available
   interpreter is selected from the pool.  As there is a I<conn_rec> and
   I<request_rec> per thread, a pointer is saved in either the
  -conn_rec->pool or request_rec->pool, which will be used for the
  +conn_rec-E<gt>pool or request_rec-E<gt>pool, which will be used for the
   lifetime of that request.  For handlers that are called when threads
   are not running (PerlChild{Init,Exit}Handler), the parent interpreter
   is used.  Several configuration directives control the interpreter
  @@ -161,11 +161,11 @@
   
   Perl*Handlers are now "compiled", that is, the various forms of:
   
  - PerlResponseHandler MyModule->handler
  - # defaults to MyModule::handler or MyModule->handler
  - PerlResponseHandler MyModule
  - PerlResponseHandler $MyObject->handler
  - PerlResponseHandler 'sub { print "foo\n" }'
  +  PerlResponseHandler MyModule->handler
  +  # defaults to MyModule::handler or MyModule->handler
  +  PerlResponseHandler MyModule
  +  PerlResponseHandler $MyObject->handler
  +  PerlResponseHandler 'sub { print "foo\n" }'
   
   are only parsed once, unlike 1.xx which parsed every time the handler
   was used.  there will also be an option to parse the handlers at
  @@ -382,7 +382,7 @@
   generated and compiled.  The 2.0 version will provide the same
   functionality, but will not require the generated xs module.
   
  -=head1 <Perl> Configuration Sections
  +=head1 E<lt>PerlE<gt> Configuration Sections
   
   The ability to write configuration in Perl will carry over from 1.x,
   but will likely be implemented much different internally.  The mapping
  
  
  
  1.2       +594 -591  modperl-docs/src/docs/2.0/user/overview/overview.pod
  
  Index: overview.pod
  ===================================================================
  RCS file: /home/cvs/modperl-docs/src/docs/2.0/user/overview/overview.pod,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- overview.pod	27 Dec 2001 12:02:47 -0000	1.1
  +++ overview.pod	9 Jan 2002 18:09:49 -0000	1.2
  @@ -11,28 +11,28 @@
   more and more difficult to maintain, in large part to provide
   compatibility between the many different flavors of Apache and Perl.
   And, compatibility across these versions and flavors is a more
  -diffcult goal for mod_perl to reach that a typical Apache or Perl
  +difficult goal for mod_perl to reach that a typical Apache or Perl
   module, since mod_perl reaches a bit deeper into the corners of Apache
   and Perl internals than most.  Discussions of the idea to rewrite
  -mod_perl as version 2.0 started in 1998, but never made it much further
  -than an idea.  When Apache 2.0 development was underway it became
  -clear that a rewrite of mod_perl would be required to adjust to the
  -new Apache architechure and API.
  +mod_perl as version 2.0 started in 1998, but never made it much
  +further than an idea.  When Apache 2.0 development was underway it
  +became clear that a rewrite of mod_perl would be required to adjust to
  +the new Apache architecture and API.
   
   Of the many changes happening in Apache 2.0, the one which has the
  -most impact on mod_perl is the introduction of threads to the overall
  -design.  Threads have been a part of Apache on the win32 side since
  -the Apache port was introduced.  The mod_perl port to win32 happened
  -in verison 1.00b1, released in June of 1997.  This port enabled
  -mod_perl to compile and run in a threaded windows environment, with
  -one major caveat: only one concurrent mod_perl request could be
  -handled at any given time.  This was due to the fact that Perl did not 
  +most significant impact on mod_perl is the introduction of threads to
  +the overall design.  Threads have been a part of Apache on the win32
  +side since the Apache port was introduced.  The mod_perl port to win32
  +happened in version 1.00b1, released in June of 1997.  This port
  +enabled mod_perl to compile and run in a threaded windows environment,
  +with one major caveat: only one concurrent mod_perl request could be
  +handled at any given time.  This was due to the fact that Perl did not
   introduce thread safe interpreters until version 5.6.0, released in
  -March of 2000.  Contrary to popular belief, the "thread support"
  +March of 2000.  Contrary to popular belief, the "threads support"
   implemented in Perl 5.005 (released July 1998), did not make Perl
  -thread safe internally.  Well before that version, Perl had the notion 
  -of "Multiplicity", which allowed multiple interpreter instances in the 
  -same process.  However, these instances were not thread safe, that is, 
  +thread-safe internally.  Well before that version, Perl had the notion
  +of "Multiplicity", which allowed multiple interpreter instances in the
  +same process.  However, these instances were not thread safe, that is,
   concurrent callbacks into multiple interpreters were not supported.
   
   It just so happens that the release of Perl 5.6.0 was nearly at the
  @@ -46,27 +46,29 @@
   implementation based on lessons learned over the 4.5 years since
   mod_perl was introduced.
   
  -This paper and talk assume basic knowlege of mod_perl 1.xx features
  -and will focus only the differences mod_perl-2.00 will bring.
  +This document assumes basic knowlege of mod_perl-1.x features and will
  +focus only the differences mod_perl-2.0 will bring.
   
  -Note 1: The Apache and mod_perl APIs mentioned in this paper are both in
  -an "alpha" state and subject to change.
  +Note 1: The Apache and mod_perl APIs mentioned in this document are
  +both in an "alpha" state and subject to change.
   
  -Note 2: Some of the mod_perl APIs mentioned in this paper do not even
  -exist and are subject to be implemented, in which case you would be
  -redirected to "Note 1".
  +Note 2: Some of the mod_perl APIs mentioned in this document do not
  +even exist and are subject to be implemented, in which case you would
  +be redirected to "Note 1".
   
   =head1 Apache 2.0 Summary
   
   Note: This section will give you a brief overview of the changes in
  -Apache 2.0, just enough to understand where mod_perl will fit in.  For
  -more details on Apache 2.0 consult the papers by Ryan Bloom.
  +Apache 2.0, just enough to understand where mod_perl-2.0 fits in.  For
  +more details on Apache 2.0 consult the documents by Ryan Bloom.
  +
  +META: URLs?
   
   =head2 MPMs - Multi-Processing Model Modules
   
   In Apache 1.3.x concurrent requests were handled by multiple
   processes, and the logic to manage these processes lived in one place,
  -I<http_main.c>, 7200 some odd lines of code.  If Apache 1.3.x is
  +I<http_main.c>, 7700 some odd lines of code.  If Apache 1.3.x is
   compiled on a Win32 system large parts of this source file are
   redefined to handle requests using threads.  Now suppose you want to
   change the way Apache 1.3.x processes requests, say, into a DCE RPC
  @@ -75,11 +77,11 @@
   with a C<-DSTANDALONE_MAIN=your_function> compile time flag.
   Neither of which is a clean, modular mechanism.
   
  -Apache-2.0 solves this problem by intoducing I<Multi Processing Model
  +Apache-2.0 solves this problem by introducing I<Multi Processing Model
   modules>, better known as I<MPMs>.  The task of managing incoming
   requests is left to the MPMs, shrinking I<http_main.c> to less than
   500 lines of code.  Several MPMs are included with Apache 2.0 in the
  -I<src/modules/mpm> directory:
  +I<server/mpm> directory:
   
   =over 4
   
  @@ -88,22 +90,23 @@
   The I<prefork> module emulates 1.3.x's preforking model, where each
   request is handled by a different process.
   
  -=item threaded
  +=item worker
   
  -This MPMs implements a hybrid multi-process multi-threaded
  -approach based on the I<pthreads> standard.
  +This MPMs implements a hybrid multi-process multi-threaded approach
  +based on the I<pthreads> standard. It uses one acceptor thread,
  +multiple worker threads.
   
  -=item os2/winnt/beos
  +=item spmt_os2, mpmt_os2, netware, win32 and beos
   
   These MPMs also implement the hybrid multi-process/multi-threaded
   model, with each based on native OS thread implementations.
   
   =item perchild
   
  -The I<perchild> MPM is similar to the I<threaded> MPM, but is extended
  +The I<perchild> MPM is similar to the I<worker> MPM, but is extended
   with a mechanism which allows mapping of requests to virtual hosts to
  -a process running under the user id and group configured for that host.
  -This provides a robust replacement for the I<suexec> mechanism.
  +a process running under the user id and group configured for that
  +host.  This provides a robust replacement for the I<suexec> mechanism.
   
   =back
   
  @@ -112,33 +115,33 @@
   Apache 1.3.x has been ported to a very large number of platforms
   including various flavors of unix, win32, os/2, the list goes on.
   However, in 1.3.x there was no clear-cut, pre-designed portability
  -layer for third-party modules to take advantage of.  APR provides this 
  -API layer in a very clean way.  For mod_perl, APR will assist a great
  -deal with portability.  Combined with the portablity of Perl, mod_perl-2.0
  -needs only to implement a portable build system, the rest comes "for free".
  -A Perl interface will be provided for certain areas of APR, such as
  -the shared memory abstraction, but the majority of APR will be used by 
  -mod_perl "under the covers".
  +layer for third-party modules to take advantage of.  APR provides this
  +API layer in a very clean way.  APR assists a great deal with mod_perl
  +portability.  Combined with the portablity of Perl, mod_perl-2.0 needs
  +only to implement a portable build system, the rest comes "for free".
  +A Perl interface is provided for certain areas of APR, such as the
  +shared memory abstraction, but the majority of APR is used by mod_perl
  +"under the covers".
   
   =head2 New Hook Scheme
   
   In Apache 1.3, modules were registered using the I<module> structure,
   normally static to I<mod_foo.c>.  This structure contains pointers to
  -the command table, config create/merge functions, response handler
  -table and function pointers for all of the other hooks, such as
  -I<child_init> and I<check_user_id>.  In 2.0, this structure has been
  -pruned down to the first three items mention and a new function
  -pointer added called I<register_hooks>.  It is the job of
  -I<register_hooks> to register functions for all other hooks (such as
  -I<child_init> and I<check_user_id>).  Not only is hook registration
  -now dynamic, it is also possible for modules to register more than one 
  -function per hook, unlike 1.3.  The new hook mechanism also makes it
  -possible to sort registered functions, unlike 1.3 with function
  -pointers hardwired into the module structure, and each module
  +the command table, configuration creation and merging functions,
  +response handler table and function pointers for all of the other
  +hooks, such as I<child_init> and I<check_user_id>.  In Apache 2.0,
  +this structure has been pruned down to the first three items mentioned
  +and a new function pointer added called I<register_hooks>.  It is the
  +job of I<register_hooks> to register functions for all other hooks
  +(such as I<child_init> and I<check_user_id>).  Not only is hook
  +registration now dynamic, it is also possible for modules to register
  +more than one function per hook, unlike 1.3.  The new hook mechanism
  +also makes it possible to sort registered functions, unlike 1.3 with
  +function pointers hardwired into the module structure, and each module
   structure into a linked list.  Order in 1.3 depended on this list,
  -which was possible to order using compile-time and configuration-time
  +which was possible to order using compile-time and startup-time
   configuration, but that was left to the user.  Whereas in 2.0, the
  -add_hook functions accept an order preference parameter, those
  +I<add_hook> functions accept an order preference parameter, those
   commonly used are:
   
   =over 4
  @@ -151,24 +154,25 @@
   
   =back
   
  -For mod_perl, dynamic registration provides a cleaner way to bypass the
  -I<Perl*Handler> configuration.  By simply adding this configuration:
  +For mod_perl, dynamic registration provides a cleaner way to bypass
  +the C<Perl*Handler> configuration directives.  By simply adding this
  +configuration:
   
  - PerlModule Apache::Foo
  +  PerlModule Apache::Foo
   
  -I<Apache/Foo.pm> can register hooks itself at server startup:
  +C<Apache::Foo> can register hooks itself at server startup:
   
  - Apache::Hook->add(PerlAuthenHandler => \&authenticate, Apache::Hook::MIDDLE);
  - Apache::Hook->add(PerlLogHandler => \&logger, Apache::Hook::LAST);
  +  Apache::Hook->add(PerlAuthenHandler => \&authenticate, Apache::Hook::MIDDLE);
  +  Apache::Hook->add(PerlLogHandler    => \&logger,       Apache::Hook::LAST);
   
   However, this means that Perl subroutines registered via this
  -mechanism will be called for *every* request.  It will be left to that 
  -subroutine to decide if it was to handle or decline the given phase.
  -As there is overhead in entering the Perl runtime, it will most likely 
  -be to your advantage to continue using I<Perl*Handler> configuration
  -to reduce this overhead.  If it is the case that your I<Perl*Handler>
  -should be invoked for every request, the hook registration mechanism
  -will save some configuration keystrokes.
  +mechanism will be called for B<every> request.  It will be left to
  +that subroutine to decide if it was to handle or decline the given
  +phase.  As there is overhead in entering the Perl runtime, it will
  +most likely be to your advantage to continue using C<Perl*Handler>
  +configuration directives to reduce this overhead.  If it is the case
  +that your C<Perl*Handler> should be invoked for every request, the
  +hook registration mechanism will save some configuration keystrokes.
   
   =head2 Configuration Tree
   
  @@ -178,33 +182,33 @@
   first parsed into a tree structure, which is then walked to pass data
   down to the modules.  This tree is then left in memory with an API for 
   accessing it at request time.  The tree can be quite useful for other
  -modules.  For example, in 1.3, mod_info has it's own configuration
  +modules.  For example, in 1.3, mod_info has its own configuration
   parser and parses the configuration files each time you access it.
   With 2.0 there is already a parse tree in memory, which mod_info can
  -then walk to output it's information.
  +then walk to output its information.
   
   If a mod_perl 1.xx module wants access to configuration information,
  -there are two approaches.  A module can "subclass" directive handlers, 
  -saving a copy of the data for itself, then returning B<DECLINE_CMD> so 
  +there are two approaches.  A module can "subclass" directive handlers,
  +saving a copy of the data for itself, then returning B<DECLINE_CMD> so
   the other modules are also handed the info.  Or, the
  -C<$Apache::Server::SaveConfig> variable can be set to save <Perl>
  -configuration in the C<%Apache::ReadConfig::> namespace.  Both methods 
  -are rather kludgy, version 2.0 will provide a Perl interface to the
  -Apache configuration tree.
  +C<$Apache::Server::SaveConfig> variable can be set to save
  +E<lt>PerlE<gt> configuration in the C<%Apache::ReadConfig::>
  +namespace.  Both methods are rather kludgy, version 2.0 will provide a
  +Perl interface to the Apache configuration tree.
   
   =head2 Filtering
   
   Filtering of Perl modules output has been possible for years since
  -tied filehandle support was added to Perl.  There are several modules, 
  -such as I<Apache::Filter> and I<Apache::OutputChain> which have been
  -written to provide mechanisms for filtering the C<STDOUT> "stream".
  -There are several of these modules because no one approach has quite
  +tied filehandle support was added to Perl.  There are several modules,
  +such as C<Apache::Filter> and C<Apache::OutputChain> which have been
  +written to provide mechanisms for filtering the C<STDOUT> stream.
  +There are several of these modules because no one's approach has quite
   been able to offer the ease of use one would expect, which is due
   simply to limitations of the Perl tied filehandle design.  Another
   problem is that these filters can only filter the output of other Perl
   modules. C modules in Apache 1.3 send data directly to the client and
   there is no clean way to capture this stream.  Apache 2.0 has solved
  -this problem by introducing a filtering API.  With the baseline i/o
  +this problem by introducing a filtering API.  With the baseline I/O
   stream tied to this filter mechansim, any module can filter the output
   of any other module, with any number of filters in between.
   
  @@ -213,7 +217,7 @@
   Apache 1.3 is hardwired to speak only one protocol, HTTP.  Apache 2.0
   has moved to more of a "server framework" architecture making it
   possible to plugin handlers for protocols other than HTTP.  The
  -protocol module design also abstracts the transport layer so protocols 
  +protocol module design also abstracts the transport layer so protocols
   such as SSL can be hooked into the server without requiring
   modifications to the Apache source code.  This allows Apache to be
   extended much further than in the past, making it possible to add
  @@ -227,32 +231,33 @@
   =head2 Perl 5.6
   
   Thread safe Perl interpreters, also known as "ithreads" (Intepreter
  -Threads) provide the mechanism need for mod_perl to adapt to the
  -Apache 2.0 thread architecture.  This mechanism is a compile time
  +Threads) provide the mechanism needed for mod_perl to adapt to the
  +Apache 2.0 threads architecture.  This mechanism is a compile time
   option which encapsulates the Perl runtime inside of a single
  -I<PerlInterpreter> structure.  With each interpreter instance
  +C<PerlInterpreter> structure.  With each interpreter instance
   containing its own symbol tables, stacks and other Perl runtime
   mechanisms, it is possible for any number of threads in the same
   process to concurrently callback into Perl.  This of course requires
  -each thread to have it's own I<PerlInterpreter> object, or at least
  +each thread to have its own C<PerlInterpreter> object, or at least
   that each instance is only access by one thread at any given time.
   
  -mod_perl-1.xx has only a single I<PerlInterpreter>, which is
  +mod_perl-1.xx has only a single C<PerlInterpreter>, which is
   contructed by the parent process, then inherited across the forks to
   child processes.  mod_perl-2.0 has a configurable number of
  -I<PerlInterpreters> and two classes of interpreters, I<parent> and
  +C<PerlInterpreters> and two classes of interpreters, I<parent> and
   I<clone>.  A I<parent> is like that in 1.xx, the main interpreter
  -created at startup time which compiles any pre-loaded Perl code.
  -A I<clone> is created from the parent using the Perl API
  -I<perl_clone()> function.  At request time, I<parent> interpreters are 
  -only used for making more I<clones>, as they are the interpreters
  -which actually handle requests.  Care is taken by Perl to copy only
  -mutable data, which means that no runtime locking is required and
  -read-only data such as the syntax tree is shared from the I<parent>.
  +created at startup time which compiles any pre-loaded Perl code.  A
  +I<clone> is created from the parent using the Perl API I<perl_clone()>
  +function.  At request time, I<parent> interpreters are only used for
  +making more I<clones>, as the I<clones> are the interpreters which
  +actually handle requests.  Care is taken by Perl to copy only mutable
  +data, which means that no runtime locking is required and read-only
  +data such as the syntax tree is shared from the I<parent>, which
  +should reduce the overall mod_perl memory footprint.
   
   =head2 New mod_perl Directives for Threaded MPMs
   
  -Rather than create a I<PerlInterperter> per-thread by default,
  +Rather than create a C<PerlInterperter> per-thread by default,
   mod_perl creates a pool of interpreters.  The pool mechanism helps cut 
   down memory usage a great deal.  As already mentioned, the syntax tree 
   is shared between all cloned interpreters.  If your server is serving
  @@ -317,17 +322,17 @@
   By default, an interpreter will be held for the lifetime of the
   request, equivalent to this configuration:
   
  - PerlInterpScope request
  +  PerlInterpScope request
   
   For example, if a PerlAccessHandler is configured, an interpreter will
  -selected before it is run and not released until after the logging
  +be selected before it is run and not released until after the logging
   phase.
   
   Intepreters will be shared across subrequests by default, however, it
   is possible configure the intepreter scope to be per-subrequest on
   a per-directory basis:
   
  - PerlInterpScope subrequest
  +  PerlInterpScope subrequest
   
   With this configuration, an autoindex generated page for example would 
   select an interpreter for each item in the listing that is configured
  @@ -335,7 +340,7 @@
   
   It is also possible to configure the scope to be per-handler:
   
  - PerlInterpScope handler
  +  PerlInterpScope handler
   
   With this configuration, an interpreter will be selected before
   PerlAccessHandlers are run, and putback immediately afterwards, before
  @@ -351,7 +356,7 @@
   maintain state for the lifetime of an ftp connection, it is possible
   to do so on a per-virtualhost basis:
   
  - PerlInterpScope connection
  +  PerlInterpScope connection
   
   =back
   
  @@ -375,12 +380,12 @@
   =head1 Thread Item Pool API
   
   As we discussed, mod_perl implements a pool mechanism to manage
  -I<PerlInterpreters> between threads.  This mechanism has been
  +C<PerlInterpreters> between threads.  This mechanism has been
   abstracted into an API known as "tipool", I<Thread Item Pool>.  This
   pool can be used to manage any data structure, in which you wish to
   have a smaller number than the number of configured threads.  A good
   example of such a data structure is a database connection handle.
  -The I<Apache::DBI> module implements persisent connections for 1.xx,
  +The C<Apache::DBI> module implements persisent connections for 1.xx,
   but may result in each child maintaining its own connection, when it
   is most often the case that number of connections is never needed
   concurrently.  The TIPool API provides a mechanism to solve this
  @@ -391,19 +396,19 @@
   =item new
   
   Create a new thread item pool.  This constructor is passed an
  -I<Apache::Pool> object, a hash reference to pool configuration parameters,
  +C<Apache::Pool> object, a hash reference to pool configuration parameters,
   a hash reference to pool callbacks and an optional userdata variable
   which is passed to callbacks:
   
  - my $tip = Apache::TIPool->new($p,
  -                               {Start => 3, Max => 6},
  -                               {grow => \&new_connection,
  -                                shrink => \&close_connection},
  -                               \%my_config);
  -
  -The configuration parameters, I<Start>, I<Max>, I<MinSpare>, I<MaxSpare>
  -and I<MaxRequests> configure the pool for your items, just as the
  -I<PerlInterp*> directives do for I<PerlInterpreters>.
  +  my $tip = Apache::TIPool->new($p,
  +                                {Start => 3, Max => 6},
  +                                {grow   => \&new_connection,
  +                                 shrink => \&close_connection},
  +                                \%my_config);
  +
  +The configuration parameters, C<Start>, C<Max>, C<MinSpare>, C<MaxSpare>
  +and C<MaxRequests> configure the pool for your items, just as the
  +C<PerlInterp*> directives do for C<PerlInterpreters>.
   
   The I<grow> callback is called to create new items to be added to the
   pool, I<shrink> is called when an item is removed from the pool.
  @@ -417,14 +422,14 @@
   by calling the configured I<grow> callback.  Otherwise, the I<pop>
   method will block until an item is available.
   
  - my $item = $tip->pop;
  +  my $item = $tip->pop;
   
   =item putback
   
   This method gives an item (returned from I<pop>) back to the pool,
   which is pushed into the head of the available list:
   
  - $tip->putback($item);
  +  $tip->putback($item);
   
   =back
   
  @@ -435,85 +440,86 @@
   
   =head2 Apache::DBIPool
   
  -Now we will take a look at how to make I<DBI> take advantage of
  -I<TIPool> API with the I<Apache::DBIPool> module.  The module
  -configuration in httpd.conf will look something like so:
  -
  - PerlModule Apache::DBIPool
  -
  - <DBIPool dbi:mysql:db_name>
  -   DBIPoolStart 10
  -   DBIPoolMax   20
  -   DBIPoolMaxSpare 10
  -   DBIPoolMinSpare 5
  -   DBIUserName dougm
  -   DBIPassWord XxXx
  - </DBIPool>
  -
  -The module is loaded using the I<PerlModule> directive just as with
  -other modules.  TIPools are then configured using I<DBIPool>
  -configuration sections.  The argument given to the container is the
  -I<dsn> and within are the pool directives I<Start>, I<Max>,
  -I<MaxSpare> and I<MinSpare>.  The I<UserName> and I<PassWord>
  -directives will be passed to the I<DBI> I<connect> method.
  -There can be any number of I<DBIPool> containers, provided each I<dsn> 
  +Now we will take a look at how to make C<DBI> take advantage of
  +C<TIPool> API with the C<Apache::DBIPool> module.  The module
  +configuration in I<httpd.conf> will look something like so:
  +
  +  PerlModule Apache::DBIPool
  +  
  +  <DBIPool dbi:mysql:db_name>
  +      DBIPoolStart 10
  +      DBIPoolMax   20
  +      DBIPoolMaxSpare 10
  +      DBIPoolMinSpare 5
  +      DBIUserName dougm
  +      DBIPassWord XxXx
  +  </DBIPool>
  +
  +The module is loaded using the C<PerlModule> directive just as with
  +other modules.  TIPools are then configured using C<DBIPool>
  + configuration sections.  The argument given to the container is the
  +C<dsn> and within are the pool directives C<Start>, C<Max>,
  +C<MaxSpare> and C<MinSpare>.  The C<UserName> and C<PassWord>
  +directives will be passed to the C<DBI> C<connect> method.
  +There can be any number of C<DBIPool> containers, provided each C<dsn> 
   is different, and/or each container is inside a different
  -I<VirtualHost> container.
  +C<VirtualHost> container.
   
   Now let's examine the source code, keeping in mind this module
  -contains the basics and the official release (tbd) will likely contain 
  -more details, such as how it hooks into I<DBI.pm> to provide
  -transparency the way I<Apache::DBI> currently does.
  +contains the basics and the official release (tbd) will likely contain
  +more details, such as how it hooks into C<DBI> to provide transparency
  +the way C<Apache::DBI> currently does.
   
  -After pulling in the modules needed I<Apache::TIPool>,
  -I<Apache::ModuleConfig> and I<DBI>, we setup a callback table.  The 
  +After pulling in the needed modules C<Apache::TIPool>,
  +C<Apache::ModuleConfig> and C<DBI>, we setup a callback table.  The
   I<new_connection> function will be called with the TIP needs to add a
   new item and I<close_connection> when an item is being removed from
  -the pool.  The I<Apache::Hook> I<add> method registers a
  -I<PerlPostConfigHandler> which will be called after Apache has read
  +the pool.  The C<Apache::Hook> I<add> method registers a
  +C<PerlPostConfigHandler> which will be called after Apache has read
   the configuration files.
   
  -This handler (our I<init> function) is passed 3 I<Apache::Pool>
  -objects and one I<Apache::Server> object.  Each I<Apache::Pool> has a
  +This handler (our I<init> function) is passed three C<Apache::Pool>
  +objects and one C<Apache::Server> object.  Each C<Apache::Pool> has a
   different lifetime, the first will be alive until configuration is
   read again, such as during restarts.  The second will be alive until
   logs are re-opened and the third is a temporary pool which is cleared
   before Apache starts serving requests.  Since the DBI connection pool
  -is associated with configuration in httpd.conf, we will use that pool.  
  +is associated with configuration in I<httpd.conf>, we will use that
  +pool.
   
  -The I<Apache::ModuleConfig> I<get> method is called with the
  -I<Apache::Server> object to give us the configuration associated with
  +The C<Apache::ModuleConfig> I<get> method is called with the
  +C<Apache::Server> object to give us the configuration associated with
   the given server.  Next is a while loop which iterates over the
  -configuration parsed by the I<DBIPool> directive handler.  The keys of
  -this hash are the configured I<dsn>, of which there is one per
  -I<DBIPool> configuration section.  The values will be a hash reference
  -to the pool configuration, I<Start>, I<Max>, I<MinSpare>, I<MaxSpare>
  -and I<MaxRequests>.
  -
  -A I<new> I<Apache::TIPool> is then contructed, passing it the
  -C<$pconf> I<Apache::Pool>, configuration C<$params>, the I<$callbacks> 
  -table and C<$conn> hash ref.  The I<TIPool> is then saved into the
  -C<$cfg> object, indexed by the I<dsn>.
  +configuration parsed by the C<DBIPool> directive handler.  The keys of
  +this hash are the configured C<dsn>, of which there is one per
  +C<DBIPool> configuration section.  The values will be a hash reference
  +to the pool configuration, C<Start>, C<Max>, C<MinSpare>, C<MaxSpare>
  +and C<MaxRequests>.
  +
  +A I<new> C<Apache::TIPool> is then constructed, passing it the
  +C<$pconf>, C<Apache::Pool>, configuration C<$params>, the C<$callbacks> 
  +table and C<$conn> hash ref.  The C<TIPool> is then saved into the
  +C<$cfg> object, indexed by the C<dsn>.
   
  -At the time I<Apache::TIPool::new> is called, the I<new_connection>
  -callback will be called the number of time to which I<Start> is
  +At the time C<Apache::TIPool::new> is called, the I<new_connection>
  +callback will be called the number of times to which C<Start> is
   configured.  This callback localizes I<Apache::DBIPool::connect> to a
   code reference which makes the real database connection.
   
   At request time I<Apache::DBIPool::connect> will fetch a database
  -handle from the I<TIPool>.  It does so by digging into the
  +handle from the C<TIPool>.  It does so by digging into the
   configuration object associated with the current virtual host to
  -obtain a reference to the I<TIPool> object.  It then calls the I<pop>
  +obtain a reference to the C<TIPool> object.  It then calls the I<pop>
   method, which will immediatly return a database handle if one is
  -available.  If all opened connection are in used and the current
  -number of connections is less than the configured I<Max>, the call to
  -I<pop> will result in a call to I<new_connection>.  If I<Max> has
  -already been reached, then I<pop> will block until a handle is
  -I<putback> into the pool.
  +available.  If all opened connection are in use and the current number
  +of connections is less than the configured C<Max>, the call to I<pop>
  +will result in a call to I<new_connection>.  If C<Max> has already
  +been reached, then I<pop> will block until a handle is I<putback> into
  +the pool.
   
  -Finally, the handle is blessed into the I<Apache::DBIPool::db> class
  +Finally, the handle is blessed into the C<Apache::DBIPool::db> class
   which will override the dbd class I<disconnect> method.  The
  -overridden I<disconnect> method obtains a reference to the I<TIPool>
  +overridden I<disconnect> method obtains a reference to the C<TIPool>
   object and passes it to the I<putback> method, making it available for 
   use by other threads.  Should the Perl code using this handle neglect to
   call the I<disconnect> method, the overridden I<connect> method has
  @@ -521,183 +527,184 @@
   
   =head2 Apache::DBIPool Source
   
  - package Apache::DBIPool;
  -
  - use strict;
  - use Apache::TIPool ();
  - use Apache::ModuleConfig ();
  - use DBI ();
  -
  - my $callbacks = {
  -    grow => \&new_connection,     #add new connection to the pool
  -    shrink => \&close_connection, #handle removed connection from pool
  - };
  -
  - Apache::Hook->add(PerlPostConfigHandler => \&init); #called at startup
  -
  - sub init {
  -     my($pconf, $plog, $ptemp, $s) = @_;
  -
  -     my $cfg = Apache::ModuleConfig->get($s, __PACKAGE__);
  -
  -     #create a TIPool for each dsn
  -     while (my($conn, $params) = each %{ $cfg->{DBIPool} }) {
  -         my $tip = Apache::TIPool->new($pconf, $params, $callbacks, $conn);
  -         $cfg->{TIPool}->{ $conn->{dsn} } = $tip;
  -     }
  - }
  -
  - sub new_connection {
  -     my($tip, $conn) = @_;
  -
  -     #make actual connection to the database
  -     local *Apache::DBIPool::connect = sub {
  -         my($class, $drh) = (shift, shift);
  -         $drh->connect($dbname, @_);
  -     };
  -
  -     return DBI->connect(@{$conn}{qw(dsn username password attr)});
  - }
  -
  - sub close_connection {
  -     my($tip, $conn, $dbh) = @_;
  -     my $driver = (split $conn->{dsn}, ':')[1];
  -     my $method = join '::', 'DBD', $driver, 'db', 'disconnect';
  -     $dbh->$method(); #call the real disconnect method
  - }
  -
  - my $EndToken = '</DBIPool>';
  -
  - #parse <DBIPool dbi:mysql:...>...
  -
  - sub DBIPool ($$$;*) {
  -     my($cfg, $parms, $dsn, $cfg_fh) = @_;
  -     $dsn =~ s/>$//;
  -
  -     $cfg->{DBIPool}->{$dsn}->{dsn} = $dsn;
  -
  -     while((my $line = <$cfg_fh>) !~ m:^$EndToken:o) {
  -         my($name, $value) = split $line, /\s+/, 2;
  -         $name =~ s/^DBIPool(\w+)/lc $1/ei;
  -         $cfg->{DBIPool}->{$dsn}->{$name} = $value;
  -     }
  - }
  -
  - sub config {
  -     my $r = Apache->request;
  -     return Apache::ModuleConfig->get($r, __PACKAGE__);
  - }
  -
  - #called from DBI::connect
  - sub connect {
  -     my($class, $drh) = (shift, shift);
  -
  -     $drh->{DSN} = join ':', 'dbi', $drh->{Name}, $_[0];
  -     my $cfg = config();
  -
  -     my $tip = $cfg->{TIPool}->{ $drh->{DSN} };
  -
  -     unless ($tip) {
  -         #XXX: do a real connect or fallback to Apache::DBI
  -     }
  -
  -     my $item = $tip->pop; #select a connection from the pool
  -
  -     $r->register_cleanup(sub { #incase disconnect() is not called
  -         $tip->putback($item);
  -     });
  -
  -     return bless 'Apache::DBIPool::db', $item->data; #the dbh
  - }
  -
  - package Apache::DBIPool::db;
  -
  - our @ISA = qw(DBI::db);
  -
  - #override disconnect, puts database handle back in the pool
  - sub disconnect {
  -     my $dbh = shift;
  -     my $tip = config()->{TIPool}->{ $dbh->{DSN} };
  -     $tip->putback($dbh);
  -     1;
  - }
  -
  - 1;
  - __END__
  +  package Apache::DBIPool;
  +  
  +  use strict;
  +  use Apache::TIPool ();
  +  use Apache::ModuleConfig ();
  +  use DBI ();
  +  
  +  my $callbacks = {
  +     grow => \&new_connection,     #add new connection to the pool
  +     shrink => \&close_connection, #handle removed connection from pool
  +  };
  +  
  +  Apache::Hook->add(PerlPostConfigHandler => \&init); #called at startup
  +  
  +  sub init {
  +      my($pconf, $plog, $ptemp, $s) = @_;
  +  
  +      my $cfg = Apache::ModuleConfig->get($s, __PACKAGE__);
  +  
  +      #create a TIPool for each dsn
  +      while (my($conn, $params) = each %{ $cfg->{DBIPool} }) {
  +          my $tip = Apache::TIPool->new($pconf, $params, $callbacks, $conn);
  +          $cfg->{TIPool}->{ $conn->{dsn} } = $tip;
  +      }
  +  }
  +  
  +  sub new_connection {
  +      my($tip, $conn) = @_;
  +  
  +      #make actual connection to the database
  +      local *Apache::DBIPool::connect = sub {
  +          my($class, $drh) = (shift, shift);
  +          $drh->connect($dbname, @_);
  +      };
  +  
  +      return DBI->connect(@{$conn}{qw(dsn username password attr)});
  +  }
  +  
  +  sub close_connection {
  +      my($tip, $conn, $dbh) = @_;
  +      my $driver = (split $conn->{dsn}, ':')[1];
  +      my $method = join '::', 'DBD', $driver, 'db', 'disconnect';
  +      $dbh->$method(); #call the real disconnect method
  +  }
  +  
  +  my $EndToken = '</DBIPool>';
  +  
  +  #parse <DBIPool dbi:mysql:...>...
  +  
  +  sub DBIPool ($$$;*) {
  +      my($cfg, $parms, $dsn, $cfg_fh) = @_;
  +      $dsn =~ s/>$//;
  +  
  +      $cfg->{DBIPool}->{$dsn}->{dsn} = $dsn;
  +  
  +      while((my $line = <$cfg_fh>) !~ m:^$EndToken:o) {
  +          my($name, $value) = split $line, /\s+/, 2;
  +          $name =~ s/^DBIPool(\w+)/lc $1/ei;
  +          $cfg->{DBIPool}->{$dsn}->{$name} = $value;
  +      }
  +  }
  +  
  +  sub config {
  +      my $r = Apache->request;
  +      return Apache::ModuleConfig->get($r, __PACKAGE__);
  +  }
  +  
  +  #called from DBI::connect
  +  sub connect {
  +      my($class, $drh) = (shift, shift);
  +  
  +      $drh->{DSN} = join ':', 'dbi', $drh->{Name}, $_[0];
  +      my $cfg = config();
  +  
  +      my $tip = $cfg->{TIPool}->{ $drh->{DSN} };
  +  
  +      unless ($tip) {
  +          #XXX: do a real connect or fallback to Apache::DBI
  +      }
  +  
  +      my $item = $tip->pop; #select a connection from the pool
  +  
  +      $r->register_cleanup(sub { #incase disconnect() is not called
  +          $tip->putback($item);
  +      });
  +  
  +      return bless 'Apache::DBIPool::db', $item->data; #the dbh
  +  }
  +  
  +  package Apache::DBIPool::db;
  +  
  +  our @ISA = qw(DBI::db);
  +  
  +  #override disconnect, puts database handle back in the pool
  +  sub disconnect {
  +      my $dbh = shift;
  +      my $tip = config()->{TIPool}->{ $dbh->{DSN} };
  +      $tip->putback($dbh);
  +      1;
  +  }
  +  
  +  1;
  +  __END__
   
   =head1 PerlOptions Directive
   
  -A new configuration directive to mod_perl-2.0, I<PerlOptions>,
  +A new configuration directive to mod_perl-2.0, C<PerlOptions>,
   provides fine-grained configuration for what were compile-time only
   options in mod_perl-1.xx.  In addition, this directive provides
  -control over what class of I<PerlInterpreter> is used for a
  -I<VirtualHost> or location configured with I<Location>, I<Directory>, etc.
  +control over what class of C<PerlInterpreter> is used for a
  +C<E<lt>VirtualHostE<gt>> or location configured with
  +C<E<lt>LocationE<gt>>, C<E<lt>DirectoryE<gt>>, etc.
   
   These are all best explained with examples, first here's how to
   disable mod_perl for a certain host:
   
  - <VirtualHost ...>
  -    PerlOptions -Enable
  - </VirtualHost>
  +  <VirtualHost ...>
  +      PerlOptions -Enable
  +  </VirtualHost>
   
   
  -Suppose a one of the hosts does not want to allow users to configure
  -I<PerlAuthenHandler>, I<PerlAuthzHandler> or I<PerlAccessHandler> or
  -<Perl> sections:
  -
  - <VirtualHost ...>
  -    PerlOptions -Authen -Authz -Access -Sections
  - </VirtualHost>
  +Suppose one of the hosts does not want to allow users to configure
  +C<PerlAuthenHandler>, C<PerlAuthzHandler>, C<PerlAccessHandler> and
  +E<lt>PerlE<gt> sections:
  +
  +  <VirtualHost ...>
  +      PerlOptions -Authen -Authz -Access -Sections
  +  </VirtualHost>
   
   Or maybe everything but the response handler:
   
  - <VirtualHost ...>
  -    PerlOptions None +Response
  - </VirtualHost>
  +  <VirtualHost ...>
  +      PerlOptions None +Response
  +  </VirtualHost>
   
   A common problem with mod_perl-1.xx was the shared namespace between
   all code within the process.  Consider two developers using the same
   server and each which to run a different version of a module with the
   same name.  This example will create two I<parent> Perls, one for each 
  -I<VirtualHost>, each with its own namespace and pointing to a
  +C<E<lt>VirtualHostE<gt>>, each with its own namespace and pointing to a
   different paths in C<@INC>:
   
  - <VirtualHost ...>
  -    ServerName dev1
  -    PerlOptions +Parent
  -    PerlSwitches -Mblib=/home/dev1/lib/perl
  - </VirtualHost>
  -
  - <VirtualHost ...>
  -    ServerName dev2
  -    PerlOptions +Parent
  -    PerlSwitches -Mblib=/home/dev2/lib/perl
  - </VirtualHost>
  +  <VirtualHost ...>
  +      ServerName dev1
  +      PerlOptions +Parent
  +      PerlSwitches -Mblib=/home/dev1/lib/perl
  +  </VirtualHost>
  +
  +  <VirtualHost ...>
  +      ServerName dev2
  +      PerlOptions +Parent
  +      PerlSwitches -Mblib=/home/dev2/lib/perl
  +  </VirtualHost>
   
   Or even for a given location, for something like "dirty" cgi scripts:
   
  - <Location /cgi-bin>
  -    PerlOptions +Parent
  -    PerlInterpMaxRequests 1
  -    PerlInterpStart 1
  -    PerlInterpMax 1
  -    PerlResponseHandler Apache::Registry
  - </Location>
  +  <Location /cgi-bin>
  +      PerlOptions +Parent
  +      PerlInterpMaxRequests 1
  +      PerlInterpStart 1
  +      PerlInterpMax 1
  +      PerlResponseHandler Apache::Registry
  +  </Location>
   
  -Will use a fresh interpreter with its own namespace to handle each
  +will use a fresh interpreter with its own namespace to handle each
   request.
   
   Should you wish to fine tune Interpreter pools for a given host:
   
  - <VirtualHost ...>
  -    PerlOptions +Clone
  -    PerlInterpStart 2
  -    PerlInterpMax 2
  - </VirtualHost>
  +  <VirtualHost ...>
  +      PerlOptions +Clone
  +      PerlInterpStart 2
  +      PerlInterpMax 2
  +  </VirtualHost>
   
   This might be worthwhile in the case where certain hosts have their
   own sets of large-ish modules, used only in each host.  By tuning each 
  -host to have it's own pool, that host will continue to reuse the Perl
  +host to have its own pool, that host will continue to reuse the Perl
   allocations in their specific modules.
   
   In 1.x versions of mod_perl, configured Perl*Handlers which are not a
  @@ -707,14 +714,14 @@
   not auto-loaded during startup-time resolution.  It is possible to
   configure this feature with:
   
  - PerlOptions +Autoload
  +  PerlOptions +Autoload
   
   Consider this configuration:
   
  - PerlResponseHandler Apache::Magick
  +  PerlResponseHandler Apache::Magick
   
  -In this case, I<Apache::Magick> is the package name, and the
  -subroutine name will default to I<handler>.  If the I<Apache::Magick>
  +In this case, C<Apache::Magick> is the package name, and the
  +subroutine name will default to I<handler>.  If the C<Apache::Magick>
   module is not already loaded, B<PerlOptions +Autoload> will attempt to
   pull it in at startup time.
   
  @@ -722,28 +729,28 @@
   
   The mod_perl-2.0 interface to the Apache filter API is much simpler
   than the C API, hiding most of the details underneath.  Perl filters
  -are configured using the I<PerlFilterHandler> directive, for example:
  +are configured using the C<PerlFilterHandler> directive, for example:
   
  - PerlFilterHandler Apache::ReverseFilter
  +  PerlFilterHandler Apache::ReverseFilter
   
   This simply registers the filter, which can then be turned on using
  -the core I<AddOutputFilter> directive:
  +the core C<AddOutputFilter> directive:
   
  - <Location /foo>
  -    AddOutputFilter Apache::ReverseFilter
  - </Location>
  +  <Location /foo>
  +      AddOutputFilter Apache::ReverseFilter
  +  </Location>
   
  -The I<Apache::ReverseFilter> handler will now be called for anything
  -accessed in the I</foo> url space.  The I<AddOutputFilter> directive takes
  +The C<Apache::ReverseFilter> handler will now be called for anything
  +accessed in the I</foo> url space.  The C<AddOutputFilter> directive takes
   any number of filters, for example, this configuration will first send 
   the output to I<mod_include>, which will in turn pass its output down
  -to I<Apache::ReverseFilter>:
  +to C<Apache::ReverseFilter>:
   
  - AddOutputFilter INCLUDE Apache::ReverseFilter
  +  AddOutputFilter INCLUDE Apache::ReverseFilter
   
  -For our example, I<Apache::ReverseFilter> simply reverses all of the
  +For our example, C<Apache::ReverseFilter> simply reverses all of the
   output characters and then sends them downstream.  The first argument
  -to a filter handler is an I<Apache::Filter> object, which at the
  +to a filter handler is an C<Apache::Filter> object, which at the
   moment provides two methods I<read> and I<write>.  The I<read> method
   pulls down a chunk of the output stream into the given buffer,
   returning the length read into the buffer.  An optional size argument
  @@ -753,21 +760,21 @@
   filter.  In our case C<scalar reverse> takes advantage of Perl's
   builtins to reverse the upstream buffer:
   
  - package Apache::ReverseFilter;
  -
  - use strict;
  -
  - sub handler {
  -     my $filter = shift;
  -
  -     while ($filter->read(my $buffer, 1024)) {
  -         $filter->write(scalar reverse $buffer);
  -     }
  -
  -     return Apache::OK;
  - }
  -
  - 1;
  +  package Apache::ReverseFilter;
  +  
  +  use strict;
  +  
  +  sub handler {
  +      my $filter = shift;
  +  
  +      while ($filter->read(my $buffer, 1024)) {
  +          $filter->write(scalar reverse $buffer);
  +      }
  +  
  +      return Apache::OK;
  +  }
  +  
  +  1;
   
   =head1 Perl interface to the APR and Apache API
   
  @@ -779,20 +786,19 @@
   The goal for 2.0 is to generate the majority of xs code and provide
   thin wrappers were needed to make the API more Perlish.  As part of
   this goal, nearly the entire APR and Apache API, along with their
  -public data structures will covered from the get-go.  Certain
  -functions and structures which are considered "private" to Apache or
  -otherwise un-useful to Perl will not be glued.  The API behaves just
  -as it did in 1.x, sosers of the API will not notice the difference,
  -other than the addition of many new methods.  And in the case of
  -I<APR>, it is possible to use I<APR> modules outside of Apache, for
  -example:
  +public data structures are covered from the get-go.  Certain functions
  +and structures which are considered "private" to Apache or otherwise
  +un-useful to Perl aren't glued.  The API behaves just as it did in
  +1.x, so users of the API will not notice the difference, other than the
  +addition of many new methods.  And in the case of C<APR>, it is
  +possible to use C<APR> modules outside of Apache, for example:
   
  - % perl -MAPR -MAPR::UUID -le 'print APR::UUID->new->format'
  - b059a4b2-d11d-b211-bc23-d644b8ce0981
  +  % perl -MAPR -MAPR::UUID -le 'print APR::UUID->new->format'
  +  b059a4b2-d11d-b211-bc23-d644b8ce0981
   
   The mod_perl generator is a custom suite of modules specifically tuned
   for gluing Apache and allows for complete control over I<everything>,
  -providing many possibilities none of I<xsubpp>, I<swig> nor
  +providing many possibilities none of I<xsubpp>, I<SWIG> nor
   I<Inline.pm> are designed to do.  Advantages to generating the glue
   code include:
   
  @@ -840,142 +846,141 @@
   
   =head2 Apache::Echo
   
  -Apache 2.0 ships with an example protocol module, I<mod_echo>, which
  +Apache 2.0 ships with an example protocol module, C<mod_echo>, which
   simply reads data from the client and echos it right back.  Here we'll 
  -take a look at a Perl version of that module, called I<Apache::Echo>.
  +take a look at a Perl version of that module, called C<Apache::Echo>.
   A protocol handler is configured using the
  -I<PerlProcessConnectionHandler> directive and we'll use the I<Listen> 
  -and I<VirtualHost> directives to bind to a non-standard port B<8084>:
  +C<PerlProcessConnectionHandler> directive and we'll use the C<Listen> 
  +and C<E<lt>VirtualHostE<gt>> directives to bind to a non-standard port B<8084>:
   
  - Listen 8084
  - <VirtualHost _default_:8084>
  -     PerlProcessConnectionHandler Apache::Echo
  - </VirtualHost>
  +  Listen 8084
  +  <VirtualHost _default_:8084>
  +      PerlProcessConnectionHandler Apache::Echo
  +  </VirtualHost>
   
  -Apache::Echo is then enabled when starting Apache:
  +C<Apache::Echo> is then enabled when starting Apache:
   
  - % httpd
  +  % httpd
   
   And we give it a whirl:
   
  - % telnet localhost 8084
  - Trying 127.0.0.1...
  - Connected to localhost (127.0.0.1).
  - Escape character is '^]'.
  - hello apachecon
  - hello apachecon
  - ^]
  +  % telnet localhost 8084
  +  Trying 127.0.0.1...
  +  Connected to localhost (127.0.0.1).
  +  Escape character is '^]'.
  +  mod_perl rules
  +  mod_perl rules
  +  ^]
   
   The code is just a few lines of code, with the standard I<package>
   declaration and of course, C<use strict;>.  As with all
  -I<Perl*Handler>s, the subroutine name defaults to I<handler>.  However, 
  -in the case of a protocol handler, the first argument is not a
  -I<request_rec>, but a I<conn_rec> blessed into the
  -I<Apache::Connection> class.  We have direct access to the client
  -socket via I<Apache::Connection>'s I<client_socket> method.  This
  -returns an object blessed into the I<APR::Socket> class.
  +C<Perl*Handler>s, the subroutine name defaults to I<handler>.
  +However, in the case of a protocol handler, the first argument is not
  +a C<request_rec>, but a C<conn_rec> blessed into the
  +C<Apache::Connection> class.  We have direct access to the client
  +socket via C<Apache::Connection>'s I<client_socket> method.  This
  +returns an object blessed into the C<APR::Socket> class.
   
   Inside the echo loop, we attempt to read B<BUFF_LEN> bytes from the
   client socket into the C<$buff> buffer.  The C<$rlen> parameter will
  -be set to the number of bytes actually read.  The I<APR::Socket>
  +be set to the number of bytes actually read.  The C<APR::Socket>
   I<recv> method will return an I<apr_status_t> value, be we need only
   check the read length to break out of the loop if it is less than or
   equal to B<0> bytes. If we received some data, it is immediately
  -echoed back to the client with the I<APR::Socket> I<send> method.
  -If we were unable to echo back the same number of bytes read from the
  +echoed back to the client with the C<APR::Socket> I<send> method.  If
  +we were unable to echo back the same number of bytes read from the
   client, assume the connection was dropped and break out of the loop.
   Once the client has disconnected, the module returns B<Apache::OK>,
   telling Apache we have handled the connection:
   
  - package Apache::Echo;
  - 
  - use strict;
  - use Apache::Connection ();
  - use APR::Socket ();
  - 
  - use constant BUFF_LEN => 1024;
  - 
  - sub handler {
  -     my Apache::Connection $c = shift;
  -     my APR::Socket $socket = $c->client_socket;
  - 
  -     my $buff;
  - 
  -     for (;;) {
  -         my($rlen, $wlen);
  -         my $rlen = BUFF_LEN;
  -         $socket->recv($buff, $rlen);
  -         last if $rlen <= 0;
  -         $wlen = $rlen;
  -         $socket->send($buff, $wlen);
  -         last if $wlen != $rlen;
  -     }
  - 
  -     return Apache::OK;
  - }
  - 
  - 1;
  - __END__
  +  package Apache::Echo;
  +  
  +  use strict;
  +  use Apache::Connection ();
  +  use APR::Socket ();
  +  
  +  use constant BUFF_LEN => 1024;
  +  
  +  sub handler {
  +      my Apache::Connection $c = shift;
  +      my APR::Socket $socket = $c->client_socket;
  +  
  +      my $buff;
  +  
  +      for (;;) {
  +          my($rlen, $wlen);
  +          my $rlen = BUFF_LEN;
  +          $socket->recv($buff, $rlen);
  +          last if $rlen <= 0;
  +          $wlen = $rlen;
  +          $socket->send($buff, $wlen);
  +          last if $wlen != $rlen;
  +      }
  +  
  +      return Apache::OK;
  +  }
  +  
  +  1;
   
   =head2 Apache::CommandServer
   
   Our first protocol handler example took advange of Apache's server
   framework, but did not tap into any other modules.  The next example
   is based on the example in the "TCP Servers with IO::Socket" section
  -of I<perlipc>.  Of course, we don't need I<IO::Socket> since Apache
  -takes care of those details for us.  The rest of that example can
  -still be used to illustrate implementing a simple text protocol.  In
  -this case, one where a command is sent by the client to be executed on
  -the server side, with results sent back to the client.
  +of the I<perlipc> manpage.  Of course, we don't need C<IO::Socket>
  +since Apache takes care of those details for us.  The rest of that
  +example can still be used to illustrate implementing a simple text
  +protocol.  In this case, one where a command is sent by the client to
  +be executed on the server side, with results sent back to the client.
   
  -The I<Apache::CommandServer> handler will support four commands:
  -I<motd>, I<date>, I<who> and I<quit>.  These are probably not
  +The C<Apache::CommandServer> handler will support four commands:
  +C<motd>, C<date>, C<who> and C<quit>.  These are probably not
   commands which can be exploited, but should we add such commands,
   we'll want to limit access based on ip address/hostname,
   authentication and authorization.  Protocol handlers need to take care 
   of these tasks themselves, since we bypass the HTTP protocol handler.
   
  -As with all I<PerlProcessConnectionHandlers>, we are passed an
  -I<Apache::Connection> object as the first argument.  Again, we will be
  +As with all C<PerlProcessConnectionHandlers>, we are passed an
  +C<Apache::Connection> object as the first argument.  Again, we will be
   directly accessing the client socket via the I<client_socket> method.
   The I<login> subroutine is called to check if access by this client
  -should be allowed.  This routine makes up for what we lost with the 
  +should be allowed.  This routine makes up for what we lost with the
   core HTTP protocol handler bypassed.  First we call the
  -I<Apache::RequestRec> I<new> method, which returns a I<request_rec>
  -object, just like that which is passed into request time
  -I<Perl*Handlers> and returned by the subrequest API methods,
  +C<Apache::RequestRec> I<new> method, which returns a I<request_rec>
  +object, just like that which is passed at request time to
  +C<Perl*Handlers> and returned by the subrequest API methods,
   I<lookup_uri> and I<lookup_file>.  However, this "fake request" does
   not run handlers for any of the phases, it simply returns an object
   which we can use to do that ourselves.  The C<location_merge> method
   is passed the "location" for this request, it will look up the
  -<Location> section that matches the given name and merge it with the
  -default server configuration.  For example, should we only wish to
  -allow access to this server from certain locations:
  -
  -    <Location Apache::CommandServer>
  -        deny from all
  -        allow from 10.*
  -    </Location>
  +C<E<lt>LocationE<gt>> section that matches the given name and merge it
  +with the default server configuration.  For example, should we only
  +wish to allow access to this server from certain locations:
  +
  +  <Location Apache::CommandServer>
  +      deny from all
  +      allow from 10.*
  +  </Location>
   
   The I<location_merge> method only looks up and merges the
  -configuration, we still need to apply it.
  -This is done in I<for> loop, iterating over three methods:
  -I<run_access_checker>, I<run_check_user_id> and I<run_auth_checker>.
  -These methods will call directly into the Apache functions that invoke
  -module handlers for these phases and will return an integer status
  -code, such as B<OK>, B<DECLINED> or B<FORBIDDEN>.  If I<run_access_check>
  -returns something other than B<OK> or B<DECLINED>, that status will be
  -propagated up to the handler routine and then back up to Apache.
  -Otherwise, the access check passed and the loop will break unless
  -I<some_auth_required> returns true.  This would be false given the
  -previous configuration example, but would be true in the presense of a 
  -I<require> directive, such as:
  -
  -    <Location Apache::CommandServer>
  -        deny from all
  -        allow from 10.*
  -        require user dougm
  -    </Location>
  +configuration, we still need to apply it.  This is done in I<for>
  +loop, iterating over three methods: I<run_access_checker>,
  +I<run_check_user_id> and I<run_auth_checker>.  These methods will call
  +directly into the Apache functions that invoke module handlers for
  +these phases and will return an integer status code, such as C<OK>,
  +C<DECLINED> or C<FORBIDDEN>.  If I<run_access_check> returns something
  +other than C<OK> or C<DECLINED>, that status will be propagated up to
  +the handler routine and then back up to Apache.  Otherwise, the access
  +check passed and the loop will break unless I<some_auth_required>
  +returns true.  This would be false given the previous configuration
  +example, but would be true in the presense of a I<require> directive,
  +such as:
  +
  +  <Location Apache::CommandServer>
  +      deny from all
  +      allow from 10.*
  +      require user dougm
  +  </Location>
   
   Given this configuration, I<some_auth_required> will return true.
   The I<user> method is then called, which will return false if we have
  @@ -1003,141 +1008,141 @@
   return a true value, we break out of the loop.  Let's give it a try
   with this configuration:
   
  - Listen 8085
  - <VirtualHost _default_:8085>
  -     PerlProcessConnectionHandler Apache::CommandServer
  -
  -     <Location Apache::CommandServer>
  -         allow from 127.0.0.1
  -         require user dougm
  -         satisfy any
  -         AuthUserFile /tmp/basic-auth
  -     </Location>
  - </VirtualHost>
  -
  - % telnet localhost 8085
  - Trying 127.0.0.1...
  - Connected to localhost (127.0.0.1).
  - Escape character is '^]'.
  - Login: dougm
  - Password: foo
  - Welcome to Apache::CommandServer
  - Available commands: motd date who quit
  - motd
  - Have a lot of fun...
  - date
  - Mon Mar 12 19:20:10 PST 2001
  - who
  - dougm    tty1     Mar 12 00:49
  - dougm    pts/0    Mar 12 11:23
  - dougm    pts/1    Mar 12 14:08
  - dougm    pts/2    Mar 12 17:09
  - quit
  - Connection closed by foreign host.
  +  Listen 8085
  +  <VirtualHost _default_:8085>
  +      PerlProcessConnectionHandler Apache::CommandServer
  +  
  +      <Location Apache::CommandServer>
  +          allow from 127.0.0.1
  +          require user dougm
  +          satisfy any
  +          AuthUserFile /tmp/basic-auth
  +      </Location>
  +  </VirtualHost>
  +
  +  % telnet localhost 8085
  +  Trying 127.0.0.1...
  +  Connected to localhost (127.0.0.1).
  +  Escape character is '^]'.
  +  Login: dougm
  +  Password: foo
  +  Welcome to Apache::CommandServer
  +  Available commands: motd date who quit
  +  motd
  +  Have a lot of fun...
  +  date
  +  Mon Mar 12 19:20:10 PST 2001
  +  who
  +  dougm    tty1     Mar 12 00:49
  +  dougm    pts/0    Mar 12 11:23
  +  dougm    pts/1    Mar 12 14:08
  +  dougm    pts/2    Mar 12 17:09
  +  quit
  +  Connection closed by foreign host.
   
   =head2 Apache::CommandServer Source
   
  - package Apache::CommandServer;
  - 
  - use strict;
  - use Apache::Connection ();
  - use APR::Socket ();
  - 
  - my @cmds = qw(motd date who quit);
  - my %commands = map { $_, \&{$_} } @cmds;
  - 
  - sub handler {
  -     my Apache::Connection $c = shift;
  -     my APR::Socket $socket = $c->client_socket;
  - 
  -     if ((my $rc = login($c)) != Apache::OK) {
  -         $socket->send("Access Denied\n");
  -         return $rc;
  -     }
  - 
  -     $socket->send("Welcome to " . __PACKAGE__ .
  -                   "\nAvailable commands: @cmds\n");
  - 
  -     for (;;) {
  -         my $cmd;
  -         next unless $cmd = getline($socket);
  - 
  -         if (my $sub = $commands{$cmd}) {
  -             last unless $sub->($socket) == APR::SUCCESS;
  -         }
  -         else {
  -             $socket->send("Commands: @cmds\n");
  -         }
  -     }
  - 
  -     return Apache::OK;
  - }
  - 
  - sub login {
  -     my $c = shift;
  - 
  -     my $r = Apache::RequestRec->new($c);
  -     $r->location_merge(__PACKAGE__);
  - 
  -     for my $method (qw(run_access_checker run_check_user_id run_auth_checker)) {
  -         my $rc = $r->$method();
  - 
  -         if ($rc != Apache::OK and $rc != Apache::DECLINED) {
  -             return $rc;
  -         }
  - 
  -         last unless $r->some_auth_required;
  - 
  -         unless ($r->user) {
  -             my $socket = $c->client_socket;
  -             my $username = prompt($socket, "Login");
  -             my $password = prompt($socket, "Password");
  - 
  -             $r->set_basic_credentials($username, $password);
  -         }
  -     }
  - 
  -     return Apache::OK;
  - }
  - 
  - sub getline {
  -     my $socket = shift;
  -     my $line;
  -     $socket->recv($line, 1024);
  -     return unless $line;
  -     $line =~ s/[\r\n]*$//;
  -     return $line;
  - }
  - 
  - sub prompt {
  -     my($socket, $msg) = @_;
  -     $socket->send("$msg: ");
  -     getline($socket);
  - }
  - 
  - sub motd {
  -     my $socket = shift;
  -     open my $fh, '/etc/motd' or return;
  -     local $/;
  -     my $status = $socket->send(scalar <$fh>);
  -     close $fh;
  -     return $status;
  - }
  - 
  - sub date {
  -     my $socket = shift;
  -     $socket->send(scalar(localtime) . "\n");
  - }
  - 
  - sub who {
  -     my $socket = shift;
  -     $socket->send(scalar `who`);
  - }
  - 
  - sub quit {1}
  - 
  - 1;
  - __END__
  +  package Apache::CommandServer;
  +  
  +  use strict;
  +  use Apache::Connection ();
  +  use APR::Socket ();
  +  
  +  my @cmds = qw(motd date who quit);
  +  my %commands = map { $_, \&{$_} } @cmds;
  +  
  +  sub handler {
  +      my Apache::Connection $c = shift;
  +      my APR::Socket $socket = $c->client_socket;
  +  
  +      if ((my $rc = login($c)) != Apache::OK) {
  +          $socket->send("Access Denied\n");
  +          return $rc;
  +      }
  +  
  +      $socket->send("Welcome to " . __PACKAGE__ .
  +                    "\nAvailable commands: @cmds\n");
  +  
  +      for (;;) {
  +          my $cmd;
  +          next unless $cmd = getline($socket);
  +  
  +          if (my $sub = $commands{$cmd}) {
  +              last unless $sub->($socket) == APR::SUCCESS;
  +          }
  +          else {
  +              $socket->send("Commands: @cmds\n");
  +          }
  +      }
  +  
  +      return Apache::OK;
  +  }
  +  
  +  sub login {
  +      my $c = shift;
  +  
  +      my $r = Apache::RequestRec->new($c);
  +      $r->location_merge(__PACKAGE__);
  +  
  +      for my $method (qw(run_access_checker run_check_user_id run_auth_checker)) {
  +          my $rc = $r->$method();
  +  
  +          if ($rc != Apache::OK and $rc != Apache::DECLINED) {
  +              return $rc;
  +          }
  +  
  +          last unless $r->some_auth_required;
  +  
  +          unless ($r->user) {
  +              my $socket = $c->client_socket;
  +              my $username = prompt($socket, "Login");
  +              my $password = prompt($socket, "Password");
  +  
  +              $r->set_basic_credentials($username, $password);
  +          }
  +      }
  +  
  +      return Apache::OK;
  +  }
  +  
  +  sub getline {
  +      my $socket = shift;
  +      my $line;
  +      $socket->recv($line, 1024);
  +      return unless $line;
  +      $line =~ s/[\r\n]*$//;
  +      return $line;
  +  }
  +  
  +  sub prompt {
  +      my($socket, $msg) = @_;
  +      $socket->send("$msg: ");
  +      getline($socket);
  +  }
  +  
  +  sub motd {
  +      my $socket = shift;
  +      open my $fh, '/etc/motd' or return;
  +      local $/;
  +      my $status = $socket->send(scalar <$fh>);
  +      close $fh;
  +      return $status;
  +  }
  +  
  +  sub date {
  +      my $socket = shift;
  +      $socket->send(scalar(localtime) . "\n");
  +  }
  +  
  +  sub who {
  +      my $socket = shift;
  +      $socket->send(scalar `who`);
  +  }
  +  
  +  sub quit {1}
  +  
  +  1;
  +  __END__
   
   =head1 mod_perl-2.0 Optimizations
   
  @@ -1149,17 +1154,15 @@
   tree and some a combination of both.  In this section we'll take a
   brief look at some of the optimizations that are being considered.
   
  -The details of these optimizations will from the most part be hidden
  -from mod_perl users, the exeception being that some will only be turned 
  -on with configuration directives.  The explanation of these
  -optimization ideas are best left for the live talk, a few which will
  -be overviewed include:
  +The details of these optimizations from the most part are hidden from
  +mod_perl users, the exception being that some will only be turned on
  +with configuration directives.  A few of which include:
   
   =over 4
   
   =item *
   
  -"Compiled" Perl*Handlers
  +"Compiled" C<Perl*Handlers>
   
   =item *
   
  @@ -1167,11 +1170,11 @@
   
   =item *
   
  -`print' enhancements
  +I<print> enhancements
   
   =item *
   
  -Inlined Apache::*.xs calls
  +Inlined C<Apache::*.xs> calls
   
   =item *
   
  
  
  

---------------------------------------------------------------------
To unsubscribe, e-mail: docs-cvs-unsubscribe@perl.apache.org
For additional commands, e-mail: docs-cvs-help@perl.apache.org