You are viewing a plain text version of this content. The canonical link for it is here.
Posted to modperl-cvs@perl.apache.org by sb...@locus.apache.org on 2000/06/08 00:45:56 UTC

cvs commit: modperl-site/guide CHANGES advocacy.html browserbugs.html config.html control.html correct_headers.html databases.html dbm.html debug.html download.html frequent.html hardware.html help.html index.html index_long.html install.html intro.html mod_perl_guide.pdf.gz modules.html multiuser.html performance.html perl.html porting.html scenario.html security.html snippets.html start.html strategy.html style.css troubleshooting.html

sbekman     00/06/07 15:45:47

  Modified:    guide    CHANGES advocacy.html browserbugs.html config.html
                        control.html correct_headers.html databases.html
                        dbm.html debug.html download.html frequent.html
                        hardware.html help.html index.html index_long.html
                        install.html intro.html mod_perl_guide.pdf.gz
                        modules.html multiuser.html performance.html
                        perl.html porting.html scenario.html security.html
                        snippets.html start.html strategy.html style.css
                        troubleshooting.html
  Log:
  06.07.2000 ver 1.24
  
  * perl: "catching exceptions" -- a few corrections (Matt Sergeant)
  
  * modules: added Apache::Gzip (Ken Williams)
  
  * guide's design
  
    o put back the links underlining
  
    o background-color: #ffffee;
  
    o added (jump) menus to reach search/download/index from everywhere
  
    o added the two new search engines (both working on the split
      version of the guide)
  
  * guide's build:
  
    o The build code was completely rewritten, html2ps is now bundled
      with the guide so one can create PS version, and if there is
      ps2pdf the PDF version.
  
    o It can produce the split version of the Guide.
  
    o One can easily reuse the package to build his own docs, since the
      look-n-feel has been moved into the templates from the code.
  
    o Once I feel confident I'll probably separate the build code from
      the Guide to give it its own life and make it easier to reuse by
      other developers. I need testers who want to use this package
      before I release it a separate module.
  
  * performance:
  
    o old sections rewritten/improved:
      - Are My Variables Shared?
      - Preloading Registry Scripts
      - Calculating Real Memory Usage
      - Preloading Perl Modules at Server Startup
      -  Preloading Registry Scripts at Server Startup
      - Forking and Executing Subprocesses from mod_perl
        = Spawning a Detachable Sub-Process
        = Gory Details About fork()
        = Executing system() in the Right Way
        = Avoiding Zombie Processes
  
    o new sections:
      - Apache/mod_perl Build Options
        = mod_perl Process Size as a Function of Compiled in C Modules and
                 mod_perl Features
      - Modules Initializing at Server Startup
        = Initializing DBI.pm (corrections by Tim Bunce)
        = Initializing CGI.pm
  
  * control:
  
    o These sections were rewritten and extended:
      - Server Maintenance Chores
          = Handling Log Files
            + Log Rotation
            + Non-Scheduled Emergency Log Rotation
  
    o 'cyclog' is now called multilog (from daemontools package)
  
    o Moved from debug and rewritten "Speeding up the Apache Termination
      and Restart"
  
    o Rewritten and extended "SUID Start-up Scripts" with:
      "Introduction to SUID Executables"
      "Apache Startup SUID Script's Security"
      "Sample Apache Startup SUID Script"
  
  * hardware: partly rewritten and improved.
  
  * reconstruction process: obvious.pod has been disassembled and merged
    into debug.pod.
  
  * debug: update: Apache::DumpHeaders (Ask Bjoern Hansen)
  
  * troubleshooting: PerlFreshRestart is irrelevant for DSO (Vivek
    Khera, Doug)
  
  * review:
  
    o Drew Taylor has reviewed these chapters: scenario and strategy
      chapters.
  
    o Mark Summerfield has reviewed these chapters: scenario, perl and
      strategy chapters.
  
    o Eric Cholet has reviewed the porting chapter.
  
  * Minor corrections:
    o download (Salve J Nilsen)
    o performance (w trillich)
    o perl (Scott Holdren)
    o snippets+download (Ask Bjoern Hansen)
    o debug (Robert Mathews)
    o scenario (Tuomas Salo)
  
  Revision  Changes    Path
  1.24      +106 -1    modperl-site/guide/CHANGES
  
  Index: CHANGES
  ===================================================================
  RCS file: /home/cvs/modperl-site/guide/CHANGES,v
  retrieving revision 1.23
  retrieving revision 1.24
  diff -u -r1.23 -r1.24
  --- CHANGES	2000/05/12 22:42:49	1.23
  +++ CHANGES	2000/06/07 22:45:29	1.24
  @@ -2,8 +2,113 @@
   		### mod_perl Guide CHANGES file ###
   		###################################
   
  +06.07.2000 ver 1.24
   
  -05.09.2000 ver 1.23
  +* perl: "catching exceptions" -- a few corrections (Matt Sergeant)
  +
  +* modules: added Apache::Gzip (Ken Williams)
  +
  +* guide's design
  +
  +  o put back the links underlining
  +
  +  o background-color: #ffffee;
  +
  +  o added (jump) menus to reach search/download/index from everywhere
  +  
  +  o added the two new search engines (both working on the split
  +    version of the guide)
  +
  +* guide's build: 
  +
  +  o The build code was completely rewritten, html2ps is now bundled
  +    with the guide so one can create PS version, and if there is
  +    ps2pdf the PDF version.
  +
  +  o It can produce the split version of the Guide.
  +
  +  o One can easily reuse the package to build his own docs, since the
  +    look-n-feel has been moved into the templates from the code.
  +
  +  o Once I feel confident I'll probably separate the build code from
  +    the Guide to give it its own life and make it easier to reuse by
  +    other developers. I need testers who want to use this package
  +    before I release it a separate module.
  +
  +* performance: 
  +
  +  o old sections rewritten/improved:
  +    - Are My Variables Shared?
  +    - Preloading Registry Scripts
  +    - Calculating Real Memory Usage
  +    - Preloading Perl Modules at Server Startup 
  +    -  Preloading Registry Scripts at Server Startup 
  +    - Forking and Executing Subprocesses from mod_perl 
  +      = Spawning a Detachable Sub-Process
  +      = Gory Details About fork()
  +      = Executing system() in the Right Way
  +      = Avoiding Zombie Processes
  +
  +  o new sections:
  +    - Apache/mod_perl Build Options
  +      = mod_perl Process Size as a Function of Compiled in C Modules and
  +               mod_perl Features
  +    - Modules Initializing at Server Startup
  +      = Initializing DBI.pm (corrections by Tim Bunce)
  +      = Initializing CGI.pm
  +
  +* control: 
  +
  +  o These sections were rewritten and extended:
  +    - Server Maintenance Chores 
  +        = Handling Log Files 
  +          + Log Rotation 
  +          + Non-Scheduled Emergency Log Rotation 
  +
  +  o 'cyclog' is now called multilog (from daemontools package)
  +
  +  o Moved from debug and rewritten "Speeding up the Apache Termination
  +    and Restart"
  +
  +  o Rewritten and extended "SUID Start-up Scripts" with: 
  +    "Introduction to SUID Executables"
  +    "Apache Startup SUID Script's Security"
  +    "Sample Apache Startup SUID Script"
  +
  +* hardware: partly rewritten and improved.
  +
  +* reconstruction process: obvious.pod has been disassembled and merged
  +  into debug.pod.
  +
  +* debug: update: Apache::DumpHeaders (Ask Bjoern Hansen)
  +
  +* troubleshooting: PerlFreshRestart is irrelevant for DSO (Vivek
  +  Khera, Doug)
  +
  +* review: 
  +
  +  o Drew Taylor has reviewed these chapters: scenario and strategy
  +    chapters.
  +
  +  o Mark Summerfield has reviewed these chapters: scenario, perl and
  +    strategy chapters.
  +
  +  o Eric Cholet has reviewed the porting chapter.
  +
  +* Minor corrections: 
  +  o download (Salve J Nilsen)
  +  o performance (w trillich) 
  +  o perl (Scott Holdren) 
  +  o snippets+download (Ask Bjoern Hansen) 
  +  o debug (Robert Mathews) 
  +  o scenario (Tuomas Salo)
  +
  +
  +
  +
  +
  +
  +05.12.2000 ver 1.23
   
   * guide's layout changed: Now there are two index files -- the default
     index.html shows only the names of the chapters in TOC, the new
  
  
  
  1.9       +171 -119  modperl-site/guide/advocacy.html
  
  Index: advocacy.html
  ===================================================================
  RCS file: /home/cvs/modperl-site/guide/advocacy.html,v
  retrieving revision 1.8
  retrieving revision 1.9
  diff -u -r1.8 -r1.9
  --- advocacy.html	2000/05/12 22:42:50	1.8
  +++ advocacy.html	2000/06/07 22:45:29	1.9
  @@ -1,68 +1,92 @@
   <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
  -<HTML>
  -<HEAD>
  -   <TITLE>mod_perl guide: mod_perl Advocacy</TITLE>
  -   <META NAME="GENERATOR" CONTENT="Pod2HTML [Perl/Linux]">
  -   <META NAME="Author" CONTENT="Stas Bekman">
  -   <META NAME="Description" CONTENT="All Apache/Perl related information: Hints, Guidelines, Scenarios and Troubleshottings">
  -   <META NAME="keywords" CONTENT="mod_perl modperl perl apache cgi webserver speed  fast guide mod_perl apache guide help info faq mod_perl installation cgi troubleshooting help no sex speedup free open source OSS mod_perl apache guide">
  -</HEAD>
  -     <LINK REL=STYLESHEET TYPE="text/css"
  -        HREF="style.css" TITLE="refstyle">
  -     <style type="text/css">
  -     <!-- 
  -        @import url(style.css);
  -     -->
  -     
  -     </style>
  -<BODY BGCOLOR="white">
  +<html>
  +  <head>
  +   <title>mod_perl guide: mod_perl Advocacy</title>
  +   <meta name="Author" content="Stas Bekman">
  +   <meta name="Description" content="All Apache/Perl related information: Hints, Guidelines, Scenarios and Troubleshottings">
  +   <meta name="keywords" content="mod_perl modperl perl cgi apache webserver speed fast guide mod_perl apache guide help info faq mod_perl installation cgi troubleshooting help no sex speedup free open source OSS mod_perl apache guide">
  +   <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
  +   <meta name="Classification" content="information">
  +   <link href="style.css" rel=stylesheet type="text/css" title="refstyle">
  +  </head>
  +  <body>
  +
  +    <h1 align=center>
  +      <a href="http://perl.apache.org"><img src="images/mod_perl.gif" alt="Mod Perl Icon" border=0 height=30 width=90 align=left></a>
  +      <a href="http://perl.apache.org"><img src="images/mod_perl.gif" alt="Mod Perl Icon" border=0 height=30 width=90 align=right></a>
  +      mod_perl Advocacy
  +    </h1>
  +    <hr>
  +    <p>
  +    <div class="navbar">
  +      <a href="hardware.html">Prev</a>                                 |
  +      <a href="index.html"         >Contents</a> |
  +      <a href="index.html#search"  >Search</a>   |
  +      <a href="index.html#download">Download</a> |
  +      <a href="help.html">Next</a>
  +    </div>
  +    <p>
  +
  +    <div class="toc">
  +      
   <A NAME="toc"></A>
  -<H1 ALIGN=CENTER>
  -<A HREF="http://perl.apache.org"><IMG SRC="images/mod_perl.gif" ALT="Mod Perl Icon" BORDER=0 HEIGHT=30 WIDTH=90 ALIGN=LEFT></A>
  -<A HREF="http://perl.apache.org"><IMG SRC="images/mod_perl.gif" ALT="Mod Perl Icon" BORDER=0 HEIGHT=30 WIDTH=90 ALIGN=RIGHT></A>
  -mod_perl Advocacy</H1>
  -<HR WIDTH="100%">
  -	    [    <A HREF="hardware.html">Prev</A> |      <A HREF="index.html">Main Page</A> | <A HREF="help.html">Next</A>      ]<HR><!-- INDEX BEGIN -->
  -<P><B><FONT SIZE=-1>Table of Contents:</FONT></B></P>
  +<P><B>Table of Contents:</B></P>
  +
   <UL>
   
   	<LI><A HREF="#Thoughts_about_scalability_and_f">Thoughts about scalability and flexibility</A>
   	<LI><A HREF="#The_boss_the_developer_and_advo">The boss, the developer and advocacy</A>
   	<LI><A HREF="#A_summary_of_perl_cgi_discussion">A summary of perl/cgi discussion at slashdot.org</A>
   </UL>
  -<!-- INDEX END -->
   
  +    </div>
  +
  +    [ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
   <HR>
  +    <table width="60%" align="center">
  +
  +      <tr>
  +	<td>
  +	  <div class="ad">
  +	    The <a href="http://www.modperl.com/">
  +	      <B>Writing Apache Modules with Perl and C</B></a>
  +	    book can be purchased online from <a
  +	      href="http://www.ora.com/catalog/wrapmod/">O'Reilly </a>
  +	    and <a
  +	    href="http://www.amazon.com/exec/obidos/ASIN/156592567X/writinapachemodu">
  +	      Amazon.com</a>.
  +	  </div>
  +	</td>
  +      </tr>
  +
  +      <tr>
  +	<td>
  +	  <div class="notice">
  +	  <B>Your corrections of the technical and grammatical
  +	     errors are very welcome. You are encouraged to help me
  +	     improve this guide.  If you have something to contribute
  +	     please <A HREF="help.html#Contacting_me"> send it
  +	     directly to me</A>.</B>
  +	  </div>
  +	</td>
  +      </tr>
   
  -	     The <a href="http://www.modperl.com/">
  -	     <B>Writing Apache Modules with Perl and C</B></a>
  -	     book can be purchased online from <a
  -	     href="http://www.ora.com/catalog/wrapmod/">O'Reilly </a>
  -	     and <a
  -	     href="http://www.amazon.com/exec/obidos/ASIN/156592567X/writinapachemodu">
  -	     Amazon.com</a>.
  -
  -	     <HR>
  -
  -	       <B>Your corrections of either technical or grammatical
  -	       errors are very welcome. You are encouraged to help me
  -	       to improve this guide.  If you have something to
  -	       contribute please <A
  -	       HREF="help.html#Contacting_me"> send it
  -	       directly to me</A>.
  -	       </B>
  -	       <HR>
  +</table>
   
  -	      <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<P><A NAME="anchor0"></A>
  +    
  +
  +	    [ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
  +
  +<P>
   <CENTER><H1><A NAME="Thoughts_about_scalability_and_f">Thoughts about scalability and flexibility</A></H1></CENTER>
  -<P><A NAME="anchor1"></A>
  +<P>
   Your need for scalability and flexibility depends on what you need from
   your web site. If you only want a simple guest book or database gateway
   with no feature headroom, you can get away with any
   EASY_AND_FAST_TO_DEVELOP_TOOL (Exchange, MS IIS, Lotus Notes, etc).
   
  -<P><A NAME="anchor2"></A>
  +<P>
   Experience shows that you will soon want more functionality, at which point
   you'll discover the limitations of these ``easy'' tools. Gradually, your
   boss will ask for increasing functionality and at some point you'll realize
  @@ -72,7 +96,7 @@
   in learning how to use a powerful, flexible tool to make the long-term
   development cycle easier.
   
  -<P><A NAME="anchor3"></A>
  +<P>
   If you and your company are serious about delivering flexible Internet
   functionality, do your homework. Then urge your boss to invest a little
   extra time and resources in choosing the right tool for the job. The extra
  @@ -80,10 +104,11 @@
   new and improved functionality of high quality and in good time will prove
   the superiority of using solid flexible tools.
   
  -<P><A NAME="anchor4"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H1><A NAME="The_boss_the_developer_and_advo">The boss, the developer and advocacy</A></H1></CENTER>
  -<P><A NAME="anchor5"></A>
  +<P>
   Each developer has a boss who participates in the decision-making process.
   Remember that the boss considers input from sales people, developers, the
   media and associates before handing down large decisions. Of course,
  @@ -91,7 +116,7 @@
   working demonstration, and demonstrations of company-specific and
   developer-specific results count for a lot!
   
  -<P><A NAME="anchor6"></A>
  +<P>
   Personally, when I discovered mod_perl I did a lot of testing and coding at
   home and at work. Once I had a working heavy application, I came to my boss
   with two URLs - one for the plain CGI server and the other for the
  @@ -100,7 +125,7 @@
   developers, which is why I took time to learn it in first place (and why
   this guide was created!).
   
  -<P><A NAME="anchor7"></A>
  +<P>
   Chances are that if you've done your homework, learnt the tools and can
   deliver results, you'll have a successful project. If you convince your
   boss to try a tool that you don't know very well, your results may suffer.
  @@ -108,7 +133,7 @@
   progress is much worse than expected, you might be told to ``forget it''
   and mod_perl might not get a second chance.
   
  -<P><A NAME="anchor8"></A>
  +<P>
   Advocacy is a great thing for the open-source software movement, but it's
   best done quietly until you have confidence that you can show productivity.
   If you can demonstrate to your boss a heavy CGI which is running much
  @@ -116,135 +141,162 @@
   evaluation. Your company may even sponsor a portion of your learning
   process.
   
  -<P><A NAME="anchor9"></A>
  +<P>
   Learn the technology by working on sample projects. Learn how to support
   yourself and learn how to get support from the community; then advocate
   your ideas to your boss. Then you'll have the knowledge; your company will
   have the benefit; and mod_perl will have the reputation it deserves.
   
  -<P><A NAME="anchor10"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H1><A NAME="A_summary_of_perl_cgi_discussion">A summary of perl/cgi discussion at slashdot.org</A></H1></CENTER>
  -<P><A NAME="anchor11"></A>
  +<P>
   Well, there was a nice discussion of merits of Perl in CGI world. I took
   the time to summarize this thread, so here is what I've got:
   
  -<P><A NAME="anchor12"></A>
  +<P>
   Perl Domination in CGI Programming? <A
   HREF="http://slashdot.org/askslashdot/99/10/20/1246241.shtml">http://slashdot.org/askslashdot/99/10/20/1246241.shtml</A>
   
   
   <UL>
   <P><LI>
  -<P><A NAME="anchor13"></A>
  +<P>
   Perl is cool and fun to code with.
   
   <P><LI>
  -<P><A NAME="anchor14"></A>
  +<P>
   Perl is very fast to develop with.
   
   <P><LI>
  -<P><A NAME="anchor15"></A>
  +<P>
   Perl is even faster to develop with if you know what CPAN is. :)
   
   <P><LI>
  -<P><A NAME="anchor16"></A>
  +<P>
   Math intensive code and other stuff which is faster in C/C++, can be
   plugged into Perl with XS/SWIG and may be used transparently by Perl
   programmers.
   
   <P><LI>
  -<P><A NAME="anchor17"></A>
  +<P>
   Most CGI applications do text processing, at which Perl excels
   
   <P><LI>
  -<P><A NAME="anchor18"></A>
  +<P>
   Forking and loading (unless the code is shared) of C/C++ CGI programs
   produces an overhead.
   
   <P><LI>
  -<P><A NAME="anchor19"></A>
  +<P>
   Except for Intranets, bandwidth is usually a bigger bottleneck than Perl
   performance, although this might change in the future.
   
   <P><LI>
  -<P><A NAME="anchor20"></A>
  +<P>
   For database driven applications, the database itself is a bottleneck. Lots
   of posts talk about latency vs throughput.
   
   <P><LI>
  -<P><A NAME="anchor21"></A>
  +<P>
   mod_perl, FastCGI, Velocigen and PerlEx are all give good performance gains
   over plain mod_cgi.
   
   <P><LI>
  -<P><A NAME="anchor22"></A>
  +<P>
   Other light alternatives to Perl and its derivatives which have been
   mentioned: PHP, Python.
   
   <P><LI>
  -<P><A NAME="anchor23"></A>
  +<P>
   There were almost no voices from users of M$ and similar technologies, I
   guess that's because they don't read <A
   HREF="http://slashdot.org">http://slashdot.org</A> :)
   
   <P><LI>
  -<P><A NAME="anchor24"></A>
  +<P>
   Many said that in many people's minds: 'CGI' eq 'Perl'
   
   </UL>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -	     The <a href="http://www.modperl.com/">
  -	     <B>Writing Apache Modules with Perl and C</B></a>
  -	     book can be purchased online from <a
  -	     href="http://www.ora.com/catalog/wrapmod/">O'Reilly </a>
  -	     and <a
  -	     href="http://www.amazon.com/exec/obidos/ASIN/156592567X/writinapachemodu">
  -	     Amazon.com</a>.
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   
  -	     <HR>
   
  -	     <B>Your corrections of either technical or grammatical
  +    <p>
  +    <div class="navbar">
  +      <a href="hardware.html">Prev</a>                                 |
  +      <A HREF="index.html"         >Contents</A> |
  +      <A HREF="index.html#search"  >Search</A>   |
  +      <A HREF="index.html#download">Download</A> |
  +      <a href="help.html">Next</a>
  +    </div>
  +    <p>
  +
  +    <table width="60%" align="center">
  +
  +      <tr>
  +	<td>
  +	  <div class="notice">
  +	  <B>Your corrections of the technical and grammatical
   	     errors are very welcome. You are encouraged to help me
  -	     to improve this guide.  If you have something to
  -	     contribute please <A
  -	     HREF="help.html#Contacting_me"> send it
  +	     improve this guide.  If you have something to contribute
  +	     please <A HREF="help.html#Contacting_me"> send it
   	     directly to me</A>.</B>
  +	  </div>
  +	</td>
  +      </tr>
  +
  +      <tr>
  +	<td>
  +	  <div class="ad">
  +	    The <a href="http://www.modperl.com/">
  +	      <B>Writing Apache Modules with Perl and C</B></a>
  +	    book can be purchased online from <a
  +	      href="http://www.ora.com/catalog/wrapmod/">O'Reilly </a>
  +	    and <a
  +	    href="http://www.amazon.com/exec/obidos/ASIN/156592567X/writinapachemodu">
  +	      Amazon.com</a>.
  +	  </div>
  +	</td>
  +      </tr>
  +
  +</table>
  +
  +<center>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
  +<table cellspacing=2 cellpadding=2>
  +
  +<tr align=center valign=top>
  +<td align=center valign=center>
  +
  +<b><font size=-1>Written by <a
  +href="help.html#Contacting_me">Stas Bekman</a>.<br> Last Modified at 05/27/2000
  +</font></b>
  +<br>
  +
  +</td>
  +
  +<td>
  +
  +<a href="http://perl.apache.org"><img src="images/mod_perl2.jpg"  border=0 alt="mod_perl icon" border=0 height=59 width=150></a>
  +<br>
  +
  +</td>
  +
  +<td>
  +
  +<font size=-2>Use of the Camel for Perl is <br>
  +a trademark of <a href="http://www.ora.com">O'Reilly &amp; Associates</a>,<br>
  +and is used by permission. </font> 
  +<br>
   
  -	     <HR>
  +</td>
   
  -	     [    <A HREF="hardware.html">Prev</A> |      <A HREF="index.html">Main Page</A> | <A HREF="help.html">Next</A>      ]
  +</tr>
  +</table>
  +</center>
   
  -<CENTER><TABLE CELLSPACING=2 CELLPADDING=2 WIDTH="100%" >
  -<TR ALIGN=CENTER VALIGN=TOP>
  -  <TD ALIGN=CENTER VALIGN=CENTER COLSPAN="3">
  -	     <HR>
  -  </TD>
  -</TR>
  -<TR ALIGN=CENTER VALIGN=TOP>
  -  <TD ALIGN=CENTER VALIGN=CENTER>
  -    <B>
  -      <FONT SIZE=-1>
  -	     Written by <A HREF="help.html#Contacting_me">Stas Bekman</A>.
  -	     <BR>Last Modified at 05/03/2000
  -      </FONT>
  -    </B>
  -  </TD>
  -
  -  <TD>
  -	     <A HREF="http://perl.apache.org"><IMG SRC="images/mod_perl2.jpg" ALT="Mod Perl Icon" BORDER=0 HEIGHT=59 WIDTH=150></A>
  -  </TD>
  -
  -  <TD>
  -    <FONT SIZE=-2>
  -	     Use of the Camel for Perl is <BR>
  -	     a trademark of <A HREF="http://www.ora.com">O'Reilly &amp; Associates</A>,<BR>
  -             and is used by permission. 
  -    </FONT> 
  -  </TD>
  -</TR>
  -</TABLE></CENTER>
  -
  -</BODY>
  -</HTML>
  -	    
  \ No newline at end of file
  +</body>
  +</html>
  
  
  
  1.10      +150 -99   modperl-site/guide/browserbugs.html
  
  Index: browserbugs.html
  ===================================================================
  RCS file: /home/cvs/modperl-site/guide/browserbugs.html,v
  retrieving revision 1.9
  retrieving revision 1.10
  diff -u -r1.9 -r1.10
  --- browserbugs.html	2000/05/12 22:42:50	1.9
  +++ browserbugs.html	2000/06/07 22:45:29	1.10
  @@ -1,134 +1,185 @@
   <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
  -<HTML>
  -<HEAD>
  -   <TITLE>mod_perl guide: Workarounds for some known bugs in browsers.</TITLE>
  -   <META NAME="GENERATOR" CONTENT="Pod2HTML [Perl/Linux]">
  -   <META NAME="Author" CONTENT="Stas Bekman">
  -   <META NAME="Description" CONTENT="All Apache/Perl related information: Hints, Guidelines, Scenarios and Troubleshottings">
  -   <META NAME="keywords" CONTENT="mod_perl modperl perl apache cgi webserver speed  fast guide mod_perl apache guide help info faq mod_perl installation cgi troubleshooting help no sex speedup free open source OSS mod_perl apache guide">
  -</HEAD>
  -     <LINK REL=STYLESHEET TYPE="text/css"
  -        HREF="style.css" TITLE="refstyle">
  -     <style type="text/css">
  -     <!-- 
  -        @import url(style.css);
  -     -->
  -     
  -     </style>
  -<BODY BGCOLOR="white">
  +<html>
  +  <head>
  +   <title>mod_perl guide: Workarounds for some known bugs in browsers.</title>
  +   <meta name="Author" content="Stas Bekman">
  +   <meta name="Description" content="All Apache/Perl related information: Hints, Guidelines, Scenarios and Troubleshottings">
  +   <meta name="keywords" content="mod_perl modperl perl cgi apache webserver speed fast guide mod_perl apache guide help info faq mod_perl installation cgi troubleshooting help no sex speedup free open source OSS mod_perl apache guide">
  +   <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
  +   <meta name="Classification" content="information">
  +   <link href="style.css" rel=stylesheet type="text/css" title="refstyle">
  +  </head>
  +  <body>
  +
  +    <h1 align=center>
  +      <a href="http://perl.apache.org"><img src="images/mod_perl.gif" alt="Mod Perl Icon" border=0 height=30 width=90 align=left></a>
  +      <a href="http://perl.apache.org"><img src="images/mod_perl.gif" alt="Mod Perl Icon" border=0 height=30 width=90 align=right></a>
  +      Workarounds for some known bugs in browsers.
  +    </h1>
  +    <hr>
  +    <p>
  +    <div class="navbar">
  +      <a href="debug.html">Prev</a>                                 |
  +      <a href="index.html"         >Contents</a> |
  +      <a href="index.html#search"  >Search</a>   |
  +      <a href="index.html#download">Download</a> |
  +      <a href="modules.html">Next</a>
  +    </div>
  +    <p>
  +
  +    <div class="toc">
  +      
   <A NAME="toc"></A>
  -<H1 ALIGN=CENTER>
  -<A HREF="http://perl.apache.org"><IMG SRC="images/mod_perl.gif" ALT="Mod Perl Icon" BORDER=0 HEIGHT=30 WIDTH=90 ALIGN=LEFT></A>
  -<A HREF="http://perl.apache.org"><IMG SRC="images/mod_perl.gif" ALT="Mod Perl Icon" BORDER=0 HEIGHT=30 WIDTH=90 ALIGN=RIGHT></A>
  -Workarounds for some known bugs in browsers.</H1>
  -<HR WIDTH="100%">
  -	    [    <A HREF="debug.html">Prev</A> |      <A HREF="index.html">Main Page</A> | <A HREF="modules.html">Next</A>      ]<HR><!-- INDEX BEGIN -->
  -<P><B><FONT SIZE=-1>Table of Contents:</FONT></B></P>
  +<P><B>Table of Contents:</B></P>
  +
   <UL>
   
   	<LI><A HREF="#Preventing_QUERY_STRING_from_get">Preventing QUERY_STRING from getting corrupted because of &amp;entity key names</A>
   	<LI><A HREF="#IE_4_x_does_not_re_post_data_to_">IE 4.x does not re-post data to a non-port-80 URL</A>
   </UL>
  -<!-- INDEX END -->
   
  +    </div>
  +
  +    [ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
   <HR>
  +    <table width="60%" align="center">
  +
  +      <tr>
  +	<td>
  +	  <div class="ad">
  +	    The <a href="http://www.modperl.com/">
  +	      <B>Writing Apache Modules with Perl and C</B></a>
  +	    book can be purchased online from <a
  +	      href="http://www.ora.com/catalog/wrapmod/">O'Reilly </a>
  +	    and <a
  +	    href="http://www.amazon.com/exec/obidos/ASIN/156592567X/writinapachemodu">
  +	      Amazon.com</a>.
  +	  </div>
  +	</td>
  +      </tr>
  +
  +      <tr>
  +	<td>
  +	  <div class="notice">
  +	  <B>Your corrections of the technical and grammatical
  +	     errors are very welcome. You are encouraged to help me
  +	     improve this guide.  If you have something to contribute
  +	     please <A HREF="help.html#Contacting_me"> send it
  +	     directly to me</A>.</B>
  +	  </div>
  +	</td>
  +      </tr>
   
  -	     The <a href="http://www.modperl.com/">
  -	     <B>Writing Apache Modules with Perl and C</B></a>
  -	     book can be purchased online from <a
  -	     href="http://www.ora.com/catalog/wrapmod/">O'Reilly </a>
  -	     and <a
  -	     href="http://www.amazon.com/exec/obidos/ASIN/156592567X/writinapachemodu">
  -	     Amazon.com</a>.
  -
  -	     <HR>
  -
  -	       <B>Your corrections of either technical or grammatical
  -	       errors are very welcome. You are encouraged to help me
  -	       to improve this guide.  If you have something to
  -	       contribute please <A
  -	       HREF="help.html#Contacting_me"> send it
  -	       directly to me</A>.
  -	       </B>
  -	       <HR>
  +</table>
   
  -	      <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<P><A NAME="anchor0"></A>
  +    
  +
  +	    [ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
  +
  +<P>
   <CENTER><H1><A NAME="Preventing_QUERY_STRING_from_get">Preventing QUERY_STRING from getting corrupted because of &amp;entity key names</A></H1></CENTER>
  -<P><A NAME="anchor1"></A>
  +<P>
   In a URL which contains a query string, if the string has multiple parts
   separated by ampersands and it contains a key named ``reg'', for example <CODE>http://my.site.com/foo.pl?foo=bar&amp;reg=foobar</CODE>, then some browsers will interpret <CODE>&amp;reg</CODE> as a magic entity and encode it as <CODE>&amp;reg;</CODE>. This will result in a corrupted <CODE>QUERY_STRING</CODE>. If you encounter this problem, then either you should avoid using such
   keys or you should separate parameter pairs with <CODE>;</CODE> instead of <CODE>&amp;</CODE>. Both <CODE>CGI.pm</CODE> and <CODE>Apache::Request</CODE> support a semicolon instead of an ampersand as a separator. So your URI
   should look like this: <CODE>http://my.site.com/foo.pl?foo=bar;reg=foobar</CODE>.
   
  -<P><A NAME="anchor2"></A>
  +<P>
   Note that this is only an issue when you are building your own URLs with
   query strings. It is not a problem when the URL is the result of submitting
   a form because the browsers <EM>have</EM> to get that right.
   
  -<P><A NAME="anchor3"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H1><A NAME="IE_4_x_does_not_re_post_data_to_">IE 4.x does not re-post data to a non-port-80 URL</A></H1></CENTER>
  -<P><A NAME="anchor4"></A>
  +<P>
   One problem with publishing 8080 port numbers (or so I have been told) is
   that IE 4.x has a bug when re-posting data to a non-port-80 URL. It drops
   the port designator and uses port 80 anyway.
   
  -<P><A NAME="anchor5"></A>
  +<P>
   See <A HREF="././config.html#Publishing_Port_Numbers_other_th">Publishing Port Numbers other than 80</A>.
   
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -	     The <a href="http://www.modperl.com/">
  -	     <B>Writing Apache Modules with Perl and C</B></a>
  -	     book can be purchased online from <a
  -	     href="http://www.ora.com/catalog/wrapmod/">O'Reilly </a>
  -	     and <a
  -	     href="http://www.amazon.com/exec/obidos/ASIN/156592567X/writinapachemodu">
  -	     Amazon.com</a>.
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   
  -	     <HR>
   
  -	     <B>Your corrections of either technical or grammatical
  +    <p>
  +    <div class="navbar">
  +      <a href="debug.html">Prev</a>                                 |
  +      <A HREF="index.html"         >Contents</A> |
  +      <A HREF="index.html#search"  >Search</A>   |
  +      <A HREF="index.html#download">Download</A> |
  +      <a href="modules.html">Next</a>
  +    </div>
  +    <p>
  +
  +    <table width="60%" align="center">
  +
  +      <tr>
  +	<td>
  +	  <div class="notice">
  +	  <B>Your corrections of the technical and grammatical
   	     errors are very welcome. You are encouraged to help me
  -	     to improve this guide.  If you have something to
  -	     contribute please <A
  -	     HREF="help.html#Contacting_me"> send it
  +	     improve this guide.  If you have something to contribute
  +	     please <A HREF="help.html#Contacting_me"> send it
   	     directly to me</A>.</B>
  +	  </div>
  +	</td>
  +      </tr>
  +
  +      <tr>
  +	<td>
  +	  <div class="ad">
  +	    The <a href="http://www.modperl.com/">
  +	      <B>Writing Apache Modules with Perl and C</B></a>
  +	    book can be purchased online from <a
  +	      href="http://www.ora.com/catalog/wrapmod/">O'Reilly </a>
  +	    and <a
  +	    href="http://www.amazon.com/exec/obidos/ASIN/156592567X/writinapachemodu">
  +	      Amazon.com</a>.
  +	  </div>
  +	</td>
  +      </tr>
  +
  +</table>
  +
  +<center>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
  +<table cellspacing=2 cellpadding=2>
  +
  +<tr align=center valign=top>
  +<td align=center valign=center>
  +
  +<b><font size=-1>Written by <a
  +href="help.html#Contacting_me">Stas Bekman</a>.<br> Last Modified at 05/27/2000
  +</font></b>
  +<br>
  +
  +</td>
  +
  +<td>
  +
  +<a href="http://perl.apache.org"><img src="images/mod_perl2.jpg"  border=0 alt="mod_perl icon" border=0 height=59 width=150></a>
  +<br>
  +
  +</td>
  +
  +<td>
  +
  +<font size=-2>Use of the Camel for Perl is <br>
  +a trademark of <a href="http://www.ora.com">O'Reilly &amp; Associates</a>,<br>
  +and is used by permission. </font> 
  +<br>
   
  -	     <HR>
  +</td>
   
  -	     [    <A HREF="debug.html">Prev</A> |      <A HREF="index.html">Main Page</A> | <A HREF="modules.html">Next</A>      ]
  +</tr>
  +</table>
  +</center>
   
  -<CENTER><TABLE CELLSPACING=2 CELLPADDING=2 WIDTH="100%" >
  -<TR ALIGN=CENTER VALIGN=TOP>
  -  <TD ALIGN=CENTER VALIGN=CENTER COLSPAN="3">
  -	     <HR>
  -  </TD>
  -</TR>
  -<TR ALIGN=CENTER VALIGN=TOP>
  -  <TD ALIGN=CENTER VALIGN=CENTER>
  -    <B>
  -      <FONT SIZE=-1>
  -	     Written by <A HREF="help.html#Contacting_me">Stas Bekman</A>.
  -	     <BR>Last Modified at 05/03/2000
  -      </FONT>
  -    </B>
  -  </TD>
  -
  -  <TD>
  -	     <A HREF="http://perl.apache.org"><IMG SRC="images/mod_perl2.jpg" ALT="Mod Perl Icon" BORDER=0 HEIGHT=59 WIDTH=150></A>
  -  </TD>
  -
  -  <TD>
  -    <FONT SIZE=-2>
  -	     Use of the Camel for Perl is <BR>
  -	     a trademark of <A HREF="http://www.ora.com">O'Reilly &amp; Associates</A>,<BR>
  -             and is used by permission. 
  -    </FONT> 
  -  </TD>
  -</TR>
  -</TABLE></CENTER>
  -
  -</BODY>
  -</HTML>
  -	    
  \ No newline at end of file
  +</body>
  +</html>
  
  
  
  1.26      +2632 -949 modperl-site/guide/config.html
  
  Index: config.html
  ===================================================================
  RCS file: /home/cvs/modperl-site/guide/config.html,v
  retrieving revision 1.25
  retrieving revision 1.26
  diff -u -r1.25 -r1.26
  --- config.html	2000/05/12 22:42:50	1.25
  +++ config.html	2000/06/07 22:45:29	1.26
  @@ -1,29 +1,37 @@
   <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
  -<HTML>
  -<HEAD>
  -   <TITLE>mod_perl guide: mod_perl Configuration</TITLE>
  -   <META NAME="GENERATOR" CONTENT="Pod2HTML [Perl/Linux]">
  -   <META NAME="Author" CONTENT="Stas Bekman">
  -   <META NAME="Description" CONTENT="All Apache/Perl related information: Hints, Guidelines, Scenarios and Troubleshottings">
  -   <META NAME="keywords" CONTENT="mod_perl modperl perl apache cgi webserver speed  fast guide mod_perl apache guide help info faq mod_perl installation cgi troubleshooting help no sex speedup free open source OSS mod_perl apache guide">
  -</HEAD>
  -     <LINK REL=STYLESHEET TYPE="text/css"
  -        HREF="style.css" TITLE="refstyle">
  -     <style type="text/css">
  -     <!-- 
  -        @import url(style.css);
  -     -->
  -     
  -     </style>
  -<BODY BGCOLOR="white">
  +<html>
  +  <head>
  +   <title>mod_perl guide: mod_perl Configuration</title>
  +   <meta name="Author" content="Stas Bekman">
  +   <meta name="Description" content="All Apache/Perl related information: Hints, Guidelines, Scenarios and Troubleshottings">
  +   <meta name="keywords" content="mod_perl modperl perl cgi apache webserver speed fast guide mod_perl apache guide help info faq mod_perl installation cgi troubleshooting help no sex speedup free open source OSS mod_perl apache guide">
  +   <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
  +   <meta name="Classification" content="information">
  +   <link href="style.css" rel=stylesheet type="text/css" title="refstyle">
  +  </head>
  +  <body>
  +
  +    <h1 align=center>
  +      <a href="http://perl.apache.org"><img src="images/mod_perl.gif" alt="Mod Perl Icon" border=0 height=30 width=90 align=left></a>
  +      <a href="http://perl.apache.org"><img src="images/mod_perl.gif" alt="Mod Perl Icon" border=0 height=30 width=90 align=right></a>
  +      mod_perl Configuration
  +    </h1>
  +    <hr>
  +    <p>
  +    <div class="navbar">
  +      <a href="install.html">Prev</a>                                 |
  +      <a href="index.html"         >Contents</a> |
  +      <a href="index.html#search"  >Search</a>   |
  +      <a href="index.html#download">Download</a> |
  +      <a href="control.html">Next</a>
  +    </div>
  +    <p>
  +
  +    <div class="toc">
  +      
   <A NAME="toc"></A>
  -<H1 ALIGN=CENTER>
  -<A HREF="http://perl.apache.org"><IMG SRC="images/mod_perl.gif" ALT="Mod Perl Icon" BORDER=0 HEIGHT=30 WIDTH=90 ALIGN=LEFT></A>
  -<A HREF="http://perl.apache.org"><IMG SRC="images/mod_perl.gif" ALT="Mod Perl Icon" BORDER=0 HEIGHT=30 WIDTH=90 ALIGN=RIGHT></A>
  -mod_perl Configuration</H1>
  -<HR WIDTH="100%">
  -	    [    <A HREF="install.html">Prev</A> |      <A HREF="index.html">Main Page</A> | <A HREF="control.html">Next</A>      ]<HR><!-- INDEX BEGIN -->
  -<P><B><FONT SIZE=-1>Table of Contents:</FONT></B></P>
  +<P><B>Table of Contents:</B></P>
  +
   <UL>
   
   	<LI><A HREF="#Server_Configuration">Server Configuration</A>
  @@ -97,124 +105,191 @@
   	<LI><A HREF="#Knowing_the_proxy_pass_ed_Connec">Knowing the proxy_pass'ed Connection Type</A>
   	<LI><A HREF="#Adding_Custom_Configuration_Dire">Adding Custom Configuration Directives </A>
   </UL>
  -<!-- INDEX END -->
   
  +    </div>
  +
  +    [ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
   <HR>
  +    <table width="60%" align="center">
   
  -	     The <a href="http://www.modperl.com/">
  -	     <B>Writing Apache Modules with Perl and C</B></a>
  -	     book can be purchased online from <a
  -	     href="http://www.ora.com/catalog/wrapmod/">O'Reilly </a>
  -	     and <a
  -	     href="http://www.amazon.com/exec/obidos/ASIN/156592567X/writinapachemodu">
  -	     Amazon.com</a>.
  -
  -	     <HR>
  -
  -	       <B>Your corrections of either technical or grammatical
  -	       errors are very welcome. You are encouraged to help me
  -	       to improve this guide.  If you have something to
  -	       contribute please <A
  -	       HREF="help.html#Contacting_me"> send it
  -	       directly to me</A>.
  -	       </B>
  -	       <HR>
  +      <tr>
  +	<td>
  +	  <div class="ad">
  +	    The <a href="http://www.modperl.com/">
  +	      <B>Writing Apache Modules with Perl and C</B></a>
  +	    book can be purchased online from <a
  +	      href="http://www.ora.com/catalog/wrapmod/">O'Reilly </a>
  +	    and <a
  +	    href="http://www.amazon.com/exec/obidos/ASIN/156592567X/writinapachemodu">
  +	      Amazon.com</a>.
  +	  </div>
  +	</td>
  +      </tr>
  +
  +      <tr>
  +	<td>
  +	  <div class="notice">
  +	  <B>Your corrections of the technical and grammatical
  +	     errors are very welcome. You are encouraged to help me
  +	     improve this guide.  If you have something to contribute
  +	     please <A HREF="help.html#Contacting_me"> send it
  +	     directly to me</A>.</B>
  +	  </div>
  +	</td>
  +      </tr>
  +
  +</table>
   
  -	      <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<P><A NAME="anchor0"></A>
  +    
  +
  +	    [ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
  +
  +<P>
   <CENTER><H1><A NAME="Server_Configuration">Server Configuration</A></H1></CENTER>
  -<P><A NAME="anchor1"></A>
  +<P>
   The next step after building and installing your new mod_perl enabled
   Apache server is to configure the server. There are two separate parts to
   configure: Apache and mod_perl. Each has its own set of directives.
   
  -<P><A NAME="anchor2"></A>
  +<P>
   To configure your mod_perl enabled Apache server, the only file that you
   should need to edit is <EM>httpd.conf</EM>. By default, <EM>httpd.conf</EM> is put into the <EM>conf</EM> directory under the server root directory. The default server root is <EM>/usr/local/apache/</EM> on many UNIX platforms, but within reason it can be any directory you
   choose. If you are new to Apache and mod_perl, you will probably find it
   helpful to keep to the directory layouts we use in this Guide if you can.
   
  -<P><A NAME="anchor3"></A>
  +<P>
   Apache versions 1.3.4 and later are distributed with the configuration
   directives in a single file -- <EM>httpd.conf</EM>. This Guide uses the same approach in its examples. Prior to version
   1.3.4, the default Apache installation used three configuration files -- <EM>httpd.conf</EM>,
   <EM>srm.conf</EM>, and <EM>access.conf</EM>. If you wish you can still use all three files, by setting the
   AccessConfig and ResourceConfig directives in <EM>httpd.conf</EM>. You will also see later on that we use other files, for example <EM>perl.conf</EM> and <EM>startup.pl</EM>. This is just for our convenience, you could still do everything in <EM>httpd.conf</EM> if you wished.
   
  -<P><A NAME="anchor4"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H1><A NAME="Apache_Configuration">Apache Configuration</A></H1></CENTER>
  -<P><A NAME="anchor5"></A>
  +<P>
   Apache configuration can be confusing. To minimize the number of things
   that can go wrong, it can be a good idea first to configure Apache itself
   without mod_perl. This will give you the confidence that it works and maybe
   that you have some idea how to configure it.
   
  -<P><A NAME="anchor6"></A>
  +<P>
   There is a warning in the <EM>httpd.conf</EM> distributed with Apache about simply editing <EM>httpd.conf</EM> and running the server, without understanding all the implications. This is
   another warning. Modifying the config file and adding new directives can
   introduce security problems, and have performance implications.
   
  -<P><A NAME="anchor7"></A>
  +<P>
   The Apache distribution comes with an extensive configuration manual, and
   in addition each section of the distributed configuration file includes
   helpful comments explaining how every directive should be configured and
   what the defaults values are.
   
  -<P><A NAME="anchor8"></A>
  +<P>
   If you haven't moved Apache's directories around, the installation program
   will have configured everything for you. You can just start the server and
   test it. To start the server use the <CODE>apachectl</CODE>
   utility which comes bundled with the Apache distribution. It resides in the
   same directory as <CODE>httpd</CODE>, the Apache server itself. Execute:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor9"></A>
  -<PRE>  /usr/local/apache/bin/apachectl start
  -</PRE>
  -<P><A NAME="anchor10"></A>
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  /usr/local/apache/bin/apachectl start</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Now you can test the server, for example by accessing <A
   HREF="http://localhost">http://localhost</A> from a browser running on the
   same host.
   
  -<P><A NAME="anchor11"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="Configuration_Directives">Configuration Directives</A></H2></CENTER>
  -<P><A NAME="anchor12"></A>
  +<P>
   For a basic setup there are just a few things to configure. If you have
   moved any directories you have to update them in <EM>httpd.conf</EM>. There are many of them, here are just a couple of examples:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor13"></A>
  -<PRE>  ServerRoot   &quot;/usr/local/apache&quot;
  -  DocumentRoot &quot;/home/httpd/docs&quot;
  -</PRE>
  -<P><A NAME="anchor14"></A>
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  ServerRoot   &quot;/usr/local/apache&quot;
  +  DocumentRoot &quot;/home/httpd/docs&quot;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   If you want to run it on a port other than port 80 edit the <CODE>Port</CODE>
   directive:
   
  -<P><A NAME="anchor15"></A>
  -<PRE>  Port 8080
  -</PRE>
  -<P><A NAME="anchor16"></A>
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  Port 8080</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   You might want to change the user and group names the server will run
   under. Note that if started as the <EM>root</EM> user (which is generally the case), the parent process will continue to run
   as <EM>root</EM>, but its children will run as the user and group you have specified. For
   example:
  +
  +<P>
   
  -<P><A NAME="anchor17"></A>
  -<PRE>  User httpd
  -  Group httpd
  -</PRE>
  -<P><A NAME="anchor18"></A>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  User httpd
  +  Group httpd</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   There are many other directives that you might need to configure as well.
   In addition to directives which take a single value there are whole
   sections of the configuration (such as the <CODE>&lt;Directory&gt;</CODE> and
   <CODE>&lt;Location&gt;</CODE> sections) which apply only to certain areas of your Web space. As mentioned
   earlier you will find them all in <EM>httpd.conf</EM>.
   
  -<P><A NAME="anchor19"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="_htaccess_files">.htaccess files</A></H2></CENTER>
  -<P><A NAME="anchor20"></A>
  +<P>
   If there is a file with the name <EM>.htaccess</EM> in any directory, Apache scans it for further configuration directives
   which it then applies only to that directory (and its subdirectories). The
   name
  @@ -223,50 +298,63 @@
   that a configuration directive can change the names of the files used in
   this way.
   
  -<P><A NAME="anchor21"></A>
  +<P>
   Note that if there is a
  +
  +<P>
   
  -<P><A NAME="anchor22"></A>
  -<PRE>  AllowOverride None
  -</PRE>
  -<P><A NAME="anchor23"></A>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  AllowOverride None</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   directive in <EM>httpd.conf</EM>, Apache will not try to look for
   <EM>.htaccess</EM> at all.
   
  -<P><A NAME="anchor24"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="E_lt_DirectoryE_gt_E_lt_Locati">&lt;Directory&gt;, &lt;Location&gt; and &lt;Files&gt; Sections</A></H2></CENTER>
  -<P><A NAME="anchor25"></A>
  +<P>
   I'll explain just the basics of the <CODE>&lt;Directory&gt;</CODE>, <CODE>&lt;Location&gt;</CODE> and
   <CODE>&lt;Files&gt;</CODE> sections. Remember that there is more to know and the rest of the
   information is available in the Apache documentation. The information I'll
   present here is just what is important for understanding the mod_perl
   configuration sections.
   
  -<P><A NAME="anchor26"></A>
  +<P>
   Apache considers directories and files on your machine all to be resources.
   For each resource you can determine a particular behaviour which will apply
   to every request for information from that particular resource.
   
  -<P><A NAME="anchor27"></A>
  +<P>
   Obviously the directives in <CODE>&lt;Directory&gt;</CODE> sections apply to specific directories on your host machine, and those in <CODE>&lt;Files&gt;</CODE> sections apply only to specific files (actually groups of files with names
   which have something in common). In addition to these sections, Apache has
   the concept of a <CODE>&lt;Location&gt;</CODE>, which is also just a resource.  <CODE>&lt;Location&gt;</CODE> sections apply to specific URIs. Locations are based at the document root,
   directories are based at the filesystem root. For example, if you have the
   default server directory layout where the server root is <EM>/usr/local/apache</EM> and the document root is <EM>/usr/local/apache/htdocs</EM> then static files in the directory <EM>/usr/local/apache/htdocs/pub</EM> are in the location <EM>/pub</EM>.
   
  -<P><A NAME="anchor28"></A>
  +<P>
   It is up to you to decide which directories on your host machine are mapped
   to which locations. You should be careful how you do it, because the
   security of your server may be at stake.
   
  -<P><A NAME="anchor29"></A>
  +<P>
   Locations do not necessarily have to refer to existing physical
   directories, but may refer to virtual resources which the server creates
   for the duration of a single browser request. As you will see, this is
   often the case for a mod_perl server.
   
  -<P><A NAME="anchor30"></A>
  +<P>
   When a browser asks for a resource from your server, Apache determines from
   its configuration whether or not to serve the request, whether to pass the
   request to another server, what (if any) authorization is required for
  @@ -279,47 +367,83 @@
   
   <UL>
   <P><LI><STRONG><A NAME="item__Directory_directoryPath_">&lt;Directory directoryPath&gt; ... &lt;/Directory&gt;</A></STRONG>
  -<P><A NAME="anchor31"></A>
  +<P>
   Can appear in server and virtual host configurations.
   
  -<P><A NAME="anchor32"></A>
  +<P>
   <CODE>&lt;Directory&gt;</CODE> and <CODE>&lt;/Directory&gt;</CODE> are used to enclose a group of directives which will apply only to the
   named directory and sub-directories of that directory. Any directive which
   is allowed in a directory context (see the Apache documentation) may be
   used.
   
  -<P><A NAME="anchor33"></A>
  +<P>
   The path given in the <CODE>&lt;Directory&gt;</CODE> directive is either the full path to a directory, or a wild-card string. In
   a wild-card string, <CODE>?</CODE>
   matches any single character, <CODE>*</CODE> matches any sequence of characters, and <CODE>[]</CODE> matches character ranges. (This is similar to the shell's file globs.) None
   of the wildcards will match a <EM>/</EM> character. For example:
  +
  +<P>
   
  -<P><A NAME="anchor34"></A>
  -<PRE>   &lt;Directory /home/httpd/docs&gt;
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>   &lt;Directory /home/httpd/docs&gt;
        Options Indexes
  -   &lt;/Directory&gt;
  -</PRE>
  -<P><A NAME="anchor35"></A>
  +   &lt;/Directory&gt;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   If you want to use a regular expression to match then you should use the
   syntax <CODE>&lt;DirectoryMatch regex&gt;</CODE> ... <CODE>&lt;/DirectoryMatch&gt;</CODE>.
   
  -<P><A NAME="anchor36"></A>
  +<P>
   If multiple (non-regular expression) directory sections match the directory
   (or its parents) containing a document, then the directives are applied in
   the order of shortest match first, interspersed with the directives from
   any <EM>.htaccess</EM> files. For example, with
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor37"></A>
  -<PRE>     &lt;Directory /&gt;
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>     &lt;Directory /&gt;
          AllowOverride None
  -     &lt;/Directory&gt;
  -</PRE>
  -<P><A NAME="anchor38"></A>
  -<PRE>     &lt;Directory /home/httpd/docs/*&gt;
  +     &lt;/Directory&gt;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>     &lt;Directory /home/httpd/docs/*&gt;
          AllowOverride FileInfo
  -     &lt;/Directory&gt;
  -</PRE>
  -<P><A NAME="anchor39"></A>
  +     &lt;/Directory&gt;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   for access to the document <EM>/home/httpd/docs/index.html</EM> the steps are:
   
   <UL>
  @@ -332,78 +456,103 @@
   /home/httpd/docs/.htaccess.</A></STRONG>
   </UL>
   <P><LI><STRONG><A NAME="item__lt_Files_filename_gt_lt_">&lt;Files filename&gt; ... &lt;/Files&gt;</A></STRONG>
  -<P><A NAME="anchor40"></A>
  +<P>
   Can appear in server and virtual host configurations, and <EM>.htaccess</EM>
   files as well.
   
  -<P><A NAME="anchor41"></A>
  +<P>
   The <CODE>&lt;Files&gt;</CODE> directive provides for access control by filename. It is comparable to the <CODE>&lt;Directory&gt;</CODE> and <CODE>&lt;Location&gt;</CODE> directives. It should be closed with the <CODE>&lt;/Files&gt;</CODE> directive. The directives given within this section will be applied to any
   object with a basename (last component of filename) matching the specified
   filename.
   
  -<P><A NAME="anchor42"></A>
  +<P>
   <CODE>&lt;Files&gt;</CODE> sections are processed in the order they appear in the configuration file,
   after the <CODE>&lt;Directory&gt;</CODE> sections and <EM>.htaccess</EM>
   files are read, but before <CODE>&lt;Location&gt;</CODE> sections. Note that
   <CODE>&lt;Files&gt;</CODE> can be nested inside <CODE>&lt;Directory&gt;</CODE> sections to restrict the portion of the filesystem they apply to.
   
  -<P><A NAME="anchor43"></A>
  +<P>
   The filename argument should include a filename, or a wild-card string,
   where <CODE>?</CODE> matches any single character, and <CODE>*</CODE> matches any sequence of characters. Extended regular expressions can also
   be used, simply place a tilde character <CODE>~</CODE> between the directive and the regular expression. The regular expression
   should be in quotes. The dollar symbol refers to the end of the string. The
   pipe character indicates alternatives. Special characters in extended
   regular expressions must escaped with a backslash. For example:
  +
  +<P>
   
  -<P><A NAME="anchor44"></A>
  -<PRE>   &lt;Files ~ &quot;\.(gif|jpe?g|png)$&quot;&gt;
  -</PRE>
  -<P><A NAME="anchor45"></A>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>   &lt;Files ~ &quot;\.(gif|jpe?g|png)$&quot;&gt;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   would match most common Internet graphics formats. Alternatively you can
   use the <CODE>&lt;FilesMatch regex&gt;</CODE> ... <CODE>&lt;/FilesMatch&gt;</CODE> syntax.
   
   <P><LI><STRONG><A NAME="item__Location_URL_Location_">&lt;Location URL&gt; ... &lt;/Location&gt;</A></STRONG>
  -<P><A NAME="anchor46"></A>
  +<P>
   Can appear in server and virtual host configurations.
   
  -<P><A NAME="anchor47"></A>
  +<P>
   The <CODE>&lt;Location&gt;</CODE> directive provides for access control by URL. It is similar to the <CODE>&lt;Directory&gt;</CODE> directive, and starts a section which is terminated with the <CODE>&lt;/Location&gt;</CODE> directive.
   
  -<P><A NAME="anchor48"></A>
  +<P>
   <CODE>&lt;Location&gt;</CODE> sections are processed in the order they appear in the configuration file,
   after the <CODE>&lt;Directory&gt;</CODE> sections, <EM>.htaccess</EM>
   files and <CODE>&lt;Files&gt;</CODE> sections are read.
   
  -<P><A NAME="anchor49"></A>
  +<P>
   The <CODE>&lt;Location&gt;</CODE> section is the directive that is used most often with mod_perl.
   
  -<P><A NAME="anchor50"></A>
  +<P>
   URLs <EM>do not</EM> have to refer to real directories or files within the filesystem at all, <CODE>&lt;Location&gt;</CODE> operates completely outside the filesystem. Indeed it may sometimes be wise
   to ensure that
   <CODE>&lt;Location&gt;</CODE>s do not match real paths to avoid confusion.
   
  -<P><A NAME="anchor51"></A>
  +<P>
   The URL may use wildcards. In a wild-card string, <CODE>?</CODE> matches any single character, and <CODE>*</CODE> matches any sequences of characters, <CODE>[]</CODE>
   groups characters to match. For regular expression matches use the
   <CODE>&lt;LocationMatch regex&gt;</CODE> ... <CODE>&lt;/LocationMatch&gt;</CODE> syntax.
   
  -<P><A NAME="anchor52"></A>
  +<P>
   The <CODE>&lt;Location&gt;</CODE> functionality is especially useful when combined with the <CODE>SetHandler</CODE> directive. For example to enable status requests, but allow them only from
   browsers at <EM>example.com</EM>, you might use:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor53"></A>
  -<PRE>  &lt;Location /status&gt;
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  &lt;Location /status&gt;
       SetHandler server-status
       order deny,allow
       deny from all
       allow from .example.com
  -  &lt;/Location&gt;
  -</PRE>
  -</UL>
  -<P><A NAME="anchor54"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +  &lt;/Location&gt;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    </UL>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="How_Directory_Location_and_File">How Directory, Location and Files Sections are Merged</A></H2></CENTER>
  -<P><A NAME="anchor55"></A>
  +<P>
   When configuring the server, it's important to understand the order in
   which the rules of each section apply to requests. The order of merging is:
   
  @@ -416,99 +565,138 @@
   <P><LI><STRONG><A NAME="item__lt_Files_gt_and_lt_FilesMatch">&lt;Files&gt; and &lt;FilesMatch&gt; are processed simultaneously</A></STRONG>
   <P><LI><STRONG><A NAME="item__lt_Location_gt_and_lt_Locatio">&lt;Location&gt; and &lt;LocationMatch&gt; are processed simultaneously</A></STRONG>
   </OL>
  -<P><A NAME="anchor56"></A>
  +<P>
   Apart from <CODE>&lt;Directory&gt;</CODE>, each group is processed in the order that it appears in the configuration
   files.  <CODE>&lt;Directory&gt;</CODE> (group 1 above) is processed in the order shortest directory component to
   longest. If multiple <CODE>&lt;Directory&gt;</CODE> sections apply to the same directory then they are processed in the
   configuration file order.
   
  -<P><A NAME="anchor57"></A>
  +<P>
   Sections inside <CODE>&lt;VirtualHost&gt;</CODE> sections are applied as if you were running several independent servers.
   The directives inside
   <CODE>&lt;VirtualHost&gt;</CODE> sections do not interact with each other. They are applied after first
   processing any sections outside the virtual host definition. This allows
   virtual host configurations to override the main server configuration.
   
  -<P><A NAME="anchor58"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="Sub_Grouping_of_Location_Dir">Sub-Grouping of &lt;Location&gt;, &lt;Directory&gt; and &lt;Files&gt; Sections</A></H2></CENTER>
  -<P><A NAME="anchor59"></A>
  +<P>
   Let's say that you want all files, except for a few of the files in a
   specific directory and below, to be handled in the same way. For example if
   you want all the files in <EM>/home/http/docs</EM> to be served as plain files, but any files with ending <EM>.html</EM> and <EM>.txt</EM> to be processed by the content handler of your <CODE>Apache::MyFilter</CODE> module.
  +
  +<P>
   
  -<P><A NAME="anchor60"></A>
  -<PRE>  &lt;Directory /home/httpd/docs&gt;
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  &lt;Directory /home/httpd/docs&gt;
       &lt;FilesMatch &quot;\.(html|txt)$&quot;&gt;
         SetHandler perl-script
         PerlHandler Apache::MyFilter
       &lt;/FilesMatch&gt;
  -  &lt;/Directory&gt;
  -</PRE>
  -<P><A NAME="anchor61"></A>
  +  &lt;/Directory&gt;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Thus it is possible to embed sections inside sections to create subgroups
   which have their own distinct behavior. Alternatively you could use a <CODE>&lt;Files&gt;</CODE> section inside an <EM>.htaccess</EM> file.
   
  -<P><A NAME="anchor62"></A>
  +<P>
   Note that you can't put <CODE>&lt;Files&gt;</CODE> or <CODE>&lt;FilesMatch&gt;</CODE> sections inside a <CODE>&lt;Location&gt;</CODE> section, but you can put them inside a <CODE>&lt;Directory&gt;</CODE>
   section.
   
  -<P><A NAME="anchor63"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="Options_Directive">Options Directive</A></H2></CENTER>
  -<P><A NAME="anchor64"></A>
  +<P>
   Normally, if multiple <CODE>Options</CODE> directives apply to a directory, then the most specific one is taken
   complete; the options are not merged.
   
  -<P><A NAME="anchor65"></A>
  +<P>
   However if all the options on the <CODE>Options</CODE> directive are preceded by a <CODE>+</CODE> or <CODE>-</CODE> symbol, the options are merged. Any options preceded by
   <CODE>+</CODE> are added to the options currently in force, and any options preceded by <CODE>-</CODE> are removed.
   
  -<P><A NAME="anchor66"></A>
  +<P>
   For example, without any <CODE>+</CODE> and <CODE>-</CODE> symbols:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor67"></A>
  -<PRE>  &lt;Directory /home/httpd/docs&gt;
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  &lt;Directory /home/httpd/docs&gt;
       Options Indexes FollowSymLinks
     &lt;/Directory&gt;
     &lt;Directory /home/httpd/docs/shtml&gt;
       Options Includes
  -  &lt;/Directory&gt;
  -</PRE>
  -<P><A NAME="anchor68"></A>
  +  &lt;/Directory&gt;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   then only <CODE>Includes</CODE> will be set for the <EM>/home/httpd/docs/shtml</EM>
   directory. However if the second <CODE>Options</CODE> directive uses the <CODE>+</CODE>
   and <CODE>-</CODE> symbols:
  +
  +<P>
   
  -<P><A NAME="anchor69"></A>
  -<PRE>  &lt;Directory /home/httpd/docs&gt;
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  &lt;Directory /home/httpd/docs&gt;
       Options Indexes FollowSymLinks
     &lt;/Directory&gt;
     &lt;Directory /home/httpd/docs/shtml&gt;
       Options +Includes -Indexes
  -  &lt;/Directory&gt;
  -</PRE>
  -<P><A NAME="anchor70"></A>
  +  &lt;/Directory&gt;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   then the options <CODE>FollowSymLinks</CODE> and <CODE>Includes</CODE> are set for the
   <EM>/home/httpd/docs/shtml</EM> directory.
   
  -<P><A NAME="anchor71"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H1><A NAME="mod_perl_Configuration">mod_perl Configuration</A></H1></CENTER>
  -<P><A NAME="anchor72"></A>
  +<P>
   When you have tested that the Apache server works on your machine, it's
   time to configure mod_perl. Some of the configuration directives are
   already familiar to you, but mod_perl introduces a few new ones.
   
  -<P><A NAME="anchor73"></A>
  +<P>
   It can be a good idea to keep all the mod_perl related configuration at the
   end of the configuration file, after the native Apache configuration
   directives.
   
  -<P><A NAME="anchor74"></A>
  +<P>
   META: explain Include file directive to load mod_perl side configuration.
   
  -<P><A NAME="anchor75"></A>
  +<P>
   To ease maintenance and to simplify multiple server installations, the
   Apache/mod_perl configuration system allows you several alternative ways to
   keep your configration directives in separate places. The
  @@ -516,72 +704,133 @@
   information were all contained in <EM>httpd.conf</EM>. This is a feature of Apache itself. For example if you want all your
   mod_perl configuration to be placed in a separate file <EM>mod_perl.conf</EM> you can do that by adding to <EM>httpd.conf</EM> this directive:
   
  -<P><A NAME="anchor76"></A>
  -<PRE>  Include conf/mod_perl.conf
  -</PRE>
  -<P><A NAME="anchor77"></A>
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  Include conf/mod_perl.conf</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   mod_perl adds two further directives: <CODE>&lt;Perl&gt;</CODE> sections allow you to execute Perl code from within any configuration file
   at server startup time, and as you will see later, a file containing any
   Perl program can be executed (also at server startup time) simply by
   mentioning its name in a <CODE>PerlRequire</CODE> or <CODE>PerlModule</CODE> directve.
   
  -<P><A NAME="anchor78"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="Alias_Configurations">Alias Configurations</A></H2></CENTER>
  -<P><A NAME="anchor79"></A>
  +<P>
   The <CODE>ScriptAlias</CODE> and <CODE>Alias</CODE> directives provide a mapping of a URI to a file system directory. The
   directive:
   
  -<P><A NAME="anchor80"></A>
  -<PRE>  Alias /foo /home/httpd/perl/foo
  -</PRE>
  -<P><A NAME="anchor81"></A>
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  Alias /foo /home/httpd/perl/foo</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   will map all requests starting with <EM>/foo</EM> onto the files starting with <EM>/home/httpd/perl/foo</EM>. So when Apache gets a request <A
   HREF="http://www.example.com/perl/test.pl">http://www.example.com/perl/test.pl</A>
   the server will remap this into the file <EM>test.pl</EM> in the directory <EM>/home/httpd/perl/foo</EM>.
   
  -<P><A NAME="anchor82"></A>
  +<P>
   In addition <CODE>ScriptAlias</CODE> assigns all the requests that match the URI (i.e. <EM>/cgi-bin</EM>) to be executed under mod_cgi.
  +
  +<P>
   
  -<P><A NAME="anchor83"></A>
  -<PRE>  ScriptAlias /cgi-bin /home/httpd/cgi-bin
  -</PRE>
  -<P><A NAME="anchor84"></A>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  ScriptAlias /cgi-bin /home/httpd/cgi-bin</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   is actually the same as: 
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor85"></A>
  -<PRE>  Alias /cgi-bin /home/httpd/cgi-bin
  -  SetHandler cgi-handler
  -</PRE>
  -<P><A NAME="anchor86"></A>
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  Alias /cgi-bin /home/httpd/cgi-bin
  +  SetHandler cgi-handler</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   where latter directive invokes mod_cgi. You shouldn't use the
   <CODE>ScriptAlias</CODE> directive unless you want the request to be processed under mod_cgi.
   Therefore when you configure a mod_perl sections use
   <CODE>Alias</CODE> instead.
   
  -<P><A NAME="anchor87"></A>
  +<P>
   Under mod_perl the <CODE>Alias</CODE> directive will be followed by two further directives. The first is the SetHandler&nbsp;perl-script directive, which tells Apache to invoke mod_perl to run the script. The
   second directive (for example <CODE>PerlHandler</CODE>) tells mod_perl which handler (Perl module) the script should be run
   under, and hence for which phase of the request. Refer to the section
   <A HREF="././config.html#Perl_Handlers">Perl*Handlers</A> for more information about handlers for the various request phases.
   
  -<P><A NAME="anchor88"></A>
  +<P>
   When you have decided what methods to use to run your scripts and where you
   will keep them, you can add the configuration <CODE>directive(s)</CODE> to <EM>httpd.conf</EM>. They will look like those below, but they will of course reflect the
   locations of your scripts in your file-system and the decisions you have
   made about how to run the scripts:
   
  -<P><A NAME="anchor89"></A>
  -<PRE>  # Typical for plain cgi scripts:
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  # Typical for plain cgi scripts:
     ScriptAlias /cgi-bin/ /home/httpd/perl/
       
     # Typical for Apache::Registry scripts:
     Alias /perl/ /home/httpd/perl/
       
     # Typical for Apache::PerlRun scripts:
  -  Alias /cgi-perl/ /home/httpd/perl/
  -</PRE>
  -<P><A NAME="anchor90"></A>
  +  Alias /cgi-perl/ /home/httpd/perl/</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   In the examples above we have mapped the three different URIs (<EM>http://www.example.com/perl/test.pl</EM>
   
   <EM>http://www.example.com/cgi-bin/test.pl</EM> and
  @@ -590,206 +839,378 @@
   in the file-system, and call the script in any of three ways simply by
   changing one component of the URI (<EM>cgi-bin|perl|cgi-perl</EM>).
   
  -<P><A NAME="anchor91"></A>
  +<P>
   This technique makes it easy to migrate your scripts to mod_perl. If your
   script does not seem to be working while running under mod_perl, then in
   most cases you can easily call the script in straight mod_cgi mode without
   making any script changes. Simply change the URL you use to invoke it.
   
  -<P><A NAME="anchor92"></A>
  +<P>
   Although in the configuration above we have configured all three
   <EM>Aliases</EM> to point to the same directory within our file system, you can of course
   have them point to different directories if you prefer.
   
  -<P><A NAME="anchor93"></A>
  +<P>
   You should remember that it is undesirable to run scripts in plain mod_cgi
   mode from a mod_perl-enabled server -- the resource consumption is too
   high, it is better to run these on a plain Apache server. See <A HREF="././strategy.html#Standalone_mod_perl_Enabled_Apac">Standalone mod_perl Enabled Apache Server</A>.
   
  -<P><A NAME="anchor94"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="_Location_Configuration">&lt;Location&gt; Configuration</A></H2></CENTER>
  -<P><A NAME="anchor95"></A>
  +<P>
   The <CODE>&lt;Location&gt;</CODE> section assigns a number of rules which the server should follow when the
   request's URI matches the <EM>Location</EM>. Just as it is the widely accepted convention to use <EM>/cgi-bin</EM> for your mod_cgi scripts, it is conventional to use <EM>/perl</EM> as the base URI of the perl scripts which you are running under mod_perl.
   Let's review the following very widely used <CODE>&lt;Location&gt;</CODE> section:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor96"></A>
  -<PRE>  &lt;Location /perl&gt;
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  &lt;Location /perl&gt;
       SetHandler perl-script
       PerlHandler Apache::Registry
       Options ExecCGI
       allow from all
       PerlSendHeader On
  -  &lt;/Location&gt;
  -</PRE>
  -<P><A NAME="anchor97"></A>
  +  &lt;/Location&gt;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   This configuration causes all requests for URIs starting with <EM>/perl</EM>
   to be handled by the mod_perl Apache module with the handler from the
   <CODE>Apache::Registry</CODE> Perl module. Let's review the directives inside the <CODE>&lt;Location&gt;</CODE> section in the example:
  +
  +<P>
   
  -<P><A NAME="anchor98"></A>
  -<PRE>  &lt;Location /perl&gt;
  -</PRE>
  -<P><A NAME="anchor99"></A>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  &lt;Location /perl&gt;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Remember the <CODE>Alias</CODE> from the above section? We use the same <CODE>Alias</CODE>
   here; if you were to use a <CODE>&lt;Location&gt;</CODE> that does not have the same
   <CODE>Alias</CODE>, the server would fail to locate the script in the file system. You need
   the <CODE>Alias</CODE> setting only if the code that should be executed is located in the file. So <CODE>Alias</CODE> just provides the URI to filepath translation rule.
   
  -<P><A NAME="anchor100"></A>
  +<P>
   Sometimes there is no script to be executed. Instead there is some module
   whose method is being executed, similar to <EM>/perl-status</EM>, where the code is stored in an Apache module. In such cases we don't need <CODE>Alias</CODE> settings for those <CODE>&lt;Location&gt;</CODE>s.
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor101"></A>
  -<PRE>  SetHandler perl-script
  -</PRE>
  -<P><A NAME="anchor102"></A>
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  SetHandler perl-script</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   This assigns the mod_perl Apache module to handle the content generation
   phase.
   
  -<P><A NAME="anchor103"></A>
  -<PRE>  PerlHandler Apache::Registry
  -</PRE>
  -<P><A NAME="anchor104"></A>
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  PerlHandler Apache::Registry</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Here we tell Apache to use the <CODE>Apache::Registry</CODE> Perl module for the actual content generation.
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor105"></A>
  -<PRE>  Options ExecCGI
  -</PRE>
  -<P><A NAME="anchor106"></A>
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  Options ExecCGI</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   The <CODE>Options</CODE> directive accepts various parameters (options), one of which is <CODE>ExecCGI</CODE>. This tells the server that the file is a program and should be executed,
   instead of just being displayed like a static file (like HTML file). If you
   omit this option then the script will either be rendered as plain text or
   else it will trigger a <EM>Save-As</EM>
   dialog, depending on the client's configuration.
   
  -<P><A NAME="anchor107"></A>
  -<PRE>  allow from all
  -</PRE>
  -<P><A NAME="anchor108"></A>
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  allow from all</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   This directive is used to set access control based on domain. The above
   settings allow any client to run the script from any domain.
  +
  +<P>
   
  -<P><A NAME="anchor109"></A>
  -<PRE>  PerlSendHeader On
  -</PRE>
  -<P><A NAME="anchor110"></A>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  PerlSendHeader On</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   <CODE>PerlSendHeader On</CODE> tells the server to send an HTTP header to the browser on every script
   invocation. You will want to turn this off for nph (non-parsed-headers)
   scripts.
   
  -<P><A NAME="anchor111"></A>
  +<P>
   The <CODE>PerlSendHeader On</CODE> setting invokes <CODE>ap_send_http_header()</CODE>
   after parsing your script headers. It is only meant for CGI emulation, and
   to send the HTTP header it's always better either to use <CODE>$q-&gt;header</CODE> from the <CODE>CGI.pm</CODE> module or to use
   <CODE>$r-&gt;send_http_header</CODE> using the Apache Perl API.
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor112"></A>
  -<PRE>  &lt;/Location&gt;
  -</PRE>
  -<P><A NAME="anchor113"></A>
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  &lt;/Location&gt;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Closes the <CODE>&lt;Location&gt;</CODE> section definition.
   
  -<P><A NAME="anchor114"></A>
  +<P>
   Note that sometimes you will have to preload the module before using it in
   the <CODE>&lt;Location&gt;</CODE> section. In the case of <CODE>Apache::Registry</CODE>
   the configuration will look like this:
  +
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
   
  -<P><A NAME="anchor115"></A>
  -<PRE>  PerlModule Apache::Registry
  +	<td>
  +	  <pre>  PerlModule Apache::Registry
     &lt;Location /perl&gt;
       SetHandler perl-script
       PerlHandler Apache::Registry
       Options ExecCGI
       allow from all
       PerlSendHeader On
  -  &lt;/Location&gt;
  -</PRE>
  -<P><A NAME="anchor116"></A>
  +  &lt;/Location&gt;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   <CODE>PerlModule</CODE> is equivalent to Perl's native <CODE>use()</CODE> function call.
   
  -<P><A NAME="anchor117"></A>
  +<P>
   No changes are required to the <EM>/cgi-bin</EM> location (mod_cgi), since it has nothing to do with mod_perl.
   
  -<P><A NAME="anchor118"></A>
  +<P>
   Here is another very similar example, this time using
   <CODE>Apache::PerlRun</CODE> (For more information see
   <A HREF="././porting.html#Apache_PerlRun_a_closer_look">Apache::PerlRun</A>):
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor119"></A>
  -<PRE>  &lt;Location /cgi-perl&gt;
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  &lt;Location /cgi-perl&gt;
       SetHandler perl-script
       PerlHandler Apache::PerlRun
       Options ExecCGI
       allow from all
       PerlSendHeader On
  -  &lt;/Location&gt;
  -</PRE>
  -<P><A NAME="anchor120"></A>
  +  &lt;/Location&gt;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   The only difference from the <CODE>Apache::Registry</CODE> configuration is the argument of the <CODE>PerlHandler</CODE> directive, where <CODE>Apache::Registry</CODE>
   has been replaced with <CODE>Apache::PerlRun</CODE>.
   
  -<P><A NAME="anchor121"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="Overriding_Location_Setting_in">Overriding &lt;Location&gt; Setting in &quot;Sub-Location&quot;</A></H2></CENTER>
  -<P><A NAME="anchor122"></A>
  +<P>
   So if you have:
   
  -<P><A NAME="anchor123"></A>
  -<PRE>  &lt;Location /foo&gt;
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  &lt;Location /foo&gt;
       SetHandler perl-script
       PerlHandler My::Module
  -   &lt;/Location&gt;
  -</PRE>
  -<P><A NAME="anchor124"></A>
  +   &lt;/Location&gt;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   If you want to remove a mod_perl handler setting from a location beneath a
   location where the handler was set (i.e. <EM>/foo/bar</EM>), all you have to do is to reset it, like this:
  +
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
   
  -<P><A NAME="anchor125"></A>
  -<PRE>  &lt;Location /foo/bar&gt;
  +	<td>
  +	  <pre>  &lt;Location /foo/bar&gt;
       SetHandler default-handler
  -  &lt;/Location&gt;
  -</PRE>
  -<P><A NAME="anchor126"></A>
  +  &lt;/Location&gt;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Now, all the requests starting with <EM>/foo/bar</EM> would be served by Apache's default handler.
   
  -<P><A NAME="anchor127"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="PerlModule_and_PerlRequire_Direc">PerlModule and PerlRequire Directives</A></H2></CENTER>
  -<P><A NAME="anchor128"></A>
  +<P>
   As we saw earlier, a module should be loaded before it is used.
   <CODE>PerlModule</CODE> and <CODE>PerlRequire</CODE> are the two mod_perl directives which are used to load modules and code.
   They are equivalent to Perl's <CODE>use()</CODE> and <CODE>require()</CODE>
   functions respectively. Since they are equivalent, the same rules apply to
   their arguments. Thus you would give <CODE>Apache::DBI</CODE> as an argument for a <CODE>PerlModule</CODE> directive, while you would give <EM>Apache/DBI.pm</EM> for <CODE>PerlRequire</CODE>.
   
  -<P><A NAME="anchor129"></A>
  +<P>
   You may load modules from the configuration file at server startup e.g.:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor130"></A>
  -<PRE>    PerlModule Apache::DBI CGI DBD::Mysql
  -</PRE>
  -<P><A NAME="anchor131"></A>
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>    PerlModule Apache::DBI CGI DBD::Mysql</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Generally the modules are preloaded from the startup script, which is
   usually called <EM>startup.pl</EM>. This is a file containing plain Perl code which is executed through the <CODE>PerlRequire</CODE> directive. For example:
   
  -<P><A NAME="anchor132"></A>
  -<PRE>    PerlRequire  /home/httpd/perl/lib/startup.pl
  -</PRE>
  -<P><A NAME="anchor133"></A>
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>    PerlRequire  /home/httpd/perl/lib/startup.pl</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   As with any file with Perl code that gets <CODE>require()'d,</CODE> it must
   return a <EM>true</EM> value. To ensure that this happens don't forget to add
   <CODE>1;</CODE> at the end of <EM>startup.pl</EM>.
   
  -<P><A NAME="anchor134"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="Perl_Handlers">Perl*Handlers</A></H2></CENTER>
  -<P><A NAME="anchor135"></A>
  +<P>
   As you probably know Apache traverses a loop for each HTTP request it
   receives.
   
  -<P><A NAME="anchor136"></A>
  +<P>
   After you have compiled and installed mod_perl, your Apache mod_perl
   configuration directives tell Apache to invoke the module mod_perl as the
   handler for some request which it receives. Although it could in fact
  @@ -798,7 +1219,7 @@
   modules, or to the default Apache routines) by putting
   <CODE>Perl*Handler</CODE> directives in the configuration files.
   
  -<P><A NAME="anchor137"></A>
  +<P>
   Because you need the Perl interpreter to be present for your Perl script to
   do any processing at all, there is a slight difference between the way that
   you configure Perl and C handlers to handle parts of the request loop.
  @@ -809,7 +1230,7 @@
   file to tell mod_perl that it is to pass the responsibility for handling
   that part of the request phase to your Perl module.
   
  -<P><A NAME="anchor138"></A>
  +<P>
   mod_perl is an Apache module written in C. As most programmers will only
   need to handle the response phase, in the default compilation most of the
   Perl*Handlers are disabled. When you configure the
  @@ -818,10 +1239,10 @@
   phase. If so you need to specify which parts. See the INSTALL section for
   how to do this.
   
  -<P><A NAME="anchor139"></A>
  +<P>
   META: link above
   
  -<P><A NAME="anchor140"></A>
  +<P>
   Apache specifies about eleven phases of the request loop, namely (and in
   order of processing): Post-Read-Request, URI Translation, Header Parsing,
   Access Control, Authentication, Authorization, MIME type checking, FixUp,
  @@ -830,27 +1251,36 @@
   module to step in and do something. There is a dedicated <CODE>Perl*Handler</CODE> for each of these stages plus a couple of others which don't correspond to
   parts of the request loop.
   
  -<P><A NAME="anchor141"></A>
  +<P>
   We call them <CODE>Perl*Handler</CODE> directives because the names of the many mod_perl handler directives for
   the various phases of the request loop all follow the same format. The <CODE>*</CODE> in <CODE>Perl*Handler</CODE> is a placeholder to be replaced by something which identifies the phase to
   be handled. For example <CODE>PerlLogHandler</CODE> is a Perl Handler which (fairly obviously) handles the logging phase.  
   
  -<P><A NAME="anchor142"></A>
  +<P>
   The slight exception is <CODE>PerlHandler</CODE>, which you can think of as
   <CODE>PerlResponseHandler</CODE>. It is the content generation handler and so it is probably the one that
   you will use most frequently.  
   
  -<P><A NAME="anchor143"></A>
  +<P>
   Note that it is mod_perl which recognizes these directives, and not Apache.
   They are mod_perl directives, and an ordinary Apache does not recognize
   them. If you get error messages about these directives being <EM>"perhaps mis-spelled"</EM> it is a sure sign that the appropriate part of mod_perl (or the entire
   mod_perl module!) is not present in your copy of Apache executable.
   
  -<P><A NAME="anchor144"></A>
  +<P>
   The full list of Perl*Handlers follows:
   
  -<P><A NAME="anchor145"></A>
  -<PRE>    PerlChildInitHandler
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>    PerlChildInitHandler
       PerlPostReadRequestHandler
       PerlInitHandler
       PerlTransHandler
  @@ -865,205 +1295,387 @@
       PerlCleanupHandler
       PerlChildExitHandler
       PerlDispatchHandler
  -    PerlRestartHandler
  -</PRE>
  -<P><A NAME="anchor146"></A>
  +    PerlRestartHandler</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   <CODE>PerlChildInitHandler</CODE> and <CODE>PerlChildExitHandler</CODE> do not refer to parts of the request loop, they are to allow your modules
   to initialize data structures and to clean up at the child process start-up
   and shutdown respectively, for example by allocating and deallocating
   memory.
   
  -<P><A NAME="anchor147"></A>
  +<P>
   All <CODE>&lt;Location&gt;</CODE>, <CODE>&lt;Directory&gt;</CODE> and <CODE>&lt;Files&gt;</CODE> sections contain a physical path specification. Like <CODE>PerlChildInitHandler</CODE> and
   <CODE>PerlChildExitHandler</CODE>, the directives <CODE>PerlPostReadRequestHandler</CODE>
   and <CODE>PerlTransHandler</CODE> cannot be used in these sections, nor in
   <EM>.htaccess</EM> files, because it is not until the end of the Translation Handler (<CODE>PerlTransHandler</CODE>) phase that the path translation is completed and a physical path is
   known.
   
  -<P><A NAME="anchor148"></A>
  +<P>
   <CODE>PerlInitHandler</CODE> changes its behaviour depending upon where it is used. In any case it is
   the first handler to be invoked in serving a request. If found outside any <CODE>&lt;Location&gt;</CODE>, <CODE>&lt;Directory&gt;</CODE> or
   <CODE>&lt;Files&gt;</CODE> section, it is an alias for <CODE>PerlPostReadRequestHandler</CODE>. When outside any such section it is an alias for
   <CODE>PerlHeaderParserHandler</CODE>.
   
  -<P><A NAME="anchor149"></A>
  +<P>
   Starting from <CODE>PerlHeaderParserHandler</CODE> the requested URI has been mapped to a physical server pathname, and thus
   it can be used to match a <CODE>&lt;Location&gt;</CODE>, <CODE>&lt;Directory&gt;</CODE> or <CODE>&lt;Files&gt;</CODE> configuration section, or to look in a <EM>.htaccess</EM> file if such a file exists in the specified directory in the translated
   path.
   
  -<P><A NAME="anchor150"></A>
  +<P>
   <CODE>PerlDispatchHandler</CODE> and <CODE>PerlRestartHandler</CODE> do not correspond to parts of the Apache API, but allow you to fine-tune
   the mod_perl API.
   
  -<P><A NAME="anchor151"></A>
  +<P>
   The Apache documentation will tell you all about these stages and what your
   modules can do. By default, most of these hooks are disabled at compile
   time, see the INSTALL section for information on enabling them.
   
  -<P><A NAME="anchor152"></A>
  +<P>
   META: Link for INSTALL section above?
   
  -<P><A NAME="anchor153"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="The_handler_subroutine">The handler subroutine</A></H2></CENTER>
  -<P><A NAME="anchor154"></A>
  +<P>
   By default the mod_perl API expects a subroutine called <CODE>handler()</CODE>
   to handle the request in the registered Perl*Handler module. Thus if your
   module implements this subroutine, you can register the handler with
   mod_perl like this:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor155"></A>
  -<PRE>  Perl*Handler Apache::Foo
  -</PRE>
  -<P><A NAME="anchor156"></A>
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  Perl*Handler Apache::Foo</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Replace <EM>Perl*Handler</EM> with the name of a specific handler from the list given above. mod_perl
   will preload the specified module for you. Please note that this approach
   will not preload the module at startup. To make sure it gets loaded you
   have three options: you can explicitly preload it with the <CODE>PerlModule</CODE> directive:
   
  -<P><A NAME="anchor157"></A>
  -<PRE>  PerlModule Apache::Foo
  -</PRE>
  -<P><A NAME="anchor158"></A>
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  PerlModule Apache::Foo</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   You can preload it at the startup file:
  +
  +<P>
   
  -<P><A NAME="anchor159"></A>
  -<PRE>  use Apache::Foo ();
  -</PRE>
  -<P><A NAME="anchor160"></A>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  use Apache::Foo ();</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Or you can use a nice shortcut that the <CODE>Perl*Handler</CODE> syntax provides:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor161"></A>
  -<PRE>  Perl*Handler +Apache::Foo
  -</PRE>
  -<P><A NAME="anchor162"></A>
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  Perl*Handler +Apache::Foo</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Note the leading <CODE>+</CODE> character. This directive is equivalent to:
   
  -<P><A NAME="anchor163"></A>
  -<PRE>  PerlModule Apache::Foo
  -  Perl*Handler Apache::Foo
  -</PRE>
  -<P><A NAME="anchor164"></A>
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  PerlModule Apache::Foo
  +  Perl*Handler Apache::Foo</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   If you decide to give the handler routine a name other than
   <CODE>handler</CODE>, for example <CODE>my_handler</CODE>, you must preload the module and explicitly give the name of the handler
   subroutine:
  +
  +<P>
   
  -<P><A NAME="anchor165"></A>
  -<PRE>  PerlModule Apache::Foo
  -  Perl*Handler Apache::Foo::my_handler
  -</PRE>
  -<P><A NAME="anchor166"></A>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  PerlModule Apache::Foo
  +  Perl*Handler Apache::Foo::my_handler</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   As you have seen, this will preload the module at server startup.
   
  -<P><A NAME="anchor167"></A>
  +<P>
   If a module needs to know which handler is currently being run, it can find
   out with the <EM>current_callback</EM> method. This method is most useful to <EM>PerlDispatchHandlers</EM> which wish to take action for certain phases only.
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor168"></A>
  -<PRE>  if($r-&gt;current_callback eq &quot;PerlLogHandler&quot;) {
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  if($r-&gt;current_callback eq &quot;PerlLogHandler&quot;) {
         $r-&gt;warn(&quot;Logging request&quot;);
  -  }
  -</PRE>
  -<P><A NAME="anchor169"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +  }</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="Stacked_Handlers">Stacked Handlers</A></H2></CENTER>
  -<P><A NAME="anchor170"></A>
  +<P>
   With the mod_perl stacked handlers mechanism, during any stage of a request
   it is possible for more than one <CODE>Perl*Handler</CODE> to be defined and run.
   
  -<P><A NAME="anchor171"></A>
  +<P>
   <CODE>Perl*Handler</CODE> directives (in your configuration files) can define any number of
   subroutines. For example:
  +
  +<P>
   
  -<P><A NAME="anchor172"></A>
  -<PRE> PerlTransHandler OneTrans TwoTrans RedTrans BlueTrans
  -</PRE>
  -<P><A NAME="anchor173"></A>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre> PerlTransHandler OneTrans TwoTrans RedTrans BlueTrans</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   With the method <CODE>Apache-&gt;push_handlers()</CODE>, callbacks (handlers) can be added to a stack <EM>at runtime</EM> by mod_perl scripts.
   
  -<P><A NAME="anchor174"></A>
  +<P>
   <CODE>Apache-&gt;push_handlers()</CODE> takes the callback hook name as its first argument and a subroutine name or
   reference as its second.
   
  -<P><A NAME="anchor175"></A>
  +<P>
   Here's an example:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor176"></A>
  -<PRE> Apache-&gt;push_handlers(&quot;PerlLogHandler&quot;, \&amp;first_one);
  -</PRE>
  -<P><A NAME="anchor177"></A>
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre> Apache-&gt;push_handlers(&quot;PerlLogHandler&quot;, \&amp;first_one);</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Here's another one: use Apache::Constants <CODE>qw(:common);</CODE>
   $r-&gt;push_handlers(``PerlLogHandler'', sub { print STDERR ``__ANON__
   called\n''; return OK; });
   
  -<P><A NAME="anchor178"></A>
  +<P>
   After each request, this stack is erased.
   
  -<P><A NAME="anchor179"></A>
  +<P>
   All handlers will be called unless a handler returns a status other than <CODE>OK</CODE> or <CODE>DECLINED</CODE>.
   
  -<P><A NAME="anchor180"></A>
  +<P>
   Example uses:
   
  -<P><A NAME="anchor181"></A>
  +<P>
   <CODE>CGI.pm</CODE> maintains a global object for its plain function interface. Since the
   object is global, it does not go out of scope, DESTROY is never called.  <CODE>CGI-&gt;new</CODE> can call:
   
  -<P><A NAME="anchor182"></A>
  -<PRE> Apache-&gt;push_handlers(&quot;PerlCleanupHandler&quot;, \&amp;CGI::_reset_globals);
  -</PRE>
  -<P><A NAME="anchor183"></A>
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre> Apache-&gt;push_handlers(&quot;PerlCleanupHandler&quot;, \&amp;CGI::_reset_globals);</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   This function will be called during the final stage of a request,
   refreshing <CODE>CGI.pm</CODE>'s globals before the next request comes in.
   
  -<P><A NAME="anchor184"></A>
  +<P>
   <CODE>Apache::DCELogin</CODE> establishes a DCE login context which must exist for the lifetime of a
   request, so the <CODE>DCE::Login</CODE> object is stored in a global variable. Without stacked handlers, users must
   set
  +
  +<P>
   
  -<P><A NAME="anchor185"></A>
  -<PRE> PerlCleanupHandler Apache::DCELogin::purge
  -</PRE>
  -<P><A NAME="anchor186"></A>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre> PerlCleanupHandler Apache::DCELogin::purge</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   in the configuration files to destroy the context. This is not
   ``user-friendly''. Now, <CODE>Apache::DCELogin::handler</CODE> can call:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor187"></A>
  -<PRE> Apache-&gt;push_handlers(&quot;PerlCleanupHandler&quot;, \&amp;purge);
  -</PRE>
  -<P><A NAME="anchor188"></A>
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre> Apache-&gt;push_handlers(&quot;PerlCleanupHandler&quot;, \&amp;purge);</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Persistent database connection modules such as <CODE>Apache::DBI</CODE> could push a <CODE>PerlCleanupHandler</CODE> handler that iterates over <CODE>%Connected</CODE>, refreshing connections or just checking that connections have not gone
   stale. Remember, by the time we get to <CODE>PerlCleanupHandler</CODE>, the client has what it wants and has gone away, so we can spend as much
   time as we want here without slowing down response time to the client
   (although the process itself is unavailable for serving new requests before
   the operation is completed).
   
  -<P><A NAME="anchor189"></A>
  +<P>
   <CODE>PerlTransHandlers</CODE> (e.g. <CODE>Apache::MsqlProxy</CODE>) may decide, based on the URI or some arbitrary condition, whether or not
   to handle a request. Without stacked handlers, users must configure it
   themselves:
   
  -<P><A NAME="anchor190"></A>
  -<PRE> PerlTransHandler Apache::MsqlProxy::translate
  - PerlHandler      Apache::MsqlProxy
  -</PRE>
  -<P><A NAME="anchor191"></A>
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre> PerlTransHandler Apache::MsqlProxy::translate
  + PerlHandler      Apache::MsqlProxy</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   <CODE>PerlHandler</CODE> is never actually invoked unless <CODE>translate()</CODE> sees that the request is a proxy request (<CODE>$r-&gt;proxyreq</CODE>). If it is a proxy request, <CODE>translate()</CODE> sets <CODE>$r-&gt;handler("perl-script")</CODE>, and only then will <CODE>PerlHandler</CODE> handle the request. Now users do not have to specify <CODE>PerlHandler Apache::MsqlProxy</CODE>, the
   <CODE>translate()</CODE> function can set it with <CODE>push_handlers()</CODE>.
   
  -<P><A NAME="anchor192"></A>
  +<P>
   Imagine that you want to include footers, headers, etc., piecing together a
   document, without using SSI. The following example shows how to implement
   it. First we prepare the code as follows:
  +
  +<P>
   
  -<P><A NAME="anchor193"></A>
  -<PRE>  My/Compose.pm
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  My/Compose.pm
     ----------
     package Test::Compose;
  -  use Apache::Constants qw(:common);
  -</PRE>
  -<P><A NAME="anchor194"></A>
  -<PRE>  sub header {
  +  use Apache::Constants qw(:common);</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  sub header {
        my $r = shift;
        $r-&gt;content_type(&quot;text/plain&quot;);
        $r-&gt;send_http_header;
  @@ -1073,21 +1685,45 @@
     sub body   { shift-&gt;print(&quot;body text\n&quot;)   ; return OK}
     sub footer { shift-&gt;print(&quot;footer text\n&quot;) ; return OK}
     1;
  -  __END__
  -</PRE>
  -<P><A NAME="anchor195"></A>
  -<PRE>  # in httpd.conf or perl.conf
  +  __END__</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  # in httpd.conf or perl.conf
     &lt;Location /foo&gt;
        SetHandler &quot;perl-script&quot;
        PerlHandler Test::Compose::header Test::Compose::body Test::Compose::footer   
  -   &lt;/Location&gt;
  -</PRE>
  -<P><A NAME="anchor196"></A>
  +   &lt;/Location&gt;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Parsing the output of another PerlHandler? This is a little more tricky,
   but consider:
  +
  +<P>
   
  -<P><A NAME="anchor197"></A>
  -<PRE>  &lt;Location /foo&gt;
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  &lt;Location /foo&gt;
       SetHandler &quot;perl-script&quot;
       PerlHandler OutputParser SomeApp
     &lt;/Location&gt;
  @@ -1095,16 +1731,40 @@
     &lt;Location /bar&gt;
       SetHandler &quot;perl-script&quot;
       PerlHandler OutputParser AnotherApp
  -  &lt;/Location&gt;
  -</PRE>
  -<P><A NAME="anchor198"></A>
  +  &lt;/Location&gt;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Now, OutputParser goes first, but it <CODE>untie()'s</CODE> <CODE>*STDOUT</CODE> and re-tie()'s it to its own package like so:
   
  -<P><A NAME="anchor199"></A>
  -<PRE> package OutputParser;
  -</PRE>
  -<P><A NAME="anchor200"></A>
  -<PRE> sub handler {
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre> package OutputParser;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre> sub handler {
        my $r = shift;
        untie *STDOUT;
        tie *STDOUT =&gt; 'OutputParser', $r;
  @@ -1121,31 +1781,68 @@
            #do whatever you want to $_ for example:
            $self-&gt;{r}-&gt;print($_ . &quot;[insert stuff]&quot;);
        }
  - }
  -</PRE>
  -<P><A NAME="anchor201"></A>
  -<PRE> 1;
  - __END__
  -</PRE>
  -<P><A NAME="anchor202"></A>
  + }</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre> 1;
  + __END__</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   To build in this feature, configure with:
   
  -<P><A NAME="anchor203"></A>
  -<PRE>  % perl Makefile.PL PERL_STACKED_HANDLERS=1 [ ... ]
  -</PRE>
  -<P><A NAME="anchor204"></A>
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  % perl Makefile.PL PERL_STACKED_HANDLERS=1 [ ... ]</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   If you want to test whether your running mod_perl Apache can stack
   handlers, the method <CODE>Apache-&gt;can_stack_handlers</CODE> will return
   <CODE>TRUE</CODE> if mod_perl was configured with <CODE>PERL_STACKED_HANDLERS=1</CODE>, and <CODE>FALSE</CODE> otherwise.
   
  -<P><A NAME="anchor205"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="Perl_Method_Handlers">Perl Method Handlers</A></H2></CENTER>
  -<P><A NAME="anchor206"></A>
  +<P>
   If a <CODE>Perl*Handler</CODE> is prototyped with <CODE>$$</CODE>, this handler will be invoked as a method. For example:
   
  -<P><A NAME="anchor207"></A>
  -<PRE>  package My;
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  package My;
     @ISA = qw(BaseClass);
      
     sub handler ($$) {
  @@ -1161,142 +1858,294 @@
     }
     
     1;
  -  __END__
  -</PRE>
  -<P><A NAME="anchor208"></A>
  +  __END__</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Configuration:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor209"></A>
  -<PRE> PerlHandler My
  -</PRE>
  -<P><A NAME="anchor210"></A>
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre> PerlHandler My</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   or
   
  -<P><A NAME="anchor211"></A>
  -<PRE> PerlHandler My-&gt;handler
  -</PRE>
  -<P><A NAME="anchor212"></A>
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre> PerlHandler My-&gt;handler</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Since the handler is invoked as a method, it may inherit from other
   classes:
  +
  +<P>
   
  -<P><A NAME="anchor213"></A>
  -<PRE> PerlHandler My-&gt;method
  -</PRE>
  -<P><A NAME="anchor214"></A>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre> PerlHandler My-&gt;method</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   META: requires more explanation!
   
  -<P><A NAME="anchor215"></A>
  +<P>
   In this case, the <CODE>My</CODE> class inherits this method from <CODE>BaseClass</CODE>.
   
  -<P><A NAME="anchor216"></A>
  +<P>
   To build in this feature, configure with:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor217"></A>
  -<PRE> % perl Makefile.PL PERL_METHOD_HANDLERS=1 [ ... ]
  -</PRE>
  -<P><A NAME="anchor218"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre> % perl Makefile.PL PERL_METHOD_HANDLERS=1 [ ... ]</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="PerlFreshRestart">PerlFreshRestart</A></H2></CENTER>
  -<P><A NAME="anchor219"></A>
  +<P>
   To reload <CODE>PerlRequire</CODE>, <CODE>PerlModule</CODE> and other <CODE>use()</CODE>'d modules, and to flush the <CODE>Apache::Registry</CODE> cache on server restart, add to 
   <EM>httpd.conf</EM>:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor220"></A>
  -<PRE>  PerlFreshRestart On
  -</PRE>
  -<P><A NAME="anchor221"></A>
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  PerlFreshRestart On</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Make sure you read <A HREF="././troubleshooting.html#Evil_things_might_happen_when_us">Evil things might happen when using PerlFreshRestart</A>.
   
  -<P><A NAME="anchor222"></A>
  +<P>
   Starting from mod_perl version 1.22 <CODE>PerlFreshRestart</CODE> is ignored when mod_perl is compiled as a DSO. But it almost doesn't
   matter, since mod_perl as a DSO will do a full tear-down (perl_destruct()).
   So it's still a <EM>FreshRestart</EM>, just fresher than static (non-DSO) mod_perl :)
   
  -<P><A NAME="anchor223"></A>
  +<P>
   But note that even if you have
   
  -<P><A NAME="anchor224"></A>
  -<PRE>  PerlFreshRestart No
  -</PRE>
  -<P><A NAME="anchor225"></A>
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  PerlFreshRestart No</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   and mod_perl as a DSO you will still get a <EM>FreshRestart</EM>.
   
  -<P><A NAME="anchor226"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="PerlSetVar_PerlSetEnv_and_PerlP">PerlSetVar, PerlSetEnv and PerlPassEnv</A></H2></CENTER>
  -<P><A NAME="anchor227"></A>
  -<PRE>  PerlSetEnv key val
  -  PerlPassEnv key
  -</PRE>
  -<P><A NAME="anchor228"></A>
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  PerlSetEnv key val
  +  PerlPassEnv key</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   <CODE>PerlPassEnv</CODE> passes, <CODE>PerlSetEnv</CODE> sets and passes <EM>ENVironment</EM>
   variables to your scripts. You can access them in your scripts through
   <CODE>%ENV</CODE> (e.g. <CODE>$ENV{&quot;key&quot;}</CODE>).
   
  -<P><A NAME="anchor229"></A>
  +<P>
   Regarding the setting of <CODE>PerlPassEnv PERL5LIB</CODE> in <EM>httpd.conf</EM>: if you turn on taint checks (<CODE>PerlTaintMode On</CODE>), <CODE>$ENV{PERL5LIB}</CODE> will be ignored (unset). See the '<A HREF="././porting.html#Command_line_Switches_w_T_e">Switches -w, -T</A>' section.
   
  -<P><A NAME="anchor230"></A>
  +<P>
   <CODE>PerlSetVar</CODE> is very similar to <CODE>PerlSetEnv</CODE>, but you extract it with another method. 
  +
  +<P>
   
  -<P><A NAME="anchor231"></A>
  -<PRE>  PerlSetVar key val
  -</PRE>
  -<P><A NAME="anchor232"></A>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  PerlSetVar key val</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   or
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor233"></A>
  -<PRE>  push @{ $Location{&quot;/&quot;}-&gt;{PerlSetVar} }, [ key =&gt; 'val' ];
  -</PRE>
  -<P><A NAME="anchor234"></A>
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  push @{ $Location{&quot;/&quot;}-&gt;{PerlSetVar} }, [ key =&gt; 'val' ];</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   and in the code you read it with:
   
  -<P><A NAME="anchor235"></A>
  -<PRE>  my $r = Apache-&gt;request;
  -  print $r-&gt;dir_config('key');
  -</PRE>
  -<P><A NAME="anchor236"></A>
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  my $r = Apache-&gt;request;
  +  print $r-&gt;dir_config('key');</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   The above prints: 
  +
  +<P>
   
  -<P><A NAME="anchor237"></A>
  -<PRE>  val
  -</PRE>
  -<P><A NAME="anchor238"></A>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  val</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Note that you cannot do this:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor239"></A>
  -<PRE>  push @{ $Location{&quot;/&quot;}-&gt;{PerlSetVar} }, [ key =&gt; \%hash ];
  -</PRE>
  -<P><A NAME="anchor240"></A>
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  push @{ $Location{&quot;/&quot;}-&gt;{PerlSetVar} }, [ key =&gt; \%hash ];</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   All values are treated as strings, so you will get a stringified reference
   to a hash as a value (something which will look like ``<CODE>HASH(0x87a5108)</CODE>''). This cannot be turned back into a reference and therefore the original
   hash upon retrieval.
   
  -<P><A NAME="anchor241"></A>
  +<P>
   However you can 
   
  -<P><A NAME="anchor242"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="PerlSetupEnv">PerlSetupEnv</A></H2></CENTER>
  -<P><A NAME="anchor243"></A>
  +<P>
   See <A HREF="././performance.html#PerlSetupEnv_Off">PerlSetupEnv Off</A>.
   
  -<P><A NAME="anchor244"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="PerlWarn_and_PerlTaintCheck">PerlWarn and PerlTaintCheck</A></H2></CENTER>
  -<P><A NAME="anchor245"></A>
  +<P>
   For <STRONG>PerlWarn</STRONG> and <STRONG>PerlTaintCheck</STRONG> directives see the '<A HREF="././porting.html#Command_line_Switches_w_T_e">Switches -w, -T</A>' section.
   
  -<P><A NAME="anchor246"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="MinSpareServers_MaxSpareServers_">MinSpareServers MaxSpareServers StartServers MaxClients MaxRequestsPerChild</A></H2></CENTER>
  -<P><A NAME="anchor247"></A>
  +<P>
   <CODE>MinSpareServers</CODE>, <CODE>MaxSpareServers</CODE>, <CODE>StartServers</CODE> and
   <CODE>MaxClients</CODE> are standard Apache configuration directives that control the number of
   servers that will be launched at server startup and kept alive during the
   server's operation.
   
  -<P><A NAME="anchor248"></A>
  +<P>
   <CODE>MaxRequestsPerChild</CODE> lets you specify the maximum number of requests which each child will be
   allowed to serve. When a process has served
   <CODE>MaxRequestsPerChild</CODE> requests the parent kills it and replaces it with a new one. There may also
  @@ -1304,27 +2153,40 @@
   will in fact serve this many requests, only that it will not be allowed to
   serve more than that number.
   
  -<P><A NAME="anchor249"></A>
  +<P>
   These five directives are very important for achieving the best performance
   from your server. The section ' <A HREF="././performance.html#Performance_Tuning_by_Tweaking_A">Performance Tuning by Tweaking Apache Configuration</A>' provides all the details.
   
  -<P><A NAME="anchor250"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H1><A NAME="The_Startup_File">The Startup File</A></H1></CENTER>
  -<P><A NAME="anchor251"></A>
  +<P>
   At server startup, before child processes are spawned to receive incoming
   requests, there is more that can be done than just preloading files. You
   might want to register code that will initialize a database connection for
   each child when it is forked, tie read-only dbm files, etc.
   
  -<P><A NAME="anchor252"></A>
  +<P>
   The <EM>startup.pl</EM> file is an ideal place to put the code that should be executed when the
   server starts. Once you have prepared the code, load it in <EM>httpd.conf</EM> before the rest of the mod_perl configuration directives like this:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor253"></A>
  -<PRE>    PerlRequire  /home/httpd/perl/lib/startup.pl
  -</PRE>
  -<P><A NAME="anchor254"></A>
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>    PerlRequire  /home/httpd/perl/lib/startup.pl</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   I must stress that all the code that is run at server initialization time
   is run with root priveleges if you are executing it as the root user (which
   you have to do unless you choose to run the server on an unprivileged port,
  @@ -1335,21 +2197,43 @@
   directive and <CODE>PERL_OPMASK_DEFAULT</CODE> compile time option to try to disable some of the more dangerous
   operations.
   
  -<P><A NAME="anchor255"></A>
  +<P>
   Since the startup file is a file written in plain Perl, one can validate
   its syntax with:
   
  -<P><A NAME="anchor256"></A>
  -<PRE>  % perl -c /home/httpd/perl/lib/startup.pl
  -</PRE>
  -<P><A NAME="anchor257"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  % perl -c /home/httpd/perl/lib/startup.pl</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="The_Sample_Startup_File">The Sample Startup File</A></H2></CENTER>
  -<P><A NAME="anchor258"></A>
  +<P>
   Let's look at a real world startup file:
  +
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
   
  -<P><A NAME="anchor259"></A>
  -<PRE>  startup.pl
  +	<td>
  +	  <pre>  startup.pl
     ----------
     use strict;
     
  @@ -1387,66 +2271,150 @@
       RaiseError =&gt; 0, # don't die on error
       AutoCommit =&gt; 1, # commit executes immediately
      }
  -  );
  -</PRE>
  -<P><A NAME="anchor260"></A>
  +  );</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Now we'll review the code explaining why each line is used.
   
  -<P><A NAME="anchor261"></A>
  -<PRE>  use strict;
  -</PRE>
  -<P><A NAME="anchor262"></A>
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  use strict;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   This pragma is worth using in every script longer than half a dozen lines.
   It will save a lot of time and debugging later on.
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor263"></A>
  -<PRE>  use lib qw(/dir/foo /dir/bar);
  -</PRE>
  -<P><A NAME="anchor264"></A>
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  use lib qw(/dir/foo /dir/bar);</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   The only chance to permanently modify the <CODE>@INC</CODE> before the server is started is with this command. Later the running code
   can modify
   <CODE>@INC</CODE> just for the moment it <CODE>requre()'s</CODE> some file, and then
   <CODE>@INC</CODE>'s value gets reset to what it was originally.
   
  -<P><A NAME="anchor265"></A>
  -<PRE>  $ENV{MOD_PERL} or die &quot;not running under mod_perl!&quot;;
  -</PRE>
  -<P><A NAME="anchor266"></A>
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  $ENV{MOD_PERL} or die &quot;not running under mod_perl!&quot;;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   A sanity check, if Apache/mod_perl wasn't properly built, the above code
   will abort the server startup.
  +
  +<P>
   
  -<P><A NAME="anchor267"></A>
  -<PRE>  use Apache::Registry;          
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  use Apache::Registry;          
     use LWP::UserAgent ();
     use Apache::DBI ();
  -  use DBI ();
  -</PRE>
  -<P><A NAME="anchor268"></A>
  +  use DBI ();</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Preload the modules that get used by our Perl code serving the requests.
   Unless you need the symbols (variables and subroutines) exported by the
   modules you preload to accomplish something within the startup file, don't
   import them, since it's just a waste of startup time. Instead use the empty
   list <CODE>()</CODE> to tell the <CODE>import()</CODE> function not to import anything.
   
  -<P><A NAME="anchor269"></A>
  -<PRE>  use Carp ();
  -  $SIG{__WARN__} = \&amp;Carp::cluck;
  -</PRE>
  -<P><A NAME="anchor270"></A>
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  use Carp ();
  +  $SIG{__WARN__} = \&amp;Carp::cluck;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   This is a useful snippet to enable extended warnings logged in the
   error_log file. In addition to basic warnings, a trace of calls is added.
   This makes the tracking of the potential problem a much easier task, since
   you know who called whom. For example, with normal warnings you might see:
   
  -<P><A NAME="anchor271"></A>
  -<PRE>  Use of uninitialized value at
  -      /usr/lib/perl5/site_perl/5.005/Apache/DBI.pm  line 110.
  -</PRE>
  -<P><A NAME="anchor272"></A>
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  Use of uninitialized value at
  +      /usr/lib/perl5/site_perl/5.005/Apache/DBI.pm  line 110.</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   but you have no idea where it was called from. When we use <CODE>Carp</CODE> as shown above we might see:
  +
  +<P>
   
  -<P><A NAME="anchor273"></A>
  -<PRE>  Use of uninitialized value at
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  Use of uninitialized value at
               /usr/lib/perl5/site_perl/5.005/Apache/DBI.pm line 110.
         Apache::DBI::connect(undef, 'mydb::localhost', 'user',
            'passwd', 'HASH(0x87a5108)') called at
  @@ -1458,120 +2426,209 @@
               PerlChildInitHandler subroutine 
               `Apache::DBI::__ANON__' line 0
         eval {...} called at PerlChildInitHandler subroutine 
  -            `Apache::DBI::__ANON__' line 0
  -</PRE>
  -<P><A NAME="anchor274"></A>
  +            `Apache::DBI::__ANON__' line 0</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   we clearly see that the warning was triggered by <CODE>eval()'uating</CODE>
   the
   <CODE>Apache::DBI::__ANON__</CODE> which called <CODE>DBI::connect</CODE> (with the arguments that we see as well), which in turn called the
   <CODE>Apache::DBI::connect</CODE> method. Now we know where to look for our problem.
   
  -<P><A NAME="anchor275"></A>
  -<PRE>  use CGI ();
  -  CGI-&gt;compile(':all');
  -</PRE>
  -<P><A NAME="anchor276"></A>
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  use CGI ();
  +  CGI-&gt;compile(':all');</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Some modules create their subroutines at run time to improve their load
   time. This helps when the module includes many subroutines, but only a few
   are actually used. <CODE>CGI.pm</CODE> falls into this category. Since with mod_perl the module is loaded only
   once, it might be a good idea to precompile all or a part of its methods.
   
  -<P><A NAME="anchor277"></A>
  +<P>
   <CODE>CGI.pm</CODE>'s <CODE>compile()</CODE> method performs this task. Notice that this is a
   propietary function of this module, other modules can implement this
   feature or not and use this or some other name for this functionality. As
   with all modules we preload in the startup file, we don't import symbols
   from them as they will be lost when they go out of the file's scope.
   
  -<P><A NAME="anchor278"></A>
  +<P>
   Note that starting with <CODE>$CGI::VERSION</CODE> 2.46, the recommended method to precompile the code in <CODE>CGI.pm</CODE> is:
   
  -<P><A NAME="anchor279"></A>
  -<PRE>  use CGI qw(-compile :all);
  -</PRE>
  -<P><A NAME="anchor280"></A>
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  use CGI qw(-compile :all);</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   But the old method is still available for backward compatibility.
   
  -<P><A NAME="anchor281"></A>
  +<P>
   See also the '<A HREF="././debug.html#Apache_Status_Embedded_Inter">Apache::Status -- Embedded interpreter status information</A>' section.
   
  -<P><A NAME="anchor282"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="What_Modules_You_Should_Add_to_t">What Modules You Should Add to the Startup File and Why</A></H2></CENTER>
  -<P><A NAME="anchor283"></A>
  +<P>
   Every module loaded at server startup will be shared among the server
   children, saving a lot of RAM on your machine. Usually I put most of the
   code I develop into modules and preload them.
   
  -<P><A NAME="anchor284"></A>
  +<P>
   You can even preload your CGI script with <CODE>Apache::RegistryLoader</CODE>
  -(See <A HREF="././performance.html#Preload_Perl_Modules_at_Server_S">Preload Perl modules at server startup</A>) and you can get the children to preopen their database connections with
  +(See <A HREF="././performance.html#Preloading_Perl_Modules_at_Serve">Preload Perl modules at server startup</A>) and you can get the children to preopen their database connections with
   <CODE>Apache::DBI</CODE>.
   
  -<P><A NAME="anchor285"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="The_Confusion_with_use_in_the_">The Confusion with use() in the Server Startup File</A></H2></CENTER>
  -<P><A NAME="anchor286"></A>
  +<P>
   Some people wonder why you need to duplicate the <CODE>use()</CODE> clause in the startup file and in the script itself. The confusion arises
   due to misunderstanding the <CODE>use()</CODE> function. <CODE>use()</CODE> normally performs two operations, namely <CODE>require()</CODE> and <CODE>import()</CODE>, called within a
   <CODE>BEGIN</CODE> block. See the section ``<A HREF="././perl.html#use_">use()</A>'' for a detailed explanation of the <CODE>use(),</CODE>
   <CODE>require()</CODE> and <CODE>import()</CODE> functions.
   
  -<P><A NAME="anchor287"></A>
  +<P>
   In the startup file we don't want to import any symbols since they will be
   lost when we leave the scope of the startup file anyway, i.e. they won't be
   visible to any of the child processes which run our mod_perl scripts.
   Instead we want to preload the module in the startup file and then import
   any symbols that we actually need in each script individually.
   
  -<P><A NAME="anchor288"></A>
  +<P>
   Normally when we write <CODE>use MyModule;</CODE>, <CODE>use</CODE> will both load the module and import its symbols; so for the startup file
   we write <CODE>use
   MyModule ();</CODE> and the empty parentheses will ensure that the module is loaded but that no
   symbols are imported. Then in the actual mod_perl script we write <CODE>use()</CODE> in the standard way, e.g. <CODE>use MyModule;</CODE>. Since the module has already been preloaded, the only action taken is to
   import the symbols. For example in the startup file you write:
  +
  +<P>
   
  -<P><A NAME="anchor289"></A>
  -<PRE>  use CGI ();
  -</PRE>
  -<P><A NAME="anchor290"></A>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  use CGI ();</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   since you probably don't need any symbols to be imported there. But in your
   code you would probably write:
  +
  +<P>
   
  -<P><A NAME="anchor291"></A>
  -<PRE>  use CGI qw(:html);
  -</PRE>
  -<P><A NAME="anchor292"></A>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  use CGI qw(:html);</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   For example, if you have <CODE>use()'d</CODE>  <CODE>Apache::Constants</CODE> in the startup file, it does not mean you can have the following handler:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor293"></A>
  -<PRE>  package MyModule;
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  package MyModule;
     sub {
       my $r = shift;
       ## Cool stuff goes here
       return OK;
     }
  -  1;
  -</PRE>
  -<P><A NAME="anchor294"></A>
  +  1;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   You would either need to add:
  +
  +<P>
   
  -<P><A NAME="anchor295"></A>
  -<PRE>  use Apache::Constants qw( OK );
  -</PRE>
  -<P><A NAME="anchor296"></A>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  use Apache::Constants qw( OK );</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Or use the fully qualified name:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor297"></A>
  -<PRE>  return Apache::Constants::OK;
  -</PRE>
  -<P><A NAME="anchor298"></A>
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  return Apache::Constants::OK;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   If you want to use the function interface without exporting the symbols,
   use fully qualified function names, e.g. <CODE>CGI::param</CODE>. The same rule applies to variables, you can import variables and you can
   access them by their full name. e g. <CODE>$My::Module::bar</CODE>. When you use the object oriented (method) interface you don't need to
   export the method symbols.
   
  -<P><A NAME="anchor299"></A>
  +<P>
   Technically, you aren't required to supply the <CODE>use()</CODE> statement
   in your (handler?) code if it was already loaded during server startup
   (i.e. by '<CODE>PerlRequire startup.pl</CODE>'). When writing your code, however, you should not assume the module code
  @@ -1579,19 +2636,20 @@
   code and will not understand how it is possible to use a module's methods
   without first loading the module itself.
   
  -<P><A NAME="anchor300"></A>
  +<P>
   Read the <CODE>Exporter</CODE> and <CODE>perlmod</CODE> manpages for more information about <CODE>import()</CODE>.
   
  -<P><A NAME="anchor301"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="The_Confusion_with_Global_Variab">The Confusion with Global Variables in the Startup File</A></H2></CENTER>
  -<P><A NAME="anchor302"></A>
  +<P>
   <CODE>PerlRequire</CODE> allows you to execute code that preloads modules and performs other
   functions. Imported or defined variables are visible in the scope of the
   startup file. It is wrong to assume that global variables that were defined
   in the startup file will be visible to child processes.
   
  -<P><A NAME="anchor303"></A>
  +<P>
   If you define or import variables in your scripts they will be visible
   inside the child process which is running the script: but they will not be
   shared between siblings. Remember that every script is running in a
  @@ -1599,25 +2657,36 @@
   other packages unless it inherits from them or
   <CODE>use()</CODE>'s them.
   
  -<P><A NAME="anchor304"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H1><A NAME="Apache_Configuration_in_Perl">Apache Configuration in Perl</A></H1></CENTER>
  -<P><A NAME="anchor305"></A>
  +<P>
   With <CODE>&lt;Perl&gt;</CODE>...<CODE>&lt;/Perl&gt;</CODE> sections, it is possible to configure your server entirely in Perl.
   
  -<P><A NAME="anchor306"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="Usage">Usage</A></H2></CENTER>
  -<P><A NAME="anchor307"></A>
  +<P>
   <CODE>&lt;Perl&gt;</CODE> sections can contain <EM>any</EM> and as much Perl code as you wish. These sections are compiled into a
   special package whose symbol table mod_perl can then walk and grind the
   names and values of Perl variables/structures through the Apache core
   configuration gears. Most of the configuration directives can be
   represented as scalars (<CODE>$scalar</CODE>) or lists (<CODE>@list</CODE>). A <CODE>@List</CODE> inside these sections is simply converted into a space delimited string for
   you. Here is an example:
  +
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
   
  -<P><A NAME="anchor308"></A>
  -<PRE>   httpd.conf
  +	<td>
  +	  <pre>   httpd.conf
     ------------
     &lt;Perl&gt;
     @PerlModule = qw(Mail::Send Devel::Peek);
  @@ -1628,13 +2697,25 @@
     
     $ServerAdmin = $User;
     
  -  &lt;/Perl&gt;
  -</PRE>
  -<P><A NAME="anchor309"></A>
  +  &lt;/Perl&gt;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Block sections such as <CODE>&lt;Location&gt;</CODE>..<CODE>&lt;/Location&gt;</CODE> are represented in a <CODE>%Location</CODE> hash, e.g.:
   
  -<P><A NAME="anchor310"></A>
  -<PRE>  &lt;Perl&gt;
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  &lt;Perl&gt;
     
     $Location{&quot;/~dougm/&quot;} = {
       AuthUserFile =&gt; '/tmp/htpasswd',
  @@ -1647,83 +2728,155 @@
       },
     };
     
  -  &lt;/Perl&gt;
  -</PRE>
  -<P><A NAME="anchor311"></A>
  +  &lt;/Perl&gt;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   If an Apache directive can take two or three arguments you may push strings
   (the lowest number of arguments will be shifted off the
   <CODE>@List</CODE>) or use an array reference to handle any number greater than the minimum
   for that directive:
  +
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
   
  -<P><A NAME="anchor312"></A>
  -<PRE>  push @Redirect, &quot;/foo&quot;, &quot;<A HREF="http://www.foo.com/&quot">http://www.foo.com/&quot</A>;;
  +	<td>
  +	  <pre>  push @Redirect, &quot;/foo&quot;, &quot;<A HREF="http://www.foo.com/&quot">http://www.foo.com/&quot</A>;;
     
     push @Redirect, &quot;/imdb&quot;, &quot;<A HREF="http://www.imdb.com/&quot">http://www.imdb.com/&quot</A>;;
     
  -  push @Redirect, [qw(temp &quot;/here&quot; &quot;<A HREF="http://www.there.com&quot">http://www.there.com&quot</A>;)];
  -</PRE>
  -<P><A NAME="anchor313"></A>
  +  push @Redirect, [qw(temp &quot;/here&quot; &quot;<A HREF="http://www.there.com&quot">http://www.there.com&quot</A>;)];</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Other section counterparts include <CODE>%VirtualHost</CODE>, <CODE>%Directory</CODE> and
   <CODE>%Files</CODE>.
   
  -<P><A NAME="anchor314"></A>
  +<P>
   To pass all environment variables to the children with a single
   configuration directive, rather than listing each one via <CODE>PassEnv</CODE>
   or <CODE>PerlPassEnv</CODE>, a <CODE>&lt;Perl&gt;</CODE> section could read in a file and:
   
  -<P><A NAME="anchor315"></A>
  -<PRE>  push @PerlPassEnv, [$key =&gt; $val];
  -</PRE>
  -<P><A NAME="anchor316"></A>
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  push @PerlPassEnv, [$key =&gt; $val];</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   or
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor317"></A>
  -<PRE>  Apache-&gt;httpd_conf(&quot;PerlPassEnv $key $val&quot;);
  -</PRE>
  -<P><A NAME="anchor318"></A>
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  Apache-&gt;httpd_conf(&quot;PerlPassEnv $key $val&quot;);</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   These are somewhat simple examples, but they should give you the basic
   idea. You can mix in any Perl code you desire. See <EM>eg/httpd.conf.pl</EM>
   and <EM>eg/perl_sections.txt</EM> in the mod_perl distribution for more examples.
   
  -<P><A NAME="anchor319"></A>
  +<P>
   Assume that you have a cluster of machines with similar configurations and
   only small distinctions between them: ideally you would want to maintain a
   single configuration file, but because the configurations aren't <EM>exactly</EM> the same (e.g. the <CODE>ServerName</CODE> directive) it's not quite that simple.
   
  -<P><A NAME="anchor320"></A>
  +<P>
   <CODE>&lt;Perl&gt;</CODE> sections come to rescue. Now you have a single configuration file and the
   full power of Perl to tweak the local configuration. For example to solve
   the problem of the <CODE>ServerName</CODE> directive you might have this <CODE>&lt;Perl&gt;</CODE> section:
  +
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
   
  -<P><A NAME="anchor321"></A>
  -<PRE>  &lt;Perl&gt;
  +	<td>
  +	  <pre>  &lt;Perl&gt;
     $ServerName = `hostname`;
  -  &lt;/Perl&gt;
  -</PRE>
  -<P><A NAME="anchor322"></A>
  +  &lt;/Perl&gt;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   For example if you want to allow personal directories on all machines
   except the ones whose names start with <EM>secure</EM>:
   
  -<P><A NAME="anchor323"></A>
  -<PRE>  &lt;Perl&gt;
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  &lt;Perl&gt;
     $ServerName = `hostname`;
     if ( $ServerName !~ /^secure/) {
       $UserDir = &quot;public.html&quot;;
     } else {
       $UserDir = &quot;DISABLED&quot;;
     }
  -  &lt;/Perl&gt;
  -</PRE>
  -<P><A NAME="anchor324"></A>
  +  &lt;/Perl&gt;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Behind the scenes, mod_perl defines a package called
   <CODE>Apache::ReadConfig</CODE>. Here it keeps all the variables that you define inside the <CODE>&lt;Perl&gt;</CODE> sections. Therefore it's not necessarily to configure the server within the <CODE>&lt;Perl&gt;</CODE> sections. Actually what you can do is to write the Perl code to configure
   the server just like you'd do in the <CODE>&lt;Perl&gt;</CODE> sections, but instead place it into a separate file that should be called
   during the configuration parsing with either <CODE>PerlModule</CODE> or <CODE>PerlRequire</CODE> directives, or from within the startup file. All you have to do is to
   declare the package
   <CODE>Apache::ReadConfig</CODE> within this file. Using the last example:
  +
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
   
  -<P><A NAME="anchor325"></A>
  -<PRE>  apache_config.pl
  +	<td>
  +	  <pre>  apache_config.pl
     ---------------- 
     package Apache::ReadConfig;
     
  @@ -1734,74 +2887,140 @@
       $UserDir = &quot;DISABLED&quot;;
     }
     
  -  1;
  -</PRE>
  -<P><A NAME="anchor326"></A>
  -<PRE>  httpd.conf
  +  1;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  httpd.conf
     ----------
  -  PerlRequire /home/httpd/perl/lib/apache_config.pl
  -</PRE>
  -<P><A NAME="anchor327"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +  PerlRequire /home/httpd/perl/lib/apache_config.pl</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="Enabling">Enabling</A></H2></CENTER>
  -<P><A NAME="anchor328"></A>
  +<P>
   To enable <CODE>&lt;Perl&gt;</CODE> sections you should build mod_perl with perl
   Makefile.PL&nbsp;PERL_SECTIONS=1&nbsp;[&nbsp;...&nbsp;].
   
  -<P><A NAME="anchor329"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="Caveats">Caveats</A></H2></CENTER>
  -<P><A NAME="anchor330"></A>
  +<P>
   Be careful when you declare package names inside <CODE>&lt;Perl&gt;</CODE> sections, for example this code has a problem:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor331"></A>
  -<PRE>  &lt;Perl&gt;  
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  &lt;Perl&gt;  
       package My::Trans;
       use Apache::Constants qw(:common);
       sub handler{ OK }
       
       $PerlTransHandler = &quot;My::Trans&quot;;
  -  &lt;/Perl&gt;
  -</PRE>
  -<P><A NAME="anchor332"></A>
  +  &lt;/Perl&gt;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   When you put code inside a <CODE>&lt;Perl&gt;</CODE> section, by default it actually goes into the <CODE>Apache::ReadConfig</CODE> package, which is already declared for you. This means that the <CODE>PerlTransHandler</CODE> we have tried to define above is actually undefined. If you define a
   different package name within a <CODE>&lt;Perl&gt;</CODE> section you must make sure to close the scope of that package and return to
   the <CODE>Apache::ReadConfig</CODE> package when you want to define the configuration directives, like this:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor333"></A>
  -<PRE>  &lt;Perl&gt;  
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  &lt;Perl&gt;  
       package My::Trans;
       use Apache::Constants qw(:common);
       sub handler{ OK }
       
       package Apache::ReadConfig;  
       $PerlTransHandler = &quot;My::Trans&quot;;
  -  &lt;/Perl&gt;
  -</PRE>
  -<P><A NAME="anchor334"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +  &lt;/Perl&gt;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="Verifying">Verifying</A></H2></CENTER>
  -<P><A NAME="anchor335"></A>
  +<P>
   This section shows how to check and dump the configuration you have made
   with the help of <CODE>&lt;Perl&gt;</CODE> sections in <EM>httpd.conf</EM>.
   
  -<P><A NAME="anchor336"></A>
  +<P>
   To check the <CODE>&lt;Perl&gt;</CODE> section syntax outside of httpd, we make it look like a Perl script:
  +
  +<P>
   
  -<P><A NAME="anchor337"></A>
  -<PRE>  &lt;Perl&gt;
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  &lt;Perl&gt;
     # !perl
     # ... code here ...
     __END__
  -  &lt;/Perl&gt;
  -</PRE>
  -<P><A NAME="anchor338"></A>
  +  &lt;/Perl&gt;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Now you may run:
  +
  +<P>
   
  -<P><A NAME="anchor339"></A>
  -<PRE>  perl -cx httpd.conf
  -</PRE>
  -<P><A NAME="anchor340"></A>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  perl -cx httpd.conf</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   In a running httpd you can see how you have configured the <CODE>&lt;Perl&gt;</CODE>
   sections through the URI
   <A HREF="././debug.html#Apache_Status_Embedded_Inter">/perl-status</A>, by choosing <EM>Perl
  @@ -1809,198 +3028,358 @@
   set <CODE>$Apache::Server::SaveConfig</CODE> to a true value. When you do that the <EM>Apache::ReadConfig</EM> namespace (in which the configuration data is stored) will not be flushed,
   making configuration data available to Perl modules at request time.
   
  -<P><A NAME="anchor341"></A>
  +<P>
   Example:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor342"></A>
  -<PRE> &lt;Perl&gt;
  - $Apache::Server::SaveConfig = 1;
  -</PRE>
  -<P><A NAME="anchor343"></A>
  -<PRE> $DocumentRoot = ...
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre> &lt;Perl&gt;
  + $Apache::Server::SaveConfig = 1;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre> $DocumentRoot = ...
    ...
  - &lt;/Perl&gt;
  -</PRE>
  -<P><A NAME="anchor344"></A>
  + &lt;/Perl&gt;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   At request time, the value of <STRONG>$DocumentRoot</STRONG> can be accessed with the fully qualified name <STRONG>$Apache::ReadConfig::DocumentRoot</STRONG>.
   
  -<P><A NAME="anchor345"></A>
  +<P>
   You can dump the configuration of <CODE>&lt;Perl&gt;</CODE> sections like this:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor346"></A>
  -<PRE>  &lt;Perl&gt;
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  &lt;Perl&gt;
     use Apache::PerlSections();
     ...
     # Configuration Perl code here
     ...
     print STDERR Apache::PerlSections-&gt;dump();
  -  &lt;/Perl&gt;
  -</PRE>
  -<P><A NAME="anchor347"></A>
  +  &lt;/Perl&gt;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Alternatively you can store it in a file:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor348"></A>
  -<PRE>  Apache::PerlSections-&gt;store(&quot;httpd_config.pl&quot;);
  -</PRE>
  -<P><A NAME="anchor349"></A>
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  Apache::PerlSections-&gt;store(&quot;httpd_config.pl&quot;);</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   You can then <CODE>require()</CODE> that file in some other <CODE>&lt;Perl&gt;</CODE> section.
   
  -<P><A NAME="anchor350"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="Strict_Perl_Sections">Strict &lt;Perl&gt; Sections</A></H2></CENTER>
  -<P><A NAME="anchor351"></A>
  +<P>
   If the Perl code doesn't compile, the server won't start. If the generated
   Apache config is invalid, <CODE>&lt;Perl&gt;</CODE> sections have always just logged an error and carried on, since there might
   be globals in the section that are not intended for the config.
   
  -<P><A NAME="anchor352"></A>
  +<P>
   The variable <CODE>$Apache::Server::StrictPerlSections</CODE> has been added in mod_perl version 1.22. If you set this variable to a true
   value, for example
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor353"></A>
  -<PRE>  $Apache::Server::StrictPerlSections = 1;
  -</PRE>
  -<P><A NAME="anchor354"></A>
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  $Apache::Server::StrictPerlSections = 1;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   then mod_perl will not tolerate invalid Apache configuration syntax and
   will croak (die) if this is the case. At the time of writing the default
   value is <CODE>0</CODE>.
   
  -<P><A NAME="anchor355"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="Debugging">Debugging</A></H2></CENTER>
  -<P><A NAME="anchor356"></A>
  +<P>
   If you compile modperl with <CODE>PERL_TRACE=1</CODE> and set the environment variable <A HREF="././debug.html#Debug_Tracing">MOD_PERL_TRACE</A> then you should see some useful diagnostics when mod_perl is processing
   &lt;Perl&gt; sections.
   
  -<P><A NAME="anchor357"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="References">References</A></H2></CENTER>
  -<P><A NAME="anchor358"></A>
  +<P>
   For more info see <A
   HREF="http://www.modperl.com">http://www.modperl.com</A> Chapter 8
   
  -<P><A NAME="anchor359"></A>
  +<P>
   META: a direct link?
   
  -<P><A NAME="anchor360"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H1><A NAME="Validating_the_Configuration_Syn">Validating the Configuration Syntax</A></H1></CENTER>
  -<P><A NAME="anchor361"></A>
  +<P>
   <CODE>apachectl configtest</CODE> tests the configuration file without starting the server. You can safely
   validate the configuration file on your production server, if you run this
   test before you restart the server with <CODE>apachectl restart</CODE>. Of course it is not 100% perfect, but it will reveal any syntax errors
   you might have made while editing the file. 
   
  -<P><A NAME="anchor362"></A>
  +<P>
   '<CODE>apachectl configtest</CODE>' is the same as '<CODE>httpd -t</CODE>' and it doesn't just parse the code in startup.pl it actually executes it.
   <CODE>&lt;Perl&gt;</CODE> configuration has always started Perl during the configuration read, and <CODE>Perl{Require,Module}</CODE> do so as well.
   
  -<P><A NAME="anchor363"></A>
  +<P>
   Of course we assume that the code that gets called during this test cannot
   cause any harm to your running production environment. The following hint
   shows how to prevent the code in the startup script and
   <CODE>&lt;Perl&gt;</CODE> from being executed during the syntax check, if that's what you want.
   
  -<P><A NAME="anchor364"></A>
  +<P>
   If you want your startup code to get control over the <CODE>-t</CODE>
   (<CODE>configtest</CODE>) server launch, start the server configuration test with:
   
  -<P><A NAME="anchor365"></A>
  -<PRE>  httpd -t -Dsyntax_check
  -</PRE>
  -<P><A NAME="anchor366"></A>
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  httpd -t -Dsyntax_check</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   and, if for example you want to prevent your startup code from being
   executed, at the top of the code add:
  +
  +<P>
   
  -<P><A NAME="anchor367"></A>
  -<PRE>  return if Apache-&gt;define('syntax_check');
  -</PRE>
  -<P><A NAME="anchor368"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  return if Apache-&gt;define('syntax_check');</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H1><A NAME="Enabling_Remote_Server_Configura">Enabling Remote Server Configuration Reports</A></H1></CENTER>
  -<P><A NAME="anchor369"></A>
  +<P>
   The nifty mod_info module displays the complete server configuration in
   your browser. In order to use it you have compile it in or, if the server
   was compiled with DSO mode enabled, load it as an object. Then just
   uncomment the ready-prepared section in the <EM>httpd.conf</EM> file:
  +
  +<P>
   
  -<P><A NAME="anchor370"></A>
  -<PRE>  &lt;Location /server-info&gt;
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  &lt;Location /server-info&gt;
       SetHandler server-info
       Order deny,allow
       Deny from all
       Allow from www.example.com
  -  &lt;/Location&gt;
  -</PRE>
  -<P><A NAME="anchor371"></A>
  +  &lt;/Location&gt;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Now restart the server and issue the request:
  +
  +<P>
   
  -<P><A NAME="anchor372"></A>
  -<PRE>  <A HREF="http://www.example.com/server-info">http://www.example.com/server-info</A>
  -</PRE>
  -<P><A NAME="anchor373"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  <A HREF="http://www.example.com/server-info">http://www.example.com/server-info</A></pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H1><A NAME="Publishing_Port_Numbers_other_th">Publishing Port Numbers other than 80</A></H1></CENTER>
  -<P><A NAME="anchor374"></A>
  +<P>
   If you are using a two-server setup, with a mod_perl server listening on a
   high port, it is advised that you do not publish the number of the high
   port number in URLs. Rather use a proxying rewrite rule in the non-mod_perl
   server:
  +
  +<P>
   
  -<P><A NAME="anchor375"></A>
  -<PRE>  RewriteRule .*/perl/(.*) <A HREF="http://example.com:8080/perl/">http://example.com:8080/perl/</A>$1 [P]
  -</PRE>
  -<P><A NAME="anchor376"></A>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  RewriteRule .*/perl/(.*) <A HREF="http://example.com:8080/perl/">http://example.com:8080/perl/</A>$1 [P]</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   I was told one problem with publishing high port numbers is that IE 4.x has
   a bug when re-posting data to a non-port-80 URL. It drops the port
   designator, and uses port 80 anyway.
   
  -<P><A NAME="anchor377"></A>
  +<P>
   Another reason is that firewalls probably will have the high port closed,
   therefore users behind the firewalls will be unable to reach your service,
   running on the blocked port.
   
  -<P><A NAME="anchor378"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H1><A NAME="Configuring_Apache_mod_perl_wi">Configuring Apache + mod_perl with mod_macro</A></H1></CENTER>
  -<P><A NAME="anchor379"></A>
  +<P>
   mod_macro is an Apache module written by Fabien Coelho that lets you define
   and use macros in the Apache configuration file.
   
  -<P><A NAME="anchor380"></A>
  +<P>
   mod_macro can be really useful when you have many virtual hosts, and where
   each virtual host has a number of scripts/modules, most of them with a
   moderately complex configuration setup.
   
  -<P><A NAME="anchor381"></A>
  +<P>
   First download the latest version of mod_macro from <A
   HREF="http://www.cri.ensmp.fr/~coelho/mod_macro/">http://www.cri.ensmp.fr/~coelho/mod_macro/</A>
   , and configure your Apache server to use this module.
   
  -<P><A NAME="anchor382"></A>
  +<P>
   Here are some useful macros for mod_perl users:
  +
  +<P>
   
  -<P><A NAME="anchor383"></A>
  -<PRE>  # set up a registry script
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  # set up a registry script
     &lt;Macro registry&gt;
     SetHandler &quot;perl-script&quot;
     PerlHandler Apache::Registry
     Options +ExecCGI
  -  &lt;/Macro&gt;
  -</PRE>
  -<P><A NAME="anchor384"></A>
  -<PRE>  # example
  +  &lt;/Macro&gt;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  # example
     Alias /stuff /usr/www/scripts/stuff
     &lt;Location /stuff&gt;
     Use registry
  -  &lt;/Location&gt;
  -</PRE>
  -<P><A NAME="anchor385"></A>
  +  &lt;/Location&gt;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   If your registry scripts are all located in the same directory, and your
   aliasing rules consistent, you can use this macro:
  +
  +<P>
   
  -<P><A NAME="anchor386"></A>
  -<PRE>  # set up a registry script for a specific location
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  # set up a registry script for a specific location
     &lt;Macro registry $location $script&gt;
     Alias /$location /home/httpd/perl/scripts/$script
     &lt;Location /$location&gt;
  @@ -2008,18 +3387,42 @@
     PerlHandler Apache::Registry
     Options +ExecCGI
     &lt;/Location&gt;
  -  &lt;/Macro&gt;
  -</PRE>
  -<P><A NAME="anchor387"></A>
  -<PRE>  # example
  -  Use registry stuff stuff.pl
  -</PRE>
  -<P><A NAME="anchor388"></A>
  +  &lt;/Macro&gt;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  # example
  +  Use registry stuff stuff.pl</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   If you're using content handlers packaged as modules, you can use the
   following macro:
   
  -<P><A NAME="anchor389"></A>
  -<PRE>  # set up a mod_perl content handler module
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  # set up a mod_perl content handler module
     &lt;Macro modperl $module&gt;
     SetHandler &quot;perl-script&quot;
     Options +ExecCGI
  @@ -2032,13 +3435,25 @@
     PerlSetVar StatusGraph On
     PerlSetVar StatusDumper On
     Use modperl Apache::Status
  -  &lt;/Location&gt;
  -</PRE>
  -<P><A NAME="anchor390"></A>
  +  &lt;/Location&gt;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   The following macro sets up a Location for use with <CODE>HTML::Embperl</CODE>. Here we define all ``.html'' files to be processed by <CODE>Embperl</CODE>.
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor391"></A>
  -<PRE>  &lt;Macro embperl&gt;
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  &lt;Macro embperl&gt;
     SetHandler &quot;perl-script&quot;
     Options +ExecCGI
     PerlHandler HTML::Embperl
  @@ -2048,14 +3463,26 @@
     # examples
     &lt;Location /mrtg&gt;
     Use embperl
  -  &lt;/Location&gt;
  -</PRE>
  -<P><A NAME="anchor392"></A>
  +  &lt;/Location&gt;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Macros are also very useful for things that tend to be verbose, such as
   setting up Basic Authentication:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor393"></A>
  -<PRE>  # Sets up Basic Authentication
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  # Sets up Basic Authentication
     &lt;Macro BasicAuth $realm $group&gt;
     Order deny,allow
     Satisfy any
  @@ -2070,15 +3497,27 @@
     # example of use
     &lt;Location /stats&gt;
     Use BasicAuth WebStats Admin
  -  &lt;/Location&gt;
  -</PRE>
  -<P><A NAME="anchor394"></A>
  +  &lt;/Location&gt;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Finally, here is a complete example that uses macros to set up simple
   virtual hosts. It uses the BasicAuth macro defined previously (yes, macros
   can be nested!).
  +
  +<P>
   
  -<P><A NAME="anchor395"></A>
  -<PRE>  &lt;Macro vhost $ip $domain $docroot $admingroup&gt;
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  &lt;Macro vhost $ip $domain $docroot $admingroup&gt;
     &lt;VirtualHost $ip&gt;
     ServerAdmin webmaster@$domain
     DocumentRoot /usr/www/htdocs/$docroot
  @@ -2091,109 +3530,167 @@
     
     # define some virtual hosts
     Use vhost 10.1.1.1 example.com example example-admin
  -  Use vhost 10.1.1.2 example.net examplenet examplenet-admin
  -</PRE>
  -<P><A NAME="anchor396"></A>
  +  Use vhost 10.1.1.2 example.net examplenet examplenet-admin</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   mod_macro is also useful in a non vhost setting. Some sites for example
   have lots of scripts which people use to view various statistics, email
   settings and etc. It is much easier to read things like:
  +
  +<P>
   
  -<P><A NAME="anchor397"></A>
  -<PRE>  use /forwards email/showforwards
  -  use /webstats web/showstats
  -</PRE>
  -<P><A NAME="anchor398"></A>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  use /forwards email/showforwards
  +  use /webstats web/showstats</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   The actual macros for the last example are left as an exercise to reader.
   These can be easily constructed based on the examples presented in this
   section.
   
  -<P><A NAME="anchor399"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H1><A NAME="General_Pitfalls">General Pitfalls</A></H1></CENTER>
  -<P><A NAME="anchor400"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="My_CGI_Perl_Code_Gets_Returned_a">My CGI/Perl Code Gets Returned as Plain Text Instead of Being Executed by the Webserver</A></H2></CENTER>
  -<P><A NAME="anchor401"></A>
  +<P>
   Check your configuration files and make sure that the ``ExecCGI'' is turned
   on in your configurations.
   
  -<P><A NAME="anchor402"></A>
  -<PRE>  &lt;Location /perl&gt;
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  &lt;Location /perl&gt;
       SetHandler perl-script
       PerlHandler Apache::Registry
       Options ExecCGI
       allow from all
       PerlSendHeader On
  -  &lt;/Location&gt;
  -</PRE>
  -<P><A NAME="anchor403"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +  &lt;/Location&gt;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="My_Script_Works_under_mod_cgi_b">My Script Works under mod_cgi, but when Called via mod_perl I Get a 'Save-As' Prompt</A></H2></CENTER>
  -<P><A NAME="anchor404"></A>
  +<P>
   Did you put <STRONG>PerlSendHeader On</STRONG> in the configuration part of the &lt;Location foo&gt;&lt;/Location&gt;?
   
  -<P><A NAME="anchor405"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="Is_There_a_Way_to_Provide_a_Diff">Is There a Way to Provide a Different startup.pl File for Each Individual Virtual Host</A></H2></CENTER>
  -<P><A NAME="anchor406"></A>
  +<P>
   No. Any virtual host will be able to see the routines from a startup.pl
   loaded for any other virtual host.  
   
  -<P><A NAME="anchor407"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="Is_There_a_Way_to_Modify_INC_on">Is There a Way to Modify @INC on a Per-Virtual-Host or Per-Location Basis.</A></H2></CENTER>
  -<P><A NAME="anchor408"></A>
  +<P>
   You can use <CODE>PerlSetEnv PERL5LIB ...</CODE> or a <CODE>PerlFixupHandler</CODE> with the <CODE>lib</CODE> pragma (<CODE>use lib qw(...)</CODE>).
   
  -<P><A NAME="anchor409"></A>
  +<P>
   A better way is to use
   <A HREF="././modules.html#Apache_PerlVINC_set_a_differe">Apache::PerlVINC</A>
   
   
   
  -<P><A NAME="anchor410"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="A_Script_From_One_Virtual_Host_C">A Script From One Virtual Host Calls a Script with the Same Path From the Other Virtual Host</A></H2></CENTER>
  -<P><A NAME="anchor411"></A>
  +<P>
   This has been a bug before, last fixed in 1.15_01, i.e. if you are running
   1.15, that could be the problem. You should set this variable in a startup
   file (which you load with <CODE>PerlRequire</CODE> in <EM>httpd.conf</EM>):
  +
  +<P>
   
  -<P><A NAME="anchor412"></A>
  -<PRE>  $Apache::Registry::NameWithVirtualHost = 1;
  -</PRE>
  -<P><A NAME="anchor413"></A>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  $Apache::Registry::NameWithVirtualHost = 1;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   But, as we know sometimes a bug turns out to be a feature. If the same
   script is running for more than one Virtual host on the same machine, this
   can be a waste, right? Set it to 0 in a startup script if you want to turn
   it off and have this bug as a feature. (Only makes sense if you are sure
   that there will be no <EM>other</EM> scripts with the same path/name). It also saves you some memory as well.
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor414"></A>
  -<PRE>  $Apache::Registry::NameWithVirtualHost = 0;
  -</PRE>
  -<P><A NAME="anchor415"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  $Apache::Registry::NameWithVirtualHost = 0;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="the_Server_no_Longer_Retrieves_t">the Server no Longer Retrieves the DirectoryIndex Files for a Directory</A></H2></CENTER>
  -<P><A NAME="anchor416"></A>
  +<P>
   The problem was reported by users who declared mod_perl configuration
   inside a &lt;Directory&gt; section for all files matching *.pl. The problem went away
   after placing the directives in a <CODE>&lt;Files&gt;</CODE> section.
   
  -<P><A NAME="anchor417"></A>
  +<P>
   The mod_alias and mod_rewrite are both Trans handlers in the normal case.
   So in the setup where both are used, if mod_alias runs first and matches it
   will return OK and mod_rewrite won't see the request.
   
  -<P><A NAME="anchor418"></A>
  +<P>
   The opposite can happen as well, where mod_rewrite rules apply but the
   <CODE>Alias</CODE> directives are completely ignored.
   
  -<P><A NAME="anchor419"></A>
  +<P>
   The behavior is not random, but depends on the Apache modules loading
   order. Apache modules are being executed in <EM>reverse</EM> order, i.e. module that was <EM>Added</EM> first will be executed last.
   
  -<P><A NAME="anchor420"></A>
  +<P>
   The solution is not to mix mod_rewrite and mod_alias. mod_rewrite does
   everything mod_alias does--except for <CODE>ScriptAlias</CODE> which is not really relevant to mod_perl anyway. Don't rely on the module
   ordering, but use explicitely disjoint URL namespaces for Alias and
  @@ -2201,13 +3698,22 @@
   rule should not be used in an Alias, and vice versa. Given that mod_rewrite
   can easily do what mod_alias does, it's no problem
   
  -<P><A NAME="anchor421"></A>
  +<P>
   Here is one of the exmaples where <CODE>Alias</CODE> is replaced with
   <CODE>RedirectMatch</CODE>. This is a snippet of configuration at the light non-mod_perl Apache
   server:
  +
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
   
  -<P><A NAME="anchor422"></A>
  -<PRE>  RewriteEngine     on
  +	<td>
  +	  <pre>  RewriteEngine     on
     RewriteLogLevel   0
     RewriteRule       ^/(perl.*)$    <A HREF="http://127.0.0.1:8045/">http://127.0.0.1:8045/</A>$1  [P,L]
     RewriteRule       ^/(mail.*)$    <A HREF="http://127.0.0.1:8045/">http://127.0.0.1:8045/</A>$1  [P,L]
  @@ -2217,34 +3723,58 @@
     ProxyPassReverse  / <A HREF="http://www.example.com/">http://www.example.com/</A>
     
     RedirectMatch permanent ^/$      /pages/index
  -  RedirectMatch permanent ^/foo$   /pages/bar
  -</PRE>
  -<P><A NAME="anchor423"></A>
  +  RedirectMatch permanent ^/foo$   /pages/bar</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   This configuration works fine because any URI that matches one of the
   redirects will never match one of the rewrite rules.
   
  -<P><A NAME="anchor424"></A>
  +<P>
   In the above setup we proxy requests starting with <EM>/perl</EM> or
   <EM>/mail</EM> to the mod_perl server, forbid proxy requests to the external sites, and
   make sure that the proxied requests will use the <A
   HREF="http://www.example.com/">http://www.example.com/</A> as their URL on
   the way back to the client.
   
  -<P><A NAME="anchor425"></A>
  +<P>
   The <CODE>RedirectMatch</CODE> settings work exactly like if you'd write:
   
  -<P><A NAME="anchor426"></A>
  -<PRE>  Alias /      /pages/index
  -  Alias /foo   /pages/bar
  -</PRE>
  -<P><A NAME="anchor427"></A>
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  Alias /      /pages/index
  +  Alias /foo   /pages/bar</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   But as we told before we don't want to mix the two.
   
  -<P><A NAME="anchor428"></A>
  +<P>
   Here is another example where the redirect is done by a rewrite rule:
  +
  +<P>
   
  -<P><A NAME="anchor429"></A>
  -<PRE>  RewriteEngine     on
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  RewriteEngine     on
     RewriteLogLevel   0
     RewriteMap        lowercase int:tolower
     RewriteRule       ^/(perl.*)$  <A HREF="http://127.0.0.1:8042/">http://127.0.0.1:8042/</A>$1   [P,L]
  @@ -2253,61 +3783,74 @@
     RewriteRule       ^(.*)$        ${lowercase:$1}
     ProxyRequests     on
     NoCache           *
  -  ProxyPassReverse  /  <A HREF="http://www.example.com/">http://www.example.com/</A>
  -</PRE>
  -<P><A NAME="anchor430"></A>
  +  ProxyPassReverse  /  <A HREF="http://www.example.com/">http://www.example.com/</A></pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   If we ommit the rewrite rule that matches <CODE>^/$</CODE>, and instead use a redirect, it will never be called, because the URL is
   still matched by the last rule <CODE>^(.*)$</CODE>. This is a somewhat contrived example because that last regex could be
   rewritten as <CODE>^(/.+)$</CODE> and all would be well.
   
  -<P><A NAME="anchor431"></A>
  +<P>
   It's very important to stress the line that ends with <CODE>[F]</CODE>, which prevents people from unduly using your proxy server. This is a
   security issue.
   
  -<P><A NAME="anchor432"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H1><A NAME="Configuration_Security_Concerns">Configuration Security Concerns</A></H1></CENTER>
  -<P><A NAME="anchor433"></A>
  +<P>
   It is better not to advertise the port that mod_perl server uses to the
   outside world, for it creates a potential security risk by revealing which
   <CODE>module(s)</CODE> and/or OS you are running your web server on.
   
  -<P><A NAME="anchor434"></A>
  +<P>
   For more information see <A HREF="././config.html#Publishing_Port_Numbers_other_th">Publishing Port Numbers other than 80</A>.
   
  -<P><A NAME="anchor435"></A>
  +<P>
   The more modules you have in your web server, the more complex the code.
   
  -<P><A NAME="anchor436"></A>
  +<P>
   The more complex the code in your web server, the more chances for bugs.
   
  -<P><A NAME="anchor437"></A>
  +<P>
   The more chances for bugs, the more chance that some of those bugs may
   involve security.
   
  -<P><A NAME="anchor438"></A>
  +<P>
   We never were completely sure why the default of the <CODE>ServerToken</CODE>
   directive in Apache is <CODE>Full</CODE> rather than <CODE>Minimal</CODE>. Seems like you would only make it <CODE>Full</CODE> if you are debugging. Probably the reason for using the <CODE>ServerToken Full</CODE> is for a show-off, so NetCraft (http://netcraft.com) and other similar
   survey services will count more Apache servers, which is good for all of
   us, but you really want to reveal as little information as possible to the
   potential crackers.
   
  -<P><A NAME="anchor439"></A>
  +<P>
   Another approach is to modify httpd sources to reveal no unwanted
   information, so all responses will return an empty or phony <CODE>Server:</CODE>
   field.
   
  -<P><A NAME="anchor440"></A>
  +<P>
   From the other point of view, security by obscurity is a lack of security.
   Any determined cracker will eventually figure out what version of Apache
   run and what third party modules you have built in.
   
  -<P><A NAME="anchor441"></A>
  +<P>
   You can see what information is revealed by your server, by telneting to it
   and issuing some request. For example:
  +
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
   
  -<P><A NAME="anchor442"></A>
  -<PRE>  % telnet localhost 8080
  +	<td>
  +	  <pre>  % telnet localhost 8080
     Trying 127.0.0.1
     Connected to localhost
     Escape character is '^]'.
  @@ -2316,68 +3859,95 @@
     HTTP/1.1 200 OK
     Date: Sun, 16 Apr 2000 11:06:25 GMT
     Server: Apache/1.3.12 (Unix) mod_perl/1.22 mod_ssl/2.6.2 OpenSSL/0.9.5
  -  [more lines snipped]
  -</PRE>
  -<P><A NAME="anchor443"></A>
  +  [more lines snipped]</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   So as you see that a lot of information is revealed and a <CODE>Full</CODE>
   
   <CODE>ServerToken</CODE> has been used.
   
  -<P><A NAME="anchor444"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H1><A NAME="Apache_Restarts_Twice_On_Start">Apache Restarts Twice On Start</A></H1></CENTER>
  -<P><A NAME="anchor445"></A>
  +<P>
   When the server is restarted, the configuration and module initialization
   phases are called twice in total before the children are forked. The second
   restart is done in order to ensure that future restarts will work
   correctly, by making sure that all modules can survive a restart (<CODE>SIGHUP</CODE>). This is very important if you restart a production server.
   
  -<P><A NAME="anchor446"></A>
  +<P>
   You can control what code will be executed on the start or restart by
   checking the value of <CODE>$Apache::Server::Starting</CODE> and
   <CODE>$Apache::Server::ReStarting</CODE> respectively. The former variable is
   <EM>true</EM> when the server is starting and the latter is <EM>true</EM> when it's restarting.
   
  -<P><A NAME="anchor447"></A>
  +<P>
   For example:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor448"></A>
  -<PRE>  &lt;Perl&gt;
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  &lt;Perl&gt;
     print STDERR &quot;Server is Startingn\n&quot;  if $Apache::Server::Starting;
     print STDERR &quot;Server is ReStarting\n&quot; if $Apache::Server::ReStarting;
  -  &lt;/Perl&gt;
  -</PRE>
  -<P><A NAME="anchor449"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +  &lt;/Perl&gt;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H1><A NAME="Knowing_the_proxy_pass_ed_Connec">Knowing the proxy_pass'ed Connection Type</A></H1></CENTER>
  -<P><A NAME="anchor450"></A>
  +<P>
   Let's say that you have a frontend server running mod_ssl, mod_rewrite and
   mod_proxy. You want to make sure that your user is using a secure
   connection for some specific actions like login information submission. You
   don't want to let the user login unless the request was submitted through a
   secure port.
   
  -<P><A NAME="anchor451"></A>
  +<P>
   Since you have to proxy_pass the request between front and backend servers,
   you cannot know where the connection has come from. Neither is using the
   HTTP headers reliable.
   
  -<P><A NAME="anchor452"></A>
  +<P>
   A possible solution for this problem is to have the the mod_perl server
   listen on two different ports (e.g. 8000 and 8001) and have the mod_rewrite
   proxy rule in the regular server redirect to port 8000 and the mod_rewrite
   proxy rule in the SSL virtual host redirect to port 8001. In the mod_perl
   server just check the <CODE>PORT</CODE> variable to tell if the connection is secure.
   
  -<P><A NAME="anchor453"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H1><A NAME="Adding_Custom_Configuration_Dire">Adding Custom Configuration Directives</A></H1></CENTER>
  -<P><A NAME="anchor454"></A>
  +<P>
   This is covered in the Eagle Book in a great detail. This is just a simple
   example, showing how to add your own Configuration directives.
   
  -<P><A NAME="anchor455"></A>
  -<PRE>  Makefile.PL
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  Makefile.PL
     -----------
     package Apache::TestDirective;
     
  @@ -2400,10 +3970,22 @@
       'NAME'      =&gt; 'Apache::TestDirective',
       'VERSION_FROM' =&gt; 'TestDirective.pm',
       'INC'       =&gt; Apache::src-&gt;new-&gt;inc,
  -  );
  -</PRE>
  -<P><A NAME="anchor456"></A>
  -<PRE>  TestDirective.pm
  +  );</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  TestDirective.pm
     ----------------
     package Apache::TestDirective;
     
  @@ -2423,105 +4005,206 @@
     }
     
     1;
  -  __END__
  -</PRE>
  -<P><A NAME="anchor457"></A>
  +  __END__</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   In the mod_perl source tree, add this to <EM>t/docs/startup.pl</EM>:
  +
  +<P>
   
  -<P><A NAME="anchor458"></A>
  -<PRE>  use blib qw(/home/dougm/test/Apache/TestDirective);
  -</PRE>
  -<P><A NAME="anchor459"></A>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  use blib qw(/home/dougm/test/Apache/TestDirective);</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   and at the bottom of <EM>t/conf/httpd.conf</EM>:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor460"></A>
  -<PRE>  PerlModule Apache::TestDirective
  -  Directive4 hi
  -</PRE>
  -<P><A NAME="anchor461"></A>
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  PerlModule Apache::TestDirective
  +  Directive4 hi</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Test it:
   
  -<P><A NAME="anchor462"></A>
  -<PRE>  % make start_httpd
  -  % make kill_httpd
  -</PRE>
  -<P><A NAME="anchor463"></A>
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  % make start_httpd
  +  % make kill_httpd</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   You should see:
  +
  +<P>
   
  -<P><A NAME="anchor464"></A>
  -<PRE>  Directive4 Apache::TestDirective=HASH(0x83379d0)
  -  Apache::CmdParms=SCALAR(0x862b80c) hi
  -</PRE>
  -<P><A NAME="anchor465"></A>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  Directive4 Apache::TestDirective=HASH(0x83379d0)
  +  Apache::CmdParms=SCALAR(0x862b80c) hi</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   And in the error log file:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor466"></A>
  -<PRE>  % grep Directive4 t/logs/error_log 
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  % grep Directive4 t/logs/error_log 
     Directive4 Apache::TestDirective=HASH(0x83119dc)
  -  Apache::CmdParms=SCALAR(0x8326878) hi
  -</PRE>
  -<P><A NAME="anchor467"></A>
  +  Apache::CmdParms=SCALAR(0x8326878) hi</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   If it didn't work as expected try building mod_perl with PERL_TRACE=1, then
   do:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor468"></A>
  -<PRE>  setenv MOD_PERL_TRACE all
  -</PRE>
  -<P><A NAME="anchor469"></A>
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  setenv MOD_PERL_TRACE all</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   before starting the server. Now you should get some useful diagnostics.
   
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -	     The <a href="http://www.modperl.com/">
  -	     <B>Writing Apache Modules with Perl and C</B></a>
  -	     book can be purchased online from <a
  -	     href="http://www.ora.com/catalog/wrapmod/">O'Reilly </a>
  -	     and <a
  -	     href="http://www.amazon.com/exec/obidos/ASIN/156592567X/writinapachemodu">
  -	     Amazon.com</a>.
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   
  -	     <HR>
   
  -	     <B>Your corrections of either technical or grammatical
  +    <p>
  +    <div class="navbar">
  +      <a href="install.html">Prev</a>                                 |
  +      <A HREF="index.html"         >Contents</A> |
  +      <A HREF="index.html#search"  >Search</A>   |
  +      <A HREF="index.html#download">Download</A> |
  +      <a href="control.html">Next</a>
  +    </div>
  +    <p>
  +
  +    <table width="60%" align="center">
  +
  +      <tr>
  +	<td>
  +	  <div class="notice">
  +	  <B>Your corrections of the technical and grammatical
   	     errors are very welcome. You are encouraged to help me
  -	     to improve this guide.  If you have something to
  -	     contribute please <A
  -	     HREF="help.html#Contacting_me"> send it
  +	     improve this guide.  If you have something to contribute
  +	     please <A HREF="help.html#Contacting_me"> send it
   	     directly to me</A>.</B>
  +	  </div>
  +	</td>
  +      </tr>
  +
  +      <tr>
  +	<td>
  +	  <div class="ad">
  +	    The <a href="http://www.modperl.com/">
  +	      <B>Writing Apache Modules with Perl and C</B></a>
  +	    book can be purchased online from <a
  +	      href="http://www.ora.com/catalog/wrapmod/">O'Reilly </a>
  +	    and <a
  +	    href="http://www.amazon.com/exec/obidos/ASIN/156592567X/writinapachemodu">
  +	      Amazon.com</a>.
  +	  </div>
  +	</td>
  +      </tr>
  +
  +</table>
  +
  +<center>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
  +<table cellspacing=2 cellpadding=2>
  +
  +<tr align=center valign=top>
  +<td align=center valign=center>
  +
  +<b><font size=-1>Written by <a
  +href="help.html#Contacting_me">Stas Bekman</a>.<br> Last Modified at 06/07/2000
  +</font></b>
  +<br>
  +
  +</td>
  +
  +<td>
  +
  +<a href="http://perl.apache.org"><img src="images/mod_perl2.jpg"  border=0 alt="mod_perl icon" border=0 height=59 width=150></a>
  +<br>
  +
  +</td>
  +
  +<td>
  +
  +<font size=-2>Use of the Camel for Perl is <br>
  +a trademark of <a href="http://www.ora.com">O'Reilly &amp; Associates</a>,<br>
  +and is used by permission. </font> 
  +<br>
   
  -	     <HR>
  +</td>
   
  -	     [    <A HREF="install.html">Prev</A> |      <A HREF="index.html">Main Page</A> | <A HREF="control.html">Next</A>      ]
  +</tr>
  +</table>
  +</center>
   
  -<CENTER><TABLE CELLSPACING=2 CELLPADDING=2 WIDTH="100%" >
  -<TR ALIGN=CENTER VALIGN=TOP>
  -  <TD ALIGN=CENTER VALIGN=CENTER COLSPAN="3">
  -	     <HR>
  -  </TD>
  -</TR>
  -<TR ALIGN=CENTER VALIGN=TOP>
  -  <TD ALIGN=CENTER VALIGN=CENTER>
  -    <B>
  -      <FONT SIZE=-1>
  -	     Written by <A HREF="help.html#Contacting_me">Stas Bekman</A>.
  -	     <BR>Last Modified at 05/13/2000
  -      </FONT>
  -    </B>
  -  </TD>
  -
  -  <TD>
  -	     <A HREF="http://perl.apache.org"><IMG SRC="images/mod_perl2.jpg" ALT="Mod Perl Icon" BORDER=0 HEIGHT=59 WIDTH=150></A>
  -  </TD>
  -
  -  <TD>
  -    <FONT SIZE=-2>
  -	     Use of the Camel for Perl is <BR>
  -	     a trademark of <A HREF="http://www.ora.com">O'Reilly &amp; Associates</A>,<BR>
  -             and is used by permission. 
  -    </FONT> 
  -  </TD>
  -</TR>
  -</TABLE></CENTER>
  -
  -</BODY>
  -</HTML>
  -	    
  \ No newline at end of file
  +</body>
  +</html>
  
  
  
  1.26      +1768 -738 modperl-site/guide/control.html
  
  Index: control.html
  ===================================================================
  RCS file: /home/cvs/modperl-site/guide/control.html,v
  retrieving revision 1.25
  retrieving revision 1.26
  diff -u -r1.25 -r1.26
  --- control.html	2000/05/12 22:42:50	1.25
  +++ control.html	2000/06/07 22:45:30	1.26
  @@ -1,132 +1,225 @@
   <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
  -<HTML>
  -<HEAD>
  -   <TITLE>mod_perl guide: Controlling and Monitoring the Server</TITLE>
  -   <META NAME="GENERATOR" CONTENT="Pod2HTML [Perl/Linux]">
  -   <META NAME="Author" CONTENT="Stas Bekman">
  -   <META NAME="Description" CONTENT="All Apache/Perl related information: Hints, Guidelines, Scenarios and Troubleshottings">
  -   <META NAME="keywords" CONTENT="mod_perl modperl perl apache cgi webserver speed  fast guide mod_perl apache guide help info faq mod_perl installation cgi troubleshooting help no sex speedup free open source OSS mod_perl apache guide">
  -</HEAD>
  -     <LINK REL=STYLESHEET TYPE="text/css"
  -        HREF="style.css" TITLE="refstyle">
  -     <style type="text/css">
  -     <!-- 
  -        @import url(style.css);
  -     -->
  -     
  -     </style>
  -<BODY BGCOLOR="white">
  +<html>
  +  <head>
  +   <title>mod_perl guide: Controlling and Monitoring the Server</title>
  +   <meta name="Author" content="Stas Bekman">
  +   <meta name="Description" content="All Apache/Perl related information: Hints, Guidelines, Scenarios and Troubleshottings">
  +   <meta name="keywords" content="mod_perl modperl perl cgi apache webserver speed fast guide mod_perl apache guide help info faq mod_perl installation cgi troubleshooting help no sex speedup free open source OSS mod_perl apache guide">
  +   <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
  +   <meta name="Classification" content="information">
  +   <link href="style.css" rel=stylesheet type="text/css" title="refstyle">
  +  </head>
  +  <body>
  +
  +    <h1 align=center>
  +      <a href="http://perl.apache.org"><img src="images/mod_perl.gif" alt="Mod Perl Icon" border=0 height=30 width=90 align=left></a>
  +      <a href="http://perl.apache.org"><img src="images/mod_perl.gif" alt="Mod Perl Icon" border=0 height=30 width=90 align=right></a>
  +      Controlling and Monitoring the Server
  +    </h1>
  +    <hr>
  +    <p>
  +    <div class="navbar">
  +      <a href="config.html">Prev</a>                                 |
  +      <a href="index.html"         >Contents</a> |
  +      <a href="index.html#search"  >Search</a>   |
  +      <a href="index.html#download">Download</a> |
  +      <a href="strategy.html">Next</a>
  +    </div>
  +    <p>
  +
  +    <div class="toc">
  +      
   <A NAME="toc"></A>
  -<H1 ALIGN=CENTER>
  -<A HREF="http://perl.apache.org"><IMG SRC="images/mod_perl.gif" ALT="Mod Perl Icon" BORDER=0 HEIGHT=30 WIDTH=90 ALIGN=LEFT></A>
  -<A HREF="http://perl.apache.org"><IMG SRC="images/mod_perl.gif" ALT="Mod Perl Icon" BORDER=0 HEIGHT=30 WIDTH=90 ALIGN=RIGHT></A>
  -Controlling and Monitoring the Server</H1>
  -<HR WIDTH="100%">
  -	    [    <A HREF="config.html">Prev</A> |      <A HREF="index.html">Main Page</A> | <A HREF="strategy.html">Next</A>      ]<HR><!-- INDEX BEGIN -->
  -<P><B><FONT SIZE=-1>Table of Contents:</FONT></B></P>
  +<P><B>Table of Contents:</B></P>
  +
   <UL>
   
  -	<LI><A HREF="#Restarting_techniques">Restarting techniques</A>
  +	<LI><A HREF="#Restarting_Techniques">Restarting Techniques</A>
   	<LI><A HREF="#Server_Stopping_and_Restarting">Server Stopping and Restarting </A>
  -	<LI><A HREF="#Using_apachectl_to_control_the_s">Using apachectl to control the server</A>
  +	<LI><A HREF="#Speeding_up_the_Apache_Terminati">Speeding up the Apache Termination and Restart</A>
  +	<LI><A HREF="#Using_apachectl_to_Control_the_S">Using apachectl to Control the Server</A>
   	<LI><A HREF="#Safe_Code_Updates_on_a_Live_Prod">Safe Code Updates on a Live Production Server</A>
   	<LI><A HREF="#An_Intentional_Disabling_of_Live">An Intentional Disabling of Live Scripts</A>
   	<LI><A HREF="#SUID_Start_up_Scripts">SUID Start-up Scripts</A>
  +	<UL>
  +
  +		<LI><A HREF="#Introduction_to_SUID_Executables">Introduction to SUID Executables</A>
  +		<LI><A HREF="#Apache_Startup_SUID_Script_s_Sec">Apache Startup SUID Script's Security</A>
  +		<LI><A HREF="#Sample_Apache_Startup_SUID_Scrip">Sample Apache Startup SUID Script</A>
  +	</UL>
  +
   	<LI><A HREF="#Preparing_for_Machine_Reboot">Preparing for Machine Reboot</A>
   	<LI><A HREF="#Monitoring_the_Server_A_watchdo">Monitoring the Server.  A watchdog.</A>
   	<LI><A HREF="#Running_a_Server_in_Single_Proce">Running a Server in Single Process Mode</A>
   	<LI><A HREF="#Starting_a_Personal_Server_for_E">Starting a Personal Server for Each Developer</A>
  -	<LI><A HREF="#Wrapper_to_Emulate_the_Server_En">Wrapper to Emulate the Server Environment</A>
  -	<LI><A HREF="#Log_Rotation">Log Rotation</A>
  +	<LI><A HREF="#Wrapper_to_Emulate_the_Server_Pe">Wrapper to Emulate the Server Perl Environment</A>
  +	<LI><A HREF="#Server_Maintenance_Chores">Server Maintenance Chores</A>
  +	<UL>
  +
  +		<LI><A HREF="#Handling_Log_Files">Handling Log Files</A>
  +		<UL>
  +
  +			<LI><A HREF="#Log_Rotation">Log Rotation</A>
  +			<LI><A HREF="#Non_Scheduled_Emergency_Log_Rota">Non-Scheduled Emergency Log Rotation</A>
  +		</UL>
  +
  +	</UL>
  +
   	<LI><A HREF="#Preventing_mod_perl_Processes_Fr">Preventing mod_perl Processes From Going Wild</A>
   	<UL>
   
   		<LI><A HREF="#All_RAM_Consumed">All RAM Consumed </A>
  -		<LI><A HREF="#All_Disk_Space_Consumed">All Disk Space Consumed </A>
   	</UL>
   
   </UL>
  -<!-- INDEX END -->
   
  +    </div>
  +
  +    [ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
   <HR>
  +    <table width="60%" align="center">
  +
  +      <tr>
  +	<td>
  +	  <div class="ad">
  +	    The <a href="http://www.modperl.com/">
  +	      <B>Writing Apache Modules with Perl and C</B></a>
  +	    book can be purchased online from <a
  +	      href="http://www.ora.com/catalog/wrapmod/">O'Reilly </a>
  +	    and <a
  +	    href="http://www.amazon.com/exec/obidos/ASIN/156592567X/writinapachemodu">
  +	      Amazon.com</a>.
  +	  </div>
  +	</td>
  +      </tr>
  +
  +      <tr>
  +	<td>
  +	  <div class="notice">
  +	  <B>Your corrections of the technical and grammatical
  +	     errors are very welcome. You are encouraged to help me
  +	     improve this guide.  If you have something to contribute
  +	     please <A HREF="help.html#Contacting_me"> send it
  +	     directly to me</A>.</B>
  +	  </div>
  +	</td>
  +      </tr>
  +
  +</table>
  +
  +    
   
  -	     The <a href="http://www.modperl.com/">
  -	     <B>Writing Apache Modules with Perl and C</B></a>
  -	     book can be purchased online from <a
  -	     href="http://www.ora.com/catalog/wrapmod/">O'Reilly </a>
  -	     and <a
  -	     href="http://www.amazon.com/exec/obidos/ASIN/156592567X/writinapachemodu">
  -	     Amazon.com</a>.
  -
  -	     <HR>
  -
  -	       <B>Your corrections of either technical or grammatical
  -	       errors are very welcome. You are encouraged to help me
  -	       to improve this guide.  If you have something to
  -	       contribute please <A
  -	       HREF="help.html#Contacting_me"> send it
  -	       directly to me</A>.
  -	       </B>
  -	       <HR>
  -
  -	      <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<P><A NAME="anchor0"></A>
  -<CENTER><H1><A NAME="Restarting_techniques">Restarting techniques</A></H1></CENTER>
  -<P><A NAME="anchor1"></A>
  -All of these techniques require that you know the server PID (Process ID).
  +	    [ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
  +
  +<P>
  +<CENTER><H1><A NAME="Restarting_Techniques">Restarting Techniques</A></H1></CENTER>
  +<P>
  +All of these techniques require that you know the server process id (PID).
   The easiest way to find the PID is to look it up in the
  -<CODE>httpd.pid</CODE> file. It's easy to discover where to look, by looking in the <EM>httpd.conf</EM> file. Open the file and locate the entry
  +<EM>httpd.pid</EM> file. It's easy to discover where to look, by looking in the <EM>httpd.conf</EM> file. Open the file and locate the entry
   <CODE>PidFile</CODE>. Here is the line from one of my own <EM>httpd.conf</EM> files:
  +
  +<P>
   
  -<P><A NAME="anchor2"></A>
  -<PRE>  PidFile /usr/local/var/httpd_perl/run/httpd.pid
  -</PRE>
  -<P><A NAME="anchor3"></A>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  PidFile /usr/local/var/httpd_perl/run/httpd.pid</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   As you see, with my configuration the file is
  -<CODE>/usr/local/var/httpd_perl/run/httpd.pid</CODE>.
  +<EM>/usr/local/var/httpd_perl/run/httpd.pid</EM>.
   
  -<P><A NAME="anchor4"></A>
  +<P>
   Another way is to use the <CODE>ps</CODE> and <CODE>grep</CODE> utilities. Assuming that the binary is called <EM>httpd_perl</EM>, we would do:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor5"></A>
  -<PRE>  % ps auxc | grep httpd_perl
  -</PRE>
  -<P><A NAME="anchor6"></A>
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  % ps auxc | grep httpd_perl</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   or maybe:
   
  -<P><A NAME="anchor7"></A>
  -<PRE>  % ps -ef | grep httpd_perl
  -</PRE>
  -<P><A NAME="anchor8"></A>
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  % ps -ef | grep httpd_perl</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   This will produce a list of all the <CODE>httpd_perl</CODE> (parent and children) processes. You are looking for the parent process. If
   you run your server as root, you will easily locate it since it belongs to
  -root. If you run the server as some other user (when you <A HREF="././install.html#Installation_Without_Superuser_P">don't have root access</A>, the processes will belong to that user unless defined differently in <EM>httpd.conf</EM>. It's still easy to find which is the parent--it's the smallest one.
  +root. If you run the server as some other user (when you <A HREF="././install.html#Installation_Without_Superuser_P">don't have root access</A>, the processes will belong to that user unless defined differently in <EM>httpd.conf</EM>. It's still easy to find which is the parent--usually it's the process
  +with the smallest PID.
   
  -<P><A NAME="anchor9"></A>
  +<P>
   You will see many <CODE>httpd</CODE> executables running on your system, but you should never need to send
   signals to any of them except the parent, whose pid is in the <EM>PidFile</EM>. There are three signals that you can send to the parent: <CODE>SIGTERM</CODE>, <CODE>SIGHUP</CODE>, and <CODE>SIGUSR1</CODE>.
   
  -<P><A NAME="anchor10"></A>
  +<P>
   Some folks prefer to specify signals using numerical values, rather than
   using symbols. If you are looking for these, check out your
  -<CODE>kill(1)</CODE> man page. My page points to <CODE>/usr/include/sys/signal.h</CODE>, the relevant entries are:
  +<CODE>kill(1)</CODE> man page. My page points to
  +<EM>/usr/include/linux/signal.h</EM>, the relevant entries are:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor11"></A>
  -<PRE>  #define SIGHUP     1    /* hangup, generated when terminal disconnects */ 
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  #define SIGHUP     1    /* hangup, generated when terminal disconnects */ 
     #define SIGKILL    9    /* last resort */
     #define SIGTERM   15    /* software termination signal */
  -  #define SIGUSR1   30    /* user defined signal 1 */
  -</PRE>
  -<P><A NAME="anchor12"></A>
  +  #define SIGUSR1   30    /* user defined signal 1 */</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Note that to send these signals from the command line the <CODE>SIG</CODE> prefix must be omitted and under some operating systems they will need to
   be preceeded by a minus sign, e.g. <CODE>kill -15</CODE> or <CODE>kill -TERM</CODE> followed by the PID.
   
  -<P><A NAME="anchor13"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H1><A NAME="Server_Stopping_and_Restarting">Server Stopping and Restarting</A></H1></CENTER>
  -<P><A NAME="anchor14"></A>
  +<P>
   We will concentrate here on the implications of sending <A HREF="#item_TERM">TERM</A>,
  -<A HREF="#item_HUP">HUP</A>, and <A HREF="#item_USR1">USR1</A> signals (as an arguments to <CODE>kill(1))</CODE> to a mod_perl enabled
  +<A HREF="#item_HUP">HUP</A>, and <A HREF="#item_USR1">USR1</A> signals (as arguments to <CODE>kill(1))</CODE> to a mod_perl enabled
   server. See <A
   HREF="http://www.apache.org/docs/stopping.html">http://www.apache.org/docs/stopping.html</A>
   for documentation on the implications of sending these signals to a plain
  @@ -134,36 +227,37 @@
   
   <DL>
   <P><DT><STRONG><A NAME="item_TERM">TERM Signal: Stop Now</A></STRONG><DD>
  -<P><A NAME="anchor15"></A>
  +<P>
   Sending the <A HREF="#item_TERM">TERM</A> signal to the parent causes it to immediately attempt to kill off all its
   children. Any requests in progress are terminated, and no further requests
   are served. This process may take quite a few seconds to complete. To stop
   a child, the parent sends it a <CODE>SIGHUP</CODE> signal. If that fails it sends another. If that fails it sends the <CODE>SIGTERM</CODE> signal, and as a last resort it sends the
   <CODE>SIGKILL</CODE> signal. For each failed attempt to kill a child it makes an entry in the <EM>error_log</EM>.
   
  -<P><A NAME="anchor16"></A>
  -Finally the parent itself exits and any open log files are closed. This is
  -when all the accumulated <CODE>END</CODE> blocks, apart from the ones in
  -<CODE>Apache::Registry</CODE> and <CODE>Apache::PerlRun</CODE> scripts, will be executed. <CODE>END</CODE> blocks are executed after each request is served for
  -<CODE>Apache::Registry</CODE> and <CODE>Apache::PerlRun</CODE> scripts.
  -
  -<P><DT><STRONG><A NAME="item_HUP">HUP Signal: restart now</A></STRONG><DD>
  -<P><A NAME="anchor17"></A>
  -Sending the <STRONG>HUP</STRONG> signal to the parent causes it to kill off its children as if you had sent <STRONG>TERM</STRONG> (any requests in progress are terminated) but the parent doesn't exit.
  -
  -<P><A NAME="anchor18"></A>
  -The parent will reread its configuration files, close and re-open any log
  -files, flush all the compiled and preloaded modules, and rerun any startup
  -files. Then it spawns a new set of children and continues serving hits.
  -It's equivalent to stopping then restarting the server.
  -
  -<P><A NAME="anchor19"></A>
  -Note: If your configuration files have errors when you issue a restart then
  -the parent will not restart but instead it will exit with an error and your
  -sever will be stopped. See below for how to avoid this.
  +<P>
  +When all the child processes were terminated, the parent itself exits and
  +any open log files are closed. This is when all the accumulated
  +<CODE>END</CODE> blocks, apart from the ones located in scripts running under
  +<CODE>Apache::Registry</CODE> or <CODE>Apache::PerlRun</CODE> handlers. In the latter case, <CODE>END</CODE> blocks are executed after each request is served.
  +
  +<P><DT><STRONG><A NAME="item_HUP">HUP Signal: Restart Now</A></STRONG><DD>
  +<P>
  +Sending the <A HREF="#item_HUP">HUP</A> signal to the parent causes it to kill off its children as if you had sent <A HREF="#item_TERM">TERM</A> (any requests in progress are terminated) but the parent doesn't exit.
  +
  +<P>
  +Instead the parent will reread its configuration files, close and re-open
  +its log files, flush all the compiled and preloaded modules, and rerun
  +startup files. Then it spawns a new set of children and continues serving
  +requests. It's equivalent to stopping and then restarting the server.
  +
  +<P>
  +Notice that if your configuration files have errors when you issue a
  +restart, then the parent will exit. Therefore you should check the
  +configuration files for errors, before issuing the restart. We will present
  +a technique for performing this check in a moment.
   
  -<P><DT><STRONG><A NAME="item_USR1">USR1 Signal: graceful restart</A></STRONG><DD>
  -<P><A NAME="anchor20"></A>
  +<P><DT><STRONG><A NAME="item_USR1">USR1 Signal: Gracefully Restart Now</A></STRONG><DD>
  +<P>
   The <A HREF="#item_USR1">USR1</A> signal causes the parent process to advise the children to exit after
   serving their current requests, or to exit immediately if they're not
   serving a request. The parent re-reads its configuration files and re-opens
  @@ -171,253 +265,485 @@
   from the new generation (the new children use the new configuration) and it
   begins serving new requests immediately.
   
  -<P><A NAME="anchor21"></A>
  +<P>
   The only difference between <A HREF="#item_USR1">USR1</A> and <A HREF="#item_HUP">HUP</A> is that <A HREF="#item_USR1">USR1</A> allows the children to complete any current requests prior to killing them
   off and there is no interruption in the services compared to the killing
   with <A HREF="#item_HUP">HUP</A> signal, where it might take a few seconds for a restart to get completed
   and there is no real service at this time.
   
   </DL>
  -<P><A NAME="anchor22"></A>
  +<P>
   By default, if a server is restarted (using <CODE>kill -USR1 `cat
   logs/httpd.pid`</CODE> or with the <A HREF="#item_HUP">HUP</A> signal), Perl scripts and modules are not reloaded. To reload <CODE>PerlRequire</CODE>'s, <CODE>PerlModule</CODE>'s, other
   <CODE>use()</CODE>'d modules and flush the <CODE>Apache::Registry</CODE> cache, use this directive in <EM>httpd.conf</EM>:
  +
  +<P>
   
  -<P><A NAME="anchor23"></A>
  -<PRE>  PerlFreshRestart On
  -</PRE>
  -<P><A NAME="anchor24"></A>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  PerlFreshRestart On</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Make sure you read <A HREF="././troubleshooting.html#Evil_things_might_happen_when_us">Evil things might happen when using PerlFreshRestart</A>.
   
  -<P><A NAME="anchor25"></A>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
  +<CENTER><H1><A NAME="Speeding_up_the_Apache_Terminati">Speeding up the Apache Termination and Restart</A></H1></CENTER>
  +<P>
   We've already mentioned that restart or termination can sometimes take
  -quite a long time, (e.g. tens of seconds), for a mod_perl server. You have
  -an option to set the <A HREF="././debug.html#PERL_DESTRUCT_LEVEL_Environment_">PERL_DESTRUCT_LEVEL Environment Variable</A> during the <CODE>perl
  -Makefile.PL</CODE> stage. You can also simply set it to <EM>-1</EM> directly. This can speed things up, and can lead to more robust operation
  -in the face of problems such as running out of memory.
  -
  -<P><A NAME="anchor26"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<CENTER><H1><A NAME="Using_apachectl_to_control_the_s">Using apachectl to control the server</A></H1></CENTER>
  -<P><A NAME="anchor27"></A>
  +quite a long time, (e.g. tens of seconds), for a mod_perl server. The
  +reason for that is a call to the <CODE>perl_destruct()</CODE> Perl API
  +function during the child exit phase. This will cause proper execution of
  +<CODE>END</CODE> blocks found during server startup and will invoke the
  +<CODE>DESTROY</CODE> method on global objects which are still alive.
  +
  +<P>
  +It is also possible that this operation may take a long time to finish,
  +causing a long delay during a restart. Sometimes this will be followed by a
  +series of messages appearing in the server <EM>error_log</EM>
  +file, warning that certain child processes did not exit as expected. This
  +happens when after a few attempts advicing the child process to quit, the
  +child is still in the middle of <CODE>perl_destruct(),</CODE> and a lethal <CODE>KILL</CODE> signal is sent, aborting any operation the child has happened to execute
  +and <EM>brutally</EM> killing it.
  +
  +<P>
  +If your code does not contain any <CODE>END</CODE> blocks or <CODE>DESTROY</CODE> methods which need to be run during child server shutdown, or may have
  +these, but it's insignificant to execute them, this destruction can be
  +avoided by setting the <CODE>PERL_DESTRUCT_LEVEL</CODE> environment variable to
  +<CODE>-1</CODE>. For example add this setting to the <EM>httpd.conf</EM> file:
  +
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre> PerlSetEnv PERL_DESTRUCT_LEVEL -1</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +What constitutes a significant cleanup? Any change of state outside of the
  +current process that would not be handled by the operating system itself.
  +So committing database transactions and removing the lock on some resource
  +are significant operations, but closing an ordinary file isn't.
  +
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
  +<CENTER><H1><A NAME="Using_apachectl_to_Control_the_S">Using apachectl to Control the Server</A></H1></CENTER>
  +<P>
   The Apache distribution comes with a script to control the server. It's
   called <EM>apachectl</EM> and it is installed into the same location as the httpd executable. We will
  -assume for the sake of our examples that it's in
  -<CODE>/usr/local/sbin/httpd_perl/apachectl</CODE>:
  +assume for the sake of our examples that it's in <CODE>/usr/local/sbin/httpd_perl/apachectl</CODE>:
   
  -<P><A NAME="anchor28"></A>
  +<P>
   To start httpd_perl:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor29"></A>
  -<PRE>  % /usr/local/sbin/httpd_perl/apachectl start 
  -</PRE>
  -<P><A NAME="anchor30"></A>
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  % /usr/local/sbin/httpd_perl/apachectl start </pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   To stop httpd_perl:
   
  -<P><A NAME="anchor31"></A>
  -<PRE>  % /usr/local/sbin/httpd_perl/apachectl stop
  -</PRE>
  -<P><A NAME="anchor32"></A>
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  % /usr/local/sbin/httpd_perl/apachectl stop</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   To restart httpd_perl (if it is running, send <CODE>SIGHUP</CODE>; if it is not already running just start it):
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor33"></A>
  -<PRE>  % /usr/local/sbin/httpd_perl/apachectl restart
  -</PRE>
  -<P><A NAME="anchor34"></A>
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  % /usr/local/sbin/httpd_perl/apachectl restart</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Do a graceful restart by sending a <CODE>SIGUSR1</CODE>, or start if not running:
   
  -<P><A NAME="anchor35"></A>
  -<PRE>  % /usr/local/sbin/httpd_perl/apachectl graceful    
  -</PRE>
  -<P><A NAME="anchor36"></A>
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  % /usr/local/sbin/httpd_perl/apachectl graceful</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   To do a configuration test:
  +
  +<P>
   
  -<P><A NAME="anchor37"></A>
  -<PRE>  % /usr/local/sbin/httpd_perl/apachectl configtest 
  -</PRE>
  -<P><A NAME="anchor38"></A>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  % /usr/local/sbin/httpd_perl/apachectl configtest </pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Replace <CODE>httpd_perl</CODE> with <CODE>httpd_docs</CODE> in the above calls to control the <CODE>httpd_docs</CODE> server.
   
  -<P><A NAME="anchor39"></A>
  +<P>
   There are other options for <CODE>apachectl</CODE>, use the <CODE>help</CODE> option to see them all.
   
  -<P><A NAME="anchor40"></A>
  -It's important to remember that <CODE>apachectl</CODE> uses the PID file, which is specified by the <CODE>PIDFILE</CODE> directive in <CODE>httpd.conf</CODE>. If you delete the PID file by hand, <STRONG>apachectl</STRONG> will fail to run.
  +<P>
  +It's important to remember that <CODE>apachectl</CODE> uses the PID file, which is specified by the <CODE>PIDFILE</CODE> directive in <EM>httpd.conf</EM>. If you delete the PID file by hand while the server is running, <CODE>apachectl</CODE>
  +will be unable to stop or restart the server.
   
  -<P><A NAME="anchor41"></A>
  -Also note that <EM>apachectl</EM> is suitable for use from within a Unix system's startup files so that the
  -Web server is automatically restarted at system reboot.
  -
  -<P><A NAME="anchor42"></A>
  -Either copy the <EM>apachectl</EM> file to the appropriate location (<CODE>/etc/rc.d/rc3.d/S99apache</CODE> works on my RedHat Linux system) or create a symlink with that name
  -pointing to the canonical location. (If you do this, make certain that the
  -script is writable only by root! The startup scripts have root privileges
  -during initialisation, and you don't want to open up any security holes.)
  -
  -<P><A NAME="anchor43"></A>
  -You might also adopt the server executables naming convention in the
  -control script and have:
  -
  -<P><A NAME="anchor44"></A>
  -<PRE>  /usr/local/sbin/httpd_perl/httpd_perl_ctl
  -  /usr/local/sbin/httpd_docs/httpd_docs_ctl
  -</PRE>
  -<P><A NAME="anchor45"></A>
  -And to have in the <EM>rc.d</EM> directory:
  -
  -<P><A NAME="anchor46"></A>
  -<PRE>  /etc/rc.d/rc3.d/S92httpd_perl_ctl
  -  /etc/rc.d/rc3.d/S93httpd_docs_ctl
  -</PRE>
  -<P><A NAME="anchor47"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H1><A NAME="Safe_Code_Updates_on_a_Live_Prod">Safe Code Updates on a Live Production Server</A></H1></CENTER>
  -<P><A NAME="anchor48"></A>
  +<P>
   You have prepared a new version of code, uploaded it into a production
   server, restarted it and it doesn't work. What could be worse than that?
   You also cannot go back, because you have overwritten the good working
   code.
   
  -<P><A NAME="anchor49"></A>
  +<P>
   It's quite easy to prevent it, just don't overwrite the previous working
   files!
   
  -<P><A NAME="anchor50"></A>
  +<P>
   Personally I do all updates on the live server with the following sequence.
   Assume that the server root directory is
  -<CODE>/home/httpd/perl/rel</CODE>. When I'm about to update the files I create a new directory <CODE>/home/httpd/perl/beta</CODE>, copy the old files from
  -<CODE>/home/httpd/perl/rel</CODE> and update it with the new files. Then I do some last sanity checks (check
  +<EM>/home/httpd/perl/rel</EM>. When I'm about to update the files I create a new directory <EM>/home/httpd/perl/beta</EM>, copy the old files from
  +<EM>/home/httpd/perl/rel</EM> and update it with the new files. Then I do some last sanity checks (check
   file permissions are [read+executable], and run <CODE>perl -c</CODE> on the new modules to make sure there no errors in them). When I think I'm
   ready I do:
  +
  +<P>
   
  -<P><A NAME="anchor51"></A>
  -<PRE>  % cd /home/httpd/perl
  -  % mv rel old &amp;&amp; mv beta rel &amp;&amp; stop &amp;&amp; sleep 3 &amp;&amp; restart &amp;&amp; err
  -</PRE>
  -<P><A NAME="anchor52"></A>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  % cd /home/httpd/perl
  +  % mv rel old &amp;&amp; mv beta rel &amp;&amp; stop &amp;&amp; sleep 3 &amp;&amp; restart &amp;&amp; err</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Let me explain what this does.
   
  -<P><A NAME="anchor53"></A>
  +<P>
   Firstly, note that I put all the commands on one line, separated by
   <CODE>&amp;&amp;</CODE>, and only then press the <CODE>Enter</CODE> key. As I am working remotely, this ensures that if I suddenly lose my
   connection (sadly this happens sometimes) I won't leave the server down if
   only the
   <CODE>stop</CODE> command squeezed in.  <CODE>&amp;&amp;</CODE> also ensures that if any command fails, the rest won't be executed. I am
   using aliases (which I have already defined) to make the typing easier:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor54"></A>
  -<PRE>  % alias | grep apachectl
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  % alias | grep apachectl
     graceful /usr/local/apache/bin/apachectl graceful
     rehup   /usr/local/apache/sbin/apachectl restart
     restart /usr/local/apache/bin/apachectl restart
     start   /usr/local/apache/bin/apachectl start
  -  stop    /usr/local/apache/bin/apachectl stop
  -</PRE>
  -<P><A NAME="anchor55"></A>
  -<PRE>  % alias err
  -  tail -f /usr/local/apache/logs/error_log
  -</PRE>
  -<P><A NAME="anchor56"></A>
  +  stop    /usr/local/apache/bin/apachectl stop</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  % alias err
  +  tail -f /usr/local/apache/logs/error_log</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Taking the line apart piece by piece:
  +
  +<P>
   
  -<P><A NAME="anchor57"></A>
  -<PRE>  mv rel old &amp;&amp;
  -</PRE>
  -<P><A NAME="anchor58"></A>
  -back up the working directory to <CODE>old</CODE>
  +    <table>
  +      <tr>
   
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  mv rel old &amp;&amp;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +back up the working directory to <EM>old</EM>
   
   
  -<P><A NAME="anchor59"></A>
  -<PRE>  mv beta rel &amp;&amp;
  -</PRE>
  -<P><A NAME="anchor60"></A>
  +
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  mv beta rel &amp;&amp;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   put the new one in its place
  +
  +<P>
   
  -<P><A NAME="anchor61"></A>
  -<PRE>  stop &amp;&amp;
  -</PRE>
  -<P><A NAME="anchor62"></A>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  stop &amp;&amp;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   stop the server
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor63"></A>
  -<PRE>  sleep 3 &amp;&amp;
  -</PRE>
  -<P><A NAME="anchor64"></A>
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  sleep 3 &amp;&amp;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   give it a few seconds to shut down (it might take even longer)
   
  -<P><A NAME="anchor65"></A>
  -<PRE>  restart &amp;&amp;
  -</PRE>
  -<P><A NAME="anchor66"></A>
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  restart &amp;&amp;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   <CODE>restart</CODE> the server
  +
  +<P>
   
  -<P><A NAME="anchor67"></A>
  -<PRE>  err
  -</PRE>
  -<P><A NAME="anchor68"></A>
  -view of the tail of the <CODE>error_log</CODE> file in order to see that everything is OK
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor69"></A>
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  err</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +view of the tail of the <EM>error_log</EM> file in order to see that everything is OK
  +
  +<P>
   <CODE>apachectl</CODE> generates the status messages a little too early (e.g. when you issue <CODE>apachectl stop</CODE> it says the server has been stopped, while in fact it's still running) so
   don't rely on it, rely on the <CODE>error_log</CODE> file instead.
   
  -<P><A NAME="anchor70"></A>
  +<P>
   Also notice that I use <CODE>restart</CODE> and not just <CODE>start</CODE>. I do this because of Apache's potentially long stopping times (it depends
   on what you do with it of course!). If you use <CODE>start</CODE> and Apache hasn't yet released the port it's listening to, the start would
   fail and <CODE>error_log</CODE> would tell you that the port is in use, e.g.:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor71"></A>
  -<PRE>  Address already in use: make_sock: could not bind to port 8080
  -</PRE>
  -<P><A NAME="anchor72"></A>
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  Address already in use: make_sock: could not bind to port 8080</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   But if you use <CODE>restart</CODE>, it will wait for the server to quit and then will cleanly restart it.
   
  -<P><A NAME="anchor73"></A>
  +<P>
   Now what happens if the new modules are broken? First of all, I see
   immediately an indication of the problems reported in the <CODE>error_log</CODE>
   file, which I <CODE>tail -f</CODE> immediately after a restart command. If there's a problem, I just put
   everything back as it was before:
   
  -<P><A NAME="anchor74"></A>
  -<PRE>  % mv rel bad &amp;&amp; mv old rel &amp;&amp; stop &amp;&amp; sleep 3 &amp;&amp; restart &amp;&amp; err
  -</PRE>
  -<P><A NAME="anchor75"></A>
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  % mv rel bad &amp;&amp; mv old rel &amp;&amp; stop &amp;&amp; sleep 3 &amp;&amp; restart &amp;&amp; err</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Usually everything will be fine, and I have had only about 10 seconds of
   downtime, which is pretty good!
   
  -<P><A NAME="anchor76"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H1><A NAME="An_Intentional_Disabling_of_Live">An Intentional Disabling of Live Scripts</A></H1></CENTER>
  -<P><A NAME="anchor77"></A>
  +<P>
   What happens if you really must take down the server or disable the
   scripts? This situation might happen when you need to do some maintenance
   work on your database server. If you have to take your database down then
   any scripts that use it will fail.
   
  -<P><A NAME="anchor78"></A>
  +<P>
   If you do nothing, the user will see either the grey <CODE>An Error has
   happened</CODE> message or perhaps a customized error message if you have added code to
   trap and customize the errors. See <A HREF="././snippets.html#Redirecting_Errors_to_the_Client">Redirecting Errors to the Client instead of to the error_log</A> for the latter case.
   
  -<P><A NAME="anchor79"></A>
  +<P>
   A much friendlier approach is to confess to your users that you are doing
   some maintenance work and plead for patience, promising (keep the promise!)
   that the service will become fully functional in X minutes. There are a few
   ways to do this:
   
  -<P><A NAME="anchor80"></A>
  +<P>
   The first doesn't require messing with the server. It works when you have
   to disable a script running under <CODE>Apache::Registry</CODE> and relies on the fact that it checks whether the file was modified before
   using the cached version. Obviously it won't work under other handlers
   because these serve the compiled version of the code and don't check to see
   if there was a change in the code on the disk.
   
  -<P><A NAME="anchor81"></A>
  +<P>
   So if you want to disable an <CODE>Apache::Registry</CODE> script, prepare a little script like this:
  +
  +<P>
   
  -<P><A NAME="anchor82"></A>
  -<PRE>  /home/http/perl/maintenance.pl
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  /home/http/perl/maintenance.pl
     ----------------------------
     #!/usr/bin/perl -Tw
     
  @@ -428,54 +754,114 @@
     &quot;Sorry, the service is temporarily down for maintenance. 
      It will be back in ten to fifteen minutes.
      Please, bear with us.
  -   Thank you!&quot;);
  -</PRE>
  -<P><A NAME="anchor83"></A>
  +   Thank you!&quot;);</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   So if you now have to disable a script for example
   <CODE>/home/http/perl/chat.pl</CODE>, just do this:
  +
  +<P>
   
  -<P><A NAME="anchor84"></A>
  -<PRE>  % mv /home/http/perl/chat.pl /home/http/perl/chat.pl.orig
  -  % ln -s /home/http/perl/maintenance.pl /home/http/perl/chat.pl
  -</PRE>
  -<P><A NAME="anchor85"></A>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  % mv /home/http/perl/chat.pl /home/http/perl/chat.pl.orig
  +  % ln -s /home/http/perl/maintenance.pl /home/http/perl/chat.pl</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Of course you server configuration should allow symbolic links for this
   trick to work. Make sure you have the directive
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor86"></A>
  -<PRE>  Options FollowSymLinks
  -</PRE>
  -<P><A NAME="anchor87"></A>
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  Options FollowSymLinks</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   in the <CODE>&lt;Location&gt;</CODE> or <CODE>&lt;Directory&gt;</CODE> section of your
   <EM>httpd.conf</EM>.
   
  -<P><A NAME="anchor88"></A>
  +<P>
   When you're done, it's easy to restore the previous setup. Just do this:
   
  -<P><A NAME="anchor89"></A>
  -<PRE>  % mv /home/http/perl/chat.pl.orig /home/http/perl/chat.pl
  -</PRE>
  -<P><A NAME="anchor90"></A>
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  % mv /home/http/perl/chat.pl.orig /home/http/perl/chat.pl</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   which overwrites the symbolic link.
   
  -<P><A NAME="anchor91"></A>
  +<P>
   Now make sure that the script will have the current timestamp:
  +
  +<P>
   
  -<P><A NAME="anchor92"></A>
  -<PRE>  % touch /home/http/perl/chat.pl
  -</PRE>
  -<P><A NAME="anchor93"></A>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  % touch /home/http/perl/chat.pl</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Apache will automatically detect the change and will use the moved script
   instead.
   
  -<P><A NAME="anchor94"></A>
  +<P>
   The second approach is to change the server configuration and configure a
   whole directory to be handled by a <CODE>My::Maintenance</CODE>
   handler (which you must write). For example if you write something like
   this:
  +
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
   
  -<P><A NAME="anchor95"></A>
  -<PRE>  My/Maintenance.pm
  +	<td>
  +	  <pre>  My/Maintenance.pm
     ------------------
     package My::Maintenance;
     use strict;
  @@ -489,56 +875,265 @@
         Please, bear with us.  Thank you!
       };
       return OK;
  -  }
  -</PRE>
  -<P><A NAME="anchor96"></A>
  +  }</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   and put it in a directory that is in the server's <CODE>@INC</CODE>, to disable all the scripts in Location <CODE>/perl</CODE> you would replace:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor97"></A>
  -<PRE>  &lt;Location /perl&gt;
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  &lt;Location /perl&gt;
       SetHandler perl-script
       PerlHandler My::Handler
       [snip]
  -  &lt;/Location&gt;
  -</PRE>
  -<P><A NAME="anchor98"></A>
  +  &lt;/Location&gt;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   with
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor99"></A>
  -<PRE>  &lt;Location /perl&gt;
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  &lt;Location /perl&gt;
       SetHandler perl-script
       PerlHandler My::Maintenance
       [snip]
  -  &lt;/Location&gt;
  -</PRE>
  -<P><A NAME="anchor100"></A>
  +  &lt;/Location&gt;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Now restart the server. Your users will be happy to go and read <A
   HREF="http://slashdot.org">http://slashdot.org</A> for ten minutes, knowing
   that you are working on a much better version of the service.
   
  -<P><A NAME="anchor101"></A>
  +<P>
   If you need to disable a location handled by some module, the second
   approach would work just as well.
   
  -<P><A NAME="anchor102"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H1><A NAME="SUID_Start_up_Scripts">SUID Start-up Scripts</A></H1></CENTER>
  -<P><A NAME="anchor103"></A>
  -For those who want to use SUID startup scripts, here is an example. This
  -script is <EM>SUID root</EM>, and should be executable only by members of some special group at your
  -site. Note the line marked
  -<CODE>WORKAROUND</CODE>, which fixes an obscure error when starting apache/mod_perl by setting the
  -real to the effective UID. Without this workaround, a mismatch between the
  -real and the effective UIDs causes Perl to croak on the -e switch.
  +<P>
  +If you want to allow a few people in your team to start and stop the server
  +you will have to give them the root password, which is not a good thing to
  +do. The less people know the password, the less problems are likely to be
  +encountered. But there is an easy solution for this problem available on
  +UNIX platforms. It's called a setuid executable.
   
  -<P><A NAME="anchor104"></A>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
  +<CENTER><H2><A NAME="Introduction_to_SUID_Executables">Introduction to SUID Executables</A></H2></CENTER>
  +<P>
  +The setuid executable has a setuid permissions bit set. This sets the
  +process's effective user ID to that of the file upon execution. You perform
  +this setting with the following command:
  +
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  % chmod u+s filename</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +You probably have used setuid executables before without even knowing about
  +it. For example when you change your password you execute the
  +<CODE>passwd</CODE> utility, which among other things modifies the
  +<EM>/etc/passwd</EM> file. In order to change this file you need root permissions, the <CODE>passwd</CODE> utility has the setuid bit set, therefore when you execute this utility,
  +its effective ID is the same of the root user ID.
  +
  +<P>
  +You should avoid using setuid executables as a general practice. The less
  +setuid executables you have the less likely that someone will find a way to
  +break into your system, by exploiting some bug you didn't know about.
  +
  +<P>
  +When the executable is setuid to root, you have to make sure that it
  +doesn't have the group and world read and write permissions. If we take a
  +look at the <CODE>passwd</CODE> utility we will see:
  +
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  % ls -l /usr/bin/passwd
  +  -r-s--x--x 1 root root 12244 Feb 8 00:20 /usr/bin/passwd</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +You achieve this with the following command:
  +
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  % chmod 4511 filename</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +The first digit (4) stands for setuid bit, the second digit (5) is a
  +compound of read (4) and executable (1) permissions for the user, and the
  +third and the fourth digits are setting the executable permissions for the
  +group and the world.
  +
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
  +<CENTER><H2><A NAME="Apache_Startup_SUID_Script_s_Sec">Apache Startup SUID Script's Security</A></H2></CENTER>
  +<P>
  +In our case, we want to allow setuid access only to a specific group of
  +users, who all belong to the same group. For the sake of our example we
  +will use the group named <EM>apache</EM>. It's important that users who aren't root or who don't belong to the <EM>apache</EM> group will not be able to execute this script. Therefore we perform the
  +following commands:
  +
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  % chgrp apache apachectl
  +  % chmod  4510  apachectl</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +The execution order is important. If you swap the command execution order
  +you will lose the setuid bit.
  +
  +<P>
  +Now if we look at the file we see:
  +
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  % ls -l apachectl
  +  -r-s--x--- 1 root apache 32 May 13 21:52 apachectl</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +Now we are all set... Almost...
  +
  +<P>
  +When you start Apache, Apache and Perl modules are being loaded, code can
  +be executed. Since all this happens with root effective ID, any code
  +executed as if the root user was doing that. You should be very careful
  +because while you didn't gave anyone the root password, all the users in
  +the <EM>apache</EM> group have an indirect root access. Which means that if Apache loads some
  +module or executes some code that is writable by some of these users, users
  +can plant code that will allow them to gain a shell access to root account
  +and become a real root.
  +
  +<P>
  +Of course if you don't trust your team you shouldn't use this solution in
  +first place. You can try to check that all the files Apache loads aren't
  +writable by anyone but root, but there are too many of them, especially in
  +the mod_perl case, where many Perl modules are loaded at the server
  +startup.
  +
  +<P>
  +By the way, don't let all this setuid stuff to confuse you -- when the
  +parent process is loaded, the childred processes are spawned as non-root
  +processes. This section has presented a way to allow non-root users to
  +start the server as root user, the rest is exactly the same as if you were
  +executing the script as root in first place.
  +
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
  +<CENTER><H2><A NAME="Sample_Apache_Startup_SUID_Scrip">Sample Apache Startup SUID Script</A></H2></CENTER>
  +<P>
  +Now if you are still with us, here is an example of the setuid Apache
  +startup script.
  +
  +<P>
  +Note the line marked <CODE>WORKAROUND</CODE>, which fixes an obscure error when starting mod_perl enabled Apache by
  +setting the real UID to the effective UID. Without this workaround, a
  +mismatch between the real and the effective UIDs causes Perl to croak on
  +the <CODE>-e</CODE> switch.
  +
  +<P>
   Note that you must be using a version of Perl that recognizes and emulates
   the suid bits in order for this to work. This script will do different
  -things depending on whether it is named <CODE>start_http</CODE>,
  -<CODE>stop_http</CODE> or <CODE>restart_http</CODE>. You can use symbolic links for this purpose.
  +things depending on whether it is named <CODE>start_httpd</CODE>,
  +<CODE>stop_httpd</CODE> or <CODE>restart_httpd</CODE>. You can use symbolic links for this purpose.
  +
  +<P>
   
  -<P><A NAME="anchor105"></A>
  -<PRE>  #!/usr/bin/perl -T
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  suid_apache_ctl
  +  ---------------
  +  #!/usr/bin/perl -T
      
     # These constants will need to be adjusted.
     $PID_FILE = '/home/www/logs/httpd.pid';
  @@ -556,7 +1151,7 @@
     # Do different things depending on our name
     ($name) = $0 =~ m|([^/]+)$|;
     
  -  if ($name eq 'start_http') {
  +  if ($name eq 'start_httpd') {
         system $HTTPD and die &quot;Unable to start HTTP&quot;;
         print &quot;HTTP started.\n&quot;;
         exit 0;
  @@ -567,24 +1162,28 @@
     $pid =~ /(\d+)/ or die &quot;PID $pid not numeric&quot;;
     $pid = $1;
     
  -  if ($name eq 'stop_http') {
  +  if ($name eq 'stop_httpd') {
         kill 'TERM',$pid or die &quot;Unable to signal HTTP&quot;;
         print &quot;HTTP stopped.\n&quot;;
         exit 0;
     }
     
  -  if ($name eq 'restart_http') {
  +  if ($name eq 'restart_httpd') {
         kill 'HUP',$pid or die &quot;Unable to signal HTTP&quot;;
         print &quot;HTTP restarted.\n&quot;;
         exit 0;
     }
     
  -  die &quot;Script must be named start_http, stop_http, or restart_http.\n&quot;;
  -</PRE>
  -<P><A NAME="anchor106"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +  die &quot;Script must be named start_httpd, stop_httpd, or restart_httpd.\n&quot;;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H1><A NAME="Preparing_for_Machine_Reboot">Preparing for Machine Reboot</A></H1></CENTER>
  -<P><A NAME="anchor107"></A>
  +<P>
   When you run your own development box, it's okay to start the webserver by
   hand when you need to. On a production system it is possible that the
   machine the server is running on will have to be rebooted. When the reboot
  @@ -592,93 +1191,151 @@
   forget this task, and what happens if you aren't around when the machine is
   rebooted?
   
  -<P><A NAME="anchor108"></A>
  +<P>
   After the server installation is complete, it's important not to forget
   that you need to put a script to perform the server startup and shutdown
  -into the standard system location, for example <CODE>/etc/rc.d</CODE>
  -under RedHat Linux, or <CODE>/etc/init.d/apache</CODE> under Debian Slink Linux.
  +into the standard system location, for example <EM>/etc/rc.d</EM>
  +under RedHat Linux, or <EM>/etc/init.d/apache</EM> under Debian Slink Linux.
   
  -<P><A NAME="anchor109"></A>
  +<P>
   This is the directory which contains scripts to start and stop all the
   other daemons. The directory and file names vary from one Operating System
  -to another, and even between different distributions of the same OS.
  +(OS) to another, and even between different distributions of the same OS.
   
  -<P><A NAME="anchor110"></A>
  -Generally the simplest solution is to copy the <CODE>apachectl</CODE> script to your startup directory. You will find <CODE>apachectl</CODE> in the same directory as the httpd executable after Apache installation. If
  -you have more than one Apache server you will need a script for each one,
  -and of course you will have to rename them so that they can co-exist in the
  -same directories.
  +<P>
  +Generally the simplest solution is to copy the <CODE>apachectl</CODE> script to your startup directory or create a symbolic link from the startup
  +directory to the <CODE>apachectl</CODE> script. You will find <CODE>apachectl</CODE> in the same directory as the httpd executable after Apache installation. If
  +you have more than one Apache server you will need a separate script for
  +each one, and of course you will have to rename them so that they can
  +co-exist in the same directories.
   
  -<P><A NAME="anchor111"></A>
  +<P>
   For example on a RedHat Linux machine with two servers, I have the
   following setup:
  +
  +<P>
   
  -<P><A NAME="anchor112"></A>
  -<PRE>  /etc/rc.d/init.d/httpd_docs
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  /etc/rc.d/init.d/httpd_docs
     /etc/rc.d/init.d/httpd_perl
     /etc/rc.d/rc3.d/S86httpd_docs -&gt; ../init.d/httpd_docs
     /etc/rc.d/rc3.d/S87httpd_perl -&gt; ../init.d/httpd_perl
     /etc/rc.d/rc6.d/K86httpd_docs -&gt; ../init.d/httpd_docs
  -  /etc/rc.d/rc6.d/K87httpd_perl -&gt; ../init.d/httpd_perl
  -</PRE>
  -<P><A NAME="anchor113"></A>
  -The scripts themselves reside in the <EM>init.d</EM> directory. There are symbolic links to these scripts in other directories.
  +  /etc/rc.d/rc6.d/K87httpd_perl -&gt; ../init.d/httpd_perl</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +The scripts themselves reside in the <EM>/etc/rc.d/init.d</EM> directory. There are symbolic links to these scripts in other directories.
   The names are the same as the script names but they have numbers prepended,
   which are used for executing the scripts in a particular order: the lower
   numbers are executed earlier.
   
  -<P><A NAME="anchor114"></A>
  +<P>
   Under RedHat Linux, when a machine is booted and its runlevel set to 3
   (multiuser+network), Linux goes into <CODE>/etc/rc.d/rc3.d/</CODE> and executes the scripts the symbolic links point to with the <CODE>start</CODE> argument. When it sees <EM>S87httpd_perl</EM>, it executes:
  +
  +<P>
   
  -<P><A NAME="anchor115"></A>
  -<PRE>  /etc/rc.d/init.d/httpd_perl start
  -</PRE>
  -<P><A NAME="anchor116"></A>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  /etc/rc.d/init.d/httpd_perl start</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   When the machine is shut down, the scripts are executed through links from
   the <EM>/etc/rc.d/rc6.d/</EM> directory. This time the scripts are called with the <CODE>stop</CODE> argument, like this:
  +
  +<P>
   
  -<P><A NAME="anchor117"></A>
  -<PRE>  /etc/rc.d/init.d/httpd_perl stop
  -</PRE>
  -<P><A NAME="anchor118"></A>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  /etc/rc.d/init.d/httpd_perl stop</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Most systems have GUI utilites to automate the creation of symbolic links.
  -For example RedHat Linux includes the
  -<CODE>control-panel</CODE> utility, which amongst other things includes the
  -<CODE>RunLevel Manager</CODE>. This will help you to create the proper symbolic links. Of course before
  -you use it, you should put <CODE>apachectl</CODE> or similar scripts into the <EM>init.d</EM> or equivalent directory.
  +For example RedHat Linux includes the <CODE>control-panel</CODE>
  +utility, which amongst other things includes the <CODE>RunLevel Manager</CODE>. This will help you to create the proper symbolic links. Of course before
  +you use it, you should put <CODE>apachectl</CODE> or similar scripts into the <EM>init.d</EM> or equivalent directory. Or you can have a symbolic link to some other
  +location instead.
   
  -<P><A NAME="anchor119"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H1><A NAME="Monitoring_the_Server_A_watchdo">Monitoring the Server.  A watchdog.</A></H1></CENTER>
  -<P><A NAME="anchor120"></A>
  +<P>
   With mod_perl many things can happen to your server. It is possibile that
   the server might die when you are not around. As with any other critical
   service you need to run some kind of watchdog.
   
  -<P><A NAME="anchor121"></A>
  -One simple solution is to use a slightly modified <STRONG>apachectl</STRONG> script, which I've named <EM>apache.watchdog</EM>. Call it from the crontab every 30 minutes -- or even every minute -- to
  +<P>
  +One simple solution is to use a slightly modified <CODE>apachectl</CODE> script, which I've named <EM>apache.watchdog</EM>. Call it from the crontab every 30 minutes -- or even every minute -- to
   make sure the server is up all the time.
   
  -<P><A NAME="anchor122"></A>
  +<P>
   The crontab entry for 30 minutes intervals:
   
  -<P><A NAME="anchor123"></A>
  -<PRE>  0,30 * * * * /path/to/the/apache.watchdog &gt;/dev/null 2&gt;&amp;1
  -</PRE>
  -<P><A NAME="anchor124"></A>
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  0,30 * * * * /path/to/the/apache.watchdog &gt;/dev/null 2&gt;&amp;1</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   The script:
  +
  +<P>
   
  -<P><A NAME="anchor125"></A>
  -<PRE>  #!/bin/sh
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  #!/bin/sh
       
     # this script is a watchdog to see whether the server is online
     # It tries to restart the server, and if it's
     # down it sends an email alert to admin 
     
     # admin's email
  -  EMAIL=webmaster@somewhere.far
  -  #EMAIL=root@localhost
  +  EMAIL=webmaster@example.com
       
     # the path to your PID file
     PIDFILE=/usr/local/var/httpd_perl/run/httpd.pid
  @@ -711,40 +1368,64 @@
         echo &quot;$0 $ARG: httpd could not be started&quot;
         mail $EMAIL -s &quot;$0 $ARG: httpd could not be started&quot; &lt;/dev/null &gt;&amp; /dev/null
       fi
  -  fi
  -</PRE>
  -<P><A NAME="anchor126"></A>
  +  fi</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Another approach, probably even more practical, is to use the cool
   <CODE>LWP</CODE> perl package to test the server by trying to fetch some document (script)
   served by the server. Why is it more practical? Because while the server
   can be up as a process, it can be stuck and not working. Failing to get the
  -document will trigger restart, and ``probably'' the problem will go away.
  -Just replace <CODE>start</CODE> with
  -<CODE>restart</CODE> in the <CODE>$restart_command</CODE> below.
  -
  -<P><A NAME="anchor127"></A>
  -Again we put this script into the crontab to call it every 30 minutes.
  -Personally I call it every minute, to fetch some very light script. Why so
  -often? If your server starts to spin and trash your disk space with
  -multiple error messages filling the error log, in five minutes you might
  -run out of free disk space which might bring your system to its knees.
  -Chances are that no other child will be able to serve requests, since the
  -system will be too busy writing to the
  -<CODE>error_log</CODE> file. Think big -- if you are running a heavy service (which is very fast
  +document will trigger restart, and ``probably'' the problem will go away. 
  +
  +<P>
  +Like before we set a cronjob to call this script every few minutes to fetch
  +some very light script. The best thing of course is to call it every
  +minute. Why so often? If your server starts to spin and trash your disk
  +space with multiple error messages filling the <EM>error_log</EM>, in five minutes you might run out of free disk space which might bring
  +your system to its knees. Chances are that no other child will be able to
  +serve requests, since the system will be too busy writing to the <EM>error_log</EM> file. Think big -- if you are running a heavy service (which is very fast
   since you are running under mod_perl) adding one more request every minute
   will not be felt by the server at all.
   
  -<P><A NAME="anchor128"></A>
  +<P>
   So we end up with a crontab entry like this:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor129"></A>
  -<PRE>  * * * * * /path/to/the/watchdog.pl &gt;/dev/null 2&gt;&amp;1
  -</PRE>
  -<P><A NAME="anchor130"></A>
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  * * * * * /path/to/the/watchdog.pl &gt;/dev/null 2&gt;&amp;1</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   And the watchdog itself:
   
  -<P><A NAME="anchor131"></A>
  -<PRE>  #!/usr/local/bin/perl -w
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  #!/usr/bin/perl -wT
  +  
  +  # untaint
  +  $ENV{'PATH'} = '/bin:/usr/bin';
  +  delete @ENV{'IFS', 'CDPATH', 'ENV', 'BASH_ENV'};
     
     use strict;
     use diagnostics;
  @@ -754,22 +1435,21 @@
     my $VERSION = '0.01';
     use vars qw($ua $proxy);
     $proxy = '';    
  -</PRE>
  -<P><A NAME="anchor132"></A>
  -<PRE>  require LWP::UserAgent;
  +  
  +  require LWP::UserAgent;
     use HTTP::Status;
     
     ###### Config ########
  -  my $test_script_url = '<A HREF="http://www.stas.com:81/perl/test.pl">http://www.stas.com:81/perl/test.pl</A>';
  +  my $test_script_url = '<A HREF="http://www.example.com:81/perl/test.pl">http://www.example.com:81/perl/test.pl</A>';
     my $monitor_email   = 'root@localhost';
     my $restart_command = '/usr/local/sbin/httpd_perl/apachectl restart';
     my $mail_program    = '/usr/lib/sendmail -t -n';
     ######################
     
     $ua  = new LWP::UserAgent;
  -  $ua-&gt;agent(&quot;$0/Stas &quot; . $ua-&gt;agent);
  -  # Uncomment the proxy if you don't use it!
  -  #  $proxy=&quot;<A HREF="http://www-proxy.com&quot">http://www-proxy.com&quot</A>;;
  +  $ua-&gt;agent(&quot;$0/watchdog &quot; . $ua-&gt;agent);
  +  # Uncomment the proxy if you access a machine from behind a firewall
  +  # $proxy = &quot;<A HREF="http://www-proxy.com&quot">http://www-proxy.com&quot</A>;;
     $ua-&gt;proxy('http', $proxy) if $proxy;
     
     # If it returns '1' it means we are alive
  @@ -778,7 +1458,6 @@
     # Houston, we have a problem.
     # The server seems to be down, try to restart it. 
     my $status = system $restart_command;
  -  #  print &quot;Status $status\n&quot;;
     
     my $message = ($status == 0) 
                 ? &quot;Server was down and successfully restarted!&quot; 
  @@ -827,47 +1506,65 @@
     __END_OF_MAIL__
     
       close MAIL;
  -  } 
  -</PRE>
  -<P><A NAME="anchor133"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +  } </pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H1><A NAME="Running_a_Server_in_Single_Proce">Running a Server in Single Process Mode</A></H1></CENTER>
  -<P><A NAME="anchor134"></A>
  +<P>
   Often while developing new code, you will want to run the server in single
   process mode. See <A HREF="././porting.html#Sometimes_it_Works_Sometimes_it">Sometimes it works Sometimes it does Not</A> and <A HREF="././porting.html#Name_collisions_with_Modules_and">Names collisions with Modules and libs</A>. Running in single process mode inhibits the server from ``daemonizing'',
   and this allows you to run it under the control of a debugger more easily.
  +
  +<P>
   
  -<P><A NAME="anchor135"></A>
  -<PRE>  % /usr/local/sbin/httpd_perl/httpd_perl -X
  -</PRE>
  -<P><A NAME="anchor136"></A>
  -When you use the -X switch the server will run in the foreground of the
  -shell, so you can kill it with <EM>Ctrl-C</EM>.
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor137"></A>
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  % /usr/local/sbin/httpd_perl/httpd_perl -X</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +When you use the <CODE>-X</CODE> switch the server will run in the foreground of the shell, so you can kill
  +it with <EM>Ctrl-C</EM>.
  +
  +<P>
   Note that in <CODE>-X</CODE> (single-process) mode the server will run very slowly when fetching images.
   
  -<P><A NAME="anchor138"></A>
  +<P>
   Note for Netscape users:
   
  -<P><A NAME="anchor139"></A>
  +<P>
   If you use Netscape while your server is running in single-process mode,
   HTTP's <CODE>KeepAlive</CODE> feature gets in the way. Netscape tries to open multiple connections and
   keep them open. Because there is only one server process listening, each
  -connection has to time out before the next succeeds. Turn off <CODE>KeepAlive</CODE> in <CODE>httpd.conf</CODE> to avoid this effect while developing. If you use the image size
  +connection has to time out before the next succeeds. Turn off <CODE>KeepAlive</CODE> in <EM>httpd.conf</EM> to avoid this effect while developing. If you use the image size
   parameters, Netscape will be able to render the page without the images so
   you can press the browser's <EM>STOP</EM> button after a few seconds.
   
  -<P><A NAME="anchor140"></A>
  +<P>
   In addition you should know that when running with <CODE>-X</CODE> you will not see the control messages that the parent server normally
  -writes to the error_log (<EM>"server started", "server stopped"</EM> etc). Since <CODE>httpd
  --X</CODE> causes the server to handle all requests itself, without forking any
  +writes to the
  +<EM>error_log</EM> (<EM>"server started"</EM>, <EM>"server stopped"</EM> etc). Since
  +httpd&nbsp;-X causes the server to handle all requests itself, without forking any
   children, there is no controlling parent to write the status messages.
   
  -<P><A NAME="anchor141"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H1><A NAME="Starting_a_Personal_Server_for_E">Starting a Personal Server for Each Developer</A></H1></CENTER>
  -<P><A NAME="anchor142"></A>
  +<P>
   If you are the only developer working on the specific server:port you have
   no problems, since you have complete control over the server. However,
   often you will have a group of developers who need to develop mod_perl
  @@ -876,30 +1573,63 @@
   mode, to restart it etc., as well as having control over the location of
   the log files, configuration settings like <CODE>MaxClients</CODE>, and so on.
   
  -<P><A NAME="anchor143"></A>
  +<P>
   You <EM>can</EM> work around this problem by preparing a few <EM>httpd.conf</EM>
   files and forcing each developer to use
  +
  +<P>
   
  -<P><A NAME="anchor144"></A>
  -<PRE>  httpd_perl -f /path/to/httpd.conf  
  -</PRE>
  -<P><A NAME="anchor145"></A>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  httpd_perl -f /path/to/httpd.conf  </pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   but I approach it in a different way. I use the <CODE>-Dparameter</CODE>
   startup option of the server. I call my version of the server
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor146"></A>
  -<PRE>  % http_perl -Dsbekman
  -</PRE>
  -<P><A NAME="anchor147"></A>
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  % http_perl -Dstas</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   In <EM>httpd.conf</EM> I write:
   
  -<P><A NAME="anchor148"></A>
  -<PRE>  # Personal development Server for sbekman
  -  # sbekman uses the server running on port 8000
  -  &lt;IfDefine sbekman&gt;
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  # Personal development Server for stas
  +  # stas uses the server running on port 8000
  +  &lt;IfDefine stas&gt;
     Port 8000
  -  PidFile /usr/local/var/httpd_perl/run/httpd.pid.sbekman
  -  ErrorLog /usr/local/var/httpd_perl/logs/error_log.sbekman
  +  PidFile /usr/local/var/httpd_perl/run/httpd.pid.stas
  +  ErrorLog /usr/local/var/httpd_perl/logs/error_log.stas
     Timeout 300
     KeepAlive On
     MinSpareServers 2
  @@ -922,129 +1652,256 @@
     StartServers 1
     MaxClients 5
     MaxRequestsPerChild 0
  -  &lt;/IfDefine&gt;
  -</PRE>
  -<P><A NAME="anchor149"></A>
  +  &lt;/IfDefine&gt;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   With this technique we have achieved full control over start/stop, number
   of children, a separate error log file, and port selection for each server.
  -This saves me from getting called every few minutes - ``Stas, I'm going to
  -restart the server''.
  +This saves Stas from getting called every few minutes by Eric: ``Stas, I'm
  +going to restart the server''.
   
  -<P><A NAME="anchor150"></A>
  +<P>
   In the above technique, you need to discover the PID of your parent
   <CODE>httpd_perl</CODE> process, which is written in
  -<CODE>/usr/local/var/httpd_perl/run/httpd.pid.userfoo</CODE>. To make things even easier we change the <EM>apachectl</EM> script to do the work for us. We make a copy for each developer called <STRONG>apachectl.username</STRONG> and we change two lines in each script:
  +<CODE>/usr/local/var/httpd_perl/run/httpd.pid.stas</CODE> (and the same for the user eric). To make things even easier we change the <EM>apachectl</EM>
  +script to do the work for us. We make a copy for each developer called <STRONG>apachectl.username</STRONG> and we change two lines in each script:
  +
  +<P>
   
  -<P><A NAME="anchor151"></A>
  -<PRE>  PIDFILE=/usr/local/var/httpd_perl/run/httpd.pid.sbekman
  -  HTTPD='/usr/local/sbin/httpd_perl/httpd_perl -Dsbekman'
  -</PRE>
  -<P><A NAME="anchor152"></A>
  -You might think you can use only one control file and know who is calling
  -from the uid, but since you have to be root to start the server it is not
  -so simple.
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor153"></A>
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  PIDFILE=/usr/local/var/httpd_perl/run/httpd.pid.username
  +  HTTPD='/usr/local/sbin/httpd_perl/httpd_perl -Dusername'</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +So for the user <EM>stas</EM> we prepare a startup script called
  +<STRONG>apachectl.stas</STRONG> and we change these two lines in the standard apachectl script as it comes
  +unmodified from Apache distribution.
  +
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  PIDFILE=/usr/local/var/httpd_perl/run/httpd.pid.stas
  +  HTTPD='/usr/local/sbin/httpd_perl/httpd_perl -Dstas'</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +So now when user <EM>stas</EM> wants to stop the server he will execute:
  +
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  apachectl.stas stop</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +And to start:
  +
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  apachectl.stas start</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +Certainly the rest of the <CODE>apachectl</CODE> arguments apply as before.
  +
  +<P>
  +You might think about having only one <CODE>apachectl</CODE> and know who is calling by checking the UID, but since you have to be root
  +to start the server it is not possible, unless you make the setuid bit on
  +this script, as we've explained in the beginning of this chapter. If you do
  +so, you can have a single <CODE>apachectl</CODE> script for all developers, after you modify it to automatically find out
  +the UID of the user, who executes the script and set the right paths.
  +
  +<P>
   The last thing is to provide developers with an option to run in single
   process mode by:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor154"></A>
  -<PRE>  /usr/local/sbin/httpd_perl/httpd_perl -Dsbekman -X
  -</PRE>
  -<P><A NAME="anchor155"></A>
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  /usr/local/sbin/httpd_perl/httpd_perl -Dstas -X</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   In addition to making life easier, we decided to use relative links
   everywhere in the static documents, including the calls to CGIs. You may
  -ask how using relative links will get to the right server. It's very
  +ask how using relative links will get to the right server port. It's very
   simple, we use <CODE>mod_rewrite</CODE>.
   
  -<P><A NAME="anchor156"></A>
  -To use mod_rewrite you have to configure your <EM>httpd_docs</EM> server with <CODE>--enable-module=rewrite</CODE> and recompile, or use DSO and load the module in <EM>httpd.conf</EM>. In the <EM>access.conf</EM> of our <CODE>httpd_docs</CODE>
  +<P>
  +To use mod_rewrite you have to configure your <EM>httpd_docs</EM> server with <CODE>--enable-module=rewrite</CODE> and recompile, or use DSO and load the module in <EM>httpd.conf</EM>. In the <EM>httpd.conf</EM> of our <CODE>httpd_docs</CODE>
   server we have the following code:
   
  -<P><A NAME="anchor157"></A>
  -<PRE>  # sbekman's server
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  RewriteEngine on
  +  
  +  # stas's server
     # port = 8000
  -  RewriteCond  %{REQUEST_URI} ^/(perl|cgi-perl)  
  +  RewriteCond  %{REQUEST_URI} ^/(perl|cgi-perl)
     RewriteCond  %{REMOTE_ADDR} 123.34.45.56
  -  RewriteRule ^(.*)           <A HREF="http://nowhere.com:8000/">http://nowhere.com:8000/</A>$1 [R,L]
  +  RewriteRule ^(.*)           <A HREF="http://example.com:8000/">http://example.com:8000/</A>$1 [P,L]
     
  -  # userfoo's server
  +  # eric's server
     # port = 8001
  -  RewriteCond  %{REQUEST_URI} ^/(perl|cgi-perl)  
  +  RewriteCond  %{REQUEST_URI} ^/(perl|cgi-perl)
     RewriteCond  %{REMOTE_ADDR} 123.34.45.57
  -  RewriteRule ^(.*)           <A HREF="http://nowhere.com:8001/">http://nowhere.com:8001/</A>$1 [R,L]
  +  RewriteRule ^(.*)           <A HREF="http://example.com:8001/">http://example.com:8001/</A>$1 [P,L]
     
     # all the rest
  -  RewriteCond  %{REQUEST_URI} ^/(perl|cgi-perl)  
  -  RewriteRule ^(.*)           <A HREF="http://nowhere.com:81/">http://nowhere.com:81/</A>$1 [R]
  -  
  -</PRE>
  -<P><A NAME="anchor158"></A>
  -the IP addresses are the addresses of the developer client machines (where
  -they are running their web browsers). I tried to use
  -<CODE>REMOTE_USER</CODE> since we have all the users authenticated but it did not work for me.
  -
  -<P><A NAME="anchor159"></A>
  -So if I have a relative URL written in some <EM>file.html</EM> like
  -<EM>/perl/test.pl</EM> or even <A
  -HREF="http://www.nowhere.com/perl/test.pl">http://www.nowhere.com/perl/test.pl</A>
  -(the user at the machine of <EM>sbekman</EM>) it will be redirected by httpd_docs to <A
  -HREF="http://www.nowhere.com:8000/perl/test.pl.">http://www.nowhere.com:8000/perl/test.pl.</A>
  -
  -
  -<P><A NAME="anchor160"></A>
  -There is another problem: the CGI script may generate some HTML code which
  -the client may then use to request further action from the server. If the
  -script generates a URL with a hard coded PORT, the above scheme will not
  -work. There two solutions:
  -
  -<P><A NAME="anchor161"></A>
  -First, generate relative URLs so it will reuse the technique above, with
  -redirect (which is transparent to the user). But this will not work if you
  -have something to <CODE>POST</CODE>, because the redirect loses all the data!
  -
  -<P><A NAME="anchor162"></A>
  -Second, use a general configuration module which generates a correct full
  -URL according to <CODE>REMOTE_USER</CODE>, so if <CODE>$ENV{REMOTE_USER} eq
  -'sbekman'</CODE>, I return <CODE>http://www.nowhere.com:8000/perl/</CODE> as
  -<CODE>cgi_base_url</CODE>. Again this will work if the user is authenticated.
  -
  -<P><A NAME="anchor163"></A>
  -All this is good for development. It is better to use the full URLs in
  -production, since if you have a static form and the <CODE>Action</CODE> is relative but the static document is located on another server, pressing
  -the form's submit will cause a redirect to the mod_perl server and all the
  -form's data will be lost during the redirect.
  -
  -<P><A NAME="anchor164"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<CENTER><H1><A NAME="Wrapper_to_Emulate_the_Server_En">Wrapper to Emulate the Server Environment</A></H1></CENTER>
  -<P><A NAME="anchor165"></A>
  +  RewriteCond  %{REQUEST_URI} ^/(perl|cgi-perl)
  +  RewriteRule ^(.*)           <A HREF="http://example.com:81/">http://example.com:81/</A>$1 [P]</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +The IP addresses are the addresses of the developer desktop machines (where
  +they are running their web browsers). So if an html file includes a a
  +relative URI <EM>/perl/test.pl</EM> or even <A
  +HREF="http://www.example.com/perl/test.pl">http://www.example.com/perl/test.pl</A>,
  +clicking on the link will be internally proxied to <A
  +HREF="http://www.example.com:8000/perl/test.pl">http://www.example.com:8000/perl/test.pl</A>
  +if the click has been made at the user stas's desktop machine, or to <A
  +HREF="http://www.example.com:8001/perl/test.pl">http://www.example.com:8001/perl/test.pl</A>
  +for a request generated from the user eric's machine, per our above URI
  +rewrite example.
  +
  +<P>
  +Another possibility is to use <CODE>REMOTE_USER</CODE> variable if all the developers are forced to authenticate themselves before
  +they can access the server. If you do, you will have to change the
  +<CODE>RewriteRule</CODE>s to match <CODE>REMOTE_USER</CODE> in the above example.
  +
  +<P>
  +We wish to stress again, that the above setup will work only with relative
  +URIs in the HTML code. If you choose to generate full URIs including non-80
  +port the requests originated from this HTML code will bypass the light
  +server listenting to the default port 80, and go directly to the
  +server:port of the full URI.
  +
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
  +<CENTER><H1><A NAME="Wrapper_to_Emulate_the_Server_Pe">Wrapper to Emulate the Server Perl Environment</A></H1></CENTER>
  +<P>
   Often you will start off debugging your script by running it from your
  -favorite shell. Sometimes you encounter a very weird situation when the
  -script runs from the shell but dies when called as a CGI script. The real
  -problem often lies in the difference between the environment that is used
  -by your server and the one used by your shell. For example you may have a
  -different Perl path, a <CODE>PERL5LIB</CODE> environment variable which includes paths that are not in the <CODE>@INC</CODE> array of the copy of Perl which is linked into the mod_perl server and
  -configured during startup.
  +favorite shell program. Sometimes you encounter a very weird situation when
  +the script runs from the shell but dies when processed as a CGI script by a
  +web-server. The real problem often lies in the difference between the
  +environment variables that is used by your web-server and the ones used by
  +your shell program.
  +
  +<P>
  +For example you may have a set of non-standard Perl directories, used for
  +local Perl modules. You have to tell the Perl interpreter where these
  +directories are. If you don't want to modify <CODE>@INC</CODE> in all scripts and modules, you can use a <CODE>PERL5LIB</CODE> environment variable, to tell Perl where the directories are. But then you
  +might forget to alter the mod_perl startup script to correct <CODE>@INC</CODE> there as well. And if you forget this, you can be quite puzzled why the
  +scripts are running from the shell program, but not from the web. 
  +
  +<P>
  +Of course the <EM>error_log</EM> will help as well to find out what the problem is, but there can be other
  +obscure cases, where you do something different at the shell program and
  +your scripts refuse to run under the web-server.
  +
  +<P>
  +Another example is when you have more than one version of Perl installed.
  +You might call the first version of the Perl executable in the first
  +script's line (the shebang line), but to have the web-server compiled with
  +another Perl version. Since mod_perl ignores the path to the Perl
  +executable at the first line of the script, you can get quite confused the
  +code won't do the same when processed as request, compared to be executed
  +from the command line. it will take a while before you realize that you
  +test the scripts from the shell program using the <EM>wrong</EM> Perl version.
   
  -<P><A NAME="anchor166"></A>
  +<P>
   The best debugging approach is to write a wrapper that emulates the exact
   environment of the server, first deleting environment variables like <CODE>PERL5LIB</CODE> and then calling the same perl binary that it is being used by the server.
   Next, set the environment identical to the server's by copying the Perl run
  -directives from the server startup and configuration files. This will also
  -allow you to remove completely the first line of the script, since mod_perl
  -skips it and the wrapper knows how to call the script.
  -
  -<P><A NAME="anchor167"></A>
  -Below is an example of such a script. Note that we force the use of
  -<CODE>-Tw</CODE> when we call the real script. I have also added the ability to pass
  -parameters, which will not happen when you call the CGI script from the
  -Web.
  +directives from the server startup and configuration files or even
  +<CODE>require()'ing</CODE> the startup file, if it doesn't include <A HREF="#item_Apache_">Apache::</A> modules stuff, unavailable under shell. This will also allow you to remove
  +completely the first line of the script, since mod_perl doesn't need it
  +anyway and the wrapper knows how to call the script.
  +
  +<P>
  +Here is an example of such a script. Note that we force the use of
  +<CODE>-Tw</CODE> when we call the real script. Since when debugging we want to make sure
  +that the code is working when the taint mode is on, and we want to see all
  +the warnings, to help Perl help us have a better code.
  +
  +<P>
  +We have also added the ability to pass parameters, which will not happen
  +when you will issue a request to script, but it can be helpful at times.
  +
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
   
  -<P><A NAME="anchor168"></A>
  -<PRE>  #!/usr/local/bin/perl -w    
  +	<td>
  +	  <pre>  #!/usr/bin/perl -w
      
  -  # This is a wrapper example 
  +  # This is a wrapper example
      
     # It simulates the web server environment by setting @INC and other
     # stuff, so what will run under this wrapper will run under Web and
  @@ -1053,21 +1910,15 @@
     #
     # Usage: wrap.pl some_cgi.pl
     #
  -  
     BEGIN {
  -    use vars qw($basedir);
  -    $basedir = &quot;/usr/local&quot;;
  -  
  -    # we want to make a complete emulation, 
  -    # so we must remove the user's environment
  -    @INC = ();
  -  
  -    # local perl libs
  -    push @INC,
  -      qw($basedir/lib/perl5/5.00502/aix
  -         $basedir/lib/perl5/5.00502
  -         $basedir/lib/perl5/site_perl/5.005/aix
  -         $basedir/lib/perl5/site_perl/5.005
  +    # we want to make a complete emulation, so we must reset all the
  +    # paths and add the standard Perl libs
  +    @INC =
  +      qw(/usr/lib/perl5/5.00503/i386-linux
  +         /usr/lib/perl5/5.00503
  +         /usr/lib/perl5/site_perl/5.005/i386-linux
  +         /usr/lib/perl5/site_perl/5.005
  +         .
           );
     }
     
  @@ -1094,36 +1945,95 @@
     
       # run the cgi from the script's directory
       # Note that we set Warning and Taint modes ON!!!
  -  system qq{$basedir/bin/perl -I$PERL5LIB -Tw $cgi $params};
  -</PRE>
  -<P><A NAME="anchor169"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<CENTER><H1><A NAME="Log_Rotation">Log Rotation</A></H1></CENTER>
  -<P><A NAME="anchor170"></A>
  -A little bit off topic, but useful to know and use with mod_perl where your
  -error_log can grow at 10-100Mb per day if your scripts spit out lots of
  -warnings...
  -
  -<P><A NAME="anchor171"></A>
  -To rotate the logs do this:
  -
  -<P><A NAME="anchor172"></A>
  -<PRE>  mv access_log access_log.renamed
  -  kill -HUP `cat httpd.pid`
  -  sleep 10; # allow some children to complete requests and logging
  -  # now it's safe to use access_log.renamed
  -  .....
  -</PRE>
  -<P><A NAME="anchor173"></A>
  -The effect of <STRONG>SIGUSR1</STRONG> and <STRONG>SIGHUP</STRONG> is detailed in: <A
  -HREF="http://www.apache.org/docs/stopping.html">http://www.apache.org/docs/stopping.html</A>
  -.
  +  system qq{/usr/bin/perl -I$PERL5LIB -Tw $cgi $params};</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
  +<CENTER><H1><A NAME="Server_Maintenance_Chores">Server Maintenance Chores</A></H1></CENTER>
  +<P>
  +It's not enough to have your server and service up and running. You have to
  +maintain the server even when everything seems to be fine. This includes
  +security auditing, keeping an eye on the size of remaining unused disk
  +space, available RAM, the load of the system, etc.
  +
  +<P>
  +If you forget about these chores one day (sooner or later) your system will
  +crash either because it has run out of free disk space, all the available
  +CPU has been used and system has started heavily to swap or someone has
  +broken in. Unfortunately the scope of this guide is not covering the
  +latter, since it will take more than one book to profoundly cover this
  +issue, but the rest of the thing are quite easy to prevent if you follow
  +our advices.
  +
  +<P>
  +Certaintly, your particular system might have maintainance chores that
  +aren't covered here, but at least you will be alerted that these chores are
  +real and should be taken care of.
  +
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
  +<CENTER><H2><A NAME="Handling_Log_Files">Handling Log Files</A></H2></CENTER>
  +<P>
  +There are two issues to solve with log files. First they should be rotated
  +and compressed on the constant basis, since they tend to use big parts of
  +the disk space over time. Second these should be monitored for possible
  +sudden explosive growth rates, when something goes astray in your code
  +running at the mod_perl server and the process starts to log thousands of
  +error messages in second without stopping, untill all the disk space is
  +used, and the server cannot work anymore.
   
  -<P><A NAME="anchor174"></A>
  -I use this script:
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
  +<CENTER><H3><A NAME="Log_Rotation">Log Rotation</A></H3></CENTER>
  +<P>
  +The first issue is solved by having a process run by crontab at certain
  +times (usually off hours, if this term is still valid in the Internet era)
  +and rotate the logs. The log rotation includes the current log file
  +renaming, server restart (which creates a fresh new log file), and renamed
  +file compression and/or moving it on a different disk.
  +
  +<P>
  +For example if we want to rotate the <EM>access_log</EM> file we could do:
  +
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  % mv access_log access_log.renamed
  +  % apachectl restart
  +  % sleep 5; # allow all children to complete requests and logging
  +             # now it's safe to use access_log.renamed
  +  % mv access_log.renamed /some/directory/on/another/disk</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +This is the script that we run from the crontab to rotate the log files:
  +
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
   
  -<P><A NAME="anchor175"></A>
  -<PRE>  #!/usr/local/bin/perl -Tw
  +	<td>
  +	  <pre>  #!/usr/local/bin/perl -Tw
     
     # This script does log rotation. Called from crontab.
     
  @@ -1140,7 +2050,7 @@
     
     my ($sec,$min,$hour,$mday,$mon,$year) = localtime(time);
     my $time = sprintf &quot;%0.4d.%0.2d.%0.2d-%0.2d.%0.2d.%0.2d&quot;, $year+1900,++$mon,$mday,$hour,$min,$sec;
  -  $^I = &quot;.&quot;.$time;
  +  $^I = &quot;.$time&quot;;
     
     # rename log files
     chdir $logs_dir;
  @@ -1152,231 +2062,351 @@
     # now restart the server so the logs will be restarted
     system $restart_command;
     
  -  # compress log files
  +  # allow all children to complete requests and logging
  +  sleep 5;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  # compress log files
     foreach (@logfiles) {
         system &quot;$gzip_exec $_.$time&quot;;
  -  }
  -</PRE>
  -<P><A NAME="anchor176"></A>
  +  }</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Note: Setting <CODE>$^I</CODE> sets the in-place edit flag to a dot followed by the time. We copy the
   names of the logfiles into <CODE>@ARGV</CODE>, and open each in turn and immediately close them without doing any
   changes; but because the in-place edit flag is set they are effectively
   renamed.
   
  -<P><A NAME="anchor177"></A>
  -Randal L. Schwartz contributed this:
  +<P>
  +As you see the rotated files will include the date and the time in their
  +filenames.
   
  -<BLOCKQUOTE>
  +<P>
  +Here is a more generic set of scripts for log rotation. Cron job fires off
  +setuid script called log-roller that looks like this:
   
  -<P><A NAME="anchor178"></A>
  -Cron fires off setuid script called log-roller that looks like this:
  +<P>
   
  -<P><A NAME="anchor179"></A>
  -<PRE>    #!/usr/bin/perl -Tw
  -    use strict;
  -    use File::Basename;
  -    
  -    $ENV{PATH} = &quot;/usr/ucb:/bin:/usr/bin&quot;;
  -    
  -    my $ROOT = &quot;/WWW/apache&quot;; # names are relative to this
  -    my $CONF = &quot;$ROOT/conf/httpd.conf&quot;; # master conf
  -    my $MIDNIGHT = &quot;MIDNIGHT&quot;;  # name of program in each logdir
  -    
  -    my ($user_id, $group_id, $pidfile); # will be set during parse of conf
  -    die &quot;not running as root&quot; if $&gt;;
  -    
  -    chdir $ROOT or die &quot;Cannot chdir $ROOT: $!&quot;;
  -    
  -    my %midnights;
  -    open CONF, &quot;&lt;$CONF&quot; or die &quot;Cannot open $CONF: $!&quot;;
  -    while (&lt;CONF&gt;) {
  -      if (/^User (\w+)/i) {
  -        $user_id = getpwnam($1);
  -        next;
  -      }
  -      if (/^Group (\w+)/i) {
  -        $group_id = getgrnam($1);
  -        next;
  -      }
  -      if (/^PidFile (.*)/i) {
  -        $pidfile = $1;
  -        next;
  -      }
  -     next unless /^ErrorLog (.*)/i;
  -      my $midnight = (dirname $1).&quot;/$MIDNIGHT&quot;;
  -      next unless -x $midnight;
  -      $midnights{$midnight}++;
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  #!/usr/bin/perl -Tw
  +  use strict;
  +  use File::Basename;
  +  
  +  $ENV{PATH} = &quot;/usr/ucb:/bin:/usr/bin&quot;;
  +  
  +  my $ROOT = &quot;/WWW/apache&quot;; # names are relative to this
  +  my $CONF = &quot;$ROOT/conf/httpd.conf&quot;; # master conf
  +  my $MIDNIGHT = &quot;MIDNIGHT&quot;;  # name of program in each logdir
  +  
  +  my ($user_id, $group_id, $pidfile); # will be set during parse of conf
  +  die &quot;not running as root&quot; if $&gt;;
  +  
  +  chdir $ROOT or die &quot;Cannot chdir $ROOT: $!&quot;;
  +  
  +  my %midnights;
  +  open CONF, &quot;&lt;$CONF&quot; or die &quot;Cannot open $CONF: $!&quot;;
  +  while (&lt;CONF&gt;) {
  +    if (/^User (\w+)/i) {
  +      $user_id = getpwnam($1);
  +      next;
       }
  -    close CONF;
  -    
  -    die &quot;missing User definition&quot; unless defined $user_id;
  -    die &quot;missing Group definition&quot; unless defined $group_id;
  -    die &quot;missing PidFile definition&quot; unless defined $pidfile;
  -    
  -    open PID, $pidfile or die &quot;Cannot open $pidfile: $!&quot;;
  -    &lt;PID&gt; =~ /(\d+)/;
  -    my $httpd_pid = $1;
  -    close PID;
  -    die &quot;missing pid definition&quot; unless defined $httpd_pid and $httpd_pid;
  -    kill 0, $httpd_pid or die &quot;cannot find pid $httpd_pid: $!&quot;;
  -    
  -    
  -    for (sort keys %midnights) {
  -      defined(my $pid = fork) or die &quot;cannot fork: $!&quot;;
  -      if ($pid) {
  -        ## parent:
  -        waitpid $pid, 0;
  -      } else {
  -        my $dir = dirname $_;
  -        ($(,$)) = ($group_id,$group_id);
  -        ($&lt;,$&gt;) = ($user_id,$user_id);
  -        chdir $dir or die &quot;cannot chdir $dir: $!&quot;;
  -        exec &quot;./$MIDNIGHT&quot;;
  -        die &quot;cannot exec $MIDNIGHT: $!&quot;;
  -      }
  +    if (/^Group (\w+)/i) {
  +      $group_id = getgrnam($1);
  +      next;
       }
  -    
  -    kill 1, $httpd_pid or die &quot;Cannot sighup $httpd_pid: $!&quot;;
  -</PRE>
  -<P><A NAME="anchor180"></A>
  -And then individual MIDNIGHT scripts can look like this:
  -
  -<P><A NAME="anchor181"></A>
  -<PRE>    #!/usr/bin/perl -Tw
  -    use strict;
  -    
  -    die &quot;bad guy&quot; unless getpwuid($&lt;) =~ /^(root|nobody)$/;
  -    my @LOGFILES = qw(access_log error_log);
  -    umask 0;
  -    $^I = &quot;.&quot;.time;
  -    @ARGV = @LOGFILES;
  -    while (&lt;&gt;) {
  -      close ARGV;
  +    if (/^PidFile (.*)/i) {
  +      $pidfile = $1;
  +      next;
       }
  -</PRE>
  -<P><A NAME="anchor182"></A>
  -Can you spot the security holes? Our trusted user base can't or won't. :)
  -But these shouldn't be used in hostile situations.
  +   next unless /^ErrorLog (.*)/i;
  +    my $midnight = (dirname $1).&quot;/$MIDNIGHT&quot;;
  +    next unless -x $midnight;
  +    $midnights{$midnight}++;
  +  }
  +  close CONF;
  +  
  +  die &quot;missing User definition&quot; unless defined $user_id;
  +  die &quot;missing Group definition&quot; unless defined $group_id;
  +  die &quot;missing PidFile definition&quot; unless defined $pidfile;
  +  
  +  open PID, $pidfile or die &quot;Cannot open $pidfile: $!&quot;;
  +  &lt;PID&gt; =~ /(\d+)/;
  +  my $httpd_pid = $1;
  +  close PID;
  +  die &quot;missing pid definition&quot; unless defined $httpd_pid and $httpd_pid;
  +  kill 0, $httpd_pid or die &quot;cannot find pid $httpd_pid: $!&quot;;
  +  
  +  
  +  for (sort keys %midnights) {
  +    defined(my $pid = fork) or die &quot;cannot fork: $!&quot;;
  +    if ($pid) {
  +      ## parent:
  +      waitpid $pid, 0;
  +    } else {
  +      my $dir = dirname $_;
  +      ($(,$)) = ($group_id,$group_id);
  +      ($&lt;,$&gt;) = ($user_id,$user_id);
  +      chdir $dir or die &quot;cannot chdir $dir: $!&quot;;
  +      exec &quot;./$MIDNIGHT&quot;;
  +      die &quot;cannot exec $MIDNIGHT: $!&quot;;
  +    }
  +  }
  +  
  +  kill 1, $httpd_pid or die &quot;Cannot SIGHUP $httpd_pid: $!&quot;;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +And then individual <CODE>MIDNIGHT</CODE> scripts can look like this:
  +
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
   
  -</BLOCKQUOTE>
  +	<td>
  +	  <pre>  #!/usr/bin/perl -Tw
  +  use strict;
  +  
  +  die &quot;bad guy&quot; unless getpwuid($&lt;) =~ /^(root|nobody)$/;
  +  my @LOGFILES = qw(access_log error_log);
  +  umask 0;
  +  $^I = &quot;.&quot;.time;
  +  @ARGV = @LOGFILES;
  +  while (&lt;&gt;) {
  +    close ARGV;
  +  }</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +Can you spot the security holes? Take your time... This code shouldn't be
  +used in hostile situations.
   
  -<P><A NAME="anchor183"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
  +<CENTER><H3><A NAME="Non_Scheduled_Emergency_Log_Rota">Non-Scheduled Emergency Log Rotation</A></H3></CENTER>
  +<P>
  +As we have mentioned before, there are times when the web server goes wild
  +and starts to log lots of messages to the <EM>error_log</EM> file non-stop. If no one monitors this, it possible that in a few minutes
  +all the free disk spaces will be filled and no process will be able to work
  +normally. When this happens, the I/O the faulty server causes is so heavy
  +that its sibling processes cannot serve requests.
  +
  +<P>
  +Generally this not the case, but a few people have reported to encounter
  +this problem. If you are one of these people, you should run the monitoring
  +program that checks the log file size and if it notices that the file has
  +grown too large, it should attempt to restart the server and probably trim
  +the log file.
  +
  +<P>
  +When we have used a quite old mod_perl version, sometimes we have had
  +bursts of an error <EM>Callback called exit</EM> showing up in our
  +<EM>error_log</EM>. The file could grow to 300 Mbytes in a few minutes.
  +
  +<P>
  +We will show you is an example of the script that should be executed from
  +the crontab, to handle the situations like this. The cron job should run
  +every few minutes or even every minute, since if you experience this
  +problem you know that log files fills up very fast. The example script will
  +rotate when the <EM>error_log</EM> will grow over 100K. Note that this script is usefull when you have the
  +normal scheduled log rotation facility working, remember that this one is
  +an emergency solver and not to be used for routine log rotation.
  +
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  emergency_rotate.sh
  +  -------------------
  +  #!/bin/sh
  +  S=`ls -s /usr/local/apache/logs/error_log | awk '{print $1}'`
  +  if [ &quot;$S&quot; -gt 100000 ] ; then
  +    mv /usr/local/apache/logs/error_log /usr/local/apache/logs/error_log.old
  +    /etc/rc.d/init.d/httpd restart
  +    date | /bin/mail -s &quot;error_log $S kB on inx&quot; admin@example.com
  +  fi</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +Of course you could write a more advanced script, using the timestamps and
  +other whistles. This example comes to illustrate how to solve the problem
  +in question.
  +
  +<P>
  +Another solution is to use an out of box tools that are written for this
  +purpose. The <CODE>daemontools</CODE> package (ftp://koobera.math.uic.edu/www/daemontools.html) includes a
  +utility called <CODE>multilog</CODE>. This utility saves stdin stream to one or more log files. It optionally
  +timestamps each line and, for each log, includes or excludes lines matching
  +specified patterns. It automatically rotates logs to limit the amount of
  +disk space used. If the disk fills up, it pauses and tries again, without
  +losing any data.
  +
  +<P>
  +The obvious caveat is that it doesn't restart the server, so while it tries
  +to solve the log file handling problem it doesn't handle the originator of
  +the problem. But since the I/O of the log writing process Apache process
  +will be quite heavy, the rest of the servers will work very slowly if at
  +all, and a normal watchdog should detect this abnormal situation and
  +restart the Apache server.
  +
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H1><A NAME="Preventing_mod_perl_Processes_Fr">Preventing mod_perl Processes From Going Wild</A></H1></CENTER>
  -<P><A NAME="anchor184"></A>
  +<P>
   Sometimes people report that they had a problem with their code running
   under mod_perl that has caused all the RAM or all the disk to be used. The
   following tips should help you prevent these problems, before if at all
   they hit you.
   
  -<P><A NAME="anchor185"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="All_RAM_Consumed">All RAM Consumed</A></H2></CENTER>
  -<P><A NAME="anchor186"></A>
  +<P>
   Sometimes calling an undefined subroutine in a module can cause a tight
   loop that consumes all the available memory. Here is a way to catch such
   errors. Define an autoload subroutine:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor187"></A>
  -<PRE>  sub UNIVERSAL::AUTOLOAD {
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  sub UNIVERSAL::AUTOLOAD {
       my $class = shift;
       warn &quot;$class can't \$UNIVERSAL::AUTOLOAD!\n&quot;;
  -  }
  -</PRE>
  -<P><A NAME="anchor188"></A>
  +  }</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   This will produce a nice error in error_log, giving the line number of the
   call and the name of the undefined subroutine.
  -
  -<P><A NAME="anchor189"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<CENTER><H2><A NAME="All_Disk_Space_Consumed">All Disk Space Consumed</A></H2></CENTER>
  -<P><A NAME="anchor190"></A>
  -Sometimes an error happens and causes the server to write millions of lines
  -into your <EM>error_log</EM> file and in a few minutes this will bring your server to its knees due to
  -lack of disk space. For example sometimes I get bursts of an error <CODE>Callback called exit</CODE> showing up in my <EM>error_log</EM>. The file grows to 300 Mbytes in a few minutes. You should run a cron job
  -to make sure this does not happen, and if it does to take care of it.
  -Andreas J. Koenig runs this shell script every minute:
   
  -<P><A NAME="anchor191"></A>
  -<PRE>  S=`ls -s /usr/local/apache/logs/error_log | awk '{print $1}'`
  -  if [ &quot;$S&quot; -gt 100000 ] ; then
  -    mv  /usr/local/apache/logs/error_log /usr/local/apache/logs/error_log.old
  -    /etc/rc.d/init.d/httpd restart
  -    date | /bin/mail -s &quot;error_log $S kB on inx&quot; myemail@domain.com
  -  fi
  -</PRE>
  -<P><A NAME="anchor192"></A>
  -On my server I run a watchdog every five minutes which restarts the server
  -if it gets stuck. It always works since when some mod_perl child process
  -goes wild, the I/O it causes is so heavy that its sibling processes cannot
  -serve requests. See <A HREF="././control.html#Monitoring_the_Server_A_watchdo">Monitoring the Server</A> for more hints.
  -
  -<P><A NAME="anchor193"></A>
  -Also check out the daemontools from <A
  -HREF="ftp://koobera.math.uic.edu/www/daemontools.html">ftp://koobera.math.uic.edu/www/daemontools.html</A>
  -:
  -
  -<P><A NAME="anchor194"></A>
  -<PRE>  ,-----
  -  | cyclog writes a log to disk.  It automatically synchronizes the log
  -  | every 100KB (by default) to guarantee data integrity after a crash.
  -  | It automatically rotates the log to keep it below 1MB (by default).
  -  | If the disk fills up, cyclog pauses and then tries again, without
  -  | losing any data.
  -  `-----
  -</PRE>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -	     The <a href="http://www.modperl.com/">
  -	     <B>Writing Apache Modules with Perl and C</B></a>
  -	     book can be purchased online from <a
  -	     href="http://www.ora.com/catalog/wrapmod/">O'Reilly </a>
  -	     and <a
  -	     href="http://www.amazon.com/exec/obidos/ASIN/156592567X/writinapachemodu">
  -	     Amazon.com</a>.
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   
  -	     <HR>
   
  -	     <B>Your corrections of either technical or grammatical
  +    <p>
  +    <div class="navbar">
  +      <a href="config.html">Prev</a>                                 |
  +      <A HREF="index.html"         >Contents</A> |
  +      <A HREF="index.html#search"  >Search</A>   |
  +      <A HREF="index.html#download">Download</A> |
  +      <a href="strategy.html">Next</a>
  +    </div>
  +    <p>
  +
  +    <table width="60%" align="center">
  +
  +      <tr>
  +	<td>
  +	  <div class="notice">
  +	  <B>Your corrections of the technical and grammatical
   	     errors are very welcome. You are encouraged to help me
  -	     to improve this guide.  If you have something to
  -	     contribute please <A
  -	     HREF="help.html#Contacting_me"> send it
  +	     improve this guide.  If you have something to contribute
  +	     please <A HREF="help.html#Contacting_me"> send it
   	     directly to me</A>.</B>
  +	  </div>
  +	</td>
  +      </tr>
  +
  +      <tr>
  +	<td>
  +	  <div class="ad">
  +	    The <a href="http://www.modperl.com/">
  +	      <B>Writing Apache Modules with Perl and C</B></a>
  +	    book can be purchased online from <a
  +	      href="http://www.ora.com/catalog/wrapmod/">O'Reilly </a>
  +	    and <a
  +	    href="http://www.amazon.com/exec/obidos/ASIN/156592567X/writinapachemodu">
  +	      Amazon.com</a>.
  +	  </div>
  +	</td>
  +      </tr>
  +
  +</table>
  +
  +<center>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
  +<table cellspacing=2 cellpadding=2>
  +
  +<tr align=center valign=top>
  +<td align=center valign=center>
  +
  +<b><font size=-1>Written by <a
  +href="help.html#Contacting_me">Stas Bekman</a>.<br> Last Modified at 05/27/2000
  +</font></b>
  +<br>
  +
  +</td>
  +
  +<td>
  +
  +<a href="http://perl.apache.org"><img src="images/mod_perl2.jpg"  border=0 alt="mod_perl icon" border=0 height=59 width=150></a>
  +<br>
  +
  +</td>
  +
  +<td>
  +
  +<font size=-2>Use of the Camel for Perl is <br>
  +a trademark of <a href="http://www.ora.com">O'Reilly &amp; Associates</a>,<br>
  +and is used by permission. </font> 
  +<br>
   
  -	     <HR>
  +</td>
   
  -	     [    <A HREF="config.html">Prev</A> |      <A HREF="index.html">Main Page</A> | <A HREF="strategy.html">Next</A>      ]
  +</tr>
  +</table>
  +</center>
   
  -<CENTER><TABLE CELLSPACING=2 CELLPADDING=2 WIDTH="100%" >
  -<TR ALIGN=CENTER VALIGN=TOP>
  -  <TD ALIGN=CENTER VALIGN=CENTER COLSPAN="3">
  -	     <HR>
  -  </TD>
  -</TR>
  -<TR ALIGN=CENTER VALIGN=TOP>
  -  <TD ALIGN=CENTER VALIGN=CENTER>
  -    <B>
  -      <FONT SIZE=-1>
  -	     Written by <A HREF="help.html#Contacting_me">Stas Bekman</A>.
  -	     <BR>Last Modified at 05/09/2000
  -      </FONT>
  -    </B>
  -  </TD>
  -
  -  <TD>
  -	     <A HREF="http://perl.apache.org"><IMG SRC="images/mod_perl2.jpg" ALT="Mod Perl Icon" BORDER=0 HEIGHT=59 WIDTH=150></A>
  -  </TD>
  -
  -  <TD>
  -    <FONT SIZE=-2>
  -	     Use of the Camel for Perl is <BR>
  -	     a trademark of <A HREF="http://www.ora.com">O'Reilly &amp; Associates</A>,<BR>
  -             and is used by permission. 
  -    </FONT> 
  -  </TD>
  -</TR>
  -</TABLE></CENTER>
  -
  -</BODY>
  -</HTML>
  -	    
  \ No newline at end of file
  +</body>
  +</html>
  
  
  
  1.9       +816 -349  modperl-site/guide/correct_headers.html
  
  Index: correct_headers.html
  ===================================================================
  RCS file: /home/cvs/modperl-site/guide/correct_headers.html,v
  retrieving revision 1.8
  retrieving revision 1.9
  diff -u -r1.8 -r1.9
  --- correct_headers.html	2000/06/07 22:39:41	1.8
  +++ correct_headers.html	2000/06/07 22:45:30	1.9
  @@ -1,31 +1,40 @@
   <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
  -<HTML>
  -<HEAD>
  -   <TITLE>mod_perl guide: Correct Headers - A quick guide for mod_perl users</TITLE>
  -   <META NAME="GENERATOR" CONTENT="Pod2HTML [Perl/Linux]">
  -   <META NAME="Author" CONTENT="Stas Bekman">
  -   <META NAME="Description" CONTENT="All Apache/Perl related information: Hints, Guidelines, Scenarios and Troubleshottings">
  -   <META NAME="keywords" CONTENT="mod_perl modperl perl apache cgi webserver speed  fast guide mod_perl apache guide help info faq mod_perl installation cgi troubleshooting help no sex speedup free open source OSS mod_perl apache guide">
  -</HEAD>
  -     <LINK REL=STYLESHEET TYPE="text/css"
  -        HREF="style.css" TITLE="refstyle">
  -     <style type="text/css">
  -     <!-- 
  -        @import url(style.css);
  -     -->
  -     
  -     </style>
  -<BODY BGCOLOR="white">
  +<html>
  +  <head>
  +   <title>mod_perl guide: Correct Headers - A quick guide for mod_perl users</title>
  +   <meta name="Author" content="Stas Bekman">
  +   <meta name="Description" content="All Apache/Perl related information: Hints, Guidelines, Scenarios and Troubleshottings">
  +   <meta name="keywords" content="mod_perl modperl perl cgi apache webserver speed fast guide mod_perl apache guide help info faq mod_perl installation cgi troubleshooting help no sex speedup free open source OSS mod_perl apache guide">
  +   <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
  +   <meta name="Classification" content="information">
  +   <link href="style.css" rel=stylesheet type="text/css" title="refstyle">
  +  </head>
  +  <body>
  +
  +    <h1 align=center>
  +      <a href="http://perl.apache.org"><img src="images/mod_perl.gif" alt="Mod Perl Icon" border=0 height=30 width=90 align=left></a>
  +      <a href="http://perl.apache.org"><img src="images/mod_perl.gif" alt="Mod Perl Icon" border=0 height=30 width=90 align=right></a>
  +      Correct Headers - A quick guide for mod_perl users
  +    </h1>
  +    <hr>
  +    <p>
  +    <div class="navbar">
  +      <a href="troubleshooting.html">Prev</a>                                 |
  +      <a href="index.html"         >Contents</a> |
  +      <a href="index.html#search"  >Search</a>   |
  +      <a href="index.html#download">Download</a> |
  +      <a href="security.html">Next</a>
  +    </div>
  +    <p>
  +
  +    <div class="toc">
  +      
   <A NAME="toc"></A>
  -<H1 ALIGN=CENTER>
  -<A HREF="http://perl.apache.org"><IMG SRC="images/mod_perl.gif" ALT="Mod Perl Icon" BORDER=0 HEIGHT=30 WIDTH=90 ALIGN=LEFT></A>
  -<A HREF="http://perl.apache.org"><IMG SRC="images/mod_perl.gif" ALT="Mod Perl Icon" BORDER=0 HEIGHT=30 WIDTH=90 ALIGN=RIGHT></A>
  -Correct Headers - A quick guide for mod_perl users</H1>
  -<HR WIDTH="100%">
  -	    [    <A HREF="troubleshooting.html">Prev</A> |      <A HREF="index.html">Main Page</A> | <A HREF="security.html">Next</A>      ]<HR><!-- INDEX BEGIN -->
  -<P><B><FONT SIZE=-1>Table of Contents:</FONT></B></P>
  +<P><B>Table of Contents:</B></P>
  +
   <UL>
   
  +	<LI><A HREF="#Correct_Headers_A_quick_guide_">Correct Headers - A quick guide for mod_perl users</A>
   	<LI><A HREF="#SYNOPSIS">SYNOPSIS</A>
   	<LI><A HREF="#The_origin_of_this_chapter">The origin of this chapter</A>
   	<LI><A HREF="#DESCRIPTION">DESCRIPTION</A>
  @@ -68,58 +77,81 @@
   	<LI><A HREF="#VERSION">VERSION</A>
   	<LI><A HREF="#AUTHOR">AUTHOR</A>
   </UL>
  -<!-- INDEX END -->
   
  +    </div>
  +
  +    [ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
   <HR>
  +    <table width="60%" align="center">
   
  -	     The <a href="http://www.modperl.com/">
  -	     <B>Writing Apache Modules with Perl and C</B></a>
  -	     book can be purchased online from <a
  -	     href="http://www.ora.com/catalog/wrapmod/">O'Reilly </a>
  -	     and <a
  -	     href="http://www.amazon.com/exec/obidos/ASIN/156592567X/writinapachemodu">
  -	     Amazon.com</a>.
  -
  -	     <HR>
  -
  -	       <B>Your corrections of either technical or grammatical
  -	       errors are very welcome. You are encouraged to help me
  -	       to improve this guide.  If you have something to
  -	       contribute please <A
  -	       HREF="help.html#Contacting_me"> send it
  -	       directly to me</A>.
  -	       </B>
  -	       <HR>
  +      <tr>
  +	<td>
  +	  <div class="ad">
  +	    The <a href="http://www.modperl.com/">
  +	      <B>Writing Apache Modules with Perl and C</B></a>
  +	    book can be purchased online from <a
  +	      href="http://www.ora.com/catalog/wrapmod/">O'Reilly </a>
  +	    and <a
  +	    href="http://www.amazon.com/exec/obidos/ASIN/156592567X/writinapachemodu">
  +	      Amazon.com</a>.
  +	  </div>
  +	</td>
  +      </tr>
  +
  +      <tr>
  +	<td>
  +	  <div class="notice">
  +	  <B>Your corrections of the technical and grammatical
  +	     errors are very welcome. You are encouraged to help me
  +	     improve this guide.  If you have something to contribute
  +	     please <A HREF="help.html#Contacting_me"> send it
  +	     directly to me</A>.</B>
  +	  </div>
  +	</td>
  +      </tr>
  +
  +</table>
  +
  +    
  +
  +	    [ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   
  -	      <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<P><A NAME="anchor0"></A>
  +<P>
  +<CENTER><H1><A NAME="Correct_Headers_A_quick_guide_">Correct Headers - A quick guide for mod_perl users</A></H1></CENTER>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H1><A NAME="SYNOPSIS">SYNOPSIS</A></H1></CENTER>
  -<P><A NAME="anchor1"></A>
  +<P>
   As there is always more than one way to do it, I'm tempted to believe one
   must be the best. Hardly ever am I right.
   
  -<P><A NAME="anchor2"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H1><A NAME="The_origin_of_this_chapter">The origin of this chapter</A></H1></CENTER>
  -<P><A NAME="anchor3"></A>
  +<P>
   This chapter has been contributed to the Guide by Andreas Koenig. You will
   find the references and other related info at the bottom of this page. I'll
   try to keep it up to date with the Master version which resides on CPAN. If
   in doubt -- always check the CPAN for
   <CODE>Apache::correct_headers</CODE>.
   
  -<P><A NAME="anchor4"></A>
  +<P>
   If you have any questions regarding this specific document only, please
   refer to Andreas, since he is the guru on this subject. On any other matter
   please contact the mod_perl mailing list.
   
  -<P><A NAME="anchor5"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H1><A NAME="DESCRIPTION">DESCRIPTION</A></H1></CENTER>
  -<P><A NAME="anchor6"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H1><A NAME="1_Why_headers">1) Why headers</A></H1></CENTER>
  -<P><A NAME="anchor7"></A>
  +<P>
   Dynamic Content is dynamic, after all, so why would anybody care about HTTP
   headers? Header composition is a task often neglected in the CGI world.
   Because pages are generated dynamically, you might expect that pages
  @@ -129,11 +161,11 @@
   entirely driven by dynamic components and the number of hits is
   significant.
   
  -<P><A NAME="anchor8"></A>
  +<P>
   If the number of hits is not significant, don't bother to read this
   document.
   
  -<P><A NAME="anchor9"></A>
  +<P>
   If the number of hits is significant, you might want to consider what
   cache-friendliness means (you may also want to read
   <A HREF="././correct_headers.html#_4_">[4]</A>) and how you can cooperate with caches to increase the performace of your
  @@ -142,52 +174,80 @@
   <A HREF="././correct_headers.html#_1_">[1]</A>), you will have a strong motivation to cooperate with it. This document
   may help you to do it correctly.
   
  -<P><A NAME="anchor10"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H1><A NAME="2_Which_Headers">2) Which Headers</A></H1></CENTER>
  -<P><A NAME="anchor11"></A>
  +<P>
   The HTTP standard (v 1.1 is specified in <A HREF="././correct_headers.html#_3_">[3]</A>, v 1.0 in <A HREF="././correct_headers.html#_2_">[2]</A>) describes lots of headers. In this document, we only discuss those
   headers which are most relevant to caching.
   
  -<P><A NAME="anchor12"></A>
  +<P>
   I have grouped the headers into three groups: date headers, content
   headers, and the special Vary header.
   
  -<P><A NAME="anchor13"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="2_1_Date_related_headers">2.1) Date related headers</A></H2></CENTER>
  -<P><A NAME="anchor14"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="2_1_1_Date">2.1.1) Date</A></H2></CENTER>
  -<P><A NAME="anchor15"></A>
  +<P>
   Section 14.18 of the HTTP standard deals with the circumstances under which
   you must or must not send a <CODE>Date</CODE> header. For almost everything a normal mod_perl user is doing, a <CODE>Date</CODE> header needs to be generated. But the mod_perl programmer doesn't have to
   worry about this header since the Apache server guarantees that this header
   is sent.
   
  -<P><A NAME="anchor16"></A>
  +<P>
   In <CODE>http_protocol.c</CODE> the <CODE>Date</CODE> header is set according to
   <CODE>$r-&gt;request_time</CODE>. A mod_perl script can read, but not change,
   <CODE>$r-&gt;request_time</CODE>.
   
  -<P><A NAME="anchor17"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="2_1_2_Last_Modified">2.1.2) Last-Modified</A></H2></CENTER>
  -<P><A NAME="anchor18"></A>
  +<P>
   Section 14.29 of the HTTP standard deals with this. The
   <CODE>Last-Modified</CODE> header is mostly used as a so-called weak validator. Here are two sentences
   from the HTTP specs:
   
  -<P><A NAME="anchor19"></A>
  -<PRE>  A validator that does not always change when the resource
  -  changes is a &quot;weak validator.&quot;
  -</PRE>
  -<P><A NAME="anchor20"></A>
  -<PRE>  One can think of a strong validator as one that changes
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  A validator that does not always change when the resource
  +  changes is a &quot;weak validator.&quot;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  One can think of a strong validator as one that changes
     whenever the bits of an entity changes, while a weak value
  -  changes whenever the meaning of an entity changes.
  -</PRE>
  -<P><A NAME="anchor21"></A>
  +  changes whenever the meaning of an entity changes.</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   This tells us that we should consider the semantics of the page we are
   generating and not the date when we are running. The question is, when did
   the <STRONG>meaning</STRONG> of this page change last time? Let's imagine the document in question is a
  @@ -196,46 +256,59 @@
   created on-the-fly, the semantics of the page are determined when the
   script was last changed, right?
   
  -<P><A NAME="anchor22"></A>
  +<P>
   Actually, a few more things are relevant: the semantics also change a
   little when you update one of the fonts that may be used or when you update
   your <CODE>ImageMagick</CODE> or equivalent program. It's something you should consider, if you want to
   get it right.
   
  -<P><A NAME="anchor23"></A>
  +<P>
   If you have a page which comprises several components, you should ask all
   the components when they changed their semantic behaviour last time. Then
   pick the oldest of those times.
   
  -<P><A NAME="anchor24"></A>
  +<P>
   mod_perl offers you two convenient methods to deal with this header:
   <CODE>update_mtime()</CODE> and <CODE>set_last_modified().</CODE> These
   methods and several others are unavailable in the normal mod_perl
   environment but are silently imported when you use <CODE>Apache::File</CODE>. Refer to the
   <CODE>Apache::File</CODE> manpage for more info.
   
  -<P><A NAME="anchor25"></A>
  +<P>
   <CODE>update_mtime()</CODE> takes a UNIX time as its argument and sets
   Apache's request structure finfo.st_mtime to this value. It does so only
   when the argument is greater than a previously stored <CODE>finfo.st_mtime</CODE>.
   
  -<P><A NAME="anchor26"></A>
  +<P>
   <CODE>set_last_modified()</CODE> sets the outgoing header <CODE>Last-Modified</CODE> to the string that corresponds to the stored finfo.st_mtime. By passing a
   UNIX time to <CODE>set_last_modified(),</CODE> mod_perl calls
   <CODE>update_mtime()</CODE> with this argument first.
  +
  +<P>
   
  -<P><A NAME="anchor27"></A>
  -<PRE>  use Apache::File;
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  use Apache::File;
     use Date::Parse;
     # Date::Parse parses RCS format, Apache::Util::parsedate doesn't
     $Mtime ||=
  -    Date::Parse::str2time(substr q$Date: 2000/06/07 22:39:41 $, 6);
  -  $r-&gt;set_last_modified($Mtime);
  -</PRE>
  -<P><A NAME="anchor28"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +    Date::Parse::str2time(substr q$Date: 2000/06/07 22:45:30 $, 6);
  +  $r-&gt;set_last_modified($Mtime);</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="2_1_3_Expires_and_Cache_Control">2.1.3) Expires and Cache-Control</A></H2></CENTER>
  -<P><A NAME="anchor29"></A>
  +<P>
   Section 14.21 of the HTTP standard deals with the <CODE>Expires</CODE>
   header. The purpose of the <CODE>Expires</CODE> header is to determine a point in time after which the document should be
   considered out of date (stale). Don't confuse this with the very different
  @@ -243,13 +316,25 @@
   <CODE>Last-Modified</CODE> header. The <CODE>Expires</CODE> header is useful to avoid unnecessary validation from now on until the
   document expires and it helps the recipients to clean up their stored
   documents. A sentence from the HTTP standard:
  +
  +<P>
   
  -<P><A NAME="anchor30"></A>
  -<PRE>  The presence of an Expires field does not imply that the
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  The presence of an Expires field does not imply that the
     original resource will change or cease to exist at, before, or
  -  after that time.
  -</PRE>
  -<P><A NAME="anchor31"></A>
  +  after that time.</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   So think before you set up a time when you believe a resource should be
   regarded as stale. Most of the time I can determine an expected lifetime
   from ``now'', that is the time of the request. I would not recommend
  @@ -257,158 +342,282 @@
   the date arrives, you will serve ``already expired'' documents that cannot
   be cached at all by anybody. If you believe a resource will never expire,
   read this quote from the HTTP specs:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor32"></A>
  -<PRE>  To mark a response as &quot;never expires,&quot; an origin server sends an
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  To mark a response as &quot;never expires,&quot; an origin server sends an
     Expires date approximately one year from the time the response is
     sent.  HTTP/1.1 servers SHOULD NOT send Expires dates more than one
  -  year in the future.
  -</PRE>
  -<P><A NAME="anchor33"></A>
  +  year in the future.</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Now the code for the mod_perl programmer who wants to expire a document
   half a year from now:
  +
  +<P>
   
  -<P><A NAME="anchor34"></A>
  -<PRE>  $r-&gt;header_out('Expires',
  -                 HTTP::Date::time2str(time + 180*24*60*60));
  -</PRE>
  -<P><A NAME="anchor35"></A>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  $r-&gt;header_out('Expires',
  +                 HTTP::Date::time2str(time + 180*24*60*60));</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   A very handy alternative to this computation is available in HTTP 1.1, the
   cache control mechanism. Instead of setting the <CODE>Expires</CODE> header you can specify a delta value in a <CODE>Cache-Control</CODE> header. You can do that by executing just:
  +
  +<P>
   
  -<P><A NAME="anchor36"></A>
  -<PRE>  $r-&gt;header_out('Cache-Control', &quot;max-age=&quot; . 180*24*60*60);
  -</PRE>
  -<P><A NAME="anchor37"></A>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  $r-&gt;header_out('Cache-Control', &quot;max-age=&quot; . 180*24*60*60);</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   which is, of course much cheaper than the first example because perl
   computes the value only once at compile time and optimizes it into a
   constant.
   
  -<P><A NAME="anchor38"></A>
  +<P>
   As this alternative is only available in HTTP 1.1 and old cache servers may
   not understand this header, it is advisable to send both headers. In this
   case the <CODE>Cache-Control</CODE> header takes precedence, so the <CODE>Expires</CODE> header is ignored on HTTP 1.1 compliant servers. Or you could go with an
   if/else clause:
  +
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
   
  -<P><A NAME="anchor39"></A>
  -<PRE>  if ($r-&gt;protocol =~ /(\d\.\d)/ &amp;&amp; $1 &gt;= 1.1){
  +	<td>
  +	  <pre>  if ($r-&gt;protocol =~ /(\d\.\d)/ &amp;&amp; $1 &gt;= 1.1){
       $r-&gt;header_out('Cache-Control', &quot;max-age=&quot; . 180*24*60*60);
     } else {
       $r-&gt;header_out('Expires',
                      HTTP::Date::time2str(time + 180*24*60*60));
  -  }
  -</PRE>
  -<P><A NAME="anchor40"></A>
  +  }</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   If you restart your Apache server regularly, I'd save the <CODE>Expires</CODE>
   header in a global variable. Oh, well, this is probably over-engineered
   now.
   
  -<P><A NAME="anchor41"></A>
  +<P>
   If people are determined that their document shouldn't be cached, here is
   the easy way to set a suitable <CODE>Expires</CODE> header...
   
  -<P><A NAME="anchor42"></A>
  +<P>
   The call <CODE>$r-&gt;no_cache(1)</CODE> will cause Apache to generate an
   <CODE>Expires</CODE> header with the same content as the Date-header in the response, so that
   the document ``expires immediately''. Don't set
   <CODE>Expires</CODE> with <CODE>$r-&gt;header_out</CODE> if you use <CODE>$r-&gt;no_cache</CODE>, because header_out takes precedence. The problem that remains is that
   there are broken browsers which ignore <CODE>Expires</CODE> headers.
   
  -<P><A NAME="anchor43"></A>
  +<P>
   Currently (mod_perl v1.22?) to avoid caching altogether:
  +
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
   
  -<P><A NAME="anchor44"></A>
  -<PRE>  my $headers = $r-&gt;headers_out;
  +	<td>
  +	  <pre>  my $headers = $r-&gt;headers_out;
     $headers-&gt;{'Pragma'} = $headers-&gt;{'Cache-control'} = 'no-cache';
  -  $r-&gt;no_cache(1);
  -</PRE>
  -<P><A NAME="anchor45"></A>
  +  $r-&gt;no_cache(1);</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   works with the major browsers.
   
  -<P><A NAME="anchor46"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="2_2_Content_related_headers">2.2) Content related headers</A></H2></CENTER>
  -<P><A NAME="anchor47"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="2_2_1_Content_Type">2.2.1) Content-Type</A></H2></CENTER>
  -<P><A NAME="anchor48"></A>
  +<P>
   You are most probably familiar with <CODE>Content-Type</CODE>. Sections 3.7, 7.2.1 and 14.17 of the HTTP specs cover the details.
   mod_perl has the
   <CODE>content_type()</CODE> method to deal with this header, for example:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor49"></A>
  -<PRE>  $r-&gt;content_type(&quot;image/png&quot;);
  -</PRE>
  -<P><A NAME="anchor50"></A>
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  $r-&gt;content_type(&quot;image/png&quot;);</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   <CODE>Content-Type</CODE>  <EM>should</EM> be included in all messages according to the specs, and Apache will
   generate one if you don't. It will be whatever is specified in the relevant <CODE>DefaultType</CODE> configuration directive or
   <CODE>text/plain</CODE> if none is active.
   
  -<P><A NAME="anchor51"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="2_2_2_Content_Length">2.2.2) Content-Length</A></H2></CENTER>
  -<P><A NAME="anchor52"></A>
  +<P>
   According to section 14.13 of the HTTP specifications, the
   <CODE>Content-Length</CODE> header is the number of octets in the body of a message. If it can be
   determined prior to sending, it can be very useful for several reasons to
   include it. The most important reason why it is good to include it is that
   keepalive requests only work with responses that contain a <CODE>Content-Length</CODE> header. In mod_perl you can say
  +
  +<P>
   
  -<P><A NAME="anchor53"></A>
  -<PRE>  $r-&gt;header_out('Content-Length', $length);
  -</PRE>
  -<P><A NAME="anchor54"></A>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  $r-&gt;header_out('Content-Length', $length);</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   If you use <CODE>Apache::File</CODE>, you get the additional
   <CODE>set_content_length()</CODE> method for the Apache class which is a bit more efficient than the above.
   You can then say:
  +
  +<P>
   
  -<P><A NAME="anchor55"></A>
  -<PRE>  $r-&gt;set_content_length($length);
  -</PRE>
  -<P><A NAME="anchor56"></A>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  $r-&gt;set_content_length($length);</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   The <CODE>Content-Length</CODE> header can have an important impact on caches by invalidating cache entries
   as the following extract from the specification explains:
  +
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
   
  -<P><A NAME="anchor57"></A>
  -<PRE>  The response to a HEAD request MAY be cacheable in the sense that
  +	<td>
  +	  <pre>  The response to a HEAD request MAY be cacheable in the sense that
     the information contained in the response MAY be used to update a
     previously cached entity from that resource.  If the new field values
     indicate that the cached entity differs from the current entity (as
     would be indicated by a change in Content-Length, Content-MD5, ETag
     or Last-Modified), then the cache MUST treat the cache entry as
  -  stale.
  -</PRE>
  -<P><A NAME="anchor58"></A>
  +  stale.</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   So be careful never to send a wrong <CODE>Content-Length</CODE>, either in a GET or in a HEAD request.
   
  -<P><A NAME="anchor59"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="2_2_3_Entity_Tags">2.2.3) Entity Tags</A></H2></CENTER>
  -<P><A NAME="anchor60"></A>
  +<P>
   An <CODE>Entity Tag</CODE> is a validator which can be used instead of, or in addition to, the <CODE>Last-Modified</CODE> header. An entity tag is a quoted string which can be used to identify
   different versions of a particular resource. An entity tag can be added to
   the response headers like so:
  +
  +<P>
   
  -<P><A NAME="anchor61"></A>
  -<PRE>  $r-&gt;header_out(&quot;ETag&quot;,&quot;\&quot;$VERSION\&quot;&quot;);
  -</PRE>
  -<P><A NAME="anchor62"></A>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  $r-&gt;header_out(&quot;ETag&quot;,&quot;\&quot;$VERSION\&quot;&quot;);</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Note: mod_perl offers the <CODE>Apache::set_etag()</CODE> method if you have loaded <CODE>Apache::File</CODE>. It is strongly recommended that you <EM>do not</EM>
   use this method unless you know what you are doing.  <CODE>set_etag()</CODE> is expecting to be used in conjunction with a static request for a file on
   disk that has been <CODE>stat()ed</CODE> in the course of the current
   request. It is inappropriate and ``dangerous'' to use it for dynamic
   content.
   
  -<P><A NAME="anchor63"></A>
  +<P>
   By sending an entity tag you promise the recipient that you will not send
   the same <CODE>ETag</CODE> for the same resource again unless the content is <EM>'equal'</EM> to what you are sending now (see below for what equality means).
   
  -<P><A NAME="anchor64"></A>
  +<P>
   The pros and cons of using entity tags are discussed in section 13.3 of the
   HTTP specs. For us mod_perl programmers that discussion can be summed up as
   follows:
   
  -<P><A NAME="anchor65"></A>
  +<P>
   There are strong and weak validators. Strong validators change whenever a
   single bit changes in the response. Weak validators change when the meaning
   of the response changes. Strong validators are needed for caches to allow
  @@ -417,76 +626,137 @@
   but what we usually want, when we want to take advantage of caching, is a
   good weak validator.
   
  -<P><A NAME="anchor66"></A>
  +<P>
   A <CODE>Last-Modified</CODE> time, when used as a validator in a request, can be strong or weak,
   depending on a couple of rules. Please refer to section 13.3.3 of the HTTP
   standard to understand these rules. This is mostly relevant for range
   requests as this citation of section 14.27 explains:
  +
  +<P>
   
  -<P><A NAME="anchor67"></A>
  -<PRE>  If the client has no entity tag for an entity, but does have a
  -  Last-Modified date, it MAY use that date in a If-Range header.
  -</PRE>
  -<P><A NAME="anchor68"></A>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  If the client has no entity tag for an entity, but does have a
  +  Last-Modified date, it MAY use that date in a If-Range header.</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   But it is not limited to range requests. Section 13.3.1 succinctly states
   that:
  +
  +<P>
   
  -<P><A NAME="anchor69"></A>
  -<PRE>  The Last-Modified entity-header field value is often used as a
  -  cache validator.
  -</PRE>
  -<P><A NAME="anchor70"></A>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  The Last-Modified entity-header field value is often used as a
  +  cache validator.</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   The fact that a <CODE>Last-Modified</CODE> date may be used as a strong validator can be pretty disturbing if we are
   in fact changing our output slightly without changing the semantics of the
   output. To prevent these kinds of misunderstanding between us and the cache
   servers in the response chain, we can send a weak validator in an
   <CODE>ETag</CODE> header. This is possible because the specs say:
  +
  +<P>
   
  -<P><A NAME="anchor71"></A>
  -<PRE>  If a client wishes to perform a sub-range retrieval on a value for
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  If a client wishes to perform a sub-range retrieval on a value for
     which it has only a Last-Modified time and no opaque validator, it
     MAY do this only if the Last-Modified time is strong in the sense
  -  described here.
  -</PRE>
  -<P><A NAME="anchor72"></A>
  +  described here.</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   In other words: by sending them an <CODE>ETag</CODE> that is marked as weak we prevent them from using the Last-Modified header
   as a strong validator.
   
  -<P><A NAME="anchor73"></A>
  +<P>
   An <CODE>ETag</CODE> value is marked as a weak validator by prepending the string <CODE>W/</CODE> to the quoted string, otherwise it is strong. In perl this would mean
   something like this:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor74"></A>
  -<PRE>  $r-&gt;header_out('ETag',&quot;W/\&quot;$VERSION\&quot;&quot;);
  -</PRE>
  -<P><A NAME="anchor75"></A>
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  $r-&gt;header_out('ETag',&quot;W/\&quot;$VERSION\&quot;&quot;);</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Consider carefully which string you choose to act as a validator. You are
   on your own with this decision because...
   
  -<P><A NAME="anchor76"></A>
  -<PRE>  ... only the service author knows the semantics of a resource
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  ... only the service author knows the semantics of a resource
     well enough to select an appropriate cache validation
     mechanism, and the specification of any validator comparison
     function more complex than byte-equality would open up a can
     of worms.  Thus, comparisons of any other headers (except
     Last-Modified, for compatibility with HTTP/1.0) are never used
  -  for purposes of validating a cache entry.
  -</PRE>
  -<P><A NAME="anchor77"></A>
  +  for purposes of validating a cache entry.</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   If you are composing a message from multiple components, it may be
   necessary to combine some kind of version information for all these
   components into a single string.
   
  -<P><A NAME="anchor78"></A>
  +<P>
   If you are producing relatively large documents, or content that does not
   change frequently, you most likely will prefer a strong entity tag, thus
   giving caches a chance to transfer the document in chunks. (Anybody in the
   mood to add a chapter about ranges to this document?)
   
  -<P><A NAME="anchor79"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="2_3_Content_Negotiation">2.3) Content Negotiation</A></H2></CENTER>
  -<P><A NAME="anchor80"></A>
  +<P>
   Content negotiation is a particularly wonderful feature that was introduced
   with HTTP 1.1. Unfortunately it is not yet widely supported. Probably the
   most popular usage scenario of content negotiation is language negotiation.
  @@ -497,9 +767,18 @@
   from several available representations of the document the one that best
   fits the user's preferences. Content negotiation is not limited to
   language. Citing the specs:
  +
  +<P>
   
  -<P><A NAME="anchor81"></A>
  -<PRE>  HTTP/1.1 includes the following request-header fields for enabling
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  HTTP/1.1 includes the following request-header fields for enabling
     server-driven negotiation through description of user agent
     capabilities and user preferences: Accept (section 14.1), Accept-
     Charset (section 14.2), Accept-Encoding (section 14.3), Accept-
  @@ -507,73 +786,116 @@
     origin server is not limited to these dimensions and MAY vary the
     response based on any aspect of the request, including information
     outside the request-header fields or within extension header fields
  -  not defined by this specification.
  -</PRE>
  -<P><A NAME="anchor82"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +  not defined by this specification.</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="2_3_1_Vary">2.3.1) Vary</A></H2></CENTER>
  -<P><A NAME="anchor83"></A>
  +<P>
   In order to signal to the recipient that content negotiation has been used
   to determine the best available representation for a given request, the
   server must include a <CODE>Vary</CODE> header. This tells the recipient which request headers have been used to
   determine it. So an answer may be generated like this:
  +
  +<P>
   
  -<P><A NAME="anchor84"></A>
  -<PRE>  $r-&gt;header_out('Vary', join &quot;, &quot;, 
  -        qw(accept accept-language accept-encoding user-agent));
  -</PRE>
  -<P><A NAME="anchor85"></A>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  $r-&gt;header_out('Vary', join &quot;, &quot;, 
  +        qw(accept accept-language accept-encoding user-agent));</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   The header of a very cool page may greet the user with something like
  +
  +<P>
   
  -<P><A NAME="anchor86"></A>
  -<PRE>  Hallo Kraut, Dein NutScrape versteht zwar PNG aber leider
  -  kein GZIP.
  -</PRE>
  -<P><A NAME="anchor87"></A>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  Hallo Kraut, Dein NutScrape versteht zwar PNG aber leider
  +  kein GZIP.</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   but it has the side effect of being expensive for a caching proxy. As of
   this writing, Squid (version 2.1PATCH2) does not cache resources that come
   with a Vary header at all. So unless you find a clever workaround, you
   won't enjoy your Squid accelerator for these documents :-(
   
  -<P><A NAME="anchor88"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H1><A NAME="3_Requests">3) Requests</A></H1></CENTER>
  -<P><A NAME="anchor89"></A>
  +<P>
   Section 13.11 of the specifications states that the only two cachable
   methods are <CODE>GET</CODE> and <CODE>HEAD</CODE>.
   
  -<P><A NAME="anchor90"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="3_1_HEAD">3.1) HEAD</A></H2></CENTER>
  -<P><A NAME="anchor91"></A>
  +<P>
   Among the above recommended headers, the date-related ones (<CODE>Date</CODE>,
   <CODE>Last-Modified</CODE>, and <CODE>Expires</CODE>/<CODE>Cache-Control</CODE>) are usually easy to produce and thus should be computed for <CODE>HEAD</CODE> requests just the same as for <CODE>GET</CODE> requests.
   
  -<P><A NAME="anchor92"></A>
  +<P>
   The <CODE>Content-Type</CODE> and <CODE>Content-Length</CODE> headers should be exactly the same as would be supplied to the
   corresponding <CODE>GET</CODE> request. But as it can be expensive to compute them, they can just as well
   be omitted, since there is nothing in the specs that forces you to compute
   them.
   
  -<P><A NAME="anchor93"></A>
  +<P>
   What is important for the mod_perl programmer is that the response to a <CODE>HEAD</CODE> request <EM>must not</EM> contain a message-body. The code in your mod_perl handler might look like
   this:
  +
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
   
  -<P><A NAME="anchor94"></A>
  -<PRE>  # compute the headers that are easy to compute
  +	<td>
  +	  <pre>  # compute the headers that are easy to compute
     if ( $r-&gt;header_only ){ # currently equivalent to $r-&gt;method eq &quot;HEAD&quot;
       $r-&gt;send_http_header;
       return OK;
  -  }
  -</PRE>
  -<P><A NAME="anchor95"></A>
  +  }</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   If you are running a Squid accelerator, it will be able to handle the whole <CODE>HEAD</CODE> request for you, but under some circumstances it may not be allowed to do
   so.
   
  -<P><A NAME="anchor96"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="3_2_POST">3.2) POST</A></H2></CENTER>
  -<P><A NAME="anchor97"></A>
  +<P>
   The response to a <CODE>POST</CODE> request is not cachable due to an underspecification in the HTTP standards.
   Section 13.4 does not forbid caching of responses to <CODE>POST</CODE> requests but no other part of the HTTP standard explains how caching of <CODE>POST</CODE> requests could be implemented, so we are in a vacuum here and all existing
   caching servers therefore refuse to implement caching of <CODE>POST</CODE>
  @@ -582,30 +904,43 @@
   caching of <CODE>POST</CODE>
   requests.
   
  -<P><A NAME="anchor98"></A>
  +<P>
   Note: If you are running a Squid accelerator, you should be aware that it
   accelerates outgoing traffic, but does not bundle incoming traffic. If you
   have long <CODE>POST</CODE> requests, Squid doesn't buy you anything. So always consider using a <CODE>GET</CODE> instead of a <CODE>POST</CODE> if possible.
   
  -<P><A NAME="anchor99"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="3_3_GET">3.3) GET</A></H2></CENTER>
  -<P><A NAME="anchor100"></A>
  +<P>
   A normal <CODE>GET</CODE> is what we usually write our mod_perl programs for. Nothing special about
   it. We send our headers followed by the body.
   
  -<P><A NAME="anchor101"></A>
  +<P>
   But there is a certain case that needs a workaround to achieve better
   cacheability. We need to deal with the ``?'' in the rel_path part of the
   requested URI. Section 13.9 specifies that
  +
  +<P>
   
  -<P><A NAME="anchor102"></A>
  -<PRE>  ... caches MUST NOT treat responses to such URIs as fresh unless
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  ... caches MUST NOT treat responses to such URIs as fresh unless
     the server provides an explicit expiration time.  This specifically
     means that responses from HTTP/1.0 servers for such URIs SHOULD NOT
  -  be taken from a cache.
  -</PRE>
  -<P><A NAME="anchor103"></A>
  +  be taken from a cache.</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   You're tempted to believe that if we are using HTTP 1.1 and send an
   explicit expiration time we're on the safe side? Unfortunately reality is a
   little bit different. It has been a bad habit for quite a long time to
  @@ -614,12 +949,21 @@
   mark everything as uncacheable that contained the string
   <CODE>cgi-bin</CODE>.
   
  -<P><A NAME="anchor104"></A>
  +<P>
   To work around this bug in the <CODE>HEAD</CODE> requests, I have stopped calling my CGI directories <CODE>cgi-bin</CODE> and I have written the following handler that lets me work with CGI-like
   query strings without rewriting the software (such as <CODE>Apache::Request</CODE> and <CODE>CGI.pm</CODE>) that deals with them.
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor105"></A>
  -<PRE>  sub handler {
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  sub handler {
       my($r) = @_;
       my $uri = $r-&gt;uri;
       if ( my($u1,$u2) = $uri =~ / ^ ([^?]+?) ; ([^?]*) $ /x ) {
  @@ -635,51 +979,112 @@
         $r-&gt;args($u2);
       }
       DECLINED;
  -  }
  -</PRE>
  -<P><A NAME="anchor106"></A>
  +  }</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   This handler must be installed as a <CODE>PerlPostReadRequestHandler</CODE>.
   
  -<P><A NAME="anchor107"></A>
  +<P>
   The handler takes any request that contains one or more semicolons but
   <EM>no</EM> question mark such that the first semicolon is interpreted as a question
   mark and everything after that as the query string. You can now exchange
   the request:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor108"></A>
  -<PRE>  <A HREF="http://foo.com/query?BGCOLOR=blue;FGCOLOR=red">http://foo.com/query?BGCOLOR=blue;FGCOLOR=red</A>
  -</PRE>
  -<P><A NAME="anchor109"></A>
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  <A HREF="http://foo.com/query?BGCOLOR=blue;FGCOLOR=red">http://foo.com/query?BGCOLOR=blue;FGCOLOR=red</A></pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   with:
   
  -<P><A NAME="anchor110"></A>
  -<PRE>  <A HREF="http://foo.com/query;BGCOLOR=blue;FGCOLOR=red">http://foo.com/query;BGCOLOR=blue;FGCOLOR=red</A>
  -</PRE>
  -<P><A NAME="anchor111"></A>
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  <A HREF="http://foo.com/query;BGCOLOR=blue;FGCOLOR=red">http://foo.com/query;BGCOLOR=blue;FGCOLOR=red</A></pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Thus it allows the co-existence of queries from ordinary forms that are
   being processed by a browser and predefined requests for the same resource.
   It has one minor bug: Apache doesn't allow percent-escaped slashes in such
   a query string. So instead of:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor112"></A>
  -<PRE>  <A HREF="http://foo.com/query;BGCOLOR=blue;FGCOLOR=red;FONT=%2Ffont%2Fbla">http://foo.com/query;BGCOLOR=blue;FGCOLOR=red;FONT=%2Ffont%2Fbla</A>
  -</PRE>
  -<P><A NAME="anchor113"></A>
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  <A HREF="http://foo.com/query;BGCOLOR=blue;FGCOLOR=red;FONT=%2Ffont%2Fbla">http://foo.com/query;BGCOLOR=blue;FGCOLOR=red;FONT=%2Ffont%2Fbla</A></pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   you have to use:
   
  -<P><A NAME="anchor114"></A>
  -<PRE>  <A HREF="http://foo.com/query;BGCOLOR=blue;FGCOLOR=red;FONT=/font/bla">http://foo.com/query;BGCOLOR=blue;FGCOLOR=red;FONT=/font/bla</A>
  -</PRE>
  -<P><A NAME="anchor115"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  <A HREF="http://foo.com/query;BGCOLOR=blue;FGCOLOR=red;FONT=/font/bla">http://foo.com/query;BGCOLOR=blue;FGCOLOR=red;FONT=/font/bla</A></pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="3_4_Conditional_GET">3.4) Conditional GET</A></H2></CENTER>
  -<P><A NAME="anchor116"></A>
  +<P>
   A rather challenging request mod_perl programmers can get is the
   conditional <CODE>GET</CODE>, which typically means a request with an If-Modified-Since header. The
   HTTP specifications have this to say:
  +
  +<P>
   
  -<P><A NAME="anchor117"></A>
  -<PRE>  The semantics of the GET method change to a &quot;conditional GET&quot;
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  The semantics of the GET method change to a &quot;conditional GET&quot;
     if the request message includes an If-Modified-Since,
     If-Unmodified-Since, If-Match, If-None-Match, or If-Range
     header field.  A conditional GET method requests that the
  @@ -687,23 +1092,38 @@
     by the conditional header field(s). The conditional GET method
     is intended to reduce unnecessary network usage by allowing
     cached entities to be refreshed without requiring multiple
  -  requests or transferring data already held by the client.
  -</PRE>
  -<P><A NAME="anchor118"></A>
  +  requests or transferring data already held by the client.</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   So how can we reduce the unnecessary network usage in such a case? mod_perl
   makes it easy for you by offering Apache's
   <CODE>meets_conditions()</CODE>. You have to set up your <CODE>Last-Modified</CODE> (and possibly <CODE>ETag</CODE>) header before calling this method. If the return value of this method is
   anything other than <CODE>OK</CODE>, you should return that value from your handler and you're done. Apache
   handles the rest for you. The following example is taken from
   <A HREF="././correct_headers.html#_5_">[5]</A>:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor119"></A>
  -<PRE>  if((my $rc = $r-&gt;meets_conditions) != OK) {
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  if((my $rc = $r-&gt;meets_conditions) != OK) {
        return $rc;
     }
  -  #else ... go and send the response body ...
  -</PRE>
  -<P><A NAME="anchor120"></A>
  +  #else ... go and send the response body ...</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   If you have a Squid accelerator running, it will often handle the
   conditionals for you and you can enjoy its extremely fast responses for
   such requests by reading the <EM>access.log</EM>. Just grep for
  @@ -711,65 +1131,84 @@
   That is why the origin server (which is the server you're programming)
   needs to handle conditional <CODE>GET</CODE>s as well even if a Squid accelerator is running.
   
  -<P><A NAME="anchor121"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="3_Avoiding_dealing_with_them">3.) Avoiding dealing with them</A></H2></CENTER>
  -<P><A NAME="anchor122"></A>
  +<P>
   There is another approach to dynamic content that is possible with
   mod_perl. This approach is appropriate if the content changes relatively
   infrequently, if you expect lots of requests to retrieve the same content
   before it changes again and if it is much cheaper to test whether the
   content needs refreshing than it is to refresh it.
   
  -<P><A NAME="anchor123"></A>
  +<P>
   In this case a <CODE>PerlFixupHandler</CODE> can be installed for the relevant location. It tests whether the content is
   up to date. If so, it returns <CODE>DECLINED</CODE> and lets the Apache core serve the content from a file. Otherwise, it
   regenerates the content into the file, updates the <CODE>$r-&gt;finfo</CODE> status and again returns <CODE>DECLINED</CODE> so that Apache serves the updated file. Updating <CODE>$r-&gt;finfo</CODE> can be achieved by calling
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor124"></A>
  -<PRE>  $r-&gt;filename($file); # force update of finfo
  -</PRE>
  -<P><A NAME="anchor125"></A>
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  $r-&gt;filename($file); # force update of finfo</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   even if this seems redundant because the filename is already equal to
   <CODE>$file</CODE>. Setting the filename has the side effect of doing a
   <A HREF="#item_stat">stat()</A> on the file. This is important because otherwise Apache would use the out
   of date <CODE>finfo</CODE> when generating the response header.
   
  -<P><A NAME="anchor126"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H1><A NAME="References_and_other_literature">References and other literature</A></H1></CENTER>
  -<P><A NAME="anchor127"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="_1_">[1]</A></H2></CENTER>
  -<P><A NAME="anchor128"></A>
  +<P>
   Stas Bekman: mod_perl Guide. <A
   HREF="http://perl.apache.org/guide/">http://perl.apache.org/guide/</A>
   
  -<P><A NAME="anchor129"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="_2_">[2]</A></H2></CENTER>
  -<P><A NAME="anchor130"></A>
  +<P>
   T. Berners-Lee et al.: Hypertext Transfer Protocol -- HTTP/1.0, RFC 1945.
   
  -<P><A NAME="anchor131"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="_3_">[3]</A></H2></CENTER>
  -<P><A NAME="anchor132"></A>
  +<P>
   R. Fielding et al.: Hypertext Transfer Protocol -- HTTP/1.1, RFC 2616.
   
  -<P><A NAME="anchor133"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="_4_">[4]</A></H2></CENTER>
  -<P><A NAME="anchor134"></A>
  +<P>
   Martin Hamilton: Cachebusting - cause and prevention,
   draft-hamilton-cachebusting-01. Also available online at <A
   HREF="http://vancouver-webpages.com/CacheNow/">http://vancouver-webpages.com/CacheNow/</A>
   
   
  -<P><A NAME="anchor135"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="_5_">[5]</A></H2></CENTER>
  -<P><A NAME="anchor136"></A>
  +<P>
   Lincoln Stein, Doug MacEachern: Writing Apache Modules with Perl and C,
   O'Reilly, 1-56592-567-X. Selected chapters available online at <A
   HREF="http://www.modperl.com">http://www.modperl.com</A> . Amazon page at
  @@ -777,17 +1216,19 @@
   HREF="http://www.amazon.com/exec/obidos/ASIN/156592567X/writinapachemodu/">http://www.amazon.com/exec/obidos/ASIN/156592567X/writinapachemodu/</A>
   
   
  -<P><A NAME="anchor137"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H1><A NAME="VERSION">VERSION</A></H1></CENTER>
  -<P><A NAME="anchor138"></A>
  -You're reading revision $Revision: 1.8 $ of this document, written on
  -$Date: 2000/06/07 22:39:41 $
  +<P>
  +You're reading revision $Revision: 1.9 $ of this document, written on
  +$Date: 2000/06/07 22:45:30 $
   
  -<P><A NAME="anchor139"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H1><A NAME="AUTHOR">AUTHOR</A></H1></CENTER>
  -<P><A NAME="anchor140"></A>
  +<P>
   Andreas Koenig with helpful corrections, addition, comments from Ask Bjoern
   Hansen &lt;<A HREF="mailto:ask@netcetera.dk">ask@netcetera.dk</A>&gt;,
   Frank D. Cringle &lt;<A
  @@ -801,58 +1242,84 @@
   HREF="mailto:wham_bang@yahoo.com">wham_bang@yahoo.com</A>&gt; and many
   others.
   
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -	     The <a href="http://www.modperl.com/">
  -	     <B>Writing Apache Modules with Perl and C</B></a>
  -	     book can be purchased online from <a
  -	     href="http://www.ora.com/catalog/wrapmod/">O'Reilly </a>
  -	     and <a
  -	     href="http://www.amazon.com/exec/obidos/ASIN/156592567X/writinapachemodu">
  -	     Amazon.com</a>.
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   
  -	     <HR>
   
  -	     <B>Your corrections of either technical or grammatical
  +    <p>
  +    <div class="navbar">
  +      <a href="troubleshooting.html">Prev</a>                                 |
  +      <A HREF="index.html"         >Contents</A> |
  +      <A HREF="index.html#search"  >Search</A>   |
  +      <A HREF="index.html#download">Download</A> |
  +      <a href="security.html">Next</a>
  +    </div>
  +    <p>
  +
  +    <table width="60%" align="center">
  +
  +      <tr>
  +	<td>
  +	  <div class="notice">
  +	  <B>Your corrections of the technical and grammatical
   	     errors are very welcome. You are encouraged to help me
  -	     to improve this guide.  If you have something to
  -	     contribute please <A
  -	     HREF="help.html#Contacting_me"> send it
  +	     improve this guide.  If you have something to contribute
  +	     please <A HREF="help.html#Contacting_me"> send it
   	     directly to me</A>.</B>
  +	  </div>
  +	</td>
  +      </tr>
  +
  +      <tr>
  +	<td>
  +	  <div class="ad">
  +	    The <a href="http://www.modperl.com/">
  +	      <B>Writing Apache Modules with Perl and C</B></a>
  +	    book can be purchased online from <a
  +	      href="http://www.ora.com/catalog/wrapmod/">O'Reilly </a>
  +	    and <a
  +	    href="http://www.amazon.com/exec/obidos/ASIN/156592567X/writinapachemodu">
  +	      Amazon.com</a>.
  +	  </div>
  +	</td>
  +      </tr>
  +
  +</table>
  +
  +<center>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
  +<table cellspacing=2 cellpadding=2>
  +
  +<tr align=center valign=top>
  +<td align=center valign=center>
  +
  +<b><font size=-1>Written by <a
  +href="help.html#Contacting_me">Stas Bekman</a>.<br> Last Modified at 05/27/2000
  +</font></b>
  +<br>
  +
  +</td>
  +
  +<td>
  +
  +<a href="http://perl.apache.org"><img src="images/mod_perl2.jpg"  border=0 alt="mod_perl icon" border=0 height=59 width=150></a>
  +<br>
  +
  +</td>
  +
  +<td>
  +
  +<font size=-2>Use of the Camel for Perl is <br>
  +a trademark of <a href="http://www.ora.com">O'Reilly &amp; Associates</a>,<br>
  +and is used by permission. </font> 
  +<br>
   
  -	     <HR>
  +</td>
   
  -	     [    <A HREF="troubleshooting.html">Prev</A> |      <A HREF="index.html">Main Page</A> | <A HREF="security.html">Next</A>      ]
  +</tr>
  +</table>
  +</center>
   
  -<CENTER><TABLE CELLSPACING=2 CELLPADDING=2 WIDTH="100%" >
  -<TR ALIGN=CENTER VALIGN=TOP>
  -  <TD ALIGN=CENTER VALIGN=CENTER COLSPAN="3">
  -	     <HR>
  -  </TD>
  -</TR>
  -<TR ALIGN=CENTER VALIGN=TOP>
  -  <TD ALIGN=CENTER VALIGN=CENTER>
  -    <B>
  -      <FONT SIZE=-1>
  -	     Written by <A HREF="help.html#Contacting_me">Stas Bekman</A>.
  -	     <BR>Last Modified at 05/09/2000
  -      </FONT>
  -    </B>
  -  </TD>
  -
  -  <TD>
  -	     <A HREF="http://perl.apache.org"><IMG SRC="images/mod_perl2.jpg" ALT="Mod Perl Icon" BORDER=0 HEIGHT=59 WIDTH=150></A>
  -  </TD>
  -
  -  <TD>
  -    <FONT SIZE=-2>
  -	     Use of the Camel for Perl is <BR>
  -	     a trademark of <A HREF="http://www.ora.com">O'Reilly &amp; Associates</A>,<BR>
  -             and is used by permission. 
  -    </FONT> 
  -  </TD>
  -</TR>
  -</TABLE></CENTER>
  -
  -</BODY>
  -</HTML>
  -	    
  \ No newline at end of file
  +</body>
  +</html>
  
  
  
  1.15      +561 -264  modperl-site/guide/databases.html
  
  Index: databases.html
  ===================================================================
  RCS file: /home/cvs/modperl-site/guide/databases.html,v
  retrieving revision 1.14
  retrieving revision 1.15
  diff -u -r1.14 -r1.15
  --- databases.html	2000/05/12 22:42:51	1.14
  +++ databases.html	2000/06/07 22:45:30	1.15
  @@ -1,29 +1,37 @@
   <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
  -<HTML>
  -<HEAD>
  -   <TITLE>mod_perl guide: mod_perl and Relational Databases</TITLE>
  -   <META NAME="GENERATOR" CONTENT="Pod2HTML [Perl/Linux]">
  -   <META NAME="Author" CONTENT="Stas Bekman">
  -   <META NAME="Description" CONTENT="All Apache/Perl related information: Hints, Guidelines, Scenarios and Troubleshottings">
  -   <META NAME="keywords" CONTENT="mod_perl modperl perl apache cgi webserver speed  fast guide mod_perl apache guide help info faq mod_perl installation cgi troubleshooting help no sex speedup free open source OSS mod_perl apache guide">
  -</HEAD>
  -     <LINK REL=STYLESHEET TYPE="text/css"
  -        HREF="style.css" TITLE="refstyle">
  -     <style type="text/css">
  -     <!-- 
  -        @import url(style.css);
  -     -->
  -     
  -     </style>
  -<BODY BGCOLOR="white">
  +<html>
  +  <head>
  +   <title>mod_perl guide: mod_perl and Relational Databases</title>
  +   <meta name="Author" content="Stas Bekman">
  +   <meta name="Description" content="All Apache/Perl related information: Hints, Guidelines, Scenarios and Troubleshottings">
  +   <meta name="keywords" content="mod_perl modperl perl cgi apache webserver speed fast guide mod_perl apache guide help info faq mod_perl installation cgi troubleshooting help no sex speedup free open source OSS mod_perl apache guide">
  +   <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
  +   <meta name="Classification" content="information">
  +   <link href="style.css" rel=stylesheet type="text/css" title="refstyle">
  +  </head>
  +  <body>
  +
  +    <h1 align=center>
  +      <a href="http://perl.apache.org"><img src="images/mod_perl.gif" alt="Mod Perl Icon" border=0 height=30 width=90 align=left></a>
  +      <a href="http://perl.apache.org"><img src="images/mod_perl.gif" alt="Mod Perl Icon" border=0 height=30 width=90 align=right></a>
  +      mod_perl and Relational Databases
  +    </h1>
  +    <hr>
  +    <p>
  +    <div class="navbar">
  +      <a href="security.html">Prev</a>                                 |
  +      <a href="index.html"         >Contents</a> |
  +      <a href="index.html#search"  >Search</a>   |
  +      <a href="index.html#download">Download</a> |
  +      <a href="dbm.html">Next</a>
  +    </div>
  +    <p>
  +
  +    <div class="toc">
  +      
   <A NAME="toc"></A>
  -<H1 ALIGN=CENTER>
  -<A HREF="http://perl.apache.org"><IMG SRC="images/mod_perl.gif" ALT="Mod Perl Icon" BORDER=0 HEIGHT=30 WIDTH=90 ALIGN=LEFT></A>
  -<A HREF="http://perl.apache.org"><IMG SRC="images/mod_perl.gif" ALT="Mod Perl Icon" BORDER=0 HEIGHT=30 WIDTH=90 ALIGN=RIGHT></A>
  -mod_perl and Relational Databases</H1>
  -<HR WIDTH="100%">
  -	    [    <A HREF="security.html">Prev</A> |      <A HREF="index.html">Main Page</A> | <A HREF="dbm.html">Next</A>      ]<HR><!-- INDEX BEGIN -->
  -<P><B><FONT SIZE=-1>Table of Contents:</FONT></B></P>
  +<P><B>Table of Contents:</B></P>
  +
   <UL>
   
   	<LI><A HREF="#Why_Relational_SQL_Databases">Why Relational (SQL) Databases</A>
  @@ -59,33 +67,49 @@
   	</UL>
   
   </UL>
  -<!-- INDEX END -->
   
  +    </div>
  +
  +    [ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
   <HR>
  +    <table width="60%" align="center">
  +
  +      <tr>
  +	<td>
  +	  <div class="ad">
  +	    The <a href="http://www.modperl.com/">
  +	      <B>Writing Apache Modules with Perl and C</B></a>
  +	    book can be purchased online from <a
  +	      href="http://www.ora.com/catalog/wrapmod/">O'Reilly </a>
  +	    and <a
  +	    href="http://www.amazon.com/exec/obidos/ASIN/156592567X/writinapachemodu">
  +	      Amazon.com</a>.
  +	  </div>
  +	</td>
  +      </tr>
  +
  +      <tr>
  +	<td>
  +	  <div class="notice">
  +	  <B>Your corrections of the technical and grammatical
  +	     errors are very welcome. You are encouraged to help me
  +	     improve this guide.  If you have something to contribute
  +	     please <A HREF="help.html#Contacting_me"> send it
  +	     directly to me</A>.</B>
  +	  </div>
  +	</td>
  +      </tr>
   
  -	     The <a href="http://www.modperl.com/">
  -	     <B>Writing Apache Modules with Perl and C</B></a>
  -	     book can be purchased online from <a
  -	     href="http://www.ora.com/catalog/wrapmod/">O'Reilly </a>
  -	     and <a
  -	     href="http://www.amazon.com/exec/obidos/ASIN/156592567X/writinapachemodu">
  -	     Amazon.com</a>.
  -
  -	     <HR>
  -
  -	       <B>Your corrections of either technical or grammatical
  -	       errors are very welcome. You are encouraged to help me
  -	       to improve this guide.  If you have something to
  -	       contribute please <A
  -	       HREF="help.html#Contacting_me"> send it
  -	       directly to me</A>.
  -	       </B>
  -	       <HR>
  +</table>
   
  -	      <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<P><A NAME="anchor0"></A>
  +    
  +
  +	    [ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
  +
  +<P>
   <CENTER><H1><A NAME="Why_Relational_SQL_Databases">Why Relational (SQL) Databases</A></H1></CENTER>
  -<P><A NAME="anchor1"></A>
  +<P>
   Nowadays millions of people surf the Internet. There are millions of
   Terabytes of data lying around. To manipulate the data new smart techniques
   and technologies were invented. One of the major inventions was the
  @@ -93,10 +117,11 @@
   data very quickly. We use <STRONG>SQL</STRONG> (Structured Query Language) to access and manipulate the contents of these
   databases.
   
  -<P><A NAME="anchor2"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H1><A NAME="Apache_DBI_Initiate_a_persist">Apache::DBI - Initiate a persistent database connection</A></H1></CENTER>
  -<P><A NAME="anchor3"></A>
  +<P>
   When people started to use the web, they found that they needed to write
   web interfaces to their databases. CGI is the most widely used technology
   for building such interfaces. The main limitation of a CGI script driving a
  @@ -104,26 +129,27 @@
   request the CGI script has to re-connect to the database, and when the
   request is completed the connection is closed.
   
  -<P><A NAME="anchor4"></A>
  +<P>
   <CODE>Apache::DBI</CODE> was written to remove this limitation. When you use it, you have a database
   connection which persists for the process' entire life. So when your
   mod_perl script needs to use a database,
   <CODE>Apache::DBI</CODE> provides a valid connection immediately and your script starts work right
   away without having to initiate a database connection first.
   
  -<P><A NAME="anchor5"></A>
  +<P>
   This is possible only with CGI running under a mod_perl enabled server,
   since in this model the child process does not quit when the request has
   been served.
   
  -<P><A NAME="anchor6"></A>
  +<P>
   It's almost as straightforward as is it sounds; there are just a few things
   to know about and we will cover them in this section.
   
  -<P><A NAME="anchor7"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="Introduction">Introduction</A></H2></CENTER>
  -<P><A NAME="anchor8"></A>
  +<P>
   The DBI module can make use of the <CODE>Apache::DBI</CODE> module. When it loads, the DBI module tests if the environment variable
   <CODE>$ENV{MOD_PERL}</CODE> is set, and if the <CODE>Apache::DBI</CODE> module has already been loaded. If so, the DBI module will forward every
   <CODE>connect()</CODE> request to the <CODE>Apache::DBI</CODE> module. <CODE>Apache::DBI</CODE> uses the <CODE>ping()</CODE> method to look for a database handle from a
  @@ -131,21 +157,21 @@
   valid. If these two conditions are fulfilled it just returns the database
   handle.
   
  -<P><A NAME="anchor9"></A>
  +<P>
   If there is no appropriate database handle or if the <CODE>ping()</CODE>
   method fails, <CODE>Apache::DBI</CODE> establishes a new connection and stores the handle for later re-use. When
   the script is run again by a child that is still connected, <CODE>Apache::DBI</CODE> just checks the cache of open connections by matching the <EM>host</EM>, <EM>username</EM> and <EM>password</EM>
   parameters against it. A matching connection is returned if available or a
   new one is initiated and then returned.
   
  -<P><A NAME="anchor10"></A>
  +<P>
   There is no need to delete the <CODE>disconnect()</CODE> statements from
   your code. They won't do anything because the <CODE>Apache::DBI</CODE> module overloads the <CODE>disconnect()</CODE> method with an empty one.
   
  -<P><A NAME="anchor11"></A>
  +<P>
   When should this module be used and when shouldn't it be used?
   
  -<P><A NAME="anchor12"></A>
  +<P>
   You will want to use this module if you are opening several database
   connections to the server. <CODE>Apache::DBI</CODE> will make them persistent per child, so if you have ten children and each
   opens two different connections (with different <CODE>connect()</CODE>
  @@ -154,47 +180,70 @@
   for every <CODE>connect()</CODE> request from your <CODE>DBI</CODE> module. This can be a huge benefit for a server with a high volume of
   database traffic.
   
  -<P><A NAME="anchor13"></A>
  +<P>
   You must <STRONG>not</STRONG> use this module if you are opening a special connection for each of your
   users. Each connection will stay persistent and in a short time the number
   of connections will be so big that your machine will scream in agony and
   die.
   
  -<P><A NAME="anchor14"></A>
  +<P>
   If you want to use <CODE>Apache::DBI</CODE> but you have both situations on one machine, at the time of writing the
   only solution is to run two Apache/mod_perl servers, one which uses <CODE>Apache::DBI</CODE> and one which does not.
   
  -<P><A NAME="anchor15"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="Configuration">Configuration</A></H2></CENTER>
  -<P><A NAME="anchor16"></A>
  +<P>
   After installing this module, the configuration is simple - add the
   following directive to <CODE>httpd.conf</CODE>
   
   
   
  -<P><A NAME="anchor17"></A>
  -<PRE>  PerlModule Apache::DBI
  -</PRE>
  -<P><A NAME="anchor18"></A>
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  PerlModule Apache::DBI</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Note that it is important to load this module before any other
   <CODE>Apache*DBI</CODE> module and before the <CODE>DBI</CODE> module itself!
   
  -<P><A NAME="anchor19"></A>
  +<P>
   You can skip preloading <CODE>DBI</CODE>, since <CODE>Apache::DBI</CODE> does that. But there is no harm in leaving it in, as long as it is loaded
   after
   <CODE>Apache::DBI</CODE>.
   
  -<P><A NAME="anchor20"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="Preopening_DBI_connections">Preopening DBI connections</A></H2></CENTER>
  -<P><A NAME="anchor21"></A>
  +<P>
   If you want to make sure that a connection will already be opened when your
   script is first executed after a server restart, then you should use the <CODE>connect_on_init()</CODE> method in the startup file to preload every connection you are going to
   use. For example:
  +
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
   
  -<P><A NAME="anchor22"></A>
  -<PRE>  Apache::DBI-&gt;connect_on_init
  +	<td>
  +	  <pre>  Apache::DBI-&gt;connect_on_init
     (&quot;DBI:mysql:myDB::myserver&quot;,
      &quot;username&quot;,
      &quot;passwd&quot;,
  @@ -203,69 +252,112 @@
       RaiseError =&gt; 0, # don't die on error
       AutoCommit =&gt; 1, # commit executes immediately
      }
  -  );
  -</PRE>
  -<P><A NAME="anchor23"></A>
  +  );</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   As noted above, use this method only if you want all of apache to be able
   to connect to the database server as one user (or as a very few users),
   i.e. if your <CODE>user(s)</CODE> can effectively share the connection. Do
   <STRONG>not</STRONG> use this method if you want for example one unique connection per user.
   
  -<P><A NAME="anchor24"></A>
  +<P>
   Be warned though, that if you call <CODE>connect_on_init()</CODE> and your database is down, Apache children will be delayed at server
   startup, trying to connect. They won't begin serving requests until either
   they are connected, or the connection attempt fails. Depending on your DBD
   driver, this can take several minutes!
   
  -<P><A NAME="anchor25"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="Debugging_Apache_DBI">Debugging Apache::DBI</A></H2></CENTER>
  -<P><A NAME="anchor26"></A>
  +<P>
   If you are not sure if this module is working as advertised, you should
   enable Debug mode in the startup script by:
  +
  +<P>
   
  -<P><A NAME="anchor27"></A>
  -<PRE>  $Apache::DBI::DEBUG = 1;
  -</PRE>
  -<P><A NAME="anchor28"></A>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  $Apache::DBI::DEBUG = 1;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Starting with <CODE>ApacheDBI-0.84</CODE>, setting <CODE>$Apache::DBI::DEBUG = 1</CODE>
   will produce only minimal output. For a full trace you should set
   <CODE>$Apache::DBI::DEBUG = 2</CODE>.
   
  -<P><A NAME="anchor29"></A>
  +<P>
   After setting the DEBUG level you will see entries in the <CODE>error_log</CODE>
   both when <CODE>Apache::DBI</CODE> initializes a connection and when it returns one from its cache. Use the
   following command to view the log in real time (your <CODE>error_log</CODE> might be located at a different path, it is set in the Apache configuration
   files):
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor30"></A>
  -<PRE>  tail -f /usr/local/apache/logs/error_log
  -</PRE>
  -<P><A NAME="anchor31"></A>
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  tail -f /usr/local/apache/logs/error_log</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   I use <CODE>alias</CODE> (in <CODE>tcsh</CODE>) so I do not have to remember the path:
   
  -<P><A NAME="anchor32"></A>
  -<PRE>  alias err &quot;tail -f /usr/local/apache/logs/error_log&quot;
  -</PRE>
  -<P><A NAME="anchor33"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  alias err &quot;tail -f /usr/local/apache/logs/error_log&quot;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="Database_Locking_Risks">Database Locking Risks</A></H2></CENTER>
  -<P><A NAME="anchor34"></A>
  +<P>
   Be very very careful when locking the database (<CODE>LOCK TABLE ...</CODE>) or singular rows if you use <CODE>Apache::DBI</CODE> or similar persistent connections. MySQL threads keep tables locked until
   the thread ends (connection is closed) or the tables are unlocked. If your
   session <CODE>die()'s</CODE> while tables are locked, they will stay neatly
   locked as your connection won't be closed either.
   
  -<P><A NAME="anchor35"></A>
  +<P>
   See the section <A HREF="././debug.html#Handling_the_User_pressed_Stop_">Handling the 'User pressed Stop button' case</A> for more information on prevention.
   
  -<P><A NAME="anchor36"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="Troubleshooting">Troubleshooting</A></H2></CENTER>
  -<P><A NAME="anchor37"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H3><A NAME="The_Morning_Bug">The Morning Bug</A></H3></CENTER>
  -<P><A NAME="anchor38"></A>
  +<P>
   The SQL server keeps a connection to the client open for a limited period
   of time. Many developers were bitten by so called <STRONG>Morning
   bug</STRONG>, when every morning the first users to use the site received a
  @@ -274,121 +366,186 @@
   bitten by this problem. Another solution was found - to increase the
   timeout parameter when starting the SQL server. Currently I startup <CODE>MySQL</CODE>
   server with a script <CODE>safe_mysql</CODE>, so I have modified it to use this option:
  +
  +<P>
   
  -<P><A NAME="anchor39"></A>
  -<PRE>  nohup $ledir/mysqld [snipped other options] -O wait_timeout=172800
  -</PRE>
  -<P><A NAME="anchor40"></A>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  nohup $ledir/mysqld [snipped other options] -O wait_timeout=172800</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   (172800 seconds is equal to 48 hours. This change solves the problem.)
   
  -<P><A NAME="anchor41"></A>
  +<P>
   Note that as from version <CODE>0.82</CODE>, <CODE>Apache::DBI</CODE> implements <CODE>ping()</CODE> inside the <CODE>eval</CODE> block. This means that if the handle has timed out it should be reconnected
   automatically, and avoid the morning bug.
   
  -<P><A NAME="anchor42"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H3><A NAME="Opening_connections_with_differe">Opening connections with different parameters</A></H3></CENTER>
  -<P><A NAME="anchor43"></A>
  +<P>
   When it receives a connection request, before it decides to use an existing
   cached connection, <CODE>Apache::DBI</CODE> insists that the new connection be opened in exactly the same way as the
   cached connection. If I have one script that sets <CODE>LongReadLen</CODE> and one that does not, <CODE>Apache::DBI</CODE> will make two different connections. So instead of having a maximum of 40
   open connections, I can end up with 80.
   
  -<P><A NAME="anchor44"></A>
  +<P>
   However, you are free to modify the handle immediately after you get it
   from the cache. So always initiate connections using the same parameters
   and set <CODE>LongReadLen</CODE> (or whatever) afterwards.
   
  -<P><A NAME="anchor45"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H3><A NAME="Cannot_find_the_DBI_handler">Cannot find the DBI handler</A></H3></CENTER>
  -<P><A NAME="anchor46"></A>
  +<P>
   You must use <CODE>DBI::connect()</CODE> as in normal DBI usage to get your <CODE>$dbh</CODE> database handler.
   Using the <CODE>Apache::DBI</CODE> does not eliminate the need to write proper <CODE>DBI</CODE> code. As the <CODE>Apache::DBI</CODE> man page states, you should program as if you are not using <CODE>Apache::DBI</CODE> at all. <CODE>Apache::DBI</CODE> will override the DBI methods where necessary and return your cached
   connection. Any <CODE>disconnect()</CODE> call will be just ignored.
   
  -<P><A NAME="anchor47"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H3><A NAME="Apache_DBI_does_not_work">Apache:DBI does not work</A></H3></CENTER>
  -<P><A NAME="anchor48"></A>
  +<P>
   Make sure you have it installed.
   
  -<P><A NAME="anchor49"></A>
  +<P>
   Make sure you configured mod_perl with EVERYTHING=1.
   
  -<P><A NAME="anchor50"></A>
  +<P>
   Use the example script eg/startup.pl (in the mod_perl distribution). Remove
   the comment from the line.
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor51"></A>
  -<PRE>  # use Apache::DebugDBI;
  -</PRE>
  -<P><A NAME="anchor52"></A>
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  # use Apache::DebugDBI;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   and adapt the connect string. Do not change anything in your scripts for
   use with <CODE>Apache::DBI</CODE>.
   
  -<P><A NAME="anchor53"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H3><A NAME="Skipping_connection_cache_during">Skipping connection cache during server startup</A></H3></CENTER>
  -<P><A NAME="anchor54"></A>
  +<P>
   Does your error_log look like this?
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor55"></A>
  -<PRE>  10169 Apache::DBI PerlChildInitHandler
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  10169 Apache::DBI PerlChildInitHandler
     10169 Apache::DBI skipping connection cache during server startup
     Database handle destroyed without explicit disconnect at
  -  /usr/lib/perl5/site_perl/5.005/Apache/DBI.pm line 29.
  -</PRE>
  -<P><A NAME="anchor56"></A>
  +  /usr/lib/perl5/site_perl/5.005/Apache/DBI.pm line 29.</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   If so you are trying to open a database connection in the parent httpd
   process. If you do, children will each get a copy of this handle, causing
   clashes when the handle is used by two processes at the same time. Each
   child must have its own, unique, connection handle.
   
  -<P><A NAME="anchor57"></A>
  +<P>
   To avoid this problem, <CODE>Apache::DBI</CODE> checks whether it is called during server startup. If so the module skips
   the connection cache and returns immediately without a database handle.
   
  -<P><A NAME="anchor58"></A>
  +<P>
   You must use the <CODE>Apache::DBI-&gt;connect_on_init()</CODE> method in the startup file.
   
  -<P><A NAME="anchor59"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H3><A NAME="Debugging_code_which_deploys_DBI">Debugging code which deploys DBI</A></H3></CENTER>
  -<P><A NAME="anchor60"></A>
  +<P>
   To log a trace of <CODE>DBI</CODE> statement execution, you must set the
   <CODE>DBI_TRACE</CODE> environment variable. The <CODE>PerlSetEnv DBI_TRACE</CODE>
   directive must appear before you load <CODE>Apache::DBI</CODE> and <CODE>DBI</CODE>.
   
  -<P><A NAME="anchor61"></A>
  +<P>
   For example if you use <CODE>Apache::DBI</CODE>, modify your <CODE>httpd.conf</CODE> with:
  +
  +<P>
   
  -<P><A NAME="anchor62"></A>
  -<PRE>  PerlSetEnv DBI_TRACE &quot;3=/tmp/dbitrace.log&quot;
  -  PerlModule Apache::DBI
  -</PRE>
  -<P><A NAME="anchor63"></A>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  PerlSetEnv DBI_TRACE &quot;3=/tmp/dbitrace.log&quot;
  +  PerlModule Apache::DBI</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Replace <CODE>3</CODE> with the TRACE level you want. The traces from each request will be
   appended to <CODE>/tmp/dbitrace.log</CODE>. Note that the logs might interleave if requests are processed
   concurrently.
   
  -<P><A NAME="anchor64"></A>
  +<P>
   Within your code you can control trace generation with the
   <CODE>trace()</CODE> method:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor65"></A>
  -<PRE>  DBI-&gt;trace($trace_level)
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  DBI-&gt;trace($trace_level)
     DBI-&gt;trace($trace_level, $trace_filename)
     
   DBI trace information can be enabled for all handles using this DBI
   class method. To enable trace information for a specific handle use
  -the similar C&lt;$h-E&lt;gt&gt;trace&gt; method.
  -</PRE>
  -<P><A NAME="anchor66"></A>
  +the similar C&lt;$h-E&lt;gt&gt;trace&gt; method.</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Using the handle trace option with a <CODE>$dbh</CODE> or <CODE>$sth</CODE> is handy for limiting the trace info to the specific bit of code that you
   are interested in.
   
  -<P><A NAME="anchor67"></A>
  +<P>
   Trace Levels:
   
   <UL>
  @@ -402,24 +559,37 @@
   <P><LI><STRONG><A NAME="item_5">5 and above - as above but with more and more obscure
   information.</A></STRONG>
   </UL>
  -<P><A NAME="anchor68"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H1><A NAME="mysql_use_result_vs_mysql_store">mysql_use_result vs. mysql_store_result.</A></H1></CENTER>
  -<P><A NAME="anchor69"></A>
  +<P>
   Since many mod_perl developers use mysql as their preferred SQL engine,
   these notes explain the difference between <CODE>mysql_use_result()</CODE> and
   <CODE>mysql_store_result()</CODE>. The two influence the speed and size of the processes.
   
  -<P><A NAME="anchor70"></A>
  +<P>
   The <CODE>DBD::mysql</CODE> (version 2.0217) documentation includes the following snippet:
   
  -<P><A NAME="anchor71"></A>
  -<PRE>  mysql_use_result attribute: This forces the driver to use
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  mysql_use_result attribute: This forces the driver to use
     mysql_use_result rather than mysql_store_result. The former is
     faster and less memory consuming, but tends to block other
  -  processes. (That's why mysql_store_result is the default.)
  -</PRE>
  -<P><A NAME="anchor72"></A>
  +  processes. (That's why mysql_store_result is the default.)</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Think about it in client/server terms. When you ask the server to
   spoon-feed you the data as you use it, the server process must buffer the
   data, tie up that thread, and possibly keep any database locks open for a
  @@ -427,22 +597,23 @@
   tables you have locked are still locked, and the server is busy talking to
   you every so often. That is <CODE>mysql_use_result()</CODE>.
   
  -<P><A NAME="anchor73"></A>
  +<P>
   If you just suck down the whole dataset to the client, then the server is
   free to go about its business serving other requests. This results in
   parallelism since the server and client are doing work at the same time,
   rather than blocking on each other doing frequent I/O. That is
   <CODE>mysql_store_result()</CODE>.
   
  -<P><A NAME="anchor74"></A>
  +<P>
   As the mysql manual suggests: you should not use <CODE>mysql_use_result()</CODE>
   if you are doing a lot of processing for each row on the client side. This
   can tie up the server and prevent other threads from updating the tables.
   
  -<P><A NAME="anchor75"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H1><A NAME="Optimize_Run_Two_SQL_Engine_Ser">Optimize: Run Two SQL Engine Servers</A></H1></CENTER>
  -<P><A NAME="anchor76"></A>
  +<P>
   Sometimes you end up running many databases on the same machine. These
   might have very varying database needs (such as one db with sessions, very
   frequently updated but tiny amounts of data, and another with large sets of
  @@ -452,36 +623,39 @@
   cache but would gain from fast disk access. Different usage profiles
   require vastly different performance needs.
   
  -<P><A NAME="anchor77"></A>
  +<P>
   This is basically a similar idea to having <A HREF="././strategy.html#One_Plain_Apache_and_One_mod_per">two Apache servers</A>, each optimized for its specific requirements.
   
  -<P><A NAME="anchor78"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H1><A NAME="Some_useful_code_snippets_to_be_">Some useful code snippets to be used with relational Databases</A></H1></CENTER>
  -<P><A NAME="anchor79"></A>
  +<P>
   In this section you will find scripts, modules and code snippets to help
   you get started using relational Databases with mod_perl scripts. Note that
   I work with <CODE>mysql</CODE> ( <A HREF="http://www.mysql.com">http://www.mysql.com</A> ), so the code
   you find here will work out of box with mysql. If you use some other SQL
   engine, it might work for you or it might need some changes. YMMV.
   
  -<P><A NAME="anchor80"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="Turning_SQL_query_writing_into_a">Turning SQL query writing into a short and simple task</A></H2></CENTER>
  -<P><A NAME="anchor81"></A>
  +<P>
   Having to write many queries in my CGI scripts, persuaded me to write a
   stand alone module that saves me a lot of time in coding and debugging my
   code. It also makes my scripts much smaller and easier to read. I will
   present the module here, with examples following:
   
  -<P><A NAME="anchor82"></A>
  +<P>
   Notice the <CODE>DESTROY</CODE> block at the end of the module, which makes various cleanups and allows
   this module to be used under mod_perl and
   <CODE>mod_cgi</CODE> as well. Note that you will not get the benefit of persistent database
   handles with mod_cgi.
   
  -<P><A NAME="anchor83"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="The_My_DB_module">The My::DB module</A></H2></CENTER>
   
   	       <p><a href="code/My-DB.pm"><code>My-DB.pm</code></a> -- The My::DB module
  @@ -490,27 +664,49 @@
   	      <P>
   (Note that you will not find this on CPAN. at least not yet :)
   
  -<P><A NAME="anchor84"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="My_DB_Module_s_Usage_Examples">My::DB Module's Usage Examples</A></H2></CENTER>
  -<P><A NAME="anchor85"></A>
  +<P>
   To use <CODE>My::DB</CODE> in your script, you first have to create a <CODE>My::DB</CODE>
   object:
  +
  +<P>
   
  -<P><A NAME="anchor86"></A>
  -<PRE>  use vars qw($db_obj);
  -  my $db_obj = new My::DB or croak &quot;Can't initialize My::DB object: $!\n&quot;;
  -</PRE>
  -<P><A NAME="anchor87"></A>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  use vars qw($db_obj);
  +  my $db_obj = new My::DB or croak &quot;Can't initialize My::DB object: $!\n&quot;;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Now you can use any of <CODE>My::DB</CODE>'s methods. Assume that we have a table called <EM>tracker</EM> where we store the names of the users and what they are doing at each and
   every moment (think about an online community program).
   
  -<P><A NAME="anchor88"></A>
  +<P>
   I will start with a very simple query--I want to know where the users are
   and produce statistics. <CODE>tracker</CODE> is the name of the table.
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor89"></A>
  -<PRE>    # fetch the statistics of where users are
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>    # fetch the statistics of where users are
     my $r_ary = $db_obj-&gt;sql_get_matched_rows_ary_ref
       (&quot;tracker&quot;,
        [qw(where_user_are)],
  @@ -521,29 +717,65 @@
     foreach my $r_row (@$r_ary){
       $stats{$r_row-&gt;[0]}++;
       $total++;
  -  }
  -</PRE>
  -<P><A NAME="anchor90"></A>
  +  }</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Now let's count how many users we have (in table <CODE>users</CODE>):
  +
  +<P>
   
  -<P><A NAME="anchor91"></A>
  -<PRE>  my $count = $db_obj-&gt;sql_count_matched(&quot;users&quot;);
  -</PRE>
  -<P><A NAME="anchor92"></A>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  my $count = $db_obj-&gt;sql_count_matched(&quot;users&quot;);</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Check whether a user exists:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor93"></A>
  -<PRE>  my $username = 'stas';
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  my $username = 'stas';
     my $exists = $db_obj-&gt;sql_count_matched
     (&quot;users&quot;,
      [username =&gt; [&quot;=&quot;,$username]]
  -  );
  -</PRE>
  -<P><A NAME="anchor94"></A>
  +  );</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Check whether a user is online, and get the time since she went online (<CODE>since</CODE> is a column in the <CODE>tracker</CODE> table, it tells us when a user went online):
  +
  +<P>
   
  -<P><A NAME="anchor95"></A>
  -<PRE>  my @row = ();
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  my @row = ();
     $db_obj-&gt;sql_get_matched_row
     (\@row,
      &quot;tracker&quot;,
  @@ -554,14 +786,26 @@
     if (@row) {
       my $idle = int( (time() - $row[0]) / 60);
       return &quot;Current status: Is Online and idle for $idle minutes.&quot;;
  -  }
  -</PRE>
  -<P><A NAME="anchor96"></A>
  +  }</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   A complex query. I join two tables, and I want a reference to an array
   which will store a slice of the matched query (<CODE>LIMIT $offset,$hits</CODE>) sorted by <CODE>username</CODE>. Each row in the array is to include the fields from the <CODE>users</CODE> table, but only those listed in <CODE>@verbose_cols</CODE>. Then we print it out.
   
  -<P><A NAME="anchor97"></A>
  -<PRE>  my $r_ary = $db_obj-&gt;sql_get_matched_rows_ary_ref
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  my $r_ary = $db_obj-&gt;sql_get_matched_rows_ary_ref
       (
        &quot;tracker STRAIGHT_JOIN users&quot;,
        [map {&quot;users.$_&quot;} @verbose_cols],
  @@ -573,15 +817,27 @@
     
     foreach my $r_row (@$r_ary){
       print ...
  -  }
  -</PRE>
  -<P><A NAME="anchor98"></A>
  +  }</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Another complex query. The user checks checkboxes to be queried by, selects
   from lists and types in match strings, we process input and build the <CODE>@where</CODE> array. Then we want to get the number of matches and the matched rows as
   well.
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor99"></A>
  -<PRE>  my @search_keys = qw(choice1 choice2);
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  my @search_keys = qw(choice1 choice2);
     my @where = ();
       # Process the checkboxes - we turn them into a regular expression
     foreach (@search_keys) {
  @@ -617,21 +873,33 @@
      \@where,
      [&quot;ORDER BY $orderby&quot;,
       &quot;LIMIT $offset,$hits&quot;],
  -  );
  -</PRE>
  -<P><A NAME="anchor100"></A>
  +  );</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   <CODE>sql_get_matched_rows_ary_ref</CODE> knows to handle both <CODE>OR</CODE>ed and
   <CODE>AND</CODE>ed params. This example shows how to use <CODE>OR</CODE> on parameters:
   
  -<P><A NAME="anchor101"></A>
  +<P>
   This snippet is an implementation of a watchdog. Our users want to know
   when their colleagues go online. They register the usernames of the people
   they want to know about. We have to make two queries: one to get a list of
   usernames, the second to find out whether any of these users is online. In
   the second query we use the <CODE>OR</CODE> keyword.
  +
  +<P>
   
  -<P><A NAME="anchor102"></A>
  -<PRE>  # check who we are looking for
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  # check who we are looking for
     $r_ary = $db_obj-&gt;sql_get_matched_rows_ary_ref
       (&quot;watchdog&quot;,
        [qw(watched)],
  @@ -659,60 +927,89 @@
     }
     
     # Now %matched includes the usernames of the users who are being
  -  # watched by $username and currently are online.
  -</PRE>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -	     The <a href="http://www.modperl.com/">
  -	     <B>Writing Apache Modules with Perl and C</B></a>
  -	     book can be purchased online from <a
  -	     href="http://www.ora.com/catalog/wrapmod/">O'Reilly </a>
  -	     and <a
  -	     href="http://www.amazon.com/exec/obidos/ASIN/156592567X/writinapachemodu">
  -	     Amazon.com</a>.
  +  # watched by $username and currently are online.</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    [ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   
  -	     <HR>
   
  -	     <B>Your corrections of either technical or grammatical
  +    <p>
  +    <div class="navbar">
  +      <a href="security.html">Prev</a>                                 |
  +      <A HREF="index.html"         >Contents</A> |
  +      <A HREF="index.html#search"  >Search</A>   |
  +      <A HREF="index.html#download">Download</A> |
  +      <a href="dbm.html">Next</a>
  +    </div>
  +    <p>
  +
  +    <table width="60%" align="center">
  +
  +      <tr>
  +	<td>
  +	  <div class="notice">
  +	  <B>Your corrections of the technical and grammatical
   	     errors are very welcome. You are encouraged to help me
  -	     to improve this guide.  If you have something to
  -	     contribute please <A
  -	     HREF="help.html#Contacting_me"> send it
  +	     improve this guide.  If you have something to contribute
  +	     please <A HREF="help.html#Contacting_me"> send it
   	     directly to me</A>.</B>
  +	  </div>
  +	</td>
  +      </tr>
  +
  +      <tr>
  +	<td>
  +	  <div class="ad">
  +	    The <a href="http://www.modperl.com/">
  +	      <B>Writing Apache Modules with Perl and C</B></a>
  +	    book can be purchased online from <a
  +	      href="http://www.ora.com/catalog/wrapmod/">O'Reilly </a>
  +	    and <a
  +	    href="http://www.amazon.com/exec/obidos/ASIN/156592567X/writinapachemodu">
  +	      Amazon.com</a>.
  +	  </div>
  +	</td>
  +      </tr>
  +
  +</table>
  +
  +<center>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
  +<table cellspacing=2 cellpadding=2>
  +
  +<tr align=center valign=top>
  +<td align=center valign=center>
  +
  +<b><font size=-1>Written by <a
  +href="help.html#Contacting_me">Stas Bekman</a>.<br> Last Modified at 06/04/2000
  +</font></b>
  +<br>
  +
  +</td>
  +
  +<td>
  +
  +<a href="http://perl.apache.org"><img src="images/mod_perl2.jpg"  border=0 alt="mod_perl icon" border=0 height=59 width=150></a>
  +<br>
  +
  +</td>
  +
  +<td>
  +
  +<font size=-2>Use of the Camel for Perl is <br>
  +a trademark of <a href="http://www.ora.com">O'Reilly &amp; Associates</a>,<br>
  +and is used by permission. </font> 
  +<br>
   
  -	     <HR>
  +</td>
   
  -	     [    <A HREF="security.html">Prev</A> |      <A HREF="index.html">Main Page</A> | <A HREF="dbm.html">Next</A>      ]
  +</tr>
  +</table>
  +</center>
   
  -<CENTER><TABLE CELLSPACING=2 CELLPADDING=2 WIDTH="100%" >
  -<TR ALIGN=CENTER VALIGN=TOP>
  -  <TD ALIGN=CENTER VALIGN=CENTER COLSPAN="3">
  -	     <HR>
  -  </TD>
  -</TR>
  -<TR ALIGN=CENTER VALIGN=TOP>
  -  <TD ALIGN=CENTER VALIGN=CENTER>
  -    <B>
  -      <FONT SIZE=-1>
  -	     Written by <A HREF="help.html#Contacting_me">Stas Bekman</A>.
  -	     <BR>Last Modified at 04/29/2000
  -      </FONT>
  -    </B>
  -  </TD>
  -
  -  <TD>
  -	     <A HREF="http://perl.apache.org"><IMG SRC="images/mod_perl2.jpg" ALT="Mod Perl Icon" BORDER=0 HEIGHT=59 WIDTH=150></A>
  -  </TD>
  -
  -  <TD>
  -    <FONT SIZE=-2>
  -	     Use of the Camel for Perl is <BR>
  -	     a trademark of <A HREF="http://www.ora.com">O'Reilly &amp; Associates</A>,<BR>
  -             and is used by permission. 
  -    </FONT> 
  -  </TD>
  -</TR>
  -</TABLE></CENTER>
  -
  -</BODY>
  -</HTML>
  -	    
  \ No newline at end of file
  +</body>
  +</html>
  
  
  
  1.15      +325 -183  modperl-site/guide/dbm.html
  
  Index: dbm.html
  ===================================================================
  RCS file: /home/cvs/modperl-site/guide/dbm.html,v
  retrieving revision 1.14
  retrieving revision 1.15
  diff -u -r1.14 -r1.15
  --- dbm.html	2000/05/12 22:42:51	1.14
  +++ dbm.html	2000/06/07 22:45:30	1.15
  @@ -1,29 +1,37 @@
   <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
  -<HTML>
  -<HEAD>
  -   <TITLE>mod_perl guide: mod_perl and dbm files</TITLE>
  -   <META NAME="GENERATOR" CONTENT="Pod2HTML [Perl/Linux]">
  -   <META NAME="Author" CONTENT="Stas Bekman">
  -   <META NAME="Description" CONTENT="All Apache/Perl related information: Hints, Guidelines, Scenarios and Troubleshottings">
  -   <META NAME="keywords" CONTENT="mod_perl modperl perl apache cgi webserver speed  fast guide mod_perl apache guide help info faq mod_perl installation cgi troubleshooting help no sex speedup free open source OSS mod_perl apache guide">
  -</HEAD>
  -     <LINK REL=STYLESHEET TYPE="text/css"
  -        HREF="style.css" TITLE="refstyle">
  -     <style type="text/css">
  -     <!-- 
  -        @import url(style.css);
  -     -->
  -     
  -     </style>
  -<BODY BGCOLOR="white">
  +<html>
  +  <head>
  +   <title>mod_perl guide: mod_perl and dbm files</title>
  +   <meta name="Author" content="Stas Bekman">
  +   <meta name="Description" content="All Apache/Perl related information: Hints, Guidelines, Scenarios and Troubleshottings">
  +   <meta name="keywords" content="mod_perl modperl perl cgi apache webserver speed fast guide mod_perl apache guide help info faq mod_perl installation cgi troubleshooting help no sex speedup free open source OSS mod_perl apache guide">
  +   <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
  +   <meta name="Classification" content="information">
  +   <link href="style.css" rel=stylesheet type="text/css" title="refstyle">
  +  </head>
  +  <body>
  +
  +    <h1 align=center>
  +      <a href="http://perl.apache.org"><img src="images/mod_perl.gif" alt="Mod Perl Icon" border=0 height=30 width=90 align=left></a>
  +      <a href="http://perl.apache.org"><img src="images/mod_perl.gif" alt="Mod Perl Icon" border=0 height=30 width=90 align=right></a>
  +      mod_perl and dbm files
  +    </h1>
  +    <hr>
  +    <p>
  +    <div class="navbar">
  +      <a href="databases.html">Prev</a>                                 |
  +      <a href="index.html"         >Contents</a> |
  +      <a href="index.html#search"  >Search</a>   |
  +      <a href="index.html#download">Download</a> |
  +      <a href="multiuser.html">Next</a>
  +    </div>
  +    <p>
  +
  +    <div class="toc">
  +      
   <A NAME="toc"></A>
  -<H1 ALIGN=CENTER>
  -<A HREF="http://perl.apache.org"><IMG SRC="images/mod_perl.gif" ALT="Mod Perl Icon" BORDER=0 HEIGHT=30 WIDTH=90 ALIGN=LEFT></A>
  -<A HREF="http://perl.apache.org"><IMG SRC="images/mod_perl.gif" ALT="Mod Perl Icon" BORDER=0 HEIGHT=30 WIDTH=90 ALIGN=RIGHT></A>
  -mod_perl and dbm files</H1>
  -<HR WIDTH="100%">
  -	    [    <A HREF="databases.html">Prev</A> |      <A HREF="index.html">Main Page</A> | <A HREF="multiuser.html">Next</A>      ]<HR><!-- INDEX BEGIN -->
  -<P><B><FONT SIZE=-1>Table of Contents:</FONT></B></P>
  +<P><B>Table of Contents:</B></P>
  +
   <UL>
   
   	<LI><A HREF="#Where_and_Why_to_use_dbm_files">Where and Why to use dbm files</A>
  @@ -34,43 +42,59 @@
   	<LI><A HREF="#Tie_DB_Lock">Tie::DB_Lock</A>
   	<LI><A HREF="#DB_File_Lock2">DB_File::Lock2</A>
   </UL>
  -<!-- INDEX END -->
   
  +    </div>
  +
  +    [ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
   <HR>
  +    <table width="60%" align="center">
  +
  +      <tr>
  +	<td>
  +	  <div class="ad">
  +	    The <a href="http://www.modperl.com/">
  +	      <B>Writing Apache Modules with Perl and C</B></a>
  +	    book can be purchased online from <a
  +	      href="http://www.ora.com/catalog/wrapmod/">O'Reilly </a>
  +	    and <a
  +	    href="http://www.amazon.com/exec/obidos/ASIN/156592567X/writinapachemodu">
  +	      Amazon.com</a>.
  +	  </div>
  +	</td>
  +      </tr>
  +
  +      <tr>
  +	<td>
  +	  <div class="notice">
  +	  <B>Your corrections of the technical and grammatical
  +	     errors are very welcome. You are encouraged to help me
  +	     improve this guide.  If you have something to contribute
  +	     please <A HREF="help.html#Contacting_me"> send it
  +	     directly to me</A>.</B>
  +	  </div>
  +	</td>
  +      </tr>
  +
  +</table>
   
  -	     The <a href="http://www.modperl.com/">
  -	     <B>Writing Apache Modules with Perl and C</B></a>
  -	     book can be purchased online from <a
  -	     href="http://www.ora.com/catalog/wrapmod/">O'Reilly </a>
  -	     and <a
  -	     href="http://www.amazon.com/exec/obidos/ASIN/156592567X/writinapachemodu">
  -	     Amazon.com</a>.
  -
  -	     <HR>
  -
  -	       <B>Your corrections of either technical or grammatical
  -	       errors are very welcome. You are encouraged to help me
  -	       to improve this guide.  If you have something to
  -	       contribute please <A
  -	       HREF="help.html#Contacting_me"> send it
  -	       directly to me</A>.
  -	       </B>
  -	       <HR>
  +    
   
  -	      <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<P><A NAME="anchor0"></A>
  +	    [ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
  +
  +<P>
   <CENTER><H1><A NAME="Where_and_Why_to_use_dbm_files">Where and Why to use dbm files</A></H1></CENTER>
  -<P><A NAME="anchor1"></A>
  +<P>
   Some of the earliest databases implemented on Unix were dbm files, and many
   are still in use today. As of this writing the Berkeley DB is the most
   powerful dbm implementation (http://www.sleepycat.com).
   
  -<P><A NAME="anchor2"></A>
  +<P>
   If you need a light database, with an easy API, using simple key-value
   pairs to store and manipulate a relatively small number of records, this is
   a solution that should be amongst the first you consider.
   
  -<P><A NAME="anchor3"></A>
  +<P>
   With dbm, it is rare to read the whole database into memory. Combine this
   feature with the use of smart storage techniques, and dbm files can be
   manipulated much faster than flat files. Flat file databases can be very
  @@ -78,57 +102,67 @@
   starts to grow into the thousands. Sort algorithms on flat files can be
   very time-consuming.
   
  -<P><A NAME="anchor4"></A>
  +<P>
   The maximum practical size of a dbm database depends on many factors - your
   data, your hardware and the desired response times of course included - but
   as a rough guide consider 5,000 to 10,000 records to be reasonable.
   
  -<P><A NAME="anchor5"></A>
  +<P>
   Several different indexing algorithms can be used with dbm:
   
   <UL>
   <P><LI>
  -<P><A NAME="anchor6"></A>
  +<P>
   The <CODE>HASH</CODE> algorithm gives an <CODE>0(1)</CODE> complexity of search and update, fast insert and delete, but a slow sort
   (which you have to implement yourself).
   
   <P><LI>
  -<P><A NAME="anchor7"></A>
  +<P>
   The <CODE>BTREE</CODE> algorithm allows arbitrary key/value pairs to be stored in a sorted,
   balanced binary tree. This allows us to get a sorted sequence of data pairs
   in <CODE>0(1)</CODE>, but at the expense of much slower insert, update, delete operations than
   is the case with <CODE>HASH</CODE>.
   
   <P><LI>
  -<P><A NAME="anchor8"></A>
  +<P>
   The <CODE>RECNO</CODE> algorithm is more complicated, and enables both fixed-length and
   variable-length flat text files to be manipulated using the same key/value
   pair interface as in <CODE>HASH</CODE> and <CODE>BTREE</CODE>. In this case the key will consist of a record (line) number.
   
   </UL>
  -<P><A NAME="anchor9"></A>
  +<P>
   Most often you will want to use the <CODE>HASH</CODE> method, but there are many considerations and your choice may be dictated
   by your application.
   
  -<P><A NAME="anchor10"></A>
  +<P>
   In recent years dbm databases have been extended to allow you to store more
   complex values, including data structures. The <CODE>MLDBM</CODE> module can store and restore the whole symbol table of your script,
   including arrays and hashes.
   
  -<P><A NAME="anchor11"></A>
  +<P>
   It is important to note that you cannot simply switch a dbm file from one
   storage algorithm to another. The only way to change the algorithm is to
   dump the data to a flat file and then restore it using the new storage
   method. You can use a script like this:
  +
  +<P>
   
  -<P><A NAME="anchor12"></A>
  -<PRE>  #!/usr/bin/perl -w
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  #!/usr/bin/perl -w
     
     #
  -  # This script takes as its parameters a list of Berkeley DB file(s)
  -  # which are stored with the DB_BTREE algorithm.  It will back them up
  -  # using the .bak extension and create instead dbms with the same
  -  # records but stored using the DB_HASH algorithm
  +  # This script takes as its parameters a list of Berkeley DB
  +  # file(s) which are stored with the DB_BTREE algorithm.  It
  +  # will back them up using the .bak extension and create
  +  # instead dbms with the same records but stored using the
  +  # DB_HASH algorithm
     #
     # Usage: btree2hash.pl filename(s)
     
  @@ -140,7 +174,8 @@
     
     foreach my $filename (@ARGV) {
     
  -    die &quot;Can't find $filename: $!\n&quot; unless -e $filename and -r $filename;
  +    die &quot;Can't find $filename: $!\n&quot; 
  +      unless -e $filename and -r $filename;
     
         # First backup the file
       rename &quot;$filename&quot;, &quot;$filename.btree&quot; 
  @@ -161,31 +196,35 @@
         # untie
       untie %btree ;
       untie %hash ;
  -  }
  -</PRE>
  -<P><A NAME="anchor13"></A>
  +  }</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Note that some dbm implementations come with other conversion utilities as
   well.
   
  -<P><A NAME="anchor14"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H1><A NAME="mod_perl_and_dbm">mod_perl and dbm</A></H1></CENTER>
  -<P><A NAME="anchor15"></A>
  +<P>
   Where does mod_perl fit into the picture?
   
  -<P><A NAME="anchor16"></A>
  +<P>
   If you are using a read only dbm file you can have it work faster if you
   keep it open (tied) all the time, so that when your CGI script wants to
   access the database it is already tied and ready to be used. This will work
   with dynamic (read/write) databases as well, but you need to use locking
   and data flushing to avoid data corruption.
   
  -<P><A NAME="anchor17"></A>
  +<P>
   Although mod_perl and dbm can give huge performance gains to CGI scripts
   which manipulate flat files, you should be very careful. In addition to the
   need for locking, you need to consider the consequences of <CODE>die()</CODE> and unexpected process deaths.
   
  -<P><A NAME="anchor18"></A>
  +<P>
   If your locking mechanism cannot handle dropped locks, a stale lock can
   deactivate your whole site. You can enter a deadlock situation if two
   processes simultaneously try to acquire locks on two separate databases.
  @@ -194,71 +233,85 @@
   the other process. If your processes all ask for their DB files in the same
   order, this situation cannot occur.
   
  -<P><A NAME="anchor19"></A>
  +<P>
   If you modify the DB you should be make very sure that you flush the data
   and synchronize it, especially when the process serving your CGI
   unexpectedly dies. In general your application should be tested very
   thoroughly before you put it into production to handle important data.
   
  -<P><A NAME="anchor20"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H1><A NAME="Locking_dbm_handlers">Locking dbm handlers</A></H1></CENTER>
  -<P><A NAME="anchor21"></A>
  +<P>
   Let's make the lock status a global variable, so it will persist from
  -request to request. Before we request a lock - <EM>READ</EM> (shared) or 
  +request to request. Before we request a lock - <EM>READ</EM> (shared) or
   <EM>WRITE</EM> (exclusive) - we should first obtain the current lock status.
   
  -<P><A NAME="anchor22"></A>
  +<P>
   If we are making a <EM>READ</EM> lock request, it is granted as soon as the file becomes unlocked or if it
   is already <EM>READ</EM> locked. The lock status becomes <EM>READ</EM> on success.
   
  -<P><A NAME="anchor23"></A>
  +<P>
   If we make a <EM>WRITE</EM> lock request, it is granted as soon as the file becomes unlocked. The lock
   status becomes <EM>WRITE</EM> on success.
   
  -<P><A NAME="anchor24"></A>
  +<P>
   The treatment of the <EM>WRITE</EM> lock request is most important.
   
  -<P><A NAME="anchor25"></A>
  +<P>
   If the DB is <EM>READ</EM> locked, a process that makes a <EM>WRITE</EM> request will poll until there are no reading or writing processes left.
   Lots of processes can successfully read the file, since they do not block
   each other. This means that a process that wants to write to the file (so
   first it needs to obtain an exclusive lock) may never get a chance to
   squeeze in. The following diagram represents a possible scenario where
   everybody can read but no one can write:
  +
  +<P>
   
  -<P><A NAME="anchor26"></A>
  -<PRE>  [-p1-]                 [--p1--]
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  [-p1-]                 [--p1--]
        [--p2--]
      [---------p3---------]
                    [------p4-----]
  -     [--p5--]   [----p5----]
  -</PRE>
  -<P><A NAME="anchor27"></A>
  +     [--p5--]   [----p5----]</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   The result is a starving process, which will timeout the request, and it
   will fail to update the DB. This is a good reason not to cache the dbm
   handle with dynamic dbm files. It will work perfectly with static DBM files
   without any need to lock files at all.
   
  -<P><A NAME="anchor28"></A>
  +<P>
   Ken Williams solved the above problem with his
   <A HREF="././dbm.html#Tie_DB_Lock"><CODE>Tie::DB_Lock</CODE></A> module, which I will discuss in one of the following sections.
   
  -<P><A NAME="anchor29"></A>
  +<P>
   There are several locking wrappers for <CODE>DB_File</CODE> in CPAN right now. Each one implements locking differently and has
   different goals in mind. It is therefore worth knowing the difference, so
   that you can pick the right one for your application.
   
  -<P><A NAME="anchor30"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H1><A NAME="Flawed_Locking_Methods_Which_Mus">Flawed Locking Methods Which Must Not Be Used</A></H1></CENTER>
  -<P><A NAME="anchor31"></A>
  +<P>
   <EM>Caution</EM>: The suggested locking methods in the Camel book and
   <CODE>DB_File</CODE> man page (at least before version 1.72) are flawed. If you use them in an
   environment where more than one process can modify the dbm file, it can get
   corrupted!!! The following is an explanation of why this happens.
   
  -<P><A NAME="anchor32"></A>
  +<P>
   You may not use a tied file's filehandle for locking, since you get the
   filehandle after the file has been already tied. It's too late to lock. The
   problem is that the database file is locked <EM>after</EM> it is opened. When the database is opened, the first 4k (in Berkley dbm
  @@ -269,29 +322,30 @@
   view of the database. If it writes using this view it may easily corrupt
   the database on disk.
   
  -<P><A NAME="anchor33"></A>
  +<P>
   This problem can be difficult to trace because it does not cause corruption
   every time a process has to wait for a lock. One can do quite a bit of
   writing to a database file without actually changing the first 4k. But once
   you suspect this problem you can easily reproduce it by making your program
   modify the records in the first 4k of the DB.
   
  -<P><A NAME="anchor34"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H1><A NAME="Lock_Wrappers_Overview">Lock Wrappers Overview</A></H1></CENTER>
  -<P><A NAME="anchor35"></A>
  +<P>
   There are five locking wrappers known to me:
   
   <UL>
   <P><LI>
  -<P><A NAME="anchor36"></A>
  +<P>
   <CODE>Tie::DB_Lock</CODE> -- <CODE>DB_File</CODE> wrapper which creates copies of the database file for read access, so that
   you have kind of a multiversioning concurrent read system. However, updates
   are still serial. Use this for databases where reads may be lengthy and
   consistency problems may occur.  <A HREF="././dbm.html#Tie_DB_Lock">More information</A>.
   
   <P><LI>
  -<P><A NAME="anchor37"></A>
  +<P>
   <CODE>Tie::DB_LockFile</CODE> -- <CODE>DB_File</CODE> wrapper that has the ability to lock and unlock the database while it is
   being used. Avoids the tie-before-flock problem by simply re-tie-ing the
   database when you get or drop a lock. Because of the flexibility in
  @@ -301,7 +355,7 @@
   <CODE>Tie::DB_LockFile</CODE> manpage for more information.
   
   <P><LI>
  -<P><A NAME="anchor38"></A>
  +<P>
   <CODE>DB_File::Lock</CODE> -- extremely lightweight <CODE>DB_File</CODE> wrapper that simply flocks a lockfile before tie-ing the database and drops
   the lock after the untie. Allows one to use the same lockfile for multiple
   databases to avoid deadlock problems, if desired. Use this for databases
  @@ -309,53 +363,67 @@
   enough. Refer to <CODE>DB_File::Lock</CODE> manpage for more information.
   
   <P><LI>
  -<P><A NAME="anchor39"></A>
  +<P>
   <A HREF="././dbm.html#DB_File_Lock2"><CODE>DB_File::Lock2</CODE></A> -- does the same thing as
   <CODE>DB_File::Lock</CODE>, but has a slightly different implementation. I wrote it before David
   Harris released his <CODE>DB_File::Lock</CODE> and I didn't want to kill mine, so I'll keep it here for a while :).
   
   <P><LI>
  -<P><A NAME="anchor40"></A>
  +<P>
   On some Operating Systems (FreeBSD is one example) it is possible to lock
   on tie:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor41"></A>
  -<PRE>  tie my %t, 'DB_File', $TOK_FILE, O_RDWR | O_EXLOCK, 0664;
  -</PRE>
  -<P><A NAME="anchor42"></A>
  -and only release the lock by un-tie-ing the file. Check if the 
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  tie my %t, 'DB_File', $TOK_FILE, O_RDWR | O_EXLOCK, 0664;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +and only release the lock by un-tie-ing the file. Check if the
   <CODE>O_EXLOCK</CODE> flag is available on your operating system before you try to use this
   method!
   
   </UL>
  -<P><A NAME="anchor43"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H1><A NAME="Tie_DB_Lock">Tie::DB_Lock</A></H1></CENTER>
  -<P><A NAME="anchor44"></A>
  +<P>
   <CODE>Tie::DB_Lock</CODE> ties hashes to databases using shared and exclusive locks. This module, by
   Ken Williams, solves the problems raised in the previous section.
   
  -<P><A NAME="anchor45"></A>
  +<P>
   The main difference from what I have described above is that
   <CODE>Tie::DB_Lock</CODE> copies a dbm file on read. Reading processes do not have to keep the file
   locked while they read it, and writing processes can still access the file
   while others are reading. This works best when you have lots of
   long-duration reading, and a few short bursts of writing.
   
  -<P><A NAME="anchor46"></A>
  +<P>
   The drawback of this module is the heavy IO performed when every reader
   makes a fresh copy of the DB. With big dbm files this can be quite a
   disadvantage and can slow the server down considerably.
   
  -<P><A NAME="anchor47"></A>
  +<P>
   An alternative would be to have one copy of the dbm image shared by all the
   reading processes. This can cut the number of files that are copied, and
   puts the responsibility of copying the read-only file on the writer, not
   the reader. It would need some care to make sure it does not disturb
   readers when putting a new read-only copy into place.
   
  -<P><A NAME="anchor48"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H1><A NAME="DB_File_Lock2">DB_File::Lock2</A></H1></CENTER>
   
   	       <p><a href="code/DB_File-Lock2.pm"><code>DB_File-Lock2.pm</code></a> -- Here is C<DB_File::Lock2> which does the
  @@ -367,34 +435,67 @@
   not yet on CPAN and so is listed here in its entirety. Note also that this
   code still needs some testing, so <EM>be careful</EM> if you use it on a production machine.
   
  -<P><A NAME="anchor49"></A>
  +<P>
   You use it like this:
  +
  +<P>
   
  -<P><A NAME="anchor50"></A>
  -<PRE>  use DB_File::Lock2 ();
  -</PRE>
  -<P><A NAME="anchor51"></A>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  use DB_File::Lock2 ();</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   A simple tie, READ lock and untie
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor52"></A>
  -<PRE>  use DB_File::Lock2 ();
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  use DB_File::Lock2 ();
     my $dbfile = &quot;/tmp/test&quot;;
     tie my %mydb, 'DB_File::Lock2', $dbfile, 'read';
     print $mydb{foo} if exists $mydb{foo};
  -  untie %mydb;
  -</PRE>
  -<P><A NAME="anchor53"></A>
  +  untie %mydb;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   You can even skip the <CODE>untie()</CODE> call. When <CODE>$mydb</CODE> goes out of scope everything will be done automatically. However it is
   better to use the explicit call, to make sure the critical sections between
   lock and unlock are as short as possible. This is especially important when
   requesting an exclusive (write) lock.
   
  -<P><A NAME="anchor54"></A>
  +<P>
   The following example shows how it might be convenient to skip the explicit <CODE>untie()</CODE>. In this example, we don't need to save the intermediate result, we just
   return and the cleanup is done automatically.
  +
  +<P>
   
  -<P><A NAME="anchor55"></A>
  -<PRE>  use DB_File::Lock2 ();
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  use DB_File::Lock2 ();
     my $dbfile = &quot;/tmp/test&quot;;
     print user_exists(&quot;stas&quot;) ? &quot;Yes&quot; : &quot;No&quot;;
     sub user_exists{
  @@ -407,15 +508,27 @@
       # if we match the username return 1, else 0
       return $mydb{$username} ? 1 : 0;
     
  -  } # end of sub user_exists
  -</PRE>
  -<P><A NAME="anchor56"></A>
  +  } # end of sub user_exists</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Now let's write all the upper case characters and their respective ASCII
   values to a dbm file. Then read the file and print the contents of the DB,
   unsorted.
  +
  +<P>
   
  -<P><A NAME="anchor57"></A>
  -<PRE>  use DB_File::Lock2 ();
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  use DB_File::Lock2 ();
     my $dbfile = &quot;/tmp/test&quot;;
     
       # write 
  @@ -431,65 +544,94 @@
     while (my($k,$v) = each %mydb) {
       print &quot;$k =&gt; $v\n&quot;;
     }
  -  untie %mydb;
  -</PRE>
  -<P><A NAME="anchor58"></A>
  +  untie %mydb;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   If your CGI script is interrupted, the <CODE>DESTROY</CODE> block will take care of unlocking the dbm file and flush any changes. So
   your DB will be safe against possible corruption because of unclean program
   termination.
   
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -	     The <a href="http://www.modperl.com/">
  -	     <B>Writing Apache Modules with Perl and C</B></a>
  -	     book can be purchased online from <a
  -	     href="http://www.ora.com/catalog/wrapmod/">O'Reilly </a>
  -	     and <a
  -	     href="http://www.amazon.com/exec/obidos/ASIN/156592567X/writinapachemodu">
  -	     Amazon.com</a>.
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   
  -	     <HR>
   
  -	     <B>Your corrections of either technical or grammatical
  +    <p>
  +    <div class="navbar">
  +      <a href="databases.html">Prev</a>                                 |
  +      <A HREF="index.html"         >Contents</A> |
  +      <A HREF="index.html#search"  >Search</A>   |
  +      <A HREF="index.html#download">Download</A> |
  +      <a href="multiuser.html">Next</a>
  +    </div>
  +    <p>
  +
  +    <table width="60%" align="center">
  +
  +      <tr>
  +	<td>
  +	  <div class="notice">
  +	  <B>Your corrections of the technical and grammatical
   	     errors are very welcome. You are encouraged to help me
  -	     to improve this guide.  If you have something to
  -	     contribute please <A
  -	     HREF="help.html#Contacting_me"> send it
  +	     improve this guide.  If you have something to contribute
  +	     please <A HREF="help.html#Contacting_me"> send it
   	     directly to me</A>.</B>
  +	  </div>
  +	</td>
  +      </tr>
  +
  +      <tr>
  +	<td>
  +	  <div class="ad">
  +	    The <a href="http://www.modperl.com/">
  +	      <B>Writing Apache Modules with Perl and C</B></a>
  +	    book can be purchased online from <a
  +	      href="http://www.ora.com/catalog/wrapmod/">O'Reilly </a>
  +	    and <a
  +	    href="http://www.amazon.com/exec/obidos/ASIN/156592567X/writinapachemodu">
  +	      Amazon.com</a>.
  +	  </div>
  +	</td>
  +      </tr>
  +
  +</table>
  +
  +<center>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
  +<table cellspacing=2 cellpadding=2>
  +
  +<tr align=center valign=top>
  +<td align=center valign=center>
  +
  +<b><font size=-1>Written by <a
  +href="help.html#Contacting_me">Stas Bekman</a>.<br> Last Modified at 05/27/2000
  +</font></b>
  +<br>
  +
  +</td>
  +
  +<td>
  +
  +<a href="http://perl.apache.org"><img src="images/mod_perl2.jpg"  border=0 alt="mod_perl icon" border=0 height=59 width=150></a>
  +<br>
  +
  +</td>
  +
  +<td>
  +
  +<font size=-2>Use of the Camel for Perl is <br>
  +a trademark of <a href="http://www.ora.com">O'Reilly &amp; Associates</a>,<br>
  +and is used by permission. </font> 
  +<br>
   
  -	     <HR>
  +</td>
   
  -	     [    <A HREF="databases.html">Prev</A> |      <A HREF="index.html">Main Page</A> | <A HREF="multiuser.html">Next</A>      ]
  +</tr>
  +</table>
  +</center>
   
  -<CENTER><TABLE CELLSPACING=2 CELLPADDING=2 WIDTH="100%" >
  -<TR ALIGN=CENTER VALIGN=TOP>
  -  <TD ALIGN=CENTER VALIGN=CENTER COLSPAN="3">
  -	     <HR>
  -  </TD>
  -</TR>
  -<TR ALIGN=CENTER VALIGN=TOP>
  -  <TD ALIGN=CENTER VALIGN=CENTER>
  -    <B>
  -      <FONT SIZE=-1>
  -	     Written by <A HREF="help.html#Contacting_me">Stas Bekman</A>.
  -	     <BR>Last Modified at 05/01/2000
  -      </FONT>
  -    </B>
  -  </TD>
  -
  -  <TD>
  -	     <A HREF="http://perl.apache.org"><IMG SRC="images/mod_perl2.jpg" ALT="Mod Perl Icon" BORDER=0 HEIGHT=59 WIDTH=150></A>
  -  </TD>
  -
  -  <TD>
  -    <FONT SIZE=-2>
  -	     Use of the Camel for Perl is <BR>
  -	     a trademark of <A HREF="http://www.ora.com">O'Reilly &amp; Associates</A>,<BR>
  -             and is used by permission. 
  -    </FONT> 
  -  </TD>
  -</TR>
  -</TABLE></CENTER>
  -
  -</BODY>
  -</HTML>
  -	    
  \ No newline at end of file
  +</body>
  +</html>
  
  
  
  1.24      +4397 -1760modperl-site/guide/debug.html
  
  Index: debug.html
  ===================================================================
  RCS file: /home/cvs/modperl-site/guide/debug.html,v
  retrieving revision 1.23
  retrieving revision 1.24
  diff -u -r1.23 -r1.24
  --- debug.html	2000/05/12 22:42:51	1.23
  +++ debug.html	2000/06/07 22:45:30	1.24
  @@ -1,40 +1,52 @@
   <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
  -<HTML>
  -<HEAD>
  -   <TITLE>mod_perl guide: Debugging mod_perl</TITLE>
  -   <META NAME="GENERATOR" CONTENT="Pod2HTML [Perl/Linux]">
  -   <META NAME="Author" CONTENT="Stas Bekman">
  -   <META NAME="Description" CONTENT="All Apache/Perl related information: Hints, Guidelines, Scenarios and Troubleshottings">
  -   <META NAME="keywords" CONTENT="mod_perl modperl perl apache cgi webserver speed  fast guide mod_perl apache guide help info faq mod_perl installation cgi troubleshooting help no sex speedup free open source OSS mod_perl apache guide">
  -</HEAD>
  -     <LINK REL=STYLESHEET TYPE="text/css"
  -        HREF="style.css" TITLE="refstyle">
  -     <style type="text/css">
  -     <!-- 
  -        @import url(style.css);
  -     -->
  -     
  -     </style>
  -<BODY BGCOLOR="white">
  +<html>
  +  <head>
  +   <title>mod_perl guide: Debugging mod_perl</title>
  +   <meta name="Author" content="Stas Bekman">
  +   <meta name="Description" content="All Apache/Perl related information: Hints, Guidelines, Scenarios and Troubleshottings">
  +   <meta name="keywords" content="mod_perl modperl perl cgi apache webserver speed fast guide mod_perl apache guide help info faq mod_perl installation cgi troubleshooting help no sex speedup free open source OSS mod_perl apache guide">
  +   <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
  +   <meta name="Classification" content="information">
  +   <link href="style.css" rel=stylesheet type="text/css" title="refstyle">
  +  </head>
  +  <body>
  +
  +    <h1 align=center>
  +      <a href="http://perl.apache.org"><img src="images/mod_perl.gif" alt="Mod Perl Icon" border=0 height=30 width=90 align=left></a>
  +      <a href="http://perl.apache.org"><img src="images/mod_perl.gif" alt="Mod Perl Icon" border=0 height=30 width=90 align=right></a>
  +      Debugging mod_perl
  +    </h1>
  +    <hr>
  +    <p>
  +    <div class="navbar">
  +      <a href="multiuser.html">Prev</a>                                 |
  +      <a href="index.html"         >Contents</a> |
  +      <a href="index.html#search"  >Search</a>   |
  +      <a href="index.html#download">Download</a> |
  +      <a href="browserbugs.html">Next</a>
  +    </div>
  +    <p>
  +
  +    <div class="toc">
  +      
   <A NAME="toc"></A>
  -<H1 ALIGN=CENTER>
  -<A HREF="http://perl.apache.org"><IMG SRC="images/mod_perl.gif" ALT="Mod Perl Icon" BORDER=0 HEIGHT=30 WIDTH=90 ALIGN=LEFT></A>
  -<A HREF="http://perl.apache.org"><IMG SRC="images/mod_perl.gif" ALT="Mod Perl Icon" BORDER=0 HEIGHT=30 WIDTH=90 ALIGN=RIGHT></A>
  -Debugging mod_perl</H1>
  -<HR WIDTH="100%">
  -	    [    <A HREF="multiuser.html">Prev</A> |      <A HREF="index.html">Main Page</A> | <A HREF="browserbugs.html">Next</A>      ]<HR><!-- INDEX BEGIN -->
  -<P><B><FONT SIZE=-1>Table of Contents:</FONT></B></P>
  +<P><B>Table of Contents:</B></P>
  +
   <UL>
   
  -	<LI><A HREF="#Curing_The_Internal_Server_Erro">Curing The &quot;Internal Server Error&quot;</A>
  -	<LI><A HREF="#Helping_error_log_to_Help_Us">Helping error_log to Help Us</A>
  -	<LI><A HREF="#The_Importance_of_Warnings">The Importance of Warnings</A>
  +	<LI><A HREF="#Warning_and_Errors_Explained">Warning and Errors Explained</A>
   	<UL>
  +
  +		<LI><A HREF="#Curing_The_Internal_Server_Erro">Curing The &quot;Internal Server Error&quot;</A>
  +		<LI><A HREF="#Helping_error_log_to_Help_Us">Helping error_log to Help Us</A>
  +		<LI><A HREF="#The_Importance_of_Warnings">The Importance of Warnings</A>
  +		<UL>
   
  -		<LI><A HREF="#diagnostics_pragma">diagnostics pragma</A>
  +			<LI><A HREF="#diagnostics_pragma">diagnostics pragma</A>
  +		</UL>
  +
   	</UL>
   
  -	<LI><A HREF="#Monitoring_the_error_log_file">Monitoring the error_log file</A>
   	<LI><A HREF="#Hanging_Processes_Detection_and">Hanging Processes: Detection and Diagnostics</A>
   	<UL>
   
  @@ -80,11 +92,6 @@
   
   		<LI><A HREF="#mod_status">mod_status</A>
   		<LI><A HREF="#Apache_VMonitor_Visual_Syste">Apache::VMonitor - Visual System and Apache Server Monitor</A>
  -		<UL>
  -
  -			<LI><A HREF="#Configuration">Configuration</A>
  -		</UL>
  -
   	</UL>
   
   	<LI><A HREF="#Sometimes_My_Script_Works_Somet">Sometimes My Script Works, Sometimes It Does Not</A>
  @@ -111,7 +118,6 @@
   		<LI><A HREF="#Debugging_core_Dumping_Code">Debugging core Dumping Code</A>
   	</UL>
   
  -	<LI><A HREF="#PERL_DESTRUCT_LEVEL_Environment_">PERL_DESTRUCT_LEVEL Environment Variable</A>
   	<LI><A HREF="#PERL_DEBUG_1_Build_Option">PERL_DEBUG=1 Build Option</A>
   	<LI><A HREF="#Apache_Debug">Apache::Debug</A>
   	<LI><A HREF="#Debug_Tracing">Debug Tracing</A>
  @@ -124,81 +130,159 @@
   	<LI><A HREF="#Apache_DumpHeaders_Watch_HTTP">Apache::DumpHeaders - Watch HTTP Transaction Via Headers</A>
   	<LI><A HREF="#Apache_DebugInfo_Log_Various_">Apache::DebugInfo - Log Various Bits Of Per-Request Data</A>
   </UL>
  -<!-- INDEX END -->
   
  +    </div>
  +
  +    [ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
  +    <table width="60%" align="center">
  +
  +      <tr>
  +	<td>
  +	  <div class="ad">
  +	    The <a href="http://www.modperl.com/">
  +	      <B>Writing Apache Modules with Perl and C</B></a>
  +	    book can be purchased online from <a
  +	      href="http://www.ora.com/catalog/wrapmod/">O'Reilly </a>
  +	    and <a
  +	    href="http://www.amazon.com/exec/obidos/ASIN/156592567X/writinapachemodu">
  +	      Amazon.com</a>.
  +	  </div>
  +	</td>
  +      </tr>
  +
  +      <tr>
  +	<td>
  +	  <div class="notice">
  +	  <B>Your corrections of the technical and grammatical
  +	     errors are very welcome. You are encouraged to help me
  +	     improve this guide.  If you have something to contribute
  +	     please <A HREF="help.html#Contacting_me"> send it
  +	     directly to me</A>.</B>
  +	  </div>
  +	</td>
  +      </tr>
  +
  +</table>
  +
  +    
  +
  +	    [ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
   <HR>
   
  -	     The <a href="http://www.modperl.com/">
  -	     <B>Writing Apache Modules with Perl and C</B></a>
  -	     book can be purchased online from <a
  -	     href="http://www.ora.com/catalog/wrapmod/">O'Reilly </a>
  -	     and <a
  -	     href="http://www.amazon.com/exec/obidos/ASIN/156592567X/writinapachemodu">
  -	     Amazon.com</a>.
  -
  -	     <HR>
  -
  -	       <B>Your corrections of either technical or grammatical
  -	       errors are very welcome. You are encouraged to help me
  -	       to improve this guide.  If you have something to
  -	       contribute please <A
  -	       HREF="help.html#Contacting_me"> send it
  -	       directly to me</A>.
  -	       </B>
  -	       <HR>
  -
  -	      <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<P><A NAME="anchor0"></A>
  -<CENTER><H1><A NAME="Curing_The_Internal_Server_Erro">Curing The &quot;Internal Server Error&quot;</A></H1></CENTER>
  -<P><A NAME="anchor1"></A>
  +<P>
  +<CENTER><H1><A NAME="Warning_and_Errors_Explained">Warning and Errors Explained</A></H1></CENTER>
  +<P>
  +Let's talk first about things that bother most web (and non-web)
  +programmers. <EM>The bothering things</EM> are warning and errors reported by Perl. We are going to learn how to take
  +the best out of both, by turning this obvious to the newbie programmer
  +enemies into our best friends.
  +
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
  +<CENTER><H2><A NAME="Curing_The_Internal_Server_Erro">Curing The &quot;Internal Server Error&quot;</A></H2></CENTER>
  +<P>
   You have just installed this new CGI script and when you try it out you see
   the grey screen of death saying ``Internal Server Error''... Or even worse
   you have a script running on a production server for a long time without
   problems, when the same grey screen starts to show up occasionally for no
   apparent reason.
   
  -<P><A NAME="anchor2"></A>
  +<P>
   How can we find out what the problem is?
   
  -<P><A NAME="anchor3"></A>
  +<P>
   First problem:
   
  -<P><A NAME="anchor4"></A>
  +<P>
   You have been coding in Perl for years, and whenever an error occurred in
   the past it was displayed in the same terminal window that you started the
   script from. But when you work with a webserver there is no terminal to
   show you the errors, since the server in most cases has no terminal to send
   the error messages to.
   
  -<P><A NAME="anchor5"></A>
  +<P>
   Actually, the error messages don't disappear, they end up in the
   <EM>error_log</EM> file. It is located in the directory specified by the
   <CODE>ErrorLog</CODE> directive in <EM>httpd.conf</EM>. The default setting is generally:
   
  -<P><A NAME="anchor6"></A>
  -<PRE>  ErrorLog /usr/local/apache/logs/error_log
  -</PRE>
  -<P><A NAME="anchor7"></A>
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  ErrorLog /usr/local/apache/logs/error_log</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   So whenever you see <EM>"Internal Server Error"</EM> it's time to look at this file.
   
  -<P><A NAME="anchor8"></A>
  +<P>
   First problem solved!
   
  -<P><A NAME="anchor9"></A>
  +<P>
  +There are cases when errors don't go to the error_log file. For example,
  +some errors go to the httpd process' STDERR. If you haven't redirected
  +httpd's STDERR then the messages are printed to the console (tty, terminal)
  +from which you executed the httpd. This happens when the server didn't get
  +as far as opening the error_log file for writing before it needed to write
  +an error message.
  +
  +<P>
  +For example, if you have entered a non-existent directory path in your
  +<CODE>ErrorLog</CODE> directive, the error message will be printed to STDERR. If the error
  +happens when the server executes a <CODE>PerlRequire</CODE> or
  +<CODE>PerlModule</CODE> directive you might also see output sent to STDERR.
  +
  +<P>
  +You are probably wondering where all the errors go when you are running the
  +server in single process mode (<CODE>httpd -X</CODE>). They go to STDERR. This is because the error logging for all the httpd
  +children is normally done by the parent httpd. When httpd runs in single
  +process mode, it has no parent httpd process to perform all the logging.
  +The output to the terminal includes all the status messages that normally
  +go to the error_log file.
  +
  +<P>
  +Finally with a <CODE>PerlLogHandler</CODE> you can take away from Apache its control of the error logging process for
  +all HTTP transactions. If you do this, then you are responsible for
  +generating and storing the error messages. You can do whatever you like
  +with the information, (including throwing it away -- don't do it!) and,
  +depending on how you implement you <CODE>LogHandler</CODE>, the <CODE>ErrorLog</CODE> directive may have no effect. But you can also do something at this handler
  +and then return
  +<CODE>DECLINED</CODE> status, so the default Apache LogHandler will do the work as usual.
  +
  +<P>
   Second problem:
   
  -<P><A NAME="anchor10"></A>
  +<P>
   The usefulness of the error message depends to some extent on the
   programmer's coding style. An uninformative message might not help you to
   spot and fix the error.
   
  -<P><A NAME="anchor11"></A>
  +<P>
   For example, let's take a function which opens a file passed to it as a
   parameter. It does nothing else with the file. Here's our first version of
   the code:
  +
  +<P>
   
  -<P><A NAME="anchor12"></A>
  -<PRE>  my $r = shift;
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  my $r = shift;
     $r-&gt;send_http_header('text/plain');
     
     sub open_file{
  @@ -208,453 +292,654 @@
       open FILE, $filename or die;
     }
     
  -  open_file(&quot;/tmp/test.txt&quot;);
  -</PRE>
  -<P><A NAME="anchor13"></A>
  +  open_file(&quot;/tmp/test.txt&quot;);</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Let's assume that <CODE>/tmp/test.txt</CODE> doesn't exist so the <CODE>open()</CODE> will fail to open the file. When
   we call this script from our browser, the browser returns an <EM>"internal error"</EM> message and we see the following error appended to <EM>error_log</EM>:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor14"></A>
  -<PRE>  Died at /home/httpd/perl/test.pl line 9.
  -</PRE>
  -<P><A NAME="anchor15"></A>
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  Died at /home/httpd/perl/test.pl line 9.</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   We can use the hint Perl kindly gave to us to find where in the code the
   <CODE>die()</CODE> was called. However, we still don't know what filename
   was passed to this subroutine to cause the program termination.
   
  -<P><A NAME="anchor16"></A>
  +<P>
   If we have only one function call as in the example above, the task of
   finding the problematic filename will be trivial. Now let's add two more
   <CODE>open_file()</CODE> function calls and assume that among the three
   files only <EM>/tmp/test2.txt</EM> exists:
   
  -<P><A NAME="anchor17"></A>
  -<PRE>  open_file(&quot;/tmp/test.txt&quot;);
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  open_file(&quot;/tmp/test.txt&quot;);
     open_file(&quot;/tmp/test2.txt&quot;);
  -  open_file(&quot;/tmp/test3.txt&quot;);
  -</PRE>
  -<P><A NAME="anchor18"></A>
  +  open_file(&quot;/tmp/test3.txt&quot;);</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   When you execute the above call, you will see the same error message twice:
  +
  +<P>
   
  -<P><A NAME="anchor19"></A>
  -<PRE>  Died at /home/httpd/perl/test.pl line 9.
  -  Died at /home/httpd/perl/test.pl line 9.
  -</PRE>
  -<P><A NAME="anchor20"></A>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  Died at /home/httpd/perl/test.pl line 9.
  +  Died at /home/httpd/perl/test.pl line 9.</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Based on this error message, can you tell what files your program failed to
   open? Probably not. Let's fix it by passing the name of the file to
   <CODE>die():</CODE>
  +
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
   
  -<P><A NAME="anchor21"></A>
  -<PRE>  sub open_file{
  +	<td>
  +	  <pre>  sub open_file{
       my $filename = shift || '';
       die &quot;No filename passed!&quot; unless $filename;
       open FILE, $filename or die &quot;failed to open $filename&quot;;
     }
     
  -  open_file(&quot;/tmp/test.txt&quot;);
  -</PRE>
  -<P><A NAME="anchor22"></A>
  +  open_file(&quot;/tmp/test.txt&quot;);</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   When we execute the above code, we see:
   
  -<P><A NAME="anchor23"></A>
  -<PRE>  failed to open /tmp/test.txt at /home/httpd/perl/test.pl line 9.
  -</PRE>
  -<P><A NAME="anchor24"></A>
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  failed to open /tmp/test.txt at /home/httpd/perl/test.pl line 9.</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   which makes a big difference.
   
  -<P><A NAME="anchor25"></A>
  +<P>
   By the way, if you append a newline to the end of the message you pass to
   <CODE>die(),</CODE> Perl won't report the line number the error has
   happened at, so if you code:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor26"></A>
  -<PRE>  open FILE, $filename or die &quot;failed to open a file\n&quot;;
  -</PRE>
  -<P><A NAME="anchor27"></A>
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  open FILE, $filename or die &quot;failed to open a file\n&quot;;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   The error message will be:
   
  -<P><A NAME="anchor28"></A>
  -<PRE>  failed to open a file
  -</PRE>
  -<P><A NAME="anchor29"></A>
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  failed to open a file</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Which gives you very little to go on. It's very hard to debug with such
   uninformative error messages.
   
  -<P><A NAME="anchor30"></A>
  +<P>
   The <CODE>warn()</CODE> function, a kinder sister of <CODE>die(),</CODE>
   which logs the message but doesn't cause program termination, behaves in
   the same way. If you add a newline to the end of the message, the line
   number <CODE>warn()</CODE> was called at won't be logged, otherwise it
   will.
   
  -<P><A NAME="anchor31"></A>
  +<P>
   You might want to use <CODE>warn()</CODE> instead of <CODE>die()</CODE> if
   the failure isn't critical. Consider the following code:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor32"></A>
  -<PRE>  if(open FILE, $filename){
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  if(open FILE, $filename){
       # do something with file
     } else {
       warn &quot;failed to open $filename&quot;;
     } 
  -  # more code here...
  -</PRE>
  -<P><A NAME="anchor33"></A>
  +  # more code here...</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Now we've improved our code, by reporting the names of the problematic
   files, but we still don't know the reason for the failure. Let's try to
   improve the <CODE>warn()</CODE> example. The <CODE>-r</CODE> operator tests whether the file is readable:
  +
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
   
  -<P><A NAME="anchor34"></A>
  -<PRE>  if(-r $filename){
  +	<td>
  +	  <pre>  if(-r $filename){
       open FILE, $filename;
       # do something with file
     } else {
       warn &quot;Couldn't open $filename - doesn't exist or is not readable&quot;;
  -  } 
  -</PRE>
  -<P><A NAME="anchor35"></A>
  +  } </pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Now if we cannot read the file we do not even try to open it. But we still
   see a warning in error_log:
  +
  +<P>
   
  -<P><A NAME="anchor36"></A>
  -<PRE>  Couldn't open /tmp/test.txt - doesn't exist or is not readable
  -  at /home/httpd/perl/test.pl line 9.
  -</PRE>
  -<P><A NAME="anchor37"></A>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  Couldn't open /tmp/test.txt - doesn't exist or is not readable
  +  at /home/httpd/perl/test.pl line 9.</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   The warning tells us the reason for the failure, so we don't have to go to
   the code and check what it was trying to do with the file.
   
  -<P><A NAME="anchor38"></A>
  +<P>
   It could be quite a coding overhead to explain all the possible failure
   reasons that way, but why reinvent the wheel? We already have the reason
   for the failure stored in the <CODE>$!</CODE> variable. Let's go back to the <CODE>open_file()</CODE> function:
  +
  +<P>
   
  -<P><A NAME="anchor39"></A>
  -<PRE>  sub open_file{
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  sub open_file{
       my $filename = shift || '';
       die &quot;No filename passed!&quot; unless $filename;
       open FILE, $filename or die &quot;failed to open $filename: $!&quot;;
     }
     
  -  open_file(&quot;/tmp/test.txt&quot;);
  -</PRE>
  -<P><A NAME="anchor40"></A>
  +  open_file(&quot;/tmp/test.txt&quot;);</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   This time, if <CODE>open()</CODE> fails we see:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor41"></A>
  -<PRE>  failed to open /tmp/test.txt: No such file or directory
  -  at /home/httpd/perl/test.pl line 9.
  -</PRE>
  -<P><A NAME="anchor42"></A>
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  failed to open /tmp/test.txt: No such file or directory
  +  at /home/httpd/perl/test.pl line 9.</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Now we have all the information we need to debug these problems: we know
   what line of code triggered <CODE>die(),</CODE> we know what file we were
   trying to open, and last but not least we know the reason, given to us
   through Perl's <CODE>$!</CODE> variable.
   
  -<P><A NAME="anchor43"></A>
  +<P>
   Now let's create the file <EM>/tmp/test.txt</EM>.
   
  -<P><A NAME="anchor44"></A>
  -<PRE>  % touch /tmp/test.txt
  -</PRE>
  -<P><A NAME="anchor45"></A>
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  % touch /tmp/test.txt</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   When we execute the latest version of the code, we see:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor46"></A>
  -<PRE>  failed to open /tmp/test.txt: Permission denied
  -  at /home/httpd/perl/test.pl line 9.
  -</PRE>
  -<P><A NAME="anchor47"></A>
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  failed to open /tmp/test.txt: Permission denied
  +  at /home/httpd/perl/test.pl line 9.</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Here we see a different reason: we created a file that doesn't belong to
   the user which the server runs as (usually <EM>nobody</EM>). It does not have permission to read the file.
   
  -<P><A NAME="anchor48"></A>
  +<P>
   Now you can see that it's much easier to debug your code if you validate
   the return values of the system calls, and properly code arguments to
   <CODE>die()</CODE> and <CODE>warn()</CODE> calls. The <CODE>open()</CODE>
   function is just one of the many system calls perl provides to your
   convenience.
   
  -<P><A NAME="anchor49"></A>
  +<P>
   So now you can code and debug CGI scripts and modules as easily as if they
   were plain Perl scripts that you execute from a shell.
   
  -<P><A NAME="anchor50"></A>
  +<P>
   Second problem solved!
   
  -<P><A NAME="anchor51"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<CENTER><H1><A NAME="Helping_error_log_to_Help_Us">Helping error_log to Help Us</A></H1></CENTER>
  -<P><A NAME="anchor52"></A>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
  +<CENTER><H2><A NAME="Helping_error_log_to_Help_Us">Helping error_log to Help Us</A></H2></CENTER>
  +<P>
   It's a good idea to keep it open all the time in a dedicated terminal with
   the help of <EM>tail -f</EM> or <EM>less -S</EM>, whichever you prefer (the latter allows you to page around the file,
   search etc.)
  +
  +<P>
   
  -<P><A NAME="anchor53"></A>
  -<PRE>  % tail -f /usr/local/apache/logs/error_log
  -</PRE>
  -<P><A NAME="anchor54"></A>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  % tail -f /usr/local/apache/logs/error_log</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   or
  +
  +<P>
   
  -<P><A NAME="anchor55"></A>
  -<PRE>  % less -S /usr/local/apache/logs/error_log
  -</PRE>
  -<P><A NAME="anchor56"></A>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  % less -S /usr/local/apache/logs/error_log</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   So you will see all the errors and warning as they happen.
   
  -<P><A NAME="anchor57"></A>
  +<P>
   Another tip is to create a shell <EM>alias</EM>, to make it easier to execute the above command. In tcsh you would do
   something like this:
  +
  +<P>
   
  -<P><A NAME="anchor58"></A>
  -<PRE>  % alias err &quot;tail -f /usr/local/apache/logs/error_log&quot;
  -</PRE>
  -<P><A NAME="anchor59"></A>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  % alias err &quot;tail -f /usr/local/apache/logs/error_log&quot;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   For bash users the command is:
  +
  +<P>
   
  -<P><A NAME="anchor60"></A>
  -<PRE>  % alias err='tail -f /var/log/apache/error.log'
  -</PRE>
  -<P><A NAME="anchor61"></A>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  % alias err='tail -f /var/log/apache/error.log'</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   and from now on in the shell you set the alias in, executing
  +
  +<P>
   
  -<P><A NAME="anchor62"></A>
  -<PRE>  % err
  -</PRE>
  -<P><A NAME="anchor63"></A>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  % err</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   will call <EM>tail -f /usr/local/apache/logs/error_log</EM>. Since you want this alias to be available to you all the time, you should
   put it into your <EM>.tcshrc</EM> file or its equivalent. For <EM>bash</EM> users this is
   <EM>.bashrc</EM>, or you can put it in <EM>/etc/profile</EM> for use by all users.
  +
  +<P>
  +If you cannot access your <EM>error_log</EM> file because you are unable to telnet to your machine (generally the case
  +with some ISPs who provide user CGI support but no telnet access), you
  +might want to use a CGI script I wrote to fetch the latest lines from the
  +file (with a bonus of colored output for easier reading). You might need to
  +ask your ISP to install this script for general use. See <A HREF="././snippets.html#Watching_the_error_log_File_With">Watching the error_log file without telneting to the server</A> .
   
  -<P><A NAME="anchor64"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<CENTER><H1><A NAME="The_Importance_of_Warnings">The Importance of Warnings</A></H1></CENTER>
  -<P><A NAME="anchor65"></A>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
  +<CENTER><H2><A NAME="The_Importance_of_Warnings">The Importance of Warnings</A></H2></CENTER>
  +<P>
   Just like errors, Perl's mandatory warnings go to the <EM>error_log</EM>
   file, if the they are enabled. Of course you have enabled them in your
   development server, haven't you?
   
  -<P><A NAME="anchor66"></A>
  +<P>
   The code you write lives a dual life. In the first life it's being written,
   tested, debugged, improved, tested, debugged, rewritten, tested, debugged.
   In the second life it's <EM>just</EM> used.
   
  -<P><A NAME="anchor67"></A>
  +<P>
   A significant part of the script's first life is spent on the developer's
   machine. The other part is spent on the production server where the
   creature is supposed to be perfect.
   
  -<P><A NAME="anchor68"></A>
  +<P>
   So when you develop the code you want all the help in the world to help you
   spot possible problems, and that's where enabling warnings is a must.
   Whenever you see an error or warning in the <EM>error_log</EM>, you want to get rid of it. That's very important.
   
  -<P><A NAME="anchor69"></A>
  +<P>
   Why?
   
   <UL>
   <P><LI>
  -<P><A NAME="anchor70"></A>
  +<P>
   If there are warnings, your code is not clean. If they are waved away,
   expect them to come back on the production server in the form of errors,
   when it's too late.
   
   <P><LI>
  -<P><A NAME="anchor71"></A>
  +<P>
   If each invocation of a script generates more than about five lines of
   warnings, it will be very hard to catch real problems. You just can't see
   them among all the other warnings which you used to think were unimportant.
   
   </UL>
  -<P><A NAME="anchor72"></A>
  +<P>
   On the other hand, on a production server, you really <EM>want</EM> to turn warnings off. And there are good reasons for that:
   
   <UL>
   <P><LI>
  -<P><A NAME="anchor73"></A>
  +<P>
   There is no added value in having the same warning showing up, again and
   again, triggered by thousands of script invocations. If your code isn't
   very clean and generates even a single warning per script invocation, on
   the heavily loaded server you will end up with a huge
   <EM>error_log</EM> file in a short time.
   
  -<P><A NAME="anchor74"></A>
  +<P>
   The warning elimination phase is supposed to be a part of the development
   process, and should be done before the code goes live.
   
   <P><LI>
  -<P><A NAME="anchor75"></A>
  +<P>
   In any Perl script, not just under mod_perl, enabling runtime warnings has
   a performance impact.
   
   </UL>
  -<P><A NAME="anchor76"></A>
  +<P>
   mod_perl gives you a very simple solution to this warnings saga, don't
   enable warnings in the scripts unless you really have to. Let mod_perl
   control this mode globally. All you need to do is put the directive
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor77"></A>
  -<PRE>  PerlWarn On
  -</PRE>
  -<P><A NAME="anchor78"></A>
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  PerlWarn On</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   in <EM>httpd.conf</EM> on your development machine and the directive
   
  -<P><A NAME="anchor79"></A>
  -<PRE>  PerlWarn Off
  -</PRE>
  -<P><A NAME="anchor80"></A>
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  PerlWarn Off</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   on the live box.
   
  -<P><A NAME="anchor81"></A>
  +<P>
   If there is a piece of code that generates warnings and you want to disable
   them only in this code, you can do that too. The Perl special variable <CODE>$^W</CODE> allows you dynamically to turn on and off warnings mode. So just put the
   code into a block, and disable the warnings in the scope of this block. The
   original value of <CODE>$^W</CODE> will be restored upon exit from the block.
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor82"></A>
  -<PRE>  {
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  {
      local $^W=0;
       # some code that generates innocuous warnings
  -  }
  -</PRE>
  -<P><A NAME="anchor83"></A>
  +  }</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Unless you have a really good reason, for your own sake the advice is
   <EM>avoid this technique</EM>.
   
  -<P><A NAME="anchor84"></A>
  +<P>
   Don't forget the <CODE>local()</CODE> operand! If you do, setting <CODE>$^W</CODE> will affect <STRONG>all</STRONG> the requests handled by the Apache child that changed this variable. And
   for <STRONG>all</STRONG> the scripts it executes, not just the one which changed <CODE>$^W</CODE>!
   
  -<P><A NAME="anchor85"></A>
  +<P>
   The <CODE>diagnostics</CODE> pragma can shed more light on errors and warnings, as you will see in a
   moment.
   
  -<P><A NAME="anchor86"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<CENTER><H2><A NAME="diagnostics_pragma">diagnostics pragma</A></H2></CENTER>
  -<P><A NAME="anchor87"></A>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
  +<CENTER><H3><A NAME="diagnostics_pragma">diagnostics pragma</A></H3></CENTER>
  +<P>
   This module extends the terse diagnostics normally emitted by both the Perl
   compiler and the Perl interpreter, augmenting them with the more verbose
   and endearing descriptions found in the <CODE>perldiag</CODE> manpage. Like the other pragmata, it affects the compilation phase of your
   scripts as well as the execution phase.
   
  -<P><A NAME="anchor88"></A>
  +<P>
   To use in your program as a pragma, merely invoke
  +
  +<P>
   
  -<P><A NAME="anchor89"></A>
  -<PRE>    use diagnostics;
  -</PRE>
  -<P><A NAME="anchor90"></A>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>    use diagnostics;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   at or near the start of your program. This also turns on <CODE>-w</CODE> mode.
   
  -<P><A NAME="anchor91"></A>
  +<P>
   This pragma is especially useful when you are new to perl, and want a
   better explanation of the errors and warnings. It's also helpful when you
   encounter some warning you've never seen before, e.g. when a new warning
   has been introduced in an upgraded version of Perl.
   
  -<P><A NAME="anchor92"></A>
  +<P>
   You may not want to leave <CODE>diagnostics</CODE> mode On for your production server. For each warning, <CODE>diagnostics</CODE> mode generates ten times more output than warnings mode. If your code
   generates warnings, with the <CODE>diagnostics</CODE> pragma you will use disk space much faster.
   
  -<P><A NAME="anchor93"></A>
  +<P>
   <CODE>diagnostics</CODE> mode adds a large performance overhead in comparison with just having
  -warnings mode On. Let's see some numbers. We will run a benchmark, once
  -with diagnostics enabled and once disabled, on a subroutine called <EM>test_code</EM>.
  -
  -<P><A NAME="anchor94"></A>
  -The code inside the subroutine is unimportant, it does very little, just
  -some arithmetic and a numeric comparison of two strings. It assigns one
  -string to another if the condition tests true but the condition always
  -tests false. To demonstrate the <CODE>diagnostics</CODE> overhead the comparison operator is intentionally <EM>wrong</EM>. It should be a string comparison, not a numeric one.
  -
  -<P><A NAME="anchor95"></A>
  -<PRE>  use Benchmark;
  -  use diagnostics;
  -  
  -  my $count = 10000;
  -  
  -  disable diagnostics;
  -  $t1 = timeit($count,\&amp;test_code);
  -  
  -  enable  diagnostics;
  -  $t2 = timeit($count,\&amp;test_code);
  -  
  -  print &quot;Diagnostics off:&quot;,timestr($t1),&quot;\n&quot;;
  -  print &quot;Diagnostics on :&quot;,timestr($t2),&quot;\n&quot;;
  -  
  -  sub test_code{
  -    for my $i (1..10) {
  -      my $j = $i**2;
  -    }
  -    $a = &quot;Hi&quot;;
  -    $b = &quot;Bye&quot;;
  -    if ($a == $b) {
  -      $c = $a;
  -    }
  -  }
  -</PRE>
  -<P><A NAME="anchor96"></A>
  -For only a few lines of code we get:
  -
  -<P><A NAME="anchor97"></A>
  -<PRE>  Diagnostics off: 2 wallclock secs ( 1.77 usr +  0.02 sys =  1.79 CPU)
  -  Diagnostics on :17 wallclock secs (13.16 usr +  0.08 sys = 13.24 CPU)
  -</PRE>
  -<P><A NAME="anchor98"></A>
  -With <CODE>diagnostics</CODE> enabled, the code runs seven times slower!
  -
  -<P><A NAME="anchor99"></A>
  -Now let's fix the comparison the way it should be, by replacing
  -<CODE>==</CODE> with <CODE>eq</CODE>, so we get:
  -
  -<P><A NAME="anchor100"></A>
  -<PRE>    $a = &quot;Hi&quot;;
  -    $b = &quot;Bye&quot;;
  -    if ($a eq $b) {
  -      $c = $a;
  -    }
  -</PRE>
  -<P><A NAME="anchor101"></A>
  -and run the same benchmark again:
  -
  -<P><A NAME="anchor102"></A>
  -<PRE>  Diagnostics off: 1 wallclock secs ( 1.43 usr +  0.01 sys =  1.44 CPU)
  -  Diagnostics on : 2 wallclock secs ( 1.41 usr +  0.01 sys =  1.42 CPU)
  -</PRE>
  -<P><A NAME="anchor103"></A>
  -Now there is no overhead at all. The <CODE>diagnostics</CODE> pragma slows things down only when warnings are generated.
  -
  -<P><A NAME="anchor104"></A>
  -Obviously you won't benchmark all your scripts to check whether you have to
  -remove the <CODE>diagnostics</CODE> pragma or not. Just remember to remove it when your code goes live.
  -
  -<P><A NAME="anchor105"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<CENTER><H1><A NAME="Monitoring_the_error_log_file">Monitoring the error_log file</A></H1></CENTER>
  -<P><A NAME="anchor106"></A>
  -While debugging my mod_perl and general CGI code, I keep the
  -<EM>error_log</EM> file open in a dedicated terminal window (<EM>xterm</EM>), so I can see errors and warnings as soon as they are appended to the
  -file. I do it with:
  -
  -<P><A NAME="anchor107"></A>
  -<PRE>  tail -f /usr/local/apache/logs/error_log
  -</PRE>
  -<P><A NAME="anchor108"></A>
  -which shows the last few lines added to the file.
  -
  -<P><A NAME="anchor109"></A>
  -If you cannot access your <EM>error_log</EM> file because you are unable to telnet to your machine (generally the case
  -with some ISPs who provide user CGI support but no telnet access), you
  -might want to use a CGI script I wrote to fetch the latest lines from the
  -file (with a bonus of colored output for easier reading). You might need to
  -ask your ISP to install this script for general use. See <A HREF="././snippets.html#Watching_the_error_log_File_With">Watching the error_log file without telneting to the server</A> .
  +warnings mode On. You can see the benchmark results in the section '<A HREF="././performance.html#Code_Profiling_Techniques">Code Profiling Techniques</A>'.
   
  -<P><A NAME="anchor110"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H1><A NAME="Hanging_Processes_Detection_and">Hanging Processes: Detection and Diagnostics</A></H1></CENTER>
  -<P><A NAME="anchor111"></A>
  +<P>
   Sometimes a httpd process might hang in the middle of processing a request,
   either because there is a bug in your code (e.g. the code is stuck in a
   while loop), it gets blocked by some system call or because of a resource
  @@ -663,68 +948,82 @@
   reproduce the problem and after than to discover why there is problem
   (diagnostics).
   
  -<P><A NAME="anchor112"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="Hanging_because_of_the_OS_Proble">Hanging because of the OS Problem</A></H2></CENTER>
  -<P><A NAME="anchor113"></A>
  +<P>
   Sometimes you can find a process hanging because of some kind of the system
   problem. For example if the processes was doing some disk IO operation it
   might get stuck in uninterruptible sleep (<CODE>'D'</CODE> disk wait in <CODE>ps(1)</CODE> report, <CODE>'U'</CODE> in <CODE>top(1))</CODE> which indicates that either something is broken in
   your kernel or that you're using NFS. Or and you cannot kill&nbsp;-9 this process.
   
  -<P><A NAME="anchor114"></A>
  +<P>
   Another process that cannot be killed with kill&nbsp;-9 is a zombie process (<CODE>'Z'</CODE> disk wait in <CODE>ps(1)</CODE> report, <CODE>&lt;defunc&gt;</CODE> in <CODE>top(1)),</CODE> in which case the process is already dead and
   Apache didn't wait on it properly.
   
  -<P><A NAME="anchor115"></A>
  +<P>
   In the case of <EM>disk wait</EM> you can actually get the <EM>wait</EM> channel from <CODE>ps(1)</CODE> and look it up in your kernel symbol table
   to find out what resource it was waiting on. It might point the way to what
   component of the system was misbehaving if the problem occurred frequently.
   
  -<P><A NAME="anchor116"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="An_Example_of_Code_that_Might_Ha">An Example of Code that Might Hang a Process</A></H2></CENTER>
  -<P><A NAME="anchor117"></A>
  +<P>
   Deadlock is the situation where, for example, two processes, say X and Y,
   need two resources, A and B to continue. X holds onto A and Y holds onto B.
   There is no possibility for Y to continue before X releases A. But X cannot
   release A before it gets Y.
   
  -<P><A NAME="anchor118"></A>
  +<P>
   Look at the following example. Your process has to gain a lock on some
   resource (e.g. a file) before it continues. So it makes an attempt, and if
   that fails it <CODE>sleep()s</CODE> for a second and increments a counter:
  +
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
   
  -<P><A NAME="anchor119"></A>
  -<PRE>  until(gain_lock()){
  +	<td>
  +	  <pre>  until(gain_lock()){
       $tries++;
       sleep 1;
  -  }
  -</PRE>
  -<P><A NAME="anchor120"></A>
  +  }</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Because there are many processes competing for this resource, or perhaps
   because there is a deadlock, <CODE>gain_lock()</CODE> always fails. The
   process is hung.
   
  -<P><A NAME="anchor121"></A>
  +<P>
   Another situation that you may very often encounter is exclusive lock
   starvation. Generally there are two lock types in use: <EM>SHARED</EM>
   locks, which allow many processes to perform <EM>READ</EM> operations simultaneously, and <EM>EXCLUSIVE</EM> locks. The latter permits access only by a single process and so makes a
   safe <EM>WRITE</EM> operation possible.
   
  -<P><A NAME="anchor122"></A>
  +<P>
   You can lock any kind of resource, although in our examples we will talk
   about files.
   
  -<P><A NAME="anchor123"></A>
  +<P>
   If there is a <EM>READ</EM> lock request, it is granted as soon as the file becomes unlocked or
   immediately if it is already <EM>READ</EM> locked. The lock status becomes <EM>READ</EM> on success.
   
  -<P><A NAME="anchor124"></A>
  +<P>
   If there is a <EM>WRITE</EM> lock request, it is granted as soon as the file becomes unlocked. Lock
   status becomes <EM>WRITE</EM> on success.
   
  -<P><A NAME="anchor125"></A>
  +<P>
   Normally it is the <EM>WRITE</EM> lock request which is the most important. If the file is being <EM>READ</EM> locked, a process that requests to write will poll until there are no
   reading or writing process left. However, lots of processes can
   successfully read the file, since they do not block each other from doing
  @@ -732,15 +1031,27 @@
   obtaining an exclusive lock) never gets a chance to squeeze in. The
   following diagram represents a possible scenario where everybody can read
   but no one can write:
  +
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
   
  -<P><A NAME="anchor126"></A>
  -<PRE>  [-p1-]                 [--p1--]
  +	<td>
  +	  <pre>  [-p1-]                 [--p1--]
        [--p2--]
      [---------p3---------]
                    [------p4-----]
  -     [--p5--]   [----p5----]
  -</PRE>
  -<P><A NAME="anchor127"></A>
  +     [--p5--]   [----p5----]</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Let's look at some real code and see it in action. The following script
   imports <CODE>flock()</CODE> related parameters from the <CODE>Fcntl</CODE> module, and opens a file that will be locked. It then defines and sets two
   variables: <CODE>$lock_type</CODE> and <CODE>$lock_type_verbose</CODE>. These are set to
  @@ -748,13 +1059,22 @@
   process will try to gain a &lt;EM&gt;WRITE&lt;/EM&gt; (exclusive) lock.  Otherwise the
   two are set to &lt;CODE&gt;LOCK_SH&lt;/CODE&gt; and &lt;SH</CODE> for a <EM>SHARED</EM> (read) lock.
   
  -<P><A NAME="anchor128"></A>
  +<P>
   Once the variables are set, we enter the infinite <CODE>while(1)</CODE> loop that attempts to lock the file by the mode set in <CODE>$lock_type</CODE>. It report success and the type of lock that was gained, then it sleeps
   for a random period between 0 and 9 seconds and unlocks the file. The loop
   then starts from the beginning.
   
  -<P><A NAME="anchor129"></A>
  -<PRE>  lock.pl
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  lock.pl
     -------------------
     #!/usr/bin/perl -w
     use Fcntl qw(:flock);
  @@ -777,21 +1097,45 @@
         # end of critical section
       flock LOCK, LOCK_UN;
     }
  -  close LOCK;
  -</PRE>
  -<P><A NAME="anchor130"></A>
  +  close LOCK;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   It's very easy to see <EM>WRITE</EM> process starvation if you spawn a few of the above scripts simultaneously.
   Start the first few as <EM>READ</EM>
   processes and then start one <EM>WRITE</EM> process like this:
  +
  +<P>
   
  -<P><A NAME="anchor131"></A>
  -<PRE> % ./lock.pl r &amp; ; ./lock.pl r &amp; ; ./lock.pl r &amp; ; ./lock.pl w &amp;
  -</PRE>
  -<P><A NAME="anchor132"></A>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre> % ./lock.pl r &amp; ; ./lock.pl r &amp; ; ./lock.pl r &amp; ; ./lock.pl w &amp;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   You see something like:
  +
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
   
  -<P><A NAME="anchor133"></A>
  -<PRE>  24233: SH
  +	<td>
  +	  <pre>  24233: SH
     24232: SH
     24232: SH
     24233: SH
  @@ -799,20 +1143,23 @@
     24233: SH
     24231: SH
     24231: SH
  -  24231: SH
  -</PRE>
  -<P><A NAME="anchor134"></A>
  +  24231: SH</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   and not a single <CODE>EX</CODE> line... When you kill off the reading processes, then the write process
   will gain its lock. Note that as this is a rough example, I used the
   <CODE>sleep()</CODE> function. To simulate a real situation you need to use
   the <CODE>Time::HiRes</CODE> module, which allows you to choose more precise intervals to sleep.
   
  -<P><A NAME="anchor135"></A>
  +<P>
   The interval between lock and unlock is called a <EM>Critical Section</EM>, which should be kept as short as possible (in terms of the time taken to
   execute the code, and not in terms of the number of lines of code). As you
   just saw, a single sleep statement can make the critical section long.
   
  -<P><A NAME="anchor136"></A>
  +<P>
   To summarize, if you have a script that uses both <EM>READ</EM> and <EM>WRITE</EM>
   locks and the critical section isn't very short, the writing process might
   be starved. After a while a browser that initiated this request will
  @@ -822,10 +1169,11 @@
   hang until the lock is gained. Only when a write to a client's broken
   connection is attempted will Apache terminate the script.
   
  -<P><A NAME="anchor137"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="Detecting_hanging_processes">Detecting hanging processes</A></H2></CENTER>
  -<P><A NAME="anchor138"></A>
  +<P>
   It's not so easy to detect hanging processes. There is no way you can tell
   how long the request is taking to process by using plain system utilities
   like <CODE>ps()</CODE> and <CODE>top().</CODE> The reason is that each
  @@ -834,22 +1182,22 @@
   information is useless in our case, since Apache processes normally run for
   extended periods.
   
  -<P><A NAME="anchor139"></A>
  +<P>
   However there are a few approaches that can help to detect a hanging
   process.
   
  -<P><A NAME="anchor140"></A>
  +<P>
   If the process hangs and demands lots of resources it's quite easy to spot
   it by using the <CODE>top()</CODE> utility. You will see the same process
   show up in the first few lines of the automatically refreshed report. But
   often the hanging process uses few resources, e.g. when waiting for some
   event to happen.
   
  -<P><A NAME="anchor141"></A>
  +<P>
   Another easy case is when some process thrashes the <EM>error_log</EM>, writing millions of error messages there. Generally this process uses
   lots of resources and is also easily spotted by using <CODE>top().</CODE>
   
  -<P><A NAME="anchor142"></A>
  +<P>
   There are other tools that report the status of Apache processes.
   
   <UL>
  @@ -857,20 +1205,20 @@
   /server_status location.</A></STRONG>
   <P><LI><STRONG><A NAME="item_The">The Apache::VMonitor module.</A></STRONG>
   </UL>
  -<P><A NAME="anchor143"></A>
  +<P>
   Both tools provide counters of processed requests per Apache process.
   
  -<P><A NAME="anchor144"></A>
  +<P>
   You can watch the report for a few minutes, and try to spot any process
   which has the same number of processed requests while its status is 'W'
   (waiting). This means that it has hung.
   
  -<P><A NAME="anchor145"></A>
  +<P>
   But if you have fifty processes, it can be quite hard to spot such a
   process.  <A HREF="././modules.html#Apache_Watchdog_RunAway_Hang">Apache::Watchdog::RunAway is a hanging processes monitor and terminator</A> that implements this feature and should be used to solve this kind of
   problem.
   
  -<P><A NAME="anchor146"></A>
  +<P>
   If you've got a real problem, and the processes hang one after the other,
   the time will come when the number of hanging processes is equal to the
   value of <CODE>MaxClients</CODE>. This means that no more processes will be spawned. As far as the users
  @@ -879,7 +1227,7 @@
   watchdog that requests some very light script periodically. (See
   <A HREF="././control.html#Monitoring_the_Server_A_watchdo">Monitoring the Server. A watchdog.</A>)
   
  -<P><A NAME="anchor147"></A>
  +<P>
   In the watchdog you set a timeout appropriate for your service, which may
   be anything from a few seconds to a few minutes. If the server fails to
   respond before the timeout expires, the watchdog has spotted trouble and
  @@ -887,7 +1235,7 @@
   the administrator saying that there was a problem and whether or not the
   restart was successful.
   
  -<P><A NAME="anchor148"></A>
  +<P>
   If you get such reports constantly something is wrong with your web service
   and you should revise your code. Note that it's possible that your server
   is being overloaded by more requests that it can handle, so the requests
  @@ -896,27 +1244,28 @@
   more memory, or perhaps split your single machine across a cluster of
   machines.
   
  -<P><A NAME="anchor149"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="Determination_of_the_reason">Determination of the reason</A></H2></CENTER>
  -<P><A NAME="anchor150"></A>
  +<P>
   Given the process id (PID), there are three ways to find out where the
   server is hanging.
   
   <OL>
   <P><LI>
  -<P><A NAME="anchor151"></A>
  +<P>
   Deploying the Perl calls tracing mechanism. This will allow to spot the
   location of the Perl code that has triggered the problem.
   
   <P><LI>
  -<P><A NAME="anchor152"></A>
  +<P>
   Using the system calls tracing utilities, like <CODE>strace(1)</CODE> or
   <CODE>truss(1).</CODE> This approach reveals low level details about a
   potential misbehavior of some part of the system.
   
   <P><LI>
  -<P><A NAME="anchor153"></A>
  +<P>
   Using an interactive debugger, like <CODE>gdb(1).</CODE> When the process
   is stuck, and you don't know what it was doing just before it has got
   stuck, with gdb you can attach to this process and print its calls stack,
  @@ -924,66 +1273,124 @@
   you see the system call trace and not the Perl calls.
   
   </OL>
  -<P><A NAME="anchor154"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H3><A NAME="Using_the_Perl_Trace">Using the Perl Trace</A></H3></CENTER>
  -<P><A NAME="anchor155"></A>
  +<P>
   To see where an httpd is ``spinning'', try adding this to your script or a
   startup file:
   
  -<P><A NAME="anchor156"></A>
  -<PRE>  use Carp ();
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  use Carp ();
     $SIG{'USR2'} = sub { 
        Carp::confess(&quot;caught SIGUSR2!&quot;);
  -  };
  -</PRE>
  -<P><A NAME="anchor157"></A>
  +  };</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   The above code asigns a signal handler for the <CODE>USR2</CODE> signal. This signal has been chosen because it's least likely to be used by
   the other parts of the server.
   
  -<P><A NAME="anchor158"></A>
  +<P>
   We check the registered signal handlers with help of
   <A HREF="././debug.html#Apache_Status_Embedded_Inter">Apache::Status</A>. What we see at <A
   HREF="http://localhost/perl-status?sig">http://localhost/perl-status?sig</A>
   is :
   
  -<P><A NAME="anchor159"></A>
  -<PRE>  USR2 = \&amp;MyStartUp::__ANON__
  -</PRE>
  -<P><A NAME="anchor160"></A>
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  USR2 = \&amp;MyStartUp::__ANON__</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   <CODE>MyStartUp</CODE> is the name of the package I've used in mine
   <EM>startup.pl</EM>.
   
  -<P><A NAME="anchor161"></A>
  +<P>
   After applying this server configuration, let's use this simple code
   example, where <CODE>sleep(10000)</CODE> will emulate a hanging process:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor162"></A>
  -<PRE>  debug/perl_trace.pl
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  debug/perl_trace.pl
     -------------------
     $|=1;
     print &quot;Content-type:text/plain\r\n\r\n&quot;;
     print &quot;[$$] Going to sleep\n&quot;;
     hanging_sub();
  -  sub hanging_sub {sleep 10000;}
  -</PRE>
  -<P><A NAME="anchor163"></A>
  +  sub hanging_sub {sleep 10000;}</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   We execute the above script as
   <EM>http://localhost/perl/debug/perl_trace.pl</EM>, we have used <CODE>$|=1;</CODE>
   and printed the PID with <CODE>$$</CODE> to learn what process ID we want to work with.
   
  -<P><A NAME="anchor164"></A>
  +<P>
   No we issue the command line, using the PID we have just saw being printed
   to the browser's window:
  +
  +<P>
   
  -<P><A NAME="anchor165"></A>
  -<PRE>  % kill -USR2 PID
  -</PRE>
  -<P><A NAME="anchor166"></A>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  % kill -USR2 PID</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   And watch this showing up at the <EM>error_log</EM> file:
  +
  +<P>
   
  -<P><A NAME="anchor167"></A>
  -<PRE>  caught SIGUSR2!
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  caught SIGUSR2!
         at /home/httpd/perl/startup/startup.pl line 32
     MyStartUp::__ANON__('USR2') called 
         at /home/httpd/perl/debug/perl_trace.pl line 5
  @@ -999,37 +1406,74 @@
     Apache::Registry::handler('Apache=SCALAR(0x8309d08)') called 
         at PerlHandler subroutine `Apache::Registry::handler' line 0
     eval {...} called 
  -      at PerlHandler subroutine `Apache::Registry::handler' line 0
  -</PRE>
  -<P><A NAME="anchor168"></A>
  +      at PerlHandler subroutine `Apache::Registry::handler' line 0</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   We can clearly see that the process ``hangs'' in the code executed at line
   5 of the <EM>/home/httpd/perl/debug/perl_trace.pl</EM> script, and it was called by the <CODE>hanging_sub()</CODE> routine defined
   at line 4.
   
  -<P><A NAME="anchor169"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H3><A NAME="Using_the_System_Calls_Trace">Using the System Calls Trace</A></H3></CENTER>
  -<P><A NAME="anchor170"></A>
  +<P>
   Depending on the operating system you should have one of the <CODE>truss</CODE>
   or <CODE>strace</CODE> utilities available. The usage is simple:
   
  -<P><A NAME="anchor171"></A>
  -<PRE>  % truss -p PID
  -</PRE>
  -<P><A NAME="anchor172"></A>
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  % truss -p PID</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   or
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor173"></A>
  -<PRE>  % strace -p PID
  -</PRE>
  -<P><A NAME="anchor174"></A>
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  % strace -p PID</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Replace PID with the process number you want to check on.
   
  -<P><A NAME="anchor175"></A>
  +<P>
   Let's write a program that hangs, and deploy <CODE>strace</CODE> to find the point it hangs at:
   
  -<P><A NAME="anchor176"></A>
  -<PRE>  hangme.pl
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  hangme.pl
     ---------
     $|=1;
     my $r = shift;
  @@ -1040,16 +1484,19 @@
     while(1){
       $i++;
       sleep 1;
  -  }
  -</PRE>
  -<P><A NAME="anchor177"></A>
  +  }</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   The reason this simple code hangs is obvious. It never breaks from the
   while loop. As you have noticed, it prints the PID of the current process
   to the browser. Of course in a real situation you cannot use the same
   trick. In the previous section I have presented a few ways to detect the
   runaway processes and their PIDs.
   
  -<P><A NAME="anchor178"></A>
  +<P>
   I save the above code in a file and execute it from the browser. Note that
   I've made STDOUT unbuffered with <CODE>$|=1;</CODE> so I will immediately see the process ID. Once the script is requested, the
   script prints the process PID and obviously hangs. So we press the <CODE>'Stop'</CODE>
  @@ -1057,12 +1504,21 @@
   supposed to detect the broken connection and abort the request? Yes and No,
   you will understand soon what's really happening.
   
  -<P><A NAME="anchor179"></A>
  +<P>
   First let's attach to the process and see what it's doing. I use the PID
   the script printed to the browser, which is 10045 in this case:
   
  -<P><A NAME="anchor180"></A>
  -<PRE>  % strace -p 10045
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  % strace -p 10045
     
     [...truncated identical output...]
     SYS_175(0, 0xbffff41c, 0xbffff39c, 0x8, 0) = 0
  @@ -1071,25 +1527,40 @@
     nanosleep(0xbffff308, 0xbffff308, 0x401a61b4, 0xbffff308, 0xbffff41c) = 0
     time([940973834])                       = 940973834
     time([940973834])                       = 940973834
  -  [...truncated the identical output...]
  -</PRE>
  -<P><A NAME="anchor181"></A>
  +  [...truncated the identical output...]</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   It isn't what we expected to see, is it? These are some system calls we
   don't see in our little example. What we actually see is how Perl
   translates our code into system calls. Since we know that our code hangs in
   this snippet:
  +
  +<P>
   
  -<P><A NAME="anchor182"></A>
  -<PRE>  while(1){
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  while(1){
       $i++;
       sleep 1;
  -  }
  -</PRE>
  -<P><A NAME="anchor183"></A>
  +  }</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   We <EM>"easily"</EM> figure out that the first three system calls implement the <CODE>$i++</CODE>, while the other other three are responsible for the
   <CODE>sleep 1</CODE> call.
   
  -<P><A NAME="anchor184"></A>
  +<P>
   Generally the situation is the reverse of our example. You detect the
   hanging process, you attach to it and watch the trace of calls it does (or
   the last few commands if the process is hanging waiting for something, e.g.
  @@ -1097,9 +1568,18 @@
   out what it's actually doing, and probably find the corresponding lines in
   your Perl code. For example let's see how one process <EM>"hangs"</EM> while requesting an exclusive lock on a file exclusively locked by another
   process:
  +
  +<P>
   
  -<P><A NAME="anchor185"></A>
  -<PRE>  excl_lock.pl
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  excl_lock.pl
     ---------
     use Fcntl qw(:flock);
     use Symbol;
  @@ -1121,82 +1601,131 @@
       print &quot;$$: I've got the lock\n&quot;;
       sleep 20;
       close $fh;
  -  }
  -</PRE>
  -<P><A NAME="anchor186"></A>
  +  }</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   The code is simple. The process executing the code forks a second process,
   and both do the same thing: generate a unique symbol to be used as a file
   handler, open the lock file for writing using the generated symbol, lock
   the file in exclusive mode, sleep for 20 seconds (pretending to do some
   lengthy operation) and close the lock file, which also unlocks the file.
   
  -<P><A NAME="anchor187"></A>
  +<P>
   The <CODE>gensym</CODE> function is imported from the <CODE>Symbol</CODE> module. The
   <CODE>Fcntl</CODE> module provides us with a symbolic constant <CODE>LOCK_EX</CODE>. This is imported via the <CODE>:flock</CODE> tag, which imports this and other <CODE>flock()</CODE> constants.
   
  -<P><A NAME="anchor188"></A>
  +<P>
   The code used by both processes is identical, therefore we cannot predict
   which one will get its hands on the lock file and succeed in locking it
   first, so we add <CODE>print()</CODE> statements to find the PID of the
   process blocking (waiting to get the lock) on a lock request.
   
  -<P><A NAME="anchor189"></A>
  +<P>
   When the above code executed from the command line, we see that one of the
   processes gets the lock:
  +
  +<P>
   
  -<P><A NAME="anchor190"></A>
  -<PRE>  % ./excl_lock.pl
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  % ./excl_lock.pl
     
     3038: I'm going to obtain the lock
     3038: I've got the lock
  -  3037: I'm going to obtain the lock
  -</PRE>
  -<P><A NAME="anchor191"></A>
  +  3037: I'm going to obtain the lock</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Here we see that process 3037 is blocking, so we attach to it:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor192"></A>
  -<PRE>  % strace -p 3037
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  % strace -p 3037
     
     about to attach c10
  -  flock(3, LOCK_EX
  -</PRE>
  -<P><A NAME="anchor193"></A>
  +  flock(3, LOCK_EX</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   It's clear from the above trace, that the process waits for an exclusive
   lock. (Note, that the missing closing parentnheses is not a typo!)
   
  -<P><A NAME="anchor194"></A>
  +<P>
   As you become familiar with watching the traces of different processes, you
   will understand what is happening more easily.
   
  -<P><A NAME="anchor195"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H3><A NAME="Using_the_Interactive_Debugger">Using the Interactive Debugger</A></H3></CENTER>
  -<P><A NAME="anchor196"></A>
  +<P>
   Another approach to see a trace of the running code is to use a debugger
   such as <CODE>gdb</CODE> (the GNU debugger). It's supposed to work on any platform which supports
   the GNU development tools. Its purpose is to allow you to see what is going
   on <EM>inside</EM> a program while it executes, or what it was doing at the moment it crashed.  
   
  -<P><A NAME="anchor197"></A>
  +<P>
   To trace the execution of a process, <CODE>gdb</CODE> needs to know the process id (PID) and the path to the binary that the
   process is executing. For Perl code it's <EM>/usr/bin/perl</EM> (or whatever is the path to your Perl), for httpd processes it will be the
   path to your httpd executable.
   
  -<P><A NAME="anchor198"></A>
  +<P>
   Here are a few examples using gdb.
   
  -<P><A NAME="anchor199"></A>
  +<P>
   Let's go back to our last locking example, execute it as before and attach
   to the process that didn't get the lock:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor200"></A>
  -<PRE>  % gdb /usr/bin/perl 3037
  -</PRE>
  -<P><A NAME="anchor201"></A>
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  % gdb /usr/bin/perl 3037</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   After starting the debugger we execute the <CODE>where</CODE> command to see the trace:
   
  -<P><A NAME="anchor202"></A>
  -<PRE>  (gdb) where
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  (gdb) where
     #0  0x40131781 in __flock ()
     #1  0x80a5421 in Perl_pp_flock ()
     #2  0x80b148d in Perl_runops_standard ()
  @@ -1205,48 +1734,72 @@
     #5  0x400a6cb3 in __libc_start_main (main=0x80577c0 &lt;main&gt;, argc=2, 
         argv=0xbffff7f4, init=0x8056af4 &lt;_init&gt;, fini=0x80b14fc &lt;_fini&gt;, 
         rtld_fini=0x4000a350 &lt;_dl_fini&gt;, stack_end=0xbffff7ec)
  -      at ../sysdeps/generic/libc-start.c:78
  -</PRE>
  -<P><A NAME="anchor203"></A>
  +      at ../sysdeps/generic/libc-start.c:78</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   That's not what we expected to see and now it's a different trace.
   <CODE>#0</CODE> tells us the most recent call that was executed, which is a C language
   <CODE>flock()</CODE> implementation. But the previous call (<CODE>#1</CODE>) isn't <CODE>print(),</CODE> as we would expect, but a higher level of
   Perl's internal <CODE>flock().</CODE> If we follow the trace of calls what
   we actually see is an Opcodes tree, which can be better presented as:
  +
  +<P>
   
  -<P><A NAME="anchor204"></A>
  -<PRE>  __libc_start_main
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  __libc_start_main
       main ()
         perl_run () 
           Perl_runops_standard ()
             Perl_pp_flock ()
  -            __flock ()
  -</PRE>
  -<P><A NAME="anchor205"></A>
  +            __flock ()</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   So I would say that it's less useful than <CODE>strace</CODE>, since if there are several <CODE>flock()s</CODE> it's almost impossible
   to know which of them was called. This problem is solved by <CODE>strace</CODE>, which shows the sequence of the system calls executed. Using this
   sequence we can locate the corresponding lines in the code.
   
  -<P><A NAME="anchor206"></A>
  +<P>
   (META: the above is wrong - you can ask to display the previous command
   executed by the program (not gdb)! What is it?)
   
  -<P><A NAME="anchor207"></A>
  +<P>
   When you attach to a running process with debugger, the program stops
   executing and control of the program is passed to the debugger. You can
   continue the normal program run with the <CODE>continue</CODE> command or execute it step by step with the <CODE>next</CODE> and <CODE>step</CODE> commands which you type at the <CODE>gdb</CODE> prompt. (<CODE>next</CODE> steps over any function calls in the line, while <CODE>step</CODE> steps into them).
   
  -<P><A NAME="anchor208"></A>
  +<P>
   C/C++ debuggers are a very large topic and beyond the scope of this
   document, but the gdb man page is quite good and you can try <CODE>info
   gdb</CODE> as well. You might also want to check the <CODE>ddd</CODE> (Data Display Debbuger) which provides a visual interface to <CODE>gdb</CODE> and other debuggers. It even knows how to debug Perl programs!
   
  -<P><A NAME="anchor209"></A>
  +<P>
   For completeness, let's see the gdb trace of the httpd process that's still
   hanging in the <CODE>while(1)</CODE> loop of the first example in this section:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor210"></A>
  -<PRE>  % gdb /usr/local/apache/bin/httpd 1005
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  % gdb /usr/local/apache/bin/httpd 1005
     
     (gdb) where
     #0  0x4014a861 in __libc_nanosleep ()
  @@ -1268,19 +1821,23 @@
     #16 0x400d3cb3 in __libc_start_main (main=0x809d88c &lt;main&gt;, argc=1, 
         argv=0xbffff7e4, init=0x80606f8 &lt;_init&gt;, fini=0x812b33c &lt;_fini&gt;, 
         rtld_fini=0x4000a350 &lt;_dl_fini&gt;, stack_end=0xbffff7dc)
  -      at ../sysdeps/generic/libc-start.c:78
  -</PRE>
  -<P><A NAME="anchor211"></A>
  +      at ../sysdeps/generic/libc-start.c:78</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   As before we can see a complete trace of the last executed call.
   
  -<P><A NAME="anchor212"></A>
  +<P>
   As you have noticed, I still haven't explained why the process hanging in
   the <CODE>while(1)</CODE> loop isn't aborted by Apache. The next section covers this.
   
  -<P><A NAME="anchor213"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H1><A NAME="Handling_the_User_pressed_Stop_">Handling the 'User pressed Stop button' case</A></H1></CENTER>
  -<P><A NAME="anchor214"></A>
  +<P>
   When a user presses a <STRONG>STOP</STRONG> or <STRONG>RELOAD</STRONG> button, Apache could detect this via the <CODE>SIGPIPE</CODE> signal (Broken pipe). It could then halt the script execution and perform
   all the cleanup stuff it has to do. But the <CODE>SIGPIPE</CODE> will be triggered only when the process attempts to send some data to the
   client browser via the broken connection. If the script is doing some
  @@ -1288,44 +1845,66 @@
   stopped until that operation is completed and an attempt is made to send at
   least one character the client.
   
  -<P><A NAME="anchor215"></A>
  +<P>
   Apache &gt;= 1.3.6 does not catch SIGPIPE anymore, and modperl can do the
   job much better.
   
  -<P><A NAME="anchor216"></A>
  +<P>
   Since Apache version 1.3.6:
   
   <UL>
   <P><LI>
  -<P><A NAME="anchor217"></A>
  +<P>
   <CODE>$r-&gt;print</CODE> returns <EM>true</EM> on success, <EM>false</EM> on failure (broken connection).
   
   <P><LI>
  -<P><A NAME="anchor218"></A>
  +<P>
   If you want a similar to the old <CODE>SIGPIPE</CODE> behaviour, simply configure:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor219"></A>
  -<PRE>  PerlFixupHandler Apache::SIG
  -</PRE>
  -<P><A NAME="anchor220"></A>
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  PerlFixupHandler Apache::SIG</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   When Apache's <CODE>SIGPIPE</CODE> handler is used, Perl may be left in the middle of it's eval context,
   causing bizarre errors during subsequent requests are handled by that
   child. When <CODE>Apache::SIG</CODE> is used, it installs a different <CODE>SIGPIPE</CODE> handler which rewinds the context to make sure Perl is back to normal
   state, preventing these bizarre errors.
   
   </UL>
  -<P><A NAME="anchor221"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="Detecting_Aborted_Connections">Detecting Aborted Connections</A></H2></CENTER>
  -<P><A NAME="anchor222"></A>
  +<P>
   Let's use the knowledge we have acquired to trace the execution of the code
   and see all the events as they happen.
   
  -<P><A NAME="anchor223"></A>
  +<P>
   Let's take a little script that obviously ``hangs'' the server:
  +
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
   
  -<P><A NAME="anchor224"></A>
  -<PRE>  my $r = shift;
  +	<td>
  +	  <pre>  my $r = shift;
     $r-&gt;send_http_header('text/plain');
     
     print &quot;PID = $$\n&quot;;
  @@ -1334,15 +1913,18 @@
     while(1){
       $i++;
       sleep 1;
  -  }
  -</PRE>
  -<P><A NAME="anchor225"></A>
  +  }</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   The script gets a request object <CODE>$r</CODE> by <CODE>shift()ing</CODE> it from the <CODE>@_</CODE>
   argument list passed by the <CODE>handler()</CODE> subroutine. (This magic
   is done by <CODE>Apache::Registry</CODE>). Then the script sends a <EM>Content-type</EM>
   header, telling the client that we are going to send some plain text.
   
  -<P><A NAME="anchor226"></A>
  +<P>
   We print out a single line telling us the id of the process that handles
   this request, which we need to know in order to run the tracing utility.
   Then we flush Apache's buffer. (If we don't flush the buffer we will never
  @@ -1350,49 +1932,82 @@
   size and the script intentionally hangs, so the buffer won't be
   auto-flushed as the script hangs at the end.)
   
  -<P><A NAME="anchor227"></A>
  +<P>
   Then we enter an infinite loop, which just increments a dummy variable and
   sleeps for a second.
   
  -<P><A NAME="anchor228"></A>
  +<P>
   Running <CODE>strace -p PID</CODE>, where <EM>PID</EM> is the process ID as printed to the browser, we see the following output
   printed every second:
  +
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
   
  -<P><A NAME="anchor229"></A>
  -<PRE>  SYS_175(0, 0xbffff41c, 0xbffff39c, 0x8, 0) = 0
  +	<td>
  +	  <pre>  SYS_175(0, 0xbffff41c, 0xbffff39c, 0x8, 0) = 0
     SYS_174(0x11, 0, 0xbffff1a0, 0x8, 0x11) = 0
     SYS_175(0x2, 0xbffff39c, 0, 0x8, 0x2)   = 0
     nanosleep(0xbffff308, 0xbffff308, 0x401a61b4, 0xbffff308, 0xbffff41c) = 0
     time([941281947])                       = 941281947
  -  time([941281947])                       = 941281947
  -</PRE>
  -<P><A NAME="anchor230"></A>
  +  time([941281947])                       = 941281947</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Let's leave <CODE>strace</CODE> running and press the <STRONG>STOP</STRONG> button. Did anything change? No, the same trace printed every second. Which
   means that Apache didn't detect the broken pipe.
   
  -<P><A NAME="anchor231"></A>
  +<P>
   Let's try to write a NULL <CODE>\0</CODE> character to the client so the broken pipe will be detected as soon the <STRONG>Stop</STRONG> button is pressed:
  +
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
   
  -<P><A NAME="anchor232"></A>
  -<PRE>  while(1){
  +	<td>
  +	  <pre>  while(1){
       $r-&gt;print(&quot;\0&quot;);
       last if $r-&gt;connection-&gt;aborted;
       $i++;
       sleep 1;
  -  }
  -</PRE>
  -<P><A NAME="anchor233"></A>
  +  }</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   We add a <CODE>print()</CODE> statement to print a NULL character and then
   we check whether the connection was aborted. If it was, we break from the
   loop.
   
  -<P><A NAME="anchor234"></A>
  +<P>
   We run this script and strace on it as before, but we see that it still
   doesn't work. The trouble is we aren't flushing the buffer. After printing
   the NULL, add $r-&gt;rflush():
  +
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
   
  -<P><A NAME="anchor235"></A>
  -<PRE>  my $r = shift;
  +	<td>
  +	  <pre>  my $r = shift;
     $r-&gt;send_http_header('text/plain');
     
     print &quot;PID = $$\n&quot;;
  @@ -1406,14 +2021,26 @@
     
       $i++;
       sleep 1;
  -  }
  -</PRE>
  -<P><A NAME="anchor236"></A>
  +  }</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Watch <CODE>strace</CODE>'s output on the running process and then press the
   <STRONG>Stop</STRONG> button, you will see:
  +
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
   
  -<P><A NAME="anchor237"></A>
  -<PRE>  SYS_175(0, 0xbffff41c, 0xbffff39c, 0x8, 0) = 0
  +	<td>
  +	  <pre>  SYS_175(0, 0xbffff41c, 0xbffff39c, 0x8, 0) = 0
     SYS_174(0x11, 0, 0xbffff1a0, 0x8, 0x11) = 0
     SYS_175(0x2, 0xbffff39c, 0, 0x8, 0x2)   = 0
     nanosleep(0xbffff308, 0xbffff308, 0x401a61b4, 0xbffff308, 0xbffff41c) = 0
  @@ -1428,40 +2055,88 @@
     close(4)                                = 0
     SYS_174(0xa, 0xbffff4e0, 0xbffff454, 0x8, 0xa) = 0
     SYS_174(0xe, 0xbffff46c, 0xbffff3e0, 0x8, 0xe) = 0
  -  fcntl(18, F_SETLKW, {type=F_WRLCK, whence=SEEK_SET, start=0, len=0}
  -</PRE>
  -<P><A NAME="anchor238"></A>
  +  fcntl(18, F_SETLKW, {type=F_WRLCK, whence=SEEK_SET, start=0, len=0}</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Apache detects the broken pipe as you see from this snippet:
   
  -<P><A NAME="anchor239"></A>
  -<PRE>  write(4, &quot;\0&quot;, 1)                       = -1 EPIPE (Broken pipe)
  -  --- SIGPIPE (Broken pipe) ---
  -</PRE>
  -<P><A NAME="anchor240"></A>
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  write(4, &quot;\0&quot;, 1)                       = -1 EPIPE (Broken pipe)
  +  --- SIGPIPE (Broken pipe) ---</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Then it stops the script and does all the cleanup work, like access
   logging:
  +
  +<P>
   
  -<P><A NAME="anchor241"></A>
  -<PRE>  write(17, &quot;127.0.0.1 - - [30/Oct/1999:13:52&quot;..., 81) = 81
  -</PRE>
  -<P><A NAME="anchor242"></A>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  write(17, &quot;127.0.0.1 - - [30/Oct/1999:13:52&quot;..., 81) = 81</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   In the <EM>access_log</EM> file we can see the file descriptor of the logfile in this process (17).
   
  -<P><A NAME="anchor243"></A>
  +<P>
   Let's see how can we make the code more general-purpose:
   
  -<P><A NAME="anchor244"></A>
  +<P>
   <CODE>Apache::SIG</CODE> helps us, use this configuration setting in
   <EM>httpd.conf</EM>:
  +
  +<P>
   
  -<P><A NAME="anchor245"></A>
  -<PRE>  PerlFixupHandler Apache::SIG
  -</PRE>
  -<P><A NAME="anchor246"></A>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  PerlFixupHandler Apache::SIG</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Now the following script doesn't need to check for aborted connections.
  +
  +<P>
   
  -<P><A NAME="anchor247"></A>
  -<PRE>  my $r = shift;
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  my $r = shift;
     $r-&gt;send_http_header('text/plain');
     
     print &quot;PID = $$\n&quot;;
  @@ -1471,103 +2146,153 @@
       $r-&gt;rflush;
       $i++;
       sleep 1;
  -  }
  -</PRE>
  -<P><A NAME="anchor248"></A>
  +  }</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   <CODE>Apache::SIG</CODE> installs the <CODE>SIGPIPE</CODE> handler, which stops the script's execution for us when it sees the broken
   pipe. This setting affects all processes of course.
   
  -<P><A NAME="anchor249"></A>
  +<P>
   If you would like to log when a request was cancelled by a SIGPIPE in your
   Apache <EM>access_log</EM>, you must define a custom <CODE>LogFormat</CODE> in your <EM>httpd.conf</EM>, like so:
  +
  +<P>
   
  -<P><A NAME="anchor250"></A>
  -<PRE>  PerlFixupHandler Apache::SIG
  -  LogFormat &quot;%h %l %u %t \&quot;%r\&quot; %s %b %{SIGPIPE}e&quot;
  -</PRE>
  -<P><A NAME="anchor251"></A>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  PerlFixupHandler Apache::SIG
  +  LogFormat &quot;%h %l %u %t \&quot;%r\&quot; %s %b %{SIGPIPE}e&quot;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   If the server has noticed that the request was cancelled via a
   <CODE>SIGPIPE</CODE>, then the log line will end with <CODE>1</CODE>, otherwise it will just be a dash.
   
  -<P><A NAME="anchor252"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="The_Importance_of_Cleanup_Code">The Importance of Cleanup Code</A></H2></CENTER>
  -<P><A NAME="anchor253"></A>
  +<P>
   This is a critical issue with aborted scripts.
   
  -<P><A NAME="anchor254"></A>
  +<P>
   What happens to locked resources? Will they be freed or not? If not,
   scripts using these resources and the same locking scheme will hang,
   waiting for this resource to be freed.
   
  -<P><A NAME="anchor255"></A>
  +<P>
   Under mod_cgi this was a problem only if you happened to use external lock
   files for lock indication, instead of using <CODE>flock().</CODE> If the
   script was aborted between the lock and the unlock code, and you didn't
   bother to write cleanup code to remove old dead locks then you were in big
   trouble.
   
  -<P><A NAME="anchor256"></A>
  +<P>
   With mod_cgi you can create an <CODE>END</CODE> block, and put the cleanup code there:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor257"></A>
  -<PRE>  END{
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  END{
       # some code that ensures that locks are removed
  -  }
  -</PRE>
  -<P><A NAME="anchor258"></A>
  +  }</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   When the script is aborted, Apache will run the <CODE>END</CODE> blocks.
   
  -<P><A NAME="anchor259"></A>
  +<P>
   If you use <CODE>flock()</CODE> things are much simpler, since all opened files will be closed. When the
   file is closed, the lock is removed as well and all the locked resources
   will be freed. There are systems where <CODE>flock(2)</CODE> is
   unavailable, and for those you can use Perl's emulation of this function.
   
  -<P><A NAME="anchor260"></A>
  +<P>
   With mod_perl things are more complex. Because the processes don't exit
   after processing a request, files won't be closed unless you explicitly
   <CODE>close()</CODE> them or reopen with the <CODE>open()</CODE> call,
   which first closes a file. Let's see what problems we might encounter, and
   possible solutions for them.
   
  -<P><A NAME="anchor261"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H3><A NAME="Critical_Section">Critical Section</A></H3></CENTER>
  -<P><A NAME="anchor262"></A>
  +<P>
   First I want to make a little detour to discuss the <EM>"critical
   section"</EM> issue.
   
  -<P><A NAME="anchor263"></A>
  +<P>
   Let's start with a resource locking scheme. A schematic representation of a
   proper locking technique is as follows:
  +
  +<P>
   
  -<P><A NAME="anchor264"></A>
  -<PRE>  1. lock a resource
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  1. lock a resource
        &lt;critical section starts&gt;
     2. do something with the resource
        &lt;critical section ends&gt;
  -  3. unlock the resource
  -</PRE>
  -<P><A NAME="anchor265"></A>
  +  3. unlock the resource</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   If the locking is exclusive, only one process can hold the resource at any
   given time, which means that all the other processes will have to wait, and
   this code snippet becomes a so called bottleneck. That's why the section of
   the code where the resource is locked is called critical and you must make
   it as short as possible.
   
  -<P><A NAME="anchor266"></A>
  +<P>
   In a shared locking scheme, where many processes can concurrently access
   the resource, if there are processes that sometimes want to get an
   exclusive lock it's also important to keep the critical section as short as
   possible.
   
  -<P><A NAME="anchor267"></A>
  +<P>
   The code below uses a shared lock, but has a poorly-designed critical
   section:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor268"></A>
  -<PRE>  use Fcntl qw(:flock);
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  use Fcntl qw(:flock);
     use Symbol;
     my $fh = gensym;
     
  @@ -1582,26 +2307,38 @@
     }
       # end critical section
     
  -  close $fh; # close unlocks the file
  -</PRE>
  -<P><A NAME="anchor269"></A>
  +  close $fh; # close unlocks the file</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   The code opens the file for reading, locks and rewinds to the start, reads
   all the lines from the file and prints out the lines that contain the
   string <EM>foo</EM>. Note that the file remains open and locked while the loop executes.
   
  -<P><A NAME="anchor270"></A>
  +<P>
   We can optimize the critical section this way:
   
  -<P><A NAME="anchor271"></A>
  +<P>
   Once the file has been read, we have all the information we need from it.
   The loop might take some time to complete. We don't need the file to be
   open while the loop executes, because we don't access it inside the loop.
   If we close the file before we start the loop, we will allow other
   processes to have access to the file if they need it, instead of blocking
   them for no reason.
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor272"></A>
  -<PRE>  use Fcntl qw(:flock);
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  use Fcntl qw(:flock);
     use Symbol;
     my $fh = gensym;
     
  @@ -1617,15 +2354,27 @@
     
     for(@lines){
       print if /foo/;
  -  }
  -</PRE>
  -<P><A NAME="anchor273"></A>
  +  }</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   This is another very similar script, but now using an exclusive lock. It
   reads in a file and writes it back, prepending a number of new text lines
   to the head of the file.
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor274"></A>
  -<PRE>  use Fcntl qw(:flock);
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  use Fcntl qw(:flock);
     use Symbol;
     my $fh = gensym;
     
  @@ -1648,13 +2397,16 @@
     print $fh @lines;
       # end critical section
     
  -  close $fh; # close unlocks the file
  -</PRE>
  -<P><A NAME="anchor275"></A>
  +  close $fh; # close unlocks the file</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   First let's see how the code works. I will discuss why I use the
   <CODE>Symbol</CODE> module to generate the file handles in the next section.
   
  -<P><A NAME="anchor276"></A>
  +<P>
   Since we want to read the file, modify and write it back, without anyone
   else changing it on the way, we open it for read and write with the help of <EM>+&gt;&gt;</EM> and lock it with an exclusive lock. You cannot safely accomplish this task
   by opening the file first for read and then reopening for write, since
  @@ -1662,7 +2414,7 @@
   with <EM>+&lt;</EM>, see
   <EM>perldoc -f open</EM> or the <EM>perlfunc</EM> manpage for more information about the <CODE>open()</CODE> function.)
   
  -<P><A NAME="anchor277"></A>
  +<P>
   Next the code prepares the lines of text it wants to prepend to the head of
   the file, and assigns them and the content of the file to the
   <CODE>@lines</CODE> array. Now we have our data ready to be written back to the file, so we
  @@ -1675,16 +2427,25 @@
   any significant performance penalty. Finally we write the data back to the
   file and close it, which unlocks it as well.
   
  -<P><A NAME="anchor278"></A>
  +<P>
   Did you notice that we created the text lines to be prepended as close to
   the place of usage as possible? This is good ``locality of code'' style,
   but it makes the critical section longer. In such cases you should
   sacrifice style, in order to make the critical section as short as
   possible. An improved version of this script with a shorter critical
   section looks like this:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor279"></A>
  -<PRE>  use Fcntl qw(:flock);
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  use Fcntl qw(:flock);
     use Symbol;
     
     my @lines =
  @@ -1708,74 +2469,102 @@
     print $fh @lines;
       # end critical section
     
  -  close $fh; # close unlocks the file
  -</PRE>
  -<P><A NAME="anchor280"></A>
  +  close $fh; # close unlocks the file</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   There are two important differences. Firstly, we prepare the text lines to
   be prepended <EM>before</EM> the file is locked. Secondly, instead of creating a new array and copying
   lines from one array to another, we append the file directly to the <CODE>@lines</CODE> array.
   
  -<P><A NAME="anchor281"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H3><A NAME="Safe_Resource_Locking">Safe Resource Locking</A></H3></CENTER>
  -<P><A NAME="anchor282"></A>
  +<P>
   Let's get back to the main issue of this section, which is safe resource
   locking.
   
  -<P><A NAME="anchor283"></A>
  +<P>
   Unless you use the <CODE>Apache::PerlRun</CODE> handler that does the cleanup for you, if you don't make a habit of closing
   all the files that you open you will encounter lots of problems. If you
   open a file but don't close it, you will have file descriptor leakage.
   Since the number of file descriptors available to you is finite, at some
   point you will run out of them and your service will fail.
   
  -<P><A NAME="anchor284"></A>
  +<P>
   This is bad, but you can live with it until you run out of file descriptors
   (which will happen much faster on a heavily used server). But this is
   nothing compared to the trouble you will give yourself if you lock, but
   forget to unlock or close your locked files. Since <CODE>close()</CODE>
   always unlocks the file, you don't have to unlock files explicitly.
   
  -<P><A NAME="anchor285"></A>
  +<P>
   But a locked file will stay locked after your code has terminated!
   
  -<P><A NAME="anchor286"></A>
  +<P>
   Any other process requesting a lock on the same file (or resource) will
   wait indefinitely for it to become unlocked. Since this will not happen
   until the server reboots, all these processes will hang.
   
  -<P><A NAME="anchor287"></A>
  +<P>
   Here is an example of such a terrible mistake:
  +
  +<P>
   
  -<P><A NAME="anchor288"></A>
  -<PRE>  open IN, &quot;+&gt;&gt;filename&quot; or die &quot;$!&quot;;
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  open IN, &quot;+&gt;&gt;filename&quot; or die &quot;$!&quot;;
     flock IN, LOCK_EX;
     # do something
  -  # quit without closing and unlocking the file
  -</PRE>
  -<P><A NAME="anchor289"></A>
  +  # quit without closing and unlocking the file</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Is this safe code? No - we forgot to close the file.
   
  -<P><A NAME="anchor290"></A>
  +<P>
   So let's add the <CODE>close():</CODE>
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor291"></A>
  -<PRE>  open IN, &quot;+&gt;&gt;filename&quot; or die &quot;$!&quot;;
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  open IN, &quot;+&gt;&gt;filename&quot; or die &quot;$!&quot;;
     flock IN, LOCK_EX;
       # start critical section
     # do something
       # end critical section
     # close and unlock the file
  -  close IN;
  -</PRE>
  -<P><A NAME="anchor292"></A>
  +  close IN;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Is it safe code now? Unfortunately it is not. There is a chance that the
   user may abort the request (for example by pressing his browser's
   <CODE>Stop</CODE> or <CODE>Reload</CODE> buttons) during the critical section. The script will be aborted before it
   has had a chance to <CODE>close()</CODE> the file, which is just as bad as
   if we forgot to close it.
   
  -<P><A NAME="anchor293"></A>
  +<P>
   There are a few approaches we can take to solving this problem. If you are
   running under <CODE>Apache::Registry</CODE> and friends, the <CODE>END</CODE>
   block will perform the cleanup work for you. You might use <CODE>END</CODE> in the same way for scripts running under mod_cgi, or in plain Perl
  @@ -1785,7 +2574,7 @@
   handlers you will need to use the <CODE>register_cleanup()</CODE> function
   to supply cleanup code similar to that used in <CODE>END</CODE> blocks instead of using <CODE>END</CODE> blocks. We will see a few examples later.
   
  -<P><A NAME="anchor294"></A>
  +<P>
   Of course, if the same child executes the same section of code of the same
   script, the <CODE>open()</CODE> call on the same file handle will first
   <CODE>close()</CODE> the file. But this will happen only if it's the same
  @@ -1794,15 +2583,15 @@
   -- you get a file desriptor leakage and the file will be not unlocked in
   case it was locked.
   
  -<P><A NAME="anchor295"></A>
  +<P>
   On Linux OS you can use the <CODE>lsof(1)</CODE> utility to list open files
   and the processes who have opened them. On FreeBSD you would use the
   <CODE>fstat(1)</CODE> utility.
   
  -<P><A NAME="anchor296"></A>
  +<P>
   Now I want to show you a much easier safe locking solution.
   
  -<P><A NAME="anchor297"></A>
  +<P>
   Although it might not be obvious, the problem we have encountered is
   actually the fact that file handles like <CODE>IN</CODE> are global variables. If we could make them lexically scoped, all our
   worries would go away. You know that lexically scoped (with the
  @@ -1812,7 +2601,7 @@
   opened file descriptor is destroyed, the file will automatically be closed
   and unlocked.
   
  -<P><A NAME="anchor298"></A>
  +<P>
   So if you use this technique to work with files, you even don't have to
   explicitly close the files! (Of course if you recall the critical section
   discussion above, you will still want to make sure that you close them as
  @@ -1823,21 +2612,45 @@
   filehandle name somewhere else in the code in case it might still be
   associated with an open file. To emphasize the risk of collisions think of
   subroutine that opens a file for you:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor299"></A>
  -<PRE>  sub open_file{
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  sub open_file{
       my $filename  = shift;
       open FILE, &quot;&gt;$filename&quot; or die &quot;$!&quot;;
       return \*FILE;
  -  }
  -</PRE>
  -<P><A NAME="anchor300"></A>
  -<PRE>  my $fh1 = open_file(&quot;/tmp/x&quot;);
  +  }</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  my $fh1 = open_file(&quot;/tmp/x&quot;);
     my $fh2 = open_file(&quot;/tmp/y&quot;);
     print $fh1 &quot;X&quot;;
  -  print $fh2 &quot;Y&quot;;
  -</PRE>
  -<P><A NAME="anchor301"></A>
  +  print $fh2 &quot;Y&quot;;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   This code doesn't do what you think it should do. Instead of writing the
   character <CODE>X</CODE> to <EM>/tmp/x</EM> file and <CODE>Y</CODE> to <EM>/tmp/y</EM>, what you see after running this script is that <EM>/tmp/x</EM> is empty and <EM>/tmp/y</EM>
   contains a <CODE>XY</CODE> string. Why is that? Because you have used the same global variable <CODE>FILE</CODE> twice, and when you called <CODE>open_file()</CODE> for a second time it
  @@ -1845,117 +2658,202 @@
   <CODE>open_file()</CODE> always returns a reference to the same global file
   handle variable, both <CODE>$fh1</CODE> and <CODE>$fh2</CODE> point to it.
   
  -<P><A NAME="anchor302"></A>
  +<P>
   There is another way. As you saw earlier we can generate unique, lexically
   scoped file handles with the <CODE>Symbol</CODE> module.
   
  -<P><A NAME="anchor303"></A>
  +<P>
   <CODE>Symbol::gensym()</CODE> creates an anonymous glob and returns a reference to it. Such a glob
   reference can be used as a file or directory handle. Here is how you can
   use it:
   
  -<P><A NAME="anchor304"></A>
  -<PRE>  use Symbol;
  -  my $fh = gensym;
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  use Symbol;
  +  my $fh = gensym;
     open $fh, &quot;+&gt;&gt;filename&quot; or die &quot;$!&quot;;
     flock $fh, LOCK_EX;
  -  # do something
  -</PRE>
  -<P><A NAME="anchor305"></A>
  +  # do something</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Now the file will be always unlocked after processing the request.
   
  -<P><A NAME="anchor306"></A>
  +<P>
   Instead of using <CODE>close(),</CODE> you might use a block:
  +
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
   
  -<P><A NAME="anchor307"></A>
  -<PRE>  use Symbol;
  +	<td>
  +	  <pre>  use Symbol;
     {
       my $fh = gensym;
       open $fh, &quot;+&gt;&gt;filename&quot; or die &quot;$!&quot;;
       flock $fh, LOCK_EX;
       # do something
     }
  -  # the file will be automatically closed and unlocked at this point
  -</PRE>
  -<P><A NAME="anchor308"></A>
  +  # the file will be automatically closed and unlocked at this point</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   But this is perhaps not so obvious to the reader of the code, so you might
   want to avoid this last technique and put in an explicit
   <CODE>close().</CODE>
   
  -<P><A NAME="anchor309"></A>
  +<P>
   You can also use the <CODE>IO::*</CODE> modules, such as <CODE>IO::File</CODE> or
   <CODE>IO::Dir</CODE>. These are much bigger than the &lt;Symbol&gt; module, and worth using for files or directories only if you are
   already using them for the other features which they provide. As a matter
   of fact, these modules use the <CODE>Symbol</CODE> module themselves. Here are some examples of their use:
   
  -<P><A NAME="anchor310"></A>
  -<PRE>  use IO::File;
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  use IO::File;
     my $fh = IO::File-&gt;new(&quot;&gt;filename&quot;);
  -  # the rest is as before
  -</PRE>
  -<P><A NAME="anchor311"></A>
  +  # the rest is as before</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   and:
  +
  +<P>
   
  -<P><A NAME="anchor312"></A>
  -<PRE>  use IO::Dir;
  -  my $dh = IO::Dir-&gt;new(&quot;dirname&quot;);
  -</PRE>
  -<P><A NAME="anchor313"></A>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  use IO::Dir;
  +  my $dh = IO::Dir-&gt;new(&quot;dirname&quot;);</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Under perl 5.6 <CODE>Symbol.pm</CODE>-like functionality is a built-in feature, so you can do:
  +
  +<P>
   
  -<P><A NAME="anchor314"></A>
  -<PRE>  open my $fh, &quot;&gt; filename&quot;;
  -</PRE>
  -<P><A NAME="anchor315"></A>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  open my $fh, &quot;&gt; filename&quot;;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   and <CODE>$fh</CODE> will be automatically vivified as a valid filehandle, so you don't need to
   use the <CODE>Symbol</CODE> module anymore.
   
  -<P><A NAME="anchor316"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H3><A NAME="Cleanup_Code">Cleanup Code</A></H3></CENTER>
  -<P><A NAME="anchor317"></A>
  +<P>
   Finally, let's look at the case where we need special clean up code. As you
   have seen, we solved the problem of accidentally leaving file handles lying
   around by lexically scoping them. There are however, situations where you
   absolutely must write cleanup code. A tied dbm file is a good example.
   
  -<P><A NAME="anchor318"></A>
  +<P>
   A reminder: a dbm file is a simple database, which allows you to store
   pairs of keys and values in it. As of this writing, Berkeley DB is the most
   advanced dbm implementation, it allows you to store key/value pairs using
   the HASH, BTREE and RECNO algorithms. The <CODE>BerkeleyDB</CODE>
   module provides a Perl interface to Berkeley DB versions 2 and 3, while the <CODE>DB_File</CODE> module handles the older Berkeley DB, version 1. Refer to the <CODE>DB_File</CODE> man page for more information.
   
  -<P><A NAME="anchor319"></A>
  +<P>
   With the help of the TIE interface, working with dbm files is very simple
   because they are represented in Perl as simple hash variables. They behave
   almost exactly like hashes.
   
  -<P><A NAME="anchor320"></A>
  +<P>
   In order to access a dbm file you have to tie it first:
   
  -<P><A NAME="anchor321"></A>
  -<PRE>  use Fcntl qw(O_RDWR O_CREAT);
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  use Fcntl qw(O_RDWR O_CREAT);
     use DB_File;
     my $filename = &quot;/tmp/mydb&quot;;
     my %hash;
     tie %hash, 'DB_File', $filename, O_RDWR|O_CREAT, 0660, $DB_HASH
  -     or die &quot;Can't tie %hash : $!&quot;;
  -</PRE>
  -<P><A NAME="anchor322"></A>
  +     or die &quot;Can't tie %hash : $!&quot;;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   The first argument to <CODE>tie()</CODE> is the hash variable to which we
   want the dbm file to be tied. The remaining arguments are: the name of the
   module that provides the interface (<CODE>DB_File</CODE> in this case); the name of our dbm file; Fcntl flags; file permissions; and
   finally the interface method to be used (DB_HASH, DB_BTREE or DB_RECNO).
   
  -<P><A NAME="anchor323"></A>
  +<P>
   From now on we use <CODE>%hash</CODE> to read from and write to the dbm file, like this:
   
  -<P><A NAME="anchor324"></A>
  -<PRE>  $hash{foo} = &quot;Larry Wall&quot;;
  -  my $name = $hash{foo};
  -</PRE>
  -<P><A NAME="anchor325"></A>
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  $hash{foo} = &quot;Larry Wall&quot;;
  +  my $name = $hash{foo};</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   The only wrinkle is that when we modify the hash (by assigning some values
   to it) the changes are not written immediately to the file. They are cached
   to improve performance. The cache buffers are flushed in the following
  @@ -1964,51 +2862,99 @@
   be aware that if the program quits abnormally, the dbm file might be
   corrupted.
   
  -<P><A NAME="anchor326"></A>
  +<P>
   To untie the dbm file, simply call:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor327"></A>
  -<PRE>  untie %hash;
  -</PRE>
  -<P><A NAME="anchor328"></A>
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  untie %hash;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   To gain the access to the <CODE>sync()</CODE> method, you should retrieve
   the database handle which is returned by the <CODE>tie()</CODE> method:
   
  -<P><A NAME="anchor329"></A>
  -<PRE>  my $dbh = tie %hash, 'DB_File', $filename, O_RDWR|O_CREAT, 0660, $DB_HASH
  -     or die &quot;Can't tie %hash : $!&quot;;
  -</PRE>
  -<P><A NAME="anchor330"></A>
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  my $dbh = tie %hash, 'DB_File', $filename, O_RDWR|O_CREAT, 0660, $DB_HASH
  +     or die &quot;Can't tie %hash : $!&quot;;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Now you can flush the cache with:
  +
  +<P>
   
  -<P><A NAME="anchor331"></A>
  -<PRE>  $hash{foo} = &quot;Larry Wall&quot;;
  -  $dbh-&gt;sync;
  -</PRE>
  -<P><A NAME="anchor332"></A>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  $hash{foo} = &quot;Larry Wall&quot;;
  +  $dbh-&gt;sync;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Important: If you have saved a copy of the object returned from
   <CODE>tie(),</CODE> the underlying database file will not be closed until
   both the tied variable is untied and all copies of the saved object are
   destroyed.
   
  -<P><A NAME="anchor333"></A>
  +<P>
   We do this as follows:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor334"></A>
  -<PRE>  undef $dbh;
  -  untie %hash;
  -</PRE>
  -<P><A NAME="anchor335"></A>
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  undef $dbh;
  +  untie %hash;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Of course, you have to lock the dbm file exactly like any other resource if
   some script modifies its contents. Refer to <A HREF="././dbm.html#Locking_dbm_handlers">Locking dbm handlers</A> for more information.
   
  -<P><A NAME="anchor336"></A>
  +<P>
   Okay, enough introduction, let's get to the point. Since both <CODE>%hash</CODE>
   and <CODE>$dbh</CODE> are lexically scoped variables, they will always be destroyed, even if you
   forgot to <CODE>untie()</CODE> them or if the request was aborted before
   the <CODE>untie()</CODE> function was called.
   
  -<P><A NAME="anchor337"></A>
  +<P>
   Suppose that you want to have the benefit of mod_perl's persistent global
   variables in each process and to use this feature to create persistent dbm
   hashes. You <CODE>tie()</CODE> them only once per Apache child process,
  @@ -2018,12 +2964,21 @@
   <CODE>sync()</CODE> method) when you modify the hash that represents the
   dbm file, the idea is a good one. Let's code it...
   
  -<P><A NAME="anchor338"></A>
  +<P>
   We declare <CODE>$dbh</CODE> and <CODE>%hash</CODE> as global variables, then pull in the
   <CODE>Fcntl</CODE> module and import the symbols we are going to use. Actually we need only <CODE>LOCK_EX</CODE> from the tags provided by <CODE>:flock</CODE>. We pull in the <CODE>DB_File</CODE> and <CODE>Symbol</CODE> modules:
   
  -<P><A NAME="anchor339"></A>
  -<PRE>  use strict;
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  use strict;
     use vars qw($dbh %hash);
     use Fcntl qw(:flock O_RDWR O_CREAT);
     use DB_File;
  @@ -2047,87 +3002,183 @@
     
     my $fh = gensym;
     open $fh, &quot;&gt;$lockfile&quot; or die &quot;Cannot open $lockfile: $!&quot;;
  -  flock $fh, LOCK_EX;
  -</PRE>
  -<P><A NAME="anchor340"></A>
  -<PRE>  # Other copies of this script which wish to access the following
  +  flock $fh, LOCK_EX;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  # Other copies of this script which wish to access the following
     # code have to acquire the lock file first.  Since it's an exclusive
     # lock, only one copy of the script will be able to tie the dbm
  -  # file.
  -</PRE>
  -<P><A NAME="anchor341"></A>
  -<PRE>  $dbh ||= tie %hash, 'DB_File', $filename, O_RDWR|O_CREAT, 0660, $DB_HASH
  -     or die &quot;Can't tie %hash : $!&quot;;
  -</PRE>
  -<P><A NAME="anchor342"></A>
  +  # file.</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  $dbh ||= tie %hash, 'DB_File', $filename, O_RDWR|O_CREAT, 0660, $DB_HASH
  +     or die &quot;Can't tie %hash : $!&quot;;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   This code snippet demands some explanation.
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor343"></A>
  -<PRE>  $a ||= $b;
  -</PRE>
  -<P><A NAME="anchor344"></A>
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  $a ||= $b;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   is the same as:
   
  -<P><A NAME="anchor345"></A>
  -<PRE>  $a = $a || $b;
  -</PRE>
  -<P><A NAME="anchor346"></A>
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  $a = $a || $b;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   The boolean test <CODE>||</CODE> (logical OR) doesn't care about undefined values, since <CODE>undef</CODE> is <CODE>false</CODE> in Perl. So what it does is this:
   
  -<P><A NAME="anchor347"></A>
  +<P>
   If <CODE>$a</CODE> is <EM>true</EM>, leave it unmodified. Otherwise test <CODE>$b</CODE>.
   
  -<P><A NAME="anchor348"></A>
  +<P>
   If <CODE>$b</CODE>  <EM>true</EM>, assign the value of <CODE>$b</CODE> to <CODE>$a</CODE>.
   
  -<P><A NAME="anchor349"></A>
  +<P>
   If <CODE>$b</CODE> is <EM>false</EM>, <CODE>$a</CODE> stays undefined.
   
  -<P><A NAME="anchor350"></A>
  +<P>
   Note that 0 and <CODE>&quot;&quot;</CODE> (the empty string) are both <EM>defined</EM>, but they are <EM>false</EM> values! Refer to the <CODE>perlop(1)</CODE> manpage for more information
   about the <CODE>||</CODE> operator.
   
  -<P><A NAME="anchor351"></A>
  +<P>
   Back to our <CODE>tie()</CODE> snippet. For each mod_perl process, when
   this code is executed for the first time, the <CODE>$dbh</CODE> variable is undefined. Therefore the right-hand part of the statement will
   be executed, <CODE>tie()ing</CODE> the dbm file. On every subsequent
   invocation of the code by that same process, <CODE>$dbh</CODE> will contain a database handle. This is considered by Perl to be a <EM>true</EM> value, so the <CODE>tie()</CODE> call will not be executed, eliminating the
   overhead of the call to <CODE>tie().</CODE>
   
  -<P><A NAME="anchor352"></A>
  +<P>
   Now we fill the dbm file with random key/value pairs. Each invocation of
   the code will either generate a new key/value pair or, if an existing key
   is returned by <CODE>rand(),</CODE> override an old one.
   
  -<P><A NAME="anchor353"></A>
  -<PRE>  $hash{int rand 10} = (qw(a b c d))[int rand 4];
  -  $dbh-&gt;sync();
  -</PRE>
  -<P><A NAME="anchor354"></A>
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  $hash{int rand 10} = (qw(a b c d))[int rand 4];
  +  $dbh-&gt;sync();</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   The most important part of the code is to flush the modifications to the
   dbm.
   
  -<P><A NAME="anchor355"></A>
  -<PRE>    # unlock the db
  -  close $fh;
  -</PRE>
  -<P><A NAME="anchor356"></A>
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>    # unlock the db
  +  close $fh;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Now it's safe to unlock the dbm file. Please refer to <A HREF="././dbm.html#Locking_dbm_handlers">Locking dbm handlers</A> to learn why you should use a dbm's file descriptor to lock itself. To cut
   a long story short, if you don't you may corrupt your dbm file.
   
  -<P><A NAME="anchor357"></A>
  +<P>
   After we leave the critical section, we can take our time and print out the
   current contents of the dbm file.
  +
  +<P>
   
  -<P><A NAME="anchor358"></A>
  -<PRE>  # print the contents of the the dbm file
  -  print map {&quot;$_ =&gt; $hash{$_}\n&quot;} sort keys %hash;
  -</PRE>
  -<P><A NAME="anchor359"></A>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  # print the contents of the the dbm file
  +  print map {&quot;$_ =&gt; $hash{$_}\n&quot;} sort keys %hash;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Here is the same code with fewer comments:
  +
  +<P>
   
  -<P><A NAME="anchor360"></A>
  -<PRE>  use strict;
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  use strict;
     use vars qw($dbh %hash);
     use Fcntl qw(:flock O_RDWR O_CREAT);
     use DB_File;
  @@ -2159,9 +3210,12 @@
     close $fh;
     
       # print the contents of the the dbm file
  -  print map {&quot;$_ =&gt; $hash{$_}\n&quot;} sort keys %hash;
  -</PRE>
  -<P><A NAME="anchor361"></A>
  +  print map {&quot;$_ =&gt; $hash{$_}\n&quot;} sort keys %hash;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Well, if you run this code, you pretty soon figure out that this code
   doesn't do what we thought it would. What happens is that each process
   keeps its own copy of the <CODE>%hash</CODE> and modifies it. When the process calls the <CODE>sync()</CODE> method, the
  @@ -2171,7 +3225,7 @@
   of the
   <CODE>%hash</CODE> instead.
   
  -<P><A NAME="anchor362"></A>
  +<P>
   In reality things are even more complicated. The above scenario is true
   only when the hash file is smaller than the buffer size of the dbm file.
   When it becomes bigger than the buffer, its contents are flushed. When you
  @@ -2179,102 +3233,184 @@
   to read the values saved by the previous <CODE>sync()</CODE> calls and
   automatic flushes caused by buffer overflow.
   
  -<P><A NAME="anchor363"></A>
  +<P>
   Which creates a whole big mess with the data and makes the whole idea is
   useless.
   
  -<P><A NAME="anchor364"></A>
  +<P>
   But if you have followed me this far, let's see what else is wrong with
   this code. It's the <CODE>sync()</CODE> call. If the script somehow stops
   before <CODE>sync()</CODE> is called, the dbm will be unlocked because <CODE>$fh</CODE>
   is lexically scoped. But it won't be properly <CODE>sync()ed,</CODE> which
   at some point will corrupt the dbm file.
   
  -<P><A NAME="anchor365"></A>
  +<P>
   The solution is simple. Write an <CODE>END</CODE> block to sync the file:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor366"></A>
  -<PRE>  END{
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  END{
       # make sure that the DB is flushed
        $dbh-&gt;sync();
  -  }
  -</PRE>
  -<P><A NAME="anchor367"></A>
  +  }</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Under mod_perl, the above will work only for <CODE>Apache::Registry</CODE>
   scripts. Otherwise execution of the <CODE>END</CODE> block will be postponed until the process terminates. If you write a
   handler in the Perl API use the <CODE>register_cleanup()</CODE> method instead. It accepts a reference to a subroutine as an argument:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor368"></A>
  -<PRE>  $r-&gt;register_cleanup(sub { $dbh-&gt;sync() });
  -</PRE>
  -<P><A NAME="anchor369"></A>
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  $r-&gt;register_cleanup(sub { $dbh-&gt;sync() });</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Even better would be to check whether the client connection has been
   aborted. If you don't check, the cleanup code will always be executed and
   for normally terminated scripts this may not be what you want:
  +
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
   
  -<P><A NAME="anchor370"></A>
  -<PRE>  $r-&gt;register_cleanup(
  +	<td>
  +	  <pre>  $r-&gt;register_cleanup(
       # make sure that the DB is flushed
       sub{ 
         $dbh-&gt;sync() if Apache-&gt;request-&gt;connection-&gt;aborted();
       }
  -  );
  -</PRE>
  -<P><A NAME="anchor371"></A>
  +  );</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   So in the case of <CODE>END</CODE> block usage you would use:
   
  -<P><A NAME="anchor372"></A>
  -<PRE>  END{
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  END{
       # make sure that the DB is flushed
       $dbh-&gt;sync() if Apache-&gt;request-&gt;connection-&gt;aborted();
  -  }
  -</PRE>
  -<P><A NAME="anchor373"></A>
  +  }</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Note that if you use <CODE>register_cleanup()</CODE> it should be called at the beginning of the script, or as soon as the
   variables you want to use in this code become available. If you use it at
   the end of the script, and the script happens to be aborted before this
   code is reached, there will be no cleanup performed.
   
  -<P><A NAME="anchor374"></A>
  +<P>
   For example <CODE>CGI.pm</CODE> registers the cleanup subroutine in its <CODE>new()</CODE> method:
   
  -<P><A NAME="anchor375"></A>
  -<PRE>  sub new {
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  sub new {
       # code snipped
       if ($MOD_PERL) {   
           Apache-&gt;request-&gt;register_cleanup(\&amp;CGI::_reset_globals);
           undef $NPH;
       }
       # more code snipped
  -  }
  -</PRE>
  -<P><A NAME="anchor376"></A>
  +  }</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   There is another way to register a section of cleanup code for Perl API
   handlers. You may use <CODE>PerlCleanupHandler</CODE> in the configuration file, like this:
   
  -<P><A NAME="anchor377"></A>
  -<PRE>  &lt;Location /foo&gt;
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  &lt;Location /foo&gt;
       SetHandler perl-script
       PerlHandler        Apache::MyModule
       PerlCleanupHandler Apache::MyModule::cleanup()
       Options ExecCGI
  -  &lt;/Location&gt;
  -</PRE>
  -<P><A NAME="anchor378"></A>
  +  &lt;/Location&gt;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   <CODE>Apache::MyModule::cleanup()</CODE> performs the cleanup, obviously.
   
  -<P><A NAME="anchor379"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H1><A NAME="Handling_Server_Timeout_Cases_an">Handling Server Timeout Cases and Working with $SIG{ALRM}</A></H1></CENTER>
  -<P><A NAME="anchor380"></A>
  +<P>
   A similar situation to <A HREF="././debug.html#Handling_the_User_pressed_Stop_">Pressed Stop button disease</A> happens when the browser times out the connection (is it about 2 minutes?).
   There are cases when your script is about to perform a very long operation
   and there is a chance that its duration will be longer than the client's
   timeout. One example is database interaction, where the DB engine hangs or
   needs a long time to return the results. If this is the case, use <CODE>$SIG{ALRM}</CODE> to prevent the timeouts:
  +
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
   
  -<P><A NAME="anchor381"></A>
  -<PRE>    $timeout = 10; # seconds
  +	<td>
  +	  <pre>    $timeout = 10; # seconds
     eval {
       local $SIG{ALRM} =
           sub { die &quot;Sorry timed out. Please try again\n&quot; };
  @@ -2283,164 +3419,241 @@
       alarm 0;
     };
     
  -  die $@ if $@;
  -</PRE>
  -<P><A NAME="anchor382"></A>
  +  die $@ if $@;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   It was recently discovered that <CODE>local $SIG{'ALRM'}</CODE> does not restore the original underlying C handler. This was fixed in
   mod_perl 1.19_01 (<A HREF="././download.html#mod_perl">CVS version</A>). As a matter of fact none of the
   <CODE>local $SIG{FOO}</CODE> signals restores the original C handler - read
   <A HREF="././debug.html#Debugging_Signal_Handlers_SIG_">Debugging Signal Handlers ($SIG{FOO})</A> for a debug technique and a possible workaround.
   
  -<P><A NAME="anchor383"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H1><A NAME="Looking_inside_the_server">Looking inside the server</A></H1></CENTER>
  -<P><A NAME="anchor384"></A>
  +<P>
   Your server is up and running, but something appears to be wrong. You want
   to see the numbers to tune your code or server configuration. You just want
   to know what's really going on inside the server.
   
  -<P><A NAME="anchor385"></A>
  +<P>
   How do you do it?
   
  -<P><A NAME="anchor386"></A>
  +<P>
   There are a few tools that allow you to look inside the server. 
   
  -<P><A NAME="anchor387"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="Apache_Status_Embedded_Inter">Apache::Status -- Embedded Interpreter Status Information</A></H2></CENTER>
  -<P><A NAME="anchor388"></A>
  +<P>
   This is a very useful module. It lets you watch what happens to the Perl
   parts of the server. You can see the size of all subroutines and variables,
   variable dumps, lexical information, OPcode trees, and more.
   
  -<P><A NAME="anchor389"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H3><A NAME="Minimal_Configuration">Minimal Configuration</A></H3></CENTER>
  -<P><A NAME="anchor390"></A>
  +<P>
   This configuration enables the <CODE>Apache::Status</CODE> module with its minimum feature set. Add this to <EM>httpd.conf</EM>:
  +
  +<P>
   
  -<P><A NAME="anchor391"></A>
  -<PRE>  &lt;Location /perl-status&gt;
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  &lt;Location /perl-status&gt;
       SetHandler perl-script
       PerlHandler Apache::Status
       order deny,allow
       #deny from all
       #allow from 
  -  &lt;/Location&gt;
  -</PRE>
  -<P><A NAME="anchor392"></A>
  +  &lt;/Location&gt;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   If you are going to use <CODE>Apache::Status</CODE> it's important to put it as the first module in the start-up file, or in <EM>httpd.conf</EM>:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor393"></A>
  -<PRE>  # startup.pl
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  # startup.pl
     use Apache::Status ();
     use Apache::Registry ();
  -  use Apache::DBI ();
  -</PRE>
  -<P><A NAME="anchor394"></A>
  +  use Apache::DBI ();</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   If you don't put <CODE>Apache::Status</CODE> before <CODE>Apache::DBI</CODE>, you won't get the <CODE>Apache::DBI</CODE> menu entry in the status. For more about
   <CODE>Apache::DBI</CODE> see <A HREF="././performance.html#Persistent_DB_Connections">Persistent DB Connections</A>.
   
  -<P><A NAME="anchor395"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H3><A NAME="Extended_Configuration">Extended Configuration</A></H3></CENTER>
  -<P><A NAME="anchor396"></A>
  +<P>
   There are several variables which you can use to modify the behaviour of <CODE>Apache::Status</CODE>.
   
   <UL>
   <P><LI><STRONG><A NAME="item_PerlSetVar">PerlSetVar StatusOptionsAll On</A></STRONG>
  -<P><A NAME="anchor397"></A>
  +<P>
   This single directive will enable all of the options described below.
   
   <P><LI><STRONG><A NAME="item_PerlSetVar">PerlSetVar StatusDumper On</A></STRONG>
  -<P><A NAME="anchor398"></A>
  +<P>
   When you are browsing symbol tables, you can view the values of your
   arrays, hashes and scalars with <CODE>Data::Dumper</CODE>.
   
   <P><LI><STRONG><A NAME="item_PerlSetVar">PerlSetVar StatusPeek On</A></STRONG>
  -<P><A NAME="anchor399"></A>
  +<P>
   With this option On and the <CODE>Apache::Peek</CODE> module installed, functions and variables can be viewed in <CODE>Devel::Peek</CODE> style.
   
   <P><LI><STRONG><A NAME="item_PerlSetVar">PerlSetVar StatusLexInfo On</A></STRONG>
  -<P><A NAME="anchor400"></A>
  +<P>
   With this option On and the <CODE>B::LexInfo</CODE> module installed, subroutine lexical variable information can be viewed.
   
   <P><LI><STRONG><A NAME="item_PerlSetVar">PerlSetVar StatusDeparse On</A></STRONG>
  -<P><A NAME="anchor401"></A>
  +<P>
   With this option On and <CODE>B::Deparse</CODE> version 0.59 or higher (included in Perl 5.005_59+), subroutines can be
   ``deparsed''.
   
  -<P><A NAME="anchor402"></A>
  +<P>
   Options can be passed to <CODE>B::Deparse::new</CODE> like so:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor403"></A>
  -<PRE>  PerlSetVar StatusDeparseOptions &quot;-p -sC&quot;
  -</PRE>
  -<P><A NAME="anchor404"></A>
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  PerlSetVar StatusDeparseOptions &quot;-p -sC&quot;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   See the <CODE>B::Deparse</CODE> manpage for details.
   
   <P><LI><STRONG><A NAME="item_PerlSetVar">PerlSetVar StatusTerse On</A></STRONG>
  -<P><A NAME="anchor405"></A>
  +<P>
   With this option On, text-based op tree graphs of subroutines can be
   displayed, thanks to <CODE>B::Terse</CODE>.
   
   <P><LI><STRONG><A NAME="item_PerlSetVar">PerlSetVar StatusTerseSize On</A></STRONG>
  -<P><A NAME="anchor406"></A>
  +<P>
   With this option On and the <CODE>B::TerseSize</CODE> module installed, text-based op tree graphs of subroutines and their size
   can be displayed. See the <CODE>B::TerseSize</CODE> docs for more info.
   
   <P><LI><STRONG><A NAME="item_PerlSetVar">PerlSetVar StatusTerseSizeMainSummary On</A></STRONG>
  -<P><A NAME="anchor407"></A>
  +<P>
   With this option On and the <CODE>B::TerseSize</CODE> module installed, ``Memory Usage'' will be added to the <CODE>Apache::Status</CODE> main menu. This option is disabled by default, as it can be rather cpu
   intensive to summarize memory usage for the entire server. It is strongly
   suggested that this option only be used with a development server running
   in -X mode, as the results will be cached.
   
  -<P><A NAME="anchor408"></A>
  +<P>
   Remember to preload <CODE>B::TerseSize</CODE> with: 
   
  -<P><A NAME="anchor409"></A>
  -<PRE>  PerlModule B::Terse
  -</PRE>
  -<P><LI><STRONG><A NAME="item_PerlSetVar">PerlSetVar StatusGraph</A></STRONG>
  -<P><A NAME="anchor410"></A>
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  PerlModule B::Terse</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P><LI><STRONG><A NAME="item_PerlSetVar">PerlSetVar StatusGraph</A></STRONG>
  +<P>
   When <CODE>StatusDumper</CODE> (see above) is enabled, another link <EM>"OP Tree
   Graph"</EM> will be present with the dump if this configuration variable is set to On.
   
  -<P><A NAME="anchor411"></A>
  +<P>
   This requires the B module (part of the Perl compiler kit) and the
   <CODE>B::Graph</CODE> module version 0.03 or higher to be installed along with the `dot' program.
   Dot is part of the graph visualization toolkit from AT&amp;T: <A
   HREF="http://www.research.att.com/sw/tools/graphviz/.">http://www.research.att.com/sw/tools/graphviz/.</A>
   
   
  -<P><A NAME="anchor412"></A>
  +<P>
   WARNING: Some graphs may produce very large images, and some graphs may
   produce no image if <CODE>B::Graph</CODE>'s output is incorrect.
   
   </UL>
  -<P><A NAME="anchor413"></A>
  +<P>
   There is more information about <CODE>Apache::Status</CODE> in its manpage.
   
  -<P><A NAME="anchor414"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H3><A NAME="Usage">Usage</A></H3></CENTER>
  -<P><A NAME="anchor415"></A>
  +<P>
   Assuming that your mod_perl server listens on port 81, fetch <A
   HREF="http://www.myserver.com:81/perl-status">http://www.myserver.com:81/perl-status</A>
   
   
  -<P><A NAME="anchor416"></A>
  -<PRE>  Embedded Perl version 5.00502 for Apache/1.3.2 (Unix) mod_perl/1.16 
  -  process 187138, running since Thu Nov 19 09:50:33 1998
  -</PRE>
  -<P><A NAME="anchor417"></A>
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  Embedded Perl version 5.00502 for Apache/1.3.2 (Unix) mod_perl/1.16 
  +  process 187138, running since Thu Nov 19 09:50:33 1998</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Below all the sections are links when you view them through <EM>/perl-status</EM>
   
   
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor418"></A>
  -<PRE>  Signal Handlers
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  Signal Handlers
     Enabled mod_perl Hooks
     PerlRequire'd Files
     Environment
  @@ -2450,68 +3663,109 @@
     ISA Tree
     Inheritance Tree
     Compiled Registry Scripts
  -  Symbol Table Dump
  -</PRE>
  -<P><A NAME="anchor419"></A>
  +  Symbol Table Dump</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Let's follow, for example, <CODE>PerlRequire</CODE>'d Files. We see:
  +
  +<P>
   
  -<P><A NAME="anchor420"></A>
  -<PRE>  PerlRequire                   Location
  -  /home/perl/apache-startup.pl  /home/perl/apache-startup.pl
  -</PRE>
  -<P><A NAME="anchor421"></A>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  PerlRequire                   Location
  +  /home/perl/apache-startup.pl  /home/perl/apache-startup.pl</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   From some menus you can move deeper to peek into the internals of the
   server, to see the values of the global variables in the packages, to see
   the cached scripts and modules, and much more. Just click around...
   
  -<P><A NAME="anchor422"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H3><A NAME="Compiled_Registry_Scripts_sectio">Compiled Registry Scripts section seems to be empty.</A></H3></CENTER>
  -<P><A NAME="anchor423"></A>
  +<P>
   Sometimes when you fetch <EM>/perl-status</EM> and look at the <STRONG>Compiled
   Registry Scripts</STRONG> you see no listing of scripts at all. This is correct: <CODE>Apache::Status</CODE> shows the registry scripts compiled in the httpd child which is serving
   your request for <EM>/perl-status</EM>. If the child has not yet compiled the script you are asking for,
   <EM>/perl-status</EM> will just show you the main menu.
   
  -<P><A NAME="anchor424"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="mod_status">mod_status</A></H2></CENTER>
  -<P><A NAME="anchor425"></A>
  +<P>
   The Status module allows a server administrator to find out how well the
   server is performing. An HTML page is presented that gives the current
   server statistics in an easily readable form. If required, given a
   compatible browser this page can be automatically refreshed. Another page
   gives a simple machine-readable list of the current server state.
   
  -<P><A NAME="anchor426"></A>
  +<P>
   This Apache module is written in C. It is compiled by default, so all you
   have to do to use it is enable it in your configuration file:
  +
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
   
  -<P><A NAME="anchor427"></A>
  -<PRE>  &lt;Location /status&gt;
  +	<td>
  +	  <pre>  &lt;Location /status&gt;
       SetHandler server-status
  -  &lt;/Location&gt;
  -</PRE>
  -<P><A NAME="anchor428"></A>
  +  &lt;/Location&gt;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   For security reasons you will probably want to limit access to it. If you
   have installed Apache according to the instructions you will find a
   prepared configuration section in <EM>httpd.conf</EM>: to enable use of the mod_status module, just uncomment it.
  +
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
   
  -<P><A NAME="anchor429"></A>
  -<PRE>  ExtendedStatus On
  +	<td>
  +	  <pre>  ExtendedStatus On
     &lt;Location /status&gt;
       SetHandler server-status
       order deny,allow
       deny from all
       allow from localhost
  -  &lt;/Location&gt;
  -</PRE>
  -<P><A NAME="anchor430"></A>
  +  &lt;/Location&gt;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   You can now access server statistics by using a Web browser to access the
   page <A HREF="http://localhost/status">http://localhost/status</A> (as long
   as your server recognizes localhost:).
   
  -<P><A NAME="anchor431"></A>
  +<P>
   The details given by mod_status are:
   
   <UL>
  @@ -2528,91 +3782,32 @@
   Apache</A></STRONG>
   <P><LI><STRONG><A NAME="item_The">The current hosts and requests being processed</A></STRONG>
   </UL>
  -<P><A NAME="anchor432"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="Apache_VMonitor_Visual_Syste">Apache::VMonitor -- Visual System and Apache Server Monitor</A></H2></CENTER>
  -<P><A NAME="anchor433"></A>
  -<CODE>Apache::VMonitor</CODE> is the next generation of
  -<A HREF="././debug.html#mod_status">mod_status</A>. It provides all the information mod_status provides and much more.
  -
  -<P><A NAME="anchor434"></A>
  -This module emulates the reporting functions of the <CODE>top(),</CODE>
  -<CODE>mount(),</CODE> <CODE>df()</CODE> and <CODE>ifconfig()</CODE>
  -utilities. There is a special mode for mod_perl processes. It has visual
  -alert capabilities and a configurable `automatic refresh' mode. It provides
  -a Web interface, which can be used to show or hide all the sections
  -dynamically.
  -
  -<P><A NAME="anchor435"></A>
  -The are two main modes:
  -
  -<UL>
  -<P><LI>
  -<P><A NAME="anchor436"></A>
  -Multi processes mode -- All system processes and information is shown.
  -
  -<P><LI>
  -<P><A NAME="anchor437"></A>
  -Single process mode -- In-depth information about a single process is
  -shown.
  +<P>
  +This module is covered in the section ``<A HREF="././modules.html#Apache_VMonitor_Visual_Syste">Apache::*  Modules</A>''
   
  -</UL>
  -<P><A NAME="anchor438"></A>
  -The main advantage of this module is that it reduces the need to telnet to
  -the machine in order to monitor it. Indeed it provides information about
  -mod_perl processes that cannot be acquired from telneting to the machine.
  -
  -<P><A NAME="anchor439"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<CENTER><H3><A NAME="Configuration">Configuration</A></H3></CENTER>
  -<P><A NAME="anchor440"></A>
  -<PRE>  # Configuration in httpd.conf
  -  &lt;Location /sys-monitor&gt;
  -    SetHandler perl-script
  -    PerlHandler Apache::VMonitor
  -  &lt;/Location&gt;
  -</PRE>
  -<P><A NAME="anchor441"></A>
  -<PRE>  # startup file or &lt;Perl&gt; section:
  -  use Apache::VMonitor();
  -  $Apache::VMonitor::Config{BLINKING} = 0; # Blinking is evil
  -  $Apache::VMonitor::Config{REFRESH}  = 0;
  -  $Apache::VMonitor::Config{VERBOSE}  = 0;
  -  $Apache::VMonitor::Config{SYSTEM}   = 1;
  -  $Apache::VMonitor::Config{APACHE}   = 1;
  -  $Apache::VMonitor::Config{PROCS}    = 1;
  -  $Apache::VMonitor::Config{MOUNT}    = 1;
  -  $Apache::VMonitor::Config{FS_USAGE} = 1;
  -  $Apache::VMonitor::Config{NETLOAD}  = 1;
  -                                
  -  @Apache::VMonitor::NETDEVS    = qw(lo eth0);
  -  $Apache::VMonitor::PROC_REGEX = join &quot;\|&quot;, qw(httpd mysql squid);
  -</PRE>
  -<P><A NAME="anchor442"></A>
  -More information available in the module's extensive manpage.
  -
  -<P><A NAME="anchor443"></A>
  -It requires <CODE>Apache::Scoreboard</CODE> and <CODE>GTop</CODE> to work.  <CODE>GTop</CODE> in turn requires the <CODE>libgtop</CODE> library but is not available for all platforms. Visit <A
  -HREF="http://www.home-of-linux.org/gnome/libgtop/">http://www.home-of-linux.org/gnome/libgtop/</A>
  -to check whether your platform/flavor is supported.
  -
  -<P><A NAME="anchor444"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H1><A NAME="Sometimes_My_Script_Works_Somet">Sometimes My Script Works, Sometimes It Does Not</A></H1></CENTER>
  -<P><A NAME="anchor445"></A>
  +<P>
   See <A HREF="././porting.html#Sometimes_it_Works_Sometimes_it">Sometimes it Works Sometimes it does Not</A>
   
   
   
  -<P><A NAME="anchor446"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H1><A NAME="Code_Debug">Code Debug</A></H1></CENTER>
  -<P><A NAME="anchor447"></A>
  +<P>
   When the code doesn't perform as expected, either never or just sometimes,
   we say that the code needs debugging. There are several levels of debugging
   complexity.
   
  -<P><A NAME="anchor448"></A>
  +<P>
   The basic level is when Perl terminates the program during the compilation
   phase, before it tries to run the resulting byte-code. This usually happens
   because there are syntax errors in the code, or perhaps a module is
  @@ -2621,7 +3816,7 @@
   from the shell. We will learn how to solve syntax problems in mod_perl code
   quite easily.
   
  -<P><A NAME="anchor449"></A>
  +<P>
   Once the program compiles and begins to run, there might be logical
   problems, when the program doesn't do what you thought you had programmed
   it to do. These are somewhat harder to solve, especially when there is a
  @@ -2630,7 +3825,7 @@
   For example, if you wanted to compare two numbers, but you omitted the
   second '=' character so that you had something like <CODE>if $yes = 1</CODE> instead of <CODE>if $yes == 1</CODE>, it warns us about the missing '='.
   
  -<P><A NAME="anchor450"></A>
  +<P>
   The next level is when the program does what it's expected to do most of
   the time, but occasionally misbehaves. Often you find that
   <CODE>print()</CODE> statements or the Perl debugger can help, but
  @@ -2638,7 +3833,7 @@
   with <CODE>print(),</CODE> but sometimes typing the debug messages can
   become very tedious. That's where the Perl debugger comes into its own.
   
  -<P><A NAME="anchor451"></A>
  +<P>
   While <CODE>print()</CODE> statements always work, running the perl
   debugger for CGI scripts might be quite a challenge. But with the right
   knowledge and tools handy the debug process becomes much easier.
  @@ -2649,7 +3844,7 @@
   write simpler clearer code it does not need so much debugging in the first
   place.
   
  -<P><A NAME="anchor452"></A>
  +<P>
   One of the most difficult cases to debug, is when the process just
   terminates in the middle of processing a request and dumps core. Often when
   there is a bug the program tries to access a memory area that doesn't
  @@ -2660,26 +3855,27 @@
   in mod_perl itself (mod_perl is written in C), that was in a deep slumber
   before your code awakened it.
   
  -<P><A NAME="anchor453"></A>
  +<P>
   In the following sections we will go through in detail each of the problems
   presented, thoroughly discuss them and present a few techniques to solve
   them.
   
  -<P><A NAME="anchor454"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="Locating_and_correcting_Syntax_E">Locating and correcting Syntax Errors</A></H2></CENTER>
  -<P><A NAME="anchor455"></A>
  +<P>
   While developing code we often make syntax mistakes, like forgetting to put
   a comma in a list, or a semicolon at the end of a statement.
   
  -<P><A NAME="anchor456"></A>
  +<P>
   (Even after a block, where a semicolon is not required, it may be better to
   put one in: there is a chance that you will add more code later, and when
   you do you might forget to add the now required semicolon. Similarly, more
   items might be added later to a list; unlike many other languages, Perl has
   no problem when you end a list with a redundant comma.)
   
  -<P><A NAME="anchor457"></A>
  +<P>
   One approach to locating syntactically incorrect code is to execute the
   script from the shell with the <EM>-c</EM> flag. This tells Perl to check the syntax but not to run the code
   (actually, it will execute
  @@ -2687,50 +3883,72 @@
   your program). (Note also that Perl 5.6.0 has introduced a new special
   variable, <CODE>$^C</CODE>, which is set to true when perl is run with the <EM>-c</EM> flag; this provides an opportunity to have some further control over <CODE>BEGIN</CODE> and
   <CODE>END</CODE> blocks during syntax checking.) Also it's a good idea to add the <CODE>-w</CODE> switch to enable warnings:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor458"></A>
  -<PRE>  perl -cw test.pl
  -</PRE>
  -<P><A NAME="anchor459"></A>
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  perl -cw test.pl</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   If there are errors in the code, Perl will report the errors, and tell you
   at which line numbers in your script the errors were found.
   
  -<P><A NAME="anchor460"></A>
  +<P>
   The next step is to execute the script, since in addition to syntax errors
   there may be run time errors. These are the errors that cause the <EM>"Internal Server Error"</EM> page when executed from a browser. With plain CGI scripts it's the same as
   running plain Perl scripts -- just execute them and see that they work.
   
  -<P><A NAME="anchor461"></A>
  +<P>
   The whole thing is quite different with scripts that use <A HREF="#item_Apache_">Apache::*</A>
   modules which can be used only from within the mod_perl server environment.
   These scripts rely on other code, and an environment which isn't available
   when you attempt to execute the script from the shell. There is no Apache
   request object available to the code when it is executed from the shell.
   
  -<P><A NAME="anchor462"></A>
  +<P>
   If you have a problem when using <A HREF="#item_Apache_">Apache::*</A> modules, you can make a request to the script from a browser and watch the
   errors and warnings as they are logged to the <EM>error_log</EM> file. Alternatively you can use the <CODE>Apache::FakeRequest</CODE> module.
   
  -<P><A NAME="anchor463"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="Using_Apache_FakeRequest_to_Deb">Using Apache::FakeRequest to Debug Apache Perl Modules</A></H2></CENTER>
  -<P><A NAME="anchor464"></A>
  +<P>
   <CODE>Apache::FakeRequest</CODE> is used to set up an empty Apache request object that can be used for
   debugging. The <CODE>Apache::FakeRequest</CODE>
   methods just set internal variables with the same names as the methods and
   return the value of the internal variables. Initial values for methods can
   be specified when the object is created. The print method prints to STDOUT.
   
  -<P><A NAME="anchor465"></A>
  +<P>
   Subroutines for Apache constants are also defined so that you can use
   <CODE>Apache::Constants</CODE> while debugging, although the values of the constants are hard-coded rather
   than extracted from the Apache source code.
   
  -<P><A NAME="anchor466"></A>
  +<P>
   Let's write a very simple module, which prints <EM>"OK"</EM> to the client's browser:
  +
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
   
  -<P><A NAME="anchor467"></A>
  -<PRE>  package Apache::Example;
  +	<td>
  +	  <pre>  package Apache::Example;
     use Apache::Constants;
     
     sub handler{
  @@ -2740,80 +3958,144 @@
       return OK;
     }
     
  -  1;
  -</PRE>
  -<P><A NAME="anchor468"></A>
  +  1;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   You cannot debug this module unless you configure the server to run it, by
   calling its handler from somewhere. So for example you could put in <EM>httpd.conf</EM>:
   
  -<P><A NAME="anchor469"></A>
  +<P>
   &lt;Location /ex&gt; SetHandler perl-script PerlHandler Apache::Example
   &lt;/Location&gt;
   
  -<P><A NAME="anchor470"></A>
  +<P>
   Then after restarting the server you could start a browser, request the
   location <A HREF="http://localhost/ex">http://localhost/ex</A> and examine
   the output. Tedious, no?
   
  -<P><A NAME="anchor471"></A>
  +<P>
   But with the help of <CODE>Apache::FakeRequest</CODE> you can write a little script that will emulate a request and return the
   output.
   
  -<P><A NAME="anchor472"></A>
  -<PRE>  #!/usr/bin/perl
  -</PRE>
  -<P><A NAME="anchor473"></A>
  -<PRE>  use Apache::FakeRequest ();
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  #!/usr/bin/perl</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  use Apache::FakeRequest ();
     use Apache::Example ();
     
     my $r = Apache::FakeRequest-&gt;new('get_remote_host'=&gt;'www.foo.com');
  -  Apache::Example::handler($r);
  -</PRE>
  -<P><A NAME="anchor474"></A>
  +  Apache::Example::handler($r);</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   when you execute the script from the command line, you will see the
   following output:
  +
  +<P>
   
  -<P><A NAME="anchor475"></A>
  -<PRE>  You are OK www.foo.com
  -</PRE>
  -<P><A NAME="anchor476"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  You are OK www.foo.com</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="Finding_the_Line_Which_Triggered">Finding the Line Which Triggered the Error or Warning</A></H2></CENTER>
  -<P><A NAME="anchor477"></A>
  +<P>
   Perl has no problem with the line numbers and file names for modules that
   are read from disk in the normal way, but modules that are compiled via
   eval such as <CODE>Apache::Registry</CODE> and <CODE>Apache::PerlRun</CODE>
   confuse it.
   
  -<P><A NAME="anchor478"></A>
  +<P>
   META: Isn't PERL_MARK_WHERE=1 is a default now?
   
  -<P><A NAME="anchor479"></A>
  +<P>
   If you compile with the experimental <STRONG>PERL_MARK_WHERE=1</STRONG>, then even for this kind of module Perl will show you almost the exact
   line which triggered the error.
   
  -<P><A NAME="anchor480"></A>
  +<P>
   There are compiler directives to reset its counter to some value that you
   decide. You can always pepper your code with these to help you locate the
   problem. At the beginning of the line you could write something of the
   form:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor481"></A>
  -<PRE>  #line nnn label
  -</PRE>
  -<P><A NAME="anchor482"></A>
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  #line nnn label</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   For example:
  +
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
   
  -<P><A NAME="anchor483"></A>
  -<PRE>  #line 298 myscript.pl
  +	<td>
  +	  <pre>  #line 298 myscript.pl
     or 
  -  #line 890 some_label_to_be_used_in_the_error_message
  -</PRE>
  -<P><A NAME="anchor484"></A>
  +  #line 890 some_label_to_be_used_in_the_error_message</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   The '#' must be in the first column, so if you cut and paste from this text
   you must remember to remove any leading white space.
   
  -<P><A NAME="anchor485"></A>
  +<P>
   The label is optional - the filename of the script will be used by default.
   This directive sets the line number of the <STRONG>following</STRONG>
   line, not the line the directive is on. You can use a little script to
  @@ -2821,8 +4103,17 @@
   have to remember to rerun this script every time you add or remove code
   lines. The script:
   
  -<P><A NAME="anchor486"></A>
  -<PRE>  #!/usr/bin/perl
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  #!/usr/bin/perl
     # Puts Perl line markers in a Perl program for debugging purposes.  
     # Also takes out old line markers.
     die &quot;No filename to process.\n&quot; unless @ARGV;
  @@ -2839,24 +4130,40 @@
     }
     close OUT;
     close IN;
  -  chmod 0755, &quot;$filename.marked&quot;;
  -</PRE>
  -<P><A NAME="anchor487"></A>
  +  chmod 0755, &quot;$filename.marked&quot;;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Another way of narrowing down the area to be searched is to move most of
   the code into a separate modules. This ensures that the line number will be
   reported correctly.
   
  -<P><A NAME="anchor488"></A>
  +<P>
   To have a complete trace of calls add:
  +
  +<P>
   
  -<P><A NAME="anchor489"></A>
  -<PRE>  use Carp ();
  -  local $SIG{__WARN__} = \&amp;Carp::cluck;
  -</PRE>
  -<P><A NAME="anchor490"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  use Carp ();
  +  local $SIG{__WARN__} = \&amp;Carp::cluck;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="Using_print_for_Debugging">Using print() for Debugging</A></H2></CENTER>
  -<P><A NAME="anchor491"></A>
  +<P>
   The universal debugging tool across nearly all platforms and programming
   languages is <CODE>printf()</CODE> or the equivalent output function. This
   can send data to the console, a file, an application window and so on. In
  @@ -2865,7 +4172,7 @@
   <CODE>print()</CODE> statements in the source code to examine the value of
   data at certain stages of execution.
   
  -<P><A NAME="anchor492"></A>
  +<P>
   However, it is rather difficult to anticipate all possible directions a
   program might take and what data to suspect of causing trouble. In
   addition, inline debugging code tends to add bloat and degrade the
  @@ -2876,13 +4183,22 @@
   need at best to uncomment the debugging code lines or, at worst, to write
   them again from scratch.
   
  -<P><A NAME="anchor493"></A>
  +<P>
   Let's see a few examples where we use <CODE>print()</CODE> to debug some
   problem. In one of my applications I wrote a function that returns the date
   that was one week ago. Here it is:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor494"></A>
  -<PRE>  print &quot;Content-type: text/plain\r\n\r\n&quot;;
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  print &quot;Content-type: text/plain\r\n\r\n&quot;;
     
     print &quot;A week ago the date was &quot;,date_a_week_ago(),&quot;\n&quot;;
     
  @@ -2916,16 +4232,19 @@
       }     # end of for ($i = 0;$i &lt; 7;$i++)
     
       return sprintf &quot;%02d/%02d/%04d&quot;,$month,$day,$year+1900;
  -  }
  -</PRE>
  -<P><A NAME="anchor495"></A>
  +  }</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   This code is pretty straightforward. We get today's date and subtract one
   from the value of the day we get, updating the month and the year on the
   way if boundaries are being crossed (end of month, end of year). If we do
   it seven times in loop then at the end we should get a date that was a week
   ago.
   
  -<P><A NAME="anchor496"></A>
  +<P>
   Note that since <CODE>locatime()</CODE> returns the year as a value of
   <CODE>current_four_digits_format_year-1900</CODE> (which means that we don't have a century boundary to worry about) then if
   we are in the middle of the first week of the year 2000, the value of year
  @@ -2933,21 +4252,30 @@
   <CODE>-1</CODE>. At the end we add 1900 to get back the correct four-digit year format.
   (This is all correct as long as you don't go to the years prior to 1900)
   
  -<P><A NAME="anchor497"></A>
  +<P>
   Also note that we have to account for leap years where there are 29 days in
   February. For the other months we have prepared an array containing the
   month lengths.
   
  -<P><A NAME="anchor498"></A>
  +<P>
   Now when we run this code and check the result, we see that something is
   wrong. For example, if today is <CODE>10/23/1999</CODE> we expect the above code to print <CODE>10/16/1999</CODE>. In fact it prints <CODE>09/16/1999</CODE>, which means that we have lost a month. The above code is buggy!
   
  -<P><A NAME="anchor499"></A>
  +<P>
   Let's put a few debug <CODE>print()</CODE> statements in the code, near the
   <CODE>$month</CODE> variable:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor500"></A>
  -<PRE>  sub date_a_week_ago{
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  sub date_a_week_ago{
     
       my @month_len   = (31,28,31,30,31,30,31,31,30,31,30,31);
     
  @@ -2977,15 +4305,30 @@
       }     # end of for ($i = 0;$i &lt; 7;$i++)
     
       return sprintf &quot;%02d/%02d/%04d&quot;,$month,$day,$year+1900;
  -  }
  -</PRE>
  -<P><A NAME="anchor501"></A>
  +  }</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   When we run it we see:
  +
  +<P>
   
  -<P><A NAME="anchor502"></A>
  -<PRE>  [set] month : 9
  -</PRE>
  -<P><A NAME="anchor503"></A>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  [set] month : 9</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   It is supposed to be the number of the current month (<CODE>10</CODE>), but actually it is not. We have spotted a bug, since the only code that
   sets the
   <CODE>$month</CODE> variable consists of a call to <CODE>localtime().</CODE> So did we find a
  @@ -2993,77 +4336,159 @@
   function: % perldoc -f localtime Converts a time as returned by the time
   function to a 9-element array with the time analyzed for the local time
   zone. Typically used as follows:
  +
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
   
  -<P><A NAME="anchor504"></A>
  -<PRE>    #  0    1    2     3     4    5     6     7     8
  +	<td>
  +	  <pre>    #  0    1    2     3     4    5     6     7     8
       ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) =
  -                                                localtime(time);
  -</PRE>
  -<P><A NAME="anchor505"></A>
  -<PRE>  All array elements are numeric, and come straight out of a struct
  +                                                localtime(time);</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  All array elements are numeric, and come straight out of a struct
     tm.  In particular this means that C&lt;$mon&gt; has the range C&lt;0..11&gt;
     and C&lt;$wday&gt; has the range C&lt;0..6&gt; with Sunday as day C&lt;0&gt;.  Also,
     C&lt;$year&gt; is the number of years since 1900, that is, C&lt;$year&gt; is
     C&lt;123&gt; in year 2023, and I&lt;not&gt; simply the last two digits of the
     year.  If you assume it is, then you create non-Y2K-compliant
     programs--and you wouldn't want to do that, would you?
  -  [more info snipped]
  -</PRE>
  -<P><A NAME="anchor506"></A>
  +  [more info snipped]</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Which reveals to us that if we want to count months from 1 to 12 and not 0
   to 11 we are supposed to increment the value of <CODE>$month</CODE>. Among other interesting facts about <CODE>locatime()</CODE> we also see
   an explanation of
   <CODE>$year</CODE>, which as I've mentioned before is set to the number of years since 1900.
   
  -<P><A NAME="anchor507"></A>
  +<P>
   We have found the bug in our code and learned new things about
   <CODE>localtime().</CODE> To correct the above code we just increment the
   month after we call <CODE>localtime():</CODE>
  +
  +<P>
   
  -<P><A NAME="anchor508"></A>
  -<PRE>    my ($day,$month,$year) = (localtime)[3..5];
  -    $month++;
  -</PRE>
  -<P><A NAME="anchor509"></A>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>    my ($day,$month,$year) = (localtime)[3..5];
  +    $month++;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Now let's see some code including conditional and loop statements.
  +
  +<P>
   
  -<P><A NAME="anchor510"></A>
  -<PRE>  for my $i (1..31)
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  for my $i (1..31)
     if( $day &gt; 20) {
  -  }
  -</PRE>
  -<P><A NAME="anchor511"></A>
  +  }</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   META: continue (unfinished)!!!
   
  -<P><A NAME="anchor512"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="Using_print_and_Data_Dumper_f">Using print() and Data::Dumper for Debugging</A></H2></CENTER>
  -<P><A NAME="anchor513"></A>
  +<P>
   Sometimes you need to peek into complex data structures, and trying to
   print them out can be tricky. That's where <CODE>Data::Dumper</CODE> comes to our rescue. For example if we create this complex data structure:
  +
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
   
  -<P><A NAME="anchor514"></A>
  -<PRE>  $data =
  +	<td>
  +	  <pre>  $data =
       {
        array =&gt; [qw(a b c d)],
        hash  =&gt; {
                  foo =&gt; &quot;oof&quot;,
                  bar =&gt; &quot;rab&quot;,
                 },
  -    };
  -</PRE>
  -<P><A NAME="anchor515"></A>
  +    };</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   How do we print it out? Very easily:
  +
  +<P>
   
  -<P><A NAME="anchor516"></A>
  -<PRE>  use Data::Dumper;
  -  print Dumper \$data;
  -</PRE>
  -<P><A NAME="anchor517"></A>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  use Data::Dumper;
  +  print Dumper \$data;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   What we get is a pretty-printed <CODE>$data</CODE>:
  +
  +<P>
   
  -<P><A NAME="anchor518"></A>
  -<PRE>  $VAR1 = \{
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  $VAR1 = \{
               'hash' =&gt; {
                           'foo' =&gt; 'oof',
                           'bar' =&gt; 'rab'
  @@ -3074,56 +4499,84 @@
                           'c',
                           'd'
                          ]
  -          };
  -</PRE>
  -<P><A NAME="anchor519"></A>
  +          };</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   While writing this example I made a mistake and wrote <CODE>qw(a b c d)</CODE>
   instead of <CODE>[qw(a b c d)]</CODE>. When I pretty-printed the contents of
   <CODE>$data</CODE> I immediately saw my mistake:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor520"></A>
  -<PRE>  $VAR1 = \{
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  $VAR1 = \{
               'b' =&gt; 'c',
               'd' =&gt; 'hash',
               'HASH(0x80cd79c)' =&gt; undef,
               'array' =&gt; 'a'
  -          };
  -</PRE>
  -<P><A NAME="anchor521"></A>
  +          };</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   That's not what I wanted of course, but I spotted the bug and corrected it,
   as you saw in the original example from above.
   
  -<P><A NAME="anchor522"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="The_Importance_of_a_Good_Concise">The Importance of a Good Concise Coding Style</A></H2></CENTER>
  -<P><A NAME="anchor523"></A>
  +<P>
   Don't strive for elegant, clever code. Try to develop a good coding style
   by writing code which is concise yet easy to understand. It's much easier
   to find bugs in concise, simple code. And such code tends to have less
   bugs.
   
  -<P><A NAME="anchor524"></A>
  +<P>
   The <EM>'one week ago'</EM> example from the previous section is not concise. There is a lot of
   redundancy in it, and as a result it is harder to debug than it needs to
   be. Here is a condensed version of the main loop. As you can see, this
   version won't make it easier to understand the code:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor525"></A>
  -<PRE>  for (0..7) {
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  for (0..6) {
       next if --$day;
       $year--,$month=12 unless --$month;
       $day = $month != 1 ? $month_len[$month-1] : $year % 4 ? 28 : 29;
  -  }
  -</PRE>
  -<P><A NAME="anchor526"></A>
  +  }</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Don't do that at home :) 
   
  -<P><A NAME="anchor527"></A>
  +<P>
   Why did I present this version? Because it is too obscure, which makes it
   difficult to understand and maintain. On the other hand a part of this code
   is easier to understand.
   
  -<P><A NAME="anchor528"></A>
  +<P>
   Larry Wall, the author of Perl, is a linguist. He tried to define the
   syntax of Perl in a way that makes working in Perl much like working in
   English. So it can be a good idea to learn Perl coding idioms, some of
  @@ -3131,55 +4584,136 @@
   it difficult to understand how you could have lived without them before.
   I'll show just a few of the most common Perl coding idioms.
   
  -<P><A NAME="anchor529"></A>
  +<P>
   It's a good idea to write code which is more readable but which avoids
   redundancy, so it's better to write:
  +
  +<P>
   
  -<P><A NAME="anchor530"></A>
  -<PRE>  unless ($i) {...}
  -</PRE>
  -<P><A NAME="anchor531"></A>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  unless ($i) {...}</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   rather than:
  +
  +<P>
   
  -<P><A NAME="anchor532"></A>
  -<PRE>  if ($i == 0) {...}
  -</PRE>
  -<P><A NAME="anchor533"></A>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  if ($i == 0) {...}</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   if you want to test for trueness only.
   
  -<P><A NAME="anchor534"></A>
  +<P>
   Use a much more concise, Perlish style:
  +
  +<P>
   
  -<P><A NAME="anchor535"></A>
  -<PRE>  for my $j (0..7) {...}
  -</PRE>
  -<P><A NAME="anchor536"></A>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  for my $j (0..6) {...}</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   instead of the syntax used in some other languages:
  +
  +<P>
   
  -<P><A NAME="anchor537"></A>
  -<PRE>  for (my $j=0; $j&lt;7; $j++) {...}
  -</PRE>
  -<P><A NAME="anchor538"></A>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  for (my $j=0; $j&lt;=6; $j++) {...}</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   It's much simpler to write and comprehend code like this:
  +
  +<P>
   
  -<P><A NAME="anchor539"></A>
  -<PRE>  print &quot;something&quot; if $debug;
  -</PRE>
  -<P><A NAME="anchor540"></A>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  print &quot;something&quot; if $debug;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   than this:
  +
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
   
  -<P><A NAME="anchor541"></A>
  -<PRE>  if($debug){
  +	<td>
  +	  <pre>  if($debug){
       print &quot;something&quot;;
  -  }
  -</PRE>
  -<P><A NAME="anchor542"></A>
  +  }</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   A good style that improves understanding, readability and reduces the
   chances of having a bug is shown below in the form of yet another rewrite
   of our <EM>`one week ago'</EM> code:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor543"></A>
  -<PRE>  for (0..7) {
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  for (0..6) {
       $day--;
       next if $day;
     
  @@ -3194,38 +4728,54 @@
       } else {
         $day = $month_len[$month-1];
       }
  -  } 
  -</PRE>
  -<P><A NAME="anchor544"></A>
  +  } </pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   which is a happy medium between the excessively verbose style of the first
   version and very obscure second version.
   
  -<P><A NAME="anchor545"></A>
  +<P>
   And of course a two liner, which is much faster and easier to understand
   is:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor546"></A>
  -<PRE>  sub date_a_week_ago{
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  sub date_a_week_ago{
       my ($day,$month,$year) = (localtime(time-604800))[3..5];
       return sprintf &quot;%02d/%02d/%04d&quot;,$month+1,$day,$year+1900;
  -  }
  -</PRE>
  -<P><A NAME="anchor547"></A>
  +  }</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Just take the current date in seconds since epoch as <CODE>time()</CODE>
   returns, subtract a week in seconds (7*24*60*60 = 604800) and feed the
   result to <CODE>localtime()</CODE> - voila we've got the date of one week
   ago!
   
  -<P><A NAME="anchor548"></A>
  +<P>
   Why is the last version important, when the first one works just fine? Not
   because of performance issues (although this last one is twice as fast as
   the first), but because there are more ways to put a bug in the first
   version than there are in the last one.
   
  -<P><A NAME="anchor549"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="Introduction_to_the_Perl_Debugge">Introduction to the Perl Debugger</A></H2></CENTER>
  -<P><A NAME="anchor550"></A>
  +<P>
   As we saw earlier, it's <EM>almost</EM> always possible to debug code with the help of <CODE>print().</CODE>
   However, it is impossible to anticipate all the possible directions which a
   program might take, and difficult to know what code to suspect when trouble
  @@ -3235,7 +4785,7 @@
   information tends to only be useful to the programmer who added the print
   statements in the first place.
   
  -<P><A NAME="anchor551"></A>
  +<P>
   Sometimes you have to debug tens of thousands lines of Perl in an
   application, and while you may be a very experienced Perl programmer who
   can understand Perl code quite well by just looking at it, no mere mortal
  @@ -3244,7 +4794,7 @@
   start adding your trusty <CODE>print()</CODE> statements to see what is
   happening inside.
   
  -<P><A NAME="anchor552"></A>
  +<P>
   The most effective way to track down a bug is to run the program inside an
   interactive debugger. The majority of programming languages have such a
   tool available, allowing one to see what is happening inside an application
  @@ -3253,63 +4803,72 @@
   
   <UL>
   <P><LI>
  -<P><A NAME="anchor553"></A>
  +<P>
   Stop at a certain point in the code, based on a routine name or source file
   and line number
   
   <P><LI>
  -<P><A NAME="anchor554"></A>
  +<P>
   Stop at a certain point in the code, based on conditions such as the value
   of a given variable
   
   <P><LI>
  -<P><A NAME="anchor555"></A>
  +<P>
   Perform an action without stopping, based on the criteria above
   
   <P><LI>
  -<P><A NAME="anchor556"></A>
  +<P>
   View and modify the value of variables at any given point
   
   <P><LI>
  -<P><A NAME="anchor557"></A>
  +<P>
   Provide context information such as stack traces and source windows
   
   </UL>
  -<P><A NAME="anchor558"></A>
  +<P>
   It does take practice to learn the most effective ways of using an
   interactive debugger, but the time and effort will be paid back many-fold
   in the long run.
   
  -<P><A NAME="anchor559"></A>
  +<P>
   Most C and C++ programmers are familiar with the interactive GNU debugger (<CODE>gdb</CODE>).  <CODE>gdb</CODE> is a stand-alone program that requires your code to be compiled with
   debugging symbols to be useful. While <CODE>gdb</CODE>
   can be used to debug the Perl interpreter itself, it cannot be used to
   debug your Perl scripts.
   
  -<P><A NAME="anchor560"></A>
  +<P>
   Not to worry, Perl provides its own interactive debugger, called
   <CODE>perldb</CODE>. Giving control of your Perl program to the interactive debugger is simply
   a matter of specifying the <A HREF="#item__d">-d</A> command line switch. When this switch is used, Perl inserts debugging hooks
   into the program syntax tree, but it leaves the job of debugging to a Perl
   module separate from the perl binary itself.
   
  -<P><A NAME="anchor561"></A>
  +<P>
   I will start by introducing a few of the basic concepts and commands of the
   Perl interactive debugger. These warm-up examples all run from the command
   line, independent of mod_perl, but are all still relevant when we do
   finally go inside Apache.
   
  -<P><A NAME="anchor562"></A>
  +<P>
   It might be useful to keep the <EM>perldebug</EM> manpage handy for reference while reading this section, and for future
   debugging sessions on your own.
   
  -<P><A NAME="anchor563"></A>
  +<P>
   The interactive debugger will attach to the current terminal and present
   you with a prompt just before the first program statement is executed. For
   example:
  +
  +<P>
   
  -<P><A NAME="anchor564"></A>
  -<PRE>  % perl -d -le 'print &quot;mod_perl rules the world&quot;'
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  % perl -d -le 'print &quot;mod_perl rules the world&quot;'
     
     Loading DB routines from perl5db.pl version 1.0402
     
  @@ -3318,61 +4877,121 @@
     Enter h or `h h' for help.
     
     main::(-e:1):   print &quot;mod_perl rules the world&quot;
  -    DB&lt;1&gt;
  -</PRE>
  -<P><A NAME="anchor565"></A>
  +    DB&lt;1&gt;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   The source line shown is the line which Perl is <EM>about</EM> to execute, the <CODE>next</CODE> command (or just <CODE>n</CODE>) will cause this line to be executed after which execution will stop again
   just before the next line:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor566"></A>
  -<PRE>  main::(-e:1):   print &quot;mod_perl rules the world&quot;
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  main::(-e:1):   print &quot;mod_perl rules the world&quot;
       DB&lt;1&gt; n
     mod_perl rules the world
     Debugged program terminated.  Use q to quit or R to restart,
     use O inhibit_exit to avoid stopping after program termination,
     h q, h R or h O to get additional info.
  -  DB&lt;1&gt;
  -</PRE>
  -<P><A NAME="anchor567"></A>
  +  DB&lt;1&gt;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   In this case, our example code is only one line long, so we have finished
   interacting after the first line of code is executed. Let's try again with
   slightly longer example which is the following script:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor568"></A>
  -<PRE>  my $word = 'mod_perl';
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  my $word = 'mod_perl';
     my @array = qw(rules the world);
     
  -  print &quot;$word @array\n&quot;;
  -</PRE>
  -<P><A NAME="anchor569"></A>
  +  print &quot;$word @array\n&quot;;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Save the script in a file called <EM>domination.pl</EM> and run with the
   <A HREF="#item__d">-d</A> switch:
  +
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
   
  -<P><A NAME="anchor570"></A>
  -<PRE>  % perl -d domination.pl
  +	<td>
  +	  <pre>  % perl -d domination.pl
     
     main::(domination.pl:1):      my $word = 'mod_perl';
       DB&lt;1&gt; n
     main::(domination.pl:2):      my @array = qw(rules the world);
  -    DB&lt;1&gt;
  -</PRE>
  -<P><A NAME="anchor571"></A>
  +    DB&lt;1&gt;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   At this point, the first line of code has been executed and the variable <CODE>$word</CODE> has been assigned the value <EM>mod_perl</EM>. We can check this by using the <CODE>p</CODE> command (an abbreviation for the <CODE>print</CODE>
   command, the two are interchangeable):
   
  -<P><A NAME="anchor572"></A>
  -<PRE>  main::(domination.pl:2):      my @array = qw(rules the world);
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  main::(domination.pl:2):      my @array = qw(rules the world);
       DB&lt;1&gt; p $word
  -  mod_perl
  -</PRE>
  -<P><A NAME="anchor573"></A>
  +  mod_perl</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   The <CODE>print</CODE> command works just like the Perl's built-in <CODE>print()</CODE> function,
   but adds a trailing newline and outputs to the <CODE>$DB::OUT</CODE>
   file handle, which is normally opened on the terminal where Perl was
   launched from. Let's carry on:
  +
  +<P>
   
  -<P><A NAME="anchor574"></A>
  -<PRE>    DB&lt;2&gt; n
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>    DB&lt;2&gt; n
     main::(domination.pl:4):      print &quot;$word @array\n&quot;;
       DB&lt;2&gt; p @array
     rulestheworld
  @@ -3380,98 +4999,182 @@
     mod_perl rules the world
     Debugged program terminated.  Use q to quit or R to restart,
     use O inhibit_exit to avoid stopping after program termination,
  -  h q, h R or h O to get additional info.  
  -</PRE>
  -<P><A NAME="anchor575"></A>
  +  h q, h R or h O to get additional info.  </pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Ouch, <CODE>p @array</CODE> printed <CODE>rulestheworld</CODE> and not <CODE>rules the world</CODE>, as you might expect it to, but that's absolutely correct. If you print an
   array without expanding it first into a string it will be printed without
   adding the content of the <CODE>$&quot;</CODE> variable (otherwise known as
   <CODE>$LIST_SEPARATOR</CODE> if the <CODE>English</CODE> pragma is being used) between the elements of the array.
   
  -<P><A NAME="anchor576"></A>
  +<P>
   If you type:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor577"></A>
  -<PRE>  print &quot;@array&quot;;
  -</PRE>
  -<P><A NAME="anchor578"></A>
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  print &quot;@array&quot;;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   the output will be <CODE>rules the world</CODE> since the default value of the
   <CODE>$&quot;</CODE> variable is a single space.
   
  -<P><A NAME="anchor579"></A>
  +<P>
   You should have noticed by now that there is some valuable information to
   the left of each executable statement:
   
  -<P><A NAME="anchor580"></A>
  -<PRE>  main::(domination.pl:4):      print &quot;$word @array\n&quot;;
  -    DB&lt;2&gt;
  -</PRE>
  -<P><A NAME="anchor581"></A>
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  main::(domination.pl:4):      print &quot;$word @array\n&quot;;
  +    DB&lt;2&gt;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   First is the current package name, in this case <CODE>main::</CODE>. Next is the current filename and statement line number, <EM>domination.pl</EM> and 4 in the example above. The number presented at the prompt is the
   command number which can be used to recall commands from the session
   history, using the <CODE>!</CODE> command followed by this number. For example,
   <CODE>!1</CODE> would repeat the first command:
  +
  +<P>
   
  -<P><A NAME="anchor582"></A>
  -<PRE>  % perl -d -e0
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  % perl -d -e0
     
     main::(-e:1):   0
       DB&lt;1&gt; p $]
     5.00503
       DB&lt;2&gt; !1
     p $]5.00503
  -    DB&lt;3&gt; 
  -</PRE>
  -<P><A NAME="anchor583"></A>
  +    DB&lt;3&gt; </pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Where <CODE>$]</CODE> is the perl's version number. As you see <CODE>!1</CODE> prints the value of <CODE>$]</CODE>, prepended by the command that was executed.
   
  -<P><A NAME="anchor584"></A>
  +<P>
   Things start to get more interesting as the code does. In the example
   script below (save it to a file called <EM>test.pl</EM>) we've increased the number of source files and packages by including the
   standard
   <CODE>Symbol</CODE> module, along with an invocation of its <CODE>gensym()</CODE> function:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor585"></A>
  -<PRE>  use Symbol ();
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  use Symbol ();
     
     my $sym = Symbol::gensym();
     
  -  print &quot;$sym\n&quot;;
  -</PRE>
  -<P><A NAME="anchor586"></A>
  -<PRE>  % perl -d test.pl 
  +  print &quot;$sym\n&quot;;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  % perl -d test.pl 
     
     main::(test.pl:3):      my $sym = Symbol::gensym();
       DB&lt;1&gt; n
     main::(test.pl:5):      print &quot;$sym\n&quot;;
       DB&lt;1&gt; n
  -  GLOB(0x80c7a44)
  -</PRE>
  -<P><A NAME="anchor587"></A>
  +  GLOB(0x80c7a44)</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   First, notice the debugger did not stop at the first line of the file. This
   is because <CODE>use ...</CODE> is a compile-time statement, not a run-time statement. Also notice there
   was more work going on than the debugger revealed. That's because the <CODE>next</CODE> command does not enter subroutine calls. To step into a subroutine code use
   the <CODE>step</CODE>
   command (or its abbreviated form <A HREF="#item_s">s</A>):
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor588"></A>
  -<PRE>  % perl -d test.pl
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  % perl -d test.pl
     
     main::(test.pl:3):      my $sym = Symbol::gensym();
       DB&lt;1&gt; s
     Symbol::gensym(/usr/lib/perl5/5.00503/Symbol.pm:86):
     86:         my $name = &quot;GEN&quot; . $genseq++;
  -    DB&lt;1&gt; 
  -</PRE>
  -<P><A NAME="anchor589"></A>
  +    DB&lt;1&gt; </pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Notice the source line information has changed to the
   <CODE>Symbol::gensym</CODE> package and the <CODE>Symbol.pm</CODE> file. We can carry on by hitting the return key at each prompt, which
   causes the debugger to repeat the last <CODE>step</CODE> or <CODE>next</CODE> command. It won't repeat a
   <CODE>print</CODE> command though. The debugger will eventually return from the subroutine
   back to our main program:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor590"></A>
  -<PRE>    DB&lt;1&gt; 
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>    DB&lt;1&gt; 
     Symbol::gensym(/usr/lib/perl5/5.00503/Symbol.pm:87):
     87:         my $ref = \*{$genpkg . $name};
       DB&lt;1&gt; 
  @@ -3483,9 +5186,12 @@
       DB&lt;1&gt; 
     main::(test.pl:5):      print &quot;$sym\n&quot;;
       DB&lt;1&gt; 
  -  GLOB(0x80c7a44)
  -</PRE>
  -<P><A NAME="anchor591"></A>
  +  GLOB(0x80c7a44)</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Our line-by-line debugging approach has served us well for this small
   program, but imagine the time it would take to step through a large
   application at the same pace. There are several ways to speed up a
  @@ -3495,47 +5201,92 @@
   when it is called. Rather than move along with <CODE>next</CODE> or <CODE>step</CODE> we give the <CODE>continue</CODE>
   command (<A HREF="#item_c">c</A>) which tells the debugger to execute the script without stopping until it
   reaches a breakpoint:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor592"></A>
  -<PRE>  % perl -d test.pl
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  % perl -d test.pl
     
     main::(test.pl:3):      my $sym = Symbol::gensym();
       DB&lt;1&gt; b Symbol::gensym
       DB&lt;2&gt; c
     Symbol::gensym(/usr/lib/perl5/5.00503/Symbol.pm:86):
  -  86:         my $name = &quot;GEN&quot; . $genseq++;
  -</PRE>
  -<P><A NAME="anchor593"></A>
  +  86:         my $name = &quot;GEN&quot; . $genseq++;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Now let's pretend we are debugging a large application where
   <CODE>Symbol::gensym</CODE> might be called in various places. When the subroutine breakpoint is
   reached, by default the debugger does not reveal where it was called from.
   One way to find out this information is with the <CODE>Trace</CODE> command (<CODE>T</CODE>):
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor594"></A>
  -<PRE>    DB&lt;2&gt; T
  -  $ = Symbol::gensym() called from file `test.pl' line 3
  -</PRE>
  -<P><A NAME="anchor595"></A>
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>    DB&lt;2&gt; T
  +  $ = Symbol::gensym() called from file `test.pl' line 3</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   In this example, the call stack is only one level deep, so only that line
   is printed. We'll look at an example with a deeper stack later. The
   left-most character reveals the context in which the subroutine was called.  <CODE>$</CODE> represents scalar context, in other examples you may see <CODE>@</CODE> which represents list context or <CODE>.</CODE> which represents void context. In our case we have called:
   
  -<P><A NAME="anchor596"></A>
  -<PRE>  my $sym = Symbol::gensym();
  -</PRE>
  -<P><A NAME="anchor597"></A>
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  my $sym = Symbol::gensym();</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   which calls the <CODE>Symbol::gensym()</CODE> in scalar context.
   
  -<P><A NAME="anchor598"></A>
  +<P>
   Below we've made our <EM>test.pl</EM> example a little more complex. First, we've added a <CODE>My::World</CODE> package declaration at the top of the script, so we are no longer working
   in the <CODE>main::</CODE> package. Next, we've added a subroutine named <CODE>do_work()</CODE> which
   invokes the familiar
   <CODE>Symbol::gensym</CODE>, along with another function called
   <CODE>Symbol::qualify</CODE> and then returns a hash reference of the results. The
   <CODE>do_work()</CODE> routine is invoked inside a <EM>for</EM> loop which will be run twice:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor599"></A>
  -<PRE>  package My::World;
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  package My::World;
     
     use Symbol ();
     
  @@ -3557,14 +5308,26 @@
                    };
     
       return $retval;
  -  }
  -</PRE>
  -<P><A NAME="anchor600"></A>
  +  }</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   We'll start by setting a few breakpoints and then we use the <CODE>List</CODE>
   command (<CODE>L</CODE>) to display them:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor601"></A>
  -<PRE>  % perl -d test.pl
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  % perl -d test.pl
     
     My::World::(test.pl:5):   for (1,2) {
       DB&lt;1&gt; b Symbol::qualify
  @@ -3574,9 +5337,12 @@
      86:        my $name = &quot;GEN&quot; . $genseq++;
        break if (1)
      95:        my ($name) = @_;
  -     break if (1)
  -</PRE>
  -<P><A NAME="anchor602"></A>
  +     break if (1)</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   The filename and line number of the breakpoint are displayed just before
   the source line itself. Because both breakpoints are located in the same
   file, the filename is displayed only once. After the source line we see the
  @@ -3584,106 +5350,199 @@
   indicates, we will always stop at these breakpoints. Later on you'll see
   how to specify a condition.
   
  -<P><A NAME="anchor603"></A>
  +<P>
   As we will see, when the <CODE>continue</CODE> command is executed, the execution of the program stops at one of these
   breakpoints, either on line 86 or 95 of the <CODE>/usr/lib/perl5/5.00503/Symbol.pm</CODE> file, whichever is reached first. The displayed code lines are the first
   rows of the two subroutines from <CODE>Symbol.pm</CODE>. Breakpoints may only be applied to lines of run-time executable code, you
   cannot put breakpoints on empty lines or comments for example.
   
  -<P><A NAME="anchor604"></A>
  +<P>
   In our example the <CODE>List</CODE> command shows which lines the breakpoints were set on, but we cannot tell
   which breakpoint belongs to which subroutine. There are two ways to find
   this out. One is to run the
   <CODE>continue</CODE> command and when it stops, execute the <CODE>Trace</CODE> command we saw before:
  +
  +<P>
   
  -<P><A NAME="anchor605"></A>
  -<PRE>    DB&lt;3&gt; c
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>    DB&lt;3&gt; c
     Symbol::gensym(/usr/lib/perl5/5.00503/Symbol.pm:86):
     86:         my $name = &quot;GEN&quot; . $genseq++;
       DB&lt;3&gt; T
     $ = Symbol::gensym() called from file `test.pl' line 14
  -  . = My::World::do_work('now') called from file `test.pl' line 6
  -</PRE>
  -<P><A NAME="anchor606"></A>
  +  . = My::World::do_work('now') called from file `test.pl' line 6</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   So we see that it was <CODE>Symbol::gensym</CODE>. The other way is to ask for a listing of a range of lines from the code.
   For example, let's check which subroutine line 86 is a part of. We use the <CODE>list</CODE>
   (lowercase!) command (<CODE>l</CODE>), which displays parts of the code. The
   <CODE>list</CODE> command accepts various arguments, the one that we want to use here is a
   range of lines. Since the breakpoint is at line 86, let's print a few lines
   above and below that line:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor607"></A>
  -<PRE>    DB&lt;3&gt; l 85-87
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>    DB&lt;3&gt; l 85-87
     85      sub gensym () {
     86==&gt;b      my $name = &quot;GEN&quot; . $genseq++;
  -  87:         my $ref = \*{$genpkg . $name};
  -</PRE>
  -<P><A NAME="anchor608"></A>
  +  87:         my $ref = \*{$genpkg . $name};</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Now we know it's the <CODE>gensym</CODE> sub and we also see the breakpoint displayed with the help of the <CODE>==&gt;b</CODE> markup. We could also use the name of the sub to display its code:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor609"></A>
  -<PRE>    DB&lt;4&gt; l Symbol::gensym
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>    DB&lt;4&gt; l Symbol::gensym
     85      sub gensym () {
     86==&gt;b      my $name = &quot;GEN&quot; . $genseq++;
     87:         my $ref = \*{$genpkg . $name};
     88:         delete $$genpkg{$name};
     89:         $ref;
  -  90      }
  -</PRE>
  -<P><A NAME="anchor610"></A>
  +  90      }</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   The <CODE>delete</CODE> command (<A HREF="#item_d">d</A>) is used to remove a breakpoint by specifying the line number of the
   breakpoint. Let's remove the first one:
  +
  +<P>
   
  -<P><A NAME="anchor611"></A>
  -<PRE>    DB&lt;5&gt; d 95
  -</PRE>
  -<P><A NAME="anchor612"></A>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>    DB&lt;5&gt; d 95</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   The <CODE>Delete</CODE> command (with a capital `D') or <CODE>D</CODE> removes all currently installed breakpoints.
   
  -<P><A NAME="anchor613"></A>
  +<P>
   Now let's look again at the trace produced at the breakpoint:
  +
  +<P>
   
  -<P><A NAME="anchor614"></A>
  -<PRE>    DB&lt;3&gt; c
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>    DB&lt;3&gt; c
     Symbol::gensym(/usr/lib/perl5/5.00503/Symbol.pm:86):
     86:         my $name = &quot;GEN&quot; . $genseq++;
       DB&lt;3&gt; T
     $ = Symbol::gensym() called from file `test.pl' line 14
  -  . = My::World::do_work('now') called from file `test.pl' line 6
  -</PRE>
  -<P><A NAME="anchor615"></A>
  +  . = My::World::do_work('now') called from file `test.pl' line 6</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   As you can see, the stack trace prints the values which are passed into the
   subroutine. Ah, and perhaps we've found our first bug, as we can see
   <CODE>do_work()</CODE> was called in void context, so the return value was
   lost into thin air. Let's change the <EM>'for'</EM> loop to check the return value of <CODE>do_work():</CODE>
  +
  +<P>
   
  -<P><A NAME="anchor616"></A>
  -<PRE>  for (1,2) {
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  for (1,2) {
       my $stuff = do_work(&quot;now&quot;);
       if ($stuff) {
           print &quot;work is done\n&quot;;
       }
  -  }
  -</PRE>
  -<P><A NAME="anchor617"></A>
  +  }</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   In this session we will set a breakpoint at line 7 of <CODE>test.pl</CODE> where we check the return value of <CODE>do_work():</CODE>
  +
  +<P>
   
  -<P><A NAME="anchor618"></A>
  -<PRE>  % perl -d test.pl
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  % perl -d test.pl
     
     My::World::(test.pl:5):   for (1,2) {
       DB&lt;1&gt; b 7
       DB&lt;2&gt; c
     My::World::(test.pl:7):     if ($stuff) {
  -    DB&lt;2&gt;
  -</PRE>
  -<P><A NAME="anchor619"></A>
  +    DB&lt;2&gt;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Our program is still small, but already it is getting more difficult to
   understand the context of just one line of code. The <CODE>window</CODE>
   command (<CODE>w</CODE>) will list a few lines of code that surround the current line:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor620"></A>
  -<PRE>    DB&lt;2&gt; w
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>    DB&lt;2&gt; w
     4         
     5:        for (1,2) {
     6:          my $stuff = do_work(&quot;now&quot;);
  @@ -3693,53 +5552,101 @@
     10        }
     11        
     12        sub do_work {
  -  13:         my($var) = @_;
  -</PRE>
  -<P><A NAME="anchor621"></A>
  +  13:         my($var) = @_;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   The arrow points to the line which is about to be executed and also
   contains a <CODE>'b'</CODE> indicating that we have set a breakpoint at this line. The breakable lines
   of code include a <CODE>`:'</CODE> immediately after the line number.
   
  -<P><A NAME="anchor622"></A>
  +<P>
   Now, let's take a look at the value of the <CODE>$stuff</CODE> variable with the trusty old <CODE>print</CODE> command:
  +
  +<P>
   
  -<P><A NAME="anchor623"></A>
  -<PRE>    DB&lt;2&gt; p $stuff
  -  HASH(0x82b89b4)
  -</PRE>
  -<P><A NAME="anchor624"></A>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>    DB&lt;2&gt; p $stuff
  +  HASH(0x82b89b4)</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   That's not very useful information. Remember, the <CODE>print</CODE> command works just like the built-in <CODE>print()</CODE> function does.
   The debugger's
   <CODE>x</CODE> command evaluates a given expression and prints the results in a ``pretty''
   fashion:
  +
  +<P>
   
  -<P><A NAME="anchor625"></A>
  -<PRE>    DB&lt;3&gt; x $stuff
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>    DB&lt;3&gt; x $stuff
     0  HASH(0x82b89b4)
        'sym' =&gt; GLOB(0x826a944)
           -&gt; *Symbol::GEN0
  -     'var' =&gt; 'My::World::now'
  -</PRE>
  -<P><A NAME="anchor626"></A>
  +     'var' =&gt; 'My::World::now'</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   There, things seem to be okay, let's double check by calling
   <CODE>do_work()</CODE> with a different value and print the results:
  +
  +<P>
   
  -<P><A NAME="anchor627"></A>
  -<PRE>    DB&lt;4&gt; x do_work('later')
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>    DB&lt;4&gt; x do_work('later')
     0  HASH(0x82bacc8)
        'sym' =&gt; GLOB(0x818f16c)
           -&gt; *Symbol::GEN1
  -     'var' =&gt; 'My::World::later'
  -</PRE>
  -<P><A NAME="anchor628"></A>
  +     'var' =&gt; 'My::World::later'</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   We can see the symbol was incremented from <CODE>GEN0</CODE> to <CODE>GEN1</CODE> and the variable later was qualified, as expected.
   
  -<P><A NAME="anchor629"></A>
  +<P>
   Now let's change the test program a little to iterate over a list of
   arguments held in <CODE>@args</CODE> and print a slightly different message:
  +
  +<P>
   
  -<P><A NAME="anchor630"></A>
  -<PRE>  package My::World;
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  package My::World;
     
     use Symbol ();
     
  @@ -3765,9 +5672,12 @@
       };
     
       return $retval;
  -  }
  -</PRE>
  -<P><A NAME="anchor631"></A>
  +  }</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   There are only two arguments in the list, so stopping to look at each one
   isn't too time consuming, but consider the debugging pace if we had a large
   list of 100 or so entries. It is possible to customize breakpoints by
  @@ -3776,9 +5686,18 @@
   the <CODE>window</CODE> command shows breakable lines and we set a breakpoint at line 7 with the
   condition <CODE>$arg eq
   'later'</CODE>. As we continue, the breakpoint is skipped when <CODE>$arg</CODE> has the value of <EM>now</EM> but not when it has the value of <EM>later</EM>:
  +
  +<P>
   
  -<P><A NAME="anchor632"></A>
  -<PRE>  % perl -d test.pl
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  % perl -d test.pl
     
     My::World::(test.pl:5): my @args = qw(now later);
       DB&lt;1&gt; w
  @@ -3791,13 +5710,25 @@
     8:          if ($stuff) {
     9:              print &quot;do your work $arg\n&quot;;
     10          }
  -  11      }
  -</PRE>
  -<P><A NAME="anchor633"></A>
  +  11      }</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   The <CODE>==&gt;</CODE> symbol shows us the line of code that's about to be executed.
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor634"></A>
  -<PRE>    DB&lt;1&gt; b 7 $arg eq 'later'
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>    DB&lt;1&gt; b 7 $arg eq 'later'
       DB&lt;2&gt; c
     do your work now
     My::World::(test.pl:7):     my $stuff = do_work($arg);
  @@ -3810,123 +5741,198 @@
        'var' =&gt; 'My::World::later'
       DB&lt;5&gt; c
     do your work later
  -  Debugged program terminated.  Use q to quit or R to restart,
  -</PRE>
  -<P><A NAME="anchor635"></A>
  +  Debugged program terminated.  Use q to quit or R to restart,</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   There are plenty more tricks left to pull from the perldb bag, but you
   should now understand enough about the debugger to try them on your own
   with the perldebug manpage by your side. Quick online help from inside the
   debugger can be reached by typing the <A HREF="#item_h">h</A> command. It will display a list of the most useful commands and a short
   explanation of what they do.
   
  -<P><A NAME="anchor636"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="Interactive_Perl_Debugging_under">Interactive Perl Debugging under mod_cgi</A></H2></CENTER>
  -<P><A NAME="anchor637"></A>
  +<P>
   <CODE>Devel::ptkdb</CODE> is a visual Perl debugger that uses perlTk for the user interface and
   requires a windows system like X-Windows or Windows to run.
   
  -<P><A NAME="anchor638"></A>
  +<P>
   To debug a plain perl script with ptkdb, invoke it as:
   
  -<P><A NAME="anchor639"></A>
  -<PRE>  % perl -d:ptkdb myscript.pl
  -</PRE>
  -<P><A NAME="anchor640"></A>
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  % perl -d:ptkdb myscript.pl</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   The Tk application will be loaded. Now you can do most of the debugging you
   did with the command line Perl debugger, but using a simple GUI to
   set/remove breakpoints, browse the code, step through it and more.
   
  -<P><A NAME="anchor641"></A>
  +<P>
   With the help of ptkdb you can debug your CGI scripts running under
   mod_cgi. Be sure that the web server's Perl installation includes the Tk
   package. In order to enable the debugger you should change your ``shebang''
   line from
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor642"></A>
  -<PRE>  #! /usr/local/bin/perl -Tw
  -</PRE>
  -<P><A NAME="anchor643"></A>
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  #! /usr/local/bin/perl -Tw</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   to
   
  -<P><A NAME="anchor644"></A>
  -<PRE>  #! /usr/local/bin/perl -Twd:ptkdb
  -</PRE>
  -<P><A NAME="anchor645"></A>
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  #! /usr/local/bin/perl -Twd:ptkdb</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   You can debug scripts remotely if you're using a Unix based server and if
   the machine where you are writing the script has an X-server. The X-server
   can be another Unix workstation, or a Macintosh or Win32 platform with an
   appropriate X-Windows package. You must insert the following <CODE>BEGIN</CODE> subroutine into your script:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor646"></A>
  -<PRE>  BEGIN {
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  BEGIN {
       $ENV{'DISPLAY'} = &quot;myHostname:0.0&quot; ;
  -  }
  -</PRE>
  -<P><A NAME="anchor647"></A>
  +  }</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   You can use either the IP (<EM>123.123.123.123:0.0</EM>) or the DNS convention (<EM>myhost.com:0.0</EM>). You must be sure that your web server has permission to open windows on
   your X-server (see the <EM>xhost</EM>
   manpage for more info).
   
  -<P><A NAME="anchor648"></A>
  +<P>
   Access the web page with the browser and <EM>Submit</EM> the script as normal. The ptkdb window should appear on the monitor if you
   have correctly set the <CODE>$ENV{'DISPLAY'}</CODE> variable. At this point you can start debugging your script. Be aware that
   the browser may timeout waiting for the script to run.
   
  -<P><A NAME="anchor649"></A>
  +<P>
   To expedite debugging you may want to set your breakpoints in advance with
   a <EM>.ptkdbrc</EM> file and use the <CODE>$DB::no_stop_at_start</CODE> variable. NOTE: for debugging web scripts you may have to have the <EM>.ptkdbrc</EM>
   file installed in the server account's home directory (~www) or whatever
   username the webserver is running under. Also try installing a <EM>.ptkdbrc</EM> file in the same directory as the target script.
   
  -<P><A NAME="anchor650"></A>
  +<P>
   META: insert snapshots of ptkdb screen
   
  -<P><A NAME="anchor651"></A>
  +<P>
   ptkdb is not part of the standard perl distribution; it is available from
   CPAN: <A
   HREF="http://www.perl.com/CPAN/authors/id/A/AE/AEPAGE/">http://www.perl.com/CPAN/authors/id/A/AE/AEPAGE/</A>
    
   
  -<P><A NAME="anchor652"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="Non_Interactive_Perl_Debugging_u">Non-Interactive Perl Debugging under mod_perl</A></H2></CENTER>
  -<P><A NAME="anchor653"></A>
  +<P>
   To debug scripts running under mod_perl either use <A HREF="././debug.html#Interactive_mod_perl_Debugging">Apache::DB (interactive Perl debugging)</A> or an older non-interactive method as described below.
   
  -<P><A NAME="anchor654"></A>
  +<P>
   The <CODE>NonStop</CODE> debugger option enables you to get some decent debugging information when
   running under mod_perl. For example, before starting the server:
  +
  +<P>
   
  -<P><A NAME="anchor655"></A>
  -<PRE>  % setenv PERL5OPT -d
  -  % setenv PERLDB_OPTS &quot;NonStop=1 LineInfo=db.out AutoTrace=1 frame=2&quot;
  -</PRE>
  -<P><A NAME="anchor656"></A>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  % setenv PERL5OPT -d
  +  % setenv PERLDB_OPTS &quot;NonStop=1 LineInfo=db.out AutoTrace=1 frame=2&quot;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Now watch db.out for line:filename info. This is most useful for tracking
   those core dumps that normally leave us guessing, even with a stack trace
   from gdb.  <EM>db.out</EM> will show you what Perl code triggered the core dump.  <EM>'man perldebug'</EM> for more <CODE>PERLDB_OPTS</CODE>. Note that Perl will ignore <CODE>PERL5OPT</CODE> if <CODE>PerlTaintCheck</CODE> is <CODE>On</CODE>.
   
  -<P><A NAME="anchor657"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="Interactive_mod_perl_Debugging">Interactive mod_perl Debugging</A></H2></CENTER>
  -<P><A NAME="anchor658"></A>
  +<P>
   Now we'll turn to looking at how the interactive debugger is used in a
   mod_perl environment. The <CODE>Apache::DB</CODE> module available from CPAN provides a wrapper around <CODE>perldb</CODE> for debugging Perl code running under mod_perl.
   
  -<P><A NAME="anchor659"></A>
  +<P>
   The server must be run in non-forking mode to use the interactive debugger,
   this mode is turned on by passing the <CODE>-X</CODE> flag to the httpd executable. It is convenient to use an <CODE>IfDefine</CODE> section around the <CODE>Apache::DB</CODE> configuration, the example below does this using the name <EM>PERLDB</EM>. With this setup, debugging is only turned on when starting the server
   with the <CODE>httpd -D PERLDB</CODE> command.
   
  -<P><A NAME="anchor660"></A>
  +<P>
   This section should be at the top of the Perl configuration section of the
   configuration file, before any other Perl code is pulled in, so that
   debugging symbols will be inserted into the syntax tree, triggered by the
   call to <CODE>Apache::DB-&gt;init</CODE>. The <CODE>Apache::DB::handler</CODE> can be configured using any of the <CODE>Perl*Handler</CODE> directives, in this case you use a <CODE>PerlFixupHandler</CODE> so handlers in the response phase will bring up the debugger prompt:
  +
  +<P>
   
  -<P><A NAME="anchor661"></A>
  -<PRE>  &lt;IfDefine PERLDB&gt;
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  &lt;IfDefine PERLDB&gt;
     
       &lt;Perl&gt;
         use Apache::DB ();
  @@ -3937,33 +5943,60 @@
         PerlFixupHandler Apache::DB
       &lt;/Location&gt;
     
  -  &lt;/IfDefine&gt;
  -</PRE>
  -<P><A NAME="anchor662"></A>
  +  &lt;/IfDefine&gt;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Since we have used <CODE>/</CODE> as the argument to the <CODE>Location</CODE> directive, the debugger will be invoked for any kind of request (even for
   static documents and images) but of course it will immediately quit unless
   there is some Perl module registered to handle these requests.
   
  -<P><A NAME="anchor663"></A>
  +<P>
   In our first example, we will debug the standard <CODE>Apache::Status</CODE>
   module, which is configured like this:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor664"></A>
  -<PRE>  PerlModule Apache::Status
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  PerlModule Apache::Status
     &lt;Location /perl-status&gt;
       PerlHandler Apache::Status
       SetHandler perl-script
  -  &lt;/Location&gt;
  -</PRE>
  -<P><A NAME="anchor665"></A>
  +  &lt;/Location&gt;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   When the server is started with the debugging flag, a notice will be
   printed to the console:
  +
  +<P>
   
  -<P><A NAME="anchor666"></A>
  -<PRE>  % httpd -X -D PERLDB
  -  [notice] Apache::DB initialized in child 950
  -</PRE>
  -<P><A NAME="anchor667"></A>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  % httpd -X -D PERLDB
  +  [notice] Apache::DB initialized in child 950</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   The debugger prompt will not be available until the first request is made,
   in our case to <A
   HREF="http://localhost/perl-status.">http://localhost/perl-status.</A> Once
  @@ -3972,9 +6005,18 @@
   then we move to the next statement after a value has been assigned to
   <CODE>$r</CODE>, and finally we print the request URI. If no breakpoints are set, the <CODE>continue</CODE> command will give control back to Apache and the request will finish with
   the <CODE>Apache::Status</CODE> main menu showing in the browser window:
  +
  +<P>
   
  -<P><A NAME="anchor668"></A>
  -<PRE>  Loading DB routines from perl5db.pl version 1.0402
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  Loading DB routines from perl5db.pl version 1.0402
     Emacs support available.
     
     Enter h or `h h' for help.
  @@ -3997,34 +6039,58 @@
     56:         Apache-&gt;request($r); #  for Apache::CGI
       DB&lt;1&gt; p $r-&gt;uri
     /perl-status
  -    DB&lt;2&gt; c
  -</PRE>
  -<P><A NAME="anchor669"></A>
  +    DB&lt;2&gt; c</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   All the techniques we saw while debugging plain perl scripts can be applied
   to this debugging session.
   
  -<P><A NAME="anchor670"></A>
  +<P>
   Debugging <CODE>Apache::Registry</CODE> scripts is somewhat different, because the handler routine does quite a bit
   of work before it reaches your script. In this example, we make a request
   for <CODE>/perl/test.pl</CODE>, which consists of this code:
  +
  +<P>
   
  -<P><A NAME="anchor671"></A>
  -<PRE>  use strict;
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  use strict;
     
     my $r = shift;
     $r-&gt;send_http_header('text/plain');
     
  -  print &quot;mod_perl rules&quot;;
  -</PRE>
  -<P><A NAME="anchor672"></A>
  +  print &quot;mod_perl rules&quot;;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   When a request is issued, the debugger stops at line 28 of
   <EM>Apache/Registry.pm</EM>. We set a breakpoint at line 140, which is the line that actually calls
   the script wrapper subroutine. The
   <CODE>continue</CODE> command will bring us to that line, where we can step into the script
   handler:
  +
  +<P>
   
  -<P><A NAME="anchor673"></A>
  -<PRE>  Apache::Registry::handler(/usr/lib/perl5/site_perl/5.005/i386-linux/Apache/Registry.pm:28):
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  Apache::Registry::handler(/usr/lib/perl5/site_perl/5.005/i386-linux/Apache/Registry.pm:28):
   28:         my $r = shift;
       DB&lt;1&gt; b 140
       DB&lt;2&gt; c
  @@ -4032,26 +6098,50 @@
     140:            eval { &amp;{$cv}($r, @_) } if $r-&gt;seqno;
       DB&lt;2&gt; s
     Apache::ROOT::perl::test_2epl::handler((eval 87):3):
  -  3:        my $r = shift;
  -</PRE>
  -<P><A NAME="anchor674"></A>
  +  3:        my $r = shift;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Notice the funny package name, that's generated from the URI of the request
   for namespace protection. The filename is not displayed, since the code was
   compiled via <CODE>eval(),</CODE> but the <CODE>print</CODE> command can be used to show you <CODE>$r-&gt;filename</CODE>:
  +
  +<P>
   
  -<P><A NAME="anchor675"></A>
  -<PRE>    DB&lt;2&gt; n
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>    DB&lt;2&gt; n
     Apache::ROOT::perl::test_2epl::handler((eval 87):4):
     4:        $r-&gt;send_http_header('text/plain');
       DB&lt;2&gt; p $r-&gt;filename
  -  /home/httpd/perl/test.pl
  -</PRE>
  -<P><A NAME="anchor676"></A>
  +  /home/httpd/perl/test.pl</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   The line number might seem off too, but the window command will give you a
   better idea where you are:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor677"></A>
  -<PRE>    DB&lt;4&gt; w
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>    DB&lt;4&gt; w
     1:      package Apache::ROOT::perl::test_2epl;use Apache qw(exit);
     sub handler {  use strict;
     2 
  @@ -4061,127 +6151,237 @@
     6:        print &quot;mod_perl rules&quot;;
     7 
     8       }
  -  9       ;
  -</PRE>
  -<P><A NAME="anchor678"></A>
  +  9       ;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   The code from the <EM>test.pl</EM> file is between lines 2 and 7, the rest is the <CODE>Apache::Registry</CODE> magic to cache your code inside a
   <EM>handler</EM> subroutine.
   
  -<P><A NAME="anchor679"></A>
  +<P>
   It will always take some practice and patience when putting together
   debugging strategies that make effective use of the interactive debugger
   for various situations. Once you have a good strategy, bug squashing can
   actually be quite a bit of fun!
   
  -<P><A NAME="anchor680"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="ptkdb_and_Interactive_mod_perl_D">ptkdb and Interactive mod_perl Debugging</A></H2></CENTER>
  -<P><A NAME="anchor681"></A>
  +<P>
   As you saw earlier you can use the <CODE>ptkdb</CODE> visual debugger to debug CGI scripts running under mod_cgi. But it won't
   work for mod_perl using the same configuration as used in mod_cgi. We have
   to tweak the <EM>Apache/DB.pm</EM> module to use <EM>Devel/ptkdb.pm</EM> instead of
   <EM>Apache/perl5db.pl</EM>.
   
  -<P><A NAME="anchor682"></A>
  +<P>
   Open the file in your favorite editor and replace:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor683"></A>
  -<PRE>    require 'Apache/perl5db.pl';
  -</PRE>
  -<P><A NAME="anchor684"></A>
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>    require 'Apache/perl5db.pl';</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   with:
   
  -<P><A NAME="anchor685"></A>
  -<PRE>    require 'Devel/ptkdb.pm';
  -</PRE>
  -<P><A NAME="anchor686"></A>
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>    require 'Devel/ptkdb.pm';</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Now when you use the interactive mod_perl debugger configuration from the
   previous section and issue a request, the <EM>ptkdb</EM> visual debugger will be loaded.
   
  -<P><A NAME="anchor687"></A>
  +<P>
   If you are debugging <CODE>Apache::Registry</CODE> scripts, as in the terminal debugging mode example, go to line 140 (or to
   whatever line the <CODE>eval
   { &amp;{$cv}($r, @_) } if $r-</CODE>seqno;&gt; statement is located) and press the &lt;step in&gt; button to
   start the debug of the script itself.
   
  -<P><A NAME="anchor688"></A>
  +<P>
   Note that you can use Apache with <CODE>ptkdb</CODE> in plain multi-server mode, you don't have to start <CODE>httpd</CODE> with the <CODE>-X</CODE> option.
   
  -<P><A NAME="anchor689"></A>
  +<P>
   META: One caveat:
   
  -<P><A NAME="anchor690"></A>
  +<P>
   When the request is completed, <CODE>ptkdb</CODE> hangs. Does anyone know what code should be registered for it to exit on
   completion? To replace the original <CODE>Apache::DB</CODE> cleanup code, as:
  +
  +<P>
   
  -<P><A NAME="anchor691"></A>
  -<PRE>    if (ref $r) {
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>    if (ref $r) {
           $SIG{INT} = \&amp;DB::catch;
           $r-&gt;register_cleanup(sub { 
               $SIG{INT} = \&amp;DB::ApacheSIGINT();
           });
  -    }
  -</PRE>
  -<P><A NAME="anchor692"></A>
  +    }</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Any Perl/Tk guru to assist???
   
  -<P><A NAME="anchor693"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="Debugging_when_Server_Crashes_on">Debugging when Server Crashes on Startup before Writing to Log File.</A></H2></CENTER>
  -<P><A NAME="anchor694"></A>
  +<P>
   If your server crashes on startup, you need to start it under gdb and ask
   it to generate a stack trace.
   
  -<P><A NAME="anchor695"></A>
  +<P>
   I'll emulate a faulty server by starting a startup file with the
   <CODE>dump()</CODE> command:
   
  -<P><A NAME="anchor696"></A>
  -<PRE>  startup.pl
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  startup.pl
     ----------
     dump;
  -  1;
  -</PRE>
  -<P><A NAME="anchor697"></A>
  +  1;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   and then requiring this file from the <EM>httpd.conf</EM>:
  +
  +<P>
   
  -<P><A NAME="anchor698"></A>
  -<PRE>  PerlRequire /path/to/startup.pl
  -</PRE>
  -<P><A NAME="anchor699"></A>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  PerlRequire /path/to/startup.pl</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Make sure no server is running on port 80 or use an alternate config with
   an alternate port if using a production server.
  +
  +<P>
   
  -<P><A NAME="anchor700"></A>
  -<PRE>  % gdb /path/to/httpd
  -  (gdb) set args -X
  -</PRE>
  -<P><A NAME="anchor701"></A>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  % gdb /path/to/httpd
  +  (gdb) set args -X</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Use:
  +
  +<P>
   
  -<P><A NAME="anchor702"></A>
  -<PRE>  set args -X -f /path/to/alternate/serverconfig_ifneeded.conf
  -</PRE>
  -<P><A NAME="anchor703"></A>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  set args -X -f /path/to/alternate/serverconfig_ifneeded.conf</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   if the server must be started from an alternative configuration file.
   
  -<P><A NAME="anchor704"></A>
  +<P>
   Now run the program:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor705"></A>
  -<PRE>  (gdb) run
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  (gdb) run
     
     Starting program: /usr/local/apache/bin/httpd -X
     
     Program received signal SIGABRT, Aborted.
  -  0x400da4e1 in __kill () from /lib/libc.so.6
  -</PRE>
  -<P><A NAME="anchor706"></A>
  +  0x400da4e1 in __kill () from /lib/libc.so.6</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   At this point the server should die because of the call to
   <CODE>dump().</CODE> When that happens we use <CODE>bt</CODE> or <CODE>where</CODE> to ask for a stack back trace.
  +
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
   
  -<P><A NAME="anchor707"></A>
  -<PRE>  (gdb) where
  +	<td>
  +	  <pre>  (gdb) where
     
     #0  0x400da4e1 in __kill () from /lib/libc.so.6
     #1  0x80d43bc in Perl_my_unexec ()
  @@ -4201,177 +6401,318 @@
     #15 0x400d41eb in __libc_start_main (main=0x809d8dc &lt;main&gt;, argc=2, 
         argv=0xbffffab4, init=0x80606f8 &lt;_init&gt;, fini=0x812b38c &lt;_fini&gt;, 
         rtld_fini=0x4000a610 &lt;_dl_fini&gt;, stack_end=0xbffffaac)
  -      at ../sysdeps/generic/libc-start.c:90
  -</PRE>
  -<P><A NAME="anchor708"></A>
  +      at ../sysdeps/generic/libc-start.c:90</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   If you do not know what this trace means, you could send it to the mod_perl
   mailing list to ask for help. Make sure to include the version numbers of
   Apache, mod_perl and Perl, and use a subject line that says something about
   the problem rather than 'help'.
   
  -<P><A NAME="anchor709"></A>
  +<P>
   In our case we already know that the server is supposed to die when
   compiling the startup file and we can clearly see that from the trace. We
   always read it from the bottom upward:
   
  -<P><A NAME="anchor710"></A>
  +<P>
   We are in config file:
   
  -<P><A NAME="anchor711"></A>
  -<PRE>  #13 0x8093ca2 in ap_read_config ()
  -</PRE>
  -<P><A NAME="anchor712"></A>
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  #13 0x8093ca2 in ap_read_config ()</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   We do require:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor713"></A>
  -<PRE>  #8  0x807b7ec in perl_cmd_require ()
  -</PRE>
  -<P><A NAME="anchor714"></A>
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  #8  0x807b7ec in perl_cmd_require ()</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   We load the file and compile it:
   
  -<P><A NAME="anchor715"></A>
  -<PRE>  #6  0x807ef1c in perl_do_file ()
  -  #5  0x80d3a9c in perl_eval_sv ()
  -</PRE>
  -<P><A NAME="anchor716"></A>
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  #6  0x807ef1c in perl_do_file ()
  +  #5  0x80d3a9c in perl_eval_sv ()</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   <CODE>dump()</CODE> gets executed:
  +
  +<P>
   
  -<P><A NAME="anchor717"></A>
  -<PRE>  #3  0x8118990 in Perl_pp_dump ()
  -</PRE>
  -<P><A NAME="anchor718"></A>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  #3  0x8118990 in Perl_pp_dump ()</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   <CODE>dump()</CODE> calls <CODE>__kill():</CODE>
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor719"></A>
  -<PRE>  #0  0x400da4e1 in __kill () from /lib/libc.so.6
  -</PRE>
  -<P><A NAME="anchor720"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  #0  0x400da4e1 in __kill () from /lib/libc.so.6</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H1><A NAME="Debugging_Hanging_processes_con">Debugging Hanging processes (continued)</A></H1></CENTER>
  -<P><A NAME="anchor721"></A>
  +<P>
   META: incomplete
   
  -<P><A NAME="anchor722"></A>
  +<P>
   mod_perl comes with a number of useful of gdb macros to ease the debug
   process. You will find the file with macros in the mod_perl source
   distribution in the <EM>.gdbinit</EM> file (mod_perl-x.xx/.gdbinit). You might want to modify the macro
   definitions.
   
  -<P><A NAME="anchor723"></A>
  +<P>
   In order to use this you need to compile mod_perl with
   <CODE>PERL_DEBUG=1</CODE>.
   
  -<P><A NAME="anchor724"></A>
  +<P>
   To debug the server, start it:
  +
  +<P>
   
  -<P><A NAME="anchor725"></A>
  -<PRE>  % httpd -X
  -</PRE>
  -<P><A NAME="anchor726"></A>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  % httpd -X</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Issue a request to the offending script that hangs. Find the PID number of
   the process that hangs.
   
  -<P><A NAME="anchor727"></A>
  +<P>
   Go to the server root:
  +
  +<P>
   
  -<P><A NAME="anchor728"></A>
  -<PRE>  % cd /usr/local/apache
  -</PRE>
  -<P><A NAME="anchor729"></A>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  % cd /usr/local/apache</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Now attach to it with gdb (replace the <CODE>PID</CODE> with the actual process id) and load the macros from <EM>.gdbinit</EM>:
  +
  +<P>
   
  -<P><A NAME="anchor730"></A>
  -<PRE>  % gdb /path/to/httpd PID
  -  % source /usr/src/mod_perl-x.xx/.gdbinit
  -</PRE>
  -<P><A NAME="anchor731"></A>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  % gdb /path/to/httpd PID
  +  % source /usr/src/mod_perl-x.xx/.gdbinit</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Now you can start the server (<EM>httpd</EM> below is a gdb macro):
  +
  +<P>
   
  -<P><A NAME="anchor732"></A>
  -<PRE>  (gdb) httpd
  -</PRE>
  -<P><A NAME="anchor733"></A>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  (gdb) httpd</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Now run the <CODE>curinfo</CODE> macro:
  +
  +<P>
   
  -<P><A NAME="anchor734"></A>
  -<PRE>  (gdb) curinfo
  -</PRE>
  -<P><A NAME="anchor735"></A>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  (gdb) curinfo</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   It should tell you the line/filename of the offending Perl code.
   
  -<P><A NAME="anchor736"></A>
  +<P>
   Add this to <EM>.gdbinit</EM>:
  +
  +<P>
   
  -<P><A NAME="anchor737"></A>
  -<PRE>  define longmess
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  define longmess
       set $sv = perl_eval_pv(&quot;Carp::longmess()&quot;, 1)
       printf &quot;%s\n&quot;, ((XPV*) ($sv)-&gt;sv_any )-&gt;xpv_pv
  -  end
  -</PRE>
  -<P><A NAME="anchor738"></A>
  +  end</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   and when you reload the macros, run:
  +
  +<P>
   
  -<P><A NAME="anchor739"></A>
  -<PRE>  (gdb) longmess
  -</PRE>
  -<P><A NAME="anchor740"></A>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  (gdb) longmess</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   to produce a Perl stacktrace.
   
  -<P><A NAME="anchor741"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="Debugging_core_Dumping_Code">Debugging core Dumping Code</A></H2></CENTER>
  -<P><A NAME="anchor742"></A>
  -<PRE>       $ perl -e dump
  -        Abort(coredump)
  -</PRE>
  -<P><A NAME="anchor743"></A>
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>       $ perl -e dump
  +        Abort(coredump)</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   META: should I move the Apache::StatINC here? (I think not, since it
   relates to other topics like reloading config files, but you should mention
   it here with a pointer to it)
   
  -<P><A NAME="anchor744"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<CENTER><H1><A NAME="PERL_DESTRUCT_LEVEL_Environment_">PERL_DESTRUCT_LEVEL Environment Variable</A></H1></CENTER>
  -<P><A NAME="anchor745"></A>
  -With Apache versions 1.3.0 and higher, mod_perl will call the
  -<CODE>perl_destruct()</CODE> Perl API function during the child exit phase.
  -This will cause proper execution of <CODE>END</CODE> blocks found during server startup and will invoke the <CODE>DESTROY</CODE> method on global objects which are still alive.
  -
  -<P><A NAME="anchor746"></A>
  -It is possible that this operation may take a long time to finish, causing
  -problems during a restart. If your code does not contain any
  -<CODE>END</CODE> blocks or <CODE>DESTROY</CODE> methods which need to be run during child server shutdown, this destruction
  -can be avoided by setting the
  -<CODE>PERL_DESTRUCT_LEVEL</CODE> environment variable to <CODE>-1</CODE>. This will cause mod_perl to skip the call to <CODE>perl_destruct()</CODE>
  -in <CODE>perl_shutdown().</CODE>
  -
  -<P><A NAME="anchor747"></A>
  -It is only usable if no significant cleanup has to be done by perl
  -<CODE>END</CODE> blocks and <CODE>DESTROY</CODE> methods when the child terminates, of course. What constitutes significant
  -cleanup? Any change of state outside of the current process that would not
  -be handled by the operating system itself. So committing database
  -transactions is significant but closing an ordinary file isn't.
  -
  -<P><A NAME="anchor748"></A>
  -Setting <CODE>PERL_DESTRUCT_LEVEL=-1</CODE> speeds the server restart or termination and leads to more robust operation
  -in the face of problems like running out of memory. If set--
  -
  -<P><A NAME="anchor749"></A>
  -META: to be continued
  -
  -<P><A NAME="anchor750"></A>
  -You can also use <CODE>-DPERL_DESTRUCT_LEVEL</CODE>.
  -
  -<P><A NAME="anchor751"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H1><A NAME="PERL_DEBUG_1_Build_Option">PERL_DEBUG=1 Build Option</A></H1></CENTER>
  -<P><A NAME="anchor752"></A>
  +<P>
   Building mod_perl with <CODE>PERL_DEBUG=1</CODE>:
   
  -<P><A NAME="anchor753"></A>
  -<PRE>  perl Makefile.PL PERL_DEBUG=1
  -</PRE>
  -<P><A NAME="anchor754"></A>
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  perl Makefile.PL PERL_DEBUG=1</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   will:
   
   <OL>
  @@ -4381,145 +6722,254 @@
   <P><LI><STRONG><A NAME="item_Link_against_libperld_if_e_Con">Link against libperld if -e
   $Config{archlibexp}/CORE/libperld$Config{lib_ext}</A></STRONG>
   </OL>
  -<P><A NAME="anchor755"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H1><A NAME="Apache_Debug">Apache::Debug</A></H1></CENTER>
  -<P><A NAME="anchor756"></A>
  +<P>
   (META: to be written)
  +
  +<P>
   
  -<P><A NAME="anchor757"></A>
  -<PRE>  use Apache::Debug ();
  -  Apache::Debug::dump($r, SERVER_ERROR, &quot;Uh Oh!&quot;);
  -</PRE>
  -<P><A NAME="anchor758"></A>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  use Apache::Debug ();
  +  Apache::Debug::dump($r, SERVER_ERROR, &quot;Uh Oh!&quot;);</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   This module sends what may be helpful debugging information to the client
   rather than to <EM>error_log</EM>.
   
  -<P><A NAME="anchor759"></A>
  +<P>
   Also, you could try using a larger emergency pool, try this instead of
   Apache::Debug:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor760"></A>
  -<PRE> $^M = 'a' x (1&lt;&lt;18);  #256k buffer
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre> $^M = 'a' x (1&lt;&lt;18);  #256k buffer
    use Carp ();
    $SIG{__DIE__} = \&amp;Carp::confess;
  - eval { Carp::confess(&quot;init&quot;) };
  -</PRE>
  -<P><A NAME="anchor761"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  + eval { Carp::confess(&quot;init&quot;) };</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H1><A NAME="Debug_Tracing">Debug Tracing</A></H1></CENTER>
  -<P><A NAME="anchor762"></A>
  +<P>
   To enable mod_perl debug tracing, configure mod_perl with the PERL_TRACE
   option:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor763"></A>
  -<PRE> perl Makefile.PL PERL_TRACE=1
  -</PRE>
  -<P><A NAME="anchor764"></A>
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre> perl Makefile.PL PERL_TRACE=1</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   The trace levels can then be enabled via the <CODE>MOD_PERL_TRACE</CODE>
   environment variable which can contain any combination of:
   
   <DL>
   <P><DT><STRONG><A NAME="item_c">c</A></STRONG><DD>
  -<P><A NAME="anchor765"></A>
  +<P>
   Trace directive handling during <EM>Apache</EM> (non-mod_perl)
   <STRONG>c</STRONG>onfiguration directive handling. (Startup.)
   
   <P><DT><STRONG><A NAME="item_d">d</A></STRONG><DD>
  -<P><A NAME="anchor766"></A>
  +<P>
   Trace directive handling during <EM>mod_perl</EM>  <STRONG>d</STRONG>irective processing during configuration read. (Startup.)
   
   <P><DT><STRONG><A NAME="item_s">s</A></STRONG><DD>
  -<P><A NAME="anchor767"></A>
  +<P>
   Trace processing of <EM>&lt;Perl&gt;</EM>  <STRONG>s</STRONG>ections. (Startup.)
   
   <P><DT><STRONG><A NAME="item_h">h</A></STRONG><DD>
  -<P><A NAME="anchor768"></A>
  +<P>
   Trace Perl <STRONG>h</STRONG>andler callbacks. (RunTime.)
   
   <P><DT><STRONG><A NAME="item_g">g</A></STRONG><DD>
  -<P><A NAME="anchor769"></A>
  +<P>
   Trace <STRONG>g</STRONG>lobal variable handling, interpreter construction, <CODE>END</CODE>
   blocks, etc. (RunTime.)
   
   <P><DT><STRONG><A NAME="item_all">all</A></STRONG><DD>
  -<P><A NAME="anchor770"></A>
  +<P>
   <STRONG>all</STRONG> of the options listed above. (Startup + RunTime.)
   
   </DL>
  -<P><A NAME="anchor771"></A>
  +<P>
   One way of setting this variable is by adding this directive to
   <EM>httpd.conf</EM>:
   
  -<P><A NAME="anchor772"></A>
  -<PRE>  PerlSetEnv MOD_PERL_TRACE all
  -</PRE>
  -<P><A NAME="anchor773"></A>
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  PerlSetEnv MOD_PERL_TRACE all</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   For example if you want to see a trace of the <CODE>PerlRequire</CODE> and
   <CODE>PerlModule</CODE> directives as they are executed, use:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor774"></A>
  -<PRE>  PerlSetEnv MOD_PERL_TRACE d
  -</PRE>
  -<P><A NAME="anchor775"></A>
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  PerlSetEnv MOD_PERL_TRACE d</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Of course you can use the command line environment setting:
   
  -<P><A NAME="anchor776"></A>
  -<PRE>  % setenv MOD_PERL_TRACE all
  -  % httpd -X
  -</PRE>
  -<P><A NAME="anchor777"></A>
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  % setenv MOD_PERL_TRACE all
  +  % httpd -X</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   META: add output examples
   
  -<P><A NAME="anchor778"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H1><A NAME="gdb_says_there_are_no_debugging_">gdb says there are no debugging symbols</A></H1></CENTER>
  -<P><A NAME="anchor779"></A>
  +<P>
   As you know you need an unstripped executable to be able to debug it. While
   you can compile mod_perl with <A HREF="#item__g">-g</A> (or <CODE>PERL_DEBUG=1</CODE>), the Apache <CODE>install</CODE> strips the symbols.
   
  -<P><A NAME="anchor780"></A>
  +<P>
   Makefile.tmpl contains a line:
  +
  +<P>
   
  -<P><A NAME="anchor781"></A>
  -<PRE>  IFLAGS_PROGRAM  = -m 755 -s 
  -</PRE>
  -<P><A NAME="anchor782"></A>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  IFLAGS_PROGRAM  = -m 755 -s </pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Removing the -s does the trick.
   
  -<P><A NAME="anchor783"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H1><A NAME="Debugging_Signal_Handlers_SIG_">Debugging Signal Handlers ($SIG{FOO})</A></H1></CENTER>
  -<P><A NAME="anchor784"></A>
  +<P>
   The current Perl implementation does not restore the original Apache C
   handler when you use the <CODE>local $SIG{FOO}</CODE> clause. While the save/restore of <CODE>$SIG{ALRM}</CODE> was fixed in mod_perl 1.19_01 (CVS version), other signals are not yet
   fixed. The real fix should probably be in Perl itself.
   
  -<P><A NAME="anchor785"></A>
  +<P>
   Until recently <CODE>local $SIG{ALRM}</CODE> restored the <CODE>SIGALRM</CODE> handler to Perl's handler, not the handler it was in the first place
   (Apache's
   <CODE>alrm_handler()</CODE>). If you build mod_perl with <CODE>PERL_TRACE=1</CODE> and set the <CODE>MOD_PERL_TRACE</CODE> environment variable to <STRONG>g</STRONG>, you will see this in the <EM>error_log</EM> file:
  +
  +<P>
   
  -<P><A NAME="anchor786"></A>
  -<PRE>  mod_perl: saving SIGALRM (14) handler 0x80b1ff0
  -  mod_perl: restoring SIGALRM (14) handler from: 0x0 to: 0x80b1ff0
  -</PRE>
  -<P><A NAME="anchor787"></A>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  mod_perl: saving SIGALRM (14) handler 0x80b1ff0
  +  mod_perl: restoring SIGALRM (14) handler from: 0x0 to: 0x80b1ff0</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   If nobody has touched <CODE>$SIG{ALRM}</CODE>, <CODE>0x0</CODE> will be the same address as the others.
   
  -<P><A NAME="anchor788"></A>
  +<P>
   If you work with signal handlers you should take a look at the
   <CODE>Sys::Signal</CODE> module, which solves the problem:
   
  -<P><A NAME="anchor789"></A>
  +<P>
   <CODE>Sys::Signal</CODE> - Set signal handlers with restoration of the existing C sighandler. Get it
   from <A HREF="././download.html#Perl">CPAN</A>.
   
  -<P><A NAME="anchor790"></A>
  +<P>
   The usage is simple. If the original code was:
  +
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
   
  -<P><A NAME="anchor791"></A>
  -<PRE>  # If a timeout happens and C&lt;SIGALRM&gt; is thrown, the alarm() will be
  +	<td>
  +	  <pre>  # If a timeout happens and C&lt;SIGALRM&gt; is thrown, the alarm() will be
     # reset, otherwise C&lt;alarm 0&gt; is reached and timer is reset as well.
     eval {
       local $SIG{ALRM} = sub { die &quot;timeout\n&quot; };
  @@ -4527,76 +6977,126 @@
       ... db stuff ...
       alarm 0;
     };
  -  die $@ if $@;
  -</PRE>
  -<P><A NAME="anchor792"></A>
  +  die $@ if $@;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Now you would write:
   
  -<P><A NAME="anchor793"></A>
  -<PRE>  use Sys::Signal ();
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  use Sys::Signal ();
     eval {
       my $h = Sys::Signal-&gt;set(ALRM =&gt; sub { die &quot;timeout\n&quot; });
       alarm $timeout;
       ... do something that may timeout ...
       alarm 0;
     };
  -  die $@ if $@;
  -</PRE>
  -<P><A NAME="anchor794"></A>
  +  die $@ if $@;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   This should be fixed in Perl 5.6.1, so if you use this version of Perl,
   chances are that you don't need to use <CODE>Sys::Signal</CODE>.
   
  -<P><A NAME="anchor795"></A>
  +<P>
   mod_perl tries to deal only with those signals that cause conflict with
   Apache's. Currently this is only <CODE>SIGALRM</CODE>. If there is another one that gives you trouble, you can add it to the
   list in
   <EM>perl_config.c</EM> after <EM>"ALRM"</EM>, before <EM>NULL</EM>.
  +
  +<P>
   
  -<P><A NAME="anchor796"></A>
  -<PRE>  static char *sigsave[] = { &quot;ALRM&quot;, NULL };
  -</PRE>
  -<P><A NAME="anchor797"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  static char *sigsave[] = { &quot;ALRM&quot;, NULL };</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H1><A NAME="Code_Profiling">Code Profiling</A></H1></CENTER>
  -<P><A NAME="anchor798"></A>
  +<P>
   (Meta: duplication??? I've started to write about profiling somewhere in
   this file)
   
  -<P><A NAME="anchor799"></A>
  +<P>
   It is possible to profile code run under mod_perl with the
   <CODE>Devel::DProf</CODE> module available on CPAN. However, you must have apache version 1.3b3 or
   higher and the <CODE>PerlChildExitHandler</CODE>
   enabled. When the server is started, <CODE>Devel::DProf</CODE> installs an
   <CODE>END</CODE> block (to write the <CODE>tmon.out</CODE> file) which will be run when the server is shutdown. Here's how to start
   and stop a server with the profiler enabled:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor800"></A>
  -<PRE> % setenv PERL5OPT -d:DProf
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre> % setenv PERL5OPT -d:DProf
    % httpd -X -d `pwd` &amp;
    ... make some requests to the server here ...
    % kill `cat logs/httpd.pid`
    % unsetenv PERL5OPT
  - % dprofpp
  -</PRE>
  -<P><A NAME="anchor801"></A>
  + % dprofpp</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   See also: <CODE>Apache::DProf</CODE>
   
   
   
  -<P><A NAME="anchor802"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H1><A NAME="Devel_Peek">Devel::Peek</A></H1></CENTER>
  -<P><A NAME="anchor803"></A>
  +<P>
   Devel::Peek - A data debugging tool for the XS programmer
   
  -<P><A NAME="anchor804"></A>
  +<P>
   Let's see an example of Perl allocating a buffer only once, regardless of
   <CODE>my()</CODE> scoping, although it will <CODE>realloc()</CODE> if the
   size is &gt;
   <CODE>SvLEN</CODE>:
  +
  +<P>
   
  -<P><A NAME="anchor805"></A>
  -<PRE>  use Devel::Peek;
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  use Devel::Peek;
     
     for (1..3) {
         foo();
  @@ -4607,13 +7107,25 @@
         Dump $sv;
         $sv = 'x' x 100_000;
         $sv = &quot;&quot;;
  -  }
  -</PRE>
  -<P><A NAME="anchor806"></A>
  +  }</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   The output:
  +
  +<P>
   
  -<P><A NAME="anchor807"></A>
  -<PRE>  SV = NULL(0x0) at 0x8138008
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  SV = NULL(0x0) at 0x8138008
       REFCNT = 1
       FLAGS = (PADBUSY,PADMY)
     SV = PV(0x80e5794) at 0x8138008
  @@ -4626,85 +7138,149 @@
       REFCNT = 1
       FLAGS = (PADBUSY,PADMY)
       PV = 0x815f808 &quot;&quot;\0
  -    CUR = 0
  -</PRE>
  -<P><A NAME="anchor808"></A>
  +    CUR = 0</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   We can see that on the second and subsequent calls <CODE>$sv</CODE> already has preallocated memory.
   
  -<P><A NAME="anchor809"></A>
  +<P>
   So, if you can afford the memory, a larger buffer means fewer <CODE>brk()</CODE>
   syscalls. If you watch that example with <CODE>strace</CODE> you will only see calls to <CODE>brk()</CODE> the first time through the loop. So this is a case where your module might
   want to pre-allocate the buffer like this:
  +
  +<P>
   
  -<P><A NAME="anchor810"></A>
  -<PRE>  package Your::Proxy;
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  package Your::Proxy;
     
     my $buffer = ' ' x 100_000;
  -  $buffer = &quot;&quot;;
  -</PRE>
  -<P><A NAME="anchor811"></A>
  +  $buffer = &quot;&quot;;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Now only the parent has to <CODE>brk()</CODE> at server startup, each child
   already will already have an allocated buffer. Just reset to ``'' when you
   are done.
   
  -<P><A NAME="anchor812"></A>
  +<P>
   Note: Preallocating a scalar in this way saves reallocation in v5.005 but
   may not do so in other versions.
   
  -<P><A NAME="anchor813"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H1><A NAME="How_can_I_find_out_if_a_mod_perl">How can I find out if a mod_perl script has a memory leak</A></H1></CENTER>
  -<P><A NAME="anchor814"></A>
  +<P>
   <CODE>Apache::Leak</CODE> (derived from <CODE>Devel::Leak</CODE>) should help you with this task. Example:
  +
  +<P>
   
  -<P><A NAME="anchor815"></A>
  -<PRE>  use Apache::Leak;
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  use Apache::Leak;
     
     my $global = &quot;FooAAA&quot;;
     
     leak_test {
       $$global = 1;
       ++$global;
  -  };
  -</PRE>
  -<P><A NAME="anchor816"></A>
  +  };</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   The argument to <CODE>leak_test()</CODE> is an anonymous sub, so you can just throw it any code you suspect might be
   leaking. Beware, it will run the code twice! The first time in, new <CODE>SV</CODE>s are created, but does not mean you are leaking. The second pass will give
   better evidence. You do not need to be inside mod_perl to use it. From the
   command line, the above script outputs:
   
  -<P><A NAME="anchor817"></A>
  -<PRE>  ENTER: 1482 SVs
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  ENTER: 1482 SVs
     new c28b8 : new c2918 : 
     LEAVE: 1484 SVs
     ENTER: 1484 SVs
     new db690 : new db6a8 : 
     LEAVE: 1486 SVs
  -  !!! 2 SVs leaked !!!
  -</PRE>
  -<P><A NAME="anchor818"></A>
  +  !!! 2 SVs leaked !!!</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Build a debuggable Perl to see dumps of the <CODE>SV</CODE>s. The simple way to have both a normal Perl and debuggable Perl is to
   follow hints in the
   <CODE>SUPPORT</CODE> doc for building <CODE>libperld.a</CODE>. When that is built, copy the <CODE>perl</CODE> from that directory to your Perl bin directory, but name it <CODE>dperl</CODE>.
   
  -<P><A NAME="anchor819"></A>
  +<P>
   Leak explanation: <CODE>$$global = 1;</CODE> : new global variable created
   <CODE>FooAAA</CODE> with value of <CODE>1</CODE>, this will not be destroyed until this module is destroyed.
   
  -<P><A NAME="anchor820"></A>
  +<P>
   <CODE>Apache::Leak</CODE> is not very user-friendly, have a look at
   <CODE>B::LexInfo</CODE>. It is possible to see something that might appear to be a leak, but is
   actually just a Perl optimization. e.g. consider this code:
  +
  +<P>
   
  -<P><A NAME="anchor821"></A>
  -<PRE>  sub foo {
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  sub foo {
       my $string = shift;
  -  }
  -</PRE>
  -<P><A NAME="anchor822"></A>
  -<PRE>  foo(&quot;a string&quot;);
  -</PRE>
  -<P><A NAME="anchor823"></A>
  +  }</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  foo(&quot;a string&quot;);</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   <CODE>B::LexInfo</CODE> will show you that Perl does not release the value from $string, unless you
   <CODE>undef()</CODE> it. This is because Perl anticipates the memory will
   be needed for another string, the next time the subroutine is entered.
  @@ -4712,22 +7288,23 @@
   <CODE>%hash</CODE> keys, and scratch areas of the pad-list for OPs such as
   <CODE>join()</CODE>, `<CODE>.</CODE>', etc.
   
  -<P><A NAME="anchor824"></A>
  +<P>
   <CODE>Apache::Status</CODE> now includes a new <CODE>StatusLexInfo</CODE> option.
   
  -<P><A NAME="anchor825"></A>
  +<P>
   <CODE>Apache::Leak</CODE> works better if you've built a <EM>libperld.a</EM> (see
   <EM>SUPPORT</EM> document) and given <CODE>PERL_DEBUG=1</CODE> to mod_perl's
   <CODE>Makefile.PL</CODE>.
   
  -<P><A NAME="anchor826"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H1><A NAME="Debugging_your_code_in_Single_Se">Debugging your code in Single Server Mode</A></H1></CENTER>
  -<P><A NAME="anchor827"></A>
  +<P>
   Running in httpd -X mode is good only for testing during the development
   phase.
   
  -<P><A NAME="anchor828"></A>
  +<P>
   You want to test that your application correctly handles global variables
   (if you have any - the less you have of them the better of course - but
   sometimes you just can't do without them). It's hard to test with multiple
  @@ -4735,12 +7312,24 @@
   global variables. Imagine that you have a
   <CODE>random()</CODE> sub that returns a random number and you have the following script.
   
  -<P><A NAME="anchor829"></A>
  -<PRE>  use vars qw($num);
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  use vars qw($num);
     $num ||= random();
  -  print ++$num;
  -</PRE>
  -<P><A NAME="anchor830"></A>
  +  print ++$num;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   This script initializes the variable <CODE>$num</CODE> with a random value, then increments it on each request and prints it out.
   Running this script in a multiple server environments will result in
   something like <CODE>1</CODE>,
  @@ -4751,32 +7340,44 @@
   But if you run in <CODE>httpd
   -X</CODE> single server mode you will get <CODE>2</CODE>, <CODE>3</CODE>, <CODE>4</CODE>, <CODE>5</CODE>... (assuming that <CODE>random()</CODE> returned <CODE>1</CODE> at the first call)
   
  -<P><A NAME="anchor831"></A>
  +<P>
   But do not get too obsessive with this mode, since working in single server
   mode sometimes hides problems that show up when you switch to normal
   (multi-server) mode.
   
  -<P><A NAME="anchor832"></A>
  +<P>
   Consider an application that allows you to change the configuration at run
   time. Let's say the script produces a form to change the background color
   of the page. It's not good design, but for the sake of demonstrating the
   potential problem we will assume that our script doesn't write the changed
   background color to the disk, but simply changes it in memory, like this:
  +
  +<P>
   
  -<P><A NAME="anchor833"></A>
  -<PRE>  use vars qw($bgcolor);
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  use vars qw($bgcolor);
       # assign default value at first invocation
     $bgcolor ||= &quot;white&quot;;
       # modify the color if requested to
  -  $bgcolor = $q-&gt;param('bgcolor') || $bgcolor;
  -</PRE>
  -<P><A NAME="anchor834"></A>
  +  $bgcolor = $q-&gt;param('bgcolor') || $bgcolor;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   So you have typed in a new color, and in response, your script prints back
   the html with a new color - you think that's it! It was so simple. If you
   keep running in single server mode you will never notice that you have a
   problem...
   
  -<P><A NAME="anchor835"></A>
  +<P>
   If you run the same code in normal server mode, after you submit the color
   change you will get the result as expected, but when you call the same URL
   again (not reload!) the chances are that you will get back the original
  @@ -4787,7 +7388,7 @@
   for the color to be remembered, or store it on the server side (database,
   shared memory, etc).
   
  -<P><A NAME="anchor836"></A>
  +<P>
   If you use the Netscape client while your server is running in
   single-process mode, if the output returns HTML with <CODE>&lt;IMG&gt;</CODE>
   tags, then the loading of the images will take a long time, since
  @@ -4797,30 +7398,40 @@
   parameters, so that Netscape will be able to render the rest of the page)
   you can press <STRONG>STOP</STRONG> after a few seconds.
   
  -<P><A NAME="anchor837"></A>
  +<P>
   In addition you should be aware that when running with <CODE>-X</CODE> you will not see the status messages that the parent server normally writes
   to the error_log. (``server started'', ``server stopped'', etc.). Since <CODE>httpd
   -X</CODE> causes the server to handle all requests itself, without forking any
   children, there is no controlling parent to write the status messages.
   
  -<P><A NAME="anchor838"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H1><A NAME="Apache_DumpHeaders_Watch_HTTP">Apache::DumpHeaders - Watch HTTP Transaction Via Headers</A></H1></CENTER>
  -<P><A NAME="anchor839"></A>
  +<P>
   This module is used to watch an HTTP transaction, looking at client and
   servers headers.
   
  -<P><A NAME="anchor840"></A>
  +<P>
   With <CODE>Apache::ProxyPassThru</CODE> configured, you are able to watch your browser talk to any server besides
   the one with this module living inside.
   
  -<P><A NAME="anchor841"></A>
  +<P>
  +<CODE>Apache::DumpHeaders</CODE> has the ability to filter on IP addresses, has an interface for other
  +modules to decide if the headers should be dumped or not and a function to
  +only dump <EM>n%</EM> of the transactions.
  +
  +<P>
   For more information read the module's manpage.
  +
  +<P>
  +Download the module from <A HREF="././download.html#CPAN_Downloads">CPAN</A>.
   
  -<P><A NAME="anchor842"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H1><A NAME="Apache_DebugInfo_Log_Various_">Apache::DebugInfo - Log Various Bits Of Per-Request Data</A></H1></CENTER>
  -<P><A NAME="anchor843"></A>
  +<P>
   <CODE>Apache::DebugInfo</CODE> offers the ability to monitor various bits of per-request data. Its
   functionality is similar to
   <A HREF="././debug.html#Apache_DumpHeaders_Watch_HTTP">Apache::DumpHeaders</A>
  @@ -4835,61 +7446,87 @@
   <P><DT><STRONG>- use partial IP addresses for filtering by IP</STRONG><DD>
   <P><DT><STRONG>- offer a subclassable interface</STRONG><DD>
   </DL>
  -<P><A NAME="anchor844"></A>
  +<P>
   See the module's manpage for more details.
   
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -	     The <a href="http://www.modperl.com/">
  -	     <B>Writing Apache Modules with Perl and C</B></a>
  -	     book can be purchased online from <a
  -	     href="http://www.ora.com/catalog/wrapmod/">O'Reilly </a>
  -	     and <a
  -	     href="http://www.amazon.com/exec/obidos/ASIN/156592567X/writinapachemodu">
  -	     Amazon.com</a>.
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   
  -	     <HR>
   
  -	     <B>Your corrections of either technical or grammatical
  +    <p>
  +    <div class="navbar">
  +      <a href="multiuser.html">Prev</a>                                 |
  +      <A HREF="index.html"         >Contents</A> |
  +      <A HREF="index.html#search"  >Search</A>   |
  +      <A HREF="index.html#download">Download</A> |
  +      <a href="browserbugs.html">Next</a>
  +    </div>
  +    <p>
  +
  +    <table width="60%" align="center">
  +
  +      <tr>
  +	<td>
  +	  <div class="notice">
  +	  <B>Your corrections of the technical and grammatical
   	     errors are very welcome. You are encouraged to help me
  -	     to improve this guide.  If you have something to
  -	     contribute please <A
  -	     HREF="help.html#Contacting_me"> send it
  +	     improve this guide.  If you have something to contribute
  +	     please <A HREF="help.html#Contacting_me"> send it
   	     directly to me</A>.</B>
  +	  </div>
  +	</td>
  +      </tr>
  +
  +      <tr>
  +	<td>
  +	  <div class="ad">
  +	    The <a href="http://www.modperl.com/">
  +	      <B>Writing Apache Modules with Perl and C</B></a>
  +	    book can be purchased online from <a
  +	      href="http://www.ora.com/catalog/wrapmod/">O'Reilly </a>
  +	    and <a
  +	    href="http://www.amazon.com/exec/obidos/ASIN/156592567X/writinapachemodu">
  +	      Amazon.com</a>.
  +	  </div>
  +	</td>
  +      </tr>
  +
  +</table>
  +
  +<center>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
  +<table cellspacing=2 cellpadding=2>
  +
  +<tr align=center valign=top>
  +<td align=center valign=center>
  +
  +<b><font size=-1>Written by <a
  +href="help.html#Contacting_me">Stas Bekman</a>.<br> Last Modified at 05/30/2000
  +</font></b>
  +<br>
  +
  +</td>
  +
  +<td>
  +
  +<a href="http://perl.apache.org"><img src="images/mod_perl2.jpg"  border=0 alt="mod_perl icon" border=0 height=59 width=150></a>
  +<br>
  +
  +</td>
  +
  +<td>
  +
  +<font size=-2>Use of the Camel for Perl is <br>
  +a trademark of <a href="http://www.ora.com">O'Reilly &amp; Associates</a>,<br>
  +and is used by permission. </font> 
  +<br>
   
  -	     <HR>
  +</td>
   
  -	     [    <A HREF="multiuser.html">Prev</A> |      <A HREF="index.html">Main Page</A> | <A HREF="browserbugs.html">Next</A>      ]
  +</tr>
  +</table>
  +</center>
   
  -<CENTER><TABLE CELLSPACING=2 CELLPADDING=2 WIDTH="100%" >
  -<TR ALIGN=CENTER VALIGN=TOP>
  -  <TD ALIGN=CENTER VALIGN=CENTER COLSPAN="3">
  -	     <HR>
  -  </TD>
  -</TR>
  -<TR ALIGN=CENTER VALIGN=TOP>
  -  <TD ALIGN=CENTER VALIGN=CENTER>
  -    <B>
  -      <FONT SIZE=-1>
  -	     Written by <A HREF="help.html#Contacting_me">Stas Bekman</A>.
  -	     <BR>Last Modified at 05/13/2000
  -      </FONT>
  -    </B>
  -  </TD>
  -
  -  <TD>
  -	     <A HREF="http://perl.apache.org"><IMG SRC="images/mod_perl2.jpg" ALT="Mod Perl Icon" BORDER=0 HEIGHT=59 WIDTH=150></A>
  -  </TD>
  -
  -  <TD>
  -    <FONT SIZE=-2>
  -	     Use of the Camel for Perl is <BR>
  -	     a trademark of <A HREF="http://www.ora.com">O'Reilly &amp; Associates</A>,<BR>
  -             and is used by permission. 
  -    </FONT> 
  -  </TD>
  -</TR>
  -</TABLE></CENTER>
  -
  -</BODY>
  -</HTML>
  -	    
  \ No newline at end of file
  +</body>
  +</html>
  
  
  
  1.12      +255 -169  modperl-site/guide/download.html
  
  Index: download.html
  ===================================================================
  RCS file: /home/cvs/modperl-site/guide/download.html,v
  retrieving revision 1.11
  retrieving revision 1.12
  diff -u -r1.11 -r1.12
  --- download.html	2000/05/12 22:42:51	1.11
  +++ download.html	2000/06/07 22:45:31	1.12
  @@ -1,33 +1,42 @@
   <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
  -<HTML>
  -<HEAD>
  -   <TITLE>mod_perl guide: Appendix A: Downloading software and documentation</TITLE>
  -   <META NAME="GENERATOR" CONTENT="Pod2HTML [Perl/Linux]">
  -   <META NAME="Author" CONTENT="Stas Bekman">
  -   <META NAME="Description" CONTENT="All Apache/Perl related information: Hints, Guidelines, Scenarios and Troubleshottings">
  -   <META NAME="keywords" CONTENT="mod_perl modperl perl apache cgi webserver speed  fast guide mod_perl apache guide help info faq mod_perl installation cgi troubleshooting help no sex speedup free open source OSS mod_perl apache guide">
  -</HEAD>
  -     <LINK REL=STYLESHEET TYPE="text/css"
  -        HREF="style.css" TITLE="refstyle">
  -     <style type="text/css">
  -     <!-- 
  -        @import url(style.css);
  -     -->
  -     
  -     </style>
  -<BODY BGCOLOR="white">
  +<html>
  +  <head>
  +   <title>mod_perl guide: Appendix A: Downloading software and documentation</title>
  +   <meta name="Author" content="Stas Bekman">
  +   <meta name="Description" content="All Apache/Perl related information: Hints, Guidelines, Scenarios and Troubleshottings">
  +   <meta name="keywords" content="mod_perl modperl perl cgi apache webserver speed fast guide mod_perl apache guide help info faq mod_perl installation cgi troubleshooting help no sex speedup free open source OSS mod_perl apache guide">
  +   <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
  +   <meta name="Classification" content="information">
  +   <link href="style.css" rel=stylesheet type="text/css" title="refstyle">
  +  </head>
  +  <body>
  +
  +    <h1 align=center>
  +      <a href="http://perl.apache.org"><img src="images/mod_perl.gif" alt="Mod Perl Icon" border=0 height=30 width=90 align=left></a>
  +      <a href="http://perl.apache.org"><img src="images/mod_perl.gif" alt="Mod Perl Icon" border=0 height=30 width=90 align=right></a>
  +      Appendix A: Downloading software and documentation
  +    </h1>
  +    <hr>
  +    <p>
  +    <div class="navbar">
  +      <a href="help.html">Prev</a>                                 |
  +      <a href="index.html"         >Contents</a> |
  +      <a href="index.html#search"  >Search</a>   |
  +      <a href="index.html#download">Download</a> |
  +      <a href="">Next</a>
  +    </div>
  +    <p>
  +
  +    <div class="toc">
  +      
   <A NAME="toc"></A>
  -<H1 ALIGN=CENTER>
  -<A HREF="http://perl.apache.org"><IMG SRC="images/mod_perl.gif" ALT="Mod Perl Icon" BORDER=0 HEIGHT=30 WIDTH=90 ALIGN=LEFT></A>
  -<A HREF="http://perl.apache.org"><IMG SRC="images/mod_perl.gif" ALT="Mod Perl Icon" BORDER=0 HEIGHT=30 WIDTH=90 ALIGN=RIGHT></A>
  -Appendix A: Downloading software and documentation</H1>
  -<HR WIDTH="100%">
  -	    [    <A HREF="help.html">Prev</A> |      <A HREF="index.html">Main Page</A> ]<HR><!-- INDEX BEGIN -->
  -<P><B><FONT SIZE=-1>Table of Contents:</FONT></B></P>
  +<P><B>Table of Contents:</B></P>
  +
   <UL>
   
   	<LI><A HREF="#Coverage">Coverage</A>
   	<LI><A HREF="#Perl">Perl</A>
  +	<LI><A HREF="#CPAN_Downloads">CPAN Downloads</A>
   	<LI><A HREF="#Apache">Apache</A>
   	<LI><A HREF="#mod_perl">mod_perl</A>
   	<LI><A HREF="#Squid_Internet_Object_Cache">Squid - Internet Object Cache</A>
  @@ -52,40 +61,57 @@
   	<LI><A HREF="#Apache_Request">Apache::Request</A>
   	<LI><A HREF="#DataBases">DataBases</A>
   </UL>
  -<!-- INDEX END -->
   
  +    </div>
  +
  +    [ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
   <HR>
  +    <table width="60%" align="center">
  +
  +      <tr>
  +	<td>
  +	  <div class="ad">
  +	    The <a href="http://www.modperl.com/">
  +	      <B>Writing Apache Modules with Perl and C</B></a>
  +	    book can be purchased online from <a
  +	      href="http://www.ora.com/catalog/wrapmod/">O'Reilly </a>
  +	    and <a
  +	    href="http://www.amazon.com/exec/obidos/ASIN/156592567X/writinapachemodu">
  +	      Amazon.com</a>.
  +	  </div>
  +	</td>
  +      </tr>
  +
  +      <tr>
  +	<td>
  +	  <div class="notice">
  +	  <B>Your corrections of the technical and grammatical
  +	     errors are very welcome. You are encouraged to help me
  +	     improve this guide.  If you have something to contribute
  +	     please <A HREF="help.html#Contacting_me"> send it
  +	     directly to me</A>.</B>
  +	  </div>
  +	</td>
  +      </tr>
   
  -	     The <a href="http://www.modperl.com/">
  -	     <B>Writing Apache Modules with Perl and C</B></a>
  -	     book can be purchased online from <a
  -	     href="http://www.ora.com/catalog/wrapmod/">O'Reilly </a>
  -	     and <a
  -	     href="http://www.amazon.com/exec/obidos/ASIN/156592567X/writinapachemodu">
  -	     Amazon.com</a>.
  -
  -	     <HR>
  -
  -	       <B>Your corrections of either technical or grammatical
  -	       errors are very welcome. You are encouraged to help me
  -	       to improve this guide.  If you have something to
  -	       contribute please <A
  -	       HREF="help.html#Contacting_me"> send it
  -	       directly to me</A>.
  -	       </B>
  -	       <HR>
  +</table>
   
  -	      <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<P><A NAME="anchor0"></A>
  +    
  +
  +	    [ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
  +
  +<P>
   <CENTER><H1><A NAME="Coverage">Coverage</A></H1></CENTER>
  -<P><A NAME="anchor1"></A>
  +<P>
   Here you will find instructions for downloading the software and its
   related documentation.
   
  -<P><A NAME="anchor2"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H1><A NAME="Perl">Perl</A></H1></CENTER>
  -<P><A NAME="anchor3"></A>
  +<P>
   Perl is probably already installed on your machine, but you should at least
   check the version you are using. It is highly recommended that you have at
   least Perl version 5.004. You can get the latest perl version from <A
  @@ -95,37 +121,52 @@
   . You can get Perl documentation from the same location (although copious
   documentation is included in the downloaded Perl distribution).
   
  -<P><A NAME="anchor4"></A>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
  +<CENTER><H1><A NAME="CPAN_Downloads">CPAN Downloads</A></H1></CENTER>
  +<P>
   You can download most of the Perl modules from CPAN. There are many mirrors
   of this site. The main site's URL is <A
  -HREF="http://cpan.org/.">http://cpan.org/.</A> You may want to search the
  -Perl modules database by using <A
  +HREF="http://cpan.org/.">http://cpan.org/.</A>  
  +
  +<P>
  +You may want to search the Perl modules database by using <A
   HREF="http://search.cpan.org/.">http://search.cpan.org/.</A>
   
  -<P><A NAME="anchor5"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +Either use the search form, or type in the name of the package the module
  +is distributed in. For example if you are looking for
  +<CODE>Apache::DumpHeaders</CODE>, you can type: <A
  +HREF="http://search.cpan.org/search?dist=Apache-DumpHeaders">http://search.cpan.org/search?dist=Apache-DumpHeaders</A>
  +.
  +
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H1><A NAME="Apache">Apache</A></H1></CENTER>
  -<P><A NAME="anchor6"></A>
  +<P>
   Get the latest Apache webserver and documentation from <A
   HREF="http://www.apache.org">http://www.apache.org</A> . Try the direct
   download link <A
   HREF="http://www.apache.org/dist/">http://www.apache.org/dist/</A> .
   
  -<P><A NAME="anchor7"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H1><A NAME="mod_perl">mod_perl</A></H1></CENTER>
  -<P><A NAME="anchor8"></A>
  +<P>
   Get the latest mod_perl sources and documentation from <A
   HREF="http://perl.apache.org">http://perl.apache.org</A> . Try the direct
   download link <A
   HREF="http://perl.apache.org/dist/">http://perl.apache.org/dist/</A> .
   
  -<P><A NAME="anchor9"></A>
  +<P>
   Source/Binary Distributions: <A
   HREF="http://perl.apache.org/distributions.html">http://perl.apache.org/distributions.html</A>
   
   
  -<P><A NAME="anchor10"></A>
  +<P>
   Every Apache project rolls a new tar.gz snapshot of the latest CVS version
   every 6 hours. You can grab the latest mod_perl CVS snapshot from <A
   HREF="http://perl.apache.org/from-cvs/modperl/">http://perl.apache.org/from-cvs/modperl/</A>,
  @@ -133,47 +174,51 @@
   HREF="http://perl.apache.org/from-cvs.">http://perl.apache.org/from-cvs.</A>
   
   
  -<P><A NAME="anchor11"></A>
  +<P>
   RPM: <A HREF="http://perl.apache.org/rpm/">http://perl.apache.org/rpm/</A>
   
  -<P><A NAME="anchor12"></A>
  +<P>
   Debian users will find Perl, Apache and mod_perl are available as .deb
   files on official image CDs or from the Debian web site <A
   HREF="http://www.debian.org">http://www.debian.org</A> . The Debian
   distribution also contains many additional Perl and Apache libraries and
   modules. 
   
  -<P><A NAME="anchor13"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H1><A NAME="Squid_Internet_Object_Cache">Squid - Internet Object Cache</A></H1></CENTER>
  -<P><A NAME="anchor14"></A>
  +<P>
   <A HREF="http://squid.nlanr.net/">http://squid.nlanr.net/</A>
   
  -<P><A NAME="anchor15"></A>
  +<P>
   Squid Linux 2.x Redhat RPMs : <A
   HREF="http://home.earthlink.net/~intrep/linux/">http://home.earthlink.net/~intrep/linux/</A>
   
   
  -<P><A NAME="anchor16"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H1><A NAME="thttpd_tiny_turbo_throttling_H">thttpd - tiny/turbo/throttling HTTP server</A></H1></CENTER>
  -<P><A NAME="anchor17"></A>
  +<P>
   <A
   HREF="http://www.acme.com/software/thttpd/">http://www.acme.com/software/thttpd/</A>
   
   
  -<P><A NAME="anchor18"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H1><A NAME="mod_throttle_access">mod_throttle_access</A></H1></CENTER>
  -<P><A NAME="anchor19"></A>
  +<P>
   <A
   HREF="http://www.fremen.org/apache/mod_throttle_access.html">http://www.fremen.org/apache/mod_throttle_access.html</A>
   
   
  -<P><A NAME="anchor20"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H1><A NAME="mod_proxy_add_forward">mod_proxy_add_forward</A></H1></CENTER>
  -<P><A NAME="anchor21"></A>
  +<P>
   Ask Bjoern Hansen has written the <CODE>mod_proxy_add_forward.c</CODE> module for Apache that sets the <CODE>X-Forwarded-For</CODE> field when doing a ProxyPass, similar to what Squid does. His module is
   available from one of these URLs: <A
   HREF="http://modules.apache.org/search?id=124">http://modules.apache.org/search?id=124</A>,
  @@ -183,60 +228,67 @@
   HREF="http://www.cpan.org/authors/id/ABH/mod_proxy_add_forward.c">http://www.cpan.org/authors/id/ABH/mod_proxy_add_forward.c</A>,
   complete with instructions on how to compile it and whatnot.
   
  -<P><A NAME="anchor22"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H1><A NAME="httperf_webserver_Benchmarking">httperf - webserver Benchmarking tool</A></H1></CENTER>
  -<P><A NAME="anchor23"></A>
  +<P>
   <A
   HREF="http://www.hpl.hp.com/personal/David_Mosberger/httperf.html">http://www.hpl.hp.com/personal/David_Mosberger/httperf.html</A>
   
   
  -<P><A NAME="anchor24"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H1><A NAME="ab_ApacheBench">ab - ApacheBench</A></H1></CENTER>
  -<P><A NAME="anchor25"></A>
  +<P>
   ApacheBench comes with the Apache distribution.
   
  -<P><A NAME="anchor26"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H1><A NAME="High_Availability_and_Load_Balan">High-Availability and Load Balancing Projects</A></H1></CENTER>
  -<P><A NAME="anchor27"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="mod_backhand_Load_Balancing_f">mod_backhand -- Load Balancing for Apache</A></H2></CENTER>
  -<P><A NAME="anchor28"></A>
  +<P>
   <A
   HREF="http://www.backhand.org/mod_backhand/">http://www.backhand.org/mod_backhand/</A>
   
   
  -<P><A NAME="anchor29"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="mod_redundancy">mod_redundancy</A></H2></CENTER>
  -<P><A NAME="anchor30"></A>
  +<P>
   mod_redundancy is a module that works with Apache webserver. It creates a
   Master/Slave Relationship between two physical webservers. The Slave takes
   over the IP-Address(es) and the <CODE>Webservice(s)</CODE> in case of a
   failure of the Master. One of the clues of this solution is, that the
   Redundancy/Failover-Configuration is made inside the Apache-Configfile.
   
  -<P><A NAME="anchor31"></A>
  +<P>
   The product is neither OSS, nor free :(
   
  -<P><A NAME="anchor32"></A>
  +<P>
   The homepage of mod_redundancy is <A
   HREF="http://www.ask-the-guru.com">http://www.ask-the-guru.com</A> .
   
  -<P><A NAME="anchor33"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="High_Availability_Linux_Project">High-Availability Linux Project</A></H2></CENTER>
  -<P><A NAME="anchor34"></A>
  +<P>
   You will find the definitive guide to load balancing techniques at the
   High-Availability Linux Project site -- <A
   HREF="http://www.henge.com/~alanr/ha/">http://www.henge.com/~alanr/ha/</A>
   
  -<P><A NAME="anchor35"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="lbnamed_a_Load_Balancing_Name_">lbnamed - a Load Balancing Name Server Written in Perl</A></H2></CENTER>
  -<P><A NAME="anchor36"></A>
  +<P>
   <A
   HREF="http://www.stanford.edu/~riepel/lbnamed/">http://www.stanford.edu/~riepel/lbnamed/</A>
   <A
  @@ -245,26 +297,29 @@
   HREF="http://www.stanford.edu/~schemers/docs/lbnamed/lbnamed.html">http://www.stanford.edu/~schemers/docs/lbnamed/lbnamed.html</A>
   
   
  -<P><A NAME="anchor37"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="Network_Address_Translation_and_">Network Address Translation and Networks: Virtual Servers (Load Balancing)</A></H2></CENTER>
  -<P><A NAME="anchor38"></A>
  +<P>
   <A
  -HREF="http://www.csn.tu-chemnitz.de/~mha/linux-ip-nat/diplom/node4.html#">http://www.csn.tu-chemnitz.de/~mha/linux-ip-nat/diplom/node4.html#</A>
  -SECTION00043100000000000000
  +HREF="http://www.csn.tu-chemnitz.de/~mha/linux-ip-nat/diplom/node4.html#SECTION00043100000000000000">http://www.csn.tu-chemnitz.de/~mha/linux-ip-nat/diplom/node4.html#SECTION00043100000000000000</A>
  +
   
  -<P><A NAME="anchor39"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="Linux_Virtual_Server_Project">Linux Virtual Server Project</A></H2></CENTER>
  -<P><A NAME="anchor40"></A>
  +<P>
   <A
   HREF="http://www.linuxvirtualserver.org/">http://www.linuxvirtualserver.org/</A>
   
   
  -<P><A NAME="anchor41"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="Efficient_Support_for_P_HTTP_in_">Efficient Support for P-HTTP in Cluster-Based Web Servers</A></H2></CENTER>
  -<P><A NAME="anchor42"></A>
  +<P>
   (with Mohit Aron and Willy Zwaenepoel.) In Proceedings of the USENIX 1999
   Annual Technical Conference, Monterey, CA, June 1999. <A
   HREF="http://www.cs.rice.edu/~druschel/usenix99lard.ps.gz">http://www.cs.rice.edu/~druschel/usenix99lard.ps.gz</A>
  @@ -272,89 +327,120 @@
   HREF="http://www.usenix.org/publications/library/proceedings/usenix99/full_papers/aron/aron_html/index.html">http://www.usenix.org/publications/library/proceedings/usenix99/full_papers/aron/aron_html/index.html</A>
   
   
  -<P><A NAME="anchor43"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="IP_Filter">IP Filter</A></H2></CENTER>
  -<P><A NAME="anchor44"></A>
  +<P>
   The latest ip filter includes some simple load balancing code, that allows
   a round-robin distribution onto several machines via ipnat. That may be a
   simple solution for a few specific load problem. <A
   HREF="http://coombs.anu.edu.au/~avalon/ipf3.4beta3.tgz">http://coombs.anu.edu.au/~avalon/ipf3.4beta3.tgz</A>
   
   
  -<P><A NAME="anchor45"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H1><A NAME="Apache_Request">Apache::Request</A></H1></CENTER>
  -<P><A NAME="anchor46"></A>
  -Get it from CPAN at $CPAN/authors/id/DOUGM/libapreq-x.xx.tar.gz or from <A
  -HREF="http://perl.apache.org/dist/libapreq-x.xx.tar.gz">http://perl.apache.org/dist/libapreq-x.xx.tar.gz</A>
  -. Replace x.xx with the current version.
  +<P>
  +The package name is <EM>libapreq</EM>.
   
  -<P><A NAME="anchor47"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +Get it from your favorite CPAN mirror at $CPAN/authors/id/DOUGM/ or from <A
  +HREF="http://perl.apache.org/dist/.">http://perl.apache.org/dist/.</A>
  +
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H1><A NAME="DataBases">DataBases</A></H1></CENTER>
  -<P><A NAME="anchor48"></A>
  +<P>
   Low-Cost Unix Database Differences <A
   HREF="http://www.toodarkpark.org/computers/dbs.html">http://www.toodarkpark.org/computers/dbs.html</A>
   
   
  -<P><A NAME="anchor49"></A>
  +<P>
   My collection of various links to databases implementations <A
   HREF="http://stason.org/TULARC/webmaster/db.html">http://stason.org/TULARC/webmaster/db.html</A>
   
   
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -	     The <a href="http://www.modperl.com/">
  -	     <B>Writing Apache Modules with Perl and C</B></a>
  -	     book can be purchased online from <a
  -	     href="http://www.ora.com/catalog/wrapmod/">O'Reilly </a>
  -	     and <a
  -	     href="http://www.amazon.com/exec/obidos/ASIN/156592567X/writinapachemodu">
  -	     Amazon.com</a>.
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   
  -	     <HR>
   
  -	     <B>Your corrections of either technical or grammatical
  +    <p>
  +    <div class="navbar">
  +      <a href="help.html">Prev</a>                                 |
  +      <A HREF="index.html"         >Contents</A> |
  +      <A HREF="index.html#search"  >Search</A>   |
  +      <A HREF="index.html#download">Download</A> |
  +      <a href="">Next</a>
  +    </div>
  +    <p>
  +
  +    <table width="60%" align="center">
  +
  +      <tr>
  +	<td>
  +	  <div class="notice">
  +	  <B>Your corrections of the technical and grammatical
   	     errors are very welcome. You are encouraged to help me
  -	     to improve this guide.  If you have something to
  -	     contribute please <A
  -	     HREF="help.html#Contacting_me"> send it
  +	     improve this guide.  If you have something to contribute
  +	     please <A HREF="help.html#Contacting_me"> send it
   	     directly to me</A>.</B>
  +	  </div>
  +	</td>
  +      </tr>
  +
  +      <tr>
  +	<td>
  +	  <div class="ad">
  +	    The <a href="http://www.modperl.com/">
  +	      <B>Writing Apache Modules with Perl and C</B></a>
  +	    book can be purchased online from <a
  +	      href="http://www.ora.com/catalog/wrapmod/">O'Reilly </a>
  +	    and <a
  +	    href="http://www.amazon.com/exec/obidos/ASIN/156592567X/writinapachemodu">
  +	      Amazon.com</a>.
  +	  </div>
  +	</td>
  +      </tr>
  +
  +</table>
  +
  +<center>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
  +<table cellspacing=2 cellpadding=2>
  +
  +<tr align=center valign=top>
  +<td align=center valign=center>
  +
  +<b><font size=-1>Written by <a
  +href="help.html#Contacting_me">Stas Bekman</a>.<br> Last Modified at 05/27/2000
  +</font></b>
  +<br>
  +
  +</td>
  +
  +<td>
  +
  +<a href="http://perl.apache.org"><img src="images/mod_perl2.jpg"  border=0 alt="mod_perl icon" border=0 height=59 width=150></a>
  +<br>
  +
  +</td>
  +
  +<td>
  +
  +<font size=-2>Use of the Camel for Perl is <br>
  +a trademark of <a href="http://www.ora.com">O'Reilly &amp; Associates</a>,<br>
  +and is used by permission. </font> 
  +<br>
   
  -	     <HR>
  +</td>
   
  -	     [    <A HREF="help.html">Prev</A> |      <A HREF="index.html">Main Page</A> ]
  +</tr>
  +</table>
  +</center>
   
  -<CENTER><TABLE CELLSPACING=2 CELLPADDING=2 WIDTH="100%" >
  -<TR ALIGN=CENTER VALIGN=TOP>
  -  <TD ALIGN=CENTER VALIGN=CENTER COLSPAN="3">
  -	     <HR>
  -  </TD>
  -</TR>
  -<TR ALIGN=CENTER VALIGN=TOP>
  -  <TD ALIGN=CENTER VALIGN=CENTER>
  -    <B>
  -      <FONT SIZE=-1>
  -	     Written by <A HREF="help.html#Contacting_me">Stas Bekman</A>.
  -	     <BR>Last Modified at 05/09/2000
  -      </FONT>
  -    </B>
  -  </TD>
  -
  -  <TD>
  -	     <A HREF="http://perl.apache.org"><IMG SRC="images/mod_perl2.jpg" ALT="Mod Perl Icon" BORDER=0 HEIGHT=59 WIDTH=150></A>
  -  </TD>
  -
  -  <TD>
  -    <FONT SIZE=-2>
  -	     Use of the Camel for Perl is <BR>
  -	     a trademark of <A HREF="http://www.ora.com">O'Reilly &amp; Associates</A>,<BR>
  -             and is used by permission. 
  -    </FONT> 
  -  </TD>
  -</TR>
  -</TABLE></CENTER>
  -
  -</BODY>
  -</HTML>
  -	    
  \ No newline at end of file
  +</body>
  +</html>
  
  
  
  1.14      +152 -120  modperl-site/guide/frequent.html
  
  Index: frequent.html
  ===================================================================
  RCS file: /home/cvs/modperl-site/guide/frequent.html,v
  retrieving revision 1.13
  retrieving revision 1.14
  diff -u -r1.13 -r1.14
  --- frequent.html	2000/05/12 22:42:51	1.13
  +++ frequent.html	2000/06/07 22:45:31	1.14
  @@ -1,152 +1,184 @@
   <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
  -<HTML>
  -<HEAD>
  -   <TITLE>mod_perl guide: Frequent mod_perl problems</TITLE>
  -   <META NAME="GENERATOR" CONTENT="Pod2HTML [Perl/Linux]">
  -   <META NAME="Author" CONTENT="Stas Bekman">
  -   <META NAME="Description" CONTENT="All Apache/Perl related information: Hints, Guidelines, Scenarios and Troubleshottings">
  -   <META NAME="keywords" CONTENT="mod_perl modperl perl apache cgi webserver speed  fast guide mod_perl apache guide help info faq mod_perl installation cgi troubleshooting help no sex speedup free open source OSS mod_perl apache guide">
  -</HEAD>
  -     <LINK REL=STYLESHEET TYPE="text/css"
  -        HREF="style.css" TITLE="refstyle">
  -     <style type="text/css">
  -     <!-- 
  -        @import url(style.css);
  -     -->
  -     
  -     </style>
  -<BODY BGCOLOR="white">
  +<html>
  +  <head>
  +   <title>mod_perl guide: Frequent mod_perl problems</title>
  +   <meta name="Author" content="Stas Bekman">
  +   <meta name="Description" content="All Apache/Perl related information: Hints, Guidelines, Scenarios and Troubleshottings">
  +   <meta name="keywords" content="mod_perl modperl perl cgi apache webserver speed fast guide mod_perl apache guide help info faq mod_perl installation cgi troubleshooting help no sex speedup free open source OSS mod_perl apache guide">
  +   <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
  +   <meta name="Classification" content="information">
  +   <link href="style.css" rel=stylesheet type="text/css" title="refstyle">
  +  </head>
  +  <body>
  +
  +    <h1 align=center>
  +      <a href="http://perl.apache.org"><img src="images/mod_perl.gif" alt="Mod Perl Icon" border=0 height=30 width=90 align=left></a>
  +      <a href="http://perl.apache.org"><img src="images/mod_perl.gif" alt="Mod Perl Icon" border=0 height=30 width=90 align=right></a>
  +      Frequent mod_perl problems
  +    </h1>
  +    <hr>
  +    <p>
  +    <div class="navbar">
  +      <a href="performance.html">Prev</a>                                 |
  +      <a href="index.html"         >Contents</a> |
  +      <a href="index.html#search"  >Search</a>   |
  +      <a href="index.html#download">Download</a> |
  +      <a href="troubleshooting.html">Next</a>
  +    </div>
  +    <p>
  +
  +    <div class="toc">
  +      
   <A NAME="toc"></A>
  -<H1 ALIGN=CENTER>
  -<A HREF="http://perl.apache.org"><IMG SRC="images/mod_perl.gif" ALT="Mod Perl Icon" BORDER=0 HEIGHT=30 WIDTH=90 ALIGN=LEFT></A>
  -<A HREF="http://perl.apache.org"><IMG SRC="images/mod_perl.gif" ALT="Mod Perl Icon" BORDER=0 HEIGHT=30 WIDTH=90 ALIGN=RIGHT></A>
  -Frequent mod_perl problems</H1>
  -<HR WIDTH="100%">
  -	    [    <A HREF="performance.html">Prev</A> |      <A HREF="index.html">Main Page</A> | <A HREF="obvious.html">Next</A>      ]<HR><!-- INDEX BEGIN -->
  -<P><B><FONT SIZE=-1>Table of Contents:</FONT></B></P>
  +<P><B>Table of Contents:</B></P>
  +
   <UL>
   
   	<LI><A HREF="#Coverage">Coverage</A>
   	<LI><A HREF="#my_scoped_variable_in_nested_s">my() scoped variable in nested subroutines</A>
   	<LI><A HREF="#Segfaults_caused_by_PerlFreshRes">Segfaults caused by PerlFreshRestart</A>
  -	<LI><A HREF="#Problems_with_DSO">Problems with DSO</A>
   </UL>
  -<!-- INDEX END -->
   
  +    </div>
  +
  +    [ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
   <HR>
  +    <table width="60%" align="center">
  +
  +      <tr>
  +	<td>
  +	  <div class="ad">
  +	    The <a href="http://www.modperl.com/">
  +	      <B>Writing Apache Modules with Perl and C</B></a>
  +	    book can be purchased online from <a
  +	      href="http://www.ora.com/catalog/wrapmod/">O'Reilly </a>
  +	    and <a
  +	    href="http://www.amazon.com/exec/obidos/ASIN/156592567X/writinapachemodu">
  +	      Amazon.com</a>.
  +	  </div>
  +	</td>
  +      </tr>
  +
  +      <tr>
  +	<td>
  +	  <div class="notice">
  +	  <B>Your corrections of the technical and grammatical
  +	     errors are very welcome. You are encouraged to help me
  +	     improve this guide.  If you have something to contribute
  +	     please <A HREF="help.html#Contacting_me"> send it
  +	     directly to me</A>.</B>
  +	  </div>
  +	</td>
  +      </tr>
   
  -	     The <a href="http://www.modperl.com/">
  -	     <B>Writing Apache Modules with Perl and C</B></a>
  -	     book can be purchased online from <a
  -	     href="http://www.ora.com/catalog/wrapmod/">O'Reilly </a>
  -	     and <a
  -	     href="http://www.amazon.com/exec/obidos/ASIN/156592567X/writinapachemodu">
  -	     Amazon.com</a>.
  -
  -	     <HR>
  -
  -	       <B>Your corrections of either technical or grammatical
  -	       errors are very welcome. You are encouraged to help me
  -	       to improve this guide.  If you have something to
  -	       contribute please <A
  -	       HREF="help.html#Contacting_me"> send it
  -	       directly to me</A>.
  -	       </B>
  -	       <HR>
  +</table>
   
  -	      <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<P><A NAME="anchor0"></A>
  +    
  +
  +	    [ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
  +
  +<P>
   <CENTER><H1><A NAME="Coverage">Coverage</A></H1></CENTER>
  -<P><A NAME="anchor1"></A>
  +<P>
   Some problems come up very often on the mailing list. If there is some
   important problem that is being reported frequently on the list which is
   not included below, even if it is found elsewhere in the Guide, please <A HREF="././help.html#Contacting_me">tell me</A>.
   
  -<P><A NAME="anchor2"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H1><A NAME="my_scoped_variable_in_nested_s">my() scoped variable in nested subroutines</A></H1></CENTER>
  -<P><A NAME="anchor3"></A>
  +<P>
   See the section ``<A HREF="././perl.html#my_Scoped_Variable_in_Nested_S">my() Scoped Variable in Nested  Subroutines</A>''.
   
  -<P><A NAME="anchor4"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H1><A NAME="Segfaults_caused_by_PerlFreshRes">Segfaults caused by PerlFreshRestart</A></H1></CENTER>
  -<P><A NAME="anchor5"></A>
  +<P>
   See the section <A HREF="././troubleshooting.html#Evil_things_might_happen_when_us">Evil things might happen when using PerlFreshRestart</A>
   
   
   
  -<P><A NAME="anchor6"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<CENTER><H1><A NAME="Problems_with_DSO">Problems with DSO</A></H1></CENTER>
  -<P><A NAME="anchor7"></A>
  -If you get the mod_perl binary package (i.e. RPM) and it doesn't work, try
  -and get a static install to work. mod_perl DSO does not work reliably. If
  -mod_perl is compiled statically into Apache, it just works, and you don't
  -need to configure the web server with anything, and you'll probably need to
  -comment out lines like ``LoadModule ...''.
  -
  -<P><A NAME="anchor8"></A>
  -META: Not clear on last sentence -- are you saying that if you have a
  -static version people <EM>will</EM> have to comment out lines or they won't? If they will then the text is
  -correct, if the won't then it should be: ``...server with anything, and we
  -shouldn't even need to comment out lines...''
  -
  -<P><A NAME="anchor9"></A>
  -Also see the section`` <A HREF="././strategy.html#mod_perl_Deployment_Overview">mod_perl Deployment Overview</A>''.
  -
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -	     The <a href="http://www.modperl.com/">
  -	     <B>Writing Apache Modules with Perl and C</B></a>
  -	     book can be purchased online from <a
  -	     href="http://www.ora.com/catalog/wrapmod/">O'Reilly </a>
  -	     and <a
  -	     href="http://www.amazon.com/exec/obidos/ASIN/156592567X/writinapachemodu">
  -	     Amazon.com</a>.
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   
  -	     <HR>
   
  -	     <B>Your corrections of either technical or grammatical
  +    <p>
  +    <div class="navbar">
  +      <a href="performance.html">Prev</a>                                 |
  +      <A HREF="index.html"         >Contents</A> |
  +      <A HREF="index.html#search"  >Search</A>   |
  +      <A HREF="index.html#download">Download</A> |
  +      <a href="troubleshooting.html">Next</a>
  +    </div>
  +    <p>
  +
  +    <table width="60%" align="center">
  +
  +      <tr>
  +	<td>
  +	  <div class="notice">
  +	  <B>Your corrections of the technical and grammatical
   	     errors are very welcome. You are encouraged to help me
  -	     to improve this guide.  If you have something to
  -	     contribute please <A
  -	     HREF="help.html#Contacting_me"> send it
  +	     improve this guide.  If you have something to contribute
  +	     please <A HREF="help.html#Contacting_me"> send it
   	     directly to me</A>.</B>
  +	  </div>
  +	</td>
  +      </tr>
  +
  +      <tr>
  +	<td>
  +	  <div class="ad">
  +	    The <a href="http://www.modperl.com/">
  +	      <B>Writing Apache Modules with Perl and C</B></a>
  +	    book can be purchased online from <a
  +	      href="http://www.ora.com/catalog/wrapmod/">O'Reilly </a>
  +	    and <a
  +	    href="http://www.amazon.com/exec/obidos/ASIN/156592567X/writinapachemodu">
  +	      Amazon.com</a>.
  +	  </div>
  +	</td>
  +      </tr>
  +
  +</table>
  +
  +<center>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
  +<table cellspacing=2 cellpadding=2>
  +
  +<tr align=center valign=top>
  +<td align=center valign=center>
  +
  +<b><font size=-1>Written by <a
  +href="help.html#Contacting_me">Stas Bekman</a>.<br> Last Modified at 05/27/2000
  +</font></b>
  +<br>
  +
  +</td>
  +
  +<td>
  +
  +<a href="http://perl.apache.org"><img src="images/mod_perl2.jpg"  border=0 alt="mod_perl icon" border=0 height=59 width=150></a>
  +<br>
  +
  +</td>
  +
  +<td>
  +
  +<font size=-2>Use of the Camel for Perl is <br>
  +a trademark of <a href="http://www.ora.com">O'Reilly &amp; Associates</a>,<br>
  +and is used by permission. </font> 
  +<br>
   
  -	     <HR>
  +</td>
   
  -	     [    <A HREF="performance.html">Prev</A> |      <A HREF="index.html">Main Page</A> | <A HREF="obvious.html">Next</A>      ]
  +</tr>
  +</table>
  +</center>
   
  -<CENTER><TABLE CELLSPACING=2 CELLPADDING=2 WIDTH="100%" >
  -<TR ALIGN=CENTER VALIGN=TOP>
  -  <TD ALIGN=CENTER VALIGN=CENTER COLSPAN="3">
  -	     <HR>
  -  </TD>
  -</TR>
  -<TR ALIGN=CENTER VALIGN=TOP>
  -  <TD ALIGN=CENTER VALIGN=CENTER>
  -    <B>
  -      <FONT SIZE=-1>
  -	     Written by <A HREF="help.html#Contacting_me">Stas Bekman</A>.
  -	     <BR>Last Modified at 04/01/2000
  -      </FONT>
  -    </B>
  -  </TD>
  -
  -  <TD>
  -	     <A HREF="http://perl.apache.org"><IMG SRC="images/mod_perl2.jpg" ALT="Mod Perl Icon" BORDER=0 HEIGHT=59 WIDTH=150></A>
  -  </TD>
  -
  -  <TD>
  -    <FONT SIZE=-2>
  -	     Use of the Camel for Perl is <BR>
  -	     a trademark of <A HREF="http://www.ora.com">O'Reilly &amp; Associates</A>,<BR>
  -             and is used by permission. 
  -    </FONT> 
  -  </TD>
  -</TR>
  -</TABLE></CENTER>
  -
  -</BODY>
  -</HTML>
  -	    
  \ No newline at end of file
  +</body>
  +</html>
  
  
  
  1.10      +388 -263  modperl-site/guide/hardware.html
  
  Index: hardware.html
  ===================================================================
  RCS file: /home/cvs/modperl-site/guide/hardware.html,v
  retrieving revision 1.9
  retrieving revision 1.10
  diff -u -r1.9 -r1.10
  --- hardware.html	2000/05/12 22:42:51	1.9
  +++ hardware.html	2000/06/07 22:45:31	1.10
  @@ -1,29 +1,37 @@
   <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
  -<HTML>
  -<HEAD>
  -   <TITLE>mod_perl guide: Choosing an Operating System and Hardware</TITLE>
  -   <META NAME="GENERATOR" CONTENT="Pod2HTML [Perl/Linux]">
  -   <META NAME="Author" CONTENT="Stas Bekman">
  -   <META NAME="Description" CONTENT="All Apache/Perl related information: Hints, Guidelines, Scenarios and Troubleshottings">
  -   <META NAME="keywords" CONTENT="mod_perl modperl perl apache cgi webserver speed  fast guide mod_perl apache guide help info faq mod_perl installation cgi troubleshooting help no sex speedup free open source OSS mod_perl apache guide">
  -</HEAD>
  -     <LINK REL=STYLESHEET TYPE="text/css"
  -        HREF="style.css" TITLE="refstyle">
  -     <style type="text/css">
  -     <!-- 
  -        @import url(style.css);
  -     -->
  -     
  -     </style>
  -<BODY BGCOLOR="white">
  +<html>
  +  <head>
  +   <title>mod_perl guide: Choosing an Operating System and Hardware</title>
  +   <meta name="Author" content="Stas Bekman">
  +   <meta name="Description" content="All Apache/Perl related information: Hints, Guidelines, Scenarios and Troubleshottings">
  +   <meta name="keywords" content="mod_perl modperl perl cgi apache webserver speed fast guide mod_perl apache guide help info faq mod_perl installation cgi troubleshooting help no sex speedup free open source OSS mod_perl apache guide">
  +   <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
  +   <meta name="Classification" content="information">
  +   <link href="style.css" rel=stylesheet type="text/css" title="refstyle">
  +  </head>
  +  <body>
  +
  +    <h1 align=center>
  +      <a href="http://perl.apache.org"><img src="images/mod_perl.gif" alt="Mod Perl Icon" border=0 height=30 width=90 align=left></a>
  +      <a href="http://perl.apache.org"><img src="images/mod_perl.gif" alt="Mod Perl Icon" border=0 height=30 width=90 align=right></a>
  +      Choosing an Operating System and Hardware
  +    </h1>
  +    <hr>
  +    <p>
  +    <div class="navbar">
  +      <a href="snippets.html">Prev</a>                                 |
  +      <a href="index.html"         >Contents</a> |
  +      <a href="index.html#search"  >Search</a>   |
  +      <a href="index.html#download">Download</a> |
  +      <a href="advocacy.html">Next</a>
  +    </div>
  +    <p>
  +
  +    <div class="toc">
  +      
   <A NAME="toc"></A>
  -<H1 ALIGN=CENTER>
  -<A HREF="http://perl.apache.org"><IMG SRC="images/mod_perl.gif" ALT="Mod Perl Icon" BORDER=0 HEIGHT=30 WIDTH=90 ALIGN=LEFT></A>
  -<A HREF="http://perl.apache.org"><IMG SRC="images/mod_perl.gif" ALT="Mod Perl Icon" BORDER=0 HEIGHT=30 WIDTH=90 ALIGN=RIGHT></A>
  -Choosing an Operating System and Hardware</H1>
  -<HR WIDTH="100%">
  -	    [    <A HREF="snippets.html">Prev</A> |      <A HREF="index.html">Main Page</A> | <A HREF="advocacy.html">Next</A>      ]<HR><!-- INDEX BEGIN -->
  -<P><B><FONT SIZE=-1>Table of Contents:</FONT></B></P>
  +<P><B>Table of Contents:</B></P>
  +
   <UL>
   
   	<LI><A HREF="#Is_it_important_">Is it important?</A>
  @@ -35,52 +43,76 @@
   		<LI><A HREF="#Memory_Leaks">Memory Leaks</A>
   		<LI><A HREF="#Sharing_Memory">Sharing Memory</A>
   		<LI><A HREF="#Cost_and_Support">Cost and Support</A>
  -		<LI><A HREF="#Discontinued_products">Discontinued products</A>
  +		<LI><A HREF="#Discontinued_Products">Discontinued Products</A>
   		<LI><A HREF="#OS_Releases">OS Releases</A>
   	</UL>
   
   	<LI><A HREF="#Choosing_Hardware">Choosing Hardware</A>
   	<UL>
  +
  +		<LI><A HREF="#Machine_Strength_Demands_Accordi">Machine Strength Demands According to Expected Site Traffic</A>
  +		<UL>
  +
  +			<LI><A HREF="#Single_Strong_Machine_vs_Many_We">Single Strong Machine vs Many Weaker Machines</A>
  +		</UL>
   
  -		<LI><A HREF="#Expected_site_traffic">Expected site traffic</A>
  -		<LI><A HREF="#Cash">Cash</A>
   		<LI><A HREF="#Internet_Connection">Internet Connection</A>
  -		<LI><A HREF="#I_O_performance">I/O performance</A>
  +		<LI><A HREF="#I_O_Performance">I/O Performance</A>
   		<LI><A HREF="#Memory">Memory</A>
   		<LI><A HREF="#CPU">CPU</A>
   		<LI><A HREF="#Bottlenecks">Bottlenecks</A>
  -		<LI><A HREF="#Tuning">Tuning</A>
  +		<UL>
  +
  +			<LI><A HREF="#Solving_Hardware_Requirement_Con">Solving Hardware Requirement Conflicts</A>
  +		</UL>
  +
   		<LI><A HREF="#Conclusion">Conclusion</A>
   	</UL>
   
   </UL>
  -<!-- INDEX END -->
   
  +    </div>
  +
  +    [ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
   <HR>
  +    <table width="60%" align="center">
   
  -	     The <a href="http://www.modperl.com/">
  -	     <B>Writing Apache Modules with Perl and C</B></a>
  -	     book can be purchased online from <a
  -	     href="http://www.ora.com/catalog/wrapmod/">O'Reilly </a>
  -	     and <a
  -	     href="http://www.amazon.com/exec/obidos/ASIN/156592567X/writinapachemodu">
  -	     Amazon.com</a>.
  -
  -	     <HR>
  -
  -	       <B>Your corrections of either technical or grammatical
  -	       errors are very welcome. You are encouraged to help me
  -	       to improve this guide.  If you have something to
  -	       contribute please <A
  -	       HREF="help.html#Contacting_me"> send it
  -	       directly to me</A>.
  -	       </B>
  -	       <HR>
  +      <tr>
  +	<td>
  +	  <div class="ad">
  +	    The <a href="http://www.modperl.com/">
  +	      <B>Writing Apache Modules with Perl and C</B></a>
  +	    book can be purchased online from <a
  +	      href="http://www.ora.com/catalog/wrapmod/">O'Reilly </a>
  +	    and <a
  +	    href="http://www.amazon.com/exec/obidos/ASIN/156592567X/writinapachemodu">
  +	      Amazon.com</a>.
  +	  </div>
  +	</td>
  +      </tr>
  +
  +      <tr>
  +	<td>
  +	  <div class="notice">
  +	  <B>Your corrections of the technical and grammatical
  +	     errors are very welcome. You are encouraged to help me
  +	     improve this guide.  If you have something to contribute
  +	     please <A HREF="help.html#Contacting_me"> send it
  +	     directly to me</A>.</B>
  +	  </div>
  +	</td>
  +      </tr>
  +
  +</table>
  +
  +    
  +
  +	    [ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   
  -	      <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<P><A NAME="anchor0"></A>
  +<P>
   <CENTER><H1><A NAME="Is_it_important_">Is it important?</A></H1></CENTER>
  -<P><A NAME="anchor1"></A>
  +<P>
   Before you use the techniques in this Guide to tune servers and write code
   you need to consider the demands which will be placed on the hardware and
   the operating system. There is no point in investing a lot of time and
  @@ -88,27 +120,28 @@
   performance is poor because you did not choose a suitable platform in the
   first place.
   
  -<P><A NAME="anchor2"></A>
  +<P>
   While the tips below could apply to many web servers, they are aimed
  -primarily at administrators of mod_perl-enabled webservers.
  +primarily at administrators of mod_perl enabled Apache server.
   
  -<P><A NAME="anchor3"></A>
  +<P>
   Because hardware platforms and operating systems are developing rapidly
   (even while you are reading this Guide), this discussion must be in general
   terms.
   
  -<P><A NAME="anchor4"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H1><A NAME="Choosing_an_Operating_System">Choosing an Operating System</A></H1></CENTER>
  -<P><A NAME="anchor5"></A>
  +<P>
   First let's talk about Operating Systems (OSs).
   
  -<P><A NAME="anchor6"></A>
  +<P>
   Most of the time I prefer to use Linux or something from the
   <CODE>*BSD</CODE> family. Although I am personally a Linux devotee, I do
   not want to start yet another OS war.
   
  -<P><A NAME="anchor7"></A>
  +<P>
   I will try to talk about what characteristics and features you should be
   looking for to support an Apache/mod_perl server, then when you know what
   you want from your OS, you can go out and find it. Visit the Web sites of
  @@ -118,40 +151,44 @@
   - <A HREF="http://egroups.com">http://egroups.com</A> are good examples. I
   will leave this fan research to the reader.
   
  -<P><A NAME="anchor8"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="Stability_and_Robustness">Stability and Robustness</A></H2></CENTER>
  -<P><A NAME="anchor9"></A>
  +<P>
   Probably the most important features in an OS are stability and robustness.
   You are in an Internet business. You do not keep normal 9am to 5pm working
   hours like many conventional businesses you know. You are open 24 hours a
   day. You cannot afford to be off-line, for your customers will go shop at
   another service like yours (unless you have a monopoly :). If the OS of
   your choice crashes every day, first do a little investigation. There might
  -be a simple reason which you can find and fix. Common problems for which
  -you cannot blame the OS are a runaway server that eats up all the memory
  -and disk space.
  +be a simple reason which you can find and fix. There are OSs which won't
  +work unless you reboot them twice a day. You don't want to use the OS of
  +this kind, no matter how good the OS' vendor sales department. Do not
  +follow flushy advertisments, follow developers advices instead.
   
  -<P><A NAME="anchor10"></A>
  +<P>
   Generally, people who have used the OS for some time can tell you a lot
   about its stability. Ask them. Try to find people who are doing similar
   things to what you are planning to do, they may even be using the same
   software. There are often compatibility issues to resolve. You may need to
   become familiar with patching and compiling your OS. It's easy.
   
  -<P><A NAME="anchor11"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="Memory_Management">Memory Management</A></H2></CENTER>
  -<P><A NAME="anchor12"></A>
  +<P>
   You want an OS with a good memory management, some OSs are well known as
   memory hogs. The same code can use twice as much memory on one OS compared
   to another. If the size of the mod_perl process is 10Mb and you have tens
   of these running, it definitely adds up!
   
  -<P><A NAME="anchor13"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="Memory_Leaks">Memory Leaks</A></H2></CENTER>
  -<P><A NAME="anchor14"></A>
  +<P>
   Some OSs and/or their libraries (e.g. C runtime libraries) suffer from
   memory leaks. A leak is when some process requests a chunk of memory for
   temporary storage, but then does not subsequently release it. The chunk of
  @@ -162,20 +199,22 @@
   our code can be the cause of the memory leaks as well (check out the <CODE>Apache::Leak</CODE> module on CPAN). Certainly, we can reduce the number of requests to be
   served over the process' life, but that can degrade performance.
   
  -<P><A NAME="anchor15"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="Sharing_Memory">Sharing Memory</A></H2></CENTER>
  -<P><A NAME="anchor16"></A>
  +<P>
   We want an OS with good memory sharing capabilities. As we have seen, if we
   preload the modules and scripts at server startup, they are shared between
   the spawned children (at least for a part of a process' life - memory pages
   can become ``dirty'' and cease to be shared). This feature can reduce
   memory consumption a lot!
   
  -<P><A NAME="anchor17"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="Cost_and_Support">Cost and Support</A></H2></CENTER>
  -<P><A NAME="anchor18"></A>
  +<P>
   If we are in a big business we probably do not mind paying another
   <CODE>$1000</CODE> for some fancy OS with bundled support. But if our
   resources are low, we will look for cheaper and free OSs. Free does not
  @@ -190,29 +229,37 @@
   was there, I was touched by that spirit and I am keen to keep that spirit
   alive.
   
  -<P><A NAME="anchor19"></A>
  +<P>
   But, let's get back to our world. We are living in material world, and our
  -bosses pay us to keep the systems running. So if we feel that we cannot
  -provide the support ourselves and we do not trust the available free
  -resources, we must pay for an OS backed by a company, and blame them for
  -any problem. Our boss wants to be able to sue someone if the project has a
  +bosses pay us to keep the systems running. So if you feel that you cannot
  +provide the support yourself and you do not trust the available free
  +resources, you must pay for an OS backed by a company, and blame them for
  +any problem. Your boss wants to be able to sue someone if the project has a
   problem caused by the external product that is being used in the project.
  -If we buy a product and the company selling it claims support, we have
  -someone to sue. If we go with Open Source and it fails we do not have
  -someone to sue, so we will probably just get fired.
  +If you buy a product and the company selling it claims support, you have
  +someone to sue or at least to put the blame on.
   
  -<P><A NAME="anchor20"></A>
  +<P>
  +If we go with Open Source and it fails we do not have someone to sue...
  +wrong--in the last years many companies have realized how good the Open
  +Source products are and started to provide an official support for these
  +products. So your boss cannot just dismiss your suggestion of using an Open
  +Source Operating System. You can get a paid support just like with any
  +other commercial OS vendor.
  +
  +<P>
   Also remember that the less money you spend on OS and Software, the more
   you will be able to spend on faster and stronger hardware.
   
  -<P><A NAME="anchor21"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<CENTER><H2><A NAME="Discontinued_products">Discontinued products</A></H2></CENTER>
  -<P><A NAME="anchor22"></A>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
  +<CENTER><H2><A NAME="Discontinued_Products">Discontinued Products</A></H2></CENTER>
  +<P>
   The OSs in this hazard group tend to be developed by a single company or
   organization.
   
  -<P><A NAME="anchor23"></A>
  +<P>
   You might find yourself in a position where you have invested a lot of time
   and money into developing some proprietary software that is bundled with
   the OS you chose (say writing a mod_perl handler which takes advantage of
  @@ -222,10 +269,10 @@
   your beloved OS goes bankrupt (not unlikely nowadays), or they produce a
   newer incompatible version and they will not support the old one (happens
   all the time). You are stuck with their early masterpiece, no support and
  -no source! What are you going to do? Invest more money into porting the
  -software to another OS...
  +no source code! What are you going to do? Invest more money into porting
  +the software to another OS...
   
  -<P><A NAME="anchor24"></A>
  +<P>
   Everyone can be hit by this mini-disaster so it is better to check the
   background of the company when making your choice. Even so you never know
   what will happen tomorrow - in 1980, a company called Tektronix did
  @@ -237,7 +284,7 @@
   software. It didn't take long, it works fine, and he's still using it 18
   years later.
   
  -<P><A NAME="anchor25"></A>
  +<P>
   Free and Open Source OSs are probably less susceptible to this kind of
   problem. Development is usually distributed between many companies and
   developers, so if a person who developed a really important part of the
  @@ -250,15 +297,16 @@
   of notice of the forthcoming changes so that you have time to plan for
   them.
   
  -<P><A NAME="anchor26"></A>
  +<P>
   Of course with the Open Source OSs you can have the source! So you can
   always have a go yourself, but do not under-estimate the amounts of work
   involved. There are many, many man-years of work in an OS.
   
  -<P><A NAME="anchor27"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="OS_Releases">OS Releases</A></H2></CENTER>
  -<P><A NAME="anchor28"></A>
  +<P>
   Actively developed OSs generally try to keep pace with the latest
   technology developments, and continually optimize the kernel and other
   parts of the OS to become better and faster. Nowadays, Internet and
  @@ -267,27 +315,28 @@
   expensive hardware upgrade. Also, remember that when you buy new hardware,
   chances are that the latest software will make the most of it.
   
  -<P><A NAME="anchor29"></A>
  +<P>
   If a new product supports an old one by virtue of backwards compatibility
   with previous products of the same family, you might not reap all the
   benefits of the new product's features. Perhaps you get almost the same
   functionality for much less money if you were to buy an older model of the
   same product.
   
  -<P><A NAME="anchor30"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H1><A NAME="Choosing_Hardware">Choosing Hardware</A></H1></CENTER>
  -<P><A NAME="anchor31"></A>
  +<P>
   Sometimes the most expensive machine is not the one which provides the best
   performance. Your demands on the platform hardware are based on many
   aspects and affect many components. Let's discuss some of them.
   
  -<P><A NAME="anchor32"></A>
  +<P>
   In the discussion we use terms that may be unfamiliar to some readers:
   
   <UL>
   <P><LI>
  -<P><A NAME="anchor33"></A>
  +<P>
   Cluster - a group of machines connected together to perform one big or many
   small computational tasks in a reasonable time. Clustering can also be used
   to provide 'fail-over' where if one machine fails its processes are
  @@ -297,7 +346,7 @@
   requests to the machine that was taken down.
   
   <P><LI>
  -<P><A NAME="anchor34"></A>
  +<P>
   Load balancing - users are given the name of one of your machines but
   perhaps it cannot stand the heavy load. You can use a clustering approach
   to distribute the load over a number of machines. The central server, which
  @@ -306,23 +355,28 @@
   central server also collects the results and returns them to the users. You
   can get the advantages of clustering too.
   
  -<P><A NAME="anchor35"></A>
  +<P>
   There are many load balancing techniques. (See <A HREF="././download.html#High_Availability_Linux_Project">High-Availability Linux Project</A> for more info.)
   
   <P><LI>
  -<P><A NAME="anchor36"></A>
  -NIC - Network Interface Card.
  +<P>
  +NIC - Network Interface Card. A hardware component that allows to connect
  +your machine to the network. It performs packets sending and receiving,
  +newer cards can encrypt and decrypt packets and perform digital signing and
  +verifying of the such. These are coming in different speeds categories
  +varying from 10Mbps to 10Gbps and faster. The most used type of the NIC
  +card is the one that implements the Ethernet networking protocol.
   
   <P><LI>
  -<P><A NAME="anchor37"></A>
  +<P>
   RAM - Random Access Memory. It's the memory that you have in your computer.
  -(16Mb, 64Mb, 256Mb, etc.)
  +(Comes in units of 8Mb, 16Mb, 64Mb, 256Mb, etc.)
   
   <P><LI>
  -<P><A NAME="anchor38"></A>
  +<P>
   RAID - Redundant Array of Inexpensive Disks.
   
  -<P><A NAME="anchor39"></A>
  +<P>
   An array of physical disks, usually treated by the operating system as one
   single disk, and often forced to appear that way by the hardware. The
   reason for using RAID is often simply to achieve a high data transfer rate,
  @@ -336,10 +390,11 @@
   Parallel-Processing-HOWTO.
   
   </UL>
  -<P><A NAME="anchor40"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<CENTER><H2><A NAME="Expected_site_traffic">Expected site traffic</A></H2></CENTER>
  -<P><A NAME="anchor41"></A>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
  +<CENTER><H2><A NAME="Machine_Strength_Demands_Accordi">Machine Strength Demands According to Expected Site Traffic</A></H2></CENTER>
  +<P>
   If you are building a fan site and you want to amaze your friends with a
   mod_perl guest book, any old 486 machine could do it. If you are in a
   serious business, it is very important to build a scalable server. If your
  @@ -353,50 +408,49 @@
   hardware and OSs that can talk to other machines and become a part of a
   cluster.
   
  -<P><A NAME="anchor42"></A>
  +<P>
   On the other hand if you prepare for a lot of traffic and buy a monster to
   do the work for you, what happens if your service doesn't prove to be as
   successful as you thought it would be? Then you've spent too much money,
   and meanwhile faster processors and other hardware components have been
  -released, so you lose again.
  +released, so you lose.
   
  -<P><A NAME="anchor43"></A>
  +<P>
   Wisdom and prophecy, that's all it takes :)
   
  -<P><A NAME="anchor44"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<CENTER><H2><A NAME="Cash">Cash</A></H2></CENTER>
  -<P><A NAME="anchor45"></A>
  -Everybody knows that Internet is a cash hole. What you throw in hardly ever
  -comes back. This is not always true, but there is a lot of wisdom in these
  -words. Although you know that you are going to have to invest money to
  -build a decent service, you will always want it to be cheaper! Remember
  -that a four year old processor is still very powerful.
  -
  -<P><A NAME="anchor46"></A>
  -If you really need a lot of power do not want to have a single powerful
  -machine, then (unless you have money to throw away) think about clustering
  -and load balancing. For a given amount of money you can probably buy 10 old
  -but very cheap machines and have a 8 times more power, or one single new
  -machine. Why is that? Because generally the performance improvement on a
  -new machine is marginal while, the price is much higher. Ten machines will
  -do faster disk I/O than one single machine, even if the new disk is quite a
  -bit faster. Yes, you have more administration overhead, but there is a
  -chance you will have it anyway, for in a short time the new machine you
  -have just bought might not stand the load. Then you will have to purchase
  -more equipment and think about how to implement load balancing and file
  -system distribution anyway.
  -
  -<P><A NAME="anchor47"></A>
  -Why I am so convinced? Look at the busiest services on the Internet: search
  -engines, email servers and the like -- most of them use a clustering
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
  +<CENTER><H3><A NAME="Single_Strong_Machine_vs_Many_We">Single Strong Machine vs Many Weaker Machines</A></H3></CENTER>
  +<P>
  +Let's start with a claim that a four years old processor is still very
  +powerful and can be put to a good use. Now let's say that for a given
  +amount of money you can probably buy either one new very strong machine or
  +about ten older but very cheap machines. I claim that with ten old machines
  +connected into a cluster and by deploying load balancing you will be able
  +to serve about five times more requests than with one single new machine.
  +
  +<P>
  +Why is that? Because generally the performance improvement on a new machine
  +is marginal while the price is much higher. Ten machines will do faster
  +disk I/O than one single machine, even if the new disk is quite a bit
  +faster. Yes, you have more administration overhead, but there is a chance
  +you will have it anyway, for in a short time the new machine you have just
  +bought might not stand the load. Then you will have to purchase more
  +equipment and think about how to implement load balancing and web server
  +file system distribution anyway.
  +
  +<P>
  +Why I'm so convinced? Look at the busiest services on the Internet: search
  +engines, web-email servers and the like -- most of them use a clustering
   approach. You may not always notice it, because they hide the real
   implementation behind proxy servers.
   
  -<P><A NAME="anchor48"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="Internet_Connection">Internet Connection</A></H2></CENTER>
  -<P><A NAME="anchor49"></A>
  +<P>
   You have the best hardware you can get, but the service is still crawling.
   Make sure you have a fast Internet connection. Not as fast as your ISP
   claims it to be, but fast as it should be. The ISP might have a very good
  @@ -405,31 +459,52 @@
   throughput will suffer. Think about a dedicated connection and make sure it
   is truly dedicated. Don't trust the ISP, check it!
   
  -<P><A NAME="anchor50"></A>
  +<P>
   The idea of having a connection to <STRONG>The Internet</STRONG> is a little misleading. Many Web hosting and co-location companies have
   large amounts of bandwidth, but still have poor connectivity. The public
   exchanges, such as MAE-East and MAE-West, frequently become overloaded, yet
   many ISPs depend on these exchanges.
   
  -<P><A NAME="anchor51"></A>
  +<P>
   Private peering means that providers can exchange traffic much quicker.
   
  -<P><A NAME="anchor52"></A>
  +<P>
   Also, if your Web site is of global interest, check that the ISP has good
   global connectivity. If the Web site is going to be visited mostly by
   people in a certain country or region, your server should probably be
   located there.
   
  -<P><A NAME="anchor53"></A>
  +<P>
   Bad connectivity can directly influence your machine's performance. Here is
   a story one of the developers told on the mod_perl mailing list:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor54"></A>
  -<PRE>  What relationship has 10% packet loss on one upstream provider got
  -  to do with machine memory ?
  -</PRE>
  -<P><A NAME="anchor55"></A>
  -<PRE>  Yes.. a lot. For a nightmare week, the box was located downstream of
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  What relationship has 10% packet loss on one upstream provider got
  +  to do with machine memory ?</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  Yes.. a lot. For a nightmare week, the box was located downstream of
     a provider who was struggling with some serious bandwidth problems
     of his own... people were connecting to the site via this link, and
     packet loss was such that retransmits and tcp stalls were keeping
  @@ -438,50 +513,65 @@
     stuck at 1k/sec or stalled out...  people would press stop and
     refresh, httpds would take 300 seconds to timeout on writes to
     no-one.. it was a nightmare.  Those problems didn't go away till I
  -  moved the box to a place closer to some decent backbones.
  -</PRE>
  -<P><A NAME="anchor56"></A>
  -<PRE>  Note that with a proxy, this only keeps a lightweight httpd tied up,
  +  moved the box to a place closer to some decent backbones.</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  Note that with a proxy, this only keeps a lightweight httpd tied up,
     assuming the page is small enough to fit in the buffers.  If you are
     a busy internet site you always have some slow clients.  This is a
  -  difficult thing to simulate in benchmark testing, though.
  -</PRE>
  -<P><A NAME="anchor57"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<CENTER><H2><A NAME="I_O_performance">I/O performance</A></H2></CENTER>
  -<P><A NAME="anchor58"></A>
  -If your service is I/O bound (does a lot of read/write operations to disk
  --- remember that relational databases are sitting on disk as well), you
  -need a very fast disk. So you should not spend the money on Video card and
  -monitor! A cheap card and a 14`` monochrome monitor are perfectly adequate
  -for a Web server, you will probably access it by telnet or ssh-ed most of
  -the time. But look for disks with the best price/performance ratio. Of
  +  difficult thing to simulate in benchmark testing, though.</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
  +<CENTER><H2><A NAME="I_O_Performance">I/O Performance</A></H2></CENTER>
  +<P>
  +If your service is I/O bound (does a lot of read/write operations to disk)
  +you need a very fast disk, especially if the you need a relational
  +database, which are the main I/O stream creaters. So you should not spend
  +the money on Video card and monitor! A cheap card and a 14`` monochrome
  +monitor are perfectly adequate for a Web server, you will probably access
  +it by <CODE>telnet</CODE> or <CODE>ssh</CODE> most of the time. Look for disks with the best price/performance ratio. Of
   course, ask around and avoid disks that have a reputation for headcrashes
   and other disasters.
   
  -<P><A NAME="anchor59"></A>
  +<P>
   You must think about RAID or similar systems if you have an enormous data
   set to serve (what is an enormous data set nowadays? Gigabytes, terabytes?)
  -or you expect a lot of traffic.
  +or you expect a really big web traffic.
   
  -<P><A NAME="anchor60"></A>
  -Ok, we have a fast disk, what's next? You need a fast disk controller.
  +<P>
  +Ok, you have a fast disk, what's next? You need a fast disk controller.
   There may be one embedded on your computer's motherboard. If the controller
   is not fast enough you should buy a faster one. Don't forget that it may be
   necessary to disable the original controller.
   
  -<P><A NAME="anchor61"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="Memory">Memory</A></H2></CENTER>
  -<P><A NAME="anchor62"></A>
  +<P>
   Memory should be well tested. Many memory test programs are practically
  -useless. Running a busy Linux system for a few weeks without ever shutting
  -it down is a pretty good memory test. I have seen RAM which gave no trouble
  -on DOS and Windows systems cause all kinds of crashes under Linux. Once you
  -have tested your RAM, don't mess about with it unless you have to. If you
  -increase the amount of RAM on a well-tested box, use well-tested RAM.
  +useless. Running a busy system for a few weeks without ever shutting it
  +down is a pretty good memory test. If you increase the amount of RAM on a
  +well-tested box, use well-tested RAM.
   
  -<P><A NAME="anchor63"></A>
  +<P>
   How much RAM do you need? Nowadays, the chances are that you will hear:
   ``Memory is cheap, the more you buy the better''. But how much is enough?
   The answer is pretty straightforward: <EM>you do not want your
  @@ -496,16 +586,16 @@
   there is, the more often this scenario arises. Worse, you can exhaust swap
   space as well, and then your troubles really start...
   
  -<P><A NAME="anchor64"></A>
  +<P>
   How do you make a decision? You know the highest rate at which your server
   expects to serve pages and how long it takes on average to serve one. Now
   you can calculate how many server processes you need. If you know the
   maximum size your servers can grow to, you know how much memory you need.
   If your OS supports <A HREF="././hardware.html#Sharing_Memory">memory sharing</A>, you can make best use of this feature by preloading the modules and
  -scripts at server startup, and so you will probably need less memory than
  -you have calculated.
  +scripts at server startup, and so you will need less memory than you have
  +calculated.
   
  -<P><A NAME="anchor65"></A>
  +<P>
   Do not forget that other essential system processes need memory as well, so
   you should plan not only for the Web server, but also take into account the
   other players. Remember that requests can be queued, so you can afford to
  @@ -518,10 +608,11 @@
   HREF="http://slashdot.org">http://slashdot.org</A> ). If you are about to
   announce something cool, be aware of the possible consequences.
   
  -<P><A NAME="anchor66"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="CPU">CPU</A></H2></CENTER>
  -<P><A NAME="anchor67"></A>
  +<P>
   Make sure that the CPU is operating within its specifications. Many boxes
   are shipped with incorrect settings for CPU clock speed, power supply
   voltage etc. Sometimes a cooling fan is not fitted. It may be ineffective
  @@ -530,110 +621,144 @@
   things to happen. Some CPUs are known to have bugs which can be serious in
   certain circumstances. Try not to get one of them.
   
  -<P><A NAME="anchor68"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="Bottlenecks">Bottlenecks</A></H2></CENTER>
  -<P><A NAME="anchor69"></A>
  +<P>
   You might use the most expensive components, but still get bad performance.
   Why? Let me introduce an annoying word: bottleneck.
   
  -<P><A NAME="anchor70"></A>
  +<P>
   A machine is an aggregate of many components. Almost any one of them may
   become a bottleneck.
   
  -<P><A NAME="anchor71"></A>
  +<P>
   If you have a fast processor but a small amount of RAM, the RAM will
   probably be the bottleneck. The processor will be under-utilized, usually
   it will be waiting for the kernel to swap the memory pages in and out,
   because memory is too small to hold the busiest pages.
   
  -<P><A NAME="anchor72"></A>
  +<P>
   If you have a lot of memory, a fast processor, a fast disk, but a slow disk
   controller, the disk controller will be the bottleneck. The performance
   will still be bad, and you will have wasted money.
   
  -<P><A NAME="anchor73"></A>
  +<P>
   Use a fast NIC that does not create a bottleneck. They are cheap. If the
   NIC is slow, the whole service is slow. This is a most important component,
   since webservers are much more often network-bound than they are
   disk-bound!
   
  -<P><A NAME="anchor74"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<CENTER><H2><A NAME="Tuning">Tuning</A></H2></CENTER>
  -<P><A NAME="anchor75"></A>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
  +<CENTER><H3><A NAME="Solving_Hardware_Requirement_Con">Solving Hardware Requirement Conflicts</A></H3></CENTER>
  +<P>
   It may happen that the combination of software components which you find
   yourself using gives rise to conflicting requirements for the optimization
   of tuning parameters. If you can separate the components onto different
   machines you may find that this approach (a kind of clustering) solves the
   problem, at much less cost than buying faster hardware, because you can
  -tune the machines individually to suit the jobs they have to do. For
  -example, one machine might need a lot of RAM but perhaps it does not need
  -to be particularly fast. Another machine might need very fast RAM but
  -little of it. Of course there's no reason why you should be that lucky...
  +tune the machines individually to suit the tasks they should perform.
  +
  +<P>
  +For example if you need to run a relational database engine and mod_perl
  +server, it can be wise to put the two on different machines, since while
  +RDBMS need a very fast disk, mod_perl processes need lots of memory. So by
  +placing the two on different machines it's easy to optimize each machine at
  +separate and satisfy the each software components requirements in the best
  +way.
   
  -<P><A NAME="anchor76"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="Conclusion">Conclusion</A></H2></CENTER>
  -<P><A NAME="anchor77"></A>
  +<P>
   To use your money optimally you have to understand the hardware very well,
   so you will know what to pick. Otherwise, you should hire a knowledgeable
   hardware consultant and employ them on a regular basis, since your needs
   will probably change as time goes by and your hardware will likewise be
   forced to adapt as well.
   
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -	     The <a href="http://www.modperl.com/">
  -	     <B>Writing Apache Modules with Perl and C</B></a>
  -	     book can be purchased online from <a
  -	     href="http://www.ora.com/catalog/wrapmod/">O'Reilly </a>
  -	     and <a
  -	     href="http://www.amazon.com/exec/obidos/ASIN/156592567X/writinapachemodu">
  -	     Amazon.com</a>.
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   
  -	     <HR>
   
  -	     <B>Your corrections of either technical or grammatical
  +    <p>
  +    <div class="navbar">
  +      <a href="snippets.html">Prev</a>                                 |
  +      <A HREF="index.html"         >Contents</A> |
  +      <A HREF="index.html#search"  >Search</A>   |
  +      <A HREF="index.html#download">Download</A> |
  +      <a href="advocacy.html">Next</a>
  +    </div>
  +    <p>
  +
  +    <table width="60%" align="center">
  +
  +      <tr>
  +	<td>
  +	  <div class="notice">
  +	  <B>Your corrections of the technical and grammatical
   	     errors are very welcome. You are encouraged to help me
  -	     to improve this guide.  If you have something to
  -	     contribute please <A
  -	     HREF="help.html#Contacting_me"> send it
  +	     improve this guide.  If you have something to contribute
  +	     please <A HREF="help.html#Contacting_me"> send it
   	     directly to me</A>.</B>
  +	  </div>
  +	</td>
  +      </tr>
  +
  +      <tr>
  +	<td>
  +	  <div class="ad">
  +	    The <a href="http://www.modperl.com/">
  +	      <B>Writing Apache Modules with Perl and C</B></a>
  +	    book can be purchased online from <a
  +	      href="http://www.ora.com/catalog/wrapmod/">O'Reilly </a>
  +	    and <a
  +	    href="http://www.amazon.com/exec/obidos/ASIN/156592567X/writinapachemodu">
  +	      Amazon.com</a>.
  +	  </div>
  +	</td>
  +      </tr>
  +
  +</table>
  +
  +<center>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
  +<table cellspacing=2 cellpadding=2>
  +
  +<tr align=center valign=top>
  +<td align=center valign=center>
  +
  +<b><font size=-1>Written by <a
  +href="help.html#Contacting_me">Stas Bekman</a>.<br> Last Modified at 05/28/2000
  +</font></b>
  +<br>
  +
  +</td>
  +
  +<td>
  +
  +<a href="http://perl.apache.org"><img src="images/mod_perl2.jpg"  border=0 alt="mod_perl icon" border=0 height=59 width=150></a>
  +<br>
  +
  +</td>
  +
  +<td>
  +
  +<font size=-2>Use of the Camel for Perl is <br>
  +a trademark of <a href="http://www.ora.com">O'Reilly &amp; Associates</a>,<br>
  +and is used by permission. </font> 
  +<br>
   
  -	     <HR>
  +</td>
   
  -	     [    <A HREF="snippets.html">Prev</A> |      <A HREF="index.html">Main Page</A> | <A HREF="advocacy.html">Next</A>      ]
  +</tr>
  +</table>
  +</center>
   
  -<CENTER><TABLE CELLSPACING=2 CELLPADDING=2 WIDTH="100%" >
  -<TR ALIGN=CENTER VALIGN=TOP>
  -  <TD ALIGN=CENTER VALIGN=CENTER COLSPAN="3">
  -	     <HR>
  -  </TD>
  -</TR>
  -<TR ALIGN=CENTER VALIGN=TOP>
  -  <TD ALIGN=CENTER VALIGN=CENTER>
  -    <B>
  -      <FONT SIZE=-1>
  -	     Written by <A HREF="help.html#Contacting_me">Stas Bekman</A>.
  -	     <BR>Last Modified at 04/29/2000
  -      </FONT>
  -    </B>
  -  </TD>
  -
  -  <TD>
  -	     <A HREF="http://perl.apache.org"><IMG SRC="images/mod_perl2.jpg" ALT="Mod Perl Icon" BORDER=0 HEIGHT=59 WIDTH=150></A>
  -  </TD>
  -
  -  <TD>
  -    <FONT SIZE=-2>
  -	     Use of the Camel for Perl is <BR>
  -	     a trademark of <A HREF="http://www.ora.com">O'Reilly &amp; Associates</A>,<BR>
  -             and is used by permission. 
  -    </FONT> 
  -  </TD>
  -</TR>
  -</TABLE></CENTER>
  -
  -</BODY>
  -</HTML>
  -	    
  \ No newline at end of file
  +</body>
  +</html>
  
  
  
  1.24      +291 -193  modperl-site/guide/help.html
  
  Index: help.html
  ===================================================================
  RCS file: /home/cvs/modperl-site/guide/help.html,v
  retrieving revision 1.23
  retrieving revision 1.24
  diff -u -r1.23 -r1.24
  --- help.html	2000/05/12 22:42:51	1.23
  +++ help.html	2000/06/07 22:45:31	1.24
  @@ -1,29 +1,37 @@
   <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
  -<HTML>
  -<HEAD>
  -   <TITLE>mod_perl guide: Getting Help and Further Learning</TITLE>
  -   <META NAME="GENERATOR" CONTENT="Pod2HTML [Perl/Linux]">
  -   <META NAME="Author" CONTENT="Stas Bekman">
  -   <META NAME="Description" CONTENT="All Apache/Perl related information: Hints, Guidelines, Scenarios and Troubleshottings">
  -   <META NAME="keywords" CONTENT="mod_perl modperl perl apache cgi webserver speed  fast guide mod_perl apache guide help info faq mod_perl installation cgi troubleshooting help no sex speedup free open source OSS mod_perl apache guide">
  -</HEAD>
  -     <LINK REL=STYLESHEET TYPE="text/css"
  -        HREF="style.css" TITLE="refstyle">
  -     <style type="text/css">
  -     <!-- 
  -        @import url(style.css);
  -     -->
  -     
  -     </style>
  -<BODY BGCOLOR="white">
  +<html>
  +  <head>
  +   <title>mod_perl guide: Getting Help and Further Learning</title>
  +   <meta name="Author" content="Stas Bekman">
  +   <meta name="Description" content="All Apache/Perl related information: Hints, Guidelines, Scenarios and Troubleshottings">
  +   <meta name="keywords" content="mod_perl modperl perl cgi apache webserver speed fast guide mod_perl apache guide help info faq mod_perl installation cgi troubleshooting help no sex speedup free open source OSS mod_perl apache guide">
  +   <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
  +   <meta name="Classification" content="information">
  +   <link href="style.css" rel=stylesheet type="text/css" title="refstyle">
  +  </head>
  +  <body>
  +
  +    <h1 align=center>
  +      <a href="http://perl.apache.org"><img src="images/mod_perl.gif" alt="Mod Perl Icon" border=0 height=30 width=90 align=left></a>
  +      <a href="http://perl.apache.org"><img src="images/mod_perl.gif" alt="Mod Perl Icon" border=0 height=30 width=90 align=right></a>
  +      Getting Help and Further Learning
  +    </h1>
  +    <hr>
  +    <p>
  +    <div class="navbar">
  +      <a href="advocacy.html">Prev</a>                                 |
  +      <a href="index.html"         >Contents</a> |
  +      <a href="index.html#search"  >Search</a>   |
  +      <a href="index.html#download">Download</a> |
  +      <a href="download.html">Next</a>
  +    </div>
  +    <p>
  +
  +    <div class="toc">
  +      
   <A NAME="toc"></A>
  -<H1 ALIGN=CENTER>
  -<A HREF="http://perl.apache.org"><IMG SRC="images/mod_perl.gif" ALT="Mod Perl Icon" BORDER=0 HEIGHT=30 WIDTH=90 ALIGN=LEFT></A>
  -<A HREF="http://perl.apache.org"><IMG SRC="images/mod_perl.gif" ALT="Mod Perl Icon" BORDER=0 HEIGHT=30 WIDTH=90 ALIGN=RIGHT></A>
  -Getting Help and Further Learning</H1>
  -<HR WIDTH="100%">
  -	    [    <A HREF="advocacy.html">Prev</A> |      <A HREF="index.html">Main Page</A> | <A HREF="download.html">Next</A>      ]<HR><!-- INDEX BEGIN -->
  -<P><B><FONT SIZE=-1>Table of Contents:</FONT></B></P>
  +<P><B>Table of Contents:</B></P>
  +
   <UL>
   
   	<LI><A HREF="#READ_ME_FIRST">READ ME FIRST</A>
  @@ -36,33 +44,49 @@
   	<LI><A HREF="#Get_help_with_Squid_Internet_O">Get help with Squid - Internet Object Cache</A>
   	<LI><A HREF="#Get_help_with_CVS_Concurrent_">Get help with CVS - Concurrent Version Control</A>
   </UL>
  -<!-- INDEX END -->
   
  +    </div>
  +
  +    [ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
   <HR>
  +    <table width="60%" align="center">
  +
  +      <tr>
  +	<td>
  +	  <div class="ad">
  +	    The <a href="http://www.modperl.com/">
  +	      <B>Writing Apache Modules with Perl and C</B></a>
  +	    book can be purchased online from <a
  +	      href="http://www.ora.com/catalog/wrapmod/">O'Reilly </a>
  +	    and <a
  +	    href="http://www.amazon.com/exec/obidos/ASIN/156592567X/writinapachemodu">
  +	      Amazon.com</a>.
  +	  </div>
  +	</td>
  +      </tr>
  +
  +      <tr>
  +	<td>
  +	  <div class="notice">
  +	  <B>Your corrections of the technical and grammatical
  +	     errors are very welcome. You are encouraged to help me
  +	     improve this guide.  If you have something to contribute
  +	     please <A HREF="help.html#Contacting_me"> send it
  +	     directly to me</A>.</B>
  +	  </div>
  +	</td>
  +      </tr>
   
  -	     The <a href="http://www.modperl.com/">
  -	     <B>Writing Apache Modules with Perl and C</B></a>
  -	     book can be purchased online from <a
  -	     href="http://www.ora.com/catalog/wrapmod/">O'Reilly </a>
  -	     and <a
  -	     href="http://www.amazon.com/exec/obidos/ASIN/156592567X/writinapachemodu">
  -	     Amazon.com</a>.
  -
  -	     <HR>
  -
  -	       <B>Your corrections of either technical or grammatical
  -	       errors are very welcome. You are encouraged to help me
  -	       to improve this guide.  If you have something to
  -	       contribute please <A
  -	       HREF="help.html#Contacting_me"> send it
  -	       directly to me</A>.
  -	       </B>
  -	       <HR>
  +</table>
   
  -	      <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<P><A NAME="anchor0"></A>
  +    
  +
  +	    [ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
  +
  +<P>
   <CENTER><H1><A NAME="READ_ME_FIRST">READ ME FIRST</A></H1></CENTER>
  -<P><A NAME="anchor1"></A>
  +<P>
   If, after reading this guide and the other documents listed in this
   section, you still don't have the answers/information needed, please ask
   for help on the Apache/mod_perl mailing list. But please, first try to
  @@ -74,19 +98,20 @@
   more than once. This does not mean that you should avoid asking questions,
   but you should not abuse the available help and you should <EM>RTFM</EM> before you call for <EM>HELP</EM>. (Remember the fable of the shepherd boy and the wolves).
   
  -<P><A NAME="anchor2"></A>
  +<P>
   For more information See <A HREF="././help.html#Get_help_with_mod_perl">Get helped with mod_perl</A>.
   
  -<P><A NAME="anchor3"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H1><A NAME="Contacting_me">Contacting me</A></H1></CENTER>
  -<P><A NAME="anchor4"></A>
  +<P>
   Hi, I wrote this document to help people with mod_perl. It does not mean
   that if you have any question regarding mod_perl, perl or whatever you
   think I might know, that you should send it directly to me. Please see the <A HREF="#Get_help_with_mod_perl">Get help with mod_perl</A>
   section and follow the guidelines described there.
   
  -<P><A NAME="anchor5"></A>
  +<P>
   However, you are welcome to submit corrections and suggestions directly to
   me at <A
   HREF="mailto:stas@stason.org?subject=mod_perl%20guide%20corrections.">stas@stason.org?subject=mod_perl%20guide%20corrections.</A>
  @@ -96,7 +121,7 @@
   directly editing them and sending them to me. I will use Emacs Ediff to
   perform an easy merge of such changes. Thank you!
   
  -<P><A NAME="anchor6"></A>
  +<P>
   <EM>PLEASE DO NOT SEND QUESTIONS DIRECTLY TO ME, I didn't invite those
   by writing the guide.  They will all be immediately deleted.  Please
   ask questions on the mod_perl list and if we can answer your question,
  @@ -104,97 +129,110 @@
   
   
   
  -<P><A NAME="anchor7"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H1><A NAME="Get_help_with_mod_perl">Get help with mod_perl</A></H1></CENTER>
   <UL>
   <P><LI><STRONG><A NAME="item_mod_perl">mod_perl home</A></STRONG>
  -<P><A NAME="anchor8"></A>
  +<P>
   <A HREF="http://perl.apache.org">http://perl.apache.org</A>
   
   <P><LI><STRONG><A NAME="item_mod_perl">mod_perl Source Garden project</A></STRONG>
  -<P><A NAME="anchor9"></A>
  +<P>
   <A
   HREF="http://modperl.sourcegarden.org">http://modperl.sourcegarden.org</A>
   
   <P><LI><STRONG><A NAME="item_mod_perl">mod_perl Books</A></STRONG>
   <UL>
   <P><LI><STRONG><A NAME="item__Apache_Modules_Book">'Apache Modules' Book</A></STRONG>
  -<P><A NAME="anchor10"></A>
  +<P>
   <A HREF="http://www.modperl.com">http://www.modperl.com</A> is the home
   site of The Apache Modules Book, a book about creating Web server modules
   using the Apache API, written by Lincoln Stein and Doug MacEachern.
   
  -<P><A NAME="anchor11"></A>
  +<P>
   The book should be available from your local bookstore or from your
   favourite on-line bookseller. O'Reilly lists this book as:
   
  -<P><A NAME="anchor12"></A>
  -<PRE>  Writing Apache Modules with Perl and C
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  Writing Apache Modules with Perl and C
     By Lincoln Stein &amp; Doug MacEachern
     1st Edition March 1999
     2nd Edition Feb 2000
     1-56592-567-X, Order Number: 567X
  -  746 pages, $34.95
  -</PRE>
  -<P><LI><STRONG><A NAME="item__Enabling_web_services_with_mod_">'Enabling web services with mod_perl' Book</A></STRONG>
  -<P><A NAME="anchor13"></A>
  +  746 pages, $34.95</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P><LI><STRONG><A NAME="item__Enabling_web_services_with_mod_">'Enabling web services with mod_perl' Book</A></STRONG>
  +<P>
   <A HREF="http://www.modperlbook.com">http://www.modperlbook.com</A> is the
   home site of the new mod_perl book, that Eric Cholet and Stas Bekman are
   co-authoring. We expect the book to be published in fall 2000.
   
  -<P><A NAME="anchor14"></A>
  +<P>
   Ideas, suggestions and comments are welcome. Please send them to <A
   HREF="mailto:info@modperlbook.com">info@modperlbook.com</A> .
   
   </UL>
   <P><LI><STRONG><A NAME="item_mod_perl">mod_perl Guide</A></STRONG>
  -<P><A NAME="anchor15"></A>
  +<P>
   by Stas Bekman at <A
   HREF="http://perl.apache.org/guide">http://perl.apache.org/guide</A>
   
   <P><LI><STRONG><A NAME="item_mod_perl">mod_perl FAQ</A></STRONG>
  -<P><A NAME="anchor16"></A>
  +<P>
   by Frank Cringle at <A
   HREF="http://perl.apache.org/faq/">http://perl.apache.org/faq/</A> .
   
   <P><LI><STRONG><A NAME="item_mod_perl">mod_perl performance tuning guide</A></STRONG>
  -<P><A NAME="anchor17"></A>
  +<P>
   by Vivek Khera at <A
   HREF="http://perl.apache.org/tuning/">http://perl.apache.org/tuning/</A> .
   
   <P><LI><STRONG><A NAME="item_mod_perl">mod_perl plugin reference guide</A></STRONG>
  -<P><A NAME="anchor18"></A>
  +<P>
   by Doug MacEachern at <A
   HREF="http://perl.apache.org/src/mod_perl.html">http://perl.apache.org/src/mod_perl.html</A>
   .
   
   <P><LI><STRONG><A NAME="item_Quick">Quick guide for moving from CGI to mod_perl</A></STRONG>
  -<P><A NAME="anchor19"></A>
  +<P>
   at <A
   HREF="http://perl.apache.org/dist/cgi_to_mod_perl.html">http://perl.apache.org/dist/cgi_to_mod_perl.html</A>
   .
   
   <P><LI><STRONG><A NAME="item_mod_perl_traps">mod_perl_traps, common traps and solutions for mod_perl users</A></STRONG>
  -<P><A NAME="anchor20"></A>
  +<P>
   at <A
   HREF="http://perl.apache.org/dist/mod_perl_traps.html">http://perl.apache.org/dist/mod_perl_traps.html</A>
   .
   
   <P><LI><STRONG><A NAME="item_mod_perl">mod_perl Quick Reference Card</A></STRONG>
  -<P><A NAME="anchor21"></A>
  +<P>
   <A HREF="http://www.refcards.com">http://www.refcards.com</A> (Reference
   cards for Apache and other programs are available from this link)
   
   <P><LI><STRONG><A NAME="item_Articles">Articles</A></STRONG>
   <UL>
   <P><LI><STRONG><A NAME="item_PerlMonth">PerlMonth</A></STRONG>
  -<P><A NAME="anchor22"></A>
  +<P>
   <A HREF="http://perlmonth.com">http://perlmonth.com</A>
   
   <P><LI><STRONG><A NAME="item_Basic">Basic knowledge about Apache stages and
   mod_perl handlers article in German</A></STRONG>
  -<P><A NAME="anchor23"></A>
  +<P>
   <A
   HREF="http://www.heise.de/ix/artikel/2000/01/156/">http://www.heise.de/ix/artikel/2000/01/156/</A>
   
  @@ -203,7 +241,7 @@
   <P><LI><STRONG><A NAME="item_mod_perl">mod_perl mailing lists</A></STRONG>
   <UL>
   <P><LI><STRONG><A NAME="item_The">The mod_perl mailing list</A></STRONG>
  -<P><A NAME="anchor24"></A>
  +<P>
   The Apache/Perl mailing list <EM>is available for mod_perl users and
   developers to share ideas, solve problems and discuss things related
   to mod_perl and the Apache::* modules.</EM>  To subscribe to this list, send email to <A
  @@ -213,56 +251,56 @@
   . Send email to <A HREF="mailto:modperl@apache.org">modperl@apache.org</A>
   to post to the list.
   
  -<P><A NAME="anchor25"></A>
  +<P>
   To subscribe to the digest list send email to <A
   HREF="mailto:modperl-digest-subscribe@apache.org">modperl-digest-subscribe@apache.org</A>
   .
   
  -<P><A NAME="anchor26"></A>
  +<P>
   A <EM>searchable</EM> mod_perl mailing list archive is available at <A
   HREF="http://forum.swarthmore.edu/epigone/modperl">http://forum.swarthmore.edu/epigone/modperl</A>
   . Thanks to Ken Williams for this.
   
  -<P><A NAME="anchor27"></A>
  +<P>
   More archives available:
   
   <UL>
   <P><LI>
  -<P><A NAME="anchor28"></A>
  +<P>
   <A
   HREF="http://www.geocrawler.com/lists/3/web/182/0/">http://www.geocrawler.com/lists/3/web/182/0/</A>
   
   
   <P><LI>
  -<P><A NAME="anchor29"></A>
  +<P>
   <A
   HREF="http://www.mail-archive.com/modperl%40apache.org/">http://www.mail-archive.com/modperl%40apache.org/</A>
   
   
   <P><LI>
  -<P><A NAME="anchor30"></A>
  +<P>
   <A
   HREF="http://www.davin.ottawa.on.ca/archive/modperl/">http://www.davin.ottawa.on.ca/archive/modperl/</A>
   
   
   <P><LI>
  -<P><A NAME="anchor31"></A>
  +<P>
   <A
  -HREF="http://www.progressive-comp.com/Lists/?l=apache-modperl&r=1&w=2#apache-modperl">http://www.progressive-comp.com/Lists/?l=apache-modperl&r=1&w=2#apache-modperl</A>
  +HREF="http://marc.theaimsgroup.com/?l=apache-modperl">http://marc.theaimsgroup.com/?l=apache-modperl</A>
   
   
   <P><LI>
  -<P><A NAME="anchor32"></A>
  +<P>
   <A
   HREF="http://www.egroups.com/group/modperl/">http://www.egroups.com/group/modperl/</A>
   
   
   </UL>
   <P><LI><STRONG><A NAME="item_The">The advocacy mailing list</A></STRONG>
  -<P><A NAME="anchor33"></A>
  +<P>
   The list for mod_perl advocacy issues, discussions about sites, etc.
   
  -<P><A NAME="anchor34"></A>
  +<P>
   Subscribe by sending a mail to <A
   HREF="mailto:advocacy-subscribe@perl.apache.org.">advocacy-subscribe@perl.apache.org.</A>
   Unsubscribe by sending a mail to <A
  @@ -270,19 +308,19 @@
   Use <A HREF="mailto:advocacy@perl.apache.org">advocacy@perl.apache.org</A>
   to post to the list.
   
  -<P><A NAME="anchor35"></A>
  +<P>
   The archive: <A
   HREF="http://www.mail-archive.com/advocacy@perl.apache.org/.">http://www.mail-archive.com/advocacy@perl.apache.org/.</A>
   
   
   <P><LI><STRONG><A NAME="item_The">The modperl-cvs mailing list</A></STRONG>
  -<P><A NAME="anchor36"></A>
  +<P>
   The modperl developers list is the list where you can watch mod_perl
   getting patched. No real discussions happen on this list, but if you want
   to know about the latest changes in the mod_perl core before everyone else,
   this is a list to be on.
   
  -<P><A NAME="anchor37"></A>
  +<P>
   To subscribe to this list, send email to <A
   HREF="mailto:modperl-cvs-subscribe@apache.org">modperl-cvs-subscribe@apache.org</A>
   . To unsubscribe send email to <A
  @@ -291,171 +329,203 @@
   HREF="mailto:modperl-cvs@apache.org">modperl-cvs@apache.org</A> to post to
   the list.
   
  -<P><A NAME="anchor38"></A>
  +<P>
   No archives available.
   
   </UL>
   </UL>
  -<P><A NAME="anchor39"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H1><A NAME="Get_help_with_Perl">Get help with Perl</A></H1></CENTER>
   <UL>
   <P><LI><STRONG><A NAME="item_The">The Perl FAQ</A></STRONG>
  -<P><A NAME="anchor40"></A>
  +<P>
   <A
   HREF="http://www.perl.com/CPAN/doc/FAQs/FAQ/PerlFAQ.html">http://www.perl.com/CPAN/doc/FAQs/FAQ/PerlFAQ.html</A>
   
   
   <P><LI><STRONG><A NAME="item_The">The Perl Home Page</A></STRONG>
  -<P><A NAME="anchor41"></A>
  +<P>
   <A HREF="http://www.perl.com/">http://www.perl.com/</A>
   
   <P><LI><STRONG><A NAME="item_The">The Perl Journal</A></STRONG>
  -<P><A NAME="anchor42"></A>
  +<P>
   <A HREF="http://www.tpj.com/">http://www.tpj.com/</A>
   
   <P><LI><STRONG><A NAME="item_Perl">Perl Module Mechanics</A></STRONG>
  -<P><A NAME="anchor43"></A>
  +<P>
   <A
   HREF="http://world.std.com/~swmcd/steven/perl/module_mechanics.html">http://world.std.com/~swmcd/steven/perl/module_mechanics.html</A>
   - This page describes the mechanics of creating, compiling, releasing and
   maintaining Perl modules.
   
   <P><LI><STRONG><A NAME="item_perl5">perl5-porters mailing list</A></STRONG>
  -<P><A NAME="anchor44"></A>
  -To subscribe to this list send an email to <EM>majordomo@perl.org</EM> with the message body <EM>subscribe perl5-porters</EM>. If you prefer a digest version send the message body <EM>subscribe perl5-porters-digest</EM>.
  +<P>
  +Send an email:
   
  -<P><A NAME="anchor45"></A>
  -To unsubscribe use <EM>unsubscribe perl5-porters</EM> or <EM>unsubscribe
  -perl5-porters-digest</EM> in the body of the message.
  +<UL>
  +<P><LI>
  +<P>
  +to <A
  +HREF="mailto:perl5-porters-subscribe@perl.org">perl5-porters-subscribe@perl.org</A>
  +to subscribe to this list.
   
  -<P><A NAME="anchor46"></A>
  +<P><LI>
  +<P>
  +to <A
  +HREF="mailto:perl5-porters-unsubscribe@perl.org">perl5-porters-unsubscribe@perl.org</A>
  +to unsubscribe to this list.
  +
  +<P><LI>
  +<P>
  +to <A
  +HREF="mailto:perl5-porters-digest-subscribe@perl.org">perl5-porters-digest-subscribe@perl.org</A>
  +if you prefer a digest version.
  +
  +<P><LI>
  +<P>
  +to <A
  +HREF="mailto:perl5-porters-digest-unsubscribe@perl.org">perl5-porters-digest-unsubscribe@perl.org</A>
  +to unsubscribe from the digest.
  +
  +<P><LI>
  +<P>
  +to <A
  +HREF="mailto:perl5-porters-help@perl.org">perl5-porters-help@perl.org</A>
  +for more information about the subscription options.
  +
  +</UL>
  +<P>
   See also <A
   HREF="http://tile.net/listserv/perl5portersdigest.html">http://tile.net/listserv/perl5portersdigest.html</A>
   and <A
   HREF="http://tile.net/lists/perl5porters.html">http://tile.net/lists/perl5porters.html</A>
   .
   
  -<P><A NAME="anchor47"></A>
  -List's archive is available from <A
  +<P>
  +List's archive is available at <A
   HREF="http://www.xray.mpe.mpg.de/mailing-lists/perl5-porters/.">http://www.xray.mpe.mpg.de/mailing-lists/perl5-porters/.</A>
   
   
   </UL>
  -<P><A NAME="anchor48"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H1><A NAME="Get_help_with_Perl_CGI">Get help with Perl/CGI</A></H1></CENTER>
   <UL>
   <P><LI><STRONG><A NAME="item_Perl">Perl/CGI FAQ</A></STRONG>
  -<P><A NAME="anchor49"></A>
  +<P>
   at <A
   HREF="http://www.perl.com/CPAN/doc/FAQs/cgi/perl-cgi-faq.html">http://www.perl.com/CPAN/doc/FAQs/cgi/perl-cgi-faq.html</A>
   
   
   <P><LI><STRONG><A NAME="item_Answers">Answers to some troublesome Perl and Perl/CGI questions</A></STRONG>
  -<P><A NAME="anchor50"></A>
  +<P>
   <A
   HREF="http://stason.org/TULARC/webmaster/myfaq.html">http://stason.org/TULARC/webmaster/myfaq.html</A>
   
   
   <P><LI><STRONG><A NAME="item_Idiot">Idiot's Guide to CGI programming</A></STRONG>
  -<P><A NAME="anchor51"></A>
  +<P>
   <A
   HREF="http://www.perl.com/CPAN/doc/FAQs/cgi/idiots-guide.html">http://www.perl.com/CPAN/doc/FAQs/cgi/idiots-guide.html</A>
   
   
   <P><LI><STRONG><A NAME="item_WWW">WWW Security FAQ</A></STRONG>
  -<P><A NAME="anchor52"></A>
  +<P>
   <A
   HREF="http://www.w3.org/Security/Faq/www-security-faq.html">http://www.w3.org/Security/Faq/www-security-faq.html</A>
   
   
   <P><LI><STRONG><A NAME="item_CGI">CGI/Perl Taint Mode FAQ</A></STRONG>
  -<P><A NAME="anchor53"></A>
  +<P>
   <A
   HREF="http://www.gunther.web66.com/FAQS/taintmode.html">http://www.gunther.web66.com/FAQS/taintmode.html</A>
   (by Gunther Birznieks)
   
   </UL>
  -<P><A NAME="anchor54"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H1><A NAME="Get_help_with_Apache">Get help with Apache</A></H1></CENTER>
   <UL>
   <P><LI><STRONG><A NAME="item_Apache">Apache Project's Home</A></STRONG>
  -<P><A NAME="anchor55"></A>
  +<P>
   <A HREF="http://www.apache.org">http://www.apache.org</A>
   
   <P><LI><STRONG><A NAME="item_Apache">Apache Quick Reference Card</A></STRONG>
  -<P><A NAME="anchor56"></A>
  +<P>
   <A HREF="http://www.refcards.com">http://www.refcards.com</A> (other
   reference cards are also available from this link)
   
   <P><LI><STRONG><A NAME="item_The">The Apache FAQ</A></STRONG>
  -<P><A NAME="anchor57"></A>
  +<P>
   <A
   HREF="http://www.apache.org/docs/misc/FAQ.html">http://www.apache.org/docs/misc/FAQ.html</A>
   
   
   <P><LI><STRONG><A NAME="item_Apache">Apache Server Documentation</A></STRONG>
  -<P><A NAME="anchor58"></A>
  +<P>
   <A HREF="http://www.apache.org/docs/">http://www.apache.org/docs/</A>
   
   <P><LI><STRONG><A NAME="item_Apache">Apache Handlers</A></STRONG>
  -<P><A NAME="anchor59"></A>
  +<P>
   <A
   HREF="http://www.apache.org/docs/handler.html">http://www.apache.org/docs/handler.html</A>
   
   
   <P><LI><STRONG><A NAME="item_mod_rewrite">mod_rewrite Guide</A></STRONG>
  -<P><A NAME="anchor60"></A>
  +<P>
   <A
   HREF="http://www.engelschall.com/pw/apache/rewriteguide/">http://www.engelschall.com/pw/apache/rewriteguide/</A>
   
   
   <P><LI><STRONG><A NAME="item_articles">articles</A></STRONG>
  -<P><A NAME="anchor61"></A>
  +<P>
   Security and Apache: An Essential Primer <A
   HREF="http://linuxplanet.com/linuxplanet/print/1527/">http://linuxplanet.com/linuxplanet/print/1527/</A>
   
   
  -<P><A NAME="anchor62"></A>
  +<P>
   Using Apache with Suexec on Linux <A
   HREF="http://linuxplanet.com/linuxplanet/print/1445/">http://linuxplanet.com/linuxplanet/print/1445/</A>
   
   
  -<P><A NAME="anchor63"></A>
  +<P>
   Installing and Securing the Apache Webserver with SSL <A
   HREF="http://www.securityfocus.com/focus/sun/articles/apache-inst.html?&_ref=1653102939">http://www.securityfocus.com/focus/sun/articles/apache-inst.html?&_ref=1653102939</A>
   
   
   <P><LI><STRONG><A NAME="item_mod_throttle_access">mod_throttle_access</A></STRONG>
  -<P><A NAME="anchor64"></A>
  +<P>
   mod_throttle_access is available at <A
   HREF="http://www.fremen.org/apache/">http://www.fremen.org/apache/</A>
   
   </UL>
  -<P><A NAME="anchor65"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H1><A NAME="Get_help_with_DBI">Get help with DBI</A></H1></CENTER>
   <UL>
   <P><LI><STRONG><A NAME="item_Perl">Perl DBI examples</A></STRONG>
  -<P><A NAME="anchor66"></A>
  +<P>
   <A
   HREF="http://www.saturn5.com/~jwb/dbi-examples.html">http://www.saturn5.com/~jwb/dbi-examples.html</A>
   (by Jeffrey William Baker).
   
   <P><LI><STRONG><A NAME="item_DBI">DBI Homepage</A></STRONG>
  -<P><A NAME="anchor67"></A>
  +<P>
   <A
   HREF="http://www.symbolstone.org/technology/perl/DBI/">http://www.symbolstone.org/technology/perl/DBI/</A>
   
   
   <P><LI><STRONG><A NAME="item_DBI">DBI mailing list information</A></STRONG>
  -<P><A NAME="anchor68"></A>
  +<P>
   <A HREF="http://www.fugue.com/dbi/">http://www.fugue.com/dbi/</A> 
   
   <P><LI><STRONG><A NAME="item_DBI">DBI mailing list archives</A></STRONG>
  -<P><A NAME="anchor69"></A>
  +<P>
   <A
   HREF="http://outside.organic.com/mail-archives/dbi-users/">http://outside.organic.com/mail-archives/dbi-users/</A>
   <A
  @@ -463,138 +533,166 @@
   
   
   <P><LI><STRONG><A NAME="item_Persistent">Persistent connections with mod_perl</A></STRONG>
  -<P><A NAME="anchor70"></A>
  +<P>
   <A
   HREF="http://perl.apache.org/src/mod_perl.html#PERSISTENT_DATABASE_CONNECTIONS">http://perl.apache.org/src/mod_perl.html#PERSISTENT_DATABASE_CONNECTIONS</A>
   
   
   </UL>
  -<P><A NAME="anchor71"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H1><A NAME="Get_help_with_Squid_Internet_O">Get help with Squid - Internet Object Cache</A></H1></CENTER>
   <UL>
   <P><LI>
  -<P><A NAME="anchor72"></A>
  +<P>
   Home page - <A HREF="http://squid.nlanr.net/">http://squid.nlanr.net/</A>
   
   <P><LI>
  -<P><A NAME="anchor73"></A>
  +<P>
   FAQ - <A
   HREF="http://squid.nlanr.net/Squid/FAQ/FAQ.html">http://squid.nlanr.net/Squid/FAQ/FAQ.html</A>
   
   
   <P><LI>
  -<P><A NAME="anchor74"></A>
  +<P>
   Users Guide - <A
   HREF="http://squid.nlanr.net/Squid/Users-Guide/">http://squid.nlanr.net/Squid/Users-Guide/</A>
   
   
   <P><LI>
  -<P><A NAME="anchor75"></A>
  +<P>
   Mailing lists - <A
   HREF="http://squid.nlanr.net/Squid/mailing-lists.html">http://squid.nlanr.net/Squid/mailing-lists.html</A>
   
   
   </UL>
  -<P><A NAME="anchor76"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H1><A NAME="Get_help_with_CVS_Concurrent_">Get help with CVS -- Concurrent Version Control</A></H1></CENTER>
   <UL>
   <P><LI>
  -<P><A NAME="anchor77"></A>
  +<P>
   mod_perl repository specific doc: mod_perl_cvs.pod, located in the root of
   the mod_perl source distribution and online at <A
   HREF="http://perl.apache.org/mod_perl_cvs.html">http://perl.apache.org/mod_perl_cvs.html</A>
   
   
   <P><LI>
  -<P><A NAME="anchor78"></A>
  +<P>
   Open Source Development with CVS <A
   HREF="http://cvsbook.red-bean.com/">http://cvsbook.red-bean.com/</A>
   
   <P><LI>
  -<P><A NAME="anchor79"></A>
  +<P>
   Online Documents <A
   HREF="http://www.sourcegear.com/CVS/Docs/online">http://www.sourcegear.com/CVS/Docs/online</A>
   
   
   <P><LI>
  -<P><A NAME="anchor80"></A>
  +<P>
   CVS Quick Reference <A
   HREF="http://www.sourcegear.com/CVS/Docs/ref">http://www.sourcegear.com/CVS/Docs/ref</A>
   
   
   <P><LI>
  -<P><A NAME="anchor81"></A>
  +<P>
   CVS Books <A
   HREF="http://www.sourcegear.com/CVS/Docs/books">http://www.sourcegear.com/CVS/Docs/books</A>
   
   
   <P><LI>
  -<P><A NAME="anchor82"></A>
  +<P>
   User-Written FAQ <A
   HREF="http://www.sourcegear.com/CVS/Docs/docfaq">http://www.sourcegear.com/CVS/Docs/docfaq</A>
   
   
   <P><LI>
  -<P><A NAME="anchor83"></A>
  +<P>
   Introduction to CVS <A
   HREF="http://www.sourcegear.com/CVS/Docs/blandy">http://www.sourcegear.com/CVS/Docs/blandy</A>
   
   
   </UL>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -	     The <a href="http://www.modperl.com/">
  -	     <B>Writing Apache Modules with Perl and C</B></a>
  -	     book can be purchased online from <a
  -	     href="http://www.ora.com/catalog/wrapmod/">O'Reilly </a>
  -	     and <a
  -	     href="http://www.amazon.com/exec/obidos/ASIN/156592567X/writinapachemodu">
  -	     Amazon.com</a>.
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   
  -	     <HR>
   
  -	     <B>Your corrections of either technical or grammatical
  +    <p>
  +    <div class="navbar">
  +      <a href="advocacy.html">Prev</a>                                 |
  +      <A HREF="index.html"         >Contents</A> |
  +      <A HREF="index.html#search"  >Search</A>   |
  +      <A HREF="index.html#download">Download</A> |
  +      <a href="download.html">Next</a>
  +    </div>
  +    <p>
  +
  +    <table width="60%" align="center">
  +
  +      <tr>
  +	<td>
  +	  <div class="notice">
  +	  <B>Your corrections of the technical and grammatical
   	     errors are very welcome. You are encouraged to help me
  -	     to improve this guide.  If you have something to
  -	     contribute please <A
  -	     HREF="help.html#Contacting_me"> send it
  +	     improve this guide.  If you have something to contribute
  +	     please <A HREF="help.html#Contacting_me"> send it
   	     directly to me</A>.</B>
  +	  </div>
  +	</td>
  +      </tr>
  +
  +      <tr>
  +	<td>
  +	  <div class="ad">
  +	    The <a href="http://www.modperl.com/">
  +	      <B>Writing Apache Modules with Perl and C</B></a>
  +	    book can be purchased online from <a
  +	      href="http://www.ora.com/catalog/wrapmod/">O'Reilly </a>
  +	    and <a
  +	    href="http://www.amazon.com/exec/obidos/ASIN/156592567X/writinapachemodu">
  +	      Amazon.com</a>.
  +	  </div>
  +	</td>
  +      </tr>
  +
  +</table>
  +
  +<center>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
  +<table cellspacing=2 cellpadding=2>
  +
  +<tr align=center valign=top>
  +<td align=center valign=center>
  +
  +<b><font size=-1>Written by <a
  +href="help.html#Contacting_me">Stas Bekman</a>.<br> Last Modified at 05/27/2000
  +</font></b>
  +<br>
  +
  +</td>
  +
  +<td>
  +
  +<a href="http://perl.apache.org"><img src="images/mod_perl2.jpg"  border=0 alt="mod_perl icon" border=0 height=59 width=150></a>
  +<br>
  +
  +</td>
  +
  +<td>
  +
  +<font size=-2>Use of the Camel for Perl is <br>
  +a trademark of <a href="http://www.ora.com">O'Reilly &amp; Associates</a>,<br>
  +and is used by permission. </font> 
  +<br>
   
  -	     <HR>
  +</td>
   
  -	     [    <A HREF="advocacy.html">Prev</A> |      <A HREF="index.html">Main Page</A> | <A HREF="download.html">Next</A>      ]
  +</tr>
  +</table>
  +</center>
   
  -<CENTER><TABLE CELLSPACING=2 CELLPADDING=2 WIDTH="100%" >
  -<TR ALIGN=CENTER VALIGN=TOP>
  -  <TD ALIGN=CENTER VALIGN=CENTER COLSPAN="3">
  -	     <HR>
  -  </TD>
  -</TR>
  -<TR ALIGN=CENTER VALIGN=TOP>
  -  <TD ALIGN=CENTER VALIGN=CENTER>
  -    <B>
  -      <FONT SIZE=-1>
  -	     Written by <A HREF="help.html#Contacting_me">Stas Bekman</A>.
  -	     <BR>Last Modified at 05/09/2000
  -      </FONT>
  -    </B>
  -  </TD>
  -
  -  <TD>
  -	     <A HREF="http://perl.apache.org"><IMG SRC="images/mod_perl2.jpg" ALT="Mod Perl Icon" BORDER=0 HEIGHT=59 WIDTH=150></A>
  -  </TD>
  -
  -  <TD>
  -    <FONT SIZE=-2>
  -	     Use of the Camel for Perl is <BR>
  -	     a trademark of <A HREF="http://www.ora.com">O'Reilly &amp; Associates</A>,<BR>
  -             and is used by permission. 
  -    </FONT> 
  -  </TD>
  -</TR>
  -</TABLE></CENTER>
  -
  -</BODY>
  -</HTML>
  -	    
  \ No newline at end of file
  +</body>
  +</html>
  
  
  
  1.28      +274 -260  modperl-site/guide/index.html
  
  Index: index.html
  ===================================================================
  RCS file: /home/cvs/modperl-site/guide/index.html,v
  retrieving revision 1.27
  retrieving revision 1.28
  diff -u -r1.27 -r1.28
  --- index.html	2000/05/12 22:42:51	1.27
  +++ index.html	2000/06/07 22:45:31	1.28
  @@ -1,75 +1,69 @@
   <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
  -<HTML>
  -<HEAD>
  -   <TITLE>mod_perl Guide</TITLE>
  -   <META NAME="Author" CONTENT="Stas Bekman">
  -   <META NAME="Description" CONTENT="All Apache/Perl related information: Hints, 
  -Guidelines, Scenarios and Troubleshottings">
  -   <META NAME="keywords" CONTENT="mod_perl modperl perl cgi apache webserver speed 
  -fast guide mod_perl apache guide help info faq mod_perl installation cgi
  -troubleshooting help no sex speedup free open source OSS mod_perl apache guide">
  -   <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1">
  -   <META NAME="Classification" CONTENT="information">
  -</HEAD>
  -
  -    <LINK REL=STYLESHEET TYPE="text/css"
  -        HREF="style.css" TITLE="refstyle">
  -     <style type="text/css">
  -     <!-- 
  -        @import url(style.css);
  -     -->
  -     <font color="#008B8B">
  -
  -     </style>
  -<BODY BGCOLOR="white">
  -
  -<H1 ALIGN=CENTER>mod_perl Guide</H1>
  -
  -<CENTER>
  -<P><B>
  +<html>
  +  <head>
  +   <title>mod_perl Guide</title>
  +   <meta name="Author" content="Stas Bekman">
  +   <meta name="Description" content="All Apache/Perl related information: Hints, Guidelines, Scenarios and Troubleshottings">
  +   <meta name="keywords" content="mod_perl modperl perl cgi apache webserver speed fast guide mod_perl apache guide help info faq mod_perl installation cgi troubleshooting help no sex speedup free open source OSS mod_perl apache guide">
  +   <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
  +   <meta name="Classification" content="information">
  +   <link href="style.css" rel=stylesheet type="text/css" title="refstyle">
  +  </head>
  +  <body>
  +
  +    <h1 align=center>mod_perl Guide</h1>
  +
  +    <center>
  +      <p>
  +	<b>
  +	  Deploying mod_perl technology to give the rocket speed to
  +	  your CGI/Perl scripts.
  +	</b>
  +      </p>
  +    </center>
   
  -Deploying mod_perl technology to give the rocket speed to your
  -CGI/Perl scripts.
  -
  -</B></P>
  -</CENTER>
  -
  -<CENTER><P><B>Version 1.23 May, 13 2000</B></P></CENTER>
  +    <center><p><b>Version 1.24 Jun 7, 2000</b></p></center>
    
  -<table width="70%" align=center>
  -<tr><td>
  -
  -<HR WIDTH="100%">
  -
  -<B>Mirror readers</B>: Make sure you read <A
  -HREF="http://perl.apache.org/guide"> the latest copy</A> by comparing
  -the version number from above with Master document.
  -
  -<HR WIDTH="100%">
  -
  -</td></tr>
  -<tr><td>
  -
  -<CENTER>
  -[ <A HREF="#toc">TOC</A> ] 
  -			      [ <A HREF="index_long.html">Full TOC</A> ]
  -[ <A HREF="#changes">Changes</A> ]  
  -[ <A HREF="#download">Download</A> ] 
  -[ <A HREF="#search">Search</A> ]  
  -</CENTER>
  -
  -<HR WIDTH="65%">
   
  -</td></tr>
  -<tr><td>
  -
  -<A NAME="toc"></A>
  -<h3><font color="#008B8B">
  -Table of Contents:</font></h3>
  -
  -<UL>
  -
  -<LI><A HREF="intro.html">Introduction. Incentives. Credits.</A></LI>
  +    <table align=center width="70%">
  + 
  +      <tr>
  +	<td>	  
  +	  <div class="notice">
  +	    <b>Full Version Master Copy URL</b>: <a
  +	    href="http://perl.apache.org/guide/"><b>http://perl.apache.org/guide/</b></a><br>
  +	  </div>
  +
  +	</td>
  +      </tr>
  +
  +      <tr>
  +	<td>
  +	  <p>&nbsp;</p>
  +	  <div class="navbar">	  
  +	    [ <A HREF="#toc">TOC</A> ] 
  +			      [ <A HREF="index_long.html">Full TOC</A> ] 
  +	    | <a href="#changes">Changes</a>
  +	    | <a href="#download">Download</a>
  +	    | <a href="#search">Search</a> 
  +	  </div>
  +	  <p>&nbsp;</p>
  +	</td>
  +      </tr>
  +
  +      <tr>
  +	<td>
  +
  +	  <a name="toc"></a>
  +	  <h3>
  +	    <font color="#008B8B">
  +	      Table of Contents:
  +	    </font>
  +	  </h3>
  +
  +	  <ul>
  +	  <div class="toc">
  +	    <LI><A HREF="intro.html">Introduction. Incentives. Credits.</A></LI>
   
   
   <LI><A HREF="start.html">Guide's Overview</A></LI>
  @@ -102,9 +96,6 @@
   <LI><A HREF="frequent.html">Frequent mod_perl problems</A></LI>
   
   
  -<LI><A HREF="obvious.html">Things obvious to others, but not to you</A></LI>
  -
  -
   <LI><A HREF="troubleshooting.html">Warnings and Errors Troubleshooting Index</A></LI>
   
   
  @@ -147,198 +138,221 @@
   <LI><A HREF="download.html">Appendix A: Downloading software and documentation</A></LI>
   
   
  +	  </div>
   
  -</UL>
  +	</ul>
   
  -</td></tr>
  -<tr><td>
  +	</td>
  +      </tr>
   
  -<HR WIDTH="65%">
  +      <tr>
  +	<td>
  +	  <p>&nbsp;</p>
  +	  <div class="navbar">	  
  +	    [ <A HREF="#toc">TOC</A> ] 
  +			      [ <A HREF="index_long.html">Full TOC</A> ] 
  +	    | <a href="#changes">Changes</a>
  +	    | <a href="#download">Download</a>
  +	    | <a href="#search">Search</a> 
  +	  </div>
  +	  <p>&nbsp;</p>
  +	</td>
  +      </tr>
  +
  +      <tr>
  +	<td>
  +
  +	  <a name="changes"></a>
  +	  <h3>
  +	    <font color="#008B8B">
  +	      Changes:
  +	    </font>
  +	  </h3>
  +
  +	  <ul>
  +
  +	    <li> 
  +      The Guide's <a href="CHANGES">Changes</a> file.
  +	    </li>
  +	  </ul>
  +
  +	</td>
  +      </tr>
  +
  +      <tr>
  +	<td>
  +
  +	  <a name="download"></a>
  +	  <h3>
  +	    <font color="#008B8B">
  +	      Download:
  +	    </font>
  +	  </h3>
  +	
  +
  +	  <ul>
  +
  +	    <li> 
  +	      The latest CVS snapshots of the POD sources
  +	      and the build script you can build the HTMLs from,
  +	      are available from  <a
  +		href="http://www.stason.org/guide-snapshots/">
  +		http://www.stason.org/guide-snapshots/</a>.
  +	    </li>
  +
  +	    <li> 
  +	      <b>This</b> release's HTML files, POD sources 
  +	      and build script are available from <a
  +		href="http://www.perl.com/CPAN-local/authors/id/S/ST/STAS/">
  +		my directory at CPAN or its mirrors</a>.
  +	    </li>
  +
  +	    <li> 
  +	      <!-- this link must be FQDN, since the split version
  +	      will link to the broken link if you don't do it, since
  +	      we don't copy the pdf to the split version -->
  +	      Here is the <a href="http://perl.apache.org/guide/mod_perl_guide.pdf.gz"> Book-like
  +		version </a> (PDF format). To read PDF files you can
  +		use: <code>ghostview</code> (<code>gv</code>),
  +	      <code>xpdf</code> or <code>acroread</code>.  You can use the
  +	      <code>pdf2ps</code> utility to convert PDF to
  +	      PostSscript format.
  +	    </li>
  +
  +	  </ul>
  +
  +	</td>
  +      </tr>
  +
  +      <tr>
  +	<td>
  +
  +	  <A NAME="search"></A>
  +	  <h3>
  +	    <font color="#008B8B">
  +	      Search:
  +	    </font>
  +	  </h3>
  +
  +	  <div class="search">
  +	    Using <a
  +	    href="http://www.nexial.com/nextrieve/"><b>nextrieve</b></a>
  +	    engine on <b>split</b> Guide version (by Vivek Khera):
  +	    <form
  +	      action="http://thingy.kcilink.com/cgi-bin/modperlguide.cgi"
  +	      method="post">
  +	      <center>
  +		<input type=text name=q value="" size=25> 
  +		<input type=submit value=" Search ">
  +	      </center>
  +	    </form>
  +	  </div>
  +
  +	  <div class="search">	
  +	    Using
  +	    <a href="http://sunsite.berkeley.edu/SWISH-E/">
  +	      <b>SWISH-E</b></a> engine + Perl filters on <b>split</b>
  +	      Guide version (by Randy Kobes):
  +	    <form method="GET"
  +	      action="http://theoryx5.uwinnipeg.ca/cgi-bin/guide-search"
  +	      enctype="application/x-www-form-urlencoded" name="search">
  +	      <center>
  +		<input type="text" name="query" size=25>
  +		<input type="submit" name="Submit" value=" Search ">
  +		<input type="hidden" name=".cgifields" value="where">
  +		<input type="hidden" name=".cgifields" value="match">
  +	      </center>
  +	    </form>
  +	  </div>
  +
  +	  <div class="search">	  
  +	    Using
  +	    <a href="http://sunsite.berkeley.edu/SWISH-E/">
  +	      <b>SWISH-E</b></A> engine on <b>full</b> Guide version
  +	      (perl.apache.org) (bad results):
  +	    <form action="http://search.apache.org/" method="post">
  +	      <center>
  +		<input type="text" name="keyword" value="" size=25>
  +		<input type="hidden" name="what" value="perl">
  +		<input type="hidden" name="results" value=40>
  +		<input type="submit" value="Search">
  +	      </center>
  +	    </form>    
  +	  </div>
  +	  
  +
  +	</td>
  +      </tr>
  +
  +      <tr>
  +	<td>
  +	  <p>&nbsp;</p>
  +	  <div class="navbar">	  
  +	    [ <A HREF="#toc">TOC</A> ] 
  +			      [ <A HREF="index_long.html">Full TOC</A> ] 
  +	    | <a href="#changes">Changes</a>
  +	    | <a href="#download">Download</a>
  +	    | <a href="#search">Search</a> 
  +	  </div>
  +	  <p>&nbsp;</p>
  +	</td>
  +      </tr>
  +
  +      <tr>
  +	<td>	  
  +	  <div class="notice">
  +	    Full Version Master Copy URL: <a
  +	    href="http://perl.apache.org/guide/"><b>http://perl.apache.org/guide</b></a><br>
  +	    Copyright &copy; 1998-2000 Stas Bekman. All rights
  +	    reserved.
  +	  </div>
  +	</td>
  +      </tr>
  +
  +    </table>
  + 
   
  -<CENTER>
  -[ <A HREF="#toc">TOC</A> ] 
  -			      [ <A HREF="index_long.html">Full TOC</A> ]
  -[ <A HREF="#changes">Changes</A> ]  
  -[ <A HREF="#download">Download</A> ] 
  -[ <A HREF="#search">Search</A> ]  
  -</CENTER>
  -
  -<HR WIDTH="65%">
  -
  -</td></tr>
  -<tr><td>
  -
  -<A NAME="changes"></A>
  -<h3><font color="#008B8B">
  -Changes:</font></h3>
  -
  -      The Guide <A HREF="CHANGES">Changes</A> file.</LI>
  -
  -</td></tr>
  -<tr><td>
  -
  -<HR WIDTH="65%">
  -
  -<CENTER>
  -[ <A HREF="#toc">TOC</A> ] 
  -			      [ <A HREF="index_long.html">Full TOC</A> ]
  -[ <A HREF="#changes">Changes</A> ]  
  -[ <A HREF="#download">Download</A> ] 
  -[ <A HREF="#search">Search</A> ]  
  -</CENTER>
  -
  -<HR WIDTH="65%">
  -</td></tr>
  -<tr><td>
  -
  -      <A NAME="download"><h3><font color="#008B8B">
  -Download:</font></h3>
  -</A>
  -
  -	<UL>
  -
  -	  <LI> 
  -	    The latest CVS snapshots of the POD sources
  -	    and the build script you can build the HTMLs from,
  - 	    are available from  <A
  -	    HREF="http://www.stason.org/guide-snapshots/">
  -	    http://www.stason.org/guide-snapshots/</A>. 
  -	  </LI>
  -
  -	  <LI> 
  -	    <B>This</B> release's HTML files, POD sources 
  -            and build script are available from <A
  -	    HREF="http://www.perl.com/CPAN-local/authors/id/S/ST/STAS/">
  -	    my directory at CPAN or its mirrors</A>.
  -	  </LI>
  -
  -	  <LI> 
  -	    Here is the <A HREF="mod_perl_guide.pdf.gz"> Book-like
  -	    version </A> (PDF format). Note that <CODE>gv</CODE>
  -	    (<CODE>ghostview</CODE>), in addition to viewing PostScript
  -	    files, knows to handle PDF files as well. You can use
  -	    <CODE>pdf2ps</CODE> utility to convert PDF to PostSscript format.
  -	  </LI>
  -
  -	</UL>
  -
  -      </LI>
  -
  -    </UL>
  -
  -</td></tr>
  -<tr><td>
  -
  -<HR WIDTH="65%">
  -
  -<CENTER>
  -[ <A HREF="#toc">TOC</A> ] 
  -			      [ <A HREF="index_long.html">Full TOC</A> ]
  -[ <A HREF="#changes">Changes</A> ]  
  -[ <A HREF="#download">Download</A> ] 
  -[ <A HREF="#search">Search</A> ]  
  -</CENTER>
  -
  -<HR WIDTH="65%">
  -</td></tr>
  -<tr><td>
  -
  -<A NAME="search"><h3><font color="#008B8B">
  -Search:</font></h3>
  -</A>
  -
  -<!--
  -<CENTER>
  -<TABLE BORDER=10 CELLSPACING=2 CELLPADDING=8 >
  -<TR BGCOLOR="gray" ALIGN=CENTER VALIGN=TOP>
  -<TD ALIGN=CENTER VALIGN=TOP>
  -<FONT COLOR=WHITE>
  -Search mod_perl FAQs along with this guide 
  -<BR> at www.perlreference.com
  -<FORM action="http://perlreference.com/cgi-bin/mod_perl/search.pl" method="GET">
  -<INPUT type="text" name="q" value="" SIZE=15>
  -<INPUT TYPE="submit" VALUE="Search">
  -</FORM>
  -</FONT>
  -</TD></TR>
  -</TABLE>
  -</CENTER>
  --->
  -
  -<CENTER>
  -<TABLE BORDER=10 CELLSPACING=2 CELLPADDING=8 >
  -<TR BGCOLOR="gray" ALIGN=CENTER VALIGN=TOP>
  -<TD ALIGN=CENTER VALIGN=TOP>
  -<FONT COLOR=WHITE>
  -Search perl.apache.org along with this guide.
  -<FORM ACTION="http://search.apache.org/" METHOD="POST">
  -<INPUT TYPE="text" NAME="keyword" value="" SIZE=15>
  -<input type="hidden" name="what" value="perl">
  -<input type="hidden" name="results" value=40>
  -<INPUT TYPE="submit" VALUE="Search">
  -</FORM>
  -</FONT>
  -</TD></TR>
  -</TABLE>
  -</CENTER>
  -
  -</td></tr>
  -<tr><td>
  -
  -<HR WIDTH="65%">
  -
  -<CENTER>
  -[ <A HREF="#toc">TOC</A> ] 
  -			      [ <A HREF="index_long.html">Full TOC</A> ]
  -[ <A HREF="#changes">Changes</A> ]  
  -[ <A HREF="#download">Download</A> ] 
  -[ <A HREF="#search">Search</A> ]  
  -</CENTER>
  -
  -<HR WIDTH="65%">
  -
  -</td></tr>
  -<tr><td>
  -
  -	     The <a href="http://www.modperl.com/">
  -	     <B>Writing Apache Modules with Perl and C</B></a>
  -	     book can be purchased online from <a
  -	     href="http://www.ora.com/catalog/wrapmod/">O'Reilly </a>
  -	     and <a
  -	     href="http://www.amazon.com/exec/obidos/ASIN/156592567X/writinapachemodu">
  -	     Amazon.com</a>.
  -
  -</td></tr>
  -<tr><td>
  -
  -<HR WIDTH="100%">
  -<CENTER>
  -Master Copy URL: <B>http://perl.apache.org/guide</B><BR>
  -Copyright &copy; 1998-2000 Stas Bekman. All rights reserved.
  -</CENTER>
  -
  -</td></tr>
  -</table>
  -
  -<HR WIDTH="100%">
  -
  -<CENTER>
  -<TABLE CELLSPACING=2 CELLPADDING=2 WIDTH="100%" >
  -
  -<TR ALIGN=CENTER VALIGN=TOP>
  -<TD ALIGN=CENTER VALIGN=CENTER><B><FONT SIZE=-1>Written by <A
  -HREF="help.html#This_document_s_Author">Stas Bekman</A>.<BR> Last Modified at 05/13/2000
  -</FONT></B></TD>
  -
  -<TD><A HREF="http://perl.apache.org"><IMG SRC="images/mod_perl2.jpg"  BORDER=0 ALT="Mod Perl Icon" BORDER=0 HEIGHT=59 WIDTH=150></A>
  -</TD>
  -
  -<TD><FONT SIZE=-2>Use of the Camel for Perl is <BR>
  -a trademark of <A HREF="http://www.ora.com">O'Reilly &amp; Associates</A>,<BR>
  -and is used by permission. </FONT> </TD>
  -</TR>
  -</TABLE></CENTER>
  +    <hr>
   
  -</BODY>
  -</HTML>
  +    <center>
  +      <table cellspacing=2 cellpadding=2>
  +	
  +	<tr align=center valign=top>
  +	  <td align=center valign=center>
  +	    
  +	    <b><font size=-1>
  +		Written by <a
  +		  href="help.html#Contacting_me">Stas
  +		  Bekman</a>.<br> Last Modified at 06/07/2000
  +	      </font></b>
  +	    <br>
  +	    
  +	  </td>
  +
  +	  <td>
  +	    
  +	    <a href="http://perl.apache.org"><img
  +	    src="images/mod_perl2.jpg"
  +		border=0 alt="Mod Perl Icon" border=0 height=59 width=150></a>
  +	    <br>
  +
  +	  </td>
  +
  +	  <td>
  +
  +	    <font size=-2>
  +	      Use of the Camel for Perl is <BR> a trademark of <A
  +	      HREF="http://www.ora.com">O'Reilly &amp;
  +	      Associates</A>,<BR> and is used by permission. 
  +	    </font>
  +	    <br>
  +	    
  +	  </td>
  +	  
  +	</tr>
  +      </table>
  +    </center>
  +    
  +  </body>
  +</html>
   
  
  
  
  1.2       +357 -308  modperl-site/guide/index_long.html
  
  Index: index_long.html
  ===================================================================
  RCS file: /home/cvs/modperl-site/guide/index_long.html,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- index_long.html	2000/05/12 22:42:52	1.1
  +++ index_long.html	2000/06/07 22:45:31	1.2
  @@ -1,75 +1,69 @@
   <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
  -<HTML>
  -<HEAD>
  -   <TITLE>mod_perl Guide</TITLE>
  -   <META NAME="Author" CONTENT="Stas Bekman">
  -   <META NAME="Description" CONTENT="All Apache/Perl related information: Hints, 
  -Guidelines, Scenarios and Troubleshottings">
  -   <META NAME="keywords" CONTENT="mod_perl modperl perl cgi apache webserver speed 
  -fast guide mod_perl apache guide help info faq mod_perl installation cgi
  -troubleshooting help no sex speedup free open source OSS mod_perl apache guide">
  -   <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1">
  -   <META NAME="Classification" CONTENT="information">
  -</HEAD>
  -
  -    <LINK REL=STYLESHEET TYPE="text/css"
  -        HREF="style.css" TITLE="refstyle">
  -     <style type="text/css">
  -     <!-- 
  -        @import url(style.css);
  -     -->
  -     <font color="#008B8B">
  -
  -     </style>
  -<BODY BGCOLOR="white">
  -
  -<H1 ALIGN=CENTER>mod_perl Guide</H1>
  -
  -<CENTER>
  -<P><B>
  +<html>
  +  <head>
  +   <title>mod_perl Guide</title>
  +   <meta name="Author" content="Stas Bekman">
  +   <meta name="Description" content="All Apache/Perl related information: Hints, Guidelines, Scenarios and Troubleshottings">
  +   <meta name="keywords" content="mod_perl modperl perl cgi apache webserver speed fast guide mod_perl apache guide help info faq mod_perl installation cgi troubleshooting help no sex speedup free open source OSS mod_perl apache guide">
  +   <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
  +   <meta name="Classification" content="information">
  +   <link href="style.css" rel=stylesheet type="text/css" title="refstyle">
  +  </head>
  +  <body>
  +
  +    <h1 align=center>mod_perl Guide</h1>
  +
  +    <center>
  +      <p>
  +	<b>
  +	  Deploying mod_perl technology to give the rocket speed to
  +	  your CGI/Perl scripts.
  +	</b>
  +      </p>
  +    </center>
   
  -Deploying mod_perl technology to give the rocket speed to your
  -CGI/Perl scripts.
  -
  -</B></P>
  -</CENTER>
  -
  -<CENTER><P><B>Version 1.23 May, 13 2000</B></P></CENTER>
  +    <center><p><b>Version 1.24 Jun 7, 2000</b></p></center>
    
  -<table width="70%" align=center>
  -<tr><td>
  -
  -<HR WIDTH="100%">
  -
  -<B>Mirror readers</B>: Make sure you read <A
  -HREF="http://perl.apache.org/guide"> the latest copy</A> by comparing
  -the version number from above with Master document.
  -
  -<HR WIDTH="100%">
  -
  -</td></tr>
  -<tr><td>
  -
  -<CENTER>
  -[ <A HREF="#toc">TOC</A> ] 
  -			      [ <A HREF="index.html">Dense TOC</A> ]
  -[ <A HREF="#changes">Changes</A> ]  
  -[ <A HREF="#download">Download</A> ] 
  -[ <A HREF="#search">Search</A> ]  
  -</CENTER>
  -
  -<HR WIDTH="65%">
  -
  -</td></tr>
  -<tr><td>
   
  -<A NAME="toc"></A>
  -<h3><font color="#008B8B">
  -Table of Contents:</font></h3>
  -
  -<UL>
  -
  -<LI><A HREF="intro.html"><B><FONT SIZE=+1>Introduction. Incentives. Credits.</FONT></B></A></LI><P>
  +    <table align=center width="70%">
  + 
  +      <tr>
  +	<td>	  
  +	  <div class="notice">
  +	    <b>Full Version Master Copy URL</b>: <a
  +	    href="http://perl.apache.org/guide/"><b>http://perl.apache.org/guide/</b></a><br>
  +	  </div>
  +
  +	</td>
  +      </tr>
  +
  +      <tr>
  +	<td>
  +	  <p>&nbsp;</p>
  +	  <div class="navbar">	  
  +	    [ <A HREF="#toc">TOC</A> ] 
  +			      [ <A HREF="index.html">Dense TOC</A> ] 
  +	    | <a href="#changes">Changes</a>
  +	    | <a href="#download">Download</a>
  +	    | <a href="#search">Search</a> 
  +	  </div>
  +	  <p>&nbsp;</p>
  +	</td>
  +      </tr>
  +
  +      <tr>
  +	<td>
  +
  +	  <a name="toc"></a>
  +	  <h3>
  +	    <font color="#008B8B">
  +	      Table of Contents:
  +	    </font>
  +	  </h3>
  +
  +	  <ul>
  +	  <div class="toc">
  +	    <LI><A HREF="intro.html"><B><FONT SIZE=+1>Introduction. Incentives. Credits.</FONT></B></A></LI><P>
   <UL>
   
   	<LI><A HREF="intro.html#What_is_mod_perl">What is mod_perl</A>
  @@ -130,7 +124,7 @@
   
   		<LI><A HREF="perl.html#The_INC_array">The @INC array</A>
   		<LI><A HREF="perl.html#The_INC_hash">The %INC hash</A>
  -		<LI><A HREF="perl.html#Modules_Libraries_and_Files">Modules, Libraries and Files</A>
  +		<LI><A HREF="perl.html#Modules_Libraries_and_Program_F">Modules, Libraries and Program Files</A>
   		<LI><A HREF="perl.html#require_">require()</A>
   		<LI><A HREF="perl.html#use_">use()</A>
   		<LI><A HREF="perl.html#do_">do()</A>
  @@ -167,6 +161,7 @@
   		</UL>
   
   		<LI><A HREF="perl.html#Some_Uses">Some Uses</A>
  +		<LI><A HREF="perl.html#A_Warning">A Warning</A>
   		<LI><A HREF="perl.html#Conclusions">Conclusions</A>
   		<LI><A HREF="perl.html#The_My_Exception_class_in_its_e">The My::Exception class in its entirety</A>
   		<LI><A HREF="perl.html#Other_Implementations">Other Implementations</A>
  @@ -421,23 +416,41 @@
   <LI><A HREF="control.html"><B><FONT SIZE=+1>Controlling and Monitoring the Server</FONT></B></A></LI><P>
   <UL>
   
  -	<LI><A HREF="control.html#Restarting_techniques">Restarting techniques</A>
  +	<LI><A HREF="control.html#Restarting_Techniques">Restarting Techniques</A>
   	<LI><A HREF="control.html#Server_Stopping_and_Restarting">Server Stopping and Restarting </A>
  -	<LI><A HREF="control.html#Using_apachectl_to_control_the_s">Using apachectl to control the server</A>
  +	<LI><A HREF="control.html#Speeding_up_the_Apache_Terminati">Speeding up the Apache Termination and Restart</A>
  +	<LI><A HREF="control.html#Using_apachectl_to_Control_the_S">Using apachectl to Control the Server</A>
   	<LI><A HREF="control.html#Safe_Code_Updates_on_a_Live_Prod">Safe Code Updates on a Live Production Server</A>
   	<LI><A HREF="control.html#An_Intentional_Disabling_of_Live">An Intentional Disabling of Live Scripts</A>
   	<LI><A HREF="control.html#SUID_Start_up_Scripts">SUID Start-up Scripts</A>
  +	<UL>
  +
  +		<LI><A HREF="control.html#Introduction_to_SUID_Executables">Introduction to SUID Executables</A>
  +		<LI><A HREF="control.html#Apache_Startup_SUID_Script_s_Sec">Apache Startup SUID Script's Security</A>
  +		<LI><A HREF="control.html#Sample_Apache_Startup_SUID_Scrip">Sample Apache Startup SUID Script</A>
  +	</UL>
  +
   	<LI><A HREF="control.html#Preparing_for_Machine_Reboot">Preparing for Machine Reboot</A>
   	<LI><A HREF="control.html#Monitoring_the_Server_A_watchdo">Monitoring the Server.  A watchdog.</A>
   	<LI><A HREF="control.html#Running_a_Server_in_Single_Proce">Running a Server in Single Process Mode</A>
   	<LI><A HREF="control.html#Starting_a_Personal_Server_for_E">Starting a Personal Server for Each Developer</A>
  -	<LI><A HREF="control.html#Wrapper_to_Emulate_the_Server_En">Wrapper to Emulate the Server Environment</A>
  -	<LI><A HREF="control.html#Log_Rotation">Log Rotation</A>
  +	<LI><A HREF="control.html#Wrapper_to_Emulate_the_Server_Pe">Wrapper to Emulate the Server Perl Environment</A>
  +	<LI><A HREF="control.html#Server_Maintenance_Chores">Server Maintenance Chores</A>
  +	<UL>
  +
  +		<LI><A HREF="control.html#Handling_Log_Files">Handling Log Files</A>
  +		<UL>
  +
  +			<LI><A HREF="control.html#Log_Rotation">Log Rotation</A>
  +			<LI><A HREF="control.html#Non_Scheduled_Emergency_Log_Rota">Non-Scheduled Emergency Log Rotation</A>
  +		</UL>
  +
  +	</UL>
  +
   	<LI><A HREF="control.html#Preventing_mod_perl_Processes_Fr">Preventing mod_perl Processes From Going Wild</A>
   	<UL>
   
   		<LI><A HREF="control.html#All_RAM_Consumed">All RAM Consumed </A>
  -		<LI><A HREF="control.html#All_Disk_Space_Consumed">All Disk Space Consumed </A>
   	</UL>
   
   </UL>
  @@ -479,7 +492,7 @@
   	</UL>
   
   	<LI><A HREF="strategy.html#Do_Not_Run_Everything_on_One_mod">Do Not Run Everything on One mod_perl Server</A>
  -	<LI><A HREF="strategy.html#Do_Not_Put_mod_ssl_into_mod_perl">Do Not Put mod_ssl into mod_perl Server</A>
  +	<LI><A HREF="strategy.html#Do_Not_Put_mod_ssl_into_a_mod_pe">Do Not Put mod_ssl into a mod_perl Server</A>
   	<LI><A HREF="strategy.html#Pros_and_Cons_of_Building_mod_pe">Pros and Cons of Building mod_perl as DSO</A>
   </UL>
   <P>
  @@ -536,7 +549,7 @@
   		<LI><A HREF="scenario.html#Buffering_Feature">Buffering Feature</A>
   		<UL>
   
  -			<LI><A HREF="scenario.html#Setting_the_Buffering_Limits_on_">Setting the Buffering Limits on Various OSes</A>
  +			<LI><A HREF="scenario.html#Setting_the_Buffering_Limits_on_">Setting the Buffering Limits on Various OSs</A>
   			<UL>
   
   				<LI><A HREF="scenario.html#IOBUFSIZE_Source_Code_Definition">IOBUFSIZE Source Code Definition</A>
  @@ -547,7 +560,7 @@
   		</UL>
   
   		<LI><A HREF="scenario.html#Caching">Caching</A>
  -		<LI><A HREF="scenario.html#Building_process">Building process</A>
  +		<LI><A HREF="scenario.html#Build_process">Build process</A>
   	</UL>
   
   	<LI><A HREF="scenario.html#Front_end_Back_end_Proxying_with">Front-end Back-end Proxying with Virtual Hosts</A>
  @@ -558,7 +571,7 @@
   		<LI><A HREF="scenario.html#Use">Use</A>
   		<LI><A HREF="scenario.html#Security">Security</A>
   		<LI><A HREF="scenario.html#Caveats">Caveats</A>
  -		<LI><A HREF="scenario.html#mod_proxy_add_forward_Module_s_O">mod_proxy_add_forward Module's Order Precedence Importance</A>
  +		<LI><A HREF="scenario.html#mod_proxy_add_forward_Module_s_O">mod_proxy_add_forward Module's Order Precedence</A>
   	</UL>
   
   	<LI><A HREF="scenario.html#HTTP_Authentication_With_Two_Ser">HTTP Authentication With Two Servers Plus a Proxy</A>
  @@ -615,7 +628,7 @@
   	<LI><A HREF="porting.html#I_O_is_different">I/O is different</A>
   	<LI><A HREF="porting.html#STDIN_STDOUT_and_STDERR_streams">STDIN, STDOUT and STDERR streams</A>
   	<LI><A HREF="porting.html#Apache_print_and_CORE_print_">Apache::print() and CORE::print()</A>
  -	<LI><A HREF="porting.html#Global_Variables_Persistance">Global Variables Persistance</A>
  +	<LI><A HREF="porting.html#Global_Variables_Persistence">Global Variables Persistence</A>
   	<LI><A HREF="porting.html#Generating_correct_HTTP_Headers">Generating correct HTTP Headers</A>
   	<LI><A HREF="porting.html#NPH_Non_Parsed_Headers_scripts">NPH (Non Parsed Headers) scripts</A>
   	<LI><A HREF="porting.html#BEGIN_blocks">BEGIN blocks </A>
  @@ -684,19 +697,29 @@
   
   			<LI><A HREF="performance.html#How_Shared_Is_My_Memory_">How Shared Is My Memory?</A>
   			<LI><A HREF="performance.html#Calculating_Real_Memory_Usage">Calculating Real Memory Usage</A>
  -			<LI><A HREF="performance.html#Is_my_Code_Shared_">Is my Code Shared?</A>
  -			<LI><A HREF="performance.html#Preload_Perl_Modules_at_Server_S">Preload Perl Modules at Server Startup</A>
  -		</UL>
  +			<LI><A HREF="performance.html#Are_My_Variables_Shared_">Are My Variables Shared?</A>
  +			<LI><A HREF="performance.html#Preloading_Perl_Modules_at_Serve">Preloading Perl Modules at Server Startup</A>
  +			<LI><A HREF="performance.html#Preloading_Registry_Scripts_at_S">Preloading Registry Scripts at Server Startup</A>
  +			<LI><A HREF="performance.html#Modules_Initializing_at_Server_S">Modules Initializing at Server Startup</A>
  +			<UL>
   
  -		<LI><A HREF="performance.html#Preload_Perl_modules_Real_Numb">Preload Perl modules - Real Numbers</A>
  -		<UL>
  +				<LI><A HREF="performance.html#Initializing_DBI_pm">Initializing DBI.pm</A>
  +				<LI><A HREF="performance.html#Initializing_CGI_pm">Initializing CGI.pm</A>
  +			</UL>
   
  -			<LI><A HREF="performance.html#Preload_Registry_Scripts">Preload Registry Scripts</A>
   		</UL>
   
   		<LI><A HREF="performance.html#Memory_Swapping_is_Considered_Ba">Memory Swapping is Considered Bad</A>
   		<LI><A HREF="performance.html#Increasing_Shared_Memory_With_me">Increasing Shared Memory With mergemem</A>
   		<LI><A HREF="performance.html#Forking_and_Executing_Subprocess">Forking and Executing Subprocesses from mod_perl</A>
  +		<UL>
  +
  +			<LI><A HREF="performance.html#Spawning_a_Detachable_Sub_Proces">Spawning a Detachable Sub-Process</A>
  +			<LI><A HREF="performance.html#Gory_Details_About_fork_">Gory Details About fork()</A>
  +			<LI><A HREF="performance.html#Executing_system_in_the_Right_">Executing system() in the Right Way</A>
  +			<LI><A HREF="performance.html#Avoiding_Zombie_Processes">Avoiding Zombie Processes</A>
  +		</UL>
  +
   		<LI><A HREF="performance.html#OS_Specific_Parameters_for_Proxy">OS Specific Parameters for Proxying</A>
   	</UL>
   
  @@ -715,7 +738,7 @@
   		<LI><A HREF="performance.html#Reducing_the_Number_of_stat_Ca">Reducing the Number of stat() Calls Made by Apache</A>
   	</UL>
   
  -	<LI><A HREF="performance.html#TMTOWTDI_Convenience_and_Perfor">TMTOWTDI: Convenience and Performance</A>
  +	<LI><A HREF="performance.html#TMTOWTDI_Convenience_and_Habit_">TMTOWTDI: Convenience and Habit versus Performance</A>
   	<UL>
   
   		<LI><A HREF="performance.html#Apache_Registry_versus_pure_Per">Apache::Registry versus pure PerlHandler</A>
  @@ -731,11 +754,6 @@
   		<LI><A HREF="performance.html#_Bloatware_modules">&quot;Bloatware&quot; modules</A>
   		<LI><A HREF="performance.html#Apache_args_versus_Apache_Requ">Apache::args versus Apache::Request::params</A>
   		<LI><A HREF="performance.html#Using_1_Under_mod_perl_and_Be">Using $|=1 Under mod_perl and Better print() Techniques.</A>
  -	</UL>
  -
  -	<LI><A HREF="performance.html#Performance_Oriented_Perl_Coding">Performance Oriented Perl Coding</A>
  -	<UL>
  -
   		<LI><A HREF="performance.html#Global_vs_Fully_Qualified_Variab">Global vs Fully Qualified Variables </A>
   		<LI><A HREF="performance.html#Avoid_Importing_Functions">Avoid Importing Functions</A>
   		<LI><A HREF="performance.html#Object_Methods_Calls_Versus_Func">Object Methods Calls Versus Function Calls</A>
  @@ -748,7 +766,7 @@
   
   		<LI><A HREF="performance.html#Imported_Symbols_and_Memory_Usag">Imported Symbols and Memory Usage</A>
   		<LI><A HREF="performance.html#Concatenation_or_List">Concatenation or List</A>
  -		<LI><A HREF="performance.html#Cached_stat_Calls_by_Perl">Cached stat() Calls by Perl</A>
  +		<LI><A HREF="performance.html#Using_Perl_stat_Call_s_Cached_">Using Perl stat() Call's Cached Results</A>
   	</UL>
   
   	<LI><A HREF="performance.html#Apache_Registry_and_Derivatives">Apache::Registry and Derivatives Specific Notes</A>
  @@ -818,6 +836,12 @@
   		<LI><A HREF="performance.html#Upload_Download_of_Big_Files">Upload/Download of Big Files</A>
   	</UL>
   
  +	<LI><A HREF="performance.html#Apache_mod_perl_Build_Options">Apache/mod_perl Build Options</A>
  +	<UL>
  +
  +		<LI><A HREF="performance.html#mod_perl_Process_Size_as_a_Funct">mod_perl Process Size as a Function of Compiled in C Modules and mod_perl Features</A>
  +	</UL>
  +
   	<LI><A HREF="performance.html#Perl_Build_Options">Perl Build Options</A>
   	<UL>
   
  @@ -833,17 +857,8 @@
   	<LI><A HREF="frequent.html#Coverage">Coverage</A>
   	<LI><A HREF="frequent.html#my_scoped_variable_in_nested_s">my() scoped variable in nested subroutines</A>
   	<LI><A HREF="frequent.html#Segfaults_caused_by_PerlFreshRes">Segfaults caused by PerlFreshRestart</A>
  -	<LI><A HREF="frequent.html#Problems_with_DSO">Problems with DSO</A>
   </UL>
   <P>
  -<LI><A HREF="obvious.html"><B><FONT SIZE=+1>Things obvious to others, but not to you</FONT></B></A></LI><P>
  -<UL>
  -
  -	<LI><A HREF="obvious.html#Coverage">Coverage</A>
  -	<LI><A HREF="obvious.html#Where_do_the_warnings_errors_go_">Where do the warnings/errors go?</A>
  -	<LI><A HREF="obvious.html#Setting_Environment_Variables_Fo">Setting Environment Variables For Scripts Called From CGI.</A>
  -</UL>
  -<P>
   <LI><A HREF="troubleshooting.html"><B><FONT SIZE=+1>Warnings and Errors Troubleshooting Index</FONT></B></A></LI><P>
   <UL>
   
  @@ -911,6 +926,7 @@
   <LI><A HREF="correct_headers.html"><B><FONT SIZE=+1>Correct Headers - A quick guide for mod_perl users</FONT></B></A></LI><P>
   <UL>
   
  +	<LI><A HREF="correct_headers.html#Correct_Headers_A_quick_guide_">Correct Headers - A quick guide for mod_perl users</A>
   	<LI><A HREF="correct_headers.html#SYNOPSIS">SYNOPSIS</A>
   	<LI><A HREF="correct_headers.html#The_origin_of_this_chapter">The origin of this chapter</A>
   	<LI><A HREF="correct_headers.html#DESCRIPTION">DESCRIPTION</A>
  @@ -1032,15 +1048,19 @@
   <LI><A HREF="debug.html"><B><FONT SIZE=+1>Debugging mod_perl</FONT></B></A></LI><P>
   <UL>
   
  -	<LI><A HREF="debug.html#Curing_The_Internal_Server_Erro">Curing The &quot;Internal Server Error&quot;</A>
  -	<LI><A HREF="debug.html#Helping_error_log_to_Help_Us">Helping error_log to Help Us</A>
  -	<LI><A HREF="debug.html#The_Importance_of_Warnings">The Importance of Warnings</A>
  +	<LI><A HREF="debug.html#Warning_and_Errors_Explained">Warning and Errors Explained</A>
   	<UL>
  +
  +		<LI><A HREF="debug.html#Curing_The_Internal_Server_Erro">Curing The &quot;Internal Server Error&quot;</A>
  +		<LI><A HREF="debug.html#Helping_error_log_to_Help_Us">Helping error_log to Help Us</A>
  +		<LI><A HREF="debug.html#The_Importance_of_Warnings">The Importance of Warnings</A>
  +		<UL>
  +
  +			<LI><A HREF="debug.html#diagnostics_pragma">diagnostics pragma</A>
  +		</UL>
   
  -		<LI><A HREF="debug.html#diagnostics_pragma">diagnostics pragma</A>
   	</UL>
   
  -	<LI><A HREF="debug.html#Monitoring_the_error_log_file">Monitoring the error_log file</A>
   	<LI><A HREF="debug.html#Hanging_Processes_Detection_and">Hanging Processes: Detection and Diagnostics</A>
   	<UL>
   
  @@ -1086,11 +1106,6 @@
   
   		<LI><A HREF="debug.html#mod_status">mod_status</A>
   		<LI><A HREF="debug.html#Apache_VMonitor_Visual_Syste">Apache::VMonitor -- Visual System and Apache Server Monitor</A>
  -		<UL>
  -
  -			<LI><A HREF="debug.html#Configuration">Configuration</A>
  -		</UL>
  -
   	</UL>
   
   	<LI><A HREF="debug.html#Sometimes_My_Script_Works_Somet">Sometimes My Script Works, Sometimes It Does Not</A>
  @@ -1117,7 +1132,6 @@
   		<LI><A HREF="debug.html#Debugging_core_Dumping_Code">Debugging core Dumping Code</A>
   	</UL>
   
  -	<LI><A HREF="debug.html#PERL_DESTRUCT_LEVEL_Environment_">PERL_DESTRUCT_LEVEL Environment Variable</A>
   	<LI><A HREF="debug.html#PERL_DEBUG_1_Build_Option">PERL_DEBUG=1 Build Option</A>
   	<LI><A HREF="debug.html#Apache_Debug">Apache::Debug</A>
   	<LI><A HREF="debug.html#Debug_Tracing">Debug Tracing</A>
  @@ -1144,15 +1158,17 @@
   	<LI><A HREF="modules.html#Apache_Session_Maintain_sessi">Apache::Session - Maintain session state across HTTP requests</A>
   	<LI><A HREF="modules.html#Apache_DBI_Initiate_a_persist">Apache::DBI - Initiate a persistent database connection</A>
   	<LI><A HREF="modules.html#Apache_Watchdog_RunAway_Hang">Apache::Watchdog::RunAway - Hanging Processes Monitor and Terminator</A>
  -	<LI><A HREF="modules.html#Apache_VMonitor_Visual_System">Apache::VMonitor - Visual System and Apache Server Monitor</A>
  +	<LI><A HREF="modules.html#Apache_VMonitor_Visual_Syste">Apache::VMonitor -- Visual System and Apache Server Monitor</A>
   	<LI><A HREF="modules.html#Apache_GTopLimit_Limit_Apache">Apache::GTopLimit - Limit Apache httpd processes</A>
   	<LI><A HREF="modules.html#Apache_Request_libapreq_Gen">Apache::Request (libapreq) - Generic Apache Request Library</A>
   	<LI><A HREF="modules.html#Apache_RequestNotes_Allow_Eas">Apache::RequestNotes - Allow Easy, Consistent Access to Cookie and Form Data Across Each Request Phase</A>
   	<LI><A HREF="modules.html#Apache_PerlRun_Run_unaltered_">Apache::PerlRun - Run unaltered CGI scripts under mod_perl</A>
   	<LI><A HREF="modules.html#Apache_RegistryNG_Apache_Re">Apache::RegistryNG -- Apache::Registry New Generation</A>
   	<LI><A HREF="modules.html#Apache_RegistryBB_Apache_Re">Apache::RegistryBB -- Apache::Registry Bare Bones </A>
  -	<LI><A HREF="modules.html#Apache_GzipChain_compress_HTM">Apache::GzipChain - compress HTML (or anything) in the OutputChain</A>
   	<LI><A HREF="modules.html#Apache_OutputChain_Chain_Sta">Apache::OutputChain -- Chain Stacked Perl Handlers</A>
  +	<LI><A HREF="modules.html#Apache_GzipChain_compress_HTM">Apache::GzipChain - compress HTML (or anything) in the OutputChain</A>
  +	<LI><A HREF="modules.html#Apache_Filter_Alter_the_outpu">Apache::Filter - Alter the output of previous handlers</A>
  +	<LI><A HREF="modules.html#Apache_Gzip_Auto_compress_web">Apache::Gzip - Auto-compress web files with Gzip</A>
   	<LI><A HREF="modules.html#Apache_PerlVINC_set_a_differe">Apache::PerlVINC - set a different @INC perl-location </A>
   	<LI><A HREF="modules.html#Apache_LogSTDERR">Apache::LogSTDERR</A>
   	<LI><A HREF="modules.html#Apache_RedirectLogFix">Apache::RedirectLogFix</A>
  @@ -1191,6 +1207,7 @@
   	<LI><A HREF="snippets.html#Getting_the_Front_end_Server_s_N">Getting the Front-end Server's Name in the Back-end Server</A>
   	<LI><A HREF="snippets.html#Authentication_Snippets">Authentication Snippets</A>
   	<LI><A HREF="snippets.html#Using_DESTROY_to_Finalize_Output">Using DESTROY to Finalize Output</A>
  +	<LI><A HREF="snippets.html#Setting_Environment_Variables_Fo">Setting Environment Variables For Scripts Called From CGI.</A>
   	<LI><A HREF="snippets.html#Mysql_Backup_and_Restore_Scripts">Mysql Backup and Restore Scripts</A>
   </UL>
   <P>
  @@ -1206,21 +1223,29 @@
   		<LI><A HREF="hardware.html#Memory_Leaks">Memory Leaks</A>
   		<LI><A HREF="hardware.html#Sharing_Memory">Sharing Memory</A>
   		<LI><A HREF="hardware.html#Cost_and_Support">Cost and Support</A>
  -		<LI><A HREF="hardware.html#Discontinued_products">Discontinued products</A>
  +		<LI><A HREF="hardware.html#Discontinued_Products">Discontinued Products</A>
   		<LI><A HREF="hardware.html#OS_Releases">OS Releases</A>
   	</UL>
   
   	<LI><A HREF="hardware.html#Choosing_Hardware">Choosing Hardware</A>
   	<UL>
  +
  +		<LI><A HREF="hardware.html#Machine_Strength_Demands_Accordi">Machine Strength Demands According to Expected Site Traffic</A>
  +		<UL>
  +
  +			<LI><A HREF="hardware.html#Single_Strong_Machine_vs_Many_We">Single Strong Machine vs Many Weaker Machines</A>
  +		</UL>
   
  -		<LI><A HREF="hardware.html#Expected_site_traffic">Expected site traffic</A>
  -		<LI><A HREF="hardware.html#Cash">Cash</A>
   		<LI><A HREF="hardware.html#Internet_Connection">Internet Connection</A>
  -		<LI><A HREF="hardware.html#I_O_performance">I/O performance</A>
  +		<LI><A HREF="hardware.html#I_O_Performance">I/O Performance</A>
   		<LI><A HREF="hardware.html#Memory">Memory</A>
   		<LI><A HREF="hardware.html#CPU">CPU</A>
   		<LI><A HREF="hardware.html#Bottlenecks">Bottlenecks</A>
  -		<LI><A HREF="hardware.html#Tuning">Tuning</A>
  +		<UL>
  +
  +			<LI><A HREF="hardware.html#Solving_Hardware_Requirement_Con">Solving Hardware Requirement Conflicts</A>
  +		</UL>
  +
   		<LI><A HREF="hardware.html#Conclusion">Conclusion</A>
   	</UL>
   
  @@ -1253,6 +1278,7 @@
   
   	<LI><A HREF="download.html#Coverage">Coverage</A>
   	<LI><A HREF="download.html#Perl">Perl</A>
  +	<LI><A HREF="download.html#CPAN_Downloads">CPAN Downloads</A>
   	<LI><A HREF="download.html#Apache">Apache</A>
   	<LI><A HREF="download.html#mod_perl">mod_perl</A>
   	<LI><A HREF="download.html#Squid_Internet_Object_Cache">Squid - Internet Object Cache</A>
  @@ -1278,198 +1304,221 @@
   	<LI><A HREF="download.html#DataBases">DataBases</A>
   </UL>
   <P>
  +	  </div>
   
  -</UL>
  +	</ul>
   
  -</td></tr>
  -<tr><td>
  +	</td>
  +      </tr>
   
  -<HR WIDTH="65%">
  +      <tr>
  +	<td>
  +	  <p>&nbsp;</p>
  +	  <div class="navbar">	  
  +	    [ <A HREF="#toc">TOC</A> ] 
  +			      [ <A HREF="index.html">Dense TOC</A> ] 
  +	    | <a href="#changes">Changes</a>
  +	    | <a href="#download">Download</a>
  +	    | <a href="#search">Search</a> 
  +	  </div>
  +	  <p>&nbsp;</p>
  +	</td>
  +      </tr>
  +
  +      <tr>
  +	<td>
  +
  +	  <a name="changes"></a>
  +	  <h3>
  +	    <font color="#008B8B">
  +	      Changes:
  +	    </font>
  +	  </h3>
  +
  +	  <ul>
  +
  +	    <li> 
  +      The Guide's <a href="CHANGES">Changes</a> file.
  +	    </li>
  +	  </ul>
  +
  +	</td>
  +      </tr>
  +
  +      <tr>
  +	<td>
  +
  +	  <a name="download"></a>
  +	  <h3>
  +	    <font color="#008B8B">
  +	      Download:
  +	    </font>
  +	  </h3>
  +	
  +
  +	  <ul>
  +
  +	    <li> 
  +	      The latest CVS snapshots of the POD sources
  +	      and the build script you can build the HTMLs from,
  +	      are available from  <a
  +		href="http://www.stason.org/guide-snapshots/">
  +		http://www.stason.org/guide-snapshots/</a>.
  +	    </li>
  +
  +	    <li> 
  +	      <b>This</b> release's HTML files, POD sources 
  +	      and build script are available from <a
  +		href="http://www.perl.com/CPAN-local/authors/id/S/ST/STAS/">
  +		my directory at CPAN or its mirrors</a>.
  +	    </li>
  +
  +	    <li> 
  +	      <!-- this link must be FQDN, since the split version
  +	      will link to the broken link if you don't do it, since
  +	      we don't copy the pdf to the split version -->
  +	      Here is the <a href="http://perl.apache.org/guide/mod_perl_guide.pdf.gz"> Book-like
  +		version </a> (PDF format). To read PDF files you can
  +		use: <code>ghostview</code> (<code>gv</code>),
  +	      <code>xpdf</code> or <code>acroread</code>.  You can use the
  +	      <code>pdf2ps</code> utility to convert PDF to
  +	      PostSscript format.
  +	    </li>
  +
  +	  </ul>
  +
  +	</td>
  +      </tr>
  +
  +      <tr>
  +	<td>
  +
  +	  <A NAME="search"></A>
  +	  <h3>
  +	    <font color="#008B8B">
  +	      Search:
  +	    </font>
  +	  </h3>
  +
  +	  <div class="search">
  +	    Using <a
  +	    href="http://www.nexial.com/nextrieve/"><b>nextrieve</b></a>
  +	    engine on <b>split</b> Guide version (by Vivek Khera):
  +	    <form
  +	      action="http://thingy.kcilink.com/cgi-bin/modperlguide.cgi"
  +	      method="post">
  +	      <center>
  +		<input type=text name=q value="" size=25> 
  +		<input type=submit value=" Search ">
  +	      </center>
  +	    </form>
  +	  </div>
  +
  +	  <div class="search">	
  +	    Using
  +	    <a href="http://sunsite.berkeley.edu/SWISH-E/">
  +	      <b>SWISH-E</b></a> engine + Perl filters on <b>split</b>
  +	      Guide version (by Randy Kobes):
  +	    <form method="GET"
  +	      action="http://theoryx5.uwinnipeg.ca/cgi-bin/guide-search"
  +	      enctype="application/x-www-form-urlencoded" name="search">
  +	      <center>
  +		<input type="text" name="query" size=25>
  +		<input type="submit" name="Submit" value=" Search ">
  +		<input type="hidden" name=".cgifields" value="where">
  +		<input type="hidden" name=".cgifields" value="match">
  +	      </center>
  +	    </form>
  +	  </div>
  +
  +	  <div class="search">	  
  +	    Using
  +	    <a href="http://sunsite.berkeley.edu/SWISH-E/">
  +	      <b>SWISH-E</b></A> engine on <b>full</b> Guide version
  +	      (perl.apache.org) (bad results):
  +	    <form action="http://search.apache.org/" method="post">
  +	      <center>
  +		<input type="text" name="keyword" value="" size=25>
  +		<input type="hidden" name="what" value="perl">
  +		<input type="hidden" name="results" value=40>
  +		<input type="submit" value="Search">
  +	      </center>
  +	    </form>    
  +	  </div>
  +	  
  +
  +	</td>
  +      </tr>
  +
  +      <tr>
  +	<td>
  +	  <p>&nbsp;</p>
  +	  <div class="navbar">	  
  +	    [ <A HREF="#toc">TOC</A> ] 
  +			      [ <A HREF="index.html">Dense TOC</A> ] 
  +	    | <a href="#changes">Changes</a>
  +	    | <a href="#download">Download</a>
  +	    | <a href="#search">Search</a> 
  +	  </div>
  +	  <p>&nbsp;</p>
  +	</td>
  +      </tr>
  +
  +      <tr>
  +	<td>	  
  +	  <div class="notice">
  +	    Full Version Master Copy URL: <a
  +	    href="http://perl.apache.org/guide/"><b>http://perl.apache.org/guide</b></a><br>
  +	    Copyright &copy; 1998-2000 Stas Bekman. All rights
  +	    reserved.
  +	  </div>
  +	</td>
  +      </tr>
  +
  +    </table>
  + 
   
  -<CENTER>
  -[ <A HREF="#toc">TOC</A> ] 
  -			      [ <A HREF="index.html">Dense TOC</A> ]
  -[ <A HREF="#changes">Changes</A> ]  
  -[ <A HREF="#download">Download</A> ] 
  -[ <A HREF="#search">Search</A> ]  
  -</CENTER>
  -
  -<HR WIDTH="65%">
  -
  -</td></tr>
  -<tr><td>
  -
  -<A NAME="changes"></A>
  -<h3><font color="#008B8B">
  -Changes:</font></h3>
  -
  -      The Guide <A HREF="CHANGES">Changes</A> file.</LI>
  -
  -</td></tr>
  -<tr><td>
  -
  -<HR WIDTH="65%">
  -
  -<CENTER>
  -[ <A HREF="#toc">TOC</A> ] 
  -			      [ <A HREF="index.html">Dense TOC</A> ]
  -[ <A HREF="#changes">Changes</A> ]  
  -[ <A HREF="#download">Download</A> ] 
  -[ <A HREF="#search">Search</A> ]  
  -</CENTER>
  -
  -<HR WIDTH="65%">
  -</td></tr>
  -<tr><td>
  -
  -      <A NAME="download"><h3><font color="#008B8B">
  -Download:</font></h3>
  -</A>
  -
  -	<UL>
  -
  -	  <LI> 
  -	    The latest CVS snapshots of the POD sources
  -	    and the build script you can build the HTMLs from,
  - 	    are available from  <A
  -	    HREF="http://www.stason.org/guide-snapshots/">
  -	    http://www.stason.org/guide-snapshots/</A>. 
  -	  </LI>
  -
  -	  <LI> 
  -	    <B>This</B> release's HTML files, POD sources 
  -            and build script are available from <A
  -	    HREF="http://www.perl.com/CPAN-local/authors/id/S/ST/STAS/">
  -	    my directory at CPAN or its mirrors</A>.
  -	  </LI>
  -
  -	  <LI> 
  -	    Here is the <A HREF="mod_perl_guide.pdf.gz"> Book-like
  -	    version </A> (PDF format). Note that <CODE>gv</CODE>
  -	    (<CODE>ghostview</CODE>), in addition to viewing PostScript
  -	    files, knows to handle PDF files as well. You can use
  -	    <CODE>pdf2ps</CODE> utility to convert PDF to PostSscript format.
  -	  </LI>
  -
  -	</UL>
  -
  -      </LI>
  -
  -    </UL>
  -
  -</td></tr>
  -<tr><td>
  -
  -<HR WIDTH="65%">
  -
  -<CENTER>
  -[ <A HREF="#toc">TOC</A> ] 
  -			      [ <A HREF="index.html">Dense TOC</A> ]
  -[ <A HREF="#changes">Changes</A> ]  
  -[ <A HREF="#download">Download</A> ] 
  -[ <A HREF="#search">Search</A> ]  
  -</CENTER>
  -
  -<HR WIDTH="65%">
  -</td></tr>
  -<tr><td>
  -
  -<A NAME="search"><h3><font color="#008B8B">
  -Search:</font></h3>
  -</A>
  -
  -<!--
  -<CENTER>
  -<TABLE BORDER=10 CELLSPACING=2 CELLPADDING=8 >
  -<TR BGCOLOR="gray" ALIGN=CENTER VALIGN=TOP>
  -<TD ALIGN=CENTER VALIGN=TOP>
  -<FONT COLOR=WHITE>
  -Search mod_perl FAQs along with this guide 
  -<BR> at www.perlreference.com
  -<FORM action="http://perlreference.com/cgi-bin/mod_perl/search.pl" method="GET">
  -<INPUT type="text" name="q" value="" SIZE=15>
  -<INPUT TYPE="submit" VALUE="Search">
  -</FORM>
  -</FONT>
  -</TD></TR>
  -</TABLE>
  -</CENTER>
  --->
  -
  -<CENTER>
  -<TABLE BORDER=10 CELLSPACING=2 CELLPADDING=8 >
  -<TR BGCOLOR="gray" ALIGN=CENTER VALIGN=TOP>
  -<TD ALIGN=CENTER VALIGN=TOP>
  -<FONT COLOR=WHITE>
  -Search perl.apache.org along with this guide.
  -<FORM ACTION="http://search.apache.org/" METHOD="POST">
  -<INPUT TYPE="text" NAME="keyword" value="" SIZE=15>
  -<input type="hidden" name="what" value="perl">
  -<input type="hidden" name="results" value=40>
  -<INPUT TYPE="submit" VALUE="Search">
  -</FORM>
  -</FONT>
  -</TD></TR>
  -</TABLE>
  -</CENTER>
  -
  -</td></tr>
  -<tr><td>
  -
  -<HR WIDTH="65%">
  -
  -<CENTER>
  -[ <A HREF="#toc">TOC</A> ] 
  -			      [ <A HREF="index.html">Dense TOC</A> ]
  -[ <A HREF="#changes">Changes</A> ]  
  -[ <A HREF="#download">Download</A> ] 
  -[ <A HREF="#search">Search</A> ]  
  -</CENTER>
  -
  -<HR WIDTH="65%">
  -
  -</td></tr>
  -<tr><td>
  -
  -	     The <a href="http://www.modperl.com/">
  -	     <B>Writing Apache Modules with Perl and C</B></a>
  -	     book can be purchased online from <a
  -	     href="http://www.ora.com/catalog/wrapmod/">O'Reilly </a>
  -	     and <a
  -	     href="http://www.amazon.com/exec/obidos/ASIN/156592567X/writinapachemodu">
  -	     Amazon.com</a>.
  -
  -</td></tr>
  -<tr><td>
  -
  -<HR WIDTH="100%">
  -<CENTER>
  -Master Copy URL: <B>http://perl.apache.org/guide</B><BR>
  -Copyright &copy; 1998-2000 Stas Bekman. All rights reserved.
  -</CENTER>
  -
  -</td></tr>
  -</table>
  -
  -<HR WIDTH="100%">
  -
  -<CENTER>
  -<TABLE CELLSPACING=2 CELLPADDING=2 WIDTH="100%" >
  -
  -<TR ALIGN=CENTER VALIGN=TOP>
  -<TD ALIGN=CENTER VALIGN=CENTER><B><FONT SIZE=-1>Written by <A
  -HREF="help.html#This_document_s_Author">Stas Bekman</A>.<BR> Last Modified at 05/13/2000
  -</FONT></B></TD>
  -
  -<TD><A HREF="http://perl.apache.org"><IMG SRC="images/mod_perl2.jpg"  BORDER=0 ALT="Mod Perl Icon" BORDER=0 HEIGHT=59 WIDTH=150></A>
  -</TD>
  -
  -<TD><FONT SIZE=-2>Use of the Camel for Perl is <BR>
  -a trademark of <A HREF="http://www.ora.com">O'Reilly &amp; Associates</A>,<BR>
  -and is used by permission. </FONT> </TD>
  -</TR>
  -</TABLE></CENTER>
  +    <hr>
   
  -</BODY>
  -</HTML>
  +    <center>
  +      <table cellspacing=2 cellpadding=2>
  +	
  +	<tr align=center valign=top>
  +	  <td align=center valign=center>
  +	    
  +	    <b><font size=-1>
  +		Written by <a
  +		  href="help.html#Contacting_me">Stas
  +		  Bekman</a>.<br> Last Modified at 06/07/2000
  +	      </font></b>
  +	    <br>
  +	    
  +	  </td>
  +
  +	  <td>
  +	    
  +	    <a href="http://perl.apache.org"><img
  +	    src="images/mod_perl2.jpg"
  +		border=0 alt="Mod Perl Icon" border=0 height=59 width=150></a>
  +	    <br>
  +
  +	  </td>
  +
  +	  <td>
  +
  +	    <font size=-2>
  +	      Use of the Camel for Perl is <BR> a trademark of <A
  +	      HREF="http://www.ora.com">O'Reilly &amp;
  +	      Associates</A>,<BR> and is used by permission. 
  +	    </font>
  +	    <br>
  +	    
  +	  </td>
  +	  
  +	</tr>
  +      </table>
  +    </center>
  +    
  +  </body>
  +</html>
   
  
  
  
  1.15      +4290 -1501modperl-site/guide/install.html
  
  Index: install.html
  ===================================================================
  RCS file: /home/cvs/modperl-site/guide/install.html,v
  retrieving revision 1.14
  retrieving revision 1.15
  diff -u -r1.14 -r1.15
  --- install.html	2000/05/12 22:42:52	1.14
  +++ install.html	2000/06/07 22:45:32	1.15
  @@ -1,29 +1,37 @@
   <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
  -<HTML>
  -<HEAD>
  -   <TITLE>mod_perl guide: mod_perl Installation</TITLE>
  -   <META NAME="GENERATOR" CONTENT="Pod2HTML [Perl/Linux]">
  -   <META NAME="Author" CONTENT="Stas Bekman">
  -   <META NAME="Description" CONTENT="All Apache/Perl related information: Hints, Guidelines, Scenarios and Troubleshottings">
  -   <META NAME="keywords" CONTENT="mod_perl modperl perl apache cgi webserver speed  fast guide mod_perl apache guide help info faq mod_perl installation cgi troubleshooting help no sex speedup free open source OSS mod_perl apache guide">
  -</HEAD>
  -     <LINK REL=STYLESHEET TYPE="text/css"
  -        HREF="style.css" TITLE="refstyle">
  -     <style type="text/css">
  -     <!-- 
  -        @import url(style.css);
  -     -->
  -     
  -     </style>
  -<BODY BGCOLOR="white">
  +<html>
  +  <head>
  +   <title>mod_perl guide: mod_perl Installation</title>
  +   <meta name="Author" content="Stas Bekman">
  +   <meta name="Description" content="All Apache/Perl related information: Hints, Guidelines, Scenarios and Troubleshottings">
  +   <meta name="keywords" content="mod_perl modperl perl cgi apache webserver speed fast guide mod_perl apache guide help info faq mod_perl installation cgi troubleshooting help no sex speedup free open source OSS mod_perl apache guide">
  +   <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
  +   <meta name="Classification" content="information">
  +   <link href="style.css" rel=stylesheet type="text/css" title="refstyle">
  +  </head>
  +  <body>
  +
  +    <h1 align=center>
  +      <a href="http://perl.apache.org"><img src="images/mod_perl.gif" alt="Mod Perl Icon" border=0 height=30 width=90 align=left></a>
  +      <a href="http://perl.apache.org"><img src="images/mod_perl.gif" alt="Mod Perl Icon" border=0 height=30 width=90 align=right></a>
  +      mod_perl Installation
  +    </h1>
  +    <hr>
  +    <p>
  +    <div class="navbar">
  +      <a href="perl.html">Prev</a>                                 |
  +      <a href="index.html"         >Contents</a> |
  +      <a href="index.html#search"  >Search</a>   |
  +      <a href="index.html#download">Download</a> |
  +      <a href="config.html">Next</a>
  +    </div>
  +    <p>
  +
  +    <div class="toc">
  +      
   <A NAME="toc"></A>
  -<H1 ALIGN=CENTER>
  -<A HREF="http://perl.apache.org"><IMG SRC="images/mod_perl.gif" ALT="Mod Perl Icon" BORDER=0 HEIGHT=30 WIDTH=90 ALIGN=LEFT></A>
  -<A HREF="http://perl.apache.org"><IMG SRC="images/mod_perl.gif" ALT="Mod Perl Icon" BORDER=0 HEIGHT=30 WIDTH=90 ALIGN=RIGHT></A>
  -mod_perl Installation</H1>
  -<HR WIDTH="100%">
  -	    [    <A HREF="perl.html">Prev</A> |      <A HREF="index.html">Main Page</A> | <A HREF="config.html">Next</A>      ]<HR><!-- INDEX BEGIN -->
  -<P><B><FONT SIZE=-1>Table of Contents:</FONT></B></P>
  +<P><B>Table of Contents:</B></P>
  +
   <UL>
   
   	<LI><A HREF="#Installing_mod_perl_in_10_Minute">Installing mod_perl in 10 Minutes and 10 Command Lines</A>
  @@ -191,39 +199,64 @@
   
   	<LI><A HREF="#OS_Related_Notes">OS Related Notes</A>
   </UL>
  -<!-- INDEX END -->
   
  +    </div>
  +
  +    [ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
   <HR>
  +    <table width="60%" align="center">
  +
  +      <tr>
  +	<td>
  +	  <div class="ad">
  +	    The <a href="http://www.modperl.com/">
  +	      <B>Writing Apache Modules with Perl and C</B></a>
  +	    book can be purchased online from <a
  +	      href="http://www.ora.com/catalog/wrapmod/">O'Reilly </a>
  +	    and <a
  +	    href="http://www.amazon.com/exec/obidos/ASIN/156592567X/writinapachemodu">
  +	      Amazon.com</a>.
  +	  </div>
  +	</td>
  +      </tr>
  +
  +      <tr>
  +	<td>
  +	  <div class="notice">
  +	  <B>Your corrections of the technical and grammatical
  +	     errors are very welcome. You are encouraged to help me
  +	     improve this guide.  If you have something to contribute
  +	     please <A HREF="help.html#Contacting_me"> send it
  +	     directly to me</A>.</B>
  +	  </div>
  +	</td>
  +      </tr>
  +
  +</table>
  +
  +    
   
  -	     The <a href="http://www.modperl.com/">
  -	     <B>Writing Apache Modules with Perl and C</B></a>
  -	     book can be purchased online from <a
  -	     href="http://www.ora.com/catalog/wrapmod/">O'Reilly </a>
  -	     and <a
  -	     href="http://www.amazon.com/exec/obidos/ASIN/156592567X/writinapachemodu">
  -	     Amazon.com</a>.
  -
  -	     <HR>
  -
  -	       <B>Your corrections of either technical or grammatical
  -	       errors are very welcome. You are encouraged to help me
  -	       to improve this guide.  If you have something to
  -	       contribute please <A
  -	       HREF="help.html#Contacting_me"> send it
  -	       directly to me</A>.
  -	       </B>
  -	       <HR>
  +	    [ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   
  -	      <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<P><A NAME="anchor0"></A>
  +<P>
   <CENTER><H1><A NAME="Installing_mod_perl_in_10_Minute">Installing mod_perl in 10 Minutes and 10 Command Lines</A></H1></CENTER>
  -<P><A NAME="anchor1"></A>
  +<P>
   Did you know that it takes about 10 minutes to build and install mod_perl
   enabled Apache on a pretty average processor with a decent amount of system
   memory? It goes like this:
  +
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
   
  -<P><A NAME="anchor2"></A>
  -<PRE>  % cd /usr/src
  +	<td>
  +	  <pre>  % cd /usr/src
     % lwp-download <A HREF="http://www.apache.org/dist/apache_x.x.x.tar.gz">http://www.apache.org/dist/apache_x.x.x.tar.gz</A>
     % lwp-download <A HREF="http://perl.apache.org/dist/mod_perl-x.xx.tar.gz">http://perl.apache.org/dist/mod_perl-x.xx.tar.gz</A>
     % tar xzvf apache_x.x.x.tar.gz
  @@ -233,59 +266,87 @@
       DO_HTTPD=1 USE_APACI=1 EVERYTHING=1
     % make &amp;&amp; make test &amp;&amp; make install
     % cd ../apache_x.x.x
  -  % make install
  -</PRE>
  -<P><A NAME="anchor3"></A>
  +  % make install</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   That's all!
   
  -<P><A NAME="anchor4"></A>
  +<P>
   * Of course you should replace <EM>x.xx</EM> and <EM>x.x.x</EM> with the real version numbers of mod_perl and Apache.
   
  -<P><A NAME="anchor5"></A>
  +<P>
   * The GNU <CODE>tar</CODE> utility knows how to uncompress (the <CODE>z</CODE> flag).
   
  -<P><A NAME="anchor6"></A>
  +<P>
   All that's left is to add a few configuration lines to <CODE>httpd.conf</CODE>, the Apache configuration file, start the server and enjoy mod_perl.
   
  -<P><A NAME="anchor7"></A>
  +<P>
   If you have stumbled upon a problem at any of the above steps, don't
   despair, the next sections will explain in detail each and every step.
   
  -<P><A NAME="anchor8"></A>
  +<P>
   Of course there is a way of installing mod_perl in only a couple of minutes
   if you are using a Linux distrbution that uses RPM or deb files: 
   
  -<P><A NAME="anchor9"></A>
  -<PRE>  % rpm -i apache-xx.xx.rpm
  -  % rpm -i mod_perl-xx.xx.rpm
  -</PRE>
  -<P><A NAME="anchor10"></A>
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  % rpm -i apache-xx.xx.rpm
  +  % rpm -i mod_perl-xx.xx.rpm</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   or
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor11"></A>
  -<PRE>  % dpkg -i apache-xx.xx.deb
  -  % dpkg -i mod_perl-xx.xx.deb
  -</PRE>
  -<P><A NAME="anchor12"></A>
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  % dpkg -i apache-xx.xx.deb
  +  % dpkg -i mod_perl-xx.xx.deb</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   These should set up both Apache and mod_perl correctly for your system.
   Using a packaged distribution can make installing and reinstalling a lot
   quicker and easier. (Note that the filenames will vary, and <EM>xx.xx</EM> will differ.)
   
  -<P><A NAME="anchor13"></A>
  +<P>
   Since mod_perl can be configured in many different ways (features can be
   enabled or disabled, directories can be modified, etc.) it's preferable to
   use a manual installation, as a prepackaged version might not suite your
   needs. Manual installation will allow you to make the fine tuning for the
   best performance as well.
   
  -<P><A NAME="anchor14"></A>
  +<P>
   We will talk in extension about the prepackaged versions and scenarios to
   prepare your own packages for reuse on many machines in this chapter.
   
  -<P><A NAME="anchor15"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H1><A NAME="The_Gory_Details">The Gory Details</A></H1></CENTER>
  -<P><A NAME="anchor16"></A>
  +<P>
   We saw that the basic mod_perl installation is quite simple and takes about
   10 commands. You can copy and paste them from these pages. The parameter <CODE>EVERYTHING=1</CODE> selects a lot of options, but sometimes you will need different ones. You
   may need to pass only specific parameters, to bundle other components with
  @@ -293,12 +354,12 @@
   of compiling it into Apache, so that it can be upgraded without rebuilding
   Apache itself.
   
  -<P><A NAME="anchor17"></A>
  +<P>
   To accomplish this you will need to understand various techniques for
   mod_perl configuration and building. You need to know what configuration
   parameters are available to you and when and how to use them.
   
  -<P><A NAME="anchor18"></A>
  +<P>
   As with Perl, with mod_perl simple things are simple. But when you need to
   accomplish more complicated tasks you may have to invest some time to gain
   a deeper understanding of the process. In this chapter I will take the
  @@ -311,7 +372,7 @@
   general issues that can cause new users to stumble while installing
   mod_perl.
   
  -<P><A NAME="anchor19"></A>
  +<P>
   We can clearly separate the installation process into the following stages:
   
   <UL>
  @@ -320,33 +381,46 @@
   <P><LI><STRONG><A NAME="item_Testing">Testing and</A></STRONG>
   <P><LI><STRONG><A NAME="item_Installation">Installation.</A></STRONG>
   </UL>
  -<P><A NAME="anchor20"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="Source_Configuration_perl_Makef">Source Configuration (perl Makefile.PL ...)</A></H2></CENTER>
  -<P><A NAME="anchor21"></A>
  +<P>
   Before building and installing mod_perl you have to configure it. You
   configure mod_perl just like any other Perl module:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor22"></A>
  -<PRE>  % perl Makefile.PL [parameters]
  -</PRE>
  -<P><A NAME="anchor23"></A>
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  % perl Makefile.PL [parameters]</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   In this section we will go through most of the parameters mod_perl can
   accept and explain each one of them.
   
  -<P><A NAME="anchor24"></A>
  +<P>
   First let's see what configuration mechanisms we have available. Basically
   they all define a special set of parameters to be passed to
   <CODE>perl Makefile.PL</CODE>. Depending on the chosen configuration, the final product might be a
   stand-alone httpd binary or a loadable object.
   
  -<P><A NAME="anchor25"></A>
  +<P>
   The source configuration mechanism in Apache 1.3 provides four major
   features from which mod_perl can benefit:
   
   <DL>
   <P><DT><STRONG><A NAME="item_Per">Per-module configuration scripts (ConfigStart/End)</A></STRONG><DD>
  -<P><A NAME="anchor26"></A>
  +<P>
   This is a mechanism modules can use to link themselves into the
   configuration process. It is useful for automatically adjusting the
   configuration and build parameters from the modules sources. It is
  @@ -354,44 +428,44 @@
   <EM>modulename</EM><CODE>.module</CODE> files.
   
   <P><DT><STRONG><A NAME="item_Apache">Apache Autoconf-style Interface (APACI)</A></STRONG><DD>
  -<P><A NAME="anchor27"></A>
  +<P>
   This is the new top-level <CODE>configure</CODE> script from Apache 1.3 which provides a GNU Autoconf-style interface. It is
   useful for configuring the source tree without manually editing any <CODE>src/Configuration</CODE>
   files. Any parameterization can be done via command line options to the <CODE>configure</CODE> script. Internally this is just a nifty wrapper to the old <CODE>src/Configure</CODE> script.
   
  -<P><A NAME="anchor28"></A>
  +<P>
   Since Apache 1.3 this is the way to install mod_perl as cleanly as
   possible. Currently this is a pure Unix-based solution because at present
   the complete Apache 1.3 source configuration mechanism is only available
   under Unix. It doesn't work on the Win32 platform for example.
   
   <P><DT><STRONG><A NAME="item_Dynamic">Dynamic Shared Object (DSO) support</A></STRONG><DD>
  -<P><A NAME="anchor29"></A>
  +<P>
   Besides Windows NT support this is one of most interesting features in
   Apache 1.3. Its a way to build Apache modules as so-called <CODE>dynamic
   shared objects</CODE> (usually named <EM>modulename</EM><CODE>.so</CODE>) which can be loaded via the <CODE>LoadModule</CODE> directive in Apache's <CODE>httpd.conf</CODE> file. The benefit is that the modules are part of the <CODE>httpd</CODE> program only on demand, i.e. only when the user wants a module is it loaded
   into the address space of the <CODE>httpd</CODE> executable. This is interesting for instance in relation to memory
   consumption and upgrading.
   
  -<P><A NAME="anchor30"></A>
  +<P>
   The DSO mechanism is provided by Apache's <CODE>mod_so</CODE> module which needs to be compiled into the <CODE>httpd</CODE> binary. This is done automatically when DSO is enabled for module <CODE>mod_xxx</CODE> via <CODE>configure
   --enable-module=xxx</CODE> or by explicitly adding <CODE>mod_so</CODE> via <CODE>configure
   --enable-module=so</CODE>.
   
   <P><DT><STRONG><A NAME="item_APache">APache eXtenSion (APXS) support tool</A></STRONG><DD>
  -<P><A NAME="anchor31"></A>
  +<P>
   This is a new support tool from Apache 1.3 which can be used to build an
   Apache module as a DSO even <STRONG>outside</STRONG> the Apache source-tree. One can say <CODE>APXS</CODE> is for Apache what <CODE>MakeMaker</CODE> and <CODE>XS</CODE> are for Perl. It knows the platform dependent build parameters for making
   DSO files and provides an easy way to run the build commands with them.
   
   </DL>
  -<P><A NAME="anchor32"></A>
  +<P>
   Taking these four features together provides a way to integrate mod_perl
   into Apache in a very clean and smooth way.  <EM>No patching of
   the Apache source tree is needed in the standard situation and in the
   APXS situation not even the Apache source tree is needed</EM>.
   
  -<P><A NAME="anchor33"></A>
  +<P>
   To benefit from the above features a new hybrid build environment was
   created for the Apache side of mod_perl. The Apache-side consists of the C
   source files of mod_perl which have to be compiled into the
  @@ -400,122 +474,207 @@
   process a lot of adjustments were done by mod_perl's <CODE>Makefile.PL</CODE> in the past. And additionally the
   <CODE>Makefile.PL</CODE> controlled the Apache build process.
   
  -<P><A NAME="anchor34"></A>
  +<P>
   This approach is problematic in several ways. It is very restrictive and
   not very clean because it assumes that mod_perl is the only third-party
   module which has to be integrated into Apache.
   
  -<P><A NAME="anchor35"></A>
  +<P>
   The new approach described below avoids these problems. It prepares only
   the <CODE>src/modules/perl/</CODE> subtree inside the Apache source tree
   <EM>without</EM> adjusting or editing anything else. This way, no conflicts can occur.
   Instead, mod_perl is activated later (when the Apache source tree is
   configured, via APACI calls) and then it configures itself.
   
  -<P><A NAME="anchor36"></A>
  +<P>
   We will return to each of the above configuration mechanisms when
   describing different installation passes, once the overview of the four
   building steps is completed.
   
  -<P><A NAME="anchor37"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H3><A NAME="Configuration_parameters">Configuration parameters</A></H3></CENTER>
  -<P><A NAME="anchor38"></A>
  +<P>
   <CODE>perl Makefile.PL</CODE> accepts various parameters. In this section we will learn what they are,
   and when should they be used.
   
  -<P><A NAME="anchor39"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H4><A NAME="APACHE_SRC">APACHE_SRC</A></H4></CENTER>
  -<P><A NAME="anchor40"></A>
  +<P>
   You will be asked the following question during the configuration stage:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor41"></A>
  -<PRE>  &quot;Configure mod_perl with ../apache_x.x.x/src ?&quot;
  -</PRE>
  -<P><A NAME="anchor42"></A>
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  &quot;Configure mod_perl with ../apache_x.x.x/src ?&quot;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   <CODE>APACHE_SRC</CODE> should be used to define Apache's source tree directory. For example:
   
  -<P><A NAME="anchor43"></A>
  -<PRE>  APACHE_SRC=../apache_x.x.x/src
  -</PRE>
  -<P><A NAME="anchor44"></A>
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  APACHE_SRC=../apache_x.x.x/src</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Unless <CODE>APACHE_SRC</CODE> is specified, <EM>Makefile.PL</EM> makes an intelligent guess by looking at the directories at the same level
   as the mod_perl sources and suggests a directory with the highest version
   of Apache found there.
   
  -<P><A NAME="anchor45"></A>
  +<P>
   Answering <EM>'y'</EM> confirms either <EM>Makefile.PL</EM>'s guess about the location of the tree, or the directory you have
   specified with
   <CODE>APACHE_SRC</CODE>.
   
  -<P><A NAME="anchor46"></A>
  +<P>
   If you use <CODE>DO_HTTPD=1</CODE> or <CODE>NO_HTTPD</CODE>, the first apache source tree found or the one you have defined will be
   used for the rest of the build process.
   
  -<P><A NAME="anchor47"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H4><A NAME="DO_HTTPD_NO_HTTPD_PREP_HTTPD">DO_HTTPD, NO_HTTPD, PREP_HTTPD</A></H4></CENTER>
  -<P><A NAME="anchor48"></A>
  +<P>
   Unless any of <CODE>DO_HTTPD</CODE>, <CODE>NO_HTTPD</CODE> or <CODE>PREP_HTTPD</CODE> is used, you will be prompted by the following question:
  +
  +<P>
   
  -<P><A NAME="anchor49"></A>
  -<PRE>  &quot;Shall I build httpd in ../apache_x.x.x/src for you?&quot;
  -</PRE>
  -<P><A NAME="anchor50"></A>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  &quot;Shall I build httpd in ../apache_x.x.x/src for you?&quot;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Answering <EM>'y'</EM> will make sure an httpd binary will be built in
   <EM>../apache_x.x.x/src</EM> when you run <CODE>make</CODE>.
   
  -<P><A NAME="anchor51"></A>
  +<P>
   To avoid this prompt when the answer is <EM>Yes</EM> use:
  +
  +<P>
   
  -<P><A NAME="anchor52"></A>
  -<PRE>  DO_HTTPD=1
  -</PRE>
  -<P><A NAME="anchor53"></A>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  DO_HTTPD=1</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Note that if you set <CODE>DO_HTTPD=1</CODE>, but do not use
   <CODE>APACHE_SRC=../apache_x.x.x/src</CODE> then the first apache source tree found will be used to configure and build
   against.
   
  -<P><A NAME="anchor54"></A>
  +<P>
   <CODE>PREP_HTTPD=1</CODE> just means default '<CODE>n</CODE>' to the second prompt, meaning <EM>do not build (make) httpd in the Apache source tree</EM>. But it will still ask you about Apache's source location even if you have
   used the <CODE>APACHE_SRC</CODE> parameter. Providing the <CODE>APACHE_SRC</CODE>
   parameter will just eliminate the need for <CODE>perl Makefile.PL</CODE> to make a guess.
   
  -<P><A NAME="anchor55"></A>
  +<P>
   To avoid the two prompts and avoid building httpd, use:
  +
  +<P>
   
  -<P><A NAME="anchor56"></A>
  -<PRE>  NO_HTTPD=1
  -</PRE>
  -<P><A NAME="anchor57"></A>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  NO_HTTPD=1</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   If you choose not to build the binary you will have to do that manually. We
   will talk about it later. In any case you will need to run <CODE>make install</CODE> in the mod_perl source tree, so the Perl side of mod_perl will be
   installed. Note that, <CODE>make test</CODE> won't work until you have built the server.
   
  -<P><A NAME="anchor58"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H4><A NAME="Callback_Hooks">Callback Hooks</A></H4></CENTER>
  -<P><A NAME="anchor59"></A>
  +<P>
   A callback hook (abbrev. <EM>callback</EM>) is a reference to a subroutine. In Perl we create callbacks with the $callback&nbsp;=
   \&subroutine syntax, where in this example, <CODE>$callback</CODE> contains a reference to the subroutine called <EM>"subroutine"</EM>. Callbacks are used when we want some action (subroutine call) to occur
   when some event takes place. Since we don't know exactly when the event
   will take place we give the event handler a callback to the subroutine we
   want executed. The handler will call our subroutine at the right time.
   
  -<P><A NAME="anchor60"></A>
  +<P>
   By default, all callback hooks except for <CODE>PerlHandler</CODE> are turned off. You may enable them by editing <EM>src/modules/perl/Makefile</EM>, or when running <CODE>perl Makefile.PL</CODE>.
   
  -<P><A NAME="anchor61"></A>
  +<P>
   Possible parameters are:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor62"></A>
  -<PRE>  PERL_POST_READ_REQUEST
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  PERL_POST_READ_REQUEST
     PERL_TRANS
  -  PERL_INIT
  -</PRE>
  -<P><A NAME="anchor63"></A>
  -<PRE>  PERL_HEADER_PARSER
  +  PERL_INIT</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  PERL_HEADER_PARSER
     PERL_AUTHEN
     PERL_AUTHZ
     PERL_ACCESS
  @@ -530,155 +689,273 @@
     PERL_STACKED_HANDLERS
     PERL_METHOD_HANDLERS
     PERL_SECTIONS
  -  PERL_SSI
  -</PRE>
  -<P><A NAME="anchor64"></A>
  +  PERL_SSI</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   As with any parameters that are either defined or not, use
   <CODE>PERL_hookname=1</CODE> to enable them (e.g. <CODE>PERL_AUTHEN=1</CODE>).
   
  -<P><A NAME="anchor65"></A>
  +<P>
   To enable all callback hooks use:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor66"></A>
  -<PRE>  ALL_HOOKS=1
  -</PRE>
  -<P><A NAME="anchor67"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  ALL_HOOKS=1</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H4><A NAME="EVERYTHING">EVERYTHING</A></H4></CENTER>
  -<P><A NAME="anchor68"></A>
  +<P>
   To enable everything set:
  +
  +<P>
   
  -<P><A NAME="anchor69"></A>
  -<PRE>  EVERYTHING=1
  -</PRE>
  -<P><A NAME="anchor70"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  EVERYTHING=1</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H4><A NAME="PERL_TRACE">PERL_TRACE</A></H4></CENTER>
  -<P><A NAME="anchor71"></A>
  +<P>
   To enable <A HREF="././debug.html#Debug_Tracing">debug tracing</A> set: <CODE>PERL_TRACE=1</CODE>
   
   
   
  -<P><A NAME="anchor72"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H4><A NAME="APACHE_HEADER_INSTALL">APACHE_HEADER_INSTALL</A></H4></CENTER>
  -<P><A NAME="anchor73"></A>
  +<P>
   By default, the Apache source headers files are installed into the
   <EM>$Config{sitearchexp}/auto/Apache/include</EM> directory.
   
  -<P><A NAME="anchor74"></A>
  +<P>
   The reason for installing the header files is to make life simpler for
   module authors/users when building/installing a module that taps into some
   Apache C functions, e.g. <CODE>Embperl</CODE>, <CODE>Apache::Peek</CODE>, etc.
   
  -<P><A NAME="anchor75"></A>
  +<P>
   If you don't wish to install these files use:
  +
  +<P>
   
  -<P><A NAME="anchor76"></A>
  -<PRE>  APACHE_HEADER_INSTALL=0
  -</PRE>
  -<P><A NAME="anchor77"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  APACHE_HEADER_INSTALL=0</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H4><A NAME="PERL_STATIC_EXTS">PERL_STATIC_EXTS</A></H4></CENTER>
  -<P><A NAME="anchor78"></A>
  +<P>
   Normally, if an extension is statically linked with Perl it is listed in
   <CODE>Config.pm</CODE>'s <CODE>$Config{static_exts}</CODE>, in which case mod_perl will also statically link this extension with
   httpd. However, if an extension is statically linked with Perl after it is
   installed, it is not listed in
   <CODE>Config.pm</CODE>. You may either edit <CODE>Config.pm</CODE> and add these extensions, or configure mod_perl like this:
   
  -<P><A NAME="anchor79"></A>
  -<PRE> perl Makefile.PL &quot;PERL_STATIC_EXTS=Something::Static Another::One&quot; 
  -</PRE>
  -<P><A NAME="anchor80"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre> perl Makefile.PL &quot;PERL_STATIC_EXTS=Something::Static Another::One&quot; </pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H4><A NAME="PERL_MARK_WHERE">PERL_MARK_WHERE</A></H4></CENTER>
  -<P><A NAME="anchor81"></A>
  +<P>
   Generally for <CODE>Apache::Registry</CODE> scripts, the reported line number for warnings and errors that end up in
   the <EM>error_log</EM> file is not correct. This is due to the fact that <CODE>Apache::Registry</CODE>
   auto-magically wraps the scripts running under its handler in special code
   that enables the caching of the compiled scripts.
   
  -<P><A NAME="anchor82"></A>
  +<P>
   If configured with <CODE>PERL_MARK_WHERE=1</CODE>, mod_perl will attempt to compensate for this effect and show the exact
   line which triggered the error or warning.
   
  -<P><A NAME="anchor83"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H4><A NAME="APACI_ARGS">APACI_ARGS</A></H4></CENTER>
  -<P><A NAME="anchor84"></A>
  +<P>
   When you use the <CODE>USE_APACI=1</CODE> parameter, you can tell <CODE>Makefile.PL</CODE>
   to pass any arguments you want to the Apache <CODE>./configure</CODE> utility, e.g:
   
  -<P><A NAME="anchor85"></A>
  -<PRE>  % perl Makefile.PL USE_APACI=1 \
  -  APACI_ARGS=--sbindir=/usr/local/sbin/httpd_perl, \
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  % perl Makefile.PL USE_APACI=1 \
  +  APACI_ARGS='--sbindir=/usr/local/sbin/httpd_perl, \
            --sysconfdir=/usr/local/etc/httpd_perl, \
            --localstatedir=/usr/local/var/httpd_perl, \
            --runtimedir=/usr/local/var/httpd_perl/run, \
            --logfiledir=/usr/local/var/httpd_perl/logs, \
  -         --proxycachedir=/usr/local/var/httpd_perl/proxy
  -</PRE>
  -<P><A NAME="anchor86"></A>
  +         --proxycachedir=/usr/local/var/httpd_perl/proxy'</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Notice that <STRONG>all</STRONG>  <CODE>APACI_ARGS</CODE> (above) must be passed as one long line if you work with <CODE>t?csh</CODE>!!! However it works correctly as shown above (breaking the long lines with
   '<CODE>\</CODE>') with <CODE>(ba)?sh</CODE>. If you use <CODE>t?csh</CODE> it does not work, since <CODE>t?csh</CODE> passes the <CODE>APACI_ARGS</CODE>
   arguments to <CODE>./configure</CODE> leaving the newlines untouched, but stripping the backslashes. This causes
   all the arguments except the first to be ignored by the configuration
   process.
   
  -<P><A NAME="anchor87"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H4><A NAME="APACHE_PREFIX">APACHE_PREFIX</A></H4></CENTER>
  -<P><A NAME="anchor88"></A>
  +<P>
   If you want to use a non-default Apache installation directory, use the <CODE>APACHE_PREFIX</CODE> parameter, e.g.:
  +
  +<P>
   
  -<P><A NAME="anchor89"></A>
  -<PRE>  % perl Makefile.PL APACHE_PREFIX=/usr/local/ [...]
  -</PRE>
  -<P><A NAME="anchor90"></A>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  % perl Makefile.PL APACHE_PREFIX=/usr/local/ [...]</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   This should be used together with the <A HREF="././install.html#APACI_ARGS">APACI_ARGS</A>
   option.
   
  -<P><A NAME="anchor91"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H3><A NAME="Environment_Variables">Environment Variables</A></H3></CENTER>
  -<P><A NAME="anchor92"></A>
  +<P>
   There are a few enviroment variables that influence the build/test process.
   
  -<P><A NAME="anchor93"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H4><A NAME="APACHE_USER_and_APACHE_GROUP">APACHE_USER and APACHE_GROUP</A></H4></CENTER>
  -<P><A NAME="anchor94"></A>
  +<P>
   You can use the environment variables <CODE>APACHE_USER</CODE> and
   <CODE>APACHE_GROUP</CODE> to override the default <CODE>User</CODE> and <CODE>Group</CODE> settings in the <EM>httpd.conf</EM> used for 'make&nbsp;test' stage. (Introduced in mod_perl v1.23.)
   
  -<P><A NAME="anchor95"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H3><A NAME="Reusing_Configuration_Parameters">Reusing Configuration Parameters</A></H3></CENTER>
  -<P><A NAME="anchor96"></A>
  +<P>
   When you have to upgrade the server, it's quite hard to remember what
   parameters were used in a mod_perl build. So it's better to save them in a
   file. For example if you create a file at
   <EM>~/.mod_perl_build_options</EM>, with contents:
   
  -<P><A NAME="anchor97"></A>
  -<PRE>  APACHE_SRC=../apache_x.x.x/src DO_HTTPD=1 USE_APACI=1 \
  -  EVERYTHING=1
  -</PRE>
  -<P><A NAME="anchor98"></A>
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  APACHE_SRC=../apache_x.x.x/src DO_HTTPD=1 USE_APACI=1 \
  +  EVERYTHING=1</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   You can build the server with the following command:
   
  -<P><A NAME="anchor99"></A>
  -<PRE>  % perl Makefile.PL `cat ~/.mod_perl_build_options`
  -  % make &amp;&amp; make test &amp;&amp; make install
  -</PRE>
  -<P><A NAME="anchor100"></A>
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  % perl Makefile.PL `cat ~/.mod_perl_build_options`
  +  % make &amp;&amp; make test &amp;&amp; make install</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   But mod_perl has a standard method to perform this trick. If a file named <EM>makepl_args.mod_perl</EM> is found in the same directory as the mod_perl build location with any of
   these options, it will be read in by <EM>Makefile.PL</EM>. Parameters supplied at the command line will override the parameters
   given in this file.
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor101"></A>
  -<PRE>  % ls -1 /usr/src
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  % ls -1 /usr/src
     apache_x.x.x/
     makepl_args.mod_perl
     mod_perl-x.xx/
  @@ -689,86 +966,129 @@
     
     % cd mod_perl-x.xx
     % perl Makefile.PL
  -  % make &amp;&amp; make test &amp;&amp; make install
  -</PRE>
  -<P><A NAME="anchor102"></A>
  +  % make &amp;&amp; make test &amp;&amp; make install</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Now the parameters from <EM>makepl_args.mod_perl</EM> file will be used, as if they were directly typed in.
   
  -<P><A NAME="anchor103"></A>
  +<P>
   Notice that this file can be located in your home directory or in the
   <EM>../</EM> directory relative to the mod_perl distribution directory. This file can
   also start with dot (<EM>.makepl_args.mod_perl</EM>) so you can keep it nicely hidden along with the rest of the dot files in
   your home directory.
   
  -<P><A NAME="anchor104"></A>
  +<P>
   There is a sample <EM>makepl_args.mod_perl</EM> in the <EM>eg/</EM> directory of the mod_perl distribution package, in which you might find a
   few options to enable experimental features to play with too!
   
  -<P><A NAME="anchor105"></A>
  +<P>
   If you are faced with a compiled Apache and no trace of the parameters used
   to build it, you can usually still find them if the sources were not <CODE>make clean</CODE>'d. You will find the Apache specific parameters in
   <CODE>apache_x.x.x/config.status</CODE> and the mod_perl parameters in
   <CODE>mod_perl_x.xx/apaci/mod_perl.config</CODE>.
   
  -<P><A NAME="anchor106"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H3><A NAME="Discovering_whether_some_option_">Discovering whether some option was configured</A></H3></CENTER>
  -<P><A NAME="anchor107"></A>
  +<P>
   To find out whether some parameter was included in the server, you can take
   a look at the symbols inside the httpd executable with help of
   <CODE>nm</CODE> or a similar utility. For example if you want to see whether you enabled <CODE>PERL_AUTH=1</CODE> while building mod_perl, you do:
  +
  +<P>
   
  -<P><A NAME="anchor108"></A>
  -<PRE>  % nm httpd | grep perl_authenticate
  -</PRE>
  -<P><A NAME="anchor109"></A>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  % nm httpd | grep perl_authenticate</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   But this will only work if you have an unstripped httpd binary. By default, <CODE>make install</CODE> strips the binary before installing it.
   
  -<P><A NAME="anchor110"></A>
  +<P>
   Another approach is to configure <A HREF="././debug.html#Apache_Status_Embedded_Inter">/perl-status location</A> and run <A
   HREF="http://localhost/perl-status?hooks">http://localhost/perl-status?hooks</A>
   to check the enabled hooks.
   
  -<P><A NAME="anchor111"></A>
  +<P>
   Yet another approach is to try to use this parameter in the configuration
   file. If it wasn't enabled Apache will tell you when you start the server,
   by reporting an unknown directive.
   
  -<P><A NAME="anchor112"></A>
  +<P>
   Similarly, for example, when you attempt to use <CODE>PerlAuthenHandler</CODE>
   without building Apache with the <CODE>PERL_AUTHEN=1</CODE> parameter, Apache will give an error message.
   
  -<P><A NAME="anchor113"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H3><A NAME="Using_an_Alternative_Configurati">Using an Alternative Configuration File</A></H3></CENTER>
  -<P><A NAME="anchor114"></A>
  +<P>
   By default mod_perl provides its own copy of the <EM>Configuration</EM> file to Apache's <CODE>./configure</CODE> utility. If you wish to pass it your own version, do this:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor115"></A>
  -<PRE>  % perl Makefile.PL CONFIG=Configuration.custom
  -</PRE>
  -<P><A NAME="anchor116"></A>
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  % perl Makefile.PL CONFIG=Configuration.custom</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Where <CODE>Configuration.custom</CODE> is the full pathname of the file
   <EM>relative to the Apache source tree you build against</EM>.
   
  -<P><A NAME="anchor117"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H3><A NAME="perl_Makefile_PL_Troubleshooting">perl Makefile.PL Troubleshooting</A></H3></CENTER>
  -<P><A NAME="anchor118"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H4><A NAME="_A_test_compilation_with_your_Ma">&quot;A test compilation with your Makefile configuration failed...&quot;</A></H4></CENTER>
  -<P><A NAME="anchor119"></A>
  +<P>
   When you see this during the <CODE>perl Makefile.PL</CODE> stage:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor120"></A>
  -<PRE>  ** A test compilation with your Makefile configuration
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  ** A test compilation with your Makefile configuration
     ** failed. This is most likely because your C compiler
     ** is not ANSI. Apache requires an ANSI C Compiler, such
     ** as gcc. The above error message from your compiler
     ** will also provide a clue.
  -   Aborting!
  -</PRE>
  -<P><A NAME="anchor121"></A>
  +   Aborting!</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   you've got a problem with your compiler. It is possible that it's
   improperly installed or not installed at all. Sometimes the reason is that
   your Perl executable was built on a different machine, and the software
  @@ -777,96 +1097,218 @@
   properly defined in the Perl binary package and you were allowed to install
   it, although some essential package is not installed.
   
  -<P><A NAME="anchor122"></A>
  +<P>
   The most frequent pitfall is a missing gdbm library. See <A HREF="././install.html#Missing_or_Misconfigured_libgdbm">Missing or Misconfigured libgdbm.so</A> for more info.
   
  -<P><A NAME="anchor123"></A>
  +<P>
   But why guess, when we can actually see the real error message and
   understand what the real problem is. To get a real error message, edit the
   Apache <EM>src/Configure</EM> script. Down around line 2140 you will see a line like this:
  +
  +<P>
   
  -<P><A NAME="anchor124"></A>
  -<PRE>   if ./helpers/TestCompile sanity; then
  -</PRE>
  -<P><A NAME="anchor125"></A>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>   if ./helpers/TestCompile sanity; then</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   change it to:
  +
  +<P>
   
  -<P><A NAME="anchor126"></A>
  -<PRE>   if ./helpers/TestCompile -v sanity; then
  -</PRE>
  -<P><A NAME="anchor127"></A>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>   if ./helpers/TestCompile -v sanity; then</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   and try again. Now you should get a useful error message.
   
  -<P><A NAME="anchor128"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H4><A NAME="Missing_or_Misconfigured_libgdbm">Missing or Misconfigured libgdbm.so</A></H4></CENTER>
  -<P><A NAME="anchor129"></A>
  +<P>
   On some RedHat systems you might encounter a problem during the <CODE>perl
   Makefile.PL</CODE> stage, when the installed Perl was built with the <CODE>gdbm</CODE>
   library, but the library isn't actually installed. If this is your
   situation make sure you install it before proceeding with the build
   process.
   
  -<P><A NAME="anchor130"></A>
  +<P>
   You can check how Perl was built by running the <CODE>perl -V</CODE> command:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor131"></A>
  -<PRE>  % perl -V | grep libs
  -</PRE>
  -<P><A NAME="anchor132"></A>
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  % perl -V | grep libs</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   On my machine I get:
   
  -<P><A NAME="anchor133"></A>
  -<PRE>  libs=-lnsl -lndbm -lgdbm -ldb -ldl -lm -lc -lposix -lcrypt
  -</PRE>
  -<P><A NAME="anchor134"></A>
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  libs=-lnsl -lndbm -lgdbm -ldb -ldl -lm -lc -lposix -lcrypt</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Sometimes the problem is even more obscure: you do have <CODE>libgdbm</CODE>
   installed but it's not properly installed. Do this:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor135"></A>
  -<PRE>  % ls /usr/lib/libgdbm.so*
  -</PRE>
  -<P><A NAME="anchor136"></A>
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  % ls /usr/lib/libgdbm.so*</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   If you get at least three lines like I do:
   
  -<P><A NAME="anchor137"></A>
  -<PRE>  lrwxrwxrwx   /usr/lib/libgdbm.so -&gt; libgdbm.so.2.0.0
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  lrwxrwxrwx   /usr/lib/libgdbm.so -&gt; libgdbm.so.2.0.0
     lrwxrwxrwx   /usr/lib/libgdbm.so.2 -&gt; libgdbm.so.2.0.0
  -  -rw-r--r--   /usr/lib/libgdbm.so.2.0.0
  -</PRE>
  -<P><A NAME="anchor138"></A>
  +  -rw-r--r--   /usr/lib/libgdbm.so.2.0.0</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   you are all set. On some installations the <EM>libgdbm.so</EM> symbolic link is missing, so you get only:
  +
  +<P>
   
  -<P><A NAME="anchor139"></A>
  -<PRE>  lrwxrwxrwx   /usr/lib/libgdbm.so.2 -&gt; libgdbm.so.2.0.0
  -  -rw-r--r--   /usr/lib/libgdbm.so.2.0.0
  -</PRE>
  -<P><A NAME="anchor140"></A>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  lrwxrwxrwx   /usr/lib/libgdbm.so.2 -&gt; libgdbm.so.2.0.0
  +  -rw-r--r--   /usr/lib/libgdbm.so.2.0.0</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   To fix this problem add the missing symbolic link:
  +
  +<P>
   
  -<P><A NAME="anchor141"></A>
  -<PRE>  % cd /usr/lib
  -  % ln -s libgdbm.so.2.0.0 libgdbm.so
  -</PRE>
  -<P><A NAME="anchor142"></A>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  % cd /usr/lib
  +  % ln -s libgdbm.so.2.0.0 libgdbm.so</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Now you should be able to build mod_perl without any problems.
   
  -<P><A NAME="anchor143"></A>
  +<P>
   Note that you might need to prepare this symbolic link as well:
  +
  +<P>
   
  -<P><A NAME="anchor144"></A>
  -<PRE>  lrwxrwxrwx   /usr/lib/libgdbm.so.2 -&gt; libgdbm.so.2.0.0
  -</PRE>
  -<P><A NAME="anchor145"></A>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  lrwxrwxrwx   /usr/lib/libgdbm.so.2 -&gt; libgdbm.so.2.0.0</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   with:
  +
  +<P>
   
  -<P><A NAME="anchor146"></A>
  -<PRE>  % ln -s libgdbm.so.2.0.0 libgdbm.so.2
  -</PRE>
  -<P><A NAME="anchor147"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  % ln -s libgdbm.so.2.0.0 libgdbm.so.2</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H4><A NAME="About_gdbm_db_and_ndbm_librarie">About gdbm, db and ndbm libraries</A></H4></CENTER>
  -<P><A NAME="anchor148"></A>
  +<P>
   Both the gdbm and db libraries offer ndbm emulation, which is the interface
   that Apache actually uses, so when you build mod_perl you end up with
   whichever library was linked first by the perl compile. If you build apache
  @@ -878,14 +1320,24 @@
   likely to have trouble copying the dbm file from one system to another or
   even using it after an upgrade.
   
  -<P><A NAME="anchor149"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H4><A NAME="Undefined_reference_to_PL_perl_">Undefined reference to `PL_perl_destruct_level'</A></H4></CENTER>
  -<P><A NAME="anchor150"></A>
  +<P>
   When manually building mod_perl using the shared library:
  +
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
   
  -<P><A NAME="anchor151"></A>
  -<PRE>  cd mod_perl-x.xx
  +	<td>
  +	  <pre>  cd mod_perl-x.xx
     perl Makefile.PL PREP_HTTPD=1
     make
     make test
  @@ -893,13 +1345,25 @@
     
     cd ../apache_x.x.x
     ./configure --with-layout=RedHat --target=perlhttpd 
  -  --activate-module=src/modules/perl/libperl.a
  -</PRE>
  -<P><A NAME="anchor152"></A>
  +  --activate-module=src/modules/perl/libperl.a</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   you might get:
   
  -<P><A NAME="anchor153"></A>
  -<PRE>  gcc -c  -I./os/unix -I./include   -DLINUX=2 -DTARGET=\&quot;perlhttpd\&quot; -DUSE_HSREGEX 
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  gcc -c  -I./os/unix -I./include   -DLINUX=2 -DTARGET=\&quot;perlhttpd\&quot; -DUSE_HSREGEX 
     -DUSE_EXPAT -I./lib/expat-lite `./apaci` buildmark.c
     gcc  -DLINUX=2 -DTARGET=\&quot;perlhttpd\&quot; -DUSE_HSREGEX -DUSE_EXPAT 
     -I./lib/expat-lite `./apaci`    \
  @@ -911,48 +1375,76 @@
     mod_perl.o(.text+0x102): undefined reference to `PL_perl_destruct_level'
     mod_perl.o(.text+0x10c): undefined reference to `PL_perl_destruct_level'
     mod_perl.o(.text+0x13b): undefined reference to `Perl_av_undef'
  -  [more errors snipped]
  -</PRE>
  -<P><A NAME="anchor154"></A>
  +  [more errors snipped]</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   This happens when you have Perl built statically linked, with no shared <EM>libperl.a</EM>. Build a dynamically linked Perl (with
   <EM>libperl.a</EM>) and the problem will disappear.
   
  -<P><A NAME="anchor155"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="mod_perl_Building_make_">mod_perl Building (make)</A></H2></CENTER>
  -<P><A NAME="anchor156"></A>
  +<P>
   After completing the configuration you build the server, by calling:
   
  -<P><A NAME="anchor157"></A>
  -<PRE>  % make
  -</PRE>
  -<P><A NAME="anchor158"></A>
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  % make</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   which compiles the source files and creates an httpd binary and/or a
   separate library for each module, which can either be inserted into the
   httpd binary when <CODE>make</CODE> is called from the Apache source directory or loaded later, at run time.
   
  -<P><A NAME="anchor159"></A>
  +<P>
   Note: don't put the mod_perl directory inside the Apache directory. This
   confuses the build process.
   
  -<P><A NAME="anchor160"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H3><A NAME="make_Troubleshooting">make Troubleshooting</A></H3></CENTER>
  -<P><A NAME="anchor161"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H4><A NAME="Undefined_reference_to_Perl_new">Undefined reference to 'Perl_newAV'</A></H4></CENTER>
  -<P><A NAME="anchor162"></A>
  +<P>
   This and similar error messages may show up during the <CODE>make</CODE>
   process. Generally it happens when you have a broken Perl installation.
   Make sure it's not installed from a broken RPM or another binary package.
   If it is, build Perl from source or use another properly built binary
   package. Run <CODE>perl -V</CODE> to learn what version of Perl you are using and other important details.
   
  -<P><A NAME="anchor163"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H4><A NAME="Unrecognized_format_specifier_fo">Unrecognized format specifier for...</A></H4></CENTER>
  -<P><A NAME="anchor164"></A>
  -<PRE>  From: Scott Fagg &lt;scott.fagg@arup.com.au&gt;
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  From: Scott Fagg &lt;scott.fagg@arup.com.au&gt;
     
     I'm using apache 1.3.9 , mod_fastcgi 2.2.2 and mod_perl 1.21
     
  @@ -981,28 +1473,44 @@
     so too does my fastcgi.
     
     Hope that helps some one. I wasn't able to find any answers to the
  -  problem while searching the net.
  -</PRE>
  -<P><A NAME="anchor165"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +  problem while searching the net.</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="Built_Server_Testing_make_test_">Built Server Testing (make test)</A></H2></CENTER>
  -<P><A NAME="anchor166"></A>
  +<P>
   After building the server, it's a good idea to test it throughly, by
   calling:
  +
  +<P>
   
  -<P><A NAME="anchor167"></A>
  -<PRE>  % make test
  -</PRE>
  -<P><A NAME="anchor168"></A>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  % make test</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Fortunately mod_perl comes with a bunch of tests, which attempt to use all
   the features you asked for at the configuration stage. If any of the tests
   fails, the <CODE>make test</CODE> stage will fail.
   
  -<P><A NAME="anchor169"></A>
  +<P>
   Running <CODE>make test</CODE> will start a freshly built httpd on port 8529 running under the uid and gid
   of the <CODE>perl Makefile.PL</CODE> process. The httpd will be terminated when the tests are finished.
   
  -<P><A NAME="anchor170"></A>
  +<P>
   Each file in the testing suite generally includes more than one test, but
   when you do the testing, the program will only report how many tests were
   passed and the total number of tests defined in the test file. However if
  @@ -1010,310 +1518,642 @@
   To gain this information you should run the tests in verbose mode. You can
   enable this mode by using the <CODE>TEST_VERBOSE</CODE>
   parameter:
  +
  +<P>
   
  -<P><A NAME="anchor171"></A>
  -<PRE>  % make test TEST_VERBOSE=1
  -</PRE>
  -<P><A NAME="anchor172"></A>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  % make test TEST_VERBOSE=1</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   To change the default port (8529) used for the test do this:
  +
  +<P>
   
  -<P><A NAME="anchor173"></A>
  -<PRE>  % perl Makefile.PL PORT=xxxx
  -</PRE>
  -<P><A NAME="anchor174"></A>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  % perl Makefile.PL PORT=xxxx</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   To start the newly built Apache:
  +
  +<P>
   
  -<P><A NAME="anchor175"></A>
  -<PRE>  % make start_httpd
  -</PRE>
  -<P><A NAME="anchor176"></A>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  % make start_httpd</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   To shutdown Apache:
  +
  +<P>
   
  -<P><A NAME="anchor177"></A>
  -<PRE>  % make kill_httpd
  -</PRE>
  -<P><A NAME="anchor178"></A>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  % make kill_httpd</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   NOTE to Ben-SSL users: httpsd does not seem to handle <EM>/dev/null</EM> as the location of certain files (for example some of the configuration
   files mentioned in <EM>httpd.conf</EM> can be ignored by reading them from
   <EM>/dev/null</EM>) so you'll have to change these by hand. The tests are run with the <CODE>SSLDisable</CODE> directive.
   
  -<P><A NAME="anchor179"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H3><A NAME="Manual_Testing">Manual Testing</A></H3></CENTER>
  -<P><A NAME="anchor180"></A>
  +<P>
   Tests are invoked by running the <CODE>./TEST</CODE> script located in the
   <EM>./t</EM> directory. Use the <EM>-v</EM> option for verbose tests. You might run an individual test like this:
   
  -<P><A NAME="anchor181"></A>
  -<PRE>  % t/TEST -v modules/file.t
  -</PRE>
  -<P><A NAME="anchor182"></A>
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  % t/TEST -v modules/file.t</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   or all tests in a test sub-directory:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor183"></A>
  -<PRE>  % t/TEST modules
  -</PRE>
  -<P><A NAME="anchor184"></A>
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  % t/TEST modules</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   The <CODE>TEST</CODE> script starts the server before the test is executed. If for some reason it
   fails to start, use <CODE>make start_httpd</CODE> to start it manually.
   
  -<P><A NAME="anchor185"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H3><A NAME="make_test_Troubleshooting">make test Troubleshooting</A></H3></CENTER>
  -<P><A NAME="anchor186"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H4><A NAME="make_test_fails">make test fails</A></H4></CENTER>
  -<P><A NAME="anchor187"></A>
  +<P>
   You cannot run <CODE>make test</CODE> before you build Apache, so if you told
   <CODE>perl Makefile.PL</CODE> not to build the httpd executable, there is no httpd to run the test
   against. Go to the Apache source tree and run
   <CODE>make</CODE>, then return to the mod_perl source tree and continue with the server
   testing.
   
  -<P><A NAME="anchor188"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H4><A NAME="mod_perl_c_is_incompatible_with_">mod_perl.c is incompatible with this version of Apache</A></H4></CENTER>
  -<P><A NAME="anchor189"></A>
  +<P>
   If you had a stale old Apache header layout in one of the <EM>include</EM>
   paths during the build process you will see this message when you try to
   execute httpd. Run the <CODE>find</CODE> (or <CODE>locate</CODE>) utility in order to locate the file <EM>ap_mmn.h</EM>. Delete it and rebuild Apache. RedHat installed a copy of <EM>/usr/local/include/ap_mmn.h</EM> on my system.
   
  -<P><A NAME="anchor190"></A>
  +<P>
   For all RedHat fans, before you build Apache yourself, do:
  +
  +<P>
   
  -<P><A NAME="anchor191"></A>
  -<PRE>  % rpm -e apache
  -</PRE>
  -<P><A NAME="anchor192"></A>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  % rpm -e apache</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   to remove the pre-installed RPM package first!
   
  -<P><A NAME="anchor193"></A>
  +<P>
   Debian users would do:
  +
  +<P>
   
  -<P><A NAME="anchor194"></A>
  -<PRE>  % dpkg -r apache
  -</PRE>
  -<P><A NAME="anchor195"></A>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  % dpkg -r apache</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   instead.
   
  -<P><A NAME="anchor196"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H4><A NAME="make_test_skipping_test_on_">make test......skipping test on this platform</A></H4></CENTER>
  -<P><A NAME="anchor197"></A>
  +<P>
   While doing <CODE>make test</CODE> you will notice that some of the tests are reported as <EM>skipped</EM>. The reason is that you are missing some optional modules for these test
   to be passed. For a hint you might want to peek at the content of each test
   (you will find them all in the <CODE>./t</CODE> directory (mnemonic - t, tests). I'll list a few examples, but of course
   things may change in the future.
   
  -<P><A NAME="anchor198"></A>
  -<PRE>  modules/cookie......skipping test on this platform
  -</PRE>
  -<P><A NAME="anchor199"></A>
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  modules/cookie......skipping test on this platform</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Install libapreq
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor200"></A>
  -<PRE>  modules/psections...skipping test on this platform
  -</PRE>
  -<P><A NAME="anchor201"></A>
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  modules/psections...skipping test on this platform</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Install <CODE>Devel::Symdump</CODE> / <CODE>Data::Dumper</CODE>
   
   
   
  -<P><A NAME="anchor202"></A>
  -<PRE>  modules/request.....skipping test on this platform
  -</PRE>
  -<P><A NAME="anchor203"></A>
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  modules/request.....skipping test on this platform</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Install libapreq (<CODE>Apache::Request</CODE>)
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor204"></A>
  -<PRE>  modules/sandwich....skipping test on this platform
  -</PRE>
  -<P><A NAME="anchor205"></A>
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  modules/sandwich....skipping test on this platform</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Install Apache::Sandwich
   
  -<P><A NAME="anchor206"></A>
  -<PRE>  modules/stage.......skipping test on this platform
  -</PRE>
  -<P><A NAME="anchor207"></A>
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  modules/stage.......skipping test on this platform</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Install Apache::Stage
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor208"></A>
  -<PRE>  modules/symbol......skipping test on this platform
  -</PRE>
  -<P><A NAME="anchor209"></A>
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  modules/symbol......skipping test on this platform</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Install Devel::Symdump
   
  -<P><A NAME="anchor210"></A>
  +<P>
   Chances are that all of these are installed if you use <CODE>CPAN.pm</CODE> to
   <CODE>install Bundle::Apache</CODE>.
   
  -<P><A NAME="anchor211"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H4><A NAME="make_test_Fails_Due_to_Misconfig">make test Fails Due to Misconfigured localhost Entry</A></H4></CENTER>
  -<P><A NAME="anchor212"></A>
  +<P>
   The <CODE>make test</CODE> suite uses <EM>localhost</EM> to run the tests that require a network. Make sure you have this entry in <EM>/etc/hosts</EM>:
  +
  +<P>
   
  -<P><A NAME="anchor213"></A>
  -<PRE>  127.0.0.1       localhost.localdomain   localhost
  -</PRE>
  -<P><A NAME="anchor214"></A>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  127.0.0.1       localhost.localdomain   localhost</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Also make sure that you have the loopback device [lo] configured. [Hint:
   try 'ifconfig lo' to test for its existence.]
   
  -<P><A NAME="anchor215"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="Installation_make_install_">Installation (make install)</A></H2></CENTER>
  -<P><A NAME="anchor216"></A>
  +<P>
   After testing the server, the last step left is to install it. First
   install all the Perl side files:
   
  -<P><A NAME="anchor217"></A>
  -<PRE>   % make install
  -</PRE>
  -<P><A NAME="anchor218"></A>
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>   % make install</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Then go to the Apache source tree and complete the Apache installation
   (installing the configuration files, httpd and utilities):
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor219"></A>
  -<PRE>  % cd ../apache_x.x.x
  -  % make install
  -</PRE>
  -<P><A NAME="anchor220"></A>
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  % cd ../apache_x.x.x
  +  % make install</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Now the installation should be considered complete. You may now configure
   your server and start using it.
   
  -<P><A NAME="anchor221"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="Building_Apache_and_mod_perl_by_">Building Apache and mod_perl by Hand</A></H2></CENTER>
  -<P><A NAME="anchor222"></A>
  +<P>
   If you wish to build httpd separately from mod_perl, you should use the <CODE>NO_HTTPD=1</CODE> option during the <CODE>perl Makefile.PL</CODE> (mod_perl build) stage. Then you will need to configure various things by
   hand and proceed to build Apache. You shouldn't run <CODE>perl Makefile.PL</CODE>
   before following the steps described in this section.
   
  -<P><A NAME="anchor223"></A>
  +<P>
   If you choose to manually build mod_perl, there are three things you may
   need to set up before the build stage:
   
   <DL>
   <P><DT><STRONG><A NAME="item_mod_perl">mod_perl's Makefile</A></STRONG><DD>
  -<P><A NAME="anchor224"></A>
  +<P>
   When <CODE>perl Makefile.PL</CODE> is executed,
   <EM>$APACHE_SRC/modules/perl/Makefile</EM> may need to be modified to enable various options (e.g. <CODE>ALL_HOOKS=1</CODE>).
   
  -<P><A NAME="anchor225"></A>
  +<P>
   Optionally, instead of tweaking the options during <CODE>perl Makefile.PL</CODE>
   you may edit <EM>mod_perl-x.xx/src/modules/perl/Makefile</EM> before running
   <CODE>perl Makefile.PL</CODE>.
   
   <P><DT><STRONG><A NAME="item_Configuration">Configuration</A></STRONG><DD>
  -<P><A NAME="anchor226"></A>
  +<P>
   Add to <EM>apache_x.x.x/src/Configuration</EM> :
  +
  +<P>
   
  -<P><A NAME="anchor227"></A>
  -<PRE>  AddModule modules/perl/libperl.a
  -</PRE>
  -<P><A NAME="anchor228"></A>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  AddModule modules/perl/libperl.a</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   We suggest you add this entry at the end of the <EM>Configuration</EM> file if you want your <A HREF="././install.html#Callback_Hooks">callback hooks</A> to have precedence over core handlers.
   
  -<P><A NAME="anchor229"></A>
  +<P>
   Add the following to <CODE>EXTRA_LIBS</CODE>:
  +
  +<P>
   
  -<P><A NAME="anchor230"></A>
  -<PRE>  EXTRA_LIBS=`perl -MExtUtils::Embed -e ldopts`
  -</PRE>
  -<P><A NAME="anchor231"></A>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  EXTRA_LIBS=`perl -MExtUtils::Embed -e ldopts`</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Add the following to <CODE>EXTRA_CFLAGS</CODE>:
  +
  +<P>
   
  -<P><A NAME="anchor232"></A>
  -<PRE>  EXTRA_CFLAGS=`perl -MExtUtils::Embed -e ccopts` 
  -</PRE>
  -<P><DT><STRONG><A NAME="item_mod_perl">mod_perl Source Files</A></STRONG><DD>
  -<P><A NAME="anchor233"></A>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  EXTRA_CFLAGS=`perl -MExtUtils::Embed -e ccopts` </pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P><DT><STRONG><A NAME="item_mod_perl">mod_perl Source Files</A></STRONG><DD>
  +<P>
   Return to the mod_perl directory and copy the mod_perl source files into
   the apache build directory:
   
  -<P><A NAME="anchor234"></A>
  -<PRE>  % cp -r src/modules/perl apache_x.x.x/src/modules/
  -</PRE>
  -</DL>
  -<P><A NAME="anchor235"></A>
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  % cp -r src/modules/perl apache_x.x.x/src/modules/</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    </DL>
  +<P>
   When you have done with the configuration parts, run:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor236"></A>
  -<PRE>  % perl Makefile.PL NO_HTTPD=1 DYNAMIC=1  EVERYTHING=1\
  -   APACHE_SRC=../apache_x.x.x/src
  -</PRE>
  -<P><A NAME="anchor237"></A>
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  % perl Makefile.PL NO_HTTPD=1 DYNAMIC=1  EVERYTHING=1\
  +   APACHE_SRC=../apache_x.x.x/src</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   <CODE>DYNAMIC=1</CODE> enables a build of the shared mod_perl library. Add other options if
   required.
   
  -<P><A NAME="anchor238"></A>
  -<PRE>  % make install
  -</PRE>
  -<P><A NAME="anchor239"></A>
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  % make install</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Now you may proceed with the plain Apache build process. Note that in order
   for your changes to the <EM>apache_x.x.x/src/Configuration</EM> file to take effect, you must run <CODE>apache_x.x.x/src/Configure</CODE> instead of the default <EM>apache_x.x.x/configure</EM> script:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor240"></A>
  -<PRE>  % cd ../apache_x.x.x/src
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  % cd ../apache_x.x.x/src
     % ./Configure
     % make
  -  % make install
  -</PRE>
  -<P><A NAME="anchor241"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +  % make install</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H1><A NAME="Installation_Scenarios_for_Stand">Installation Scenarios for Standalone mod_perl</A></H1></CENTER>
  -<P><A NAME="anchor242"></A>
  +<P>
   There are various ways available to build Apache with the new hybrid build
   environment (using <CODE>USE_APACI=1</CODE>):
   
  -<P><A NAME="anchor243"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="The_All_In_One_Way">The All-In-One Way</A></H2></CENTER>
  -<P><A NAME="anchor244"></A>
  +<P>
   If your goal is just to build and install Apache with mod_perl out of their
   source trees and have no special interest in further adjusting or enhancing
   Apache proceed as before:
  +
  +<P>
   
  -<P><A NAME="anchor245"></A>
  -<PRE>  % tar xzvf apache_x.x.x.tar.gz
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  % tar xzvf apache_x.x.x.tar.gz
     % tar xzvf mod_perl-x.xx.tar.gz
     % cd mod_perl-x.xx
     % perl Makefile.PL APACHE_SRC=../apache_x.x.x/src \
       DO_HTTPD=1 USE_APACI=1 EVERYTHING=1
     % make &amp;&amp; make test &amp;&amp; make install
     % cd ../apache_x.x.x
  -  % make install
  -</PRE>
  -<P><A NAME="anchor246"></A>
  +  % make install</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   This builds Apache statically with mod_perl, installs Apache under the
   default <CODE>/usr/local/apache</CODE> tree and mod_perl into the <CODE>site_perl</CODE>
   hierarchy of your existing Perl installation. All in one step.
   
  -<P><A NAME="anchor247"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="The_Flexible_Way">The Flexible Way</A></H2></CENTER>
  -<P><A NAME="anchor248"></A>
  +<P>
   This is the normal situation where you want to be flexible while building.
   Statically building mod_perl into the Apache binary (<CODE>httpd</CODE>) but via different steps, so you have a chance to include other
   third-party Apache modules, etc.
   
   <OL>
   <P><LI><STRONG><A NAME="item_Prepare_the_Apache_source_tree">Prepare the Apache source tree</A></STRONG>
  -<P><A NAME="anchor249"></A>
  +<P>
   The first step is as before, extract the distributions:
   
  -<P><A NAME="anchor250"></A>
  -<PRE>  % tar xvzf apache_x.x.x.tar.gz
  -  % tar xzvf mod_perl-x.xx.tar.gz
  -</PRE>
  -<P><LI><STRONG><A NAME="item_Install_mod_perl_s_Perl_side_and">Install mod_perl's Perl-side and prepare the Apache-side</A></STRONG>
  -<P><A NAME="anchor251"></A>
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  % tar xvzf apache_x.x.x.tar.gz
  +  % tar xzvf mod_perl-x.xx.tar.gz</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P><LI><STRONG><A NAME="item_Install_mod_perl_s_Perl_side_and">Install mod_perl's Perl-side and prepare the Apache-side</A></STRONG>
  +<P>
   The second step is to install the Perl-side of mod_perl into the Perl
   hierarchy and prepare the <CODE>src/modules/perl/</CODE> subdirectory inside the Apache source tree:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor252"></A>
  -<PRE> $ cd mod_perl-x.xx
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre> $ cd mod_perl-x.xx
    $ perl Makefile.PL \
        APACHE_SRC=../apache_x.x.x/src \
        NO_HTTPD=1 \
  @@ -1324,196 +2164,251 @@
    $ make
    $ make test
    $ make install
  - $ cd ..
  -</PRE>
  -<P><A NAME="anchor253"></A>
  + $ cd ..</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   The <CODE>APACHE_SRC</CODE> option sets the path to your Apache source tree, the
   <CODE>NO_HTTPD</CODE> option forces this path and only this path to be used, the
   <CODE>USE_APACI</CODE> option triggers the new hybrid build environment and the
   <CODE>PREP_HTTPD</CODE> option forces preparation of the
   <CODE>APACHE_SRC/modules/perl/</CODE> tree but no automatic build.
   
  -<P><A NAME="anchor254"></A>
  +<P>
   Then the configuration process prepares the Apache-side of mod_perl in the
   Apache source tree but doesn't touch anything else in it. It then just
   builds the Perl-side of mod_perl and installs it into the Perl installation
   hierarchy.
   
  -<P><A NAME="anchor255"></A>
  +<P>
   <STRONG>Important:</STRONG> If you use <CODE>PREP_HTTPD</CODE> as described above, to complete the build you must go into the Apache
   source directory and run <CODE>make</CODE>
   and <CODE>make install</CODE>.
   
   <P><LI><STRONG><A NAME="item_Additionally_prepare_other_third">Additionally prepare other third-party modules</A></STRONG>
  -<P><A NAME="anchor256"></A>
  +<P>
   Now you have a chance to prepare third-party modules. For instance the PHP3
   language can be added in a manner similar to the mod_perl procedure.
   
   <P><LI><STRONG><A NAME="item_Build_the_Apache_Package">Build the Apache Package</A></STRONG>
  -<P><A NAME="anchor257"></A>
  +<P>
   Finally it's time to build the Apache package and thus also the Apache-side
   of mod_perl and any other third-party modules you've prepared:
  +
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
   
  -<P><A NAME="anchor258"></A>
  -<PRE> $ cd apache_x.x.x
  +	<td>
  +	  <pre> $ cd apache_x.x.x
    $ ./configure \
        --prefix=/path/to/install/of/apache \
        --activate-module=src/modules/perl/libperl.a \
        [...]
    $ make
    $ make test
  - $ make install
  -</PRE>
  -<P><A NAME="anchor259"></A>
  + $ make install</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   The <CODE>--prefix</CODE> option is needed if you want to change the default target directory of the
   Apache installation and the
   <CODE>--activate-module</CODE> option activates mod_perl for the configuration process and thus also for
   the build process. If you choose
   <CODE>--prefix=/usr/share/apache</CODE> the Apache directory tree will be installed in <EM>/usr/share/apache</EM>.
   
  -<P><A NAME="anchor260"></A>
  +<P>
   The last three steps build, test and install the Apache-side of the
   mod_perl enabled server. Presumably your new server includes third-party
   components, otherwise you probably won't choose this method of building.
   
   </OL>
  -<P><A NAME="anchor261"></A>
  +<P>
   The method described above enables you to insert mod_perl into Apache
   without having to mangle the Apache source tree for mod_perl. It also gives
   you the freedom to add third-party modules.
   
  -<P><A NAME="anchor262"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="Build_mod_perl_as_a_DSO_inside_t">Build mod_perl as a DSO inside the Apache Source Tree via APACI</A></H2></CENTER>
  -<P><A NAME="anchor263"></A>
  +<P>
   <STRONG>Warning</STRONG>:  <EM>THIS IS STILL EXPERIMENTAL, SO BE WARNED!</EM>
   
   
   
  -<P><A NAME="anchor264"></A>
  +<P>
   With Apache 1.3 there is support for building modules as Dynamic Shared
   Objects (DSO). So there is support for DSO in mod_perl now, too. Your
   mileage may vary. Almost certainly it will.
   
  -<P><A NAME="anchor265"></A>
  +<P>
   <STRONG>Warning</STRONG>:  <EM>YOU HAVE BEEN WARNED!</EM>
   
   
   
  -<P><A NAME="anchor266"></A>
  +<P>
   We have already said that the new mod_perl build environment (<CODE>USE_APACI</CODE>) is a hybrid. What does it mean? It means for instance that the same <CODE>src/modules/perl/</CODE> stuff can be used to build mod_perl as a DSO or not, without having to edit
   anything especially for this. When you want to build <CODE>libperl.so</CODE> all you have to do is to add one single option to the above steps.
   
  -<P><A NAME="anchor267"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H3><A NAME="libperl_so_and_libperl_a">libperl.so and libperl.a</A></H3></CENTER>
  -<P><A NAME="anchor268"></A>
  +<P>
   <CODE>libmodperl.so</CODE> would be more correct for the mod_perl file, but the name has to be <CODE>libperl.so</CODE> because of prehistoric Apache issues. Don't confuse the <CODE>libperl.so</CODE> for mod_perl with the file of the same name which comes with Perl itself.
   They are two different things. It is unfortunate that they happen to have
   the same name.
   
  -<P><A NAME="anchor269"></A>
  +<P>
   There is also a <CODE>libperl.a</CODE> which comes with the Perl installation. That's different too.
   
  -<P><A NAME="anchor270"></A>
  +<P>
   You have two options here, depending on which way you have chosen above: If
   you choose the All-In-One way from above then add
  +
  +<P>
   
  -<P><A NAME="anchor271"></A>
  -<PRE>  USE_DSO=1
  -</PRE>
  -<P><A NAME="anchor272"></A>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  USE_DSO=1</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   to the <CODE>perl Makefile.PL</CODE> options. If you choose the Flexible way then add:
  +
  +<P>
   
  -<P><A NAME="anchor273"></A>
  -<PRE>  --enable-shared=perl
  -</PRE>
  -<P><A NAME="anchor274"></A>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  --enable-shared=perl</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   to Apache's <CODE>./configure</CODE> options.
   
  -<P><A NAME="anchor275"></A>
  +<P>
   As you can see only an additional <CODE>USE_DSO=1</CODE> or
   <CODE>--enable-shared=perl</CODE> option is needed. Everything else is done automatically: <CODE>mod_so</CODE> is automatically enabled, the Makefiles are adjusted automatically and even
   the <CODE>install</CODE> target from APACI now additionally installs <CODE>libperl.so</CODE> into the Apache installation tree. And even more: the <CODE>LoadModule</CODE> and <CODE>AddModule</CODE> directives (which dynamically load and insert mod_perl into httpd) are
   automatically added to <EM>httpd.conf</EM>.
   
  -<P><A NAME="anchor276"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="Build_mod_perl_as_a_DSO_outside_">Build mod_perl as a DSO outside the Apache Source Tree via APXS</A></H2></CENTER>
  -<P><A NAME="anchor277"></A>
  +<P>
   Above we've seen how to build mod_perl as a DSO <EM>inside</EM> the Apache source tree. But there is a nifty alternative: building mod_perl
   as a DSO <EM>outside</EM> the Apache source tree via the new Apache 1.3 support tool <CODE>apxs</CODE> (APache eXtension). The advantage is obvious: you can extend an already
   installed Apache with mod_perl even if you don't have the sources (for
   instance, you may have installed an Apache binary package from your
   vendor).
   
  -<P><A NAME="anchor278"></A>
  +<P>
   Here are the build steps:
   
  -<P><A NAME="anchor279"></A>
  -<PRE>  % tar xzvf mod_perl-x.xx.tar.gz
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  % tar xzvf mod_perl-x.xx.tar.gz
     % cd mod_perl-x.xx
     % perl Makefile.PL \
       USE_APXS=1 \
       WITH_APXS=/path/to/bin/apxs \
       EVERYTHING=1 \
        [...]
  -  % make &amp;&amp; make test &amp;&amp; make install
  -</PRE>
  -<P><A NAME="anchor280"></A>
  +  % make &amp;&amp; make test &amp;&amp; make install</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   This will build the DSO <CODE>libperl.so</CODE>  <EM>outside</EM> the Apache source tree with the new Apache 1.3 support tool <CODE>apxs</CODE> and install it into the existing Apache hierarchy.
   
  -<P><A NAME="anchor281"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H1><A NAME="Installation_Scenarios_for_mod_p">Installation Scenarios for mod_perl and Other Components</A></H1></CENTER>
  -<P><A NAME="anchor282"></A>
  +<P>
   ([ReaderMETA]: Please send more scenarios of mod_perl + other components
   installation guidelines. Thanks!)
   
  -<P><A NAME="anchor283"></A>
  +<P>
   You have now seen very detailed installation instructions for specific
   cases, but since mod_perl is used with many other components that plug into
   Apache, you will definitely want to know how to build them together with
   mod_perl.
   
  -<P><A NAME="anchor284"></A>
  +<P>
   Since all the steps are simple, and assuming that you now understand how
   the build process works, I'll show only the commands to be executed with no
   comments unless there is something we haven't discussed before.
   
  -<P><A NAME="anchor285"></A>
  +<P>
   Generally every example that I'm going to show consist of:
   
   <OL>
   <P><LI>
  -<P><A NAME="anchor286"></A>
  +<P>
   downloading the source distributions of the components to be used
   
   <P><LI>
  -<P><A NAME="anchor287"></A>
  +<P>
   un-packing them
   
   <P><LI>
  -<P><A NAME="anchor288"></A>
  +<P>
   configuring them
   
   <P><LI>
  -<P><A NAME="anchor289"></A>
  +<P>
   building Apache using the parameters appropriate to each component
   
   <P><LI>
  -<P><A NAME="anchor290"></A>
  +<P>
   <CODE>make test</CODE> and <CODE>make install</CODE>.
   
   </OL>
  -<P><A NAME="anchor291"></A>
  +<P>
   All these scenarios were tested on a Linux platform, you might need to
   refer to the specific component's documentation if something doesn't work
   for you as described below. The intention of this section is not to show
   you how to install other non-mod_perl components alone, but how to do this
   in a bundle with mod_perl.
   
  -<P><A NAME="anchor292"></A>
  +<P>
   Also, notice that the links I've used below are very likely to have changed
   by the time you read this document. That's why I have used the <EM>x.x.x</EM> convention, instead of using hardcoded version numbers. Remember to replace
   the <EM>x.xx</EM> place-holders with the version numbers of the distributions you are about
  @@ -1525,192 +2420,491 @@
   order to learn the version number of the latest stable release and download
   the appropriate file.
   
  -<P><A NAME="anchor293"></A>
  +<P>
   Unless otherwise noted, all the components install themselves into a
   default location. When you run <CODE>make install</CODE> the installation program tells you where it's going to install the files.
   
  -<P><A NAME="anchor294"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="mod_perl_and_mod_ssl_openssl_">mod_perl and mod_ssl (+openssl)</A></H2></CENTER>
  -<P><A NAME="anchor295"></A>
  +<P>
   mod_ssl provides strong cryptography for the Apache 1.3 webserver via the
   Secure Sockets Layer (SSL v2/v3) and Transport Layer Security (TLS v1)
   protocols by the help of the Open Source SSL/TLS toolkit OpenSSL, which is
   based on SSLeay from Eric A. Young and Tim J. Hudson.
   
  -<P><A NAME="anchor296"></A>
  +<P>
   Download the sources:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor297"></A>
  -<PRE>  % lwp-download <A HREF="http://www.apache.org/dist/apache_x.xx.tar.gz">http://www.apache.org/dist/apache_x.xx.tar.gz</A>
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  % lwp-download <A HREF="http://www.apache.org/dist/apache_x.xx.tar.gz">http://www.apache.org/dist/apache_x.xx.tar.gz</A>
     % lwp-download <A HREF="http://perl.apache.org/dist/mod_perl-x.xx.tar.gz">http://perl.apache.org/dist/mod_perl-x.xx.tar.gz</A>
     % lwp-download <A HREF="http://www.modssl.org/source/mod_ssl-x.x.x-x.x.x.tar.gz">http://www.modssl.org/source/mod_ssl-x.x.x-x.x.x.tar.gz</A>
  -  % lwp-download <A HREF="http://www.openssl.org/source/openssl-x.x.x.tar.gz">http://www.openssl.org/source/openssl-x.x.x.tar.gz</A>
  -</PRE>
  -<P><A NAME="anchor298"></A>
  +  % lwp-download <A HREF="http://www.openssl.org/source/openssl-x.x.x.tar.gz">http://www.openssl.org/source/openssl-x.x.x.tar.gz</A></pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Un-pack:
  +
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
   
  -<P><A NAME="anchor299"></A>
  -<PRE>  % tar xvzf mod_perl-x.xx
  +	<td>
  +	  <pre>  % tar xvzf mod_perl-x.xx
     % tar xvzf apache_x.x.x.tar.gz
     % tar xvzf mod_ssl-x.x.x-x.x.x.tar.gz
  -  % tar xvzf openssl-x.x.x.tar.gz
  -</PRE>
  -<P><A NAME="anchor300"></A>
  +  % tar xvzf openssl-x.x.x.tar.gz</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Configure, build and install openssl:
   
  -<P><A NAME="anchor301"></A>
  -<PRE>  % cd openssl-x.x.x
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  % cd openssl-x.x.x
     % ./config
  -  % make &amp;&amp; make test &amp;&amp; make install
  -</PRE>
  -<P><A NAME="anchor302"></A>
  +  % make &amp;&amp; make test &amp;&amp; make install</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Configure:
   
  -<P><A NAME="anchor303"></A>
  -<PRE>  % cd mod_ssl-x.x.x-x.x.x
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  % cd mod_ssl-x.x.x-x.x.x
     % ./configure --with-apache=../apache_x.x.x
     % cd ../mod_perl-x.xx
     % perl Makefile.PL USE_APACI=1 EVERYTHING=1 \
           DO_HTTPD=1 SSL_BASE=/usr/local/ssl \
           APACHE_PREFIX=/usr/local/apachessl \
           APACHE_SRC=../apache_x.x.x/src \
  -        APACI_ARGS=--enable-module=ssl,--enable-module=rewrite
  -</PRE>
  -<P><A NAME="anchor304"></A>
  +        APACI_ARGS='--enable-module=ssl,--enable-module=rewrite'</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Note: Do not forget that if you use <CODE>csh</CODE> or <CODE>tcsh</CODE> you may need to put all the arguments to `perl Makefile.PL' on a single
   command line.
   
  -<P><A NAME="anchor305"></A>
  +<P>
   Build, test and install:
  +
  +<P>
   
  -<P><A NAME="anchor306"></A>
  -<PRE>  % make &amp;&amp; make test &amp;&amp; make install
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  % make &amp;&amp; make test &amp;&amp; make install
     % cd ../apache_x.x.x
     % make certificate
  -  % make install
  -</PRE>
  -<P><A NAME="anchor307"></A>
  +  % make install</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Now proceed with the mod_ssl and mod_perl parts of the server configuration
   before starting the server.
   
  -<P><A NAME="anchor308"></A>
  +<P>
   When the server starts you should see the following or similar in the
   <EM>error_log</EM> file:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor309"></A>
  -<PRE>  [Fri Nov 12 16:14:11 1999] [notice] Apache/1.3.9 (Unix)
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  [Fri Nov 12 16:14:11 1999] [notice] Apache/1.3.9 (Unix)
     mod_perl/1.21_01-dev mod_ssl/2.4.8 OpenSSL/0.9.4 configured
  -  -- resuming normal operations
  -</PRE>
  -<P><A NAME="anchor310"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +  -- resuming normal operations</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="mod_perl_and_mod_ssl_Rolled_from">mod_perl and mod_ssl Rolled from RPMs</A></H2></CENTER>
  -<P><A NAME="anchor311"></A>
  +<P>
   As in the previous section this shows an installation of mod_perl and
   mod_ssl, but this time using sources/binaries prepackaged in RPMs.
   
  -<P><A NAME="anchor312"></A>
  +<P>
   As always, replace <EM>xxx</EM> with the proper version numbers. And replace <CODE>i386</CODE> with the identifier for your platform if it is different.
   
   <OL>
   <P><LI>
  -<P><A NAME="anchor313"></A>
  -<PRE>  % get apache-mod_ssl-x.x.x.x-x.x.x.src.rpm
  -</PRE>
  -<P><A NAME="anchor314"></A>
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  % get apache-mod_ssl-x.x.x.x-x.x.x.src.rpm</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Source: <A HREF="http://www.modssl.org">http://www.modssl.org</A>
   
   <P><LI>
  -<P><A NAME="anchor315"></A>
  -<PRE>  % get openssl-x.x.x.i386.rpm
  -</PRE>
  -<P><A NAME="anchor316"></A>
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  % get openssl-x.x.x.i386.rpm</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Source: <A HREF="http://www.openssl.org/">http://www.openssl.org/</A>
   
   <P><LI>
  -<P><A NAME="anchor317"></A>
  -<PRE>  % lwp-download <A HREF="http://perl.apache.org/dist/mod_perl-x.xx.tar.gz">http://perl.apache.org/dist/mod_perl-x.xx.tar.gz</A>
  -</PRE>
  -<P><A NAME="anchor318"></A>
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  % lwp-download <A HREF="http://perl.apache.org/dist/mod_perl-x.xx.tar.gz">http://perl.apache.org/dist/mod_perl-x.xx.tar.gz</A></pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Source: <A
   HREF="http://perl.apache.org/dist">http://perl.apache.org/dist</A>
   
   <P><LI>
  -<P><A NAME="anchor319"></A>
  -<PRE>  % lwp-download <A HREF="http://www.engelschall.com/sw/mm/mm-x.x.xx.tar.gz">http://www.engelschall.com/sw/mm/mm-x.x.xx.tar.gz</A>
  -</PRE>
  -<P><A NAME="anchor320"></A>
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  % lwp-download <A HREF="http://www.engelschall.com/sw/mm/mm-x.x.xx.tar.gz">http://www.engelschall.com/sw/mm/mm-x.x.xx.tar.gz</A></pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Source: <A
   HREF="http://www.engelschall.com/sw/mm/">http://www.engelschall.com/sw/mm/</A>
   
   
   <P><LI>
  -<P><A NAME="anchor321"></A>
  -<PRE>  % rpm -ivh openssl-x.x.x.i386.rpm
  -</PRE>
  -<P><LI>
  -<P><A NAME="anchor322"></A>
  -<PRE>  % rpm -ivh apache-mod_ssl-x.x.x.x-x.x.x.src.rpm
  -</PRE>
  -<P><LI>
  -<P><A NAME="anchor323"></A>
  -<PRE>  % cd /usr/src/redhat/SPECS
  -</PRE>
  -<P><LI>
  -<P><A NAME="anchor324"></A>
  -<PRE>  % rpm -bp apache-mod_ssl.spec
  -</PRE>
  -<P><LI>
  -<P><A NAME="anchor325"></A>
  -<PRE>  % cd /usr/src/redhat/BUILD/apache-mod_ssl-x.x.x.x-x.x.x
  -</PRE>
  -<P><LI>
  -<P><A NAME="anchor326"></A>
  -<PRE>  % tar xvzf mod_perl-x.xx.tar.gz
  -</PRE>
  -<P><LI>
  -<P><A NAME="anchor327"></A>
  -<PRE>  % cd mod_perl-x.xx
  -</PRE>
  -<P><LI>
  -<P><A NAME="anchor328"></A>
  -<PRE>  % perl Makefile.PL APACHE_SRC=../apache_x.x.x/src \
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  % rpm -ivh openssl-x.x.x.i386.rpm</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P><LI>
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  % rpm -ivh apache-mod_ssl-x.x.x.x-x.x.x.src.rpm</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P><LI>
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  % cd /usr/src/redhat/SPECS</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P><LI>
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  % rpm -bp apache-mod_ssl.spec</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P><LI>
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  % cd /usr/src/redhat/BUILD/apache-mod_ssl-x.x.x.x-x.x.x</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P><LI>
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  % tar xvzf mod_perl-x.xx.tar.gz</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P><LI>
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  % cd mod_perl-x.xx</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P><LI>
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  % perl Makefile.PL APACHE_SRC=../apache_x.x.x/src \
        DO_HTTPD=1 \
        USE_APACI=1 \
        PREP_HTTPD=1 \
  -     EVERYTHING=1
  -</PRE>
  -<P><A NAME="anchor329"></A>
  +     EVERYTHING=1</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Add or remove parameters if appropriate.
   
  -<P><LI>
  -<P><A NAME="anchor330"></A>
  -<PRE>  % make
  -</PRE>
  -<P><LI>
  -<P><A NAME="anchor331"></A>
  -<PRE>  % make install
  -</PRE>
  -<P><LI>
  -<P><A NAME="anchor332"></A>
  -<PRE>  % cd ../mm-x.x.xx/
  -</PRE>
  -<P><LI>
  -<P><A NAME="anchor333"></A>
  -<PRE>  % ./configure --disable-shared
  -</PRE>
  -<P><LI>
  -<P><A NAME="anchor334"></A>
  -<PRE>  % make
  -</PRE>
  -<P><LI>
  -<P><A NAME="anchor335"></A>
  -<PRE>  % cd ../mod_ssl-x.x.x-x.x.x
  -</PRE>
   <P><LI>
  -<P><A NAME="anchor336"></A>
  -<PRE>  % ./configure \
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  % make</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P><LI>
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  % make install</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P><LI>
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  % cd ../mm-x.x.xx/</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P><LI>
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  % ./configure --disable-shared</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P><LI>
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  % make</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P><LI>
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  % cd ../mod_ssl-x.x.x-x.x.x</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P><LI>
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  % ./configure \
           --with-perl=/usr/bin/perl \
           --with-apache=../apache_x.x.x\
           --with-ssl=SYSTEM \
  @@ -1721,301 +2915,683 @@
           --enable-module=define \
           --activate-module=src/modules/perl/libperl.a \
           --enable-shared=max \
  -        --disable-shared=perl
  -</PRE>
  -<P><LI>
  -<P><A NAME="anchor337"></A>
  -<PRE>  % make
  -</PRE>
  -<P><LI>
  -<P><A NAME="anchor338"></A>
  -<PRE>  % make certificate 
  -</PRE>
  -<P><A NAME="anchor339"></A>
  +        --disable-shared=perl</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P><LI>
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  % make</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P><LI>
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  % make certificate </pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   with whatever option is suitable to your configuration.
   
   <P><LI>
  -<P><A NAME="anchor340"></A>
  -<PRE>  % make install
  -</PRE>
  -</OL>
  -<P><A NAME="anchor341"></A>
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  % make install</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    </OL>
  +<P>
   You should be all set.
   
  -<P><A NAME="anchor342"></A>
  +<P>
   Note: If you use the standard config for mod_ssl don't forget to run Apache
   like this:
  +
  +<P>
   
  -<P><A NAME="anchor343"></A>
  -<PRE>  % httpd -DSSL
  -</PRE>
  -<P><A NAME="anchor344"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  % httpd -DSSL</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="mod_perl_and_apache_ssl_openss">mod_perl and apache-ssl (+openssl)</A></H2></CENTER>
  -<P><A NAME="anchor345"></A>
  +<P>
   Apache-SSL is a secure Webserver, based on Apache and SSLeay/OpenSSL. It is
   licensed under a BSD-style license which means, in short, that you are free
   to use it for commercial or non-commercial purposes, so long as you retain
   the copyright notices.
   
  -<P><A NAME="anchor346"></A>
  +<P>
   Download the sources:
   
  -<P><A NAME="anchor347"></A>
  -<PRE>  % lwp-download <A HREF="http://www.apache.org/dist/apache_x.x.x.tar.gz">http://www.apache.org/dist/apache_x.x.x.tar.gz</A>
  -  % lwp-download <A HREF="http://perl.apache.org/dist/mod_perl-x.xx.tar.gz">http://perl.apache.org/dist/mod_perl-x.xx.tar.gz</A>
  -  % lwp-download <A HREF="http://www.apache-ssl.org/.../apache_x.x.x+ssl_x.xx.tar.gz">http://www.apache-ssl.org/.../apache_x.x.x+ssl_x.xx.tar.gz</A>
  -  % lwp-download <A HREF="http://www.openssl.org/source/openssl-x.x.x.tar.gz">http://www.openssl.org/source/openssl-x.x.x.tar.gz</A>
  -</PRE>
  -<P><A NAME="anchor348"></A>
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  % lwp-download <A HREF="http://www.apache.org/dist/apache_x.x.x.tar.gz">http://www.apache.org/dist/apache_x.x.x.tar.gz</A>
  +  % lwp-download <A HREF="http://perl.apache.org/dist/mod_perl-x.xx.tar.gz">http://perl.apache.org/dist/mod_perl-x.xx.tar.gz</A>
  +  % lwp-download <A HREF="http://www.apache-ssl.org/.../apache_x.x.x+ssl_x.xx.tar.gz">http://www.apache-ssl.org/.../apache_x.x.x+ssl_x.xx.tar.gz</A>
  +  % lwp-download <A HREF="http://www.openssl.org/source/openssl-x.x.x.tar.gz">http://www.openssl.org/source/openssl-x.x.x.tar.gz</A></pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Un-pack:
  +
  +<P>
   
  -<P><A NAME="anchor349"></A>
  -<PRE>  % tar xvzf mod_perl-x.xx
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  % tar xvzf mod_perl-x.xx
     % tar xvzf apache_x.x.x.tar.gz
  -  % tar xvzf openssl-x.x.x.tar.gz
  -</PRE>
  -<P><A NAME="anchor350"></A>
  +  % tar xvzf openssl-x.x.x.tar.gz</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Configure and install openssl:
  +
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
   
  -<P><A NAME="anchor351"></A>
  -<PRE>  % cd openssl-x.x.x
  +	<td>
  +	  <pre>  % cd openssl-x.x.x
     % ./config
  -  % make &amp;&amp; make test &amp;&amp; make install
  -</PRE>
  -<P><A NAME="anchor352"></A>
  +  % make &amp;&amp; make test &amp;&amp; make install</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Patch Apache with SSLeay paths
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor353"></A>
  -<PRE>  % cd apache_x.xx
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  % cd apache_x.xx
     % tar xzvf ../apache_x.x.x+ssl_x.xx.tar.gz
     % FixPatch
  -  Do you want me to apply the fixed-up Apache-SSL patch for you? [n] y
  -</PRE>
  -<P><A NAME="anchor354"></A>
  +  Do you want me to apply the fixed-up Apache-SSL patch for you? [n] y</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Now edit the <EM>src/Configuration</EM> file if needed and then configure:
  +
  +<P>
   
  -<P><A NAME="anchor355"></A>
  -<PRE>  % cd ../mod_perl-x.xx
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  % cd ../mod_perl-x.xx
     % perl Makefile.PL USE_APACI=1 EVERYTHING=1 \
           DO_HTTPD=1 SSL_BASE=/usr/local/ssl \
  -        APACHE_SRC=../apache_x.x.x/src
  -</PRE>
  -<P><A NAME="anchor356"></A>
  +        APACHE_SRC=../apache_x.x.x/src</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Build, test and install:
  +
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
   
  -<P><A NAME="anchor357"></A>
  -<PRE>  % make &amp;&amp; make test &amp;&amp; make install
  +	<td>
  +	  <pre>  % make &amp;&amp; make test &amp;&amp; make install
     % cd ../apache_x.x.x
     % make certificate
  -  % make install
  -</PRE>
  -<P><A NAME="anchor358"></A>
  +  % make install</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Note that you might need to modify the 'make test' stage, as it takes much
   longer for this server to get started and <CODE>make test</CODE> waits only a few seconds for Apache to start before it times out.
   
  -<P><A NAME="anchor359"></A>
  +<P>
   Now proceed with configuration of the apache_ssl and mod_perl parts of the
   server configuration files, before starting the server.
   
  -<P><A NAME="anchor360"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="mod_perl_and_Stronghold">mod_perl and Stronghold</A></H2></CENTER>
  -<P><A NAME="anchor361"></A>
  +<P>
   Stronghold is a secure SSL Web server for Unix which allows you to give
   your web site full-strength, 128-bit encryption.
   
  -<P><A NAME="anchor362"></A>
  +<P>
   You must first build and install Stronghold without mod_perl, following
   Stronghold's install procedure. For more information visit <A
   HREF="http://www.c2.net/products/sh2/">http://www.c2.net/products/sh2/</A>
   .
   
  -<P><A NAME="anchor363"></A>
  +<P>
   Having done that, download the sources:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor364"></A>
  -<PRE>  % lwp-download <A HREF="http://perl.apache.org/dist/mod_perl-x.xx.tar.gz">http://perl.apache.org/dist/mod_perl-x.xx.tar.gz</A>
  -</PRE>
  -<P><A NAME="anchor365"></A>
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  % lwp-download <A HREF="http://perl.apache.org/dist/mod_perl-x.xx.tar.gz">http://perl.apache.org/dist/mod_perl-x.xx.tar.gz</A></pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Unpack:
   
  -<P><A NAME="anchor366"></A>
  -<PRE>  % tar xvzf mod_perl-x.xx.tar.gz
  -</PRE>
  -<P><A NAME="anchor367"></A>
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  % tar xvzf mod_perl-x.xx.tar.gz</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Configure (assuming that you have the Stronghold sources extracted at
   <EM>/usr/local/stronghold</EM>):
  +
  +<P>
   
  -<P><A NAME="anchor368"></A>
  -<PRE>  % cd mod_perl-x.xx
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  % cd mod_perl-x.xx
     % perl Makefile.PL APACHE_SRC=/usr/local/stronghold/src \
  -    DO_HTTPD=1 USE_APACI=1 EVERYTHING=1
  -</PRE>
  -<P><A NAME="anchor369"></A>
  +    DO_HTTPD=1 USE_APACI=1 EVERYTHING=1</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Build:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor370"></A>
  -<PRE>  % make 
  -</PRE>
  -<P><A NAME="anchor371"></A>
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  % make </pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Before running <CODE>make test</CODE>, you must add your <CODE>StrongholdKey</CODE> to
   <EM>t/conf/httpd.conf</EM>. If you are configuring by hand, be sure to edit
   <EM>src/modules/perl/Makefile</EM> and uncomment the <CODE>#APACHE_SSL</CODE>
   directive.
   
  -<P><A NAME="anchor372"></A>
  +<P>
   Test and Install:
   
  -<P><A NAME="anchor373"></A>
  -<PRE>  % make test &amp;&amp; make install
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  % make test &amp;&amp; make install
     % cd /usr/local/stronghold
  -  % make install
  -</PRE>
  -<P><A NAME="anchor374"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +  % make install</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H3><A NAME="Note_For_Solaris_2_5_users">Note For Solaris 2.5 users</A></H3></CENTER>
  -<P><A NAME="anchor375"></A>
  +<P>
   There has been a report related to the <CODE>REGEX</CODE> library that comes with Stronghold, that after building Apache with
   mod_perl it would produce core dumps. To work around this problem, in
   <EM>$STRONGHOLD/src/Configuration</EM> change:
  +
  +<P>
   
  -<P><A NAME="anchor376"></A>
  -<PRE>  Rule WANTHSREGEX=default
  -</PRE>
  -<P><A NAME="anchor377"></A>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  Rule WANTHSREGEX=default</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   to:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor378"></A>
  -<PRE>  Rule WANTHSREGEX=no
  -</PRE>
  -<P><A NAME="anchor379"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  Rule WANTHSREGEX=no</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="mod_perl_and_Raven_SSL">mod_perl and Raven SSL</A></H2></CENTER>
  -<P><A NAME="anchor380"></A>
  +<P>
   Note: Please consult <A
   HREF="http://www.covalent.net/support">http://www.covalent.net/support</A>
   if you have additional questions regarding Raven SSL.
   
  -<P><A NAME="anchor381"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H3><A NAME="Dynamic_DSO_mod_perl_and_Raven">Dynamic (DSO) mod_perl and Raven SSL Installation</A></H3></CENTER>
  -<P><A NAME="anchor382"></A>
  +<P>
   To install Raven SSL and mod_perl dynamically:
   
   <OL>
   <P><LI>
  -<P><A NAME="anchor383"></A>
  +<P>
   Un-tar and un-gunzip Raven SSL and mod_perl into their respective
   directories.
   
   <P><LI>
  -<P><A NAME="anchor384"></A>
  -<PRE>  % cd raven_ssl-x.x.x
  -</PRE>
  -<P><A NAME="anchor385"></A>
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  % cd raven_ssl-x.x.x</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Install Raven SSL and Apache via:
   
  -<P><A NAME="anchor386"></A>
  -<PRE>  % ./setup --with-apache
  -</PRE>
  -<P><LI>
  -<P><A NAME="anchor387"></A>
  -<PRE>  % cd mod_perl_x.xx
  -</PRE>
  -<P><LI>
  -<P><A NAME="anchor388"></A>
  -<PRE>  % perl Makefile.PL USE_APXS=1 \
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  % ./setup --with-apache</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P><LI>
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  % cd mod_perl_x.xx</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P><LI>
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  % perl Makefile.PL USE_APXS=1 \
        WITH_APXS=/usr/local/apache/bin/apxs \
        EVERYTHING=1
  -     [...]
  -</PRE>
  -<P><LI>
  -<P><A NAME="anchor389"></A>
  -<PRE>  % make ; make install
  -</PRE>
  -<P><LI>
  -<P><A NAME="anchor390"></A>
  +     [...]</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P><LI>
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  % make ; make install</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P><LI>
  +<P>
   Move the <CODE>LoadModule mod_perl.c</CODE> and <CODE>Addmodule mod_perl.c</CODE> lines in
   <EM>httpd.conf</EM> above the <CODE>&lt;IfDefine SSL&gt;</CODE> section.
   
   </OL>
  -<P><A NAME="anchor391"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H3><A NAME="Static_mod_perl_and_dynamic_Rave">Static mod_perl and dynamic Raven SSL Installation</A></H3></CENTER>
  -<P><A NAME="anchor392"></A>
  +<P>
   To installs Raven SSL dynamically and mod_perl statically:
   
   <OL>
   <P><LI>
  -<P><A NAME="anchor393"></A>
  +<P>
   Un-tar and un-gunzip Apache, Raven SSL and mod_perl into their respective
   directories
   
   <P><LI>
  -<P><A NAME="anchor394"></A>
  -<PRE>  % cd raven_ssl-x.x.x
  -</PRE>
  -<P><A NAME="anchor395"></A>
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  % cd raven_ssl-x.x.x</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Install Raven SSL via
   
  -<P><A NAME="anchor396"></A>
  -<PRE>  % ./setup
  -</PRE>
  -<P><LI>
  -<P><A NAME="anchor397"></A>
  -<PRE>  % /usr/local/raven/bin/ravenctl
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  % ./setup</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P><LI>
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  % /usr/local/raven/bin/ravenctl
        select Option 1, 'Raven SSL Module Manager'
  -     select Option 2, 'Export Raven SSL module to Apache source'
  -</PRE>
  -<P><A NAME="anchor398"></A>
  +     select Option 2, 'Export Raven SSL module to Apache source'</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Note: Option 2 exports the required EAPI patches and the needed Raven SSL
   module files into your Apache source tree
   
   <P><LI>
  -<P><A NAME="anchor399"></A>
  -<PRE>  % cd mod_perl-x.xx
  -</PRE>
  -<P><LI>
  -<P><A NAME="anchor400"></A>
  -<PRE>  % perl Makefile.PL APACHE_PREFIX=/path/to/apache_1.x.x \
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  % cd mod_perl-x.xx</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P><LI>
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  % perl Makefile.PL APACHE_PREFIX=/path/to/apache_1.x.x \
           APACHE_SRC=/path/to/apache_x.x.x \
           EVERYTHING=1 \
           USE_APACI=1 \
           PREP_HTTPD=1 \
  -        DO_HTTPD=1
  -</PRE>
  -<P><LI>
  -<P><A NAME="anchor401"></A>
  -<PRE>  % make ; make install
  -</PRE>
  -<P><LI>
  -<P><A NAME="anchor402"></A>
  -<PRE>  % cd ../apache-x.x.x
  -</PRE>
  -<P><LI>
  -<P><A NAME="anchor403"></A>
  -<PRE>  % ./configure --target=httpsd \
  +        DO_HTTPD=1</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P><LI>
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  % make ; make install</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P><LI>
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  % cd ../apache-x.x.x</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P><LI>
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  % ./configure --target=httpsd \
         --enable-module=most \
         --enable-shared=max \
         --enable-suexec \
         --suexec-logfile=logs/suexec.log \
  -      --activate-module=src/modules/perl/libperl.a
  -</PRE>
  -<P><LI>
  -<P><A NAME="anchor404"></A>
  -<PRE>  % make ; make install
  -</PRE>
  -<P><LI>
  -<P><A NAME="anchor405"></A>
  +      --activate-module=src/modules/perl/libperl.a</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P><LI>
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  % make ; make install</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P><LI>
  +<P>
   In the <EM>httpd.conf</EM> file make sure that the AddModule&nbsp;mod_perl.c
   line is above <CODE>&lt;IfDefine SSL&gt;</CODE> section.
   
   </OL>
  -<P><A NAME="anchor406"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H1><A NAME="mod_perl_Installation_with_the_C">mod_perl Installation with the CPAN.pm Interactive Shell</A></H1></CENTER>
  -<P><A NAME="anchor407"></A>
  +<P>
   Installation of mod_perl and all the required packages is much easier with
   help of the <CODE>CPAN.pm</CODE> module, which provides you among other features with a shell interface to
   the CPAN repository. CPAN is the Comprehensive Perl Archive Network, a
  @@ -2023,45 +3599,102 @@
   of documentation. See <A HREF="http://cpan.org">http://cpan.org</A> for
   more information.
   
  -<P><A NAME="anchor408"></A>
  +<P>
   The first thing first is to download the Apache source code and unpack it
   into a directory -- the name of which you will need very soon.
   
  -<P><A NAME="anchor409"></A>
  +<P>
   Now execute:
  +
  +<P>
   
  -<P><A NAME="anchor410"></A>
  -<PRE>  % perl -MCPAN -eshell
  -</PRE>
  -<P><A NAME="anchor411"></A>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  % perl -MCPAN -eshell</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   If it's the first time that you have used it, <CODE>CPAN.pm</CODE> will ask you about a dozen questions to configure the module. It's quite
   easy to accomplish this task, and very helpful hints come along with the
   questions. When you are finished you will see the <CODE>CPAN</CODE> prompt:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor412"></A>
  -<PRE>  cpan&gt; 
  -</PRE>
  -<P><A NAME="anchor413"></A>
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  cpan&gt; </pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   It can be a good idea to install a special <CODE>CPAN</CODE> bundle of modules to make using the CPAN module easier. Installation is as
   simple as typing:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor414"></A>
  -<PRE>  cpan&gt; install Bundle::CPAN
  -</PRE>
  -<P><A NAME="anchor415"></A>
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  cpan&gt; install Bundle::CPAN</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   The <CODE>CPAN</CODE> shell can download mod_perl for you, unpack it, check for prerequisites,
   detect any missing third party modules, and download and install them. All
   you need to do to install mod_perl is to type at the prompt:
   
  -<P><A NAME="anchor416"></A>
  -<PRE>  cpan&gt; install mod_perl
  -</PRE>
  -<P><A NAME="anchor417"></A>
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  cpan&gt; install mod_perl</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   You will see (I'll use <CODE>x.xx</CODE> as a placeholder for real version numbers, since these change very
   frequently):
  +
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
   
  -<P><A NAME="anchor418"></A>
  -<PRE>  Running make for DOUGM/mod_perl-x.xx.tar.gz
  +	<td>
  +	  <pre>  Running make for DOUGM/mod_perl-x.xx.tar.gz
     Fetching with LWP:
     <A HREF="http://www.perl.com/CPAN-local/authors/id/DOUGM/mod_perl-x.xx.tar.gz">http://www.perl.com/CPAN-local/authors/id/DOUGM/mod_perl-x.xx.tar.gz</A>
     
  @@ -2069,9 +3702,12 @@
     
     Enter `q' to stop search
     Please tell me where I can find your apache src
  -  [../apache_x.x.x/src]
  -</PRE>
  -<P><A NAME="anchor419"></A>
  +  [../apache_x.x.x/src]</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   <CODE>CPAN.pm</CODE> will search for the latest Apache sources and suggest a directory. Here,
   unless the CPAN shell found it and suggested the right directory, you need
   to type the directory into which you unpacked Apache. The next question is
  @@ -2079,73 +3715,157 @@
   distribution. In most cases the CPAN shell will suggest the correct
   directory.
   
  -<P><A NAME="anchor420"></A>
  -<PRE>  Please tell me where I can find your apache src
  -  [../apache_x.x.x/src] 
  -</PRE>
  -<P><A NAME="anchor421"></A>
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  Please tell me where I can find your apache src
  +  [../apache_x.x.x/src] </pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Answer yes to all the following questions, unless you have a reason not to
   do that.
  +
  +<P>
   
  -<P><A NAME="anchor422"></A>
  -<PRE>  Configure mod_perl with /usr/src/apache_x.x.x/src ? [y] 
  -  Shall I build httpd in /usr/src/apache_x.x.x/src for you? [y] 
  -</PRE>
  -<P><A NAME="anchor423"></A>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  Configure mod_perl with /usr/src/apache_x.x.x/src ? [y] 
  +  Shall I build httpd in /usr/src/apache_x.x.x/src for you? [y] </pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Now we will build Apache with mod_perl enabled. Quit the <CODE>CPAN</CODE>
   shell, or use use another terminal. Go to the Apache sources root directory
   and run:
  +
  +<P>
   
  -<P><A NAME="anchor424"></A>
  -<PRE>  % make install
  -</PRE>
  -<P><A NAME="anchor425"></A>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  % make install</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   which will complete the installation by installing Apache's headers and the
   binary in the appropriate directories.
   
  -<P><A NAME="anchor426"></A>
  +<P>
   The only caveat of the process I've described is that you don't have
   control over the configuration process. Actually, that problem is easy to
   solve -- you can tell <CODE>CPAN.pm</CODE> to pass whatever parameters you want to <CODE>perl Makefile.PL</CODE>. You do this with <CODE>o conf
   makepl_arg</CODE> command:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor427"></A>
  -<PRE>  cpan&gt; o conf makepl_arg 'DO_HTTPD=1 USE_APACI=1 EVERYTHING=1'
  -</PRE>
  -<P><A NAME="anchor428"></A>
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  cpan&gt; o conf makepl_arg 'DO_HTTPD=1 USE_APACI=1 EVERYTHING=1'</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Just list all the parameters as if you were passing them to the familiar <CODE>perl Makefile.PL</CODE>. If you add the
   <CODE>APACHE_SRC=/usr/src/apache_x.x.x/src</CODE> and <CODE>DO_HTTPD=1</CODE> parameters, you will not be asked a single question. Of course you must
   give the correct path to the Apache source distribution.
   
  -<P><A NAME="anchor429"></A>
  +<P>
   Now proceed with <CODE>install mod_perl</CODE> as before. When the installation is completed, remember to unset the <CODE>makepl_arg</CODE> variable by executing:
   
  -<P><A NAME="anchor430"></A>
  -<PRE>  cpan&gt; o conf makepl_arg ''
  -</PRE>
  -<P><A NAME="anchor431"></A>
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  cpan&gt; o conf makepl_arg ''</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   If you have previously set <CODE>makepl_arg</CODE> to some value, before you alter it for the mod_perl installation you will
   probably want to save it somewhere so that you can restore it when you have
   finished with the mod_perl installation. To see the original value, use:
  +
  +<P>
   
  -<P><A NAME="anchor432"></A>
  -<PRE>  cpan&gt; o conf makepl_arg
  -</PRE>
  -<P><A NAME="anchor433"></A>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  cpan&gt; o conf makepl_arg</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   You can now install all the modules you might want to use with mod_perl.
   You install them all by typing a singe command:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor434"></A>
  -<PRE>  cpan&gt; install Bundle::Apache
  -</PRE>
  -<P><A NAME="anchor435"></A>
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  cpan&gt; install Bundle::Apache</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   This will install mod_perl if isn't yet installed, and many other packages
   such as: <CODE>ExtUtils::Embed</CODE>, <CODE>MIME::Base64</CODE>, <CODE>URI::URL</CODE>,
   <CODE>Digest::MD5</CODE>, <CODE>Net::FTP</CODE>, <CODE>LWP</CODE>, <CODE>HTML::TreeBuilder</CODE>, <CODE>CGI</CODE>,
   <CODE>Devel::Symdump</CODE>, <CODE>Apache::DB</CODE>, <CODE>Tie::IxHash</CODE>, <CODE>Data::Dumper</CODE> 
   etc.
   
  -<P><A NAME="anchor436"></A>
  +<P>
   A helpful hint: If you have a system with all the Perl modules you use and
   you want to replicate them all elsewhere, and if you cannot just copy the
   whole <CODE>/usr/lib/perl5</CODE> directory because of a possible binary incompatibility on the other system,
  @@ -2154,40 +3874,77 @@
   definition file for all modules that are installed for the currently
   running perl interpreter.
   
  -<P><A NAME="anchor437"></A>
  +<P>
   With the clever bundle file you can then simply say
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor438"></A>
  -<PRE>  cpan&gt; install Bundle::my_bundle
  -</PRE>
  -<P><A NAME="anchor439"></A>
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  cpan&gt; install Bundle::my_bundle</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   and after answering a few questions, go out for a coffee.
   
  -<P><A NAME="anchor440"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H1><A NAME="Installing_on_multiple_machines">Installing on multiple machines</A></H1></CENTER>
  -<P><A NAME="anchor441"></A>
  +<P>
   You may wish to build httpd once, then copy it to other machines. The Perl
   side of mod_perl needs the Apache headers files to compile. To avoid
   dragging and build Apache on all your other machines, there are a few
   Makefile targets to help you out:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor442"></A>
  -<PRE>  % make tar_Apache
  -</PRE>
  -<P><A NAME="anchor443"></A>
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  % make tar_Apache</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   This will tar all files mod_perl installs in your Perl's <EM>site_perl</EM>
   directory, into a file called <EM>Apache.tar</EM>. You can then unpack this under the <EM>site_perl</EM> directory on another machine.
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor444"></A>
  -<PRE>  % make offsite-tar
  -</PRE>
  -<P><A NAME="anchor445"></A>
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  % make offsite-tar</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   This will copy all the header files from the Apache source directory which
   you configured mod_perl against, then it will <CODE>make dist</CODE> which creates a mod_perl-x.xx.tar.gz, ready to unpack on another machine to
   compile and install the Perl side of mod_perl.
   
  -<P><A NAME="anchor446"></A>
  +<P>
   If you really want to make your life easy you should use one of the more
   advanced packaging systems. For example, almost all Linux OS distributions
   use packaging tools on top of plain tar.gz, allowing you to track
  @@ -2196,12 +3953,12 @@
   Manager). See <A HREF="http://www.rpm.org">http://www.rpm.org</A> for more
   information.
   
  -<P><A NAME="anchor447"></A>
  +<P>
   All you have to do is prepare a SRPM (source distribution package), then
   build a binary release. This can be installed on any number of machines in
   a matter of seconds.
   
  -<P><A NAME="anchor448"></A>
  +<P>
   It will even work on live machines! If you have two identical machines
   (identical software and hardware, although depending on your setup hardware
   may be less critical). Let's say that one is a live server and the other is
  @@ -2211,57 +3968,72 @@
   without any fear. Make sure that <EM>httpd.conf</EM> is correct, since it generally includes parameters such as hostname which
   are unique to the live machine.
   
  -<P><A NAME="anchor449"></A>
  +<P>
   When you have installed the package, just restart the server. It can be a
   good idea to keep a package of the previous system, in case something goes
   wrong. You can then easily remove the installed package and put the old one
   back.
   
  -<P><A NAME="anchor450"></A>
  +<P>
   ([ReaderMETA]: Dear reader, Can you please share a step by step scenario of
   preparation of SRPMs for mod_perl? Thanks!!!)
   
  -<P><A NAME="anchor451"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H1><A NAME="using_RPM_DEB_and_other_package">using RPM, DEB and other packages to install mod_perl</A></H1></CENTER>
  -<P><A NAME="anchor452"></A>
  +<P>
   [ReaderMETA]: Currently only RPM and Debian packages. Please submit info
   about other available packages if you use such.
   
  -<P><A NAME="anchor453"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="Static_debian_package">Static debian package</A></H2></CENTER>
  -<P><A NAME="anchor454"></A>
  +<P>
   David Huggins-Daines has built a static Apache/mod_perl 1.3.9/1.21 Debian
   package.
   
  -<P><A NAME="anchor455"></A>
  +<P>
   David has hacked the Debian package to build the Apache binary, with static
   mod_perl. Source and binary packages are at:
   
  -<P><A NAME="anchor456"></A>
  +<P>
   <A
   HREF="http://elgin.plcom.on.ca/debian/dists/unstable/main/">http://elgin.plcom.on.ca/debian/dists/unstable/main/</A>
   
   
  -<P><A NAME="anchor457"></A>
  +<P>
   Or put this in your <EM>/etc/apt/sources.list</EM> and run <CODE>&quot;apt-get
   install apache-perl&quot;</CODE>:
  +
  +<P>
   
  -<P><A NAME="anchor458"></A>
  -<PRE>  % deb <A HREF="http://elgin.plcom.on.ca/debian">http://elgin.plcom.on.ca/debian</A> unstable main
  -</PRE>
  -<P><A NAME="anchor459"></A>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  % deb <A HREF="http://elgin.plcom.on.ca/debian">http://elgin.plcom.on.ca/debian</A> unstable main</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Note: this server may be up and down for a bit, it's also the development
   machine for David's project at work that uses mod_perl...
   
  -<P><A NAME="anchor460"></A>
  +<P>
   These aren't official debian packages, of course.
   
  -<P><A NAME="anchor461"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="A_word_on_mod_perl_RPM_packages">A word on mod_perl RPM packages</A></H2></CENTER>
  -<P><A NAME="anchor462"></A>
  +<P>
   The virtues of RPM packages is a subject of much debate among mod_perl
   users. While RPMs do take the pain away from package installation and
   maintenance for most applications, the nuances of mod_perl make RPMs
  @@ -2270,114 +4042,130 @@
   know what you are doing, this is probably Old Hat - contributing your past
   experiences is, as always, welcomed by the community.
   
  -<P><A NAME="anchor463"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="Getting_Started">Getting Started</A></H2></CENTER>
  -<P><A NAME="anchor464"></A>
  +<P>
   If you are new to mod_perl and are using this Guide and the Eagle Book to
   help you on your way, it is probably better to grab the latest Apache and
   mod_perl sources and compile the sources yourself. Not only will you find
   that this is less daunting than you suspect, but it will probably save you
   a few headaches down the line for several reasons.
   
  -<P><A NAME="anchor465"></A>
  +<P>
   First, given the pace at which the open source community produces software,
   RPMs, especially those found on distribution CDs, are often several
   versions out of date. The most recent version will not only be more stable,
   but will likely incorporate some new functionality that you will eventually
   want to play with.
   
  -<P><A NAME="anchor466"></A>
  +<P>
   It is also unlikely that the file system layout of an RPM package will
   match what you see in the Eagle Book and this Guide. If you are new to
   mod_perl, Apache, or both you will probably want to get familiar with the
   file system layout used by the examples given here before trying something
   non-standard.
   
  -<P><A NAME="anchor467"></A>
  +<P>
   Finally, the RPMs found on a typical distribution's CDs use mod_perl built
   with Apache's Dynamic Shared Objects (<CODE>DSO</CODE>) support. While mod_perl can be successfully used as a DSO module, it adds
   a layer of complexity that you may want to live without for now.
   
  -<P><A NAME="anchor468"></A>
  +<P>
   All that being said, should you still feel that rolling your own mod_perl
   enabled Apache server is not likely, here are a few helpful hints...
   
  -<P><A NAME="anchor469"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="Compiling_RPM_source_files">Compiling RPM source files</A></H2></CENTER>
  -<P><A NAME="anchor470"></A>
  +<P>
   It is possible to compile the source files provided by RPM packages, but if
   you are using RPMs to ease mod_perl installation, that is not the way to do
   it. Both Apache and mod_perl RPMs are designed to be install-and-go. If you
   really want to compile mod_perl to your own specific needs, your best bet
   is to get the most recent sources from CPAN.
   
  -<P><A NAME="anchor471"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="Mix_and_Match_RPM_and_source">Mix and Match RPM and source</A></H2></CENTER>
  -<P><A NAME="anchor472"></A>
  +<P>
   It is probably not the best idea to use a self-compiled Apache with a
   mod_perl RPM (or vice versa). Sticking with one format or the other at
   first will result in fewer headaches and more hair.
   
  -<P><A NAME="anchor473"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="Installing_a_single_apache_mod_p">Installing a single apache+mod_perl RPM</A></H2></CENTER>
  -<P><A NAME="anchor474"></A>
  +<P>
   If you use an Apache+mod_perl RPM, chances are <CODE>rpm -i</CODE> or <CODE>glint</CODE>
   (GUI for RPM) will have you up and running immediately, no compilation
   necessary. If you encounter problems, try downloading from another mirror
   site or searching <A HREF="http://rpmfind.net/">http://rpmfind.net/</A> for
   a different package - there are plenty out there to choose from.
   
  -<P><A NAME="anchor475"></A>
  +<P>
   David Harris has started an effort to build better RPM/SRPM mod_perl
   packages. You will find them at: <A
   HREF="http://www.davideous.com/modperlrpm/distrib/">http://www.davideous.com/modperlrpm/distrib/</A>
   
   
  -<P><A NAME="anchor476"></A>
  +<P>
   Features of this RPM:
   
   <UL>
   <P><LI>
  -<P><A NAME="anchor477"></A>
  +<P>
   Installs mod_perl as an ``add in'' to the RedHat Apache package, but does
   not install mod_perl as a DSO and all the problems that brings.
   
   <P><LI>
  -<P><A NAME="anchor478"></A>
  +<P>
   Includes the four header files required for building <CODE>libapreq</CODE>
   (<CODE>Apache::Request</CODE>)
   
   <P><LI>
  -<P><A NAME="anchor479"></A>
  +<P>
   Distributes plain text forms of the pod documentation files that come with
   mod_perl.
   
   <P><LI>
  -<P><A NAME="anchor480"></A>
  +<P>
   Checks the module magic number on the existing Apache package to see if
   things are compatible
   
   </UL>
  -<P><A NAME="anchor481"></A>
  +<P>
   Notes on this un-conventional RPM packaging of mod_perl
   
  -<P><A NAME="anchor482"></A>
  +<P>
   by David Harris &lt;<A
   HREF="mailto:dharris@drh.net">dharris@drh.net</A>&gt; on Oct 13, 1999
   
  -<P><A NAME="anchor483"></A>
  +<P>
   This package will install the mod_perl library files on your machine along
   with the following two Apache files:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor484"></A>
  -<PRE>  /usr/lib/apache/mod_include_modperl.so
  -  /usr/sbin/httpd_modperl
  -</PRE>
  -<P><A NAME="anchor485"></A>
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  /usr/lib/apache/mod_include_modperl.so
  +  /usr/sbin/httpd_modperl</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   This package does not install a complete Apache subtree built with
   mod_perl, but rather just the two above files that are different for
   mod_perl. This conceptually thinks of mod_perl as a kind of an ``add on''
  @@ -2390,47 +4178,84 @@
   configuration files and other DSO modules, but you just ``enable'' the
   mod_perl ``add on'' by following the directions below.
   
  -<P><A NAME="anchor486"></A>
  +<P>
   To enable mod_perl, do the following:
   
  -<P><A NAME="anchor487"></A>
  -<PRE>  (1) Configure /etc/rc.d/init.d/httpd to run httpd_modperl instead of
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  (1) Configure /etc/rc.d/init.d/httpd to run httpd_modperl instead of
         httpd by changing the &quot;daemon&quot; command line.
     (2) Replace mod_include.so with mod_include_modperl.so in the
         module loading section of /etc/httpd/conf/httpd.conf
  -  (3) Uncomment the &quot;AddModule mod_perl.c&quot; line in /etc/httpd/conf/httpd.conf
  -</PRE>
  -<P><A NAME="anchor488"></A>
  +  (3) Uncomment the &quot;AddModule mod_perl.c&quot; line in /etc/httpd/conf/httpd.conf</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Or run the following command:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor489"></A>
  -<PRE>  /usr/sbin/modperl-enable on
  -</PRE>
  -<P><A NAME="anchor490"></A>
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  /usr/sbin/modperl-enable on</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   and to disable mod_perl:
   
  -<P><A NAME="anchor491"></A>
  -<PRE>  /usr/sbin/modperl-enable off
  -</PRE>
  -<P><A NAME="anchor492"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  /usr/sbin/modperl-enable off</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="Compiling_libapreq_Apache_Requ">Compiling libapreq (Apache::Request) with the RH 6.0 mod_perl RPM</A></H2></CENTER>
  -<P><A NAME="anchor493"></A>
  +<P>
   Libapreq provides the <A HREF="././download.html#Apache_Request">Apache::Request</A>
   module.
   
  -<P><A NAME="anchor494"></A>
  +<P>
   Despite many reports of libapreq not working properly with various RPM
   packages, it is possible to integrate libapreq with mod_perl RPMs. It just
   requires a few additional steps.
   
   <OL>
   <P><LI>
  -<P><A NAME="anchor495"></A>
  +<P>
   Make certain you have the <CODE>apache-devel-x.x.x-x.i386.rpm</CODE> package installed. Also, download the latest version of libapreq from CPAN.
   
   <P><LI>
  -<P><A NAME="anchor496"></A>
  +<P>
   Install the source RPM for your mod_perl RPM and then do a build prep,
   (with <CODE>rpm -bp apache-devel-x.x.x-x.src.rpm</CODE>) which unpacks the sources. From there, copy the four header files (<EM>mod_perl.h</EM>,
   <EM>mod_perl_version.h</EM>, <EM>mod_perl_xs.h</EM>, and <EM>mod_PL.h</EM>) to
  @@ -2438,25 +4263,46 @@
   
   <UL>
   <P><LI>
  -<P><A NAME="anchor497"></A>
  +<P>
   2.1 Get the SRPM from
   <CODE>somemirror.../redhat-x.x/SRPMS/mod_perl-x.xx-x.src.rpm</CODE>.
   
   <P><LI>
  -<P><A NAME="anchor498"></A>
  +<P>
   2.2 Install the SRPM. This creates files in <CODE>/usr/src/redhat/SPECS</CODE>
   and <CODE>/usr/src/redhat/SOURCES</CODE>. Run:
   
  -<P><A NAME="anchor499"></A>
  -<PRE> % rpm -ih mod_perl-x.xx-x.src.rpm
  -</PRE>
  -<P><LI>
  -<P><A NAME="anchor500"></A>
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre> % rpm -ih mod_perl-x.xx-x.src.rpm</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P><LI>
  +<P>
   2.3 Do a <CODE>&quot;prep&quot;</CODE> build of the package, which just unpackages the sources and applies any
   patches.
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor501"></A>
  -<PRE>  % rpm -bp /usr/src/redhat/SPECS/mod_perl.spec
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  % rpm -bp /usr/src/redhat/SPECS/mod_perl.spec
     Executing: %prep
     + umask 022
     + cd /usr/src/redhat/BUILD
  @@ -2477,9 +4323,12 @@
     + echo Patch #0:
     Patch #0:
     + patch -p1 -b --suffix .rh -s
  -  + exit 0
  -</PRE>
  -<P><A NAME="anchor502"></A>
  +  + exit 0</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   NOTE: Steps 2.1 through 2.3 are just a fancy un-packing of the source tree
   that builds the RPM into <CODE>/usr/src/redhat/BUILD/mod_perl-x.xx</CODE>. You could unpack the <CODE>mod_perl-x.xx.tar.gz</CODE> file somewhere and then do the following steps on that source tree. The
   method shown above is more ``pure'' because you're grabbing the header
  @@ -2489,54 +4338,103 @@
   and mess.
   
   <P><LI>
  -<P><A NAME="anchor503"></A>
  +<P>
   2.4 Look at the files you will copy: (this is not really a step, but useful
   to show)
  +
  +<P>
   
  -<P><A NAME="anchor504"></A>
  -<PRE>  % find /usr/src/redhat/BUILD/mod_perl-1.19 -name '*.h'
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  % find /usr/src/redhat/BUILD/mod_perl-1.19 -name '*.h'
     /usr/src/redhat/BUILD/mod_perl-1.19/src/modules/perl/mod_perl.h
     /usr/src/redhat/BUILD/mod_perl-1.19/src/modules/perl/mod_perl_xs.h
     /usr/src/redhat/BUILD/mod_perl-1.19/src/modules/perl/mod_perl_version.h
  -  /usr/src/redhat/BUILD/mod_perl-1.19/src/modules/perl/perl_PL.h
  -</PRE>
  -<P><LI>
  -<P><A NAME="anchor505"></A>
  +  /usr/src/redhat/BUILD/mod_perl-1.19/src/modules/perl/perl_PL.h</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P><LI>
  +<P>
   2.5 Copy the files into <CODE>/usr/include/apache</CODE>.
   
  -<P><A NAME="anchor506"></A>
  -<PRE>  % find /usr/src/redhat/BUILD/mod_perl-1.19 -name '*.h' \
  -    -exec cp {} /usr/include/apache \;
  -</PRE>
  -<P><A NAME="anchor507"></A>
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  % find /usr/src/redhat/BUILD/mod_perl-1.19 -name '*.h' \
  +    -exec cp {} /usr/include/apache \;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   NOTE: You should not have to do:
  +
  +<P>
   
  -<P><A NAME="anchor508"></A>
  -<PRE>  % mkdir /usr/include/apache
  -</PRE>
  -<P><A NAME="anchor509"></A>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  % mkdir /usr/include/apache</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   because that directory should be created by apache-devel.
   
   </UL>
   <P><LI>
  -<P><A NAME="anchor510"></A>
  +<P>
   Apply this patch to libapreq: <A
   HREF="http://www.davideous.com/modperlrpm/distrib/libapreq-0.31_include.patch">http://www.davideous.com/modperlrpm/distrib/libapreq-0.31_include.patch</A>
   
   
   <P><LI>
  -<P><A NAME="anchor511"></A>
  +<P>
   Follow the libapreq directions as usual:
   
  -<P><A NAME="anchor512"></A>
  -<PRE>  % perl Makefile.PL
  -  % make &amp;&amp; make test &amp;&amp; make install
  -</PRE>
  -</OL>
  -<P><A NAME="anchor513"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  % perl Makefile.PL
  +  % make &amp;&amp; make test &amp;&amp; make install</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    </OL>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="Installing_separate_Apache_and_m">Installing separate Apache and mod_perl RPMs</A></H2></CENTER>
  -<P><A NAME="anchor514"></A>
  +<P>
   If you are trying to install separate Apache and mod_perl RPMs, like those
   provided by the RedHat distributions, you may be in for a bit of a
   surprise. Installing the Apache RPM will go just fine, and <A
  @@ -2546,12 +4444,21 @@
   mod_perl needs to be added as a separate module using Apache's Dynamic
   Shared Objects.
   
  -<P><A NAME="anchor515"></A>
  +<P>
   To use mod_perl as a DSO, make the following modifications to your Apache
   configuration files:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor516"></A>
  -<PRE>  httpd.conf:
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  httpd.conf:
     ----------
     LoadModule perl_module modules/libperl.so
     AddModule mod_perl.c
  @@ -2563,161 +4470,309 @@
       PerlHandler Apache::Registry 
       PerlSendHeader On 
       Options +ExecCGI
  -  &lt;/Location
  -</PRE>
  -<P><A NAME="anchor517"></A>
  +  &lt;/Location</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   After a complete shutdown and startup of the server, mod_perl should be up
   and running.
   
  -<P><A NAME="anchor518"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="Testing_the_mod_perl_API">Testing the mod_perl API</A></H2></CENTER>
  -<P><A NAME="anchor519"></A>
  +<P>
   Some people have reported that even when the server responds positively to
   the <A HREF="././install.html#How_can_I_tell_whether_mod_perl_">How can I tell whether mod_perl is running</A> tests, the mod_perl API will not function properly. You may want to run the
   following script to verify the availability of the mod_perl API.
   
  -<P><A NAME="anchor520"></A>
  -<PRE>        use strict;
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>        use strict;
           my $r = shift;
           $r-&gt;send_http_header('text/html');
  -        $r-&gt;print(&quot;It worked!!!\n&quot;);
  -</PRE>
  -<P><A NAME="anchor521"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +        $r-&gt;print(&quot;It worked!!!\n&quot;);</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H1><A NAME="Installation_Without_Superuser_P">Installation Without Superuser Privileges</A></H1></CENTER>
  -<P><A NAME="anchor522"></A>
  +<P>
   As you have already learned, mod_perl enabled Apache consists of two main
   components: perl modules and Apache itself. Let's tackle the tasks one at a
   time.
   
  -<P><A NAME="anchor523"></A>
  +<P>
   I'll show a complete installation example using <EM>stas</EM> as a username, assuming that <EM>/home/stas</EM> is the home directory of that user.
   
  -<P><A NAME="anchor524"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="Installing_Perl_Modules_into_a_D">Installing Perl Modules into a Directory of Choice</A></H2></CENTER>
  -<P><A NAME="anchor525"></A>
  +<P>
   Since without superuser permissions you aren't allowed to install modules
   into system directories like <EM>/usr/lib/perl5</EM>, you need to find out how to install the modules under your home
   directory. It's easy.
   
  -<P><A NAME="anchor526"></A>
  +<P>
   First you have to decide where to install the modules. The simplest
   approach is to simulate the portion of the <EM>/</EM> file system relevant to Perl under your home directory. Actually we need
   only two directories:
   
  -<P><A NAME="anchor527"></A>
  -<PRE>  /home/stas/bin
  -  /home/stas/lib
  -</PRE>
  -<P><A NAME="anchor528"></A>
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  /home/stas/bin
  +  /home/stas/lib</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   We don't have to create them, since that will be done automatically when
   the first module is installed. 99% of the files will go into the
   <EM>lib</EM> directory. Occasionally, when some module distribution comes with Perl
   scripts, these will go into the <EM>bin</EM> directory. This directory will be created if it doesn't exist.
   
  -<P><A NAME="anchor529"></A>
  +<P>
   Let's install the <EM>CGI.pm</EM> package, which includes a few other
   <CODE>CGI::*</CODE> modules. As usual, download the package from the CPAN repository, unpack it
   and <CODE>chdir</CODE> to the newly-created directory.
   
  -<P><A NAME="anchor530"></A>
  +<P>
   Now do a standard <CODE>perl Makefile.PL</CODE> to prepare a <EM>Makefile</EM>, but this time tell <CODE>MakeMaker</CODE> to use your Perl installation directories instead of the defaults.
  +
  +<P>
   
  -<P><A NAME="anchor531"></A>
  -<PRE>  % perl Makefile.PL PREFIX=/home/stas
  -</PRE>
  -<P><A NAME="anchor532"></A>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  % perl Makefile.PL PREFIX=/home/stas</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   <CODE>PREFIX=/home/stas</CODE> is the only part of the installation process which is different from usual.
   Note that if you don't like how
   <CODE>MakeMaker</CODE> chooses the rest of the directories, or if you are using an older version
   of it which requires an explicit declaration of all the target directories,
   you should do this:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor533"></A>
  -<PRE>  % perl Makefile.PL PREFIX=/home/stas \
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  % perl Makefile.PL PREFIX=/home/stas \
       INSTALLPRIVLIB=/home/stas/lib/perl5 \
       INSTALLSCRIPT=/home/stas/bin \
       INSTALLSITELIB=/home/stas/lib/perl5/site_perl \
       INSTALLBIN=/home/stas/bin \
       INSTALLMAN1DIR=/home/stas/lib/perl5/man  \
  -    INSTALLMAN3DIR=/home/stas/lib/perl5/man3
  -</PRE>
  -<P><A NAME="anchor534"></A>
  +    INSTALLMAN3DIR=/home/stas/lib/perl5/man3</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   The rest is as usual:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor535"></A>
  -<PRE>  % make
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  % make
     % make test
  -  % make install
  -</PRE>
  -<P><A NAME="anchor536"></A>
  +  % make install</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   <CODE>make install</CODE> installs all the files in the private repository. Note that all the missing
   directories are created automatically, so there is no need to create them
   in first place. Here (slightly edited) is what it does :
  +
  +<P>
   
  -<P><A NAME="anchor537"></A>
  -<PRE>  Installing /home/stas/lib/perl5/CGI/Cookie.pm
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  Installing /home/stas/lib/perl5/CGI/Cookie.pm
     Installing /home/stas/lib/perl5/CGI.pm
     Installing /home/stas/lib/perl5/man3/CGI.3
     Installing /home/stas/lib/perl5/man3/CGI::Cookie.3
     Writing /home/stas/lib/perl5/auto/CGI/.packlist
  -  Appending installation info to /home/stas/lib/perl5/perllocal.pod
  -</PRE>
  -<P><A NAME="anchor538"></A>
  +  Appending installation info to /home/stas/lib/perl5/perllocal.pod</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   If you have to use the explicit target parameters, instead of a single
   <CODE>PREFIX</CODE> parameter, you will find it useful to create a file called for example <EM>~/.perl_dirs</EM> (where <EM>~</EM> is <CODE>/home/stas</CODE> in our example) containing:
  +
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
   
  -<P><A NAME="anchor539"></A>
  -<PRE>    PREFIX=/home/stas \
  +	<td>
  +	  <pre>    PREFIX=/home/stas \
       INSTALLPRIVLIB=/home/stas/lib/perl5 \
       INSTALLSCRIPT=/home/stas/bin \
       INSTALLSITELIB=/home/stas/lib/perl5/site_perl \
       INSTALLBIN=/home/stas/bin \
       INSTALLMAN1DIR=/home/stas/lib/perl5/man  \
  -    INSTALLMAN3DIR=/home/stas/lib/perl5/man3
  -</PRE>
  -<P><A NAME="anchor540"></A>
  +    INSTALLMAN3DIR=/home/stas/lib/perl5/man3</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   From now on, any time you want to install perl modules locally you simply
   execute:
   
  -<P><A NAME="anchor541"></A>
  -<PRE>  % perl Makefile.PL `cat ~/.perl_dirs`
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  % perl Makefile.PL `cat ~/.perl_dirs`
     % make
     % make test
  -  % make install
  -</PRE>
  -<P><A NAME="anchor542"></A>
  +  % make install</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Using this method you can easily maintain several Perl module repositories.
   For example, you could have one for production Perl and another for
   development:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor543"></A>
  -<PRE>  % perl Makefile.PL `cat ~/.perl_dirs.production`
  -</PRE>
  -<P><A NAME="anchor544"></A>
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  % perl Makefile.PL `cat ~/.perl_dirs.production`</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   or
   
  -<P><A NAME="anchor545"></A>
  -<PRE>  % perl Makefile.PL `cat ~/.perl_dirs.develop`
  -</PRE>
  -<P><A NAME="anchor546"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  % perl Makefile.PL `cat ~/.perl_dirs.develop`</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="Making_Your_Scripts_Find_the_Loc">Making Your Scripts Find the Locally Installed Modules</A></H2></CENTER>
  -<P><A NAME="anchor547"></A>
  +<P>
   Perl modules are generally placed in four main directories. To find these
   directories, execute:
   
  -<P><A NAME="anchor548"></A>
  -<PRE>  % perl -V
  -</PRE>
  -<P><A NAME="anchor549"></A>
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  % perl -V</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   The output contains important information about your Perl installation. At
   the end you will see:
  +
  +<P>
   
  -<P><A NAME="anchor550"></A>
  -<PRE>  Characteristics of this binary (from libperl):
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  Characteristics of this binary (from libperl):
     Built under linux
     Compiled at Apr  6 1999 23:34:07
     @INC:
  @@ -2725,147 +4780,255 @@
       /usr/lib/perl5/5.00503
       /usr/lib/perl5/site_perl/5.005/i386-linux
       /usr/lib/perl5/site_perl/5.005
  -    .
  -</PRE>
  -<P><A NAME="anchor551"></A>
  +    .</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   It shows us the content of the Perl special variable <CODE>@INC</CODE>, which is used by Perl to look for its modules. It is equivalent to the <CODE>PATH</CODE>
   environment variable in Unix shells which is used to find executable
   programs.
   
  -<P><A NAME="anchor552"></A>
  +<P>
   Notice that Perl looks for modules in the <EM>.</EM> directory too, which stands for the current directory. It's the last entry
   in the above output.
   
  -<P><A NAME="anchor553"></A>
  +<P>
   Of course this example is from version <EM>5.00503</EM> of Perl installed on my x86 architecture PC running Linux. That's why you
   see
   <EM>i386-linux</EM> and <EM>5.00503</EM>. If your system runs a different version of Perl, operating system,
   processor or chipset architecture, then some of the directories will have
   different names.
   
  -<P><A NAME="anchor554"></A>
  +<P>
   I also have a perl-5.00561 installed under <CODE>/usr/local/lib/</CODE>
   so when I do:
  +
  +<P>
   
  -<P><A NAME="anchor555"></A>
  -<PRE>  % /usr/local/bin/perl5.00561 -V
  -</PRE>
  -<P><A NAME="anchor556"></A>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  % /usr/local/bin/perl5.00561 -V</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   I see:
  +
  +<P>
   
  -<P><A NAME="anchor557"></A>
  -<PRE>  @INC:
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  @INC:
       /usr/local/lib/perl5/5.00561/i586-linux
       /usr/local/lib/perl5/5.00561
       /usr/local/lib/site_perl/5.00561/i586-linux
  -    /usr/local/lib/site_perl
  -</PRE>
  -<P><A NAME="anchor558"></A>
  +    /usr/local/lib/site_perl</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Note that it's still <EM>Linux</EM>, but the newer Perl version uses the version of my Pentium processor (thus
   the <EM>i586</EM> and not <EM>i386</EM>). This makes use of compiler optimizations for Pentium processors when the
   binary Perl extensions are created.
   
  -<P><A NAME="anchor559"></A>
  +<P>
   All the platform specific files, such as compiled C files glued to Perl
   with <CODE>XS</CODE> or <CODE>SWIG</CODE>, are supposed to go into the
   <CODE>i386-linux</CODE>-like directories.
   
  -<P><A NAME="anchor560"></A>
  +<P>
   <STRONG>Important:</STRONG> As we have installed the Perl modules into non-standard directories, we
   have to let Perl know where to look for the four directories. There are two
   ways to accomplish this. You can either set the <CODE>PERL5LIB</CODE> environment variable, or you can modify the
   <CODE>@INC</CODE> variable in your scripts.
   
  -<P><A NAME="anchor561"></A>
  +<P>
   Assuming that we use perl-5.00503, in our example the directories are:
  +
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
   
  -<P><A NAME="anchor562"></A>
  -<PRE>    /home/sbekman/lib/perl5/5.00503/i386-linux
  +	<td>
  +	  <pre>    /home/sbekman/lib/perl5/5.00503/i386-linux
       /home/sbekman/lib/perl5/5.00503
       /home/sbekman/lib/perl5/site_perl/5.005/i386-linux
  -    /home/sbekman/lib/perl5/site_perl/5.005
  -</PRE>
  -<P><A NAME="anchor563"></A>
  +    /home/sbekman/lib/perl5/site_perl/5.005</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   As mentioned before, you find the exact directories by executing
   <CODE>perl -V</CODE> and replacing the global Perl installation's base directory with your home
   directory.
   
  -<P><A NAME="anchor564"></A>
  +<P>
   Modifying <CODE>@INC</CODE> is quite easy. The best approach is to use the
   <CODE>lib</CODE> module (pragma), by adding the following snippet at the top of any of your
   scripts that require the locally installed modules.
   
  -<P><A NAME="anchor565"></A>
  -<PRE>  use lib qw(/home/stas/lib/perl5/5.00503/
  -             /home/stas/lib/perl5/site_perl/5.005);
  -</PRE>
  -<P><A NAME="anchor566"></A>
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  use lib qw(/home/stas/lib/perl5/5.00503/
  +             /home/stas/lib/perl5/site_perl/5.005);</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Another way is to write code to modify <CODE>@INC</CODE> explicitly:
  +
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
   
  -<P><A NAME="anchor567"></A>
  -<PRE>  BEGIN {
  +	<td>
  +	  <pre>  BEGIN {
       unshift @INC,
         qw(/home/stas/lib/perl5/5.00503
            /home/stas/lib/perl5/5.00503/i386-linux
            /home/stas/lib/perl5/site_perl/5.005
            /home/stas/lib/perl5/site_perl/5.005/i386-linux);
  -        }
  -</PRE>
  -<P><A NAME="anchor568"></A>
  +        }</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Note that with the <CODE>lib</CODE> module we don't have to list the corresponding architecture specific
   directories, since it adds them automatically if they exist (to be exact,
   when <EM>$dir/$archname/auto</EM>
   exists).
   
  -<P><A NAME="anchor569"></A>
  +<P>
   Also, notice that both approaches <EM>prepend</EM> the directories to be searched to <CODE>@INC</CODE>. This allows you to install a more recent module into your local
   repository and Perl will use it instead of the older one installed in the
   main system repository.
   
  -<P><A NAME="anchor570"></A>
  +<P>
   Both approaches modify the value of <CODE>@INC</CODE> at compilation time. The
   <CODE>lib</CODE> module uses the <EM>BEGIN</EM> block as well, but internally.
   
  -<P><A NAME="anchor571"></A>
  +<P>
   Now, let's assume the following scenario. I have installed the <CODE>LWP</CODE>
   package in my local repository. Now I want to install another module (e.g.
   mod_perl) and it has <CODE>LWP</CODE> listed in its prerequisites list. I know that I have <CODE>LWP</CODE> installed, but when I run <CODE>perl Makefile.PL</CODE>
   for the module I'm about to install I'm told that I don't have <CODE>LWP</CODE>
   installed.
   
  -<P><A NAME="anchor572"></A>
  +<P>
   There is no way for Perl to know that we have some locally installed
   modules. All it does is search the directories listed in <CODE>@INC</CODE>, and since the latter contains only the default four directories (plus the
   <EM>.</EM> directory), it cannot find the locally installed <CODE>LWP</CODE> package. We cannot solve this problem by adding code to modify <CODE>@INC</CODE>, but changing the <CODE>PERL5LIB</CODE> environment variable will do the trick. If you are using <CODE>t?csh</CODE> for interactive work, do this:
   
  -<P><A NAME="anchor573"></A>
  -<PRE>  setenv PERL5LIB /home/stas/lib/perl5/5.00503:
  -  /home/stas/lib/perl5/site_perl/5.005
  -</PRE>
  -<P><A NAME="anchor574"></A>
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  setenv PERL5LIB /home/stas/lib/perl5/5.00503:
  +  /home/stas/lib/perl5/site_perl/5.005</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   It should be a single line with directories separated by colons (<CODE>:</CODE>) and no spaces. If you are a <CODE>(ba)?sh</CODE> user, do this:
  +
  +<P>
   
  -<P><A NAME="anchor575"></A>
  -<PRE>  export PERL5LIB=/home/stas/lib/perl5/5.00503:
  -  /home/stas/lib/perl5/site_perl/5.005
  -</PRE>
  -<P><A NAME="anchor576"></A>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  export PERL5LIB=/home/stas/lib/perl5/5.00503:
  +  /home/stas/lib/perl5/site_perl/5.005</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Again make it a single line. If you use bash you can use multi-line
   commands by terminating split lines with a backslash (<CODE>\</CODE>), like this:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor577"></A>
  -<PRE>  export PERL5LIB=/home/stas/lib/perl5/5.00503:\
  -  /home/stas/lib/perl5/site_perl/5.005
  -</PRE>
  -<P><A NAME="anchor578"></A>
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  export PERL5LIB=/home/stas/lib/perl5/5.00503:\
  +  /home/stas/lib/perl5/site_perl/5.005</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   As with <CODE>use lib</CODE>, perl automatically prepends the architecture specific directories to <CODE>@INC</CODE> if those exist.
   
  -<P><A NAME="anchor579"></A>
  +<P>
   When you have done this, verify the value of the newly configured
   <CODE>@INC</CODE> by executing <CODE>perl -V</CODE> as before. You should see the modified value of <CODE>@INC</CODE>:
   
  -<P><A NAME="anchor580"></A>
  -<PRE>  % perl -V
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  % perl -V
     
     Characteristics of this binary (from libperl): 
     Built under linux
  @@ -2881,216 +5044,411 @@
       /usr/lib/perl5/5.00503
       /usr/lib/perl5/site_perl/5.005/i386-linux
       /usr/lib/perl5/site_perl/5.005
  -    .
  -</PRE>
  -<P><A NAME="anchor581"></A>
  +    .</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   When everything works as you want it to, add these commands to your
   <EM>.tcshrc</EM> or <EM>.bashrc</EM> file. The next time you start a shell, the environment will be ready for
   you to work with the new Perl.
   
  -<P><A NAME="anchor582"></A>
  +<P>
   Note that if you have a <CODE>PERL5LIB</CODE> setting, you don't need to alter the <CODE>@INC</CODE> value in your scripts. But if for example someone else (who doesn't have
   this setting in the shell) tries to execute your scripts, Perl will fail to
   find your locally installed modules. The best example is a crontab script
   that <EM>might</EM> use a different SHELL environment and therefore the <CODE>PERL5LIB</CODE> setting won't be available to it.
   
  -<P><A NAME="anchor583"></A>
  +<P>
   So the best approach is to have both the <CODE>PERL5LIB</CODE> environment variable and the explicit <CODE>@INC</CODE> extension code at the beginning of the scripts as described above.
   
  -<P><A NAME="anchor584"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="The_CPAN_pm_Shell_and_Locally_In">The CPAN.pm Shell and Locally Installed Modules</A></H2></CENTER>
  -<P><A NAME="anchor585"></A>
  +<P>
   As we saw in the section describing the usage of the <CODE>CPAN.pm</CODE> shell to install mod_perl, it saves a great deal of time. It does the job
   for us, even detecting the missing modules listed in prerequisites,
   fetching and installing them. So you might wonder whether you can use
   <CODE>CPAN.pm</CODE> to maintain your local repository as well.
   
  -<P><A NAME="anchor586"></A>
  +<P>
   When you start the <CODE>CPAN</CODE> interactive shell, it searches first for the user's private configuration
   file and then for the system wide one. When I'm logged as user <CODE>stas</CODE> the two files on my setup are:
  +
  +<P>
   
  -<P><A NAME="anchor587"></A>
  -<PRE>    /home/stas/.cpan/CPAN/MyConfig.pm
  -    /usr/lib/perl5/5.00503/CPAN/Config.pm
  -</PRE>
  -<P><A NAME="anchor588"></A>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>    /home/stas/.cpan/CPAN/MyConfig.pm
  +    /usr/lib/perl5/5.00503/CPAN/Config.pm</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   If there is no <CODE>CPAN</CODE> shell configured on your system, when you start the shell for the first
   time it will ask you a dozen configuration questions and then create the <EM>Config.pm</EM> file for you.
   
  -<P><A NAME="anchor589"></A>
  +<P>
   If you've got it already system-wide configured, you should have a
   <CODE>/usr/lib/perl5/5.00503/CPAN/Config.pm</CODE>. If you have a different Perl version, alter the path to use your Perl's
   version number, when looking up the file. Create the directory (<CODE>mkdir -p</CODE> creates the whole path at once) where the local configuration file will go:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor590"></A>
  -<PRE>  % mkdir -p /home/stas/.cpan/CPAN
  -</PRE>
  -<P><A NAME="anchor591"></A>
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  % mkdir -p /home/stas/.cpan/CPAN</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Now copy the system wide configuration file to your local one.
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor592"></A>
  -<PRE>  % cp /usr/lib/perl5/5.00503/CPAN/Config.pm /home/stas/.cpan/CPAN/MyConfig.pm
  -</PRE>
  -<P><A NAME="anchor593"></A>
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  % cp /usr/lib/perl5/5.00503/CPAN/Config.pm /home/stas/.cpan/CPAN/MyConfig.pm</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   The only thing left is to change the base directory of <EM>.cpan</EM> in your local file to the one under your home directory. On my machine I
   replace <CODE>/usr/src/.cpan</CODE> (that's where my system's <CODE>.cpan</CODE> directory resides) with <CODE>/home/stas</CODE>. I use Perl of course!
   
  -<P><A NAME="anchor594"></A>
  -<PRE>  % perl -pi -e 's|/usr/src|/home/stas|' /home/stas/.cpan/CPAN/MyConfig.pm
  -</PRE>
  -<P><A NAME="anchor595"></A>
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  % perl -pi -e 's|/usr/src|/home/stas|' /home/stas/.cpan/CPAN/MyConfig.pm</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Now you have the local configuration file ready, you have to tell it what
   special parameters you need to pass when executing the <CODE>perl
   Makefile.PL</CODE> stage.
   
  -<P><A NAME="anchor596"></A>
  +<P>
   Open the file in your favorite editor and replace line:
  +
  +<P>
   
  -<P><A NAME="anchor597"></A>
  -<PRE>  'makepl_arg' =&gt; q[],
  -</PRE>
  -<P><A NAME="anchor598"></A>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  'makepl_arg' =&gt; q[],</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   with:
  +
  +<P>
   
  -<P><A NAME="anchor599"></A>
  -<PRE>  'makepl_arg' =&gt; q[PREFIX=/home/stas],
  -</PRE>
  -<P><A NAME="anchor600"></A>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  'makepl_arg' =&gt; q[PREFIX=/home/stas],</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Now you've finished the configuration. Assuming that you are logged in as
   the same user you have prepared the local installation for (<EM>stas</EM>
   in our example), start it like this:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor601"></A>
  -<PRE>  % perl -MCPAN -e shell
  -</PRE>
  -<P><A NAME="anchor602"></A>
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  % perl -MCPAN -e shell</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   From now on any module you try to install will be installed locally. If you
   need to install some system modules, just become the superuser and install
   them in the same way. When you are logged in as the superuser, the
   system-wide configuration file will be used instead of your local one.
   
  -<P><A NAME="anchor603"></A>
  +<P>
   If you have used more than just the <CODE>PREFIX</CODE> variable, modify
   <EM>MyConfig.pm</EM> to use them. For example if you have used these variables:
  +
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
   
  -<P><A NAME="anchor604"></A>
  -<PRE>    perl Makefile.PL PREFIX=/home/stas \
  +	<td>
  +	  <pre>    perl Makefile.PL PREFIX=/home/stas \
       INSTALLPRIVLIB=/home/stas/lib/perl5 \
       INSTALLSCRIPT=/home/stas/bin \
       INSTALLSITELIB=/home/stas/lib/perl5/site_perl \
       INSTALLBIN=/home/stas/bin \
       INSTALLMAN1DIR=/home/stas/lib/perl5/man  \
  -    INSTALLMAN3DIR=/home/stas/lib/perl5/man3
  -</PRE>
  -<P><A NAME="anchor605"></A>
  +    INSTALLMAN3DIR=/home/stas/lib/perl5/man3</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   then replace <CODE>PREFIX=/home/stas</CODE> in the line:
   
  -<P><A NAME="anchor606"></A>
  -<PRE>  'makepl_arg' =&gt; q[PREFIX=/home/stas],
  -</PRE>
  -<P><A NAME="anchor607"></A>
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  'makepl_arg' =&gt; q[PREFIX=/home/stas],</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   with all the variables from above, so that the line becomes:
  +
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
   
  -<P><A NAME="anchor608"></A>
  -<PRE>  'makepl_arg' =&gt; q[PREFIX=/home/stas \
  +	<td>
  +	  <pre>  'makepl_arg' =&gt; q[PREFIX=/home/stas \
       INSTALLPRIVLIB=/home/stas/lib/perl5 \
       INSTALLSCRIPT=/home/stas/bin \
       INSTALLSITELIB=/home/stas/lib/perl5/site_perl \
       INSTALLBIN=/home/stas/bin \
       INSTALLMAN1DIR=/home/stas/lib/perl5/man  \
  -    INSTALLMAN3DIR=/home/stas/lib/perl5/man3],
  -</PRE>
  -<P><A NAME="anchor609"></A>
  +    INSTALLMAN3DIR=/home/stas/lib/perl5/man3],</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   If you arrange all the above parameters in one line, you can remove the
   backslashes (<CODE>\</CODE>).
   
  -<P><A NAME="anchor610"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="Making_a_Local_Apache_Installati">Making a Local Apache Installation</A></H2></CENTER>
  -<P><A NAME="anchor611"></A>
  +<P>
   Just like with Perl modules, if you don't have permissions to install files
   into the system area you have to install them locally under your home
   directory. It's almost the same as a plain installation, but you have to
   run the server listening to a port number greater than 1024 since only root
   processes can listen to lower numbered ports.
   
  -<P><A NAME="anchor612"></A>
  +<P>
   Another important issue you have to resolve is how to add startup and
   shutdown scripts to the directories used by the rest of the system
   services. You will have to ask your system administrator to assist you with
   this issue.
   
  -<P><A NAME="anchor613"></A>
  +<P>
   To install Apache locally, all you have to do is to tell <CODE>.configure</CODE>
   in the Apache source directory what target directories to use. If you are
   following the convention that I use, which makes your home directory look
   like the <CODE>/</CODE> (base) directory, the invocation parameters would be:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor614"></A>
  -<PRE>  ./configure --prefix=/home/stas
  -</PRE>
  -<P><A NAME="anchor615"></A>
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  ./configure --prefix=/home/stas</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Apache will use the prefix for the rest of its target directories instead
   of the default <CODE>/usr/local/apache</CODE>. If you want to see what they are, before you proceed add the <EM>--show-layout</EM> option:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor616"></A>
  -<PRE>  ./configure --prefix=/home/stas --show-layout
  -</PRE>
  -<P><A NAME="anchor617"></A>
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  ./configure --prefix=/home/stas --show-layout</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   You might want to put all the Apache files under <CODE>/home/stas/apache</CODE>
   following Apache's convention:
   
  -<P><A NAME="anchor618"></A>
  -<PRE>  ./configure --prefix=/home/stas/apache
  -</PRE>
  -<P><A NAME="anchor619"></A>
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  ./configure --prefix=/home/stas/apache</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   If you want to modify some or all of the names of the automatically created
   directories:
  +
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
   
  -<P><A NAME="anchor620"></A>
  -<PRE>  ./configure --prefix=/home/stas/apache \
  +	<td>
  +	  <pre>  ./configure --prefix=/home/stas/apache \
       --sbindir=/home/stas/apache/sbin
       --sysconfdir=/home/stas/apache/etc
       --localstatedir=/home/stas/apache/var \
       --runtimedir=/home/stas/apache/var/run \
       --logfiledir=/home/stas/apache/var/logs \
  -    --proxycachedir=/home/stas/apache/var/proxy
  -</PRE>
  -<P><A NAME="anchor621"></A>
  +    --proxycachedir=/home/stas/apache/var/proxy</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   That's all!
   
  -<P><A NAME="anchor622"></A>
  +<P>
   Also remember that you can start the script only under a user and group you
   belong to. You must set the <CODE>User</CODE> and <CODE>Group</CODE> directives in <EM>httpd.conf</EM> to appropriate values.
   
  -<P><A NAME="anchor623"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="Manual_Local_mod_perl_Enabled_Ap">Manual Local mod_perl Enabled Apache Installation</A></H2></CENTER>
  -<P><A NAME="anchor624"></A>
  +<P>
   Now when we have learned how to install local Apache and Perl modules
   separately, let's see how to install mod_perl enabled Apache in our home
   directory. It's almost as simple as doing each one separately, but there is
   one wrinkle you need to know about which I'll mention at the end of this
   section.
   
  -<P><A NAME="anchor625"></A>
  +<P>
   Let's say you have unpacked the Apache and mod_perl sources under
   <EM>/home/stas/src</EM> and they look like this:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor626"></A>
  -<PRE>  % ls /home/stas/src
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  % ls /home/stas/src
     /home/stas/src/apache_x.x.x
  -  /home/stas/src/mod_perl-x.xx
  -</PRE>
  -<P><A NAME="anchor627"></A>
  +  /home/stas/src/mod_perl-x.xx</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   where <EM>x.xx</EM> are the version numbers as usual. You want the Perl modules from the
   mod_perl package to be installed under
   <EM>/home/stas/lib/perl5</EM> and the Apache files to go under
   <EM>/home/stas/apache</EM>. The following commands will do that for you:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor628"></A>
  -<PRE>  % perl Makefile.PL \
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  % perl Makefile.PL \
     PREFIX=/home/stas \
     APACHE_PREFIX=/home/stas/apache \
     APACHE_SRC=../apache_x.x.x/src \
  @@ -3099,24 +5457,39 @@
     EVERYTHING=1
     % make &amp;&amp; make test &amp;&amp; make install 
     % cd ../apache_x.x.x
  -  % make install
  -</PRE>
  -<P><A NAME="anchor629"></A>
  +  % make install</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   If you need some parameters to be passed to the <CODE>.configure</CODE> script, as we saw in the previous section use <CODE>APACI_ARGS</CODE>. For example:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor630"></A>
  -<PRE>  APACI_ARGS=--sbindir=/home/stas/apache/sbin, \
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  APACI_ARGS='--sbindir=/home/stas/apache/sbin, \
       --sysconfdir=/home/stas/apache/etc, \
       --localstatedir=/home/stas/apache/var, \
       --runtimedir=/home/stas/apache/var/run, \
       --logfiledir=/home/stas/apache/var/logs, \
  -    --proxycachedir=/home/stas/apache/var/proxy
  -</PRE>
  -<P><A NAME="anchor631"></A>
  +    --proxycachedir=/home/stas/apache/var/proxy'</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Note that the above multiline splitting will work only with <CODE>bash</CODE>,
   <CODE>tcsh</CODE> users will have to list all the parameters on a single line.
   
  -<P><A NAME="anchor632"></A>
  +<P>
   Basically the installation is complete. The only remaining problem is the <CODE>@INC</CODE> variable. This won't be correctly set if you rely on the
   <CODE>PERL5LIB</CODE> environment variable unless you set it explicitly in a startup file which
   is <CODE>require</CODE>'d before loading any other module that resides in your local repository. A
  @@ -3124,40 +5497,77 @@
   <CODE>lib</CODE> pragma as we saw before, but in a slightly different way - we use it in the
   startup file and it affects all the code that will be executed under
   mod_perl handlers. For example:
  +
  +<P>
   
  -<P><A NAME="anchor633"></A>
  -<PRE>  PerlRequire /home/stas/apache/perl/startup.pl
  -</PRE>
  -<P><A NAME="anchor634"></A>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  PerlRequire /home/stas/apache/perl/startup.pl</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   where <CODE>startup.pl</CODE> starts with:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor635"></A>
  -<PRE>  use lib qw(/home/stas/lib/perl5/5.00503/
  -             /home/stas/lib/perl5/site_perl/5.005);
  -</PRE>
  -<P><A NAME="anchor636"></A>
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  use lib qw(/home/stas/lib/perl5/5.00503/
  +             /home/stas/lib/perl5/site_perl/5.005);</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Note that you can still use the hard-coded <CODE>@INC</CODE> modifications in the scripts themselves, but be aware that scripts modify <CODE>@INC</CODE> in
   <CODE>BEGIN</CODE> blocks and mod_perl executes the <CODE>BEGIN</CODE> blocks only when it performs script compilation. As a result, <CODE>@INC</CODE> will be reset to its original value after the scripts are compiled and the
   hard-coded settings will be forgotten. See the section '<A HREF="././porting.html#_INC_and_mod_perl">@INC and mod_perl</A>' for more information.
   
  -<P><A NAME="anchor637"></A>
  +<P>
   The only place you can alter the ``original'' value is during the server
   configuration stage either in the startup file or by putting
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor638"></A>
  -<PRE>  PerlSetEnv Perl5LIB /home/stas/lib/perl5/5.00503/:/home/stas/lib/perl5/site_perl/5.005
  -</PRE>
  -<P><A NAME="anchor639"></A>
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  PerlSetEnv Perl5LIB /home/stas/lib/perl5/5.00503/:/home/stas/lib/perl5/site_perl/5.005</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   in <EM>httpd.conf</EM>.
   
  -<P><A NAME="anchor640"></A>
  +<P>
   The rest of the mod_perl configuration and use is just the same as if you
   were installing mod_perl as superuser.
   
  -<P><A NAME="anchor641"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H3><A NAME="Resource_Usage">Resource Usage</A></H3></CENTER>
  -<P><A NAME="anchor642"></A>
  +<P>
   Another important thing to keep in mind is the consumption of system
   resources. mod_perl is memory hungry. If you run a lot of mod_perl
   processes on a public, multiuser machine, most likely the system
  @@ -3167,11 +5577,11 @@
   
   <UL>
   <P><LI>
  -<P><A NAME="anchor643"></A>
  +<P>
   Reduce resources usage (see <A HREF="././performance.html#Limiting_the_Size_of_the_Process">Limiting the size of the processes</A>).
   
   <P><LI>
  -<P><A NAME="anchor644"></A>
  +<P>
   Ask your ISP's system administrator whether they can setup a dedicated
   machine for you, so that you will be able to install as much memory as you
   need. If you get a dedicated machine the chances are that you will want to
  @@ -3184,42 +5594,55 @@
   it.
   
   <P><LI>
  -<P><A NAME="anchor645"></A>
  +<P>
   Look for another ISP with lots of resources or one that supports mod_perl.
   You can find a list of these ISPs at <A
   HREF="http://perl.apache.org">http://perl.apache.org</A> .
   
   </UL>
  -<P><A NAME="anchor646"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="Local_mod_perl_Enabled_Apache_In">Local mod_perl Enabled Apache Installation with CPAN.pm</A></H2></CENTER>
  -<P><A NAME="anchor647"></A>
  +<P>
   Again, CPAN makes installation and upgrades simpler. You have seen how to
   install a mod_perl enabled server using <CODE>CPAN.pm</CODE>'s interactive shell. You have seen how to install Perl modules and Apache
   locally. Now all you have to do is to merge these techniques into a single
   ``local mod_perl Enabled Apache Installation with CPAN.pm'' technique.
   
  -<P><A NAME="anchor648"></A>
  +<P>
   Assuming that you have configured <CODE>CPAN.pm</CODE> to install Perl modules locally, the installation is very simple. Start the <CODE>CPAN.pm</CODE> shell, set the arguments to be passed to <CODE>perl Makefile.PL</CODE> (modify the example setting to suit your needs), and tell &lt;CPAN.pm&gt;
   to do the rest for you:
  +
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
   
  -<P><A NAME="anchor649"></A>
  -<PRE>  % perl -MCPAN -eshell
  +	<td>
  +	  <pre>  % perl -MCPAN -eshell
     cpan&gt; o conf makepl_arg 'DO_HTTPD=1 USE_APACI=1 EVERYTHING=1 \
           PREFIX=/home/stas APACHE_PREFIX=/home/stas/apache'
  -  cpan&gt; install mod_perl
  -</PRE>
  -<P><A NAME="anchor650"></A>
  +  cpan&gt; install mod_perl</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   When you use <CODE>CPAN.pm</CODE> for local installations, after the mod_perl installation is complete you
   must make sure that the value of
   <CODE>makepl_arg</CODE> is restored to its original value.
   
  -<P><A NAME="anchor651"></A>
  +<P>
   The simplest way to do this is to quit the interactive shell by typing
   <EM>quit</EM> and reenter it. But if you insist here is how to make it work without
   quitting the shell. You really want to skip this :)
   
  -<P><A NAME="anchor652"></A>
  +<P>
   If you want to continue working with <CODE>CPAN</CODE> *without* quitting the shell, you must:
   
   <OL>
  @@ -3228,155 +5651,328 @@
   <P><LI><STRONG><A NAME="item_build_and_install_mod_perl">build and install mod_perl</A></STRONG>
   <P><LI><STRONG><A NAME="item_restore_it_after_completing_mod_">restore it after completing mod_perl installation</A></STRONG>
   </OL>
  -<P><A NAME="anchor653"></A>
  +<P>
   this is quite a cumbersome task as of this writing, but I believe that
   <CODE>CPAN.pm</CODE> will eventually be improved to handle this more easily.
   
  -<P><A NAME="anchor654"></A>
  +<P>
   So if you are still with me, start the shell as usual:
   
  -<P><A NAME="anchor655"></A>
  -<PRE>  % perl -MCPAN -eshell
  -</PRE>
  -<P><A NAME="anchor656"></A>
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  % perl -MCPAN -eshell</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   First, read the value of the <CODE>makepl_arg</CODE>:
  +
  +<P>
   
  -<P><A NAME="anchor657"></A>
  -<PRE>  cpan&gt; o conf makepl_arg 
  -</PRE>
  -<P><A NAME="anchor658"></A>
  -<PRE>  PREFIX=/home/stas
  -</PRE>
  -<P><A NAME="anchor659"></A>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  cpan&gt; o conf makepl_arg </pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  PREFIX=/home/stas</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   It will be something like <CODE>PREFIX=/home/stas</CODE> if you configured
   <CODE>CPAN.pm</CODE> to install modules locally. Save this value:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor660"></A>
  -<PRE>  cpan&gt; o conf makepl_arg.save PREFIX=/home/stas
  -</PRE>
  -<P><A NAME="anchor661"></A>
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  cpan&gt; o conf makepl_arg.save PREFIX=/home/stas</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Second, set a new value, to be used by the mod_perl installation process.
   (You can add parameters to this line, or remove them, according to your
   needs.)
   
  -<P><A NAME="anchor662"></A>
  -<PRE>  cpan&gt; o conf makepl_arg 'DO_HTTPD=1 USE_APACI=1 EVERYTHING=1 \
  -        PREFIX=/home/stas APACHE_PREFIX=/home/stas/apache'
  -</PRE>
  -<P><A NAME="anchor663"></A>
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  cpan&gt; o conf makepl_arg 'DO_HTTPD=1 USE_APACI=1 EVERYTHING=1 \
  +        PREFIX=/home/stas APACHE_PREFIX=/home/stas/apache'</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Third, let &lt;CPAN.pm&gt; build and install mod_perl for you:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor664"></A>
  -<PRE>  cpan&gt; install mod_perl
  -</PRE>
  -<P><A NAME="anchor665"></A>
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  cpan&gt; install mod_perl</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Fourth, reset the original value to <CODE>makepl_arg</CODE>. We do this by printing the value of the saved variable and assigning it
   to
   <CODE>makepl_arg</CODE>.
   
  -<P><A NAME="anchor666"></A>
  -<PRE>  cpan&gt; o conf makepl_arg.save
  -</PRE>
  -<P><A NAME="anchor667"></A>
  -<PRE>  PREFIX=/home/stas
  -</PRE>
  -<P><A NAME="anchor668"></A>
  -<PRE>  cpan&gt; o conf makepl_arg PREFIX=/home/stas
  -</PRE>
  -<P><A NAME="anchor669"></A>
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  cpan&gt; o conf makepl_arg.save</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  PREFIX=/home/stas</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  cpan&gt; o conf makepl_arg PREFIX=/home/stas</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Not so neat, but a working solution. You could have written the value on a
   piece of paper instead of saving it to makepl_arg.save, but you are more
   likely to make a mistake that way.
   
  -<P><A NAME="anchor670"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H1><A NAME="Automating_installation">Automating installation</A></H1></CENTER>
  -<P><A NAME="anchor671"></A>
  +<P>
   James G Smith wrote an Apache Builder, that can install a combination of
   Apache, mod_perl, and mod_ssl -- it also has limited support for including
   mod_php in the mix.
   
  -<P><A NAME="anchor672"></A>
  +<P>
   <A
   HREF="http://hex.tamu.edu/build-apache">http://hex.tamu.edu/build-apache</A>
   (the actual Perl script)
   
  -<P><A NAME="anchor673"></A>
  +<P>
   <A
   HREF="http://hex.tamu.edu/generic.conf">http://hex.tamu.edu/generic.conf</A>
   (a sample configuration file)
   
  -<P><A NAME="anchor674"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H1><A NAME="How_can_I_tell_whether_mod_perl_">How can I tell whether mod_perl is running?</A></H1></CENTER>
  -<P><A NAME="anchor675"></A>
  +<P>
   There are a few ways. In older versions of apache ( &lt; 1.3.6 ?) you could check that by running <CODE>httpd -v</CODE>, but it no longer works. Now you should use <CODE>httpd -l</CODE>. Please note that it is not enough to have it installed, you have to
   configure it for mod_perl and restart the server too.
   
  -<P><A NAME="anchor676"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="Checking_the_error_log">Checking the error_log</A></H2></CENTER>
  -<P><A NAME="anchor677"></A>
  +<P>
   When starting the server, just check the <CODE>error_log</CODE> file for the following message:
   
  -<P><A NAME="anchor678"></A>
  -<PRE>  [Thu Dec  3 17:27:52 1998] [notice] Apache/1.3.1 (Unix) mod_perl/1.15 configured 
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  [Thu Dec  3 17:27:52 1998] [notice] Apache/1.3.1 (Unix) mod_perl/1.15 configured 
                                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  -    -- resuming normal operations
  -</PRE>
  -<P><A NAME="anchor679"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +    -- resuming normal operations</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="Testing_by_viewing_perl_status">Testing by viewing /perl-status</A></H2></CENTER>
  -<P><A NAME="anchor680"></A>
  +<P>
   Assuming that you have configured the &lt;Location
   /perl-status&gt; section in the server configuration file fetch: <A
   HREF="http://www.example.com/perl-status">http://www.example.com/perl-status</A>
   using your favorite Mozilla browser :-)
   
  -<P><A NAME="anchor681"></A>
  +<P>
   You should see something like this:
  +
  +<P>
   
  -<P><A NAME="anchor682"></A>
  -<PRE>  Embedded Perl version 5.00503 for Apache/1.3.9 (Unix) mod_perl/1.21 
  -  process 50880, running since Mon Dec 6 14:31:45 1999
  -</PRE>
  -<P><A NAME="anchor683"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  Embedded Perl version 5.00503 for Apache/1.3.9 (Unix) mod_perl/1.21 
  +  process 50880, running since Mon Dec 6 14:31:45 1999</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="Testing_via_telnet">Testing via telnet</A></H2></CENTER>
  -<P><A NAME="anchor684"></A>
  +<P>
   Knowing the port you have configured apache to listen on, you can use
   <CODE>telnet</CODE> to talk directly to it.
   
  -<P><A NAME="anchor685"></A>
  +<P>
   Assuming that your mod_perl enabled server listens to port 8080, telnet to
   your server at port 8080, and type <CODE>HEAD / HTTP/1.0</CODE> then press the &lt;ENTER&gt; key TWICE:
  +
  +<P>
   
  -<P><A NAME="anchor686"></A>
  -<PRE>  % telnet localhost 8080&lt;ENTER&gt;
  -  HEAD / HTTP/1.0&lt;ENTER&gt;&lt;ENTER&gt;
  -</PRE>
  -<P><A NAME="anchor687"></A>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  % telnet localhost 8080&lt;ENTER&gt;
  +  HEAD / HTTP/1.0&lt;ENTER&gt;&lt;ENTER&gt;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   You should see a response like this:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor688"></A>
  -<PRE>  HTTP/1.1 200 OK
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  HTTP/1.1 200 OK
     Date: Mon, 06 Dec 1999 12:27:52 GMT
     Server: Apache/1.3.9 (Unix) mod_perl/1.21
     Connection: close
     Content-Type: text/html
     
  -  Connection closed.
  -</PRE>
  -<P><A NAME="anchor689"></A>
  +  Connection closed.</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   The line
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor690"></A>
  -<PRE>  Server: Apache/1.3.9 (Unix) mod_perl/1.21
  -</PRE>
  -<P><A NAME="anchor691"></A>
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  Server: Apache/1.3.9 (Unix) mod_perl/1.21</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   confirms that you have mod_perl installed and its version is <CODE>1.21</CODE>.
   
  -<P><A NAME="anchor692"></A>
  +<P>
   However, just because you have got mod_perl linked in there, that does not
   mean that you have configured your server to handle Perl scripts with
   mod_perl. You will find configuration assistance at
  @@ -3384,162 +5980,265 @@
   
   
   
  -<P><A NAME="anchor693"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="Testing_via_a_CGI_script">Testing via a CGI script</A></H2></CENTER>
  -<P><A NAME="anchor694"></A>
  +<P>
   Another method is to invoke a CGI script which dumps the server's
   environment.
   
  -<P><A NAME="anchor695"></A>
  +<P>
   I assume that you have configured the server so that scripts running under
   location <EM>/perl/</EM> are handled by the <CODE>Apache::Registry</CODE>
   handler and that you have the <CODE>PerlSendHeader</CODE> directive set to
   <CODE>On</CODE>.
   
  -<P><A NAME="anchor696"></A>
  +<P>
   Copy and paste the script below (no need for a shebang line!). Let's say
   you name it <EM>test.pl</EM>, save it at the root of the CGI scripts and CGI root is mapped directly to
   the <EM>/perl</EM> location of your server.
  +
  +<P>
   
  -<P><A NAME="anchor697"></A>
  -<PRE>  print &quot;Content-type: text/plain\r\n\r\n&quot;;
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  print &quot;Content-type: text/plain\r\n\r\n&quot;;
     print &quot;Server's environment\n&quot;;
     foreach ( keys %ENV ) {
         print &quot;$_\t$ENV{$_}\n&quot;;
  -  }
  -</PRE>
  -<P><A NAME="anchor698"></A>
  +  }</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Make it readable and executable by server (you may need to tune these
   permissions on a public host):
  +
  +<P>
   
  -<P><A NAME="anchor699"></A>
  -<PRE>  % chmod a+rx test.pl
  -</PRE>
  -<P><A NAME="anchor700"></A>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  % chmod a+rx test.pl</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Now fetch the URL <CODE>http://www.nowhere.com:8080/perl/test.pl</CODE> (replace 8080 with the port your mod_perl enabled server is listening to).
   You should see something like this (the output has been edited):
  +
  +<P>
   
  -<P><A NAME="anchor701"></A>
  -<PRE>  SERVER_SOFTWARE Apache/1.3.10-dev (Unix) mod_perl/1.21_01-dev
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  SERVER_SOFTWARE Apache/1.3.10-dev (Unix) mod_perl/1.21_01-dev
     GATEWAY_INTERFACE       CGI-Perl/1.1
     DOCUMENT_ROOT   /home/httpd/docs
     REMOTE_ADDR     127.0.0.1
     [more environment variables snipped]
     MOD_PERL        mod_perl/1.21_01-dev
  -  [more environment variables snipped]
  -</PRE>
  -<P><A NAME="anchor702"></A>
  +  [more environment variables snipped]</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   If you see the that the value of <CODE>GATEWAY_INTERFACE</CODE> is
   <CODE>CGI-Perl/1.1</CODE> everything is OK. 
   
  -<P><A NAME="anchor703"></A>
  +<P>
   If there is an error you might have to add a shebang line
   <CODE>#!/usr/bin/perl</CODE> as a first line of the CGI script and then try it again. If you see:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor704"></A>
  -<PRE>  GATEWAY_INTERFACE       CGI/1.1
  -</PRE>
  -<P><A NAME="anchor705"></A>
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  GATEWAY_INTERFACE       CGI/1.1</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   it means that you have configured this location to run under mod_cgi and
   not mod_perl.
   
  -<P><A NAME="anchor706"></A>
  +<P>
   Also note that there is a <CODE>MOD_PERL</CODE> environment variable if you run under a mod_perl handler, it's set to the
   release number you use.
   
  -<P><A NAME="anchor707"></A>
  +<P>
   Based on this difference you can write code like this:
   
  -<P><A NAME="anchor708"></A>
  -<PRE>  BEGIN {
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  BEGIN {
         # perl5.004 or better is a must under mod_perl
       require 5.004 if $ENV{MOD_PERL};
  -  }
  -</PRE>
  -<P><A NAME="anchor709"></A>
  +  }</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   You might wonder why in the world you would need to know what handler you
   are running under. Well, for example you will want to use
   <CODE>Apache::exit()</CODE> and not <CODE>CORE::exit()</CODE> in your modules, but if you think that your script might be used in both
   environments (mod_cgi and mod_perl) you will have to override the <CODE>exit()</CODE> subroutine and to make decision what method to use at the runtime.  
   
  -<P><A NAME="anchor710"></A>
  +<P>
   Note that if you run scripts under the <CODE>Apache::Registry</CODE> handler, it takes care of overriding the <CODE>exit()</CODE> call for you, so it's not an issue. For reasons and implementations see: <A HREF="././porting.html#Terminating_requests_and_process">Terminating requests and processes, exit() function</A> and also <A HREF="././porting.html#">Writing Mod Perl scripts and Porting plain CGIs to it</A>.
   
  -<P><A NAME="anchor711"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="Testing_via_lwp_request">Testing via lwp-request</A></H2></CENTER>
  -<P><A NAME="anchor712"></A>
  +<P>
   Yet another one. Why do I show all these approaches? While here they serve
   a very simple purpose, they can be helpful in other situations.
   
  -<P><A NAME="anchor713"></A>
  +<P>
   Assuming you have the <CODE>libwww-perl</CODE> (<CODE>LWP</CODE>) package installed (you will need it installed in order to pass mod_perl's <CODE>make test</CODE> anyway):
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor714"></A>
  -<PRE>  % lwp-request -e -d <A HREF="http://www.nowhere.com">http://www.nowhere.com</A>
  -</PRE>
  -<P><A NAME="anchor715"></A>
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  % lwp-request -e -d <A HREF="http://www.nowhere.com">http://www.nowhere.com</A></pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Will show you all the headers. The <CODE>-d</CODE> option disables printing the response content.
   
  -<P><A NAME="anchor716"></A>
  -<PRE>  % lwp-request -e -d <A HREF="http://www.nowhere.com">http://www.nowhere.com</A> | egrep '^Server:'
  -</PRE>
  -<P><A NAME="anchor717"></A>
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  % lwp-request -e -d <A HREF="http://www.nowhere.com">http://www.nowhere.com</A> | egrep '^Server:'</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   To see the server version only.
   
  -<P><A NAME="anchor718"></A>
  +<P>
   Use <CODE>http://www.nowhere.com:port_number</CODE> if your server is listening to a port other than port 80.
   
  -<P><A NAME="anchor719"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H1><A NAME="General_Notes">General Notes</A></H1></CENTER>
  -<P><A NAME="anchor720"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="Is_it_possible_to_run_mod_perl_e">Is it possible to run mod_perl enabled Apache as suExec?</A></H2></CENTER>
  -<P><A NAME="anchor721"></A>
  +<P>
   The answer is <STRONG>No</STRONG>. The reason is that you can't <EM>"suid</EM> a part of a process. mod_perl lives inside the Apache process. You have to
   fork somewhere to be someone else, and at that point, you aren't mod_perl
   anymore.
   
  -<P><A NAME="anchor722"></A>
  +<P>
   You have to use mod_cgi if you need this functionality.
   
  -<P><A NAME="anchor723"></A>
  +<P>
   Another solution is to use a crontab to call some script that will check
   whether there is something to do and will execute it. The mod_perl script
   will be able to create and update this todo list.
   
  -<P><A NAME="anchor724"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="Should_I_Rebuild_mod_perl_if_I_h">Should I Rebuild mod_perl if I have Upgraded Perl?</A></H2></CENTER>
  -<P><A NAME="anchor725"></A>
  +<P>
   Yes, you should. You have to rebuild the mod_perl enabled server since it
   has a hard-coded <CODE>@INC</CODE> variable. This points to the old Perl and it is probably linked to an old <CODE>libperl</CODE> library. If for some reason you need to keep the old Perl version around
   you can modify
   <CODE>@INC</CODE> in the startup script, but it is better to build afresh to save you getting
   into a mess.
   
  -<P><A NAME="anchor726"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="Perl_installation_requirements">Perl installation requirements</A></H2></CENTER>
  -<P><A NAME="anchor727"></A>
  +<P>
   Make sure you have Perl installed! The latest stable version if possible.
   Minimum perl 5.004! If you don't have it, install it. Follow the
   instructions in the distribution's <CODE>INSTALL</CODE> file.
   
  -<P><A NAME="anchor728"></A>
  +<P>
   During the configuration stage (while running <CODE>./Configure</CODE>), to be able to dynamically load Perl module extensions, make sure you
   answer
   <CODE>YES</CODE> to the question:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor729"></A>
  -<PRE>  Do you wish to use dynamic loading? [y]
  -</PRE>
  -<P><A NAME="anchor730"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  Do you wish to use dynamic loading? [y]</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="mod_auth_dbm_nuances">mod_auth_dbm nuances</A></H2></CENTER>
  -<P><A NAME="anchor731"></A>
  +<P>
   If you are a <CODE>mod_auth_dbm</CODE> or <CODE>mod_auth_db</CODE> user you may need to edit Perl's <CODE>Config</CODE> module. When Perl is configured it attempts to find libraries for ndbm,
   gdbm, db, etc., for the DB*_File modules. By default, these libraries are
   linked with Perl and remembered by the
  @@ -3549,46 +6248,107 @@
   stored in <STRONG>Config.pm</STRONG> may confuse
   <CODE>mod_auth_db*</CODE>. If <CODE>mod_auth_db*</CODE> does not work with mod_perl, take a look at the order with the following
   command:
  +
  +<P>
   
  -<P><A NAME="anchor732"></A>
  -<PRE> % perl -V:libs
  -</PRE>
  -<P><A NAME="anchor733"></A>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre> % perl -V:libs</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Here's an example:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor734"></A>
  -<PRE> libs='-lnet -lnsl_s -lgdbm -lndbm -ldb -ldld -lm -lc -lndir -lcrypt';
  -</PRE>
  -<P><A NAME="anchor735"></A>
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre> libs='-lnet -lnsl_s -lgdbm -lndbm -ldb -ldld -lm -lc -lndir -lcrypt';</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   If <CODE>-lgdbm</CODE> or <CODE>-ldb</CODE> is before <CODE>-lndbm</CODE> (as it is in the example) edit <EM>Config.pm</EM> and move <CODE>-lgdbm</CODE> and <CODE>-ldb</CODE> to the end of the list. Here's how to find <EM>Config.pm</EM>:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor736"></A>
  -<PRE> % perl -MConfig -e 'print &quot;$Config{archlibexp}/Config.pm\n&quot;'
  -</PRE>
  -<P><A NAME="anchor737"></A>
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre> % perl -MConfig -e 'print &quot;$Config{archlibexp}/Config.pm\n&quot;'</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Under Solaris, another solution for building Apache/mod_perl+mod_auth_dbm
   is to remove the DBM and NDBM ``emulation'' from <EM>libgdbm.a</EM>. It seems that Solaris already provides its own DBM and NDBM, and in our
   installation we found there's no reason to build GDBM with them.
   
  -<P><A NAME="anchor738"></A>
  +<P>
   In our Makefile for GDBM, we changed
   
  -<P><A NAME="anchor739"></A>
  -<PRE>  OBJS = $(DBM_OF) $(NDBM_OF) $(GDBM_OF)
  -</PRE>
  -<P><A NAME="anchor740"></A>
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  OBJS = $(DBM_OF) $(NDBM_OF) $(GDBM_OF)</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   to
  +
  +<P>
   
  -<P><A NAME="anchor741"></A>
  -<PRE>  OBJS = $(GDBM_OF)
  -</PRE>
  -<P><A NAME="anchor742"></A>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  OBJS = $(GDBM_OF)</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Rebuild libgdbm before Apache/mod_perl.  
   
  -<P><A NAME="anchor743"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="Stripping_Apache_to_make_it_almo">Stripping Apache to make it almost a Perl-server</A></H2></CENTER>
  -<P><A NAME="anchor744"></A>
  +<P>
   Since most of the functionality that various apache mod_* modules provide
   is implemented in the <A HREF="#item_Apache_">Apache::{*}</A> Perl modules, it was reported that one can build an Apache server with
   mod_perl only. If you can reduce the requirements to whatever mod_perl can
  @@ -3596,127 +6356,156 @@
   will have a Perl-server, with C code to handle the tricky HTTP bits. The
   only module you will need to leave in is <CODE>mod_actions</CODE>.
   
  -<P><A NAME="anchor745"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="Saving_the_config_status_Files_w">Saving the config.status Files with mod_perl, php, ssl and Other Components</A></H2></CENTER>
  -<P><A NAME="anchor746"></A>
  +<P>
   Typically, when building the bloated Apache that sits behind Squid or
   whatever, you need mod_perl, php, mod_ssl and the rest. As you install each
   they typically overwrite each other's <CODE>config.status</CODE>
   files. Save them after each step, so you will be able to reuse them later.
   
  -<P><A NAME="anchor747"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="What_Compiler_Should_Be_Used_to_">What Compiler Should Be Used to Build mod_perl?</A></H2></CENTER>
  -<P><A NAME="anchor748"></A>
  +<P>
   All Perl modules that use C extensions must be compiled using the same
   compiler that your copy of Perl was built with.
   
  -<P><A NAME="anchor749"></A>
  +<P>
   When you run <CODE>perl Makefile.PL</CODE>, a <EM>Makefile</EM> is created. This
   <EM>Makefile</EM> includes the same compilation options that were used to build Perl itself.
   They are stored in the <EM>Config.pm</EM> module and can be displayed with the <CODE>Perl -V</CODE> command. All these options are re-applied when compiling Perl modules.
   
  -<P><A NAME="anchor750"></A>
  +<P>
   If you use a different compiler to build Perl extensions, chances are that
   the options that a different compiler uses won't be the same, or they might
   be interpreted in a completely different way. So the code either won't
   compile or it will dump core when run or maybe it will behave in most
   unexpected ways.
   
  -<P><A NAME="anchor751"></A>
  +<P>
   Since mod_perl uses Perl, Apache and third party modules, and they all work
   together, it's essential to use the same compiler while building each of
   the components.
   
  -<P><A NAME="anchor752"></A>
  +<P>
   You shouldn't worry about this when compliling Perl modules since Perl will
   choose what's right automatically. Unless you override things. If you do
   that, you are on your own...
   
  -<P><A NAME="anchor753"></A>
  +<P>
   If you compile a non-Perl component separately, you should make sure to use
   the same compiler and the same options used to build Perl. Hint: Take a
   look at the <EM>Config.pm</EM> module or the output of <CODE>perl
   -V</CODE>.
   
  -<P><A NAME="anchor754"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H1><A NAME="OS_Related_Notes">OS Related Notes</A></H1></CENTER>
   <UL>
   <P><LI>
  -<P><A NAME="anchor755"></A>
  +<P>
   Gary Shea &lt;<A HREF="mailto:shea@xmission.com">shea@xmission.com</A>&gt;
   discovered a nasty BSDI bug (seen in versions 2.1 and 3.0) related to
   dynamic loading and found two workarounds:
   
  -<P><A NAME="anchor756"></A>
  +<P>
   It turns out that they use <CODE>argv[0]</CODE> to determine where to find the link tables at run-time, so if a program
   either changes <CODE>argv[0]</CODE>, or does a <CODE>chdir()</CODE> (like Apache!) it can easily confuse the
   dynamic loader. The short-term solutions to the problem are simple. Either
   of the following will work:
   
  -<P><A NAME="anchor757"></A>
  +<P>
   1) Call httpd with a full path, e.g. /opt/www/bin/httpd
   
  -<P><A NAME="anchor758"></A>
  +<P>
   2) Put the httpd you wish to run in a directory in your PATH <EM>before</EM>
   any other directory containing a version of httpd, then call it as 'httpd'.
   Don't use a relative path!
   
   </UL>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -	     The <a href="http://www.modperl.com/">
  -	     <B>Writing Apache Modules with Perl and C</B></a>
  -	     book can be purchased online from <a
  -	     href="http://www.ora.com/catalog/wrapmod/">O'Reilly </a>
  -	     and <a
  -	     href="http://www.amazon.com/exec/obidos/ASIN/156592567X/writinapachemodu">
  -	     Amazon.com</a>.
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   
  -	     <HR>
   
  -	     <B>Your corrections of either technical or grammatical
  +    <p>
  +    <div class="navbar">
  +      <a href="perl.html">Prev</a>                                 |
  +      <A HREF="index.html"         >Contents</A> |
  +      <A HREF="index.html#search"  >Search</A>   |
  +      <A HREF="index.html#download">Download</A> |
  +      <a href="config.html">Next</a>
  +    </div>
  +    <p>
  +
  +    <table width="60%" align="center">
  +
  +      <tr>
  +	<td>
  +	  <div class="notice">
  +	  <B>Your corrections of the technical and grammatical
   	     errors are very welcome. You are encouraged to help me
  -	     to improve this guide.  If you have something to
  -	     contribute please <A
  -	     HREF="help.html#Contacting_me"> send it
  +	     improve this guide.  If you have something to contribute
  +	     please <A HREF="help.html#Contacting_me"> send it
   	     directly to me</A>.</B>
  +	  </div>
  +	</td>
  +      </tr>
  +
  +      <tr>
  +	<td>
  +	  <div class="ad">
  +	    The <a href="http://www.modperl.com/">
  +	      <B>Writing Apache Modules with Perl and C</B></a>
  +	    book can be purchased online from <a
  +	      href="http://www.ora.com/catalog/wrapmod/">O'Reilly </a>
  +	    and <a
  +	    href="http://www.amazon.com/exec/obidos/ASIN/156592567X/writinapachemodu">
  +	      Amazon.com</a>.
  +	  </div>
  +	</td>
  +      </tr>
  +
  +</table>
  +
  +<center>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
  +<table cellspacing=2 cellpadding=2>
  +
  +<tr align=center valign=top>
  +<td align=center valign=center>
  +
  +<b><font size=-1>Written by <a
  +href="help.html#Contacting_me">Stas Bekman</a>.<br> Last Modified at 05/31/2000
  +</font></b>
  +<br>
  +
  +</td>
  +
  +<td>
  +
  +<a href="http://perl.apache.org"><img src="images/mod_perl2.jpg"  border=0 alt="mod_perl icon" border=0 height=59 width=150></a>
  +<br>
  +
  +</td>
  +
  +<td>
  +
  +<font size=-2>Use of the Camel for Perl is <br>
  +a trademark of <a href="http://www.ora.com">O'Reilly &amp; Associates</a>,<br>
  +and is used by permission. </font> 
  +<br>
   
  -	     <HR>
  +</td>
   
  -	     [    <A HREF="perl.html">Prev</A> |      <A HREF="index.html">Main Page</A> | <A HREF="config.html">Next</A>      ]
  +</tr>
  +</table>
  +</center>
   
  -<CENTER><TABLE CELLSPACING=2 CELLPADDING=2 WIDTH="100%" >
  -<TR ALIGN=CENTER VALIGN=TOP>
  -  <TD ALIGN=CENTER VALIGN=CENTER COLSPAN="3">
  -	     <HR>
  -  </TD>
  -</TR>
  -<TR ALIGN=CENTER VALIGN=TOP>
  -  <TD ALIGN=CENTER VALIGN=CENTER>
  -    <B>
  -      <FONT SIZE=-1>
  -	     Written by <A HREF="help.html#Contacting_me">Stas Bekman</A>.
  -	     <BR>Last Modified at 05/09/2000
  -      </FONT>
  -    </B>
  -  </TD>
  -
  -  <TD>
  -	     <A HREF="http://perl.apache.org"><IMG SRC="images/mod_perl2.jpg" ALT="Mod Perl Icon" BORDER=0 HEIGHT=59 WIDTH=150></A>
  -  </TD>
  -
  -  <TD>
  -    <FONT SIZE=-2>
  -	     Use of the Camel for Perl is <BR>
  -	     a trademark of <A HREF="http://www.ora.com">O'Reilly &amp; Associates</A>,<BR>
  -             and is used by permission. 
  -    </FONT> 
  -  </TD>
  -</TR>
  -</TABLE></CENTER>
  -
  -</BODY>
  -</HTML>
  -	    
  \ No newline at end of file
  +</body>
  +</html>
  
  
  
  1.22      +363 -244  modperl-site/guide/intro.html
  
  Index: intro.html
  ===================================================================
  RCS file: /home/cvs/modperl-site/guide/intro.html,v
  retrieving revision 1.21
  retrieving revision 1.22
  diff -u -r1.21 -r1.22
  --- intro.html	2000/05/12 22:42:52	1.21
  +++ intro.html	2000/06/07 22:45:32	1.22
  @@ -1,29 +1,37 @@
   <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
  -<HTML>
  -<HEAD>
  -   <TITLE>mod_perl guide: Introduction. Incentives. Credits.</TITLE>
  -   <META NAME="GENERATOR" CONTENT="Pod2HTML [Perl/Linux]">
  -   <META NAME="Author" CONTENT="Stas Bekman">
  -   <META NAME="Description" CONTENT="All Apache/Perl related information: Hints, Guidelines, Scenarios and Troubleshottings">
  -   <META NAME="keywords" CONTENT="mod_perl modperl perl apache cgi webserver speed  fast guide mod_perl apache guide help info faq mod_perl installation cgi troubleshooting help no sex speedup free open source OSS mod_perl apache guide">
  -</HEAD>
  -     <LINK REL=STYLESHEET TYPE="text/css"
  -        HREF="style.css" TITLE="refstyle">
  -     <style type="text/css">
  -     <!-- 
  -        @import url(style.css);
  -     -->
  -     
  -     </style>
  -<BODY BGCOLOR="white">
  +<html>
  +  <head>
  +   <title>mod_perl guide: Introduction. Incentives. Credits.</title>
  +   <meta name="Author" content="Stas Bekman">
  +   <meta name="Description" content="All Apache/Perl related information: Hints, Guidelines, Scenarios and Troubleshottings">
  +   <meta name="keywords" content="mod_perl modperl perl cgi apache webserver speed fast guide mod_perl apache guide help info faq mod_perl installation cgi troubleshooting help no sex speedup free open source OSS mod_perl apache guide">
  +   <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
  +   <meta name="Classification" content="information">
  +   <link href="style.css" rel=stylesheet type="text/css" title="refstyle">
  +  </head>
  +  <body>
  +
  +    <h1 align=center>
  +      <a href="http://perl.apache.org"><img src="images/mod_perl.gif" alt="Mod Perl Icon" border=0 height=30 width=90 align=left></a>
  +      <a href="http://perl.apache.org"><img src="images/mod_perl.gif" alt="Mod Perl Icon" border=0 height=30 width=90 align=right></a>
  +      Introduction. Incentives. Credits.
  +    </h1>
  +    <hr>
  +    <p>
  +    <div class="navbar">
  +      <a href="">Prev</a>                                 |
  +      <a href="index.html"         >Contents</a> |
  +      <a href="index.html#search"  >Search</a>   |
  +      <a href="index.html#download">Download</a> |
  +      <a href="start.html">Next</a>
  +    </div>
  +    <p>
  +
  +    <div class="toc">
  +      
   <A NAME="toc"></A>
  -<H1 ALIGN=CENTER>
  -<A HREF="http://perl.apache.org"><IMG SRC="images/mod_perl.gif" ALT="Mod Perl Icon" BORDER=0 HEIGHT=30 WIDTH=90 ALIGN=LEFT></A>
  -<A HREF="http://perl.apache.org"><IMG SRC="images/mod_perl.gif" ALT="Mod Perl Icon" BORDER=0 HEIGHT=30 WIDTH=90 ALIGN=RIGHT></A>
  -Introduction. Incentives. Credits.</H1>
  -<HR WIDTH="100%">
  -	    [    <A HREF="index.html">Main Page</A> | <A HREF="start.html">Next</A>      ]<HR><!-- INDEX BEGIN -->
  -<P><B><FONT SIZE=-1>Table of Contents:</FONT></B></P>
  +<P><B>Table of Contents:</B></P>
  +
   <UL>
   
   	<LI><A HREF="#What_is_mod_perl">What is mod_perl</A>
  @@ -40,33 +48,49 @@
   	<LI><A HREF="#High_Profile_Sites_Running_mod_p">High-Profile Sites Running mod_perl</A>
   	<LI><A HREF="#References_and_Acknowledgments">References and Acknowledgments</A>
   </UL>
  -<!-- INDEX END -->
   
  +    </div>
  +
  +    [ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
   <HR>
  +    <table width="60%" align="center">
  +
  +      <tr>
  +	<td>
  +	  <div class="ad">
  +	    The <a href="http://www.modperl.com/">
  +	      <B>Writing Apache Modules with Perl and C</B></a>
  +	    book can be purchased online from <a
  +	      href="http://www.ora.com/catalog/wrapmod/">O'Reilly </a>
  +	    and <a
  +	    href="http://www.amazon.com/exec/obidos/ASIN/156592567X/writinapachemodu">
  +	      Amazon.com</a>.
  +	  </div>
  +	</td>
  +      </tr>
  +
  +      <tr>
  +	<td>
  +	  <div class="notice">
  +	  <B>Your corrections of the technical and grammatical
  +	     errors are very welcome. You are encouraged to help me
  +	     improve this guide.  If you have something to contribute
  +	     please <A HREF="help.html#Contacting_me"> send it
  +	     directly to me</A>.</B>
  +	  </div>
  +	</td>
  +      </tr>
   
  -	     The <a href="http://www.modperl.com/">
  -	     <B>Writing Apache Modules with Perl and C</B></a>
  -	     book can be purchased online from <a
  -	     href="http://www.ora.com/catalog/wrapmod/">O'Reilly </a>
  -	     and <a
  -	     href="http://www.amazon.com/exec/obidos/ASIN/156592567X/writinapachemodu">
  -	     Amazon.com</a>.
  -
  -	     <HR>
  -
  -	       <B>Your corrections of either technical or grammatical
  -	       errors are very welcome. You are encouraged to help me
  -	       to improve this guide.  If you have something to
  -	       contribute please <A
  -	       HREF="help.html#Contacting_me"> send it
  -	       directly to me</A>.
  -	       </B>
  -	       <HR>
  +</table>
   
  -	      <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<P><A NAME="anchor0"></A>
  +    
  +
  +	    [ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
  +
  +<P>
   <CENTER><H1><A NAME="What_is_mod_perl">What is mod_perl</A></H1></CENTER>
  -<P><A NAME="anchor1"></A>
  +<P>
   The Apache/Perl integration project brings together the full power of the
   Perl programming language and the Apache HTTP server. With mod_perl it is
   possible to write Apache modules entirely in Perl, letting you easily do
  @@ -79,7 +103,7 @@
   from the cache. Thus the server spends its time only running already loaded
   and compiled code, which is very fast.
   
  -<P><A NAME="anchor2"></A>
  +<P>
   The primary advantages of mod_perl are power and speed. You have full
   access to the inner workings of the web server and can intervene at any
   stage of request-processing. This allows for customized processing of (to
  @@ -93,11 +117,11 @@
   purpose: <CODE>Apache::Registry</CODE>, which can transparently run existing perl CGI scripts and <CODE>Apache::PerlRun</CODE>, which does a similar job but allows you to run ``dirtier'' (to some
   extent) scripts.
   
  -<P><A NAME="anchor3"></A>
  +<P>
   You can configure your httpd server and handlers in Perl (using
   <CODE>PerlSetVar</CODE>, and &lt;Perl&gt; sections). You can even define your own configuration directives.
   
  -<P><A NAME="anchor4"></A>
  +<P>
   Many people ask ``How much of a performance improvement does mod_perl
   give?'' Well, it all depends on what you are doing with mod_perl and
   possibly who you ask. Developers report speed boosts from 200% to 2000%.
  @@ -107,144 +131,210 @@
   HREF="http://perl.apache.org/stories/">http://perl.apache.org/stories/</A>
   for the facts.)
   
  -<P><A NAME="anchor5"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="mod_cgi">mod_cgi</A></H2></CENTER>
  -<P><A NAME="anchor6"></A>
  +<P>
   When you run your CGI scripts by using a configuration like this:
  +
  +<P>
   
  -<P><A NAME="anchor7"></A>
  -<PRE>  ScriptAlias /cgi-bin/ /home/httpd/cgi-bin/
  -</PRE>
  -<P><A NAME="anchor8"></A>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  ScriptAlias /cgi-bin/ /home/httpd/cgi-bin/</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   you run it under a mod_cgi handler, you never define it explicitly. Apache
   does all the configuration work behind the scenes, when you use a
   ScriptAlias.
   
  -<P><A NAME="anchor9"></A>
  +<P>
   By the way, don't confuse <CODE>ScriptAlias</CODE> with the <CODE>ExecCGI</CODE>
   configuration option, which we enable so that the script will be executed
   rather than returned as a plain text file. For example for mod_perl and <CODE>Apache::Registry</CODE> you would use a configuration like:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor10"></A>
  -<PRE>  &lt;Location /perl&gt;
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  &lt;Location /perl&gt;
       SetHandler perl-script
       PerlHandler Apache::Registry
       Options ExecCGI
       PerlSendHeader On
  -  &lt;/Location&gt;
  -</PRE>
  -<P><A NAME="anchor11"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +  &lt;/Location&gt;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="C_API">C API</A></H2></CENTER>
  -<P><A NAME="anchor12"></A>
  +<P>
   META: complete
   
  -<P><A NAME="anchor13"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="Perl_API">Perl API</A></H2></CENTER>
  -<P><A NAME="anchor14"></A>
  +<P>
   META: complete
   
  -<P><A NAME="anchor15"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="Apache_Registry">Apache::Registry</A></H2></CENTER>
  -<P><A NAME="anchor16"></A>
  +<P>
   From the viewpoint of the Perl API, <CODE>Apache::Registry</CODE> is simply another handler that's not conceptually different from any other
   handler. <CODE>Apache::Registry</CODE> reads in the script file, compiles, executes it and stores into the cache.
   Since the perl interpreter keeps running from child process' creation to
   its death, any code compiled by the interpreter is kept in memory until the
   child dies.
   
  -<P><A NAME="anchor17"></A>
  +<P>
   To prevent script name collisions, <CODE>Apache::Registry</CODE> creates a unique key for each cached script by prepending <CODE>Apache::ROOT::</CODE> to the mangled path of the script's URI. This key is actually the package
   name that the script resides in. So if you have requested a script <CODE>/perl/project/test.pl</CODE>, the scripts would be wrapped in code which starts with a package
   declaration of:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor18"></A>
  -<PRE>  package Apache::ROOT::perl::project::test_e2pl;
  -</PRE>
  -<P><A NAME="anchor19"></A>
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  package Apache::ROOT::perl::project::test_e2pl;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   <CODE>Apache::Registry</CODE> also stores the script's last modification time. Everytime the script
   changes, the cached code is discarded and recompiled using the modified
   source. However, it doesn't check the modification times of any of the perl
   libraries the script might use.
   
  -<P><A NAME="anchor20"></A>
  +<P>
   <CODE>Apache::Registry</CODE> overrides <CODE>CORE::exit()</CODE> with <CODE>Apache::exit()</CODE>, so CGI scripts that use <CODE>exit()</CODE> will run correctly. We will talk about all these details in depth later.
   
  -<P><A NAME="anchor21"></A>
  +<P>
   The last thing <CODE>Apache::Registry</CODE> does, is emulation of mod_cgi's environment variables, like <CODE>$ENV{SERVER_NAME}</CODE>, <CODE>$ENV{REMOTE_USER}</CODE>
   and so on. <STRONG>PerlSetupEnv Off</STRONG> disables this feature which saves some memory and CPU cycles.
   
  -<P><A NAME="anchor22"></A>
  +<P>
   From the viewpoint of the programmer, there is almost no difference between
   running a script as a plain CGI script under mod_cgi and running it under
   mod_perl. There is however a great speed improvement, but at the expense of
   much heavier memory usage (there is no free lunch :).
   
  -<P><A NAME="anchor23"></A>
  +<P>
   When they run under mod_cgi, your CGI scripts are loaded each time they are
   called and then they exit. Under mod_perl they are loaded once and cached.
   This gives a big performance boost. But because the code is cached and
   doesn't exit, it won't cleanup memory as it would under mod_cgi. This can
   have unexpected effects.
   
  -<P><A NAME="anchor24"></A>
  +<P>
   Your scripts will be recompiled and reloaded by mod_perl when it detects
   that you have changed them, but remember that any libraries that your
   scripts might <CODE>require()</CODE> or <CODE>use()</CODE> will not be
   recompiled when they are changed. You will have to take action yourself to
   ensure that they are recompiled.
   
  -<P><A NAME="anchor25"></A>
  +<P>
   Of course the guide will answer all these issues in depth.
   
  -<P><A NAME="anchor26"></A>
  +<P>
   Let's see what happens to your script when it's being executed under
   <CODE>Apache::Registry</CODE>. If we take the simplest code of (URI
   <CODE>/perl/project/test.pl</CODE>)
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor27"></A>
  -<PRE>  print &quot;Content-type: text/html\n\n&quot;;
  -  print &quot;It works\n&quot;;
  -</PRE>
  -<P><A NAME="anchor28"></A>
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  print &quot;Content-type: text/html\n\n&quot;;
  +  print &quot;It works\n&quot;;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   <CODE>Apache::Registry</CODE> will convert it into the following:
   
  -<P><A NAME="anchor29"></A>
  -<PRE>  package Apache::ROOT::perl::project::test_e2pl;
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  package Apache::ROOT::perl::project::test_e2pl;
     use Apache qw(exit);
     sub handler {
       print &quot;Content-type: text/html\n\n&quot;;
       print &quot;It works\n&quot;;
  -  }
  -</PRE>
  -<P><A NAME="anchor30"></A>
  +  }</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   The first line provides a unique namespace for the code to use, and a
   unique key by which the code can be referenced from the cache.
   
  -<P><A NAME="anchor31"></A>
  +<P>
   The second line imports <CODE>Apache::exit</CODE> which over-rides perl's built-in <CODE>exit</CODE>.
   
  -<P><A NAME="anchor32"></A>
  +<P>
   The <CODE>sub handler</CODE> subroutine is wrapped around your code. By default (i.e. if you do not
   specify an alternative), when you use mod_perl and your code's URI is
   called, mod_perl will seek to execute the URI's associated <CODE>handler</CODE> subroutine.
   
  -<P><A NAME="anchor33"></A>
  +<P>
   META: Complete
   
  -<P><A NAME="anchor34"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="Apache_PerlRun">Apache::PerlRun</A></H2></CENTER>
  -<P><A NAME="anchor35"></A>
  +<P>
   META: Complete
   
  -<P><A NAME="anchor36"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H1><A NAME="What_will_you_learn">What will you learn</A></H1></CENTER>
  -<P><A NAME="anchor37"></A>
  +<P>
   This document was written in an effort to help you start using Apache's
   mod_perl extension as quickly and easily as possible. It includes
   information about the installation and configuration of both Perl and the
  @@ -257,7 +347,7 @@
   related to administering Apache servers, debugging scripts, using
   databases, mod_perl related Perl, code snippets and more. The <A HREF="././start.html#">Guide's Overview</A> will help you to find your way through the guide.
   
  -<P><A NAME="anchor38"></A>
  +<P>
   It is assumed that you know at least the basics of building and installing
   Perl and Apache. (If you do not, just read the INSTALL documents which are
   part of the distribution of each package.) However, in this guide you will
  @@ -265,7 +355,7 @@
   will help you successfully complete the mod_perl installation and get the
   server running in a short time.
   
  -<P><A NAME="anchor39"></A>
  +<P>
   If after reading this guide and the other documents listed in
   <A HREF="././help.html#">Getting Help and Further Learning</A> you feel that your questions remain unanswered, you could try asking the
   apache/mod_perl mailing list to help you. But first try to browse the
  @@ -282,237 +372,237 @@
   you're far more likely to get replies if people can see the issue you are
   talking about straight away.
   
  -<P><A NAME="anchor40"></A>
  +<P>
   If you find incorrect details or mistakes in my grammar, or you want to
   contribute to this document please feel free to send me an email at <A
   HREF="mailto:stas@stason.org">stas@stason.org</A> .
   
  -<P><A NAME="anchor41"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H1><A NAME="High_Profile_Sites_Running_mod_p">High-Profile Sites Running mod_perl</A></H1></CENTER>
  -<P><A NAME="anchor42"></A>
  +<P>
   A report prepared by Rex Staples at Thu, 14 Oct 1999:
   
   <UL>
   <P><LI>
  -<P><A NAME="anchor43"></A>
  +<P>
   Macromedia
   
  -<P><A NAME="anchor44"></A>
  +<P>
   4,273,000 unique visitors/month Aug-1999
   
  -<P><A NAME="anchor45"></A>
  -<A HREF="http://www.macromedia.com">http://www.macromedia.com</A> <A
  -HREF="http://www.mediametrix.com/TopRankings/TopRankings.html">http://www.mediametrix.com/TopRankings/TopRankings.html</A>
  -
  +<P>
  +<A HREF="http://www.macromedia.com">http://www.macromedia.com</A>
   
  -<P><A NAME="anchor46"></A>
  +<P>
   Apache/1.3.4 (Unix) mod_perl/1.18 on Solaris
   
   <P><LI>
  -<P><A NAME="anchor47"></A>
  +<P>
   ValueClick: Results-based advertising network
   
  -<P><A NAME="anchor48"></A>
  -60 million page views/day Oct-1999
  +<P>
  +80 million page views/day May 2000 using about 45 machines
   
  -<P><A NAME="anchor49"></A>
  +<P>
   <A HREF="http://valueclick.com">http://valueclick.com</A>
   
  -<P><A NAME="anchor50"></A>
  +<P>
   Apache/1.3.9-dev (Unix) mod_perl/1.21_01 on FreeBSD
   
   <P><LI>
  -<P><A NAME="anchor51"></A>
  +<P>
   Deja.com
   
  -<P><A NAME="anchor52"></A>
  +<P>
   130 million pageviews/month Oct-1999
   
  -<P><A NAME="anchor53"></A>
  +<P>
   <A HREF="http://www.deja.com">http://www.deja.com</A>
   
  -<P><A NAME="anchor54"></A>
  +<P>
   Apache/1.3b5 mod_perl/1.08 on Linux
   
   <P><LI>
  -<P><A NAME="anchor55"></A>
  +<P>
   MP3.com, Inc.
   
  -<P><A NAME="anchor56"></A>
  +<P>
   77 million page views/month Aug-1999
   
  -<P><A NAME="anchor57"></A>
  +<P>
   408,000 unique visitors/day Aug-1999
   
  -<P><A NAME="anchor58"></A>
  +<P>
   <A HREF="http://www.mp3.com">http://www.mp3.com</A> <A
   HREF="http://www.mp3.com/pr/990914-keymetrics.html">http://www.mp3.com/pr/990914-keymetrics.html</A>
   
   
  -<P><A NAME="anchor59"></A>
  +<P>
   Apache/1.3.4-9 (Unix) mod_perl/1.18-21 on Linux/FreeBSD
   
   <P><LI>
  -<P><A NAME="anchor60"></A>
  +<P>
   IMDB: Internet Movie Database
   
  -<P><A NAME="anchor61"></A>
  +<P>
   1.25 million page views/day Mar-1998
   
  -<P><A NAME="anchor62"></A>
  +<P>
   <A HREF="http://www.imdb.com">http://www.imdb.com</A>
   
  -<P><A NAME="anchor63"></A>
  +<P>
   * They are now an Amazon.com company
   
  -<P><A NAME="anchor64"></A>
  +<P>
   Apache/1.3.7-dev (Unix) mod_perl/1.19_01-dev
   
   <P><LI>
  -<P><A NAME="anchor65"></A>
  +<P>
   Flash.net: Internet Service Provider
   
  -<P><A NAME="anchor66"></A>
  +<P>
   1,603,000 unique visitors/month Aug-1999
   
  -<P><A NAME="anchor67"></A>
  +<P>
   <A HREF="http://www.flash.net">http://www.flash.net</A> <A
   HREF="http://www.mediametrix.com/TopRankings/TopRankings.html">http://www.mediametrix.com/TopRankings/TopRankings.html</A>
   
   
  -<P><A NAME="anchor68"></A>
  +<P>
   Apache/1.2.4 mod_perl/1.00 on Solaris
   
   <P><LI>
  -<P><A NAME="anchor69"></A>
  +<P>
   At Hand Network Yellow Pages
   
  -<P><A NAME="anchor70"></A>
  +<P>
   917,000 unique visitors/month Aug-1999
   
  -<P><A NAME="anchor71"></A>
  +<P>
   <A HREF="http://www.athand.com">http://www.athand.com</A> <A
   HREF="http://www.mediametrix.com/TopRankings/TopRankings.html">http://www.mediametrix.com/TopRankings/TopRankings.html</A>
   
   
  -<P><A NAME="anchor72"></A>
  +<P>
   Stronghold/2.3 Apache/1.2.6 (Unix) mod_perl/1.15 on Solaris
   
   <P><LI>
  -<P><A NAME="anchor73"></A>
  +<P>
   Commissioner.com: Subscription Fantasy Football
   
  -<P><A NAME="anchor74"></A>
  +<P>
   12 million page views/day Oct-1999
   
  -<P><A NAME="anchor75"></A>
  +<P>
   <A HREF="http://www.commissioner.com">http://www.commissioner.com</A>
   
  -<P><A NAME="anchor76"></A>
  +<P>
   Apache/1.35b mod_perl/1.10 on Linux
   
   <P><LI>
  -<P><A NAME="anchor77"></A>
  +<P>
   Slashdot: News For Nerds
   
  -<P><A NAME="anchor78"></A>
  +<P>
   400,000 page views/day Oct-1999
   
  -<P><A NAME="anchor79"></A>
  +<P>
   <A HREF="http://www.slashdot.org">http://www.slashdot.org</A>
   
  -<P><A NAME="anchor80"></A>
  +<P>
   Apache/1.3.6 (Unix) mod_perl/1.21 on Linux
   
   <P><LI>
  -<P><A NAME="anchor81"></A>
  +<P>
   Hot Bot mail and member web pages:
   
  -<P><A NAME="anchor82"></A>
  +<P>
   <A HREF="http://members.hotbot.com">http://members.hotbot.com</A>
   
  -<P><A NAME="anchor83"></A>
  +<P>
   Also widely used on HotWired, WiredNews, Webmonkey, and Suck.com
   
  -<P><A NAME="anchor84"></A>
  +<P>
   Apache/1.3.4 (Unix) mod_perl/1.21 on Solaris
   
   <P><LI>
  -<P><A NAME="anchor85"></A>
  +<P>
   Art Today: subscription clip-art service
   
  -<P><A NAME="anchor86"></A>
  +<P>
   250k hits/day
   
  -<P><A NAME="anchor87"></A>
  +<P>
   <A HREF="http://www.arttoday.com">http://www.arttoday.com</A>
   
  -<P><A NAME="anchor88"></A>
  +<P>
   Oracle 7 + 1 Sun Ultra w/150GB storage Apache/1.3.4 (Unix) mod_perl/1.17 on
   Solaris
   
   <P><LI>
  -<P><A NAME="anchor89"></A>
  +<P>
   CMPnet: a technology information network
   
  -<P><A NAME="anchor90"></A>
  +<P>
   500k hits/day
   
  -<P><A NAME="anchor91"></A>
  +<P>
   <A HREF="http://www.cmpnet.com">http://www.cmpnet.com</A>
   
  -<P><A NAME="anchor92"></A>
  +<P>
   Apache/1.3.9 (Unix) mod_perl/1.16
   
   </UL>
  -<P><A NAME="anchor93"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H1><A NAME="References_and_Acknowledgments">References and Acknowledgments</A></H1></CENTER>
  -<P><A NAME="anchor94"></A>
  +<P>
   I have used the following references while writing this guide:
   
   <UL>
   <P><LI>
  -<P><A NAME="anchor95"></A>
  +<P>
   <STRONG>mod_perl FAQ</STRONG> by Frank Cringle at <A
   HREF="http://perl.apache.org/faq/">http://perl.apache.org/faq/</A> .
   
   <P><LI>
  -<P><A NAME="anchor96"></A>
  +<P>
   <STRONG>mod_perl performance tuning guide</STRONG> by Vivek Khera at <A
   HREF="http://perl.apache.org/tuning/">http://perl.apache.org/tuning/</A> .
   
   <P><LI>
  -<P><A NAME="anchor97"></A>
  +<P>
   <STRONG>mod_perl plugin reference guide</STRONG> by Doug MacEachern at <A
   HREF="http://perl.apache.org/src/mod_perl.html">http://perl.apache.org/src/mod_perl.html</A>
   .
   
   <P><LI>
  -<P><A NAME="anchor98"></A>
  +<P>
   <STRONG>Quick guide for moving from CGI to mod_perl</STRONG> at <A
   HREF="http://perl.apache.org/dist/cgi_to_mod_perl.html">http://perl.apache.org/dist/cgi_to_mod_perl.html</A>
   .
   
   <P><LI>
  -<P><A NAME="anchor99"></A>
  +<P>
   <STRONG>mod_perl_traps, common traps and solutions for mod_perl users</STRONG> at <A
   HREF="http://perl.apache.org/dist/mod_perl_traps.html">http://perl.apache.org/dist/mod_perl_traps.html</A>
   .
   
   <P><LI>
  -<P><A NAME="anchor100"></A>
  +<P>
   <STRONG>mod_perl mailing list emails</STRONG>. Answers to some of the questions posted to <A
   HREF="mailto:modperl@apache.org">modperl@apache.org</A> Apache/Perl mailing
   list.
   
   <P><LI>
  -<P><A NAME="anchor101"></A>
  +<P>
   <STRONG>My personal experience with mod_perl</STRONG>.
   
   </UL>
  -<P><A NAME="anchor102"></A>
  +<P>
   I have quoted many snippets of information from FAQs and emails, but I have
   not credited each quote in the guide individually. I did not mean to take
   the credit for myself, it's just that I tried to keep track of names, and
  @@ -520,84 +610,87 @@
   gathered them all together here. If you want your name to show up under
   your original quote, please tell me and I'll add it for you.
   
  -<P><A NAME="anchor103"></A>
  +<P>
   Major contributors:
   
   <UL>
   <P><LI>
  -<P><A NAME="anchor104"></A>
  +<P>
   <STRONG>Doug MacEachern</STRONG>. A large part of this guide is built upon his email replies to users
   questions.
   
   <P><LI>
  -<P><A NAME="anchor105"></A>
  +<P>
   <STRONG>Frank Cringle</STRONG>. Parts of his mod_perl FAQ have been used in this guide.
   
   <P><LI>
  -<P><A NAME="anchor106"></A>
  -<STRONG>Vivek Khera</STRONG>. For his mod_perl performance tuning guide.
  +<P>
  +<STRONG>Vivek Khera</STRONG>. For his mod_perl performance tuning guide. And lots of useful comments on
  +the list that made into the guide.
   
   <P><LI>
  -<P><A NAME="anchor107"></A>
  +<P>
   <STRONG>Steve Reppucci</STRONG>, who did a thorough review of the stuff I wrote. He fixed lots of spelling
   and grammar errors, and made the guide readable to English speakers :)
   
   <P><LI>
  -<P><A NAME="anchor108"></A>
  +<P>
   <STRONG>Eric Cholet</STRONG>, who wrote complete sections for the guide, and pointed out technical
   errors in it.
   
   <P><LI>
  -<P><A NAME="anchor109"></A>
  +<P>
   <STRONG>Ken Williams</STRONG>, who reviewed a lot of stuff in the guide. Many snippets from his emails
   are included in the guide.
   
   <P><LI>
  -<P><A NAME="anchor110"></A>
  +<P>
   <STRONG>Matt Sergeant</STRONG>, who contributed the section ``Exception Handling for mod_perl'' for the
   perl reference chapter and made many other contributions.
   
   <P><LI>
  -<P><A NAME="anchor111"></A>
  +<P>
   <STRONG>Wesley Darlington</STRONG> for contributing a big section for the scenario chapter.
   
   <P><LI>
  -<P><A NAME="anchor112"></A>
  -<STRONG>Geoffrey S Young</STRONG> and <STRONG>David Harris</STRONG> for contributing big sections about mod_perl and RPM packages.
  +<P>
  +<STRONG>Geoffrey S Young</STRONG> and <STRONG>David Harris</STRONG> for contributing big sections about mod_perl and RPM packages, and
  +providing helpful comments and corrections.
   
   <P><LI>
  -<P><A NAME="anchor113"></A>
  +<P>
   <STRONG>Andreas J. Koenig</STRONG> for contributing his ``Correct HTTP headers'' document.
   
   <P><LI>
  -<P><A NAME="anchor114"></A>
  +<P>
   <STRONG>Ged W. Haywood</STRONG> for reviewing and fixing the whole guide, providing lots of constructive
   criticisms and helping to reorganize the guide to make it more user
   friendly.
   
   <P><LI>
  -<P><A NAME="anchor115"></A>
  -<STRONG>Mark Summerfield</STRONG> for reviewing and fixing a big part of the guide, to improve readability
  -and suggesting useful extensions.
  +<P>
  +<STRONG>Mark Summerfield</STRONG> for reviewing and fixing all the guide's chapters, improving guide's
  +readability and suggesting useful extensions.
   
   <P><LI>
  -<P><A NAME="anchor116"></A>
  -<STRONG>Jeffrey W. Baker</STRONG> for his ``guide to mod_perl database performance''.
  +<P>
  +<STRONG>Jeffrey W. Baker</STRONG> for his ``guide to mod_perl database performance'' and many useful comments
  +on the list that has been reused in the guide's material.
   
   <P><LI>
  -<P><A NAME="anchor117"></A>
  +<P>
   <STRONG>Richard A. Wells</STRONG> for reviewing and correcting a large part of the guide.
   
   <P><LI>
  -<P><A NAME="anchor118"></A>
  +<P>
   <STRONG>Randy Harmon</STRONG> for rewriting the mod_perl advocacy chapter
   
   <P><LI>
  -<P><A NAME="anchor119"></A>
  +<P>
   <STRONG>Dean Fitz</STRONG> for reviewing the ``Operating System and Hardware Demands'' chapter.
   
   </UL>
  -<P><A NAME="anchor120"></A>
  +<P>
   Credits of course go to ( alphabetically sorted ):
   
   <UL>
  @@ -734,65 +827,91 @@
   <P><LI>
   <P><LI><STRONG><A NAME="item_Did">Did I miss your name? Tell me!</A></STRONG>
   </UL>
  -<P><A NAME="anchor121"></A>
  +<P>
   I want to thank all the people who donated their time and efforts to make
   this amazing idea of mod_perl a reality. This includes Doug MacEachern, the
   author of mod_perl, and all the developers who contributed bug patches,
   modules and help. And of course the numerous unseen users around the world
   who help to promote mod_perl and to make it a better tool.
   
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -	     The <a href="http://www.modperl.com/">
  -	     <B>Writing Apache Modules with Perl and C</B></a>
  -	     book can be purchased online from <a
  -	     href="http://www.ora.com/catalog/wrapmod/">O'Reilly </a>
  -	     and <a
  -	     href="http://www.amazon.com/exec/obidos/ASIN/156592567X/writinapachemodu">
  -	     Amazon.com</a>.
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   
  -	     <HR>
   
  -	     <B>Your corrections of either technical or grammatical
  +    <p>
  +    <div class="navbar">
  +      <a href="">Prev</a>                                 |
  +      <A HREF="index.html"         >Contents</A> |
  +      <A HREF="index.html#search"  >Search</A>   |
  +      <A HREF="index.html#download">Download</A> |
  +      <a href="start.html">Next</a>
  +    </div>
  +    <p>
  +
  +    <table width="60%" align="center">
  +
  +      <tr>
  +	<td>
  +	  <div class="notice">
  +	  <B>Your corrections of the technical and grammatical
   	     errors are very welcome. You are encouraged to help me
  -	     to improve this guide.  If you have something to
  -	     contribute please <A
  -	     HREF="help.html#Contacting_me"> send it
  +	     improve this guide.  If you have something to contribute
  +	     please <A HREF="help.html#Contacting_me"> send it
   	     directly to me</A>.</B>
  +	  </div>
  +	</td>
  +      </tr>
  +
  +      <tr>
  +	<td>
  +	  <div class="ad">
  +	    The <a href="http://www.modperl.com/">
  +	      <B>Writing Apache Modules with Perl and C</B></a>
  +	    book can be purchased online from <a
  +	      href="http://www.ora.com/catalog/wrapmod/">O'Reilly </a>
  +	    and <a
  +	    href="http://www.amazon.com/exec/obidos/ASIN/156592567X/writinapachemodu">
  +	      Amazon.com</a>.
  +	  </div>
  +	</td>
  +      </tr>
  +
  +</table>
  +
  +<center>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
  +<table cellspacing=2 cellpadding=2>
  +
  +<tr align=center valign=top>
  +<td align=center valign=center>
  +
  +<b><font size=-1>Written by <a
  +href="help.html#Contacting_me">Stas Bekman</a>.<br> Last Modified at 06/07/2000
  +</font></b>
  +<br>
  +
  +</td>
  +
  +<td>
  +
  +<a href="http://perl.apache.org"><img src="images/mod_perl2.jpg"  border=0 alt="mod_perl icon" border=0 height=59 width=150></a>
  +<br>
  +
  +</td>
  +
  +<td>
  +
  +<font size=-2>Use of the Camel for Perl is <br>
  +a trademark of <a href="http://www.ora.com">O'Reilly &amp; Associates</a>,<br>
  +and is used by permission. </font> 
  +<br>
   
  -	     <HR>
  +</td>
   
  -	     [    <A HREF="index.html">Main Page</A> | <A HREF="start.html">Next</A>      ]
  +</tr>
  +</table>
  +</center>
   
  -<CENTER><TABLE CELLSPACING=2 CELLPADDING=2 WIDTH="100%" >
  -<TR ALIGN=CENTER VALIGN=TOP>
  -  <TD ALIGN=CENTER VALIGN=CENTER COLSPAN="3">
  -	     <HR>
  -  </TD>
  -</TR>
  -<TR ALIGN=CENTER VALIGN=TOP>
  -  <TD ALIGN=CENTER VALIGN=CENTER>
  -    <B>
  -      <FONT SIZE=-1>
  -	     Written by <A HREF="help.html#Contacting_me">Stas Bekman</A>.
  -	     <BR>Last Modified at 04/19/2000
  -      </FONT>
  -    </B>
  -  </TD>
  -
  -  <TD>
  -	     <A HREF="http://perl.apache.org"><IMG SRC="images/mod_perl2.jpg" ALT="Mod Perl Icon" BORDER=0 HEIGHT=59 WIDTH=150></A>
  -  </TD>
  -
  -  <TD>
  -    <FONT SIZE=-2>
  -	     Use of the Camel for Perl is <BR>
  -	     a trademark of <A HREF="http://www.ora.com">O'Reilly &amp; Associates</A>,<BR>
  -             and is used by permission. 
  -    </FONT> 
  -  </TD>
  -</TR>
  -</TABLE></CENTER>
  -
  -</BODY>
  -</HTML>
  -	    
  \ No newline at end of file
  +</body>
  +</html>
  
  
  
  1.5       +4987 -4857modperl-site/guide/mod_perl_guide.pdf.gz
  
  	<<Binary file>>
  
  
  1.16      +874 -318  modperl-site/guide/modules.html
  
  Index: modules.html
  ===================================================================
  RCS file: /home/cvs/modperl-site/guide/modules.html,v
  retrieving revision 1.15
  retrieving revision 1.16
  diff -u -r1.15 -r1.16
  --- modules.html	2000/05/12 22:42:54	1.15
  +++ modules.html	2000/06/07 22:45:35	1.16
  @@ -1,111 +1,182 @@
   <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
  -<HTML>
  -<HEAD>
  -   <TITLE>mod_perl guide: Apache::* modules</TITLE>
  -   <META NAME="GENERATOR" CONTENT="Pod2HTML [Perl/Linux]">
  -   <META NAME="Author" CONTENT="Stas Bekman">
  -   <META NAME="Description" CONTENT="All Apache/Perl related information: Hints, Guidelines, Scenarios and Troubleshottings">
  -   <META NAME="keywords" CONTENT="mod_perl modperl perl apache cgi webserver speed  fast guide mod_perl apache guide help info faq mod_perl installation cgi troubleshooting help no sex speedup free open source OSS mod_perl apache guide">
  -</HEAD>
  -     <LINK REL=STYLESHEET TYPE="text/css"
  -        HREF="style.css" TITLE="refstyle">
  -     <style type="text/css">
  -     <!-- 
  -        @import url(style.css);
  -     -->
  -     
  -     </style>
  -<BODY BGCOLOR="white">
  +<html>
  +  <head>
  +   <title>mod_perl guide: Apache::* modules</title>
  +   <meta name="Author" content="Stas Bekman">
  +   <meta name="Description" content="All Apache/Perl related information: Hints, Guidelines, Scenarios and Troubleshottings">
  +   <meta name="keywords" content="mod_perl modperl perl cgi apache webserver speed fast guide mod_perl apache guide help info faq mod_perl installation cgi troubleshooting help no sex speedup free open source OSS mod_perl apache guide">
  +   <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
  +   <meta name="Classification" content="information">
  +   <link href="style.css" rel=stylesheet type="text/css" title="refstyle">
  +  </head>
  +  <body>
  +
  +    <h1 align=center>
  +      <a href="http://perl.apache.org"><img src="images/mod_perl.gif" alt="Mod Perl Icon" border=0 height=30 width=90 align=left></a>
  +      <a href="http://perl.apache.org"><img src="images/mod_perl.gif" alt="Mod Perl Icon" border=0 height=30 width=90 align=right></a>
  +      Apache::* modules
  +    </h1>
  +    <hr>
  +    <p>
  +    <div class="navbar">
  +      <a href="browserbugs.html">Prev</a>                                 |
  +      <a href="index.html"         >Contents</a> |
  +      <a href="index.html#search"  >Search</a>   |
  +      <a href="index.html#download">Download</a> |
  +      <a href="snippets.html">Next</a>
  +    </div>
  +    <p>
  +
  +    <div class="toc">
  +      
   <A NAME="toc"></A>
  -<H1 ALIGN=CENTER>
  -<A HREF="http://perl.apache.org"><IMG SRC="images/mod_perl.gif" ALT="Mod Perl Icon" BORDER=0 HEIGHT=30 WIDTH=90 ALIGN=LEFT></A>
  -<A HREF="http://perl.apache.org"><IMG SRC="images/mod_perl.gif" ALT="Mod Perl Icon" BORDER=0 HEIGHT=30 WIDTH=90 ALIGN=RIGHT></A>
  -Apache::* modules</H1>
  -<HR WIDTH="100%">
  -	    [    <A HREF="browserbugs.html">Prev</A> |      <A HREF="index.html">Main Page</A> | <A HREF="snippets.html">Next</A>      ]<HR><!-- INDEX BEGIN -->
  -<P><B><FONT SIZE=-1>Table of Contents:</FONT></B></P>
  +<P><B>Table of Contents:</B></P>
  +
   <UL>
   
   	<LI><A HREF="#Apache_Session_Maintain_sessi">Apache::Session - Maintain session state across HTTP requests</A>
   	<LI><A HREF="#Apache_DBI_Initiate_a_persist">Apache::DBI - Initiate a persistent database connection</A>
   	<LI><A HREF="#Apache_Watchdog_RunAway_Hang">Apache::Watchdog::RunAway - Hanging Processes Monitor and Terminator</A>
  -	<LI><A HREF="#Apache_VMonitor_Visual_System">Apache::VMonitor - Visual System and Apache Server Monitor</A>
  +	<LI><A HREF="#Apache_VMonitor_Visual_Syste">Apache::VMonitor - Visual System and Apache Server Monitor</A>
   	<LI><A HREF="#Apache_GTopLimit_Limit_Apache">Apache::GTopLimit - Limit Apache httpd processes</A>
   	<LI><A HREF="#Apache_Request_libapreq_Gen">Apache::Request (libapreq) - Generic Apache Request Library</A>
   	<LI><A HREF="#Apache_RequestNotes_Allow_Eas">Apache::RequestNotes - Allow Easy, Consistent Access to Cookie and Form Data Across Each Request Phase</A>
   	<LI><A HREF="#Apache_PerlRun_Run_unaltered_">Apache::PerlRun - Run unaltered CGI scripts under mod_perl</A>
   	<LI><A HREF="#Apache_RegistryNG_Apache_Re">Apache::RegistryNG - Apache::Registry New Generation</A>
   	<LI><A HREF="#Apache_RegistryBB_Apache_Re">Apache::RegistryBB - Apache::Registry Bare Bones </A>
  -	<LI><A HREF="#Apache_GzipChain_compress_HTM">Apache::GzipChain - compress HTML (or anything) in the OutputChain</A>
   	<LI><A HREF="#Apache_OutputChain_Chain_Sta">Apache::OutputChain - Chain Stacked Perl Handlers</A>
  +	<LI><A HREF="#Apache_GzipChain_compress_HTM">Apache::GzipChain - compress HTML (or anything) in the OutputChain</A>
  +	<LI><A HREF="#Apache_Filter_Alter_the_outpu">Apache::Filter - Alter the output of previous handlers</A>
  +	<LI><A HREF="#Apache_Gzip_Auto_compress_web">Apache::Gzip - Auto-compress web files with Gzip</A>
   	<LI><A HREF="#Apache_PerlVINC_set_a_differe">Apache::PerlVINC - set a different @INC perl-location </A>
   	<LI><A HREF="#Apache_LogSTDERR">Apache::LogSTDERR</A>
   	<LI><A HREF="#Apache_RedirectLogFix">Apache::RedirectLogFix</A>
   	<LI><A HREF="#Apache_SubProcess">Apache::SubProcess</A>
   </UL>
  -<!-- INDEX END -->
   
  +    </div>
  +
  +    [ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
   <HR>
  +    <table width="60%" align="center">
   
  -	     The <a href="http://www.modperl.com/">
  -	     <B>Writing Apache Modules with Perl and C</B></a>
  -	     book can be purchased online from <a
  -	     href="http://www.ora.com/catalog/wrapmod/">O'Reilly </a>
  -	     and <a
  -	     href="http://www.amazon.com/exec/obidos/ASIN/156592567X/writinapachemodu">
  -	     Amazon.com</a>.
  -
  -	     <HR>
  -
  -	       <B>Your corrections of either technical or grammatical
  -	       errors are very welcome. You are encouraged to help me
  -	       to improve this guide.  If you have something to
  -	       contribute please <A
  -	       HREF="help.html#Contacting_me"> send it
  -	       directly to me</A>.
  -	       </B>
  -	       <HR>
  +      <tr>
  +	<td>
  +	  <div class="ad">
  +	    The <a href="http://www.modperl.com/">
  +	      <B>Writing Apache Modules with Perl and C</B></a>
  +	    book can be purchased online from <a
  +	      href="http://www.ora.com/catalog/wrapmod/">O'Reilly </a>
  +	    and <a
  +	    href="http://www.amazon.com/exec/obidos/ASIN/156592567X/writinapachemodu">
  +	      Amazon.com</a>.
  +	  </div>
  +	</td>
  +      </tr>
  +
  +      <tr>
  +	<td>
  +	  <div class="notice">
  +	  <B>Your corrections of the technical and grammatical
  +	     errors are very welcome. You are encouraged to help me
  +	     improve this guide.  If you have something to contribute
  +	     please <A HREF="help.html#Contacting_me"> send it
  +	     directly to me</A>.</B>
  +	  </div>
  +	</td>
  +      </tr>
  +
  +</table>
  +
  +    
  +
  +	    [ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   
  -	      <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<P><A NAME="anchor0"></A>
  +<P>
   <CENTER><H1><A NAME="Apache_Session_Maintain_sessi">Apache::Session - Maintain session state across HTTP requests</A></H1></CENTER>
  -<P><A NAME="anchor1"></A>
  +<P>
   This module provides the Apache/mod_perl user a mechanism for storing
   persistent user data in a global hash, which is independent of its real
   storage mechanism. Currently you can choose from these storage mechanisms <CODE>Apache::Session::DBI</CODE>, <CODE>Apache::Session::Win32</CODE>,
   <CODE>Apache::Session::File</CODE>, <CODE>Apache::Session::IPC</CODE>. Read the man page of the mechanism you want to use for a complete
   reference.
   
  -<P><A NAME="anchor2"></A>
  +<P>
   <CODE>Apache::Session</CODE> provides persistence to a data structure. The data structure has an ID
   number, and you can retrieve it by using the ID number. In the case of
   Apache, you would store the ID number in a cookie or the URL to associate
   it with one browser, but the method of dealing with the ID is completely up
   to you. The flow of things is generally:
   
  -<P><A NAME="anchor3"></A>
  -<PRE>  Tie a session to Apache::Session.
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  Tie a session to Apache::Session.
     Get the ID number.
     Store the ID number in a cookie.
  -  End of Request 1.
  -</PRE>
  -<P><A NAME="anchor4"></A>
  -<PRE>  (time passes)
  -</PRE>
  -<P><A NAME="anchor5"></A>
  -<PRE>  Get the cookie.
  +  End of Request 1.</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  (time passes)</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  Get the cookie.
     Restore your hash using the ID number in the cookie.
     Use whatever data you put in the hash.
  -  End of Request 2.
  -</PRE>
  -<P><A NAME="anchor6"></A>
  +  End of Request 2.</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Using <CODE>Apache::Session</CODE> is easy: simply tie a hash to the session object, stick any data structure
   into the hash, and the data you put in automatically persists until the
   next invocation. Here is a quick example which uses cookies to track the
   user's session.
  +
  +<P>
   
  -<P><A NAME="anchor7"></A>
  -<PRE>  #  Pull in the required packages
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  #  Pull in the required packages
     use Apache::Session::DBI;
     use Apache;
     
  @@ -127,20 +198,23 @@
     
     # Might be a new session, so lets give them their cookie back
     my $session_cookie = &quot;SESSION_ID=$session{_session_id};&quot;;
  -  $r-&gt;header_out(&quot;Set-Cookie&quot; =&gt; $session_cookie);
  -</PRE>
  -<P><A NAME="anchor8"></A>
  +  $r-&gt;header_out(&quot;Set-Cookie&quot; =&gt; $session_cookie);</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   After setting this up, you can stick anything you want into
   <CODE>%session</CODE> (except file handles), and it will still be there
   when the user invokes the next page.
   
  -<P><A NAME="anchor9"></A>
  +<P>
   It is possible to write an Apache authen handler using
   <CODE>Apache::Session</CODE>. You can put your authentication token into the session. When a user
   invokes a page, you open their session, check to see if they have a valid
   token, and approve or deny their authorization based on that.
   
  -<P><A NAME="anchor10"></A>
  +<P>
   As for IIS, let's compare. IIS's sessions are only valid on the same web
   server as the one that issued the session.
   <CODE>Apache::Session</CODE>'s session objects can be shared amongst a farm of many machines running
  @@ -153,60 +227,152 @@
   <CODE>Apache::Session::DBI</CODE> can issue 400+ session requests per second on light Celeron 300A running
   Linux. IIS?
   
  -<P><A NAME="anchor11"></A>
  +<P>
   An alternative to <CODE>Apache::Session</CODE> is Apache::ASP, which has session tracking abilities. HTML::Embperl hooks
   into <CODE>Apache::Session</CODE> for you.
   
  -<P><A NAME="anchor12"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H1><A NAME="Apache_DBI_Initiate_a_persist">Apache::DBI - Initiate a persistent database connection</A></H1></CENTER>
  -<P><A NAME="anchor13"></A>
  +<P>
   See <A HREF="././databases.html#Apache_DBI_Initiate_a_persist">mod_perl and relational Databases</A>
   
   
   
  -<P><A NAME="anchor14"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H1><A NAME="Apache_Watchdog_RunAway_Hang">Apache::Watchdog::RunAway - Hanging Processes Monitor and Terminator</A></H1></CENTER>
  -<P><A NAME="anchor15"></A>
  +<P>
   This module monitors hanging Apache/mod_perl processes. You define the time
   in seconds after which the process is to be counted as <EM>hanging</EM> or
   <EM>run away</EM>.
   
  -<P><A NAME="anchor16"></A>
  +<P>
   When the process is considered as <EM>hanging</EM> it will be killed and the event logged into a log file.
   
  -<P><A NAME="anchor17"></A>
  +<P>
   Generally you should use the <CODE>amprapmon</CODE> program that is bundled with this module's distribution package, but you
   can write your own code using the module as well. See the <EM>amprapmon</EM> manpage for more information about it.
   
  -<P><A NAME="anchor18"></A>
  +<P>
   Note that it requires the <CODE>Apache::Scoreboard</CODE> module to work.
   
  -<P><A NAME="anchor19"></A>
  +<P>
   Referer to the <CODE>Apache::Watchdog::RunAway</CODE> manpage for the configuration details.
   
  -<P><A NAME="anchor20"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<CENTER><H1><A NAME="Apache_VMonitor_Visual_System">Apache::VMonitor - Visual System and Apache Server Monitor</A></H1></CENTER>
  -<P><A NAME="anchor21"></A>
  -(META: Move it here)
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
  +<CENTER><H1><A NAME="Apache_VMonitor_Visual_Syste">Apache::VMonitor -- Visual System and Apache Server Monitor</A></H1></CENTER>
  +<P>
  +<CODE>Apache::VMonitor</CODE> is the next generation of
  +<A HREF="././debug.html#mod_status">mod_status</A>. It provides all the information mod_status provides and much more.
  +
  +<P>
  +This module emulates the reporting functions of the <CODE>top(),</CODE>
  +<CODE>mount(),</CODE> <CODE>df()</CODE> and <CODE>ifconfig()</CODE>
  +utilities. There is a special mode for mod_perl processes. It has visual
  +alert capabilities and a configurable
  +<EM>automatic refresh</EM> mode. It provides a Web interface, which can be used to show or hide all
  +the sections dynamically.
   
  -<P><A NAME="anchor22"></A>
  -<A HREF="././debug.html#Apache_VMonitor_Visual_Syste">Apache::VMonitor -- Visual System and Apache Server Monitor</A>
  +<P>
  +The are two main modes:
   
  +<UL>
  +<P><LI>
  +<P>
  +Multi processes mode -- All system processes and information is shown.
   
  +<P><LI>
  +<P>
  +Single process mode -- In-depth information about a single process is
  +shown.
  +
  +</UL>
  +<P>
  +The main advantage of this module is that it reduces the need to telnet to
  +the machine in order to monitor it. Indeed it provides information about
  +mod_perl processes that cannot be acquired from telneting to the machine.
  +=head3 Configuration
  +
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  # Configuration in httpd.conf
  +  &lt;Location /sys-monitor&gt;
  +    SetHandler perl-script
  +    PerlHandler Apache::VMonitor
  +  &lt;/Location&gt;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  # startup file or &lt;Perl&gt; section:
  +  use Apache::VMonitor();
  +  $Apache::VMonitor::Config{BLINKING} = 0; # Blinking is evil
  +  $Apache::VMonitor::Config{REFRESH}  = 0;
  +  $Apache::VMonitor::Config{VERBOSE}  = 0;
  +  $Apache::VMonitor::Config{SYSTEM}   = 1;
  +  $Apache::VMonitor::Config{APACHE}   = 1;
  +  $Apache::VMonitor::Config{PROCS}    = 1;
  +  $Apache::VMonitor::Config{MOUNT}    = 1;
  +  $Apache::VMonitor::Config{FS_USAGE} = 1;
  +  $Apache::VMonitor::Config{NETLOAD}  = 1;
  +                                
  +  @Apache::VMonitor::NETDEVS    = qw(lo eth0);
  +  $Apache::VMonitor::PROC_REGEX = join &quot;\|&quot;, qw(httpd mysql squid);</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +More information available in the module's extensive manpage.
  +
  +<P>
  +It requires <CODE>Apache::Scoreboard</CODE> and <CODE>GTop</CODE> to work.  <CODE>GTop</CODE> in turn requires the <CODE>libgtop</CODE> library but is not available for all platforms. Visit <A
  +HREF="http://www.home-of-linux.org/gnome/libgtop/">http://www.home-of-linux.org/gnome/libgtop/</A>
  +to check whether your platform/flavor is supported.
   
  -<P><A NAME="anchor23"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H1><A NAME="Apache_GTopLimit_Limit_Apache">Apache::GTopLimit - Limit Apache httpd processes</A></H1></CENTER>
  -<P><A NAME="anchor24"></A>
  +<P>
   This module allows you to kill off Apache processes if they grow too large
   or if they share too little of their memory. You can choose to set up the
   process size limiter to check the process size on every request:
  +
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
   
  -<P><A NAME="anchor25"></A>
  -<PRE>    # in your startup.pl:
  +	<td>
  +	  <pre>    # in your startup.pl:
       use Apache::GTopLimit;
     
       # Control the life based on memory size
  @@ -223,177 +389,333 @@
       # in your httpd.conf:   
       PerlFixupHandler Apache::GTopLimit
       # you can set this up as any Perl*Handler that handles
  -    # part of the request, even the LogHandler will do.
  -</PRE>
  -<P><A NAME="anchor26"></A>
  +    # part of the request, even the LogHandler will do.</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Or you can just check those requests that are likely to get big or
   unshared. This way of checking is also easier for those who are mostly just
   running Apache::Registry scripts:
   
  -<P><A NAME="anchor27"></A>
  -<PRE>    # in your CGI:
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>    # in your CGI:
       use Apache::GTopLimit;  
         # Max Process Size in KB
  -    Apache::GTopLimit-&gt;set_max_size(10000);
  -</PRE>
  -<P><A NAME="anchor28"></A>
  +    Apache::GTopLimit-&gt;set_max_size(10000);</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   and/or:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor29"></A>
  -<PRE>    use Apache::GTopLimit;
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>    use Apache::GTopLimit;
          # Min Shared process Size in KB
  -    Apache::GTopLimit-&gt;set_min_shared_size(4000);
  -</PRE>
  -<P><A NAME="anchor30"></A>
  +    Apache::GTopLimit-&gt;set_min_shared_size(4000);</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Since accessing the process info might add a little overhead, you may want
   to only check the process size every N times. To do so, put this in your <EM>startup.pl</EM> or your code:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor31"></A>
  -<PRE>    $Apache::GTopLimit::CHECK_EVERY_N_REQUESTS = 2;
  -</PRE>
  -<P><A NAME="anchor32"></A>
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>    $Apache::GTopLimit::CHECK_EVERY_N_REQUESTS = 2;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   This will only check the process size every other time the process size
   checker is called.
   
  -<P><A NAME="anchor33"></A>
  +<P>
   This module was written in response to questions on the mod_perl mailing
   list on how to tell the httpd process to exit if:
   
   <UL>
   <P><LI>
  -<P><A NAME="anchor34"></A>
  +<P>
   its memory size goes beyond a specified limit
   
   <P><LI>
  -<P><A NAME="anchor35"></A>
  +<P>
   its shared memory size goes below a specified limit
   
   </UL>
  -<P><A NAME="anchor36"></A>
  +<P>
   Note: This module will run on platforms supported by <STRONG>GTop.pm</STRONG> a Perl interface to libgtop (which of course needs <STRONG>libgtop</STRONG> : See <A
   HREF="http://home-of-linux.org/gnome/libgtop/">http://home-of-linux.org/gnome/libgtop/</A>
   ).
   
  -<P><A NAME="anchor37"></A>
  +<P>
   Referer to the <CODE>Apache::GTopLimit</CODE> manpage for more information.
   
  -<P><A NAME="anchor38"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H1><A NAME="Apache_Request_libapreq_Gen">Apache::Request (libapreq) - Generic Apache Request Library</A></H1></CENTER>
  -<P><A NAME="anchor39"></A>
  +<P>
   This package contains modules for manipulating client request data via the
   Apache API with Perl and C. Functionality includes:
   
  -<P><A NAME="anchor40"></A>
  +<P>
   - parsing of application/x-www-form-urlencoded data
   
  -<P><A NAME="anchor41"></A>
  +<P>
   - parsing of multipart/form-data
   
  -<P><A NAME="anchor42"></A>
  +<P>
   - parsing of HTTP Cookies
   
  -<P><A NAME="anchor43"></A>
  +<P>
   The Perl modules are simply a thin xs layer on top of libapreq, making them
   a lighter and faster alternative to CGI.pm and CGI::Cookie. See the <CODE>Apache::Request</CODE> and <CODE>Apache::Cookie</CODE> documentation for more details and eg/perl/ for examples.
   
  -<P><A NAME="anchor44"></A>
  +<P>
   <CODE>Apache::Request</CODE> and libapreq are tied tightly to the Apache API, to which there is no
   access in a process running under mod_cgi.
   
  -<P><A NAME="anchor45"></A>
  +<P>
   (<A HREF="././download.html#Apache_Request">Apache::Request</A>)
   
  -<P><A NAME="anchor46"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H1><A NAME="Apache_RequestNotes_Allow_Eas">Apache::RequestNotes - Allow Easy, Consistent Access to Cookie and Form Data Across Each Request Phase</A></H1></CENTER>
  -<P><A NAME="anchor47"></A>
  +<P>
   <CODE>Apache::RequestNotes</CODE> provides a simple interface allowing all phases of the request cycle access
   to cookie or form input parameters in a consistent manner. Behind the
   scenes, it uses libapreq
   <A HREF="././modules.html#Apache_Request_libapreq_Gen">Apache::Request</A>&gt;) functions to parse request data and puts references to the data in
   pnotes.
   
  -<P><A NAME="anchor48"></A>
  +<P>
   Once the request is past the PerlInit phase, all other phases can have
   access to form input and cookie data without parsing it themselves. This
   relieves some strain, especially when the GET or POST data is required by
   numerous handlers along the way.
   
  -<P><A NAME="anchor49"></A>
  +<P>
   See the <CODE>Apache::RequestNotes</CODE> manpage for more information.
   
  -<P><A NAME="anchor50"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H1><A NAME="Apache_PerlRun_Run_unaltered_">Apache::PerlRun - Run unaltered CGI scripts under mod_perl</A></H1></CENTER>
  -<P><A NAME="anchor51"></A>
  +<P>
   See <A HREF="././porting.html#Apache_PerlRun_a_closer_look">Apache::PerlRun - a closer look</A>.
   
  -<P><A NAME="anchor52"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H1><A NAME="Apache_RegistryNG_Apache_Re">Apache::RegistryNG -- Apache::Registry New Generation</A></H1></CENTER>
  -<P><A NAME="anchor53"></A>
  +<P>
   <CODE>Apache::RegistryNG</CODE> is the same as <CODE>Apache::Registry</CODE>, aside from using filename instead of URI for the namespace. It also uses
   an Object Oriented interface.
  +
  +<P>
   
  -<P><A NAME="anchor54"></A>
  -<PRE>  PerlModule Apache::RegistryNG
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  PerlModule Apache::RegistryNG
     &lt;Location /perl&gt;
       SetHandler perl-script
       PerlHandler ApacheRegistryNG-&gt;handler
  -  &lt;/Location&gt;
  -</PRE>
  -<P><A NAME="anchor55"></A>
  +  &lt;/Location&gt;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   <CODE>Apache::RegistryNG</CODE> inherits from <CODE>Apache::PerlRun</CODE>, but the <CODE>handler()</CODE> is overriden. Aside from the
   <CODE>handler(),</CODE> the rest of
   <CODE>Apache::PerlRun</CODE> contains all the functionality of
   <CODE>Apache::Registry</CODE> broken down into several subclass-able methods. These methods are used by <CODE>Apache::RegistryNG</CODE> to implement the exact same functionality of <CODE>Apache::Registry</CODE>, using the
   <CODE>Apache::PerlRun</CODE> methods.
   
  -<P><A NAME="anchor56"></A>
  +<P>
   There is no compelling reason to use <CODE>Apache::RegistryNG</CODE> over
   <CODE>Apache::Registry</CODE>, unless you want to do add or change the functionality of the existing <EM>Registry.pm</EM>. For example,
   <CODE>Apache::RegistryBB</CODE> (Bare-Bones) is another subclass that skips the <CODE>stat()</CODE> call
   performed by <CODE>Apache::Registry</CODE> on each request.
   
  -<P><A NAME="anchor57"></A>
  +<P>
   One situation where <CODE>Apache::RegistryNG</CODE> may definitely be required is if you are rewriting URIs (using either
   mod_rewrite or your own handler) in certain ways.
   
  -<P><A NAME="anchor58"></A>
  +<P>
   For instance if you have a rewrite rule of the form:
  +
  +<P>
   
  -<P><A NAME="anchor59"></A>
  -<PRE>  XYZ123456.html  ==&gt; /perl/foo.pl?p1=XYZ&amp;p2=123456
  -</PRE>
  -<P><A NAME="anchor60"></A>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  XYZ123456.html  ==&gt; /perl/foo.pl?p1=XYZ&amp;p2=123456</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   <CODE>Apache::Registry</CODE> loses big, as it recompiles <EM>foo.pl</EM> for each unique URL -- <CODE>Apache::RegistryNG</CODE> should be used instead.
   
  -<P><A NAME="anchor61"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H1><A NAME="Apache_RegistryBB_Apache_Re">Apache::RegistryBB -- Apache::Registry Bare Bones</A></H1></CENTER>
  -<P><A NAME="anchor62"></A>
  +<P>
   It works just like <CODE>Apache::Registry</CODE>, but does not test the x bit (-x) only compiles the file once (no
   <CODE>stat()</CODE> call is made per requsest), skips the OPT_EXECCGI
   checks and does not <A HREF="#item_chdir">chdir()</A> into the script parent directory. It uses the Object Oriented interface.
   
  -<P><A NAME="anchor63"></A>
  +<P>
   Configuration:
  +
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
   
  -<P><A NAME="anchor64"></A>
  -<PRE>  PerlModule Apache::RegistryBB
  +	<td>
  +	  <pre>  PerlModule Apache::RegistryBB
     &lt;Location /perl&gt;
       SetHandler perl-script
       PerlHandler ApacheRegistryBB-&gt;handler
  -  &lt;/Location&gt;
  -</PRE>
  -<P><A NAME="anchor65"></A>
  +  &lt;/Location&gt;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   See <A HREF="././modules.html#Apache_RegistryNG_Apache_Re">Apache::RegistryNG</A> for more info.
  +
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
  +<CENTER><H1><A NAME="Apache_OutputChain_Chain_Sta">Apache::OutputChain -- Chain Stacked Perl Handlers</A></H1></CENTER>
  +<P>
  +Apache::OutputChain was written as a way of exploring the possibilities of
  +stacked handlers in mod_perl. It ties STDOUT to an object which catches the
  +output and makes it easy to build a chain of modules that work on output
  +data stream.
  +
  +<P>
  +Examples of modules that are build on this idea are
  +<CODE>Apache::SSIChain</CODE>, <CODE>Apache::GzipChain</CODE> and <CODE>Apache::EmbperlChain</CODE>
  +-- the first processes the SSI's in the stream, the second compresses the
  +output on the fly, the last adds Embperl processing.
  +
  +<P>
  +The syntax goes like this:
  +
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  &lt;Files *.html&gt;
  +    SetHandler perl-script
  +    PerlHandler Apache::OutputChain Apache::SSIChain Apache::PassHtml
  +  &lt;/Files&gt;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +The modules are listed in the reverse order of their execution -- here the <CODE>Apache::PassHtml</CODE> module simply picks a file's content and sends it to STDOUT ... then it's
  +processed by <CODE>Apache::SSIChain</CODE>, which sends its output to STDOUT again ... then it's processed by
  +<CODE>Apache::OutputChain</CODE>, which finally sends the result to the browser.
  +
  +<P>
  +An alternative to this approach is <CODE>Apache::Filter</CODE>, which has a more natural ``forward'' configuration order and is easier to
  +interface with other modules.
  +
  +<P>
  +It works with <CODE>Apache::Registry</CODE> as well, for example:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor66"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  Alias /foo /home/httpd/perl/foo
  +  &lt;Location /foo&gt;
  +    SetHandler &quot;perl-script&quot;
  +    Options +ExecCGI
  +    PerlHandler Apache::OutputChain Apache::GzipChain Apache::Registry
  +  &lt;/Location&gt;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +It's really a regular <CODE>Apache::Registry</CODE> setup, except for the added modules in the PerlHandler line.
  +
  +<P>
  +(<A HREF="././modules.html#Apache_GzipChain_compress_HTM">Apache::GzipChain</A> allows to compress the output on the fly.)
  +
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H1><A NAME="Apache_GzipChain_compress_HTM">Apache::GzipChain - compress HTML (or anything) in the OutputChain</A></H1></CENTER>
  -<P><A NAME="anchor67"></A>
  +<P>
   Have you ever served a huge HTML file (e.g. a file bloated with JavaScript
   code) and wondered how could you send it compressed, thus dramatically
   cutting down the download times? After all java applets can be compressed
  @@ -401,110 +723,228 @@
   same with a plain ASCII (HTML, JS etc.)? ASCII text can often be compressed
   by a factor of 10. 
   
  -<P><A NAME="anchor68"></A>
  +<P>
   <CODE>Apache::GzipChain</CODE> comes to help you with this task. If a client (browser) understands <CODE>gzip</CODE> encoding, this module compresses the output and sends it downstream. The
   client decompresses the data upon receipt and renders the HTML as if it
   were fetching plain HTML.
   
  -<P><A NAME="anchor69"></A>
  +<P>
   For example to compress all html files on the fly, do this:
  +
  +<P>
   
  -<P><A NAME="anchor70"></A>
  -<PRE>  &lt;Files *.html&gt;
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  &lt;Files *.html&gt;
       SetHandler perl-script
       PerlHandler Apache::OutputChain Apache::GzipChain Apache::PassFile
  -  &lt;/Files&gt;
  -</PRE>
  -<P><A NAME="anchor71"></A>
  +  &lt;/Files&gt;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Remember that it will work only if the browser claims to accept compressed
   input, by setting the <CODE>Accept-Encoding</CODE> header.  
   <CODE>Apache::GzipChain</CODE> keeps a list of user-agents, thus it also looks at the <CODE>User-Agent</CODE> header to check for browsers known to accept compressed output.
   
  -<P><A NAME="anchor72"></A>
  +<P>
   For example if you want to return compressed files which will in addition
   pass through the Embperl module, you would write:
  +
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
   
  -<P><A NAME="anchor73"></A>
  -<PRE>  &lt;Location /test&gt;
  +	<td>
  +	  <pre>  &lt;Location /test&gt;
       SetHandler perl-script
       PerlHandler Apache::OutputChain Apache::GzipChain Apache::EmbperlChain Apache::PassFile
  -  &lt;/Location&gt;
  -</PRE>
  -<P><A NAME="anchor74"></A>
  +  &lt;/Location&gt;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Hint: Watch the <CODE>access_log</CODE> file to see how many bytes were actually sent, and compare that with the
   bytes sent using a regular configuration.
   
  -<P><A NAME="anchor75"></A>
  +<P>
   (See also <CODE>perldoc Apache::GzipChain</CODE>).
   
  -<P><A NAME="anchor76"></A>
  +<P>
   Notice that the rightmost PerlHandler must be a content producer. Here we
   are using <CODE>Apache::PassFile</CODE> but you can use any module which creates output.
   
  -<P><A NAME="anchor77"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<CENTER><H1><A NAME="Apache_OutputChain_Chain_Sta">Apache::OutputChain -- Chain Stacked Perl Handlers</A></H1></CENTER>
  -<P><A NAME="anchor78"></A>
  -Apache::OutputChain was written as a way of exploring the possibilities of
  -stacked handlers in mod_perl. It ties STDOUT to an object which catches the
  -output and makes it easy to build a chain of modules that work on output
  -data stream.
  -
  -<P><A NAME="anchor79"></A>
  -Examples of modules that are build on this idea are
  -<CODE>Apache::SSIChain</CODE>, <CODE>Apache::GzipChain</CODE> and <CODE>Apache::EmbperlChain</CODE>
  --- the first processes the SSI's in the stream, the second compresses the
  -output on the fly, the last adds Embperl processing.
  -
  -<P><A NAME="anchor80"></A>
  -The syntax goes like this:
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
  +<CENTER><H1><A NAME="Apache_Filter_Alter_the_outpu">Apache::Filter - Alter the output of previous handlers</A></H1></CENTER>
  +<P>
  +META: to be written (actually summarized the info from Apache::Filter
  +manpage)
   
  -<P><A NAME="anchor81"></A>
  -<PRE>  &lt;Files *.html&gt;
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
  +<CENTER><H1><A NAME="Apache_Gzip_Auto_compress_web">Apache::Gzip - Auto-compress web files with Gzip</A></H1></CENTER>
  +<P>
  +Similar to <A HREF="././modules.html#Apache_GzipChain_compress_HTM">Apache::GzipChain</A>
  +but works with <CODE>Apache::Filter</CODE>.
  +
  +<P>
  +This configuration:
  +
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  PerlModule Apache::Filter
  +  &lt;Files ~ &quot;*\.html&quot;&gt;
       SetHandler perl-script
  -    PerlHandler Apache::OutputChain Apache::SSIChain Apache::PassHtml
  -  &lt;/Files&gt;
  -</PRE>
  -<P><A NAME="anchor82"></A>
  -The modules are listed in the reverse order of their execution -- here the <CODE>Apache::PassHtml</CODE> module simply picks a file's content and sends it to STDOUT ... then it's
  -processed by <CODE>Apache::SSIChain</CODE>, which sends its output to STDOUT again ... then it's processed by
  -<CODE>Apache::OutputChain</CODE>, which finally sends the result to the browser.
  -
  -<P><A NAME="anchor83"></A>
  -An alternative to this approach is <CODE>Apache::Filter</CODE>, which has a more natural ``forward'' configuration order and is easier to
  -interface with other modules.
  -
  -<P><A NAME="anchor84"></A>
  -It works with <CODE>Apache::Registry</CODE> as well, for example:
  -
  -<P><A NAME="anchor85"></A>
  -<PRE>  Alias /foo /home/httpd/perl/foo
  -  &lt;Location /foo&gt;
  -    SetHandler &quot;perl-script&quot;
  -    Options +ExecCGI
  -    PerlHandler Apache::OutputChain Apache::GzipChain Apache::Registry
  -  &lt;/Location&gt;
  -</PRE>
  -<P><A NAME="anchor86"></A>
  -It's really a regular <CODE>Apache::Registry</CODE> setup, except for the added modules in the PerlHandler line.
  +    PerlSetVar Filter On
  +    PerlHandler Apache::Gzip
  +  &lt;/Files&gt;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +will send all the <EM>*.html</EM> files compressed if the client accepts the compressed input.
  +
  +<P>
  +And this one:
  +
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  PerlModule Apache::Filter
  +  Alias /home/http/perl /perl
  +  &lt;Location /perl&gt;
  +    SetHandler perl-script
  +    PerlSetVar Filter On
  +    PerlHandler Apache::RegistryFilter Apache::Gzip
  +  &lt;/Location&gt;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +Will compess the output of the <CODE>Apache::Registry</CODE> scripts. Yes, you should write <CODE>Apache::RegistryFilter</CODE> and not <CODE>Apache::Registry</CODE>.
  +
  +<P>
  +You can put as many filters as you want:
  +
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  PerlModule Apache::Filter
  +  &lt;Files ~ &quot;*\.blah&quot;&gt;
  +    SetHandler perl-script
  +    PerlSetVar Filter On
  +    PerlHandler Filter1 Filter2 Apache::Gzip
  +  &lt;/Files&gt;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +You can test that it works by either looking at the size of the respond at <EM>access.log</EM> or by telnet:
  +
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  telnet localhost 8000
  +  Trying 127.0.0.1
  +  Connected to 127.0.0.1
  +  Escape character is '^]'.
  +  GET /perl/test.pl HTTP 1.1
  +  Accept-Encoding: gzip
  +  User-Agent: Mozilla</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +And you will get the data compressed if configured correctly.
   
  -<P><A NAME="anchor87"></A>
  -(<A HREF="././modules.html#Apache_GzipChain_compress_HTM">Apache::GzipChain</A> allows to compress the output on the fly.)
  +<P>
  +META: what the full mime type for gzip?
   
  -<P><A NAME="anchor88"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H1><A NAME="Apache_PerlVINC_set_a_differe">Apache::PerlVINC - set a different @INC perl-location</A></H1></CENTER>
  -<P><A NAME="anchor89"></A>
  +<P>
   With this module you can configure <CODE>@INC</CODE> and have modules reloaded for a given <CODE>Location</CODE>. Suppose two versions of <CODE>Apache::Status</CODE>
   are being hacked on the same server, this fixup handler will simply
   <CODE>delete $INC{ $filename }</CODE>, unshift the preferred <CODE>PerlINC</CODE> path into
   <CODE>@INC</CODE>, and reload the file with <CODE>require()</CODE>:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor90"></A>
  -<PRE>  PerlModule Apache::PerlVINC
  -</PRE>
  -<P><A NAME="anchor91"></A>
  -<PRE>  &lt;Location /dougm-status&gt;
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  PerlModule Apache::PerlVINC</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  &lt;Location /dougm-status&gt;
       SetHandler perl-script
       PerlHandler Apache::Status
     
  @@ -512,10 +952,22 @@
       PerlVersionINC On
       PerlFixupHandler Apache::PerlVINC
       PerlRequire Apache/Status.pm
  -  &lt;/Location&gt;
  -</PRE>
  -<P><A NAME="anchor92"></A>
  -<PRE>  &lt;Location /other-status&gt;
  +  &lt;/Location&gt;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  &lt;Location /other-status&gt;
       SetHandler perl-script
       PerlHandler Apache::Status
     
  @@ -523,83 +975,158 @@
       PerlVersionINC On
       PerlFixupHandler Apache::PerlVINC
       PerlRequire Apache/Status.pm
  -  &lt;/Location&gt;
  -</PRE>
  -<P><A NAME="anchor93"></A>
  +  &lt;/Location&gt;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   It's important to be aware that a changed <CODE>@INC</CODE> is effective only inside the <CODE>&lt;Location&gt;</CODE> or a similar configuration directive.
   <CODE>Apache::PerlVINC</CODE> subclasses the <CODE>PerlRequire</CODE> directive, marking the file to be reloaded by the fixup handler, using the
   value of
   <CODE>PerlINC</CODE> for <CODE>@INC</CODE>. That's local to the fixup handler, so you won't actually see <CODE>@INC</CODE> changed in your script.
   
  -<P><A NAME="anchor94"></A>
  +<P>
   To address possible issues of namespace clashes during reload, the handler
   could call <CODE>$r-&gt;child_terminate()</CODE> so the next server to load the different versions will have a fresh
   namespace. This is not a good idea in a high load environment, of course.
   
  -<P><A NAME="anchor95"></A>
  +<P>
   If you can't find it on CPAN, get it at: <A
   HREF="http://perl.apache.org/~dougm/Apache-PerlVINC-0.01.tar.gz">http://perl.apache.org/~dougm/Apache-PerlVINC-0.01.tar.gz</A>
   
   
  -<P><A NAME="anchor96"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H1><A NAME="Apache_LogSTDERR">Apache::LogSTDERR</A></H1></CENTER>
  -<P><A NAME="anchor97"></A>
  +<P>
   When Apache's builtin syslog support is used, the stderr stream is
   redirected to <CODE>/dev/null</CODE>. This means that Perl warnings, any messages from <CODE>die()</CODE>, <CODE>croak()</CODE>, etc., will also end up in the black hole. The <EM>HookStderr</EM> directive will hook the stderr stream to a file of your choice, the default
   is shown in this example:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor98"></A>
  -<PRE> PerlModule Apache::LogSTDERR
  - HookStderr logs/stderr_log
  -</PRE>
  -<P><A NAME="anchor99"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre> PerlModule Apache::LogSTDERR
  + HookStderr logs/stderr_log</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H1><A NAME="Apache_RedirectLogFix">Apache::RedirectLogFix</A></H1></CENTER>
  -<P><A NAME="anchor100"></A>
  +<P>
   Because of the way mod_perl handles redirects, the status code is not
   properly logged. The <CODE>Apache::RedirectLogFix</CODE> module works around that bug until mod_perl can deal with this. All you
   have to do is to enable it in the <EM>httpd.conf</EM> file.
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor101"></A>
  -<PRE>  PerlLogHandler Apache::RedirectLogFix
  -</PRE>
  -<P><A NAME="anchor102"></A>
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  PerlLogHandler Apache::RedirectLogFix</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   For example, you will have to use it when doing:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor103"></A>
  -<PRE>  $r-&gt;status(304);
  -</PRE>
  -<P><A NAME="anchor104"></A>
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  $r-&gt;status(304);</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   and do some manual header sending, like this:
   
  -<P><A NAME="anchor105"></A>
  -<PRE>  $r-&gt;status(304);
  -  $r-&gt;send_http_header();
  -</PRE>
  -<P><A NAME="anchor106"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  $r-&gt;status(304);
  +  $r-&gt;send_http_header();</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H1><A NAME="Apache_SubProcess">Apache::SubProcess</A></H1></CENTER>
  -<P><A NAME="anchor107"></A>
  +<P>
   The output of <CODE>system()</CODE>, <CODE>exec()</CODE>, and <CODE>open(PIPE,&quot;|program&quot;)</CODE> calls will not be sent to the browser unless your Perl was configured with
   <CODE>sfio</CODE>.
   
  -<P><A NAME="anchor108"></A>
  +<P>
   One workaround is to use backticks:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor109"></A>
  -<PRE>  print `command here`;
  -</PRE>
  -<P><A NAME="anchor110"></A>
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  print `command here`;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   But a cleaner solution is provided by the <CODE>Apache::SubProcess</CODE>
   module. It overrides the <CODE>exec()</CODE> and <CODE>system()</CODE>
   calls with calls that work correctly under mod_perl.
   
  -<P><A NAME="anchor111"></A>
  +<P>
   Let's see a few examples:
   
  -<P><A NAME="anchor112"></A>
  -<PRE>  use strict;
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  use strict;
     use Apache::SubProcess qw(system exec);
     
     my $r = shift;
  @@ -654,60 +1181,89 @@
     # --------------------
     #!/usr/bin/perl 
     #read STDIN, $buf, $ENV{CONTENT_LENGTH}; 
  -  #print &quot;STDIN: `$buf' ($ENV{CONTENT_LENGTH})\n&quot;;
  -</PRE>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -	     The <a href="http://www.modperl.com/">
  -	     <B>Writing Apache Modules with Perl and C</B></a>
  -	     book can be purchased online from <a
  -	     href="http://www.ora.com/catalog/wrapmod/">O'Reilly </a>
  -	     and <a
  -	     href="http://www.amazon.com/exec/obidos/ASIN/156592567X/writinapachemodu">
  -	     Amazon.com</a>.
  +  #print &quot;STDIN: `$buf' ($ENV{CONTENT_LENGTH})\n&quot;;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    [ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   
  -	     <HR>
   
  -	     <B>Your corrections of either technical or grammatical
  +    <p>
  +    <div class="navbar">
  +      <a href="browserbugs.html">Prev</a>                                 |
  +      <A HREF="index.html"         >Contents</A> |
  +      <A HREF="index.html#search"  >Search</A>   |
  +      <A HREF="index.html#download">Download</A> |
  +      <a href="snippets.html">Next</a>
  +    </div>
  +    <p>
  +
  +    <table width="60%" align="center">
  +
  +      <tr>
  +	<td>
  +	  <div class="notice">
  +	  <B>Your corrections of the technical and grammatical
   	     errors are very welcome. You are encouraged to help me
  -	     to improve this guide.  If you have something to
  -	     contribute please <A
  -	     HREF="help.html#Contacting_me"> send it
  +	     improve this guide.  If you have something to contribute
  +	     please <A HREF="help.html#Contacting_me"> send it
   	     directly to me</A>.</B>
  +	  </div>
  +	</td>
  +      </tr>
  +
  +      <tr>
  +	<td>
  +	  <div class="ad">
  +	    The <a href="http://www.modperl.com/">
  +	      <B>Writing Apache Modules with Perl and C</B></a>
  +	    book can be purchased online from <a
  +	      href="http://www.ora.com/catalog/wrapmod/">O'Reilly </a>
  +	    and <a
  +	    href="http://www.amazon.com/exec/obidos/ASIN/156592567X/writinapachemodu">
  +	      Amazon.com</a>.
  +	  </div>
  +	</td>
  +      </tr>
  +
  +</table>
  +
  +<center>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
  +<table cellspacing=2 cellpadding=2>
  +
  +<tr align=center valign=top>
  +<td align=center valign=center>
  +
  +<b><font size=-1>Written by <a
  +href="help.html#Contacting_me">Stas Bekman</a>.<br> Last Modified at 06/01/2000
  +</font></b>
  +<br>
  +
  +</td>
  +
  +<td>
  +
  +<a href="http://perl.apache.org"><img src="images/mod_perl2.jpg"  border=0 alt="mod_perl icon" border=0 height=59 width=150></a>
  +<br>
  +
  +</td>
  +
  +<td>
  +
  +<font size=-2>Use of the Camel for Perl is <br>
  +a trademark of <a href="http://www.ora.com">O'Reilly &amp; Associates</a>,<br>
  +and is used by permission. </font> 
  +<br>
   
  -	     <HR>
  +</td>
   
  -	     [    <A HREF="browserbugs.html">Prev</A> |      <A HREF="index.html">Main Page</A> | <A HREF="snippets.html">Next</A>      ]
  +</tr>
  +</table>
  +</center>
   
  -<CENTER><TABLE CELLSPACING=2 CELLPADDING=2 WIDTH="100%" >
  -<TR ALIGN=CENTER VALIGN=TOP>
  -  <TD ALIGN=CENTER VALIGN=CENTER COLSPAN="3">
  -	     <HR>
  -  </TD>
  -</TR>
  -<TR ALIGN=CENTER VALIGN=TOP>
  -  <TD ALIGN=CENTER VALIGN=CENTER>
  -    <B>
  -      <FONT SIZE=-1>
  -	     Written by <A HREF="help.html#Contacting_me">Stas Bekman</A>.
  -	     <BR>Last Modified at 05/09/2000
  -      </FONT>
  -    </B>
  -  </TD>
  -
  -  <TD>
  -	     <A HREF="http://perl.apache.org"><IMG SRC="images/mod_perl2.jpg" ALT="Mod Perl Icon" BORDER=0 HEIGHT=59 WIDTH=150></A>
  -  </TD>
  -
  -  <TD>
  -    <FONT SIZE=-2>
  -	     Use of the Camel for Perl is <BR>
  -	     a trademark of <A HREF="http://www.ora.com">O'Reilly &amp; Associates</A>,<BR>
  -             and is used by permission. 
  -    </FONT> 
  -  </TD>
  -</TR>
  -</TABLE></CENTER>
  -
  -</BODY>
  -</HTML>
  -	    
  \ No newline at end of file
  +</body>
  +</html>
  
  
  
  1.14      +231 -144  modperl-site/guide/multiuser.html
  
  Index: multiuser.html
  ===================================================================
  RCS file: /home/cvs/modperl-site/guide/multiuser.html,v
  retrieving revision 1.13
  retrieving revision 1.14
  diff -u -r1.13 -r1.14
  --- multiuser.html	2000/05/12 22:42:54	1.13
  +++ multiuser.html	2000/06/07 22:45:35	1.14
  @@ -1,70 +1,94 @@
   <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
  -<HTML>
  -<HEAD>
  -   <TITLE>mod_perl guide: mod_perl for ISPs. mod_perl and Virtual Hosts</TITLE>
  -   <META NAME="GENERATOR" CONTENT="Pod2HTML [Perl/Linux]">
  -   <META NAME="Author" CONTENT="Stas Bekman">
  -   <META NAME="Description" CONTENT="All Apache/Perl related information: Hints, Guidelines, Scenarios and Troubleshottings">
  -   <META NAME="keywords" CONTENT="mod_perl modperl perl apache cgi webserver speed  fast guide mod_perl apache guide help info faq mod_perl installation cgi troubleshooting help no sex speedup free open source OSS mod_perl apache guide">
  -</HEAD>
  -     <LINK REL=STYLESHEET TYPE="text/css"
  -        HREF="style.css" TITLE="refstyle">
  -     <style type="text/css">
  -     <!-- 
  -        @import url(style.css);
  -     -->
  -     
  -     </style>
  -<BODY BGCOLOR="white">
  +<html>
  +  <head>
  +   <title>mod_perl guide: mod_perl for ISPs. mod_perl and Virtual Hosts</title>
  +   <meta name="Author" content="Stas Bekman">
  +   <meta name="Description" content="All Apache/Perl related information: Hints, Guidelines, Scenarios and Troubleshottings">
  +   <meta name="keywords" content="mod_perl modperl perl cgi apache webserver speed fast guide mod_perl apache guide help info faq mod_perl installation cgi troubleshooting help no sex speedup free open source OSS mod_perl apache guide">
  +   <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
  +   <meta name="Classification" content="information">
  +   <link href="style.css" rel=stylesheet type="text/css" title="refstyle">
  +  </head>
  +  <body>
  +
  +    <h1 align=center>
  +      <a href="http://perl.apache.org"><img src="images/mod_perl.gif" alt="Mod Perl Icon" border=0 height=30 width=90 align=left></a>
  +      <a href="http://perl.apache.org"><img src="images/mod_perl.gif" alt="Mod Perl Icon" border=0 height=30 width=90 align=right></a>
  +      mod_perl for ISPs. mod_perl and Virtual Hosts
  +    </h1>
  +    <hr>
  +    <p>
  +    <div class="navbar">
  +      <a href="dbm.html">Prev</a>                                 |
  +      <a href="index.html"         >Contents</a> |
  +      <a href="index.html#search"  >Search</a>   |
  +      <a href="index.html#download">Download</a> |
  +      <a href="debug.html">Next</a>
  +    </div>
  +    <p>
  +
  +    <div class="toc">
  +      
   <A NAME="toc"></A>
  -<H1 ALIGN=CENTER>
  -<A HREF="http://perl.apache.org"><IMG SRC="images/mod_perl.gif" ALT="Mod Perl Icon" BORDER=0 HEIGHT=30 WIDTH=90 ALIGN=LEFT></A>
  -<A HREF="http://perl.apache.org"><IMG SRC="images/mod_perl.gif" ALT="Mod Perl Icon" BORDER=0 HEIGHT=30 WIDTH=90 ALIGN=RIGHT></A>
  -mod_perl for ISPs. mod_perl and Virtual Hosts</H1>
  -<HR WIDTH="100%">
  -	    [    <A HREF="dbm.html">Prev</A> |      <A HREF="index.html">Main Page</A> | <A HREF="debug.html">Next</A>      ]<HR><!-- INDEX BEGIN -->
  -<P><B><FONT SIZE=-1>Table of Contents:</FONT></B></P>
  +<P><B>Table of Contents:</B></P>
  +
   <UL>
   
   	<LI><A HREF="#ISPs_providing_mod_perl_services">ISPs providing mod_perl services - a fantasy or a reality</A>
   	<LI><A HREF="#Virtual_Hosts_in_the_guide">Virtual Hosts in the guide</A>
   </UL>
  -<!-- INDEX END -->
   
  +    </div>
  +
  +    [ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
   <HR>
  +    <table width="60%" align="center">
  +
  +      <tr>
  +	<td>
  +	  <div class="ad">
  +	    The <a href="http://www.modperl.com/">
  +	      <B>Writing Apache Modules with Perl and C</B></a>
  +	    book can be purchased online from <a
  +	      href="http://www.ora.com/catalog/wrapmod/">O'Reilly </a>
  +	    and <a
  +	    href="http://www.amazon.com/exec/obidos/ASIN/156592567X/writinapachemodu">
  +	      Amazon.com</a>.
  +	  </div>
  +	</td>
  +      </tr>
  +
  +      <tr>
  +	<td>
  +	  <div class="notice">
  +	  <B>Your corrections of the technical and grammatical
  +	     errors are very welcome. You are encouraged to help me
  +	     improve this guide.  If you have something to contribute
  +	     please <A HREF="help.html#Contacting_me"> send it
  +	     directly to me</A>.</B>
  +	  </div>
  +	</td>
  +      </tr>
  +
  +</table>
   
  -	     The <a href="http://www.modperl.com/">
  -	     <B>Writing Apache Modules with Perl and C</B></a>
  -	     book can be purchased online from <a
  -	     href="http://www.ora.com/catalog/wrapmod/">O'Reilly </a>
  -	     and <a
  -	     href="http://www.amazon.com/exec/obidos/ASIN/156592567X/writinapachemodu">
  -	     Amazon.com</a>.
  -
  -	     <HR>
  -
  -	       <B>Your corrections of either technical or grammatical
  -	       errors are very welcome. You are encouraged to help me
  -	       to improve this guide.  If you have something to
  -	       contribute please <A
  -	       HREF="help.html#Contacting_me"> send it
  -	       directly to me</A>.
  -	       </B>
  -	       <HR>
  +    
   
  -	      <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<P><A NAME="anchor0"></A>
  +	    [ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
  +
  +<P>
   <CENTER><H1><A NAME="ISPs_providing_mod_perl_services">ISPs providing mod_perl services - a fantasy or a reality</A></H1></CENTER>
   <UL>
   <P><LI>
  -<P><A NAME="anchor1"></A>
  +<P>
   You installed mod_perl on your box at home, and you fell in love with it.
   So now you want to convert your CGI scripts (which currently are running on
   your favorite ISPs machine) to run under mod_perl. Then you discover that
   your ISP has never heard of mod_perl, or he refuses to install it for you.
   
   <P><LI>
  -<P><A NAME="anchor2"></A>
  +<P>
   You are an old sailor in the ISP business, you have seen it all, you know
   how many ISPs are out there and you know that the sales margins are too low
   to keep you happy. You are looking for some new service almost noone else
  @@ -72,41 +96,41 @@
   have a bigger slice of the action than your competitors.
   
   </UL>
  -<P><A NAME="anchor3"></A>
  +<P>
   If you are a user asking for a mod_perl service or an ISP considering to
   provide this service, this section should make things clear for both of
   you.
   
  -<P><A NAME="anchor4"></A>
  +<P>
   An ISP has three choices:
   
   <OL>
   <P><LI>
  -<P><A NAME="anchor5"></A>
  +<P>
   ISPs probably cannot let users run scripts under mod_perl on the main
   server. There are many reasons for this:
   
  -<P><A NAME="anchor6"></A>
  +<P>
   Scripts might leak memory, due to sloppy programming. There will not be
   enough memory to run as many servers as required, and clients will be not
   satisfied with the service because it will be slower.
   
  -<P><A NAME="anchor7"></A>
  +<P>
   The question of file permissions is a very important issue: any user who is
   allowed to write and run a CGI script can at least read (if not write) any
   other files that belong to the same user and/or group the web server is
   running as. Note that <A HREF="././install.html#Is_it_possible_to_run_mod_perl_e">it's impossible to run <CODE>suEXEC</CODE> and <CODE>cgiwrap</CODE> extensions under mod_perl</A>.
   
  -<P><A NAME="anchor8"></A>
  +<P>
   Another issue is the security of the database connections. If you use
   <CODE>Apache::DBI</CODE>, by hacking the <CODE>Apache::DBI</CODE> code you can pick a connection from the pool of cached connections even if
   it was opened by someone else and your scripts are running on the same web
   server.
   
  -<P><A NAME="anchor9"></A>
  +<P>
   There are many more things to be aware of so at this time you have to say <EM>No</EM>.
   
  -<P><A NAME="anchor10"></A>
  +<P>
   Of course as an ISP you can run mod_perl internally, without allowing your
   users to map their scripts so that they will run under mod_perl. If as a
   part of your service you provide scripts such as guest books, counters etc.
  @@ -114,20 +138,20 @@
   scripts running very fast.
   
   <P><LI>
  -<P><A NAME="anchor11"></A>
  +<P>
   But, hey why can't I let my users run their own servers, so I can wash my
   hands of them and don't have to worry about how dirty and sloppy their code
   is (assuming that the users are running their servers under their own
   usernames, to prevent them from stealing code and data from each other).
   
  -<P><A NAME="anchor12"></A>
  +<P>
   This option is fine as long as you are not concerned about your new systems
   resource requirements. If you have even very limited experience with
   mod_perl, you know that mod_perl enabled Apache servers while freeing up
   your CPU and allowing you to run scripts very much faster, have huge memory
   demands (5-20 times that of plain Apache).
   
  -<P><A NAME="anchor13"></A>
  +<P>
   The size depends on the code length, the sloppiness of the programming,
   possible memory leaks the code might have and all that multiplied by the
   number of children each server spawns. A very simple example: a server,
  @@ -138,41 +162,41 @@
   multiply the average required size by the number of server users you intend
   to have and you will get the total memory requirement.
   
  -<P><A NAME="anchor14"></A>
  +<P>
   Since ISPs never say no, you'd better take the inverse approach - think of
   the largest memory size you can afford then divide it by one user's
   requirements as I have shown in this example, and you will know how many
   mod_perl users you can afford :)
   
  -<P><A NAME="anchor15"></A>
  +<P>
   But you cannot tell how much memory your users may use? Their requirements
   from a single server can be very modest, but do you know how many servers
   they will run? After all, they have full control of
   <EM>httpd.conf</EM> - and it has to be this way, since this is essential for the user running
   mod_perl.
   
  -<P><A NAME="anchor16"></A>
  +<P>
   All this rumbling about memory leads to a single question: is it possible
   to prevent users from using more than X memory? Or another variation of the
   question: assuming you have as much memory as you want, can you charge
   users for their average memory usage?
   
  -<P><A NAME="anchor17"></A>
  +<P>
   If the answer to either of the above questions is <EM>Yes</EM>, you are all set and your clients will prize your name for letting them
   run mod_perl! There are tools to restrict resource usage (see for example
   the man pages for <CODE>ulimit(3)</CODE>, <CODE>getrlimit(2)</CODE>, <CODE>setrlimit(2)</CODE> and
   <CODE>sysconf(3)</CODE> ).
   
  -<P><A NAME="anchor18"></A>
  +<P>
   [ReaderMETA]: If you have experience with other resource limiting
   techniques please share it with us. Thank you!
   
  -<P><A NAME="anchor19"></A>
  +<P>
   If you have chosen this option, you have to provide your client with:
   
   <UL>
   <P><LI>
  -<P><A NAME="anchor20"></A>
  +<P>
   Shutdown and startup scripts installed together with the rest of your
   daemon startup scripts (e.g <CODE>/etc/rc.d</CODE> directory), so that when you reboot your machine the user's server will be
   correctly shutdown and will be back online the moment your system starts
  @@ -180,7 +204,7 @@
   belongs to, or you are going to be in big trouble!
   
   <P><LI>
  -<P><A NAME="anchor21"></A>
  +<P>
   Proxy services (in forward or httpd accelerator mode) for the user's
   virtual host. Since the user will have to run their server on an
   unprivileged port (&gt;1024), you will have to forward all requests from
  @@ -189,25 +213,25 @@
   <CODE>your.machine.ip:port_assigned_to_user</CODE> . You will also have to tell the users to code their scripts so that any
   self referencing URLs are of the form <CODE>user.given.virtual.hostname</CODE>.
   
  -<P><A NAME="anchor22"></A>
  +<P>
   Letting the user run a mod_perl server immediately adds a requirement for
   the user to be able to restart and configure their own server. Only root
   can bind to port 80, this is why your users have to use port numbers
   greater than 1024.
   
  -<P><A NAME="anchor23"></A>
  +<P>
   Another solution would be to use a setuid startup script, but think twice
   before you go with it, since if users can modify the scripts they will get
   a root access. For more information refer to the section ``<A HREF="././control.html#SUID_Start_up_Scripts">SUID Start-up Scripts</A>''.
   
   <P><LI>
  -<P><A NAME="anchor24"></A>
  +<P>
   Another problem you will have to solve is how to assign ports between
   users. Since users can pick any port above 1024 to run their server, you
   will have to lay down some rules here so that multiple servers do not
   conflict.
   
  -<P><A NAME="anchor25"></A>
  +<P>
   A simple example will demonstrate the importance of this problem: I am a
   malicious user or I am just a rival of some fellow who runs his server on
   your ISP. All I need to do is to find out what port my rival's server is
  @@ -217,43 +241,79 @@
   port first, now all requests will be redirected to my server. I'll leave to
   your imagination what nasty things might happen then.
   
  -<P><A NAME="anchor26"></A>
  +<P>
   Of course the ugly things will quickly be revealed, but not before the
   damage has been done.
   
   </UL>
  -<P><A NAME="anchor27"></A>
  +<P>
   Basically you can preassign each user a port, without them having to worry
   about finding a free one, as well as enforce <CODE>MaxClients</CODE> and similar values by implementing the following scenario:
   
  -<P><A NAME="anchor28"></A>
  +<P>
   For each user have two configuration files, the main file,
   <EM>httpd.conf</EM> (non-writable by user) and the user's file,
   <EM>username.httpd.conf</EM> where they can specify their own configuration parameters and override the
   ones defined in <EM>httpd.conf</EM>. Here is what the main configuration file looks like:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor29"></A>
  -<PRE>  httpd.conf
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  httpd.conf
     ----------
     # Global/default settings, the user may override some of these
     ...
     ...
     # Included so that user can set his own configuration
  -  Include username.httpd.conf
  -</PRE>
  -<P><A NAME="anchor30"></A>
  -<PRE>  # User-specific settings which will override any potentially 
  +  Include username.httpd.conf</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  # User-specific settings which will override any potentially 
     # dangerous configuration directives in username.httpd.conf
  -  ...
     ...
  -</PRE>
  -<P><A NAME="anchor31"></A>
  -<PRE>  username.httpd.conf
  +  ...</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  username.httpd.conf
     -------------------
     # Settings that your user would like to add/override,
  -  # like &lt;Location&gt; and PerlModule directives, etc.
  -</PRE>
  -<P><A NAME="anchor32"></A>
  +  # like &lt;Location&gt; and PerlModule directives, etc.</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Apache reads the global/default settings first. Then it reads the
   <EM>Include</EM>'d <EM>username.httpd.conf</EM> file with whatever settings the user has chosen, and finally it reads the
   user-specific settings that we don't want the user to override, such as the
  @@ -261,102 +321,129 @@
   you can use <A HREF="././config.html#Apache_Configuration_in_Perl">Perl sections</A> to make the configuration much easier.
   
   <P><LI>
  -<P><A NAME="anchor33"></A>
  +<P>
   A much better, but costly solution is <EM>co-location</EM>. Let the user hook his (or your) stand-alone machine into your network,
   and forget about this user. Of course either the user or you will have to
   undertake all the system administration chores and it will cost your client
   more money.
   
  -<P><A NAME="anchor34"></A>
  +<P>
   Who are the people who seek mod_perl support? They are people who run
   serious projects/businesses. Money is not usually an obstacle. They can
   afford a stand alone box, thus achieving their goal of autonomy whilst
   keeping their ISP happy.
   
   </OL>
  -<P><A NAME="anchor35"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H1><A NAME="Virtual_Hosts_in_the_guide">Virtual Hosts in the guide</A></H1></CENTER>
  -<P><A NAME="anchor36"></A>
  +<P>
   If you are about to use <EM>Virtual Hosts</EM> you might want to read these sections:
   
  -<P><A NAME="anchor37"></A>
  +<P>
   <A HREF="././config.html#Apache_Configuration_in_Perl">Apache Configuration in Perl</A>
   
   
   
  -<P><A NAME="anchor38"></A>
  +<P>
   <A HREF="././config.html#Configuring_Apache_mod_perl_wi">Easing the Chores of Configuring Virtual Hosts with mod_macro</A>
   
   
   
  -<P><A NAME="anchor39"></A>
  +<P>
   <A HREF="././config.html#Is_There_a_Way_to_Provide_a_Diff">Is There a Way to Provide a Different startup.pl File for Each Individual Virtual Host</A>
   
   
   
  -<P><A NAME="anchor40"></A>
  +<P>
   <A HREF="././config.html#Is_There_a_Way_to_Modify_INC_on">Is There a Way to Modify @INC on a Per-Virtual-Host or Per-Location Basis.</A> 
   
    
   
  -<P><A NAME="anchor41"></A>
  +<P>
   <A HREF="././config.html#A_Script_From_One_Virtual_Host_C">A Script From One Virtual Host Calls a Script with the Same Path From the Other Virtual Host</A>
   
   
   
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -	     The <a href="http://www.modperl.com/">
  -	     <B>Writing Apache Modules with Perl and C</B></a>
  -	     book can be purchased online from <a
  -	     href="http://www.ora.com/catalog/wrapmod/">O'Reilly </a>
  -	     and <a
  -	     href="http://www.amazon.com/exec/obidos/ASIN/156592567X/writinapachemodu">
  -	     Amazon.com</a>.
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   
  -	     <HR>
   
  -	     <B>Your corrections of either technical or grammatical
  +    <p>
  +    <div class="navbar">
  +      <a href="dbm.html">Prev</a>                                 |
  +      <A HREF="index.html"         >Contents</A> |
  +      <A HREF="index.html#search"  >Search</A>   |
  +      <A HREF="index.html#download">Download</A> |
  +      <a href="debug.html">Next</a>
  +    </div>
  +    <p>
  +
  +    <table width="60%" align="center">
  +
  +      <tr>
  +	<td>
  +	  <div class="notice">
  +	  <B>Your corrections of the technical and grammatical
   	     errors are very welcome. You are encouraged to help me
  -	     to improve this guide.  If you have something to
  -	     contribute please <A
  -	     HREF="help.html#Contacting_me"> send it
  +	     improve this guide.  If you have something to contribute
  +	     please <A HREF="help.html#Contacting_me"> send it
   	     directly to me</A>.</B>
  +	  </div>
  +	</td>
  +      </tr>
  +
  +      <tr>
  +	<td>
  +	  <div class="ad">
  +	    The <a href="http://www.modperl.com/">
  +	      <B>Writing Apache Modules with Perl and C</B></a>
  +	    book can be purchased online from <a
  +	      href="http://www.ora.com/catalog/wrapmod/">O'Reilly </a>
  +	    and <a
  +	    href="http://www.amazon.com/exec/obidos/ASIN/156592567X/writinapachemodu">
  +	      Amazon.com</a>.
  +	  </div>
  +	</td>
  +      </tr>
  +
  +</table>
  +
  +<center>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
  +<table cellspacing=2 cellpadding=2>
  +
  +<tr align=center valign=top>
  +<td align=center valign=center>
  +
  +<b><font size=-1>Written by <a
  +href="help.html#Contacting_me">Stas Bekman</a>.<br> Last Modified at 05/27/2000
  +</font></b>
  +<br>
  +
  +</td>
  +
  +<td>
  +
  +<a href="http://perl.apache.org"><img src="images/mod_perl2.jpg"  border=0 alt="mod_perl icon" border=0 height=59 width=150></a>
  +<br>
  +
  +</td>
  +
  +<td>
  +
  +<font size=-2>Use of the Camel for Perl is <br>
  +a trademark of <a href="http://www.ora.com">O'Reilly &amp; Associates</a>,<br>
  +and is used by permission. </font> 
  +<br>
   
  -	     <HR>
  +</td>
   
  -	     [    <A HREF="dbm.html">Prev</A> |      <A HREF="index.html">Main Page</A> | <A HREF="debug.html">Next</A>      ]
  +</tr>
  +</table>
  +</center>
   
  -<CENTER><TABLE CELLSPACING=2 CELLPADDING=2 WIDTH="100%" >
  -<TR ALIGN=CENTER VALIGN=TOP>
  -  <TD ALIGN=CENTER VALIGN=CENTER COLSPAN="3">
  -	     <HR>
  -  </TD>
  -</TR>
  -<TR ALIGN=CENTER VALIGN=TOP>
  -  <TD ALIGN=CENTER VALIGN=CENTER>
  -    <B>
  -      <FONT SIZE=-1>
  -	     Written by <A HREF="help.html#Contacting_me">Stas Bekman</A>.
  -	     <BR>Last Modified at 05/03/2000
  -      </FONT>
  -    </B>
  -  </TD>
  -
  -  <TD>
  -	     <A HREF="http://perl.apache.org"><IMG SRC="images/mod_perl2.jpg" ALT="Mod Perl Icon" BORDER=0 HEIGHT=59 WIDTH=150></A>
  -  </TD>
  -
  -  <TD>
  -    <FONT SIZE=-2>
  -	     Use of the Camel for Perl is <BR>
  -	     a trademark of <A HREF="http://www.ora.com">O'Reilly &amp; Associates</A>,<BR>
  -             and is used by permission. 
  -    </FONT> 
  -  </TD>
  -</TR>
  -</TABLE></CENTER>
  -
  -</BODY>
  -</HTML>
  -	    
  \ No newline at end of file
  +</body>
  +</html>
  
  
  
  1.27      +6293 -2234modperl-site/guide/performance.html
  
  Index: performance.html
  ===================================================================
  RCS file: /home/cvs/modperl-site/guide/performance.html,v
  retrieving revision 1.26
  retrieving revision 1.27
  diff -u -r1.26 -r1.27
  --- performance.html	2000/05/12 22:42:54	1.26
  +++ performance.html	2000/06/07 22:45:35	1.27
  @@ -1,29 +1,37 @@
   <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
  -<HTML>
  -<HEAD>
  -   <TITLE>mod_perl guide: Performance Tuning</TITLE>
  -   <META NAME="GENERATOR" CONTENT="Pod2HTML [Perl/Linux]">
  -   <META NAME="Author" CONTENT="Stas Bekman">
  -   <META NAME="Description" CONTENT="All Apache/Perl related information: Hints, Guidelines, Scenarios and Troubleshottings">
  -   <META NAME="keywords" CONTENT="mod_perl modperl perl apache cgi webserver speed  fast guide mod_perl apache guide help info faq mod_perl installation cgi troubleshooting help no sex speedup free open source OSS mod_perl apache guide">
  -</HEAD>
  -     <LINK REL=STYLESHEET TYPE="text/css"
  -        HREF="style.css" TITLE="refstyle">
  -     <style type="text/css">
  -     <!-- 
  -        @import url(style.css);
  -     -->
  -     
  -     </style>
  -<BODY BGCOLOR="white">
  +<html>
  +  <head>
  +   <title>mod_perl guide: Performance Tuning</title>
  +   <meta name="Author" content="Stas Bekman">
  +   <meta name="Description" content="All Apache/Perl related information: Hints, Guidelines, Scenarios and Troubleshottings">
  +   <meta name="keywords" content="mod_perl modperl perl cgi apache webserver speed fast guide mod_perl apache guide help info faq mod_perl installation cgi troubleshooting help no sex speedup free open source OSS mod_perl apache guide">
  +   <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
  +   <meta name="Classification" content="information">
  +   <link href="style.css" rel=stylesheet type="text/css" title="refstyle">
  +  </head>
  +  <body>
  +
  +    <h1 align=center>
  +      <a href="http://perl.apache.org"><img src="images/mod_perl.gif" alt="Mod Perl Icon" border=0 height=30 width=90 align=left></a>
  +      <a href="http://perl.apache.org"><img src="images/mod_perl.gif" alt="Mod Perl Icon" border=0 height=30 width=90 align=right></a>
  +      Performance Tuning
  +    </h1>
  +    <hr>
  +    <p>
  +    <div class="navbar">
  +      <a href="porting.html">Prev</a>                                 |
  +      <a href="index.html"         >Contents</a> |
  +      <a href="index.html#search"  >Search</a>   |
  +      <a href="index.html#download">Download</a> |
  +      <a href="frequent.html">Next</a>
  +    </div>
  +    <p>
  +
  +    <div class="toc">
  +      
   <A NAME="toc"></A>
  -<H1 ALIGN=CENTER>
  -<A HREF="http://perl.apache.org"><IMG SRC="images/mod_perl.gif" ALT="Mod Perl Icon" BORDER=0 HEIGHT=30 WIDTH=90 ALIGN=LEFT></A>
  -<A HREF="http://perl.apache.org"><IMG SRC="images/mod_perl.gif" ALT="Mod Perl Icon" BORDER=0 HEIGHT=30 WIDTH=90 ALIGN=RIGHT></A>
  -Performance Tuning</H1>
  -<HR WIDTH="100%">
  -	    [    <A HREF="porting.html">Prev</A> |      <A HREF="index.html">Main Page</A> | <A HREF="frequent.html">Next</A>      ]<HR><!-- INDEX BEGIN -->
  -<P><B><FONT SIZE=-1>Table of Contents:</FONT></B></P>
  +<P><B>Table of Contents:</B></P>
  +
   <UL>
   
   	<LI><A HREF="#The_Big_Picture">The Big Picture</A>
  @@ -58,19 +66,29 @@
   
   			<LI><A HREF="#How_Shared_Is_My_Memory_">How Shared Is My Memory?</A>
   			<LI><A HREF="#Calculating_Real_Memory_Usage">Calculating Real Memory Usage</A>
  -			<LI><A HREF="#Is_my_Code_Shared_">Is my Code Shared?</A>
  -			<LI><A HREF="#Preload_Perl_Modules_at_Server_S">Preload Perl Modules at Server Startup</A>
  -		</UL>
  +			<LI><A HREF="#Are_My_Variables_Shared_">Are My Variables Shared?</A>
  +			<LI><A HREF="#Preloading_Perl_Modules_at_Serve">Preloading Perl Modules at Server Startup</A>
  +			<LI><A HREF="#Preloading_Registry_Scripts_at_S">Preloading Registry Scripts at Server Startup</A>
  +			<LI><A HREF="#Modules_Initializing_at_Server_S">Modules Initializing at Server Startup</A>
  +			<UL>
  +
  +				<LI><A HREF="#Initializing_DBI_pm">Initializing DBI.pm</A>
  +				<LI><A HREF="#Initializing_CGI_pm">Initializing CGI.pm</A>
  +			</UL>
   
  -		<LI><A HREF="#Preload_Perl_modules_Real_Numb">Preload Perl modules - Real Numbers</A>
  -		<UL>
  -
  -			<LI><A HREF="#Preload_Registry_Scripts">Preload Registry Scripts</A>
   		</UL>
   
   		<LI><A HREF="#Memory_Swapping_is_Considered_Ba">Memory Swapping is Considered Bad</A>
   		<LI><A HREF="#Increasing_Shared_Memory_With_me">Increasing Shared Memory With mergemem</A>
   		<LI><A HREF="#Forking_and_Executing_Subprocess">Forking and Executing Subprocesses from mod_perl</A>
  +		<UL>
  +
  +			<LI><A HREF="#Spawning_a_Detachable_Sub_Proces">Spawning a Detachable Sub-Process</A>
  +			<LI><A HREF="#Gory_Details_About_fork_">Gory Details About fork()</A>
  +			<LI><A HREF="#Executing_system_in_the_Right_">Executing system() in the Right Way</A>
  +			<LI><A HREF="#Avoiding_Zombie_Processes">Avoiding Zombie Processes</A>
  +		</UL>
  +
   		<LI><A HREF="#OS_Specific_Parameters_for_Proxy">OS Specific Parameters for Proxying</A>
   	</UL>
   
  @@ -89,7 +107,7 @@
   		<LI><A HREF="#Reducing_the_Number_of_stat_Ca">Reducing the Number of stat() Calls Made by Apache</A>
   	</UL>
   
  -	<LI><A HREF="#TMTOWTDI_Convenience_and_Perfor">TMTOWTDI: Convenience and Performance</A>
  +	<LI><A HREF="#TMTOWTDI_Convenience_and_Habit_">TMTOWTDI: Convenience and Habit versus Performance</A>
   	<UL>
   
   		<LI><A HREF="#Apache_Registry_versus_pure_Per">Apache::Registry versus pure PerlHandler</A>
  @@ -105,11 +123,6 @@
   		<LI><A HREF="#_Bloatware_modules">&quot;Bloatware&quot; modules</A>
   		<LI><A HREF="#Apache_args_versus_Apache_Requ">Apache::args versus Apache::Request::params</A>
   		<LI><A HREF="#Using_1_Under_mod_perl_and_Be">Using $|=1 Under mod_perl and Better print() Techniques.</A>
  -	</UL>
  -
  -	<LI><A HREF="#Performance_Oriented_Perl_Coding">Performance Oriented Perl Coding</A>
  -	<UL>
  -
   		<LI><A HREF="#Global_vs_Fully_Qualified_Variab">Global vs Fully Qualified Variables </A>
   		<LI><A HREF="#Avoid_Importing_Functions">Avoid Importing Functions</A>
   		<LI><A HREF="#Object_Methods_Calls_Versus_Func">Object Methods Calls Versus Function Calls</A>
  @@ -122,7 +135,7 @@
   
   		<LI><A HREF="#Imported_Symbols_and_Memory_Usag">Imported Symbols and Memory Usage</A>
   		<LI><A HREF="#Concatenation_or_List">Concatenation or List</A>
  -		<LI><A HREF="#Cached_stat_Calls_by_Perl">Cached stat() Calls by Perl</A>
  +		<LI><A HREF="#Using_Perl_stat_Call_s_Cached_">Using Perl stat() Call's Cached Results</A>
   	</UL>
   
   	<LI><A HREF="#Apache_Registry_and_Derivatives">Apache::Registry and Derivatives Specific Notes</A>
  @@ -192,6 +205,12 @@
   		<LI><A HREF="#Upload_Download_of_Big_Files">Upload/Download of Big Files</A>
   	</UL>
   
  +	<LI><A HREF="#Apache_mod_perl_Build_Options">Apache/mod_perl Build Options</A>
  +	<UL>
  +
  +		<LI><A HREF="#mod_perl_Process_Size_as_a_Funct">mod_perl Process Size as a Function of Compiled in C Modules and mod_perl Features</A>
  +	</UL>
  +
   	<LI><A HREF="#Perl_Build_Options">Perl Build Options</A>
   	<UL>
   
  @@ -200,46 +219,62 @@
   	</UL>
   
   </UL>
  -<!-- INDEX END -->
   
  +    </div>
  +
  +    [ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
   <HR>
  +    <table width="60%" align="center">
  +
  +      <tr>
  +	<td>
  +	  <div class="ad">
  +	    The <a href="http://www.modperl.com/">
  +	      <B>Writing Apache Modules with Perl and C</B></a>
  +	    book can be purchased online from <a
  +	      href="http://www.ora.com/catalog/wrapmod/">O'Reilly </a>
  +	    and <a
  +	    href="http://www.amazon.com/exec/obidos/ASIN/156592567X/writinapachemodu">
  +	      Amazon.com</a>.
  +	  </div>
  +	</td>
  +      </tr>
  +
  +      <tr>
  +	<td>
  +	  <div class="notice">
  +	  <B>Your corrections of the technical and grammatical
  +	     errors are very welcome. You are encouraged to help me
  +	     improve this guide.  If you have something to contribute
  +	     please <A HREF="help.html#Contacting_me"> send it
  +	     directly to me</A>.</B>
  +	  </div>
  +	</td>
  +      </tr>
  +
  +</table>
  +
  +    
   
  -	     The <a href="http://www.modperl.com/">
  -	     <B>Writing Apache Modules with Perl and C</B></a>
  -	     book can be purchased online from <a
  -	     href="http://www.ora.com/catalog/wrapmod/">O'Reilly </a>
  -	     and <a
  -	     href="http://www.amazon.com/exec/obidos/ASIN/156592567X/writinapachemodu">
  -	     Amazon.com</a>.
  -
  -	     <HR>
  -
  -	       <B>Your corrections of either technical or grammatical
  -	       errors are very welcome. You are encouraged to help me
  -	       to improve this guide.  If you have something to
  -	       contribute please <A
  -	       HREF="help.html#Contacting_me"> send it
  -	       directly to me</A>.
  -	       </B>
  -	       <HR>
  +	    [ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   
  -	      <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<P><A NAME="anchor0"></A>
  +<P>
   <CENTER><H1><A NAME="The_Big_Picture">The Big Picture</A></H1></CENTER>
  -<P><A NAME="anchor1"></A>
  +<P>
   To make the user's Web browsing experience as painless as possible, every
   effort must be made to wring the last drop of performance from the server.
   There are many factors which affect Web site usability, but speed is one of
   the most important. This applies to any webserver, not just Apache, so it
   is very important that you understand it.
   
  -<P><A NAME="anchor2"></A>
  +<P>
   How do we measure the speed of a server? Since the user (and not the
   computer) is the one that interacts with the Web site, one good speed
   measurement is the time elapsed between the moment when she clicks on a
   link or presses a <EM>Submit</EM> button to the moment when the resulting page is fully rendered.
   
  -<P><A NAME="anchor3"></A>
  +<P>
   The requests and replies are broken into packets. A request may be made up
   of several packets, a reply may be many thousands. Each packet has to make
   its own way from one machine to another, perhaps passing through many
  @@ -247,86 +282,102 @@
   first packet of the request leaves our user's machine to when the last
   packet of the reply arrives back there.
   
  -<P><A NAME="anchor4"></A>
  +<P>
   A webserver is only one of the entities the packets see along their way. If
   we follow them from browser to server and back again, they may travel by
   different routes through many different entities. Before they are processed
   by your server the packets might have to go through proxy (accelerator)
  -servers and if the request contains more than one packet they will all have
  -to wait for the last one so that the full request message can be
  -reassembled at the server. Then the whole process is repeated in reverse.
  +servers and if the request contains more than one packet, packets might
  +arrive to the server by different routes with different arrival times,
  +therefore it's possible that some packets that arrive earlier will have to
  +wait for other packets before they could be reassembled into a chunk of the
  +request message that will be then read by the server. Then the whole
  +process is repeated in reverse.
   
  -<P><A NAME="anchor5"></A>
  +<P>
   You could work hard to fine tune your webserver's performance, but a slow
   Network Interface Card (NIC) or a slow network connection from your server
   might defeat it all. That's why it's important to think about the Big
   Picture and to be aware of possible bottlenecks between the server and the
  -Web. Of course there is little that you can do if the user has a slow
  -connection.
  +Web.
   
  -<P><A NAME="anchor6"></A>
  -You might tune your scripts and webserver to process incoming requests
  -ultra quickly, so you will need only a small number of working servers, but
  -you might find that the server processes are all busy waiting for slow
  -clients to accept their responses. You will see examples of other issues
  -explored in this chapter.
  -
  -<P><A NAME="anchor7"></A>
  -A Web service is like a car, if one of the parts or mechanisms is broken
  -the car may not go smoothly and it can even stop dead if pushed too far
  -without first fixing it.
  +<P>
  +Of course there is little that you can do if the user has a slow
  +connection. You might tune your scripts and webserver to process incoming
  +requests ultra quickly, so you will need only a small number of working
  +servers, but you might find that the server processes are all busy waiting
  +for slow clients to accept their responses.
  +
  +<P>
  +But there are techniques to cope with this. For example you can deliver the
  +respond after it was compressed. If you are delivering a pure text
  +respond--gzip compression will reduce the size of the message by 10 times.
  +
  +<P>
  +You should analyze all the involved components when you try to create the
  +best service for your users, and not the web server or the code that the
  +web server executes. A Web service is like a car, if one of the parts or
  +mechanisms is broken the car may not go smoothly and it can even stop dead
  +if pushed too far without first fixing it.
  +
  +<P>
  +And let me stress it again--If you want to have a success in the web
  +service business you should start worrying about the client's browsing
  +experience and <STRONG>not only</STRONG> how good your code benchmarks are.
   
  -<P><A NAME="anchor8"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H1><A NAME="System_Analysis">System Analysis</A></H1></CENTER>
  -<P><A NAME="anchor9"></A>
  +<P>
   Before we try to solve a problem we need to indentify it. In our case we
   want to get the best performance we can with as little monetary and time
   investment as possible.
   
  -<P><A NAME="anchor10"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="Software_Requirements">Software Requirements</A></H2></CENTER>
  -<P><A NAME="anchor11"></A>
  +<P>
   Covered in the section ``<A HREF="././hardware.html#Choosing_an_Operating_System">Choosing an Operating System</A>''.
   
  -<P><A NAME="anchor12"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="Hardware_Requirements">Hardware Requirements</A></H2></CENTER>
  -<P><A NAME="anchor13"></A>
  +<P>
   (META: Only partial analysis. Please submit more points. Many points are
   scattered around the document and should be gathered here, to represent the
   whole picture. It also should be merged with the above item!)
   
  -<P><A NAME="anchor14"></A>
  +<P>
   You need to analyze all of the problem's dimensions. There are several
   things that need to be considered:
   
   <UL>
   <P><LI>
  -<P><A NAME="anchor15"></A>
  +<P>
   How long does it take to process each request?
   
   <P><LI>
  -<P><A NAME="anchor16"></A>
  +<P>
   How many requests can you process simultaneously?
   
   <P><LI>
  -<P><A NAME="anchor17"></A>
  +<P>
   How many simultaneous requests are you planning to get?
   
   <P><LI>
  -<P><A NAME="anchor18"></A>
  +<P>
   At what rate are you expecting to receive requests?
   
   </UL>
  -<P><A NAME="anchor19"></A>
  +<P>
   The first one is probably the easiest to optimize. Following the
  -performance optimization tips in this and other documents allows a
  -professional perl (mod_perl) programmer to exercise their code and improve
  -it.
  +performance optimization tips in this and other documents allows a perl
  +(mod_perl) programmer to exercise their code and improve it.
   
  -<P><A NAME="anchor20"></A>
  +<P>
   The second one is a function of RAM. How much RAM is in each box, how many
   boxes do you have, and how much RAM does each mod_perl process use?
   Multiply the first two and divide by the third. Ask yourself whether it is
  @@ -334,44 +385,46 @@
   whether that will actually cost more than throwing another powerful machine
   into the rack.
   
  -<P><A NAME="anchor21"></A>
  +<P>
   Also ask yourself whether switching to another language will even help. In
   some applications, for example to link Oracle runtime libraries, a huge
   chunk of memory is needed so you would save nothing even if you switched
   from Perl to C.
   
  -<P><A NAME="anchor22"></A>
  -The last one is important. You need a realistic estimate. Are you really
  +<P>
  +The last two are important. You need a realistic estimate. Are you really
   expecting 8 million hits per day? What is the expected peak load, and what
   kind of response time do you need to guarantee? Remember that these numbers
   might change drastically when you apply code changes and your site becomes
   popular. Remember that when you get a very high hit rate, the resource
   requirements don't grow linearly but exponentially!
   
  -<P><A NAME="anchor23"></A>
  +<P>
   More coverage is provided in the section ``<A HREF="././hardware.html#Choosing_Hardware">Choosing Hardware</A>''.
   
  -<P><A NAME="anchor24"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H1><A NAME="Essential_Tools">Essential Tools</A></H1></CENTER>
  -<P><A NAME="anchor25"></A>
  +<P>
   In order to improve performance we need measurement tools. The main tool
   categories are benchmarking and code profiling.
   
  -<P><A NAME="anchor26"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="Benchmarking_Applications">Benchmarking Applications</A></H2></CENTER>
  -<P><A NAME="anchor27"></A>
  +<P>
   How much faster is mod_perl than mod_cgi (aka plain perl/CGI)? There are
   many ways to benchmark the two. I'll present a few examples and numbers
   below. Check out the <CODE>benchmark</CODE> directory of the mod_perl distribution for more examples.
   
  -<P><A NAME="anchor28"></A>
  +<P>
   If you are going to write your own benchmarking utility, use the
   <CODE>Benchmark</CODE> module for heavy scripts and the <CODE>Time::HiRes</CODE> module for very fast scripts (faster than 1 sec) where you will need better
   time precision.
   
  -<P><A NAME="anchor29"></A>
  +<P>
   There is no need to write a special benchmark though. If you want to
   impress your boss or colleagues, just take some heavy CGI script you have
   (e.g. a script that crunches some data and prints the results to STDOUT),
  @@ -380,21 +433,22 @@
   from the <CODE>LWP</CODE> package to emulate the browser. The <CODE>benchmark</CODE>
   directory of the mod_perl distribution includes such an example.
   
  -<P><A NAME="anchor30"></A>
  +<P>
   See also two tools for benchmarking:
   <A HREF="././performance.html#Tuning_with_ab_ApacheBench">ApacheBench</A> and <A HREF="././performance.html#Tuning_with_the_crashme_Script">crashme test</A>
   
   
   
  -<P><A NAME="anchor31"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H3><A NAME="Developers_Talk">Developers Talk</A></H3></CENTER>
  -<P><A NAME="anchor32"></A>
  +<P>
   Perrin Harkins writes on benchmarks or comparisons, official or unofficial:
   
   <BLOCKQUOTE>
   
  -<P><A NAME="anchor33"></A>
  +<P>
   I have used some of the platforms you mentioned and researched others. What
   I can tell you for sure, is that no commercially available system offers
   the depth, power, and ease of use that mod_perl has. Either they don't let
  @@ -404,14 +458,14 @@
   support available from simply posting a message to [the mod-perl] list, at
   any price.
   
  -<P><A NAME="anchor34"></A>
  +<P>
   As for performance, beyond doing several important things (code-caching,
   pre-forking/threading, and persistent database connections) there isn't
   much these tools can do, and it's mostly in your hands as the developer to
   see that the things which really take the time (like database queries) are
   optimized.
   
  -<P><A NAME="anchor35"></A>
  +<P>
   The downside of all this is that most manager types seem to be unable to
   believe that web development software available for free could be better
   than the stuff that cost $25,000 per CPU. This appears to be the major
  @@ -420,17 +474,17 @@
   literature to your boss, and you end up with an expensive disaster and an
   approaching deadline.
   
  -<P><A NAME="anchor36"></A>
  +<P>
   But I'm not bitter or anything...
   
   </BLOCKQUOTE>
   
  -<P><A NAME="anchor37"></A>
  +<P>
   Jonathan Peterson adds:
   
   <BLOCKQUOTE>
   
  -<P><A NAME="anchor38"></A>
  +<P>
   Most of the major solutions have something that they do better than the
   others, and each of them has faults. Microsoft's ASP has a very nice
   objects model, and has IMO the best data access object (better than DBI to
  @@ -441,44 +495,54 @@
   it's good. Also, it has a compiled scripting language - which is great if
   you aren't selling your clients the source code (and a pain otherwise).
   
  -<P><A NAME="anchor39"></A>
  +<P>
   mod_perl's advantage is that it is the most powerful. It offers the
   greatest degree of control with one of the more powerful languages. It also
   offers the greatest granularity. You can use an embedding module (eg eperl)
   from one place, a session module (Session) from another, and your data
   access module from yet another.
   
  -<P><A NAME="anchor40"></A>
  +<P>
   I think the <CODE>Apache::ASP</CODE> module looks very promising. It has very easy to use and adequately
   powerful state maintenance, a good embedding system, and a sensible object
   model (that emulates the Microsoft ASP one). It doesn't replicate MS's ADO
   for data access, but <CODE>DBI</CODE> is fine for that.
   
  -<P><A NAME="anchor41"></A>
  +<P>
   I have always found that the developers available make the greatest impact
   on the decision. If you have a team with no Perl experience, and a small or
   medium task, using something like PHP, or Microsoft ASP makes more sense
   than driving your staff into the vertical learning curve they'll need to
   use mod_perl.
   
  -<P><A NAME="anchor42"></A>
  +<P>
   For very large jobs, it may be worth finding the best technical solution,
   and then recruiting the team with the necessary skills.
   
   </BLOCKQUOTE>
   
  -<P><A NAME="anchor43"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H3><A NAME="Benchmarking_a_Graphic_Hits_Coun">Benchmarking a Graphic Hits Counter with Persistent DB Connections</A></H3></CENTER>
  -<P><A NAME="anchor44"></A>
  +<P>
   Here are the numbers from Michael Parker's mod_perl presentation at the
   Perl Conference (Aug, 98). (Sorry, there used to be links here to the
   source, but they went dead one day, so I removed them). The script is a
   standard hits counter, but it logs the counts into a mysql relational
   DataBase:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor45"></A>
  -<PRE>    Benchmark: timing 100 iterations of cgi, perl...  [rate 1:28]
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>    Benchmark: timing 100 iterations of cgi, perl...  [rate 1:28]
       
       cgi: 56 secs ( 0.33 usr 0.28 sys = 0.61 cpu) 
       perl: 2 secs ( 0.31 usr 0.27 sys = 0.58 cpu) 
  @@ -491,163 +555,343 @@
       Benchmark: timing 10000 iterations of cgi, perl   [rate 1:21]
        
       cgi: 6494 secs (34.87 usr 26.68 sys = 61.55 cpu) 
  -    perl: 299 secs (32.51 usr 23.98 sys = 56.49 cpu) 
  -</PRE>
  -<P><A NAME="anchor46"></A>
  +    perl: 299 secs (32.51 usr 23.98 sys = 56.49 cpu) </pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   We don't know what server configurations were used for these tests, but I
   guess the numbers speak for themselves.
   
  -<P><A NAME="anchor47"></A>
  +<P>
   The source code of the script was available at <A
   HREF="http://www.realtime.net/~parkerm/perl/conf98/sld006.htm.">http://www.realtime.net/~parkerm/perl/conf98/sld006.htm.</A>
   It's now a dead link. If you know its new location, please let me know.
   
  -<P><A NAME="anchor48"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H3><A NAME="Benchmarking_Scripts_with_Execut">Benchmarking Scripts with Execution Times Below 1 Second</A></H3></CENTER>
  -<P><A NAME="anchor49"></A>
  -If you want to get the benchmark results in micro-seconds and not in the
  -tens of milli-seconds you get with the <CODE>Benchmark</CODE> module, you will have to use the <CODE>Time::HiRes</CODE> module, its usage is similar to
  +<P>
  +If you want to get the benchmark results in micro-seconds you will have to
  +use the <CODE>Time::HiRes</CODE> module, its usage is similar to
   <CODE>Benchmark</CODE>'s.
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor50"></A>
  -<PRE>  use Time::HiRes qw(gettimeofday tv_interval);
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  use Time::HiRes qw(gettimeofday tv_interval);
     my $start_time = [ gettimeofday ];
     sub_that_takes_a_teeny_bit_of_time();
     my $end_time = [ gettimeofday ];
     my $elapsed = tv_interval($start_time,$end_time);
  -  print &quot;The sub took $elapsed seconds.&quot;
  -</PRE>
  -<P><A NAME="anchor51"></A>
  +  print &quot;The sub took $elapsed seconds.&quot;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   See also the <A HREF="././performance.html#Tuning_with_the_crashme_Script">crashme test</A>.
   
  -<P><A NAME="anchor52"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H3><A NAME="Benchmarking_PerlHandlers">Benchmarking PerlHandlers</A></H3></CENTER>
  -<P><A NAME="anchor53"></A>
  +<P>
   The <CODE>Apache::Timeit</CODE> module does <CODE>PerlHandler</CODE> Benchmarking. With the help of this module you can log the time taken to
   process the request, just like you'd use the <CODE>Benchmark</CODE> module to benchmark a regular Perl script. Of course you can extend this
   module to perform more advanced processing like putting the results into a
   database for a later processing. But all it takes is adding this
   configuration directive inside <EM>httpd.conf</EM>:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor54"></A>
  -<PRE>  PerlFixupHandler Apache::Timeit
  -</PRE>
  -<P><A NAME="anchor55"></A>
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  PerlFixupHandler Apache::Timeit</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Since scripts running under <CODE>Apache::Registry</CODE> are running inside the PerlHandler these are benchmarked as well.
   
  -<P><A NAME="anchor56"></A>
  +<P>
   An example of the lines which show up in the <EM>error_log</EM> file:
   
  -<P><A NAME="anchor57"></A>
  -<PRE>  timing request for /perl/setupenvoff.pl:
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  timing request for /perl/setupenvoff.pl:
       0 wallclock secs ( 0.04 usr +  0.01 sys =  0.05 CPU)
     timing request for /perl/setupenvoff.pl:
  -    0 wallclock secs ( 0.03 usr +  0.00 sys =  0.03 CPU)
  -</PRE>
  -<P><A NAME="anchor58"></A>
  +    0 wallclock secs ( 0.03 usr +  0.00 sys =  0.03 CPU)</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   The <CODE>Apache::Timeit</CODE> package is a part of the <EM>Apache-Perl-contrib</EM>
   files collection available from CPAN.
   
  -<P><A NAME="anchor59"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="Code_Profiling_Techniques">Code Profiling Techniques</A></H2></CENTER>
  -<P><A NAME="anchor60"></A>
  +<P>
   The profiling process helps you to determine which subroutines or just
   snippets of code take the longest time to execute and which subroutines are
   called most often. Probably you will want to optimize those.
   
  -<P><A NAME="anchor61"></A>
  -Let's write some code to mess with:
  +<P>
  +When do you need to profile your code? You do that when you suspect that
  +some part of your code is called very often and may be there is a need to
  +optimize it to significantly improve the overall performance.
  +
  +<P>
  +For example if you have ever used the <CODE>diagnostics</CODE> pragma, which extends the terse diagnostics normally emitted by both the
  +Perl compiler and the Perl interpreter, augmenting them with the more
  +verbose and endearing descriptions found in the <CODE>perldiag</CODE> manpage. You know that it might tremendously slow you code down, so let's
  +first prove that it is correct.
  +
  +<P>
  +We will run a benchmark, once with diagnostics enabled and once disabled,
  +on a subroutine called <EM>test_code</EM>.
  +
  +<P>
  +The code inside the subroutine does an arithmetic and a numeric comparison
  +of two strings. It assigns one string to another if the condition tests
  +true but the condition always tests false. To demonstrate the <CODE>diagnostics</CODE> overhead the comparison operator is intentionally <EM>wrong</EM>. It should be a string comparison, not a numeric one.
  +
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
   
  -<P><A NAME="anchor62"></A>
  -META: build a hash and sort it by value, key... then rewrite the comparison
  -subroutine to use the Shwartzian transform.. and more
  -
  -<P><A NAME="anchor63"></A>
  -Think about some more web oriented examples...!
  -
  -<P><A NAME="anchor64"></A>
  -<PRE>  map {push @list, int rand(100)} (1..1000);
  -</PRE>
  -<P><A NAME="anchor65"></A>
  -<PRE>  sub mysort {
  -    map ...
  -  }
  -</PRE>
  -<P><A NAME="anchor66"></A>
  -META: remove all the diagnostics section below it's irrelevant here. (just
  -reuse the explanations)
  -
  -<P><A NAME="anchor67"></A>
  -In the <A HREF="././debug.html#diagnostics_pragma">diagnostics pragma</A> section, I showed that leaving it in production code is a bad idea, as it
  -significantly slows down the execution time. We verified that by using the <CODE>Benchmark</CODE> module. Now let's see how to use a profiler to find what subroutine <CODE>diagnostics</CODE> spends most of its time in. Once we know it could be a good idea to
  -optimize this part of the code. We won't optimize the code here as this is
  -beyond the scope of this document - and since this is a core Perl module,
  -the chances are that it's already fairly well optimized.
  -
  -<P><A NAME="anchor68"></A>
  -We can use <CODE>Devel::DProf</CODE> to help us. Let's use this code:
  +	<td>
  +	  <pre>  use Benchmark;
  +  use diagnostics;
  +  use strict;
  +  
  +  my $count = 50000;
  +  
  +  disable diagnostics;
  +  my $t1 = timeit($count,\&amp;test_code);
  +  
  +  enable  diagnostics;
  +  my $t2 = timeit($count,\&amp;test_code);
  +  
  +  print &quot;Off: &quot;,timestr($t1),&quot;\n&quot;;
  +  print &quot;On : &quot;,timestr($t2),&quot;\n&quot;;
  +  
  +  sub test_code{
  +    my ($a,$b) = qw(foo bar);
  +    my $c;
  +    if ($a == $b) {
  +      $c = $a;
  +    }
  +  }</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +For only a few lines of code we get:
  +
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  Off:  1 wallclock secs ( 0.81 usr +  0.00 sys =  0.81 CPU)
  +  On : 13 wallclock secs (12.54 usr +  0.01 sys = 12.55 CPU)</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +With <CODE>diagnostics</CODE> enabled, the subroutine <CODE>test_code()</CODE> is 16 times slower, than
  +with <CODE>diagnostics</CODE> disabled!
  +
  +<P>
  +Now let's fix the comparison the way it should be, by replacing <CODE>==</CODE>
  +with <CODE>eq</CODE>, so we get:
  +
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>    my ($a,$b) = qw(foo bar);
  +    my $c;
  +    if ($a eq $b) {
  +      $c = $a;
  +    }</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +and run the same benchmark again:
  +
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  Off:  1 wallclock secs ( 0.57 usr +  0.00 sys =  0.57 CPU)
  +  On :  1 wallclock secs ( 0.56 usr +  0.00 sys =  0.56 CPU)</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +Now there is no overhead at all. The <CODE>diagnostics</CODE> pragma slows things down only when warnings are generated.
  +
  +<P>
  +After we have verified that using the <CODE>diagnostics</CODE> pragma might adds a big overhead to execution runtime, let's use the code
  +profiling to understand why this happens. We are going to use <CODE>Devel::DProf</CODE> to profile the code. Let's use this code:
  +
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
   
  -<P><A NAME="anchor69"></A>
  -<PRE>  diagnostics.pl
  +	<td>
  +	  <pre>  diagnostics.pl
     --------------
     use diagnostics;
  +  print &quot;Content-type:text/html\n\n&quot;;
     test_code();
     sub test_code{
  -    for my $i (1..10) {
  -      my $j = $i**2;
  -    }
  -    $a = &quot;Hi&quot;; 
  -    $b = &quot;Bye&quot;;
  +    my ($a,$b) = qw(foo bar);
  +    my $c;
       if ($a == $b) {
         $c = $a;
       }
  -  }
  -</PRE>
  -<P><A NAME="anchor70"></A>
  +  }</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Run it with the profiler enabled, and then create the profiling stastics
   with the help of dprofpp:
   
  -<P><A NAME="anchor71"></A>
  -<PRE>  % perl -d:DProf diagnostics.pl
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  % perl -d:DProf diagnostics.pl
     % dprofpp
  -</PRE>
  -<P><A NAME="anchor72"></A>
  -<PRE>  Total Elapsed Time = 0.993458 Seconds
  -    User+System Time = 0.933458 Seconds
  +  
  +  Total Elapsed Time = 0.342236 Seconds
  +    User+System Time = 0.335420 Seconds
     Exclusive Times
     %Time ExclSec CumulS #Calls sec/call Csec/c  Name
  -   81.5   0.761  0.932      1   0.7610 0.9319  main::BEGIN
  -   12.8   0.120  0.101   3161   0.0000 0.0000  diagnostics::unescape
  -   6.43   0.060  0.060      2   0.0300 0.0300  diagnostics::BEGIN
  -   2.14   0.020  0.020      3   0.0067 0.0067  diagnostics::transmo
  -   1.07   0.010  0.010      2   0.0050 0.0050  Config::FETCH
  +   92.1   0.309  0.358      1   0.3089 0.3578  main::BEGIN
  +   14.9   0.050  0.039   3161   0.0000 0.0000  diagnostics::unescape
  +   2.98   0.010  0.010      2   0.0050 0.0050  diagnostics::BEGIN
      0.00   0.000 -0.000      2   0.0000      -  Exporter::import
      0.00   0.000 -0.000      2   0.0000      -  Exporter::export
      0.00   0.000 -0.000      1   0.0000      -  Config::BEGIN
  -   0.00   0.000 -0.000      1   0.0000      -  diagnostics::import
  -   0.00   0.000  0.020      3   0.0000 0.0066  diagnostics::warn_trap
  -   0.00   0.000  0.020      3   0.0000 0.0066  diagnostics::splainthis
      0.00   0.000 -0.000      1   0.0000      -  Config::TIEHASH
  -   0.00   0.000 -0.000      3   0.0000      -  diagnostics::shorten
  -   0.00   0.000 -0.000      3   0.0000      -  diagnostics::autodescribe
  -   0.00   0.000  0.010      1   0.0000 0.0099  main::test_code
  -</PRE>
  -<P><A NAME="anchor73"></A>
  +   0.00   0.000 -0.000      2   0.0000      -  Config::FETCH
  +   0.00   0.000 -0.000      1   0.0000      -  diagnostics::import
  +   0.00   0.000 -0.000      1   0.0000      -  main::test_code
  +   0.00   0.000 -0.000      2   0.0000      -  diagnostics::warn_trap
  +   0.00   0.000 -0.000      2   0.0000      -  diagnostics::splainthis
  +   0.00   0.000 -0.000      2   0.0000      -  diagnostics::transmo
  +   0.00   0.000 -0.000      2   0.0000      -  diagnostics::shorten
  +   0.00   0.000 -0.000      2   0.0000      -  diagnostics::autodescribe</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   It's not easy to see what is responsible for this enormous overhead, even
   if <CODE>main::BEGIN</CODE> seems to be running most of the time. To get the full picture we must see
   the OPs tree, which shows us who calls whom, so we run:
  +
  +<P>
   
  -<P><A NAME="anchor74"></A>
  -<PRE>  % dprofpp -T
  -</PRE>
  -<P><A NAME="anchor75"></A>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  % dprofpp -T</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   and the output is:
  +
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
   
  -<P><A NAME="anchor76"></A>
  -<PRE> main::BEGIN
  +	<td>
  +	  <pre> main::BEGIN
      diagnostics::BEGIN
         Exporter::import
            Exporter::export
  @@ -660,7 +904,7 @@
      Config::FETCH
      diagnostics::unescape
      .....................
  -   B&lt;3159 times [diagnostics::unescape] snipped&gt; .
  +   3159 times [diagnostics::unescape] snipped
      .....................
      diagnostics::unescape
      diagnostics::import
  @@ -679,27 +923,42 @@
         diagnostics::splainthis
            diagnostics::transmo
            diagnostics::shorten
  -        diagnostics::autodescribe
  -</PRE>
  -<P><A NAME="anchor77"></A>
  +        diagnostics::autodescribe</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   So we see that two executions of <CODE>diagnostics::BEGIN</CODE> and 3161 of
   <CODE>diagnostics::unescape</CODE> are responsible for most of the running overhead.
   
  -<P><A NAME="anchor78"></A>
  +<P>
   META: but we see that it might be run only once in mod_perl, so the numbers
   are better. Am I right? check it!
   
  -<P><A NAME="anchor79"></A>
  +<P>
   If we comment out the <CODE>diagnostics</CODE> module, we get:
   
  -<P><A NAME="anchor80"></A>
  -<PRE>  Total Elapsed Time = 0.079974 Seconds
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  Total Elapsed Time = 0.079974 Seconds
       User+System Time = 0.059974 Seconds
     Exclusive Times
     %Time ExclSec CumulS #Calls sec/call Csec/c  Name
  -   0.00   0.000 -0.000      1   0.0000      -  main::test_code
  -</PRE>
  -<P><A NAME="anchor81"></A>
  +   0.00   0.000 -0.000      1   0.0000      -  main::test_code</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   It is possible to profile code running under mod_perl with the
   <CODE>Devel::DProf</CODE> module, available on CPAN. However, you must have apache version 1.3b3 or
   higher and the <CODE>PerlChildExitHandler</CODE> enabled during the httpd build process. When the server is started,
  @@ -707,67 +966,140 @@
   file. This block will be called at server shutdown. Here is how to start
   and stop a server with the profiler enabled:
   
  -<P><A NAME="anchor82"></A>
  -<PRE>  % setenv PERL5OPT -d:DProf
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  % setenv PERL5OPT -d:DProf
     % httpd -X -d `pwd` &amp;
     ... make some requests to the server here ...
     % kill `cat logs/httpd.pid`
     % unsetenv PERL5OPT
  -  % dprofpp
  -</PRE>
  -<P><A NAME="anchor83"></A>
  +  % dprofpp</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   The <CODE>Devel::DProf</CODE> package is a Perl code profiler. It will collect information on the
   execution time of a Perl script and of the subs in that script (remember
   that <CODE>print()</CODE> and <CODE>map()</CODE> are just like any other subroutines you write, but they come bundled with
   Perl!)
   
  -<P><A NAME="anchor84"></A>
  +<P>
   Another approach is to use <CODE>Apache::DProf</CODE>, which hooks
   <CODE>Devel::DProf</CODE> into mod_perl. The <CODE>Apache::DProf</CODE> module will run a
   <CODE>Devel::DProf</CODE> profiler inside each child server and write the
  -<CODE>tmon.out</CODE> file in the directory <CODE>$ServerRoot/logs/dprof/$$</CODE> when the child is shutdown (where <CODE>$$</CODE> is the number of the child process). All it takes is to add to <CODE>httpd.conf</CODE>:
  +<CODE>tmon.out</CODE> file in the directory <CODE>$ServerRoot/logs/dprof/$$</CODE> when the child is shutdown (where <CODE>$$</CODE> is the number of the child process). All it takes is to add to <EM>httpd.conf</EM>:
   
  -<P><A NAME="anchor85"></A>
  -<PRE>  PerlModule Apache::DProf
  -</PRE>
  -<P><A NAME="anchor86"></A>
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  PerlModule Apache::DProf</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Remember that any PerlHandler that was pulled in before
  -<CODE>Apache::DProf</CODE> in the <CODE>httpd.conf</CODE> or <EM>startup.pl</EM>, will not have its code debugging information inserted. To run <CODE>dprofpp</CODE>, chdir to
  +<CODE>Apache::DProf</CODE> in the <EM>httpd.conf</EM> or <EM>startup.pl</EM>, will not have its code debugging information inserted. To run <CODE>dprofpp</CODE>, chdir to
   <CODE>$ServerRoot/logs/dprof/$$</CODE> and run:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor87"></A>
  -<PRE>  % dprofpp
  -</PRE>
  -<P><A NAME="anchor88"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  % dprofpp</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="Measuring_the_Memory_Usage_of_Su">Measuring the Memory Usage of Subroutines</A></H2></CENTER>
  -<P><A NAME="anchor89"></A>
  +<P>
   With help of <CODE>Apache::Status</CODE> you can find out the size of each and every subroutine.
   
   <UL>
   <P><LI><STRONG><A NAME="item_Build">Build and install mod_perl as you always do, make sure it's 
   version 1.22 or higher.</A></STRONG>
   <P><LI><STRONG><A NAME="item_Configure">Configure /perl-status if you haven't already:</A></STRONG>
  -<P><A NAME="anchor90"></A>
  -<PRE>  &lt;Location /perl-status&gt;
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  &lt;Location /perl-status&gt;
       SetHandler perl-script
       PerlHandler Apache::Status
       order deny,allow
       #deny from all
       #allow from ...
  -  &lt;/Location&gt;
  -</PRE>
  -<P><LI><STRONG><A NAME="item_Add">Add to httpd.conf</A></STRONG>
  -<P><A NAME="anchor91"></A>
  -<PRE>  PerlSetVar StatusOptionsAll On
  +  &lt;/Location&gt;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P><LI><STRONG><A NAME="item_Add">Add to httpd.conf</A></STRONG>
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  PerlSetVar StatusOptionsAll On
     PerlSetVar StatusTerse On
     PerlSetVar StatusTerseSize On
  -  PerlSetVar StatusTerseSizeMainSummary On
  -</PRE>
  -<P><A NAME="anchor92"></A>
  -<PRE>  PerlModule B::TerseSize
  -</PRE>
  -<P><LI><STRONG><A NAME="item_Start">Start the server (best in httpd -X mode)</A></STRONG>
  +  PerlSetVar StatusTerseSizeMainSummary On</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  PerlModule B::TerseSize</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P><LI><STRONG><A NAME="item_Start">Start the server (best in httpd -X mode)</A></STRONG>
   <P><LI><STRONG><A NAME="item_From">From your favorite browser fetch http://localhost/perl-status</A></STRONG>
   <P><LI><STRONG><A NAME="item_Click">Click on 'Loaded Modules' or 'Compiled Registry Scripts'</A></STRONG>
   <P><LI><STRONG><A NAME="item_Click">Click on the module or script of your choice (you might need
  @@ -776,54 +1108,111 @@
   <P><LI><STRONG><A NAME="item_Click">Click on 'Memory Usage' at the bottom</A></STRONG>
   <P><LI><STRONG><A NAME="item_You">You should see all the subroutines and their respective sizes.</A></STRONG>
   </UL>
  -<P><A NAME="anchor93"></A>
  +<P>
   Now you can start to optimize your code. Or test which of the several
   implementations is of the least size.
   
  -<P><A NAME="anchor94"></A>
  +<P>
   For example let's compare <CODE>CGI.pm</CODE>'s OO vs procedural interfaces:
   
  -<P><A NAME="anchor95"></A>
  +<P>
   As you will see below the first OO script uses about 2k bytes while the
   second script (procedural interface) uses about 5k.
   
  -<P><A NAME="anchor96"></A>
  +<P>
   Here are the code examples and the numbers:
   
   <OL>
   <P><LI>
  -<P><A NAME="anchor97"></A>
  -<PRE>  cgi_oo.pl
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  cgi_oo.pl
     ---------
     use CGI ();
     my $q = CGI-&gt;new;
     print $q-&gt;header;
  -  print $q-&gt;b(&quot;Hello&quot;);
  -</PRE>
  -<P><LI>
  -<P><A NAME="anchor98"></A>
  -<PRE>  cgi_mtd.pl
  +  print $q-&gt;b(&quot;Hello&quot;);</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P><LI>
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  cgi_mtd.pl
     ---------
     use CGI qw(header b);
     print header();
  -  print b(&quot;Hello&quot;);
  -</PRE>
  -</OL>
  -<P><A NAME="anchor99"></A>
  +  print b(&quot;Hello&quot;);</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    </OL>
  +<P>
   After executing each script in single server mode (-X) the results are:
   
   <OL>
  -<P><LI>
  -<P><A NAME="anchor100"></A>
  -<PRE>  Totals: 1966 bytes | 27 OPs
  -</PRE>
  -<P><A NAME="anchor101"></A>
  -<PRE>  handler 1514 bytes | 27 OPs
  -  exit     116 bytes |  0 OPs
  -</PRE>
   <P><LI>
  -<P><A NAME="anchor102"></A>
  -<PRE>  Totals: 4710 bytes | 19 OPs
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  Totals: 1966 bytes | 27 OPs</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  handler 1514 bytes | 27 OPs
  +  exit     116 bytes |  0 OPs</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P><LI>
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  Totals: 4710 bytes | 19 OPs
     
     handler  1117 bytes | 19 OPs
     basefont  120 bytes |  0 OPs
  @@ -852,10 +1241,13 @@
     td        114 bytes |  0 OPs
     Tr        114 bytes |  0 OPs
     th        114 bytes |  0 OPs
  -  b         113 bytes |  0 OPs
  -</PRE>
  -</OL>
  -<P><A NAME="anchor103"></A>
  +  b         113 bytes |  0 OPs</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    </OL>
  +<P>
   Note, that the above is correct if you didn't precompile all
   <CODE>CGI.pm</CODE>'s methods at server startup. Since if you did, the procedural interface in
   the second test will take up to 18k and not 5k as we saw. That's because
  @@ -863,79 +1255,141 @@
   it doesn't really matter whether you attempt to import only the symbols
   that you need. So if you have:
   
  -<P><A NAME="anchor104"></A>
  -<PRE>  use CGI  qw(-compile :all);
  -</PRE>
  -<P><A NAME="anchor105"></A>
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  use CGI  qw(-compile :all);</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   in the server startup script. Having:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor106"></A>
  -<PRE>  use CGI qw(header);
  -</PRE>
  -<P><A NAME="anchor107"></A>
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  use CGI qw(header);</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   or
   
  -<P><A NAME="anchor108"></A>
  -<PRE>  use CGI qw(:all);
  -</PRE>
  -<P><A NAME="anchor109"></A>
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  use CGI qw(:all);</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   is essentially the same. You will have all the symbols precompiled at
   startup imported even if you ask for only one symbol. It seems to me like a
   bug, but probably that's how <CODE>CGI.pm</CODE> works.
   
  -<P><A NAME="anchor110"></A>
  +<P>
   BTW, you can check the number of opcodes in the code by a simple command
   line run. For example comparing 'my&nbsp;%hash' vs 'my&nbsp;%hash&nbsp;=
   ()'.
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor111"></A>
  -<PRE>  % perl -MO=Terse -e 'my %hash' | wc -l
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  % perl -MO=Terse -e 'my %hash' | wc -l
     -e syntax OK
  -      4
  -</PRE>
  -<P><A NAME="anchor112"></A>
  -<PRE>  % perl -MO=Terse -e 'my %hash = ()' | wc -l
  +      4</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  % perl -MO=Terse -e 'my %hash = ()' | wc -l
     -e syntax OK
  -     10
  -</PRE>
  -<P><A NAME="anchor113"></A>
  +     10</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   The first one has less opcodes.
   
  -<P><A NAME="anchor114"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H1><A NAME="Know_Your_Operating_System">Know Your Operating System</A></H1></CENTER>
  -<P><A NAME="anchor115"></A>
  +<P>
   In order to get the best performance it helps to get intimately familiar
   with the Operating System (OS) the web server is running on. There are many
   OS specific things that you may be able to optimise which will improve your
   web server's speed, reliability and security.
   
  -<P><A NAME="anchor116"></A>
  +<P>
   The following sections will unveal some of the most important details you
   should know about your OS.
   
  -<P><A NAME="anchor117"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="Sharing_Memory">Sharing Memory</A></H2></CENTER>
  -<P><A NAME="anchor118"></A>
  +<P>
   The sharing of memory is one very important factor. If your OS supports it
   (and most sane systems do), you might save memory by sharing it between
   child processes. This is only possible when you preload code at server
   startup. However, during a child process' life its memory pages tend to
   become unshared.
   
  -<P><A NAME="anchor119"></A>
  +<P>
   There is no way we can make Perl allocate memory so that (dynamic)
   variables land on different memory pages from constants, so the
   <STRONG>copy-on-write</STRONG> effect (we will explain this in a moment) will hit you almost at random.
   
  -<P><A NAME="anchor120"></A>
  +<P>
   If you are pre-loading many modules you might be able to trade off the
   memory that stays shared against the time for an occasional fork by tuning <CODE>MaxRequestsPerChild</CODE>. Each time a child reaches this upper limit and dies it should release its
   unshared pages. The new child which replaces it will share its fresh pages
   until it scribbles on them.
   
  -<P><A NAME="anchor121"></A>
  +<P>
   The ideal is a point where your processes usually restart before too much
   memory becomes unshared. You should take some measurements to see if it
   makes a real difference, and to find the range of reasonable values. If you
  @@ -943,18 +1397,18 @@
   <CODE>MaxRequestsPerChild</CODE> will probably be peculiar to your situation and may change with changing
   circumstances.
   
  -<P><A NAME="anchor122"></A>
  +<P>
   It is very important to understand that your goal is not to have
   <CODE>MaxRequestsPerChild</CODE> to be 10000. Having a child serving 300 requests on precompiled code is
   already a huge overall speedup, so if it is 100 or 10000 it probably does
   not really matter if you can save RAM by using a lower value.
   
  -<P><A NAME="anchor123"></A>
  +<P>
   Do not forget that if you preload most of your code at server startup, the
  -fork to spawn a new child will be very very fast, because it inherits most
  -of the preloaded code and the perl interpreter from the parent process.
  +newly forked child gets ready very very fast, because it inherits most of
  +the preloaded code and the perl interpreter from the parent process.
   
  -<P><A NAME="anchor124"></A>
  +<P>
   During the life of the child its memory pages (which aren't really its own
   to start with, it uses the parent's pages) gradually get `dirty' -
   variables which were originally inherited and shared are updated or
  @@ -962,180 +1416,328 @@
   the memory requirement. Killing the child and spawning a new one allows the
   new child to get back to the pristine shared memory of the parent process.
   
  -<P><A NAME="anchor125"></A>
  +<P>
   The recommendation is that <CODE>MaxRequestsPerChild</CODE> should not be too large, otherwise you lose some of the benefit of sharing
   memory.
   
  -<P><A NAME="anchor126"></A>
  +<P>
   See <A HREF="././performance.html#Choosing_MaxRequestsPerChild">Choosing MaxRequestsPerChild</A> for more about tuning the <CODE>MaxRequestsPerChild</CODE> parameter.
   
  -<P><A NAME="anchor127"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H3><A NAME="How_Shared_Is_My_Memory_">How Shared Is My Memory?</A></H3></CENTER>
  -<P><A NAME="anchor128"></A>
  +<P>
   You've probably noticed that the word shared is repeated many times in
   relation to mod_perl. Indeed, shared memory might save you a lot of money,
   since with sharing in place you can run many more servers than without it.
   See <A HREF="././performance.html#Choosing_MaxClients">the Formula and the numbers</A>.
   
  -<P><A NAME="anchor129"></A>
  +<P>
   How much shared memory do you have? You can see it by either using the
   memory utility that comes with your system or you can deploy the
   <CODE>GTop</CODE> module:
  +
  +<P>
   
  -<P><A NAME="anchor130"></A>
  -<PRE>  print &quot;Shared memory of the current process: &quot;,
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  use GTop ();
  +  print &quot;Shared memory of the current process: &quot;,
       GTop-&gt;new-&gt;proc_mem($$)-&gt;share,&quot;\n&quot;;
     
     print &quot;Total shared memory: &quot;,
  -    GTop-&gt;new-&gt;mem-&gt;share,&quot;\n&quot;;
  -</PRE>
  -<P><A NAME="anchor131"></A>
  +    GTop-&gt;new-&gt;mem-&gt;share,&quot;\n&quot;;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   When you watch the output of the <CODE>top</CODE> utility, don't confuse the
   <CODE>RES</CODE> (or <CODE>RSS</CODE>) columns with the <CODE>SHARE</CODE> column.  <CODE>RES</CODE> is RESident memory, which is the size of pages currently swapped in.
   
  -<P><A NAME="anchor132"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H3><A NAME="Calculating_Real_Memory_Usage">Calculating Real Memory Usage</A></H3></CENTER>
  -<P><A NAME="anchor133"></A>
  -You have learned how to measure the size of the process' shared memory, but
  -we still want to know what the real memory usage is. Obviously this cannot
  -be calculated simply by adding up the memory size of each process because
  -that wouldn't account for the shared memory.
  +<P>
  +I have shown how to measure the size of the process' shared memory, but we
  +still want to know what the real memory usage is. Obviously this cannot be
  +calculated simply by adding up the memory size of each process because that
  +wouldn't account for the shared memory.
   
  -<P><A NAME="anchor134"></A>
  +<P>
   On the other hand we cannot just subtract the shared memory size from the
   total size to get the real memory usage numbers, because in reality each
  -process does a different task, therefore the shared memory is not the same
  -for all processes.
  +process has a different history of processed requests, therefore the shared
  +memory is not the same for all processes.
   
  -<P><A NAME="anchor135"></A>
  +<P>
   So how do we measure the real memory size used by the server we run? It's
   probably too difficult to give the exact number, but I've found a way to
   get a fair approximation which was verified in the following way. I have
   calculated the real memory used, by the technique you will see in the
   moment, and then have stopped the Apache server and saw that the memory
   usage report indicated that the total used memory went down by almost the
  -same number I've calculated. Note that some OSes do smart caching so you
  -may not see the memory usage decrease as soon as it actually happens.
  +same number I've calculated. Note that some OSs do smart memory pages
  +caching so you may not see the memory usage decrease as soon as it actually
  +happens when you quit the application.
   
  -<P><A NAME="anchor136"></A>
  +<P>
   This is a technique I've used:
   
   <OL>
   <P><LI>
  -<P><A NAME="anchor137"></A>
  +<P>
   For each process sum up the difference between shared and system memory. To
   calculate a difference for a single process use:
   
  -<P><A NAME="anchor138"></A>
  -<PRE>  use GTop;
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  use GTop;
     my $proc_mem = GTop-&gt;new-&gt;proc_mem($$);
     my $diff     = $proc_mem-&gt;size - $proc_mem-&gt;share;
  -  print &quot;Difference is $diff bytes\n&quot;;
  -</PRE>
  -<P><LI>
  -<P><A NAME="anchor139"></A>
  +  print &quot;Difference is $diff bytes\n&quot;;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P><LI>
  +<P>
   Now if we add the shared memory size of the process with maximum shared
   memory, we will get all the memory that actually is being used by all httpd
   processes, except for the parent process.
   
   <P><LI>
  -<P><A NAME="anchor140"></A>
  +<P>
   Finally, add the size of the parent process.
   
   </OL>
  -<P><A NAME="anchor141"></A>
  +<P>
   Please note that this might be incorrect for your system, so you use this
   number on your own risk.
   
  -<P><A NAME="anchor142"></A>
  +<P>
   I've used this technique to display real memory usage in the module
   <A HREF="././debug.html#Apache_VMonitor_Visual_Syste">Apache::VMonitor</A>, so instead of trying to manually calculate this number you can use this
  -module to do it automatically.
  +module to do it automatically. In fact in the calculations used in this
  +module there is no separation between the parent and child processes, they
  +are all counted indifferently using the following code:
  +
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  use GTop ();
  +  my $gtop = GTop-&gt;new;
  +  my $total_real = 0;
  +  my $max_shared = 0;
  +  # @mod_perl_pids is initialized by Apache::Scoreboard, irrelevant here
  +  my @mod_perl_pids = some_code();
  +  for my $pid (@mod_perl_pids)
  +    my $proc_mem = $gtop-&gt;proc_mem($pid);
  +    my $size     = $proc_mem-&gt;size($pid);
  +    my $share    = $proc_mem-&gt;share($pid);
  +    $total_real += $size - $share;
  +    $max_shared  = $share if $max_shared &lt; $share;
  +  }
  +  my $total_real += $max_shared;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +So as you see we that we accumulate the difference between the shared and
  +reported memory:
  +
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>    $total_real  += $size-$share;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +and at the end add the biggest shared process size:
  +
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  my $total_real += $max_shared;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +So now <CODE>$total_real</CODE> contains approximately the really used memory.
   
  -<P><A NAME="anchor143"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<CENTER><H3><A NAME="Is_my_Code_Shared_">Is my Code Shared?</A></H3></CENTER>
  -<P><A NAME="anchor144"></A>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
  +<CENTER><H3><A NAME="Are_My_Variables_Shared_">Are My Variables Shared?</A></H3></CENTER>
  +<P>
   How do you find out if the code you write is shared between the processes
  -or not? The code should be shared (except where it is on a memory page with
  -variables that change), but some variables are read-only in usage and never
  +or not? The code should be shared, except where it is on a memory page with
  +variables that change. Some variables are read-only in usage and never
   change. For example, if you have some variables that use a lot of memory
   and you want them to be read-only. As you know the variable becomes
   unshared when the process modifies its value.
   
  -<P><A NAME="anchor145"></A>
  +<P>
   So imagine that you have this 10Mb in-memory database that resides in a
   single variable, you perform various operations on it and want to make sure
   that the variable is still shared. For example if you do some matching
  -regex processing on this variable and want to use the <CODE>pos()</CODE>
  -function, will it make the variable unshared or not?
  +regular expression (regex) processing on this variable and want to use the
  +<CODE>pos()</CODE> function, will it make the variable unshared or not?
   
  -<P><A NAME="anchor146"></A>
  -The <CODE>Apache::Peek</CODE> module comes to rescue, let's write a module called <EM>MyShared.pm</EM> which we preload at server startup, so all the variables of this module are
  +<P>
  +The <CODE>Apache::Peek</CODE> module comes to rescue. Let's write a module called <EM>MyShared.pm</EM> which we preload at server startup, so all the variables of this module are
   initially shared by all children.
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor147"></A>
  -<PRE>  MyShared.pm
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  MyShared.pm
     ---------
     package MyShared;
     use Apache::Peek;
     
     my $readonly = &quot;Chris&quot;;
     
  -  sub match{      $readonly =~ /\w/g;                  }
  -  sub print_pos{  print &quot;pos: &quot;, pos($readonly), &quot;\n&quot;; }
  -  sub dump {      Dump($readonly);                     }
  -  1; 
  -</PRE>
  -<P><A NAME="anchor148"></A>
  -This module declares the package, loads the <CODE>Apache::Peek</CODE> module and defines the <CODE>$readonly</CODE> variable which is supposed to be a <EM>big</EM>
  -variable, but we will use a small one to simplify this example. 
  +  sub match    { $readonly =~ /\w/g;               }
  +  sub print_pos{ print &quot;pos: &quot;,pos($readonly),&quot;\n&quot;;}
  +  sub dump     { Dump($readonly);                  }
  +  1;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +This module declares the package <CODE>MyShared</CODE>, loads the
  +<CODE>Apache::Peek</CODE> module and defines the lexically scoped <CODE>$readonly</CODE>
  +variable which is supposed to be a variable of large size (think about a
  +huge hash data structure), but we will use a small one to simplify this
  +example.
   
  -<P><A NAME="anchor149"></A>
  +<P>
   The module also defines three subroutines: <CODE>match()</CODE> that does a
   simple character matching, <CODE>print_pos()</CODE> that prints the current
   position of the matching engine inside the string that was last matched and
   finally the <CODE>dump()</CODE> subroutine that calls the <CODE>Apache::Peek</CODE> module's <CODE>Dump()</CODE> function to dump a raw Perl data-type of the <CODE>$readonly</CODE>
   variable.
   
  -<P><A NAME="anchor150"></A>
  -Now we write the script that prints the PID of the process and calls the
  +<P>
  +Now we write the script that prints the process ID (PID) and calls all
   three functions. The goal is to check whether <CODE>pos()</CODE> makes the
  -variable dirty and therefore unshared.
  +variable <EM>dirty</EM> and therefore unshared.
  +
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
   
  -<P><A NAME="anchor151"></A>
  -<PRE>  share_test.pl
  -  -------
  +	<td>
  +	  <pre>  share_test.pl
  +  -------------
     use MyShared;
     print &quot;Content-type: text/plain\r\n\r\n&quot;;
     print &quot;PID: $$\n&quot;;
     MyShared::match();
     MyShared::print_pos();
  -  MyShared::dump();
  -</PRE>
  -<P><A NAME="anchor152"></A>
  -Before you restart the server in <EM>httpd.conf</EM> set:
  -
  -<P><A NAME="anchor153"></A>
  -<PRE>  MaxClients 2
  -</PRE>
  -<P><A NAME="anchor154"></A>
  +  MyShared::dump();</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +Before you restart the server, in <EM>httpd.conf</EM> set:
  +
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  MaxClients 2</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   for easier tracking. You need at least two servers to compare the print
  -outs of the test program, Having more than two can make the comparison
  +outs of the test program. Having more than two can make the comparison
   process harder.
   
  -<P><A NAME="anchor155"></A>
  +<P>
   Now open two browser windows and issue the request for this script several
   times in both windows, so you get different processes PIDs reported in the
  -two windows and each process has been called a different number of times. 
  +two windows and each process has processed a different number of requests
  +to the <EM>share_test.pl</EM> script.
   
  -<P><A NAME="anchor156"></A>
  +<P>
   In the first window you will see something like that:
   
  -<P><A NAME="anchor157"></A>
  -<PRE>  PID: 27040
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  PID: 27040
     pos: 1
     SV = PVMG(0x853db20) at 0x8250e8c
       REFCNT = 3
  @@ -1148,13 +1750,25 @@
       MAGIC = 0x853dd80
         MG_VIRTUAL = &amp;vtbl_mglob
         MG_TYPE = 'g'
  -      MG_LEN = 1
  -</PRE>
  -<P><A NAME="anchor158"></A>
  +      MG_LEN = 1</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   And in the second window:
  +
  +<P>
   
  -<P><A NAME="anchor159"></A>
  -<PRE>  PID: 27041
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  PID: 27041
     pos: 2
     SV = PVMG(0x853db20) at 0x8250e8c
       REFCNT = 3
  @@ -1167,532 +1781,1580 @@
       MAGIC = 0x853dd80
         MG_VIRTUAL = &amp;vtbl_mglob
         MG_TYPE = 'g'
  -      MG_LEN = 2
  -</PRE>
  -<P><A NAME="anchor160"></A>
  -We see that all the addresses are the same (<CODE>0x8250e8c</CODE> and
  -<CODE>0x8271af0</CODE>), therefore the variable data structure is almost completely shared. The
  -only difference is in <CODE>SV.MAGIC.MG_LEN</CODE>
  -record, which is not shared.
  +      MG_LEN = 2</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +We see that all the addresses of the supposedly big structure are the same
  +(<CODE>0x8250e8c</CODE> and <CODE>0x8271af0</CODE>), therefore the variable data structure is almost completely shared. The
  +only difference is in
  +<CODE>SV.MAGIC.MG_LEN</CODE> record, which is not shared.
   
  -<P><A NAME="anchor161"></A>
  +<P>
   So given that the <CODE>$readonly</CODE> variable is a big one, its value is still shared between the processes,
  -while part of the variable data structure is non-shared but it's almost
  +while part of the variable data structure is non-shared. But it's almost
   insignificant because it takes a very little memory space.
   
  -<P><A NAME="anchor162"></A>
  +<P>
   Now if you need to compare more than variable, doing it by hand can be
   quite time consuming and error prune. Therefore it's better to correct the
   testing script to dump the Perl data-types into files (e.g
   <EM>/tmp/dump.$$</EM>, where <CODE>$$</CODE> is the PID of the process) and then using <CODE>diff(1)</CODE> utility to
   see whether there is some difference.
   
  -<P><A NAME="anchor163"></A>
  -Surely another way of ensuring that a scalar is sharable (i.e. readonly) is
  -to either use the <CODE>constant</CODE> pragma or <CODE>readonly</CODE>
  -pragma.
  -
  -<P><A NAME="anchor164"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<CENTER><H3><A NAME="Preload_Perl_Modules_at_Server_S">Preload Perl Modules at Server Startup</A></H3></CENTER>
  -<P><A NAME="anchor165"></A>
  -Use the <CODE>PerlRequire</CODE> and <CODE>PerlModule</CODE> directives to load commonly used modules such as <CODE>CGI.pm</CODE>, <CODE>DBI</CODE> and etc., when the server is started. On most systems, server children will
  +<P>
  +So correcting the <CODE>dump()</CODE> function to write the info to the
  +file will do the job. Notice that we use <CODE>Devel::Peek</CODE> and not
  +<CODE>Apache::Peek</CODE>. The both are almost the same, but <CODE>Apache::Peek</CODE>
  +prints it output directly to the opened socket so we cannot intercept and
  +redirect the result to the file. Since <CODE>Devel::Peek</CODE> dumps results to the STDERR stream we can use the old trick of saving away
  +the default STDERR handler, and open a new filehandler using the STDERR. In
  +our example when <CODE>Devel::Peek</CODE> now prints to STDERR it actually prints to our file. When we are done, we
  +make sure to restore the original STDERR filehandler. 
  +
  +<P>
  +So this is the resulting code:
  +
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  MyShared2.pm
  +  ---------
  +  package MyShared2;
  +  use Devel::Peek;
  +  
  +  my $readonly = &quot;Chris&quot;;
  +  
  +  sub match    { $readonly =~ /\w/g;               }
  +  sub print_pos{ print &quot;pos: &quot;,pos($readonly),&quot;\n&quot;;}
  +  sub dump{
  +    my $dump_file = &quot;/tmp/dump.$$&quot;;
  +    print &quot;Dumping the data into $dump_file\n&quot;;
  +    open OLDERR, &quot;&gt;&amp;STDERR&quot;;
  +    open STDERR, &quot;&gt;&quot;.$dump_file or die &quot;Can't open $dump_file: $!&quot;;
  +    Dump($readonly);
  +    close STDERR ;
  +    open STDERR, &quot;&gt;&amp;OLDERR&quot;;
  +  }
  +  1;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +When if we modify the code to use the modified module:
  +
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  share_test2.pl
  +  -------------
  +  use MyShared2;
  +  print &quot;Content-type: text/plain\r\n\r\n&quot;;
  +  print &quot;PID: $$\n&quot;;
  +  MyShared2::match();
  +  MyShared2::print_pos();
  +  MyShared2::dump();</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +And run it as before (with MaxClients&nbsp;2), two dump files will be created in the directory <EM>/tmp</EM>. In our test these were created as
  +<EM>/tmp/dump.1224</EM> and <EM>/tmp/dump.1225</EM>. When we run <CODE>diff(1):</CODE>
  +
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  % diff /tmp/dump.1224 /tmp/dump.1225
  +  12c12
  +  &lt;       MG_LEN = 1
  +  ---
  +  &gt;       MG_LEN = 2</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +We see that the two padlists (of the variable <CODE>readonly</CODE>) are different, as we have observed before when we did a manual
  +comparison.
  +
  +<P>
  +In fact we if we think about these results again, we get to a conclusion
  +that there is no need for two processes to find out whether the variable
  +gets modified (and therefore unshared). It's enough to check the
  +datastructure before the script was executed and after that. You can modify
  +the <CODE>MyShared2</CODE> module to dump the padlists into a different file after each invocation and
  +than to run the <CODE>diff(1)</CODE> on the two files.
  +
  +<P>
  +If you want to watch whether some lexically scoped (with <CODE>my())</CODE>
  +variables in your <CODE>Apache::Registry</CODE> script inside the same process get changed between invocations you can use
  +the
  +<CODE>Apache::RegistryLexInfo</CODE> module instead. Since it does exactly this: it makes a snapshot of the
  +padlist before and after the code execution and shows the difference
  +between the two. This specific module was written to work with <CODE>Apache::Registry</CODE> scripts so it won't work for loaded modules. Use the technique we have
  +described above for any type of variables in modules and scripts.
  +
  +<P>
  +Surely another way of ensuring that a scalar is readonly and therefore
  +sharable is to either use the <CODE>constant</CODE> pragma or <CODE>readonly</CODE>
  +pragma. But then you won't be able to make calls that alter the variable
  +even a little, like in the example that we just showed, because it will be
  +a true constant variable and you will get compile time error if you try
  +this:
  +
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  MyConstant.pm
  +  -------------
  +  package MyConstant;
  +  use constant readonly =&gt; &quot;Chris&quot;;
  +  
  +  sub match    { readonly =~ /\w/g;               }
  +  sub print_pos{ print &quot;pos: &quot;,pos(readonly),&quot;\n&quot;;}
  +  1;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  % perl -c MyConstant.pm</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  Can't modify constant item in match position at MyConstant.pm line
  +  5, near &quot;readonly)&quot;
  +  MyConstant.pm had compilation errors.</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +However this code is just right:
  +
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  MyConstant1.pm
  +  -------------
  +  package MyConstant1;
  +  use constant readonly =&gt; &quot;Chris&quot;;
  +  
  +  sub match { readonly =~ /\w/g; }
  +  1;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
  +<CENTER><H3><A NAME="Preloading_Perl_Modules_at_Serve">Preloading Perl Modules at Server Startup</A></H3></CENTER>
  +<P>
  +You can use the <CODE>PerlRequire</CODE> and <CODE>PerlModule</CODE> directives to load commonly used modules such as <CODE>CGI.pm</CODE>, <CODE>DBI</CODE> and etc., when the server is started. On most systems, server children will
   be able to share the code space used by these modules. Just add the
  -following directives into <CODE>httpd.conf</CODE>:
  +following directives into <EM>httpd.conf</EM>:
   
  -<P><A NAME="anchor166"></A>
  -<PRE>  PerlModule CGI
  -  PerlModule DBI
  -</PRE>
  -<P><A NAME="anchor167"></A>
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  PerlModule CGI
  +  PerlModule DBI</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   But an even better approach is to create a separate startup file (where you
   code in plain perl) and put there things like:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor168"></A>
  -<PRE>  use DBI;
  -  use Carp;
  -</PRE>
  -<P><A NAME="anchor169"></A>
  -Then you <CODE>require()</CODE> this startup file in <CODE>httpd.conf</CODE> with the
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  use DBI ();
  +  use Carp ();</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +Don't forget to prevent importing of the symbols exported by default by the
  +module you are going to preload, by placing empty parentheses
  +<CODE>()</CODE> after a module's name. Unless you need some of these in the startup file,
  +which is unlikely. This will save you a few more memory bits.
  +
  +<P>
  +Then you <CODE>require()</CODE> this startup file in <EM>httpd.conf</EM> with the
   <CODE>PerlRequire</CODE> directive, placing it before the rest of the mod_perl configuration
   directives:
  +
  +<P>
   
  -<P><A NAME="anchor170"></A>
  -<PRE>  PerlRequire /path/to/start-up.pl
  -</PRE>
  -<P><A NAME="anchor171"></A>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  PerlRequire /path/to/start-up.pl</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   <CODE>CGI.pm</CODE> is a special case. Ordinarily <CODE>CGI.pm</CODE> autoloads most of its functions on an as-needed basis. This speeds up the
   loading time by deferring the compilation phase. When you use mod_perl,
   FastCGI or another system that uses a persistent Perl interpreter, you will
   want to precompile the functions at initialization time. To accomplish
   this, call the package function <CODE>compile()</CODE> like this:
  +
  +<P>
   
  -<P><A NAME="anchor172"></A>
  -<PRE>    use CGI ();
  -    CGI-&gt;compile(':all');
  -</PRE>
  -<P><A NAME="anchor173"></A>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  use CGI ();
  +  CGI-&gt;compile(':all');</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   The arguments to <CODE>compile()</CODE> are a list of method names or sets, and are identical to those accepted by
   the <CODE>use()</CODE> and <CODE>import()</CODE>
   operators. Note that in most cases you will want to replace <CODE>':all'</CODE>
   with the tag names that you actually use in your code, since generally you
   only use a subset of them.
  +
  +<P>
  +Let's conduct a memory usage test to prove that preloading, reduces memory
  +requirements.
   
  -<P><A NAME="anchor174"></A>
  -You can also preload the Registry scripts. See <A HREF="#Preload_Registry_Scripts">Preload Registry Scripts</A>.
  +<P>
  +In order to have an easy measurement we will use only one child process,
  +therefore we will use this setting:
  +
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  MinSpareServers 1
  +  MaxSpareServers 1
  +  StartServers 1
  +  MaxClients 1
  +  MaxRequestsPerChild 100</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +We are going to use the <CODE>Apache::Registry</CODE> script <EM>memuse.pl</EM> which consists of two parts: the first one preloads a bunch of modules
  +(that most of them aren't going to be used), the second part reports the
  +memory size and the shared memory size used by the single child process
  +that we start. and of course it prints the difference between the two
  +sizes.
  +
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
   
  -<P><A NAME="anchor175"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<CENTER><H2><A NAME="Preload_Perl_modules_Real_Numb">Preload Perl modules - Real Numbers</A></H2></CENTER>
  -<P><A NAME="anchor176"></A>
  -(META: while the numbers and conclusions are mostly correct, need to
  -rewrite the whole benchmark section using the GTop library to report the
  -shared memory which is very important and will improve the benchmarks)
  -
  -<P><A NAME="anchor177"></A>
  -(META: Add the memory size tests when the server was compiled with
  -EVERYTHING=1 and without it, does loading everything make a big change in
  -the memory footprint? Probably the suggestion would be as follows: For a
  -development server use EVERYTHING=1, while for production if your server is
  -pretty busy and/or low on memory and every bit is on account, only the
  -required parts should be built in. BTW, remember that apache comes with
  -many modules that are built by default, and you might not need those!)
  -
  -<P><A NAME="anchor178"></A>
  -I have conducted a few tests to benchmark the memory usage when some
  -modules are preloaded. The first set of tests checks the memory used with a
  -Perl module preloaded (<CODE>CGI.pm</CODE>). The second set checks the compile method of <CODE>CGI.pm</CODE>. The third test checks the benefit of preloading a few Perl modules (we
  -see more memory saved) and also the effect of precompiling the Registry
  -modules with
  -<CODE>Apache::RegistryLoader</CODE>.
  -
  -<P><A NAME="anchor179"></A>
  -Hardware and software: The server is Apache 1.3.2 with mod_perl 1.16
  -running on AIX 4.1.5 RS6000 with 1G RAM.
  +	<td>
  +	  <pre>  memuse.pl
  +  ---------
  +  use strict;
  +  use CGI ();
  +  use DB_File ();
  +  use LWP::UserAgent ();
  +  use Storable ();
  +  use DBI ();
  +  use GTop ();</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
   
  -<P><A NAME="anchor180"></A>
  -1. In the first test, I used the following script:
  +	<td>
  +	  <pre>  my $r = shift;
  +  $r-&gt;send_http_header('text/plain');
  +  my $proc_mem = GTop-&gt;new-&gt;proc_mem($$);
  +  my $size  = $proc_mem-&gt;size;
  +  my $share = $proc_mem-&gt;share;
  +  my $diff  = $size - $share;
  +  printf &quot;%10s %10s %10s\n&quot;, qw(Size Shared Difference);
  +  printf &quot;%10d %10d %10d (bytes)\n&quot;,$size,$share,$diff;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +First we restart the server and execute this CGI script when none of the
  +above modules preloaded. Here is the result:
  +
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>     Size   Shared     Diff
  +  4706304  2134016  2572288 (bytes)</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +Now we take all the modules:
  +
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
   
  -<P><A NAME="anchor181"></A>
  -<PRE>  use strict;
  +	<td>
  +	  <pre>  use strict;
     use CGI ();
  -  my $q = new CGI;
  -  print $q-&gt;header;
  -  print $q-&gt;start_html,$q-&gt;p(&quot;Hello&quot;);
  -</PRE>
  -<P><A NAME="anchor182"></A>
  -<STRONG>Server restarted</STRONG>
  -
  -
  -
  -<P><A NAME="anchor183"></A>
  -Before preloading <CODE>CGI.pm</CODE>: (No other modules preloaded)
  -
  -<P><A NAME="anchor184"></A>
  -<PRE>  USER        PID %CPU %MEM   SZ  RSS    TTY STAT    STIME  TIME COMMAND
  -  root      87004  0.0  0.0 1060 1524      - A    16:51:14  0:00 httpd
  -  httpd    240864  0.0  0.0 1304 1784      - A    16:51:13  0:00 httpd
  -</PRE>
  -<P><A NAME="anchor185"></A>
  -After running a script which uses CGI's methods (no imports):
  -
  -<P><A NAME="anchor186"></A>
  -<PRE>  USER        PID %CPU %MEM   SZ  RSS    TTY STAT    STIME  TIME COMMAND
  -  root     188068  0.0  0.0 1052 1524      - A    17:04:16  0:00 httpd
  -  httpd     86952  0.0  1.0 2520 3052      - A    17:04:16  0:00 httpd
  -</PRE>
  -<P><A NAME="anchor187"></A>
  -Observation: the child httpd has grown by 1268K
  -
  -<P><A NAME="anchor188"></A>
  -<STRONG>Server restarted</STRONG>
  -
  -
  -
  -<P><A NAME="anchor189"></A>
  -After preloading <CODE>CGI.pm</CODE>:
  -
  -<P><A NAME="anchor190"></A>
  -<PRE>  USER        PID %CPU %MEM   SZ  RSS    TTY STAT    STIME  TIME COMMAND
  -  root     240796  0.0  0.0 1456 1552      - A    16:55:30  0:00 httpd
  -  httpd     86944  0.0  0.0 1688 1800      - A    16:55:30  0:00 httpd
  -</PRE>
  -<P><A NAME="anchor191"></A>
  -after running a script which uses CGI's methods (no imports):
  -
  -<P><A NAME="anchor192"></A>
  -<PRE>  USER        PID %CPU %MEM   SZ  RSS    TTY STAT    STIME  TIME COMMAND
  -  root      86872  0.0  0.0 1448 1552      - A    17:02:56  0:00 httpd
  -  httpd    187996  0.0  1.0 2808 2968      - A    17:02:56  0:00 httpd
  -</PRE>
  -<P><A NAME="anchor193"></A>
  -Observation: the child httpd has grown by 1168K, 100K less than without the
  -preload -- good!
  -
  -<P><A NAME="anchor194"></A>
  -<STRONG>Server restarted</STRONG>
  -
  -
  -
  -<P><A NAME="anchor195"></A>
  -After <CODE>CGI.pm</CODE> preloaded and compiled with CGI-&gt;<CODE>compile(':all');</CODE>
  -
  -<P><A NAME="anchor196"></A>
  -<PRE>  USER        PID %CPU %MEM   SZ  RSS    TTY STAT    STIME  TIME COMMAND
  -  root      86980  0.0  0.0 2836 1524      - A    17:05:27  0:00 httpd
  -  httpd    188104  0.0  0.0 3064 1768      - A    17:05:27  0:00 httpd
  -</PRE>
  -<P><A NAME="anchor197"></A>
  -After running a script which uses CGI's methods (no imports):
  -
  -<P><A NAME="anchor198"></A>
  -<PRE>  USER        PID %CPU %MEM   SZ  RSS    TTY STAT    STIME  TIME COMMAND
  -  root      86980  0.0  0.0 2828 1524      - A    17:05:27  0:00 httpd
  -  httpd    188104  0.0  1.0 4188 2940      - A    17:05:27  0:00 httpd
  -</PRE>
  -<P><A NAME="anchor199"></A>
  -Observation: the child httpd has grown by 1172K - no change! So does
  -<CODE>CGI-&gt;compile(':all')</CODE> help us? We probably do not use all the methods which CGI provides, so in
  -real use it's faster.
  -
  -<P><A NAME="anchor200"></A>
  -You might want to compile only the tags you are going to use, then you will
  -definitely see some benefit.
  -
  -<P><A NAME="anchor201"></A>
  -2. The second test attempts to check whether <CODE>CGI</CODE>'s <CODE>compile()</CODE> method improve things. This is the code under
  -test.
  +  use DB_File ();
  +  use LWP::UserAgent ();
  +  use Storable ();
  +  use DBI ();
  +  use GTop ();</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +and copy them into the startup script, so they will get preloaded. The
  +script remains unchanged. We restart the server and execute it again. We
  +get the following.
  +
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>     Size   Shared    Diff
  +  4710400  3997696  712704 (bytes)</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +Let's put the two results into one table:
  +
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  Preloading    Size   Shared     Diff
  +     Yes     4710400  3997696   712704 (bytes)
  +      No     4706304  2134016  2572288 (bytes)
  +  --------------------------------------------
  +  Difference    4096  1863680 -1859584</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +You can clearly see that when the modules weren't preloaded the shared
  +memory pages size, were about 1864Kb smaller relative to the case where the
  +modules were preloaded.
  +
  +<P>
  +Assuming that you have had 256M dedicated to the web server, if you didn't
  +preload the modules, you could have:
  +
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  268435456 = X * 2572288 + 2134016</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  X = (268435456 - 2134016) / 2572288 = 103 </pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +103 servers.
  +
  +<P>
  +Now let's calculate the same thing with modules preloaded:
  +
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  268435456 = X * 712704 + 3997696</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  X = (268435456 - 3997696) / 712704 = 371</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +You can have almost 4 times more servers!!!
  +
  +<P>
  +Remember that we have mentioned before that memory pages gets dirty and the
  +size of the shared memory gets smaller with time? So we have presented the
  +ideal case where the shared memory stays intact. Therefore the real numbers
  +will be a little bit different, but not far from the numbers in our
  +example.
  +
  +<P>
  +Also it's obvious that in your case it's possible that the process size
  +will be bigger and the shared memory will be smaller, since you will use
  +different modules and a different code, so you won't get this fantastic
  +ratio, but this example is certainly helps to feel the difference.
   
  -<P><A NAME="anchor202"></A>
  -<PRE>  use strict;
  -  use CGI qw(:all);
  -  print header,start_html,p(&quot;Hello&quot;);
  -</PRE>
  -<P><A NAME="anchor203"></A>
  -<STRONG>Server restarted</STRONG>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
  +<CENTER><H3><A NAME="Preloading_Registry_Scripts_at_S">Preloading Registry Scripts at Server Startup</A></H3></CENTER>
  +<P>
  +What happens if you find yourself stuck with Perl CGI scripts and you
  +cannot or don't want to move most of the stuff into modules to benefit from
  +modules preloading, so the code will be shared by the children. Luckily you
  +can preload scripts as well. This time the
  +<CODE>Apache::RegistryLoader</CODE> modules comes to aid.
  +<CODE>Apache::RegistryLoader</CODE> compiles <CODE>Apache::Registry</CODE> scripts at server startup.
  +
  +<P>
  +For example to preload the script <EM>/perl/test.pl</EM> which is in fact the file <EM>/home/httpd/perl/test.pl</EM> you would do the following:
  +
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  use Apache::RegistryLoader ();
  +  Apache::RegistryLoader-&gt;new-&gt;handler(&quot;/perl/test.pl&quot;,
  +                            &quot;/home/httpd/perl/test.pl&quot;);</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +You should put this code either into <CODE>&lt;Perl&gt;</CODE> sections or into a startup script.
  +
  +<P>
  +But what if you have a bunch of scripts located under the same directory
  +and you don't want to list them one by one. Take the benefit of Perl
  +modules and put them to a good use. The <CODE>File::Find</CODE>
  +module will do most of the work for you.
  +
  +<P>
  +The following code walks the directory tree under which all
  +<CODE>Apache::Registry</CODE> scripts are located. For each encountered file with extension <EM>.pl</EM>, it calls the
  +<CODE>Apache::RegistryLoader::handler()</CODE> method to preload the script in the parent server, before pre-forking the
  +child processes:
   
  +<P>
   
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor204"></A>
  -After <CODE>CGI.pm</CODE> was preloaded but NOT compiled with CGI-&gt;<CODE>compile():</CODE>
  -
  -<P><A NAME="anchor205"></A>
  -<PRE>  USER        PID %CPU %MEM   SZ  RSS    TTY STAT    STIME  TIME COMMAND
  -  root      17268  0.0  0.0 1456 1552      - A    18:02:49  0:00 httpd
  -  httpd     86904  0.0  0.0 1688 1800      - A    18:02:49  0:00 httpd
  -</PRE>
  -<P><A NAME="anchor206"></A>
  -After running a script which imports ALL the symbols:
  -
  -<P><A NAME="anchor207"></A>
  -<PRE>  USER        PID %CPU %MEM   SZ  RSS    TTY STAT    STIME  TIME COMMAND
  -  root      17268  0.0  0.0 1448 1552      - A    18:02:49  0:00 httpd
  -  httpd     86904  0.0  1.0 2952 3112      - A    18:02:49  0:00 httpd
  -</PRE>
  -<P><A NAME="anchor208"></A>
  -Observation: the child httpd has grown by 1264K
  -
  -<P><A NAME="anchor209"></A>
  -<STRONG>Server restarted</STRONG>
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
   
  +	<td>
  +	  <pre>  use File::Find qw(finddepth);
  +  use Apache::RegistryLoader ();
  +  {
  +    my $scripts_root_dir = &quot;/home/httpd/perl/&quot;;
  +    my $rl = Apache::RegistryLoader-&gt;new;
  +    finddepth
  +      (
  +       sub {
  +         return unless /\.pl$/;
  +         my $url = &quot;$File::Find::dir/$_&quot;;
  +         $url =~ s|$scripts_root_dir/?|/|;
  +         warn &quot;pre-loading $url\n&quot;;
  +           # preload $url
  +         my $status = $rl-&gt;handler($url);
  +         unless($status == 200) {
  +           warn &quot;pre-load of `$url' failed, status=$status\n&quot;;
  +         }
  +       },
  +       $scripts_root_dir);
  +  }</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +Note that we didn't use the second argument to <CODE>handler()</CODE> here, as in the first example. To make the loader smarter about the URI to
  +filename translation, you might need to provide a <CODE>trans()</CODE> function to translate the URI to filename. URI to filename translation
  +normally doesn't happen until HTTP request time, so the module is forced to
  +roll its own translation. If filename is omitted and a
  +<CODE>trans()</CODE> function was not defined, the loader will try using the URI relative to <STRONG>ServerRoot</STRONG>.
   
  +<P>
  +A simple <CODE>trans()</CODE> function can be something like that:
   
  -<P><A NAME="anchor210"></A>
  -After <CODE>CGI.pm</CODE> was preloaded and compiled with CGI-&gt;<CODE>compile(':all'):</CODE>
  -
  -<P><A NAME="anchor211"></A>
  -<PRE>  USER        PID %CPU %MEM   SZ  RSS    TTY STAT    STIME  TIME COMMAND
  -  root      86812  0.0  0.0 2836 1524      - A    17:59:52  0:00 httpd
  -  httpd     99104  0.0  0.0 3064 1768      - A    17:59:52  0:00 httpd
  -</PRE>
  -<P><A NAME="anchor212"></A>
  -After running a script which imports ALL the symbols:
  -
  -<P><A NAME="anchor213"></A>
  -<PRE>  USER        PID %CPU %MEM   SZ  RSS    TTY STAT    STIME  TIME COMMAND
  -  root      86812  0.0  0.0 2832 1436      - A    17:59:52  0:00 httpd
  -  httpd     99104  0.0  1.0 4884 3636      - A    17:59:52  0:00 httpd
  -</PRE>
  -<P><A NAME="anchor214"></A>
  -Observation: the child httpd has grown by 1868K.
  -
  -<P><A NAME="anchor215"></A>
  -Why so much? In fact these results are misleading. If you look at the code
  -you will see that we have called only three of <CODE>CGI.pm</CODE>'s methods. The statement <CODE>use CGI qw(:all)</CODE> doesn't compile all the available methods, it just imports their names.
  -This means that we do not use so much memory as if the methods are all
  -compiled. Execute
  -<CODE>compile()</CODE> only on the methods you intend to use and then you will see a reduction in
  -your memory requirements.
  +<P>
   
  -<P><A NAME="anchor216"></A>
  -3. The third script:
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  sub mytrans {
  +    my $uri = shift;
  +    $uri =~ s|^/perl/|/home/httpd/perl/|;
  +    return $uri;
  +  }</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +You can easily derive the right translation by looking at the <CODE>Alias</CODE>
  +directive. The above <CODE>mytrans()</CODE> function is matching our <CODE>Alias</CODE>:
  +
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  Alias /perl/ /home/httpd/perl/</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +After defining the URI to filename translation function you should pass it
  +during the creation of the <CODE>Apache::RegistryLoader</CODE> object:
  +
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  my $rl = Apache::RegistryLoader-&gt;new(trans =&gt; \&amp;mytrans);</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +I won't show any benchmarks here, since the effect is absolutely the same
  +as with preloading modules.
   
  -<P><A NAME="anchor217"></A>
  -<PRE>  use strict;
  -  use CGI;
  -  use Data::Dumper;
  -  use Storable;
  -  [and many lines of code, lots of globals - so the code is huge!]
  -</PRE>
  -<P><A NAME="anchor218"></A>
  -<STRONG>Server restarted</STRONG>
  -
  -
  -
  -<P><A NAME="anchor219"></A>
  -Nothing preloaded at startup:
  -
  -<P><A NAME="anchor220"></A>
  -<PRE>  USER        PID %CPU %MEM   SZ  RSS    TTY STAT    STIME  TIME COMMAND
  -  root      90962  0.0  0.0 1060 1524      - A    17:16:45  0:00 httpd
  -  httpd     86870  0.0  0.0 1304 1784      - A    17:16:45  0:00 httpd
  -</PRE>
  -<P><A NAME="anchor221"></A>
  -Script using CGI (methods), Storable, Data::Dumper called:
  -
  -<P><A NAME="anchor222"></A>
  -<PRE>  USER        PID %CPU %MEM   SZ  RSS    TTY STAT    STIME  TIME COMMAND
  -  root      90962  0.0  0.0 1064 1436      - A    17:16:45  0:00 httpd
  -  httpd     86870  0.0  1.0 4024 4548      - A    17:16:45  0:00 httpd
  -</PRE>
  -<P><A NAME="anchor223"></A>
  -Observation: the child httpd has grown by 2764K
  -
  -<P><A NAME="anchor224"></A>
  -<STRONG>Server restarted</STRONG>
  -
  -
  -
  -<P><A NAME="anchor225"></A>
  -Preloaded CGI (compiled), Storable, Data::Dumper at startup:
  -
  -<P><A NAME="anchor226"></A>
  -<PRE>  USER        PID %CPU %MEM   SZ  RSS    TTY STAT    STIME  TIME COMMAND
  -  root      26792  0.0  0.0 3120 1528      - A    17:19:21  0:00 httpd
  -  httpd     91052  0.0  0.0 3340 1764      - A    17:19:21  0:00 httpd
  -</PRE>
  -<P><A NAME="anchor227"></A>
  -Script using CGI (methods), Storable, Data::Dumper called
  -
  -<P><A NAME="anchor228"></A>
  -<PRE>  USER        PID %CPU %MEM   SZ  RSS    TTY STAT    STIME  TIME COMMAND
  -  root      26792  0.0  0.0 3124 1440      - A    17:19:21  0:00 httpd
  -  httpd     91052  0.0  1.0 6568 5040      - A    17:19:21  0:00 httpd
  -</PRE>
  -<P><A NAME="anchor229"></A>
  -Observation: the child httpd has grown by 3276K.
  -
  -<P><A NAME="anchor230"></A>
  -Ouch! 512K more!
  -
  -<P><A NAME="anchor231"></A>
  -The reason is that when you preload all of the methods at startup, they are
  -all precompiled. There are many of them and they take up a big chunk of
  -memory. If you don't use the <CODE>compile()</CODE> method, only the
  -functions that are used will be compiled. Yes, it will slightly slow down
  -the first response from each process, but the actual memory usage will be
  -lower.
  -
  -<P><A NAME="anchor232"></A>
  -<STRONG>Server restarted</STRONG>
  -
  -
  -
  -<P><A NAME="anchor233"></A>
  -All the above modules plus the above script precompiled at startup with <CODE>Apache::RegistryLoader</CODE>:
  -
  -<P><A NAME="anchor234"></A>
  -<PRE>  USER        PID %CPU %MEM   SZ  RSS    TTY STAT    STIME  TIME COMMAND
  -  root      43224  0.0  0.0 3256 1528      - A    17:23:12  0:00 httpd
  -  httpd     26844  0.0  0.0 3488 1776      - A    17:23:12  0:00 httpd
  -</PRE>
  -<P><A NAME="anchor235"></A>
  -Script using CGI (methods), Storable, Data::Dumper called:
  -
  -<P><A NAME="anchor236"></A>
  -<PRE>  USER        PID %CPU %MEM   SZ  RSS    TTY STAT    STIME  TIME COMMAND
  -  root      43224  0.0  0.0 3252 1440      - A    17:23:12  0:00 httpd
  -  httpd     26844  0.0  1.0 6748 5092      - A    17:23:12  0:00 httpd
  -</PRE>
  -<P><A NAME="anchor237"></A>
  -Observation: the child httpd has grown even more!
  -
  -<P><A NAME="anchor238"></A>
  -3316K! This does not look good!
  -
  -<P><A NAME="anchor239"></A>
  -<STRONG>Summary</STRONG>:
  -
  -<P><A NAME="anchor240"></A>
  -1. Preloading Perl modules gave good results everywhere.
  -
  -<P><A NAME="anchor241"></A>
  -2. <CODE>CGI.pm</CODE>'s <CODE>compile()</CODE> method seems to use even more memory. It's because we never use all of the
  -methods that CGI provides. Only
  -<CODE>compile()</CODE> the tags that you are going to use and you will save the overhead of the
  -first call for each method which has not yet been called. You will also
  -save some memory since the compiled code will be shared with the children.
  -
  -<P><A NAME="anchor242"></A>
  -3. <CODE>Apache::RegistryLoader</CODE> might make scripts load faster on the first request after the child has
  -just started but the memory usage is worse.
  -
  -<P><A NAME="anchor243"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<CENTER><H3><A NAME="Preload_Registry_Scripts">Preload Registry Scripts</A></H3></CENTER>
  -<P><A NAME="anchor244"></A>
  -<CODE>Apache::RegistryLoader</CODE> compiles <CODE>Apache::Registry</CODE> scripts at server startup. It can be a good idea to preload the scripts you
  -are going to use as well, so the code will be shared by the children.
  -
  -<P><A NAME="anchor245"></A>
  -Here is an example of the use of this technique. This code is included in a <CODE>PerlRequire</CODE>'d file, and walks the directory tree under which all registry scripts are
  -installed. For each <CODE>.pl</CODE> file encountered, it calls the <CODE>Apache::RegistryLoader::handler()</CODE> method to preload the script in the parent server, before pre-forking the
  -child processes:
  +<P>
  +See also <A HREF="././porting.html#BEGIN_blocks">BEGIN blocks</A>
   
  -<P><A NAME="anchor246"></A>
  -<PRE>  use File::Find 'finddepth';
  -  use Apache::RegistryLoader ();
  -  {
  -      my $perl_dir = &quot;perl/&quot;;
  -      my $rl = Apache::RegistryLoader-&gt;new;
  -      finddepth(sub {
  -          return unless /\.pl$/;
  -          my $url = &quot;/$File::Find::dir/$_&quot;;
  -          print &quot;pre-loading $url\n&quot;;
  -  
  -          my $status = $rl-&gt;handler($url);
  -          unless($status == 200) {
  -              warn &quot;pre-load of `$url' failed, status=$status\n&quot;;
  -          }
  -      }, $perl_dir);
  +
  +
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
  +<CENTER><H3><A NAME="Modules_Initializing_at_Server_S">Modules Initializing at Server Startup</A></H3></CENTER>
  +<P>
  +We have just learned that it's important to preload the modules and scripts
  +at the server startup. It turns out that it's not enough for some modules
  +and you have to prerun their initialization code to get more memory pages
  +shared. Basically you will find an information about specific modules in
  +their respective manpages. We will present a few examples of widely used
  +modules where the code can be initialized.
  +
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
  +<CENTER><H4><A NAME="Initializing_DBI_pm">Initializing DBI.pm</A></H4></CENTER>
  +<P>
  +The first example is the <CODE>DBI</CODE> module. As you know <CODE>DBI</CODE> works with many database drivers falling into the <CODE>DBD::</CODE> category, e.g. <CODE>DBD::mysql</CODE>. It's not enough to preload <CODE>DBI</CODE>, you should initialize <CODE>DBI</CODE> with <CODE>driver(s)</CODE> that you are going to use (usually a single
  +driver is used), if you want to minimize memory use after forking the child
  +processes. Note that you want to do this under mod_perl and other
  +environments where the shared memory is very important. Otherwise you
  +shouldn't initialize drivers.
  +
  +<P>
  +You probably know already that under mod_perl you should use the
  +<CODE>Apache::DBI</CODE> module to get the connection persistence, unless you open a separate
  +connection for each user--in this case you should not use this module. <CODE>Apache::DBI</CODE> automatically loads <CODE>DBI</CODE> and overrides some of its methods, so you should continue coding like there
  +is only a <CODE>DBI</CODE> module.
  +
  +<P>
  +Just as with modules preloading our goal is to find the startup environment
  +that will lead to the smallest <EM>"difference"</EM> between the shared and normal memory reported, therefore a smaller total
  +memory usage.
  +
  +<P>
  +And again in order to have an easy measurement we will use only one child
  +process, therefore we will use this setting in <EM>httpd.conf</EM>:
  +
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  MinSpareServers 1
  +  MaxSpareServers 1
  +  StartServers 1
  +  MaxClients 1
  +  MaxRequestsPerChild 100</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +We are going to run memory benchmarks on five different versions of the <EM>startup.pl</EM> file. We always preload these modules:
  +
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  use Gtop();
  +  use Apache::DBI(); # preloads DBI as well</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <DL>
  +<P><DT><STRONG><A NAME="item_option">option 1</A></STRONG><DD>
  +<P>
  +Leave the file unmodified.
  +
  +<P><DT><STRONG>option 2</STRONG><DD>
  +<P>
  +Install MySQL driver (we will use MySQL RDBMS for our test):
  +
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  DBI-&gt;install_driver(&quot;mysql&quot;);</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +It's safe to use this method, since just like with <CODE>use()</CODE>, if it can't be installed it'll <CODE>die().</CODE>
  +
  +<P><DT><STRONG>option 3</STRONG><DD>
  +<P>
  +Preload MySQL driver module:
  +
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  use DBD::mysql;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P><DT><STRONG>option 4</STRONG><DD>
  +<P>
  +Tell <CODE>Apache::DBI</CODE> to connect to the database when the child process starts (<CODE>ChildInitHandler</CODE>), no driver is preload before the child gets spawned!
  +
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  Apache::DBI-&gt;connect_on_init('DBI:mysql:test::localhost',
  +                             &quot;&quot;,
  +                             &quot;&quot;,
  +                             {
  +                              PrintError =&gt; 1, # warn() on errors
  +                              RaiseError =&gt; 0, # don't die on error
  +                              AutoCommit =&gt; 1, # commit executes
  +                              # immediately
  +                             }
  +                            )
  +  or die &quot;Cannot connect to database: $DBI::errstr&quot;;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    </DL>
  +<P>
  +Here is the <CODE>Apache::Registry</CODE> test script that we have used:
  +
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  preload_dbi.pl
  +  --------------
  +  use strict;
  +  use GTop ();
  +  use DBI ();
  +    
  +  my $dbh = DBI-&gt;connect(&quot;DBI:mysql:test::localhost&quot;,
  +                         &quot;&quot;,
  +                         &quot;&quot;,
  +                         {
  +                          PrintError =&gt; 1, # warn() on errors
  +                          RaiseError =&gt; 0, # don't die on error
  +                          AutoCommit =&gt; 1, # commit executes
  +                                           # immediately
  +                         }
  +                        )
  +    or die &quot;Cannot connect to database: $DBI::errstr&quot;;
  +  
  +  my $r = shift;
  +  $r-&gt;send_http_header('text/plain');
  +  
  +  my $do_sql = &quot;show tables&quot;;
  +  my $sth = $dbh-&gt;prepare($do_sql);
  +  $sth-&gt;execute();
  +  my @data = ();
  +  while (my @row = $sth-&gt;fetchrow_array){
  +    push @data, @row;
     }
  -</PRE>
  -<P><A NAME="anchor247"></A>
  -Note that we didn't use the second argument to <CODE>handler()</CODE> here, as the module's manpage suggests. To make the loader smarter about
  -the URI to filename translation, you might need to provide a <CODE>trans()</CODE>
  -function to translate the uri to filename. URI to filename translation
  -normally doesn't happen until HTTP request time, so the module is forced to
  -roll its own translation. If filename is omitted and a <CODE>trans()</CODE> routine was not defined, the loader will try using the URI relative to <STRONG>ServerRoot</STRONG>.
  +  print &quot;Data: @data\n&quot;;
  +  $dbh-&gt;disconnect(); # NOP under Apache::DBI
  +  
  +  my $proc_mem = GTop-&gt;new-&gt;proc_mem($$);
  +  my $size  = $proc_mem-&gt;size;
  +  my $share = $proc_mem-&gt;share;
  +  my $diff  = $size - $share;
  +  printf &quot;%8s %8s %8s\n&quot;, qw(Size Shared Diff);
  +  printf &quot;%8d %8d %8d (bytes)\n&quot;,$size,$share,$diff;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +What it does is opening a connection to the database <EM>'test'</EM> and issues a query to learn what tables the databases has. When the data is
  +collected and printed the connection would be closed in the regular case,
  +but <CODE>Apache::DBI</CODE> overrides it with empty method. When the data is processed a familiar to
  +you already code to print the memory usage follows.
  +
  +<P>
  +The server was restarted before each new test.
  +
  +<P>
  +So here are the results of the five tests that were conducted, sorted by
  +the <EM>Diff</EM> column:
   
  -<P><A NAME="anchor248"></A>
  -You should check whether this makes any improvement for you though, I did
  -some testing [ <A HREF="#Preload_Perl_modules_Real_Numb">Preload Perl modules - Real Numbers</A> ], and it seems that it takes more memory than when the scripts are called
  -by the child. This is only a first impression and needs further
  -investigation. If you aren't concerned about occasional script invocations
  -taking a little time to respond while they load the code, you might not
  -need it at all!
  +<OL>
  +<P><LI>
  +<P>
  +After the first request:
   
  -<P><A NAME="anchor249"></A>
  -See also <A HREF="././porting.html#BEGIN_blocks">BEGIN blocks</A>
  +<P>
   
  +    <table>
  +      <tr>
   
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  Version     Size   Shared     Diff        Test type
  +  --------------------------------------------------------------------
  +        1  3465216  2621440   843776  install_driver
  +        2  3461120  2609152   851968  install_driver &amp; connect_on_init
  +        3  3465216  2605056   860160  preload driver
  +        4  3461120  2494464   966656  nothing added
  +        5  3461120  2482176   978944  connect_on_init</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P><LI>
  +<P>
  +After the second request (all the subsequent request showed the same
  +results):
  +
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  Version     Size   Shared    Diff         Test type
  +  --------------------------------------------------------------------
  +        1  3469312  2609152   860160  install_driver
  +        2  3481600  2605056   876544  install_driver &amp; connect_on_init
  +        3  3469312  2588672   880640  preload driver
  +        4  3477504  2482176   995328  nothing added
  +        5  3481600  2469888  1011712  connect_on_init</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    </OL>
  +<P>
  +Now what do we conclude from looking at these numbers. First we see that
  +only after a second reload we get the final memory footprint for a specific
  +request in question (if you pass different arguments the memory usage might
  +and will be different).
  +
  +<P>
  +But both tables show the same pattern of memory usage. We can clearly see
  +that the real winner is the <EM>startup.pl</EM> file's version where the MySQL driver was installed (1). Since we want to
  +have a connection ready for the first request made to the freshly spawned
  +child process, we generally use the second version (2) which uses somewhat
  +more memory, but has almost the same number of shared memory pages. The
  +third version only preloads the driver which results in smaller shared
  +memory. The last two versions having nothing initialized (4) and having
  +only the <CODE>connect_on_init()</CODE> method used (5). The former is a
  +little bit better than the latter, but both significantly worse than the
  +first two versions.
  +
  +<P>
  +To remind you why do we look for the smallest value in the column
  +<EM>diff</EM>, recall the real memory usage formula:
  +
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  RAM_dedicated_to_mod_perl = diff * number_of_processes
  +                            + the_processes_with_largest_shared_memory</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +Notice that the the smaller the diff is, the bigger the number of processes
  +you can have using the same amount of RAM. Therefore every 100K difference
  +counts, when you multiply it by the number of processes. If we take the
  +number from the version version (1) vs (4) and assume that we have 256M of
  +memory dedicated to mod_perl processes we will get the following numbers
  +using the formula derived from the above formula:
  +
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>               RAM - largest_shared_size
  +  N_of Procs = -------------------------
  +                        Diff</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>                268435456 - 2609152
  +  (ver 1)  N =  ------------------- = 309
  +                      860160</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>                268435456 - 2469888
  +  (ver 5)  N =  ------------------- = 262
  +                     1011712</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +So you can tell the difference (17% more child processes in the first
  +version).
   
  -<P><A NAME="anchor250"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<CENTER><H2><A NAME="Memory_Swapping_is_Considered_Ba">Memory Swapping is Considered Bad</A></H2></CENTER>
  -<P><A NAME="anchor251"></A>
  -(META: check that you don't have a duplication somewhere in the text,
  -probably the MaxClients tuning section)
  -
  -<P><A NAME="anchor252"></A>
  -When tuning the performance of your box, you must configure the software
  -that you run in such a way that no memory swapping will occur: even during
  -peak hours.
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
  +<CENTER><H4><A NAME="Initializing_CGI_pm">Initializing CGI.pm</A></H4></CENTER>
  +<P>
  +<CODE>CGI.pm</CODE> is a big module that by default postpones the compilation of its methods
  +until they are actually needed, thus making it possible to use it under a
  +slow mod_cgi handler without adding a big overhead. That's not what we want
  +under mod_perl and if you use
  +<CODE>CGI.pm</CODE> you should precompile the methods that you are going to use at the server
  +startup in addition to preloading the module. Use the compile method for
  +that:
  +
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  use CGI;
  +  CGI-&gt;compile(':all');</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +where you should replace the tag group <CODE>:all</CODE> with the real tags and group tags that you are going to use if you want to
  +optimize the memory usage.
  +
  +<P>
  +We are going to compare the shared memory foot print by using the script
  +which is back compatible with mod_cgi. You will see that you can improve
  +performance of this kind of scripts as well, but if you really want a fast
  +code think about porting it to use
  +<CODE>Apache::Request</CODE> for CGI interface and some other module for HTML generation.
  +
  +<P>
  +So here is the <CODE>Apache::Registry</CODE> script that we are going to use to make the comparison:
  +
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  preload_cgi_pm.pl
  +  -----------------
  +  use strict;
  +  use CGI ();
  +  use GTop ();</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  my $q = new CGI;
  +  print $q-&gt;header('text/plain');
  +  print join &quot;\n&quot;, map {&quot;$_ =&gt; &quot;.$q-&gt;param($_) } $q-&gt;param;
  +  print &quot;\n&quot;;
  +  
  +  my $proc_mem = GTop-&gt;new-&gt;proc_mem($$);
  +  my $size  = $proc_mem-&gt;size;
  +  my $share = $proc_mem-&gt;share;
  +  my $diff  = $size - $share;
  +  printf &quot;%8s %8s %8s\n&quot;, qw(Size Shared Diff);
  +  printf &quot;%8d %8d %8d (bytes)\n&quot;,$size,$share,$diff;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +The script initializes the <CODE>CGI</CODE> object, sends HTTP header and then print all the arguments and values that
  +were passed to the script if at all. At the end as usual we print the
  +memory usage.
  +
  +<P>
  +As usual we are going to use a single child process, therefore we will use
  +this setting in <EM>httpd.conf</EM>:
  +
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  MinSpareServers 1
  +  MaxSpareServers 1
  +  StartServers 1
  +  MaxClients 1
  +  MaxRequestsPerChild 100</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +We are going to run memory benchmarks on three different versions of the <EM>startup.pl</EM> file. We always preload this module:
  +
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  use Gtop();</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <DL>
  +<P><DT><STRONG>option 1</STRONG><DD>
  +<P>
  +Leave the file unmodified.
  +
  +<P><DT><STRONG>option 2</STRONG><DD>
  +<P>
  +Preload <CODE>CGI.pm</CODE>:
  +
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  use CGI ();</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P><DT><STRONG>option 3</STRONG><DD>
  +<P>
  +Preload <CODE>CGI.pm</CODE> and pre-compile the methods that we are going to use in the script:
  +
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  use CGI ();
  +  CGI-&gt;compile(qw(header param));</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    </DL>
  +<P>
  +The server was restarted before each new test.
  +
  +<P>
  +So here are the results of the five tests that were conducted, sorted by
  +the <EM>Diff</EM> column:
  +
  +<OL>
  +<P><LI>
  +<P>
  +After the first request:
  +
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  Version     Size   Shared     Diff        Test type
  +  --------------------------------------------------------------------
  +        1  3321856  2146304  1175552  not preloaded
  +        2  3321856  2326528   995328  preloaded
  +        3  3244032  2465792   778240  preloaded &amp; methods+compiled</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P><LI>
  +<P>
  +After the second request (all the subsequent request showed the same
  +results):
  +
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  Version     Size   Shared    Diff         Test type
  +  --------------------------------------------------------------------
  +        1  3325952  2134016  1191936 not preloaded
  +        2  3325952  2314240  1011712 preloaded
  +        3  3248128  2445312   802816 preloaded &amp; methods+compiled</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    </OL>
  +<P>
  +The first version shows the results of the script execution when
  +<CODE>CGI.pm</CODE> wasn't preloaded. The second version with module preloaded. The third when
  +it's both preloaded and the methods that are going to be used are
  +precompiled at the server startup.
  +
  +<P>
  +By looking at the version one of the second table we can conclude that,
  +preloading adds about 20K of shared size. As we have mention at the
  +beginning of this section that's how <CODE>CGI.pm</CODE> was implemented--to reduce the load overhead. Which means that preloading
  +CGI is almost hardly change a thing. But if we compare the second and the
  +third versions we will see a very significant difference of 207K
  +(1011712-802816), and we have used only a few methods (the <EM>header</EM>
  +method loads a few more method transparently for a user). Imagine how much
  +memory we are going to save if we are going to precompile all the methods
  +that we are using in other scripts that use <CODE>CGI.pm</CODE> and do a little bit more than the script that we have used in the test.
  +
  +<P>
  +But even in our very simple case using the same formula, what do we see?
  +(assuming that we have 256MB dedicated for mod_perl)
  +
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>               RAM - largest_shared_size
  +  N_of Procs = -------------------------
  +                        Diff</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>                268435456 - 2134016
  +  (ver 1)  N =  ------------------- = 223
  +                      1191936</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>                268435456 - 2445312
  +  (ver 3)  N =  ------------------- = 331
  +                     802816</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +If we preload <CODE>CGI.pm</CODE> and precompile a few methods that we use in the test script, we can have
  +50% more child processes than when we don't preload and precompile the
  +methods that we are going to use.
  +
  +<P>
  +META: I've heard that the 3.x generation will be less bloated, so probably
  +I'll have to rerun this using the new version.
   
  -<P><A NAME="anchor253"></A>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
  +<CENTER><H2><A NAME="Memory_Swapping_is_Considered_Ba">Memory Swapping is Considered Bad</A></H2></CENTER>
  +<P>
   Swap memory is slow since it resides on the hard disc, which is
  -<EM>much</EM> slower than the RAM. When your machine starts to swap, because it's unable
  -to cope with the number of the processes it has to run, your machine will
  -become slower and slower until it grinds to a halt. When the CPU has to
  -page memory pages in and out things slow down, causing processing demands
  -to go up, which in turn slows down the system even more as more memory is
  -required and this is provided by the kernel using the reserved swap space.
  -This ever worstening spiral will lead the machine to halt, unless the
  -resource demand suddenly drops down and allows the processes to catch up
  -with their tasks and go back to normal memory usage.
  +<EM>much</EM> slower than the RAM.
   
  -<P><A NAME="anchor254"></A>
  +<P>
  +Why and when the swapping happens? Your machine starts to swap when there
  +is no more available RAM to use for the process currently using the CPU. To
  +gain the required number of memory pages requested by the process the
  +kernel has to page out (i.e. move to a hard disk's swap partition) exactly
  +the same number of pages. The kernel pages out memory pages using the LRU
  +(least recently used) or a similar algorithm to decide which pages to take
  +out, in attempt to prevent the situation where the next process in queue
  +for CPU will need exactly the pages that were paged out, and prevent the
  +page fault (when the page is not found in RAM) occur, which in turn will
  +require more pages to be swapped out in order to free the memory for the
  +pages that get swapped in.
  +
  +<P>
  +When the CPU has to page memory pages in and out things slow down, causing
  +processing demands to go up, which in turn slows down the system even more
  +as more memory is required. This ever worstening spiral will lead the
  +machine to halt, unless the resource demand suddenly drops down and allows
  +the processes to catch up with their tasks and go back to normal memory
  +usage.
  +
  +<P>
  +When tuning the performance of your box, you must configure all the
  +runnning software components in such a way that no memory swapping will
  +occur: even during peak hours. Swap space is an emergency pool, not a
  +resource to be used routinely. If you are low on memory and you badly need
  +it, buy it. Memory is cheap.
  +
  +<P>
   For swapping monitoring techniques see the section '<A HREF="././debug.html#Apache_VMonitor_Visual_Syste">Apache::VMonitor -- Visual System and Apache Server Monitor</A>'.
   
  -<P><A NAME="anchor255"></A>
  +<P>
   For the mod_perl specific swapping prevention guideliness see the section '<A HREF="././performance.html#Choosing_MaxClients">Choosing MaxClients</A>'.
   
  -<P><A NAME="anchor256"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="Increasing_Shared_Memory_With_me">Increasing Shared Memory With mergemem</A></H2></CENTER>
  -<P><A NAME="anchor257"></A>
  +<P>
   <CODE>mergemem</CODE> is an experimental utility for linux, which looks <EM>very</EM>
  -interesting for us mod_perl users:
  +interesting for us mod_perl users: <A
  +HREF="http://www.complang.tuwien.ac.at/ulrich/mergemem/">http://www.complang.tuwien.ac.at/ulrich/mergemem/</A>
   
  -<P><A NAME="anchor258"></A>
  -<PRE>        <A HREF="http://www.ist.org/mergemem/">http://www.ist.org/mergemem/</A>
  -</PRE>
  -<P><A NAME="anchor259"></A>
  +
  +<P>
   It looks like it could be run periodically on your server to find and merge
   duplicate pages. There are caveats: it would halt your httpds during the
   merge (it appears to be very fast, but still ...).
   
  -<P><A NAME="anchor260"></A>
  +<P>
   This software comes with a utility called memcmp to tell you how much you
   might save.
   
  -<P><A NAME="anchor261"></A>
  +<P>
   [ReaderMeta]: <STRONG>If you have tried this utility, please let us know what
   do you think about it! Thanks</STRONG>
   
   
   
  -<P><A NAME="anchor262"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="Forking_and_Executing_Subprocess">Forking and Executing Subprocesses from mod_perl</A></H2></CENTER>
  -<P><A NAME="anchor263"></A>
  +<P>
   In general you should not fork from your mod_perl scripts, since when you
   do, you are forking the entire Apache Web server, lock, stock and barrel.
  -Not only is your perl code being duplicated, but so is mod_ssl,
  -mod_rewrite, mod_log, mod_proxy, mod_speling or whatever modules you have
  -used in your server, all the core routines...
  +Not only is your Perl code and Perl interpreter being duplicated, but so is
  +mod_ssl, mod_rewrite, mod_log, mod_proxy, mod_speling (it's not a typo!) or
  +whatever modules you have used in your server, all the core routines...
   
  -<P><A NAME="anchor264"></A>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
  +<CENTER><H3><A NAME="Spawning_a_Detachable_Sub_Proces">Spawning a Detachable Sub-Process</A></H3></CENTER>
  +<P>
   A much better approach would be to spawn a sub-process, hand it the
   information it needs to do the task, and have it detach (close STDIN,
   STDOUT and STDERR + execute <CODE>setsid()</CODE>). This is wise only if the parent which spawns this process immediately
   continues, and does not wait for the sub-process to complete. This approach
   is suitable for a situation when you want to use the Web interface to
   trigger a process which takes a long time, such as processing lots of data
  -or sending email to thousands of users (no SPAM please!). Otherwise, you
  -should convert the code into a module, and call its functions and methods
  -from a CGI script.
  -
  -<P><A NAME="anchor265"></A>
  -Just making a <CODE>system()</CODE> call defeats the whole idea behind mod_perl. The Perl interpreter and
  -modules would be loaded again for this external program to run if it's a
  -Perl program. Remember that the backticks <EM>`program`</EM> variant of <CODE>system()</CODE> behaves in the same way.
  -
  -<P><A NAME="anchor266"></A>
  -If you really have to use a <CODE>system()</CODE> call then the approach to
  -take is this:
  -
  -<P><A NAME="anchor267"></A>
  -<PRE>  use FreezeThaw ();
  +or sending email to thousands of registered users (no SPAM please!).
  +Otherwise, you should convert the code into a module, and call its
  +functions and methods from a Perl handler or a CGI script.
  +
  +<P>
  +Just like with <CODE>fork(),</CODE> using the system call <CODE>system()</CODE> defeats the whole idea behind mod_perl. The Perl interpreter and modules
  +would be loaded again for this external program to run if it's a Perl
  +program. Remember that the backticks (<CODE>`program`</CODE>) and <CODE>qx(program)</CODE>
  +variants of <CODE>system()</CODE> behave in the same way.
  +
  +<P>
  +If you really have to use <CODE>system()</CODE> then the approach to take
  +is this:
  +
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  spawn_process.pl
  +  ----------------
  +  use FreezeThaw ();
     $params=FreezeThaw::freeze(
           [all data to pass to the other process]
           );
  -  system(&quot;program.pl&quot;, $params);
  -</PRE>
  -<P><A NAME="anchor268"></A>
  -Notice that you do a <CODE>system()</CODE> call with arguments separated by
  -commas, rather than passing them all as a single argument. When you use
  -commas, the shell won't try to parse (tokenize) the parameters, therefore
  -you don't have to worry about escaping unsafe shell characters. If you want
  -the shell to parse the variables make sure to run the escape function, for
  -example the one from the
  -<CODE>String::ShellQuote</CODE> package.
  -
  -<P><A NAME="anchor269"></A>
  -and in <CODE>program.pl</CODE> :
  -
  -<P><A NAME="anchor270"></A>
  -<PRE>  use POSIX qw(setsid);
  +  system(&quot;detach_program.pl&quot;, $params);</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +Notice that we do a <CODE>system()</CODE> call with arguments separated by
  +commas, rather than passing them all as a single argument. This calling
  +style prevents the unwanted replacement of the shell metacharacters (like
  +<CODE>*</CODE>,<CODE>?</CODE>), if some happened to be in <CODE>$params</CODE>. We will talk about this in a moment.
  +
  +<P>
  +And now the source of <EM>detach_program.pl</EM> :
  +
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  detach_program.pl
  +  -----------------
  +  use POSIX qw(setsid);
  +  use FreezeThaw ();
     @params=FreezeThaw::thaw(shift @ARGV);
     # check that @params is ok
     close STDIN;
  @@ -1701,131 +3363,239 @@
     # you might need to reopen the STDERR, i.e.
     # open STDERR, &quot;&gt;/dev/null&quot;;
     setsid(); # to detach
  -</PRE>
  -<P><A NAME="anchor271"></A>
  -At this point, <CODE>program.pl</CODE> is running in the ``background'' while the
  -<CODE>system()</CODE> returns and permits Apache to get on with things.
  +  # now do something time consuming</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +At this point, <EM>detach_program.pl</EM> is running in the <EM>"background"</EM>
  +while the call <CODE>system()</CODE> returns and permits Apache to get on with things.
   
  -<P><A NAME="anchor272"></A>
  +<P>
   This has obvious problems:
   
   <UL>
   <P><LI>
  -<P><A NAME="anchor273"></A>
  +<P>
   <CODE>@params</CODE> must not be bigger than whatever limit is imposed by your architecture.
  -This could depend on your shell.
   
   <P><LI>
  -<P><A NAME="anchor274"></A>
  -The communication is one way only.
  +<P>
  +The communication is one way only. Once the program detached, the process
  +that has spawned it has no control over it.
   
   </UL>
  -<P><A NAME="anchor275"></A>
  -However, you might be trying to do the ``wrong thing''. If what you really
  -want is to send information to the browser and then do some
  -post-processing, look into the <CODE>PerlCleanupHandler</CODE> directive.
  -
  -<P><A NAME="anchor276"></A>
  -If you are interested in more details, here is what actually happens when
  -you <CODE>fork()</CODE> and make a system call such as this fragment:
  -
  -<P><A NAME="anchor277"></A>
  -<PRE>  system(&quot;echo Hi&quot;),CORE::exit(0) unless fork();
  -</PRE>
  -<P><A NAME="anchor278"></A>
  -Notice that I use <CODE>CORE::exit()</CODE> and not <CODE>exit()</CODE>, which would be automatically overriden by <CODE>Apache::exit()</CODE> if used in conjunction with <CODE>Apache::Registry</CODE> and friends.
  +<P>
  +However, you might be trying to do the <EM>"wrong thing"</EM>. If what you really want is to send information to the browser and then do
  +some post-processing, look into the <CODE>PerlCleanupHandler</CODE> directive. The latter allows you to tell the child process after request
  +has been processed and user has received the response.
   
  -<P><A NAME="anchor279"></A>
  +<P>
  +[META: example of PerlCleanupHandler code?]
  +
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
  +<CENTER><H3><A NAME="Gory_Details_About_fork_">Gory Details About fork()</A></H3></CENTER>
  +<P>
  +Here is what actually happens when you <CODE>fork()</CODE> and call
  +<CODE>system().</CODE> Let's take a simple fragment of code:
  +
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  system(&quot;echo&quot;,&quot;Hi&quot;),CORE::exit(0) unless fork();</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   The above code which might be more familiar in this form:
   
  -<P><A NAME="anchor280"></A>
  -<PRE>  if (fork){
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  if (fork){
       #do nothing
     } else {
  -    system(&quot;echo Hi&quot;);
  +    system(&quot;echo&quot;,&quot;Hi&quot;);
       CORE::exit(0);
  -  }
  -</PRE>
  -<OL>
  -<P><LI>
  -<P><A NAME="anchor281"></A>
  -The <CODE>fork()</CODE> gives you two possible execution paths, one for the
  -parent and the other for the child. The child gets some virtual memory,
  -sharing a copy of the program text (read only) and a copy of the data space
  -copy-on-write (remember why you pre-load modules in mod_perl?).
  -
  -<P><A NAME="anchor282"></A>
  -In this example the parent will immediately continue with the code that
  -comes after the fork, while the forked (child) process will execute '<CODE>system(&quot;echo Hi&quot;)</CODE>' and then terminate.
  -
  -<P><A NAME="anchor283"></A>
  -The only work to be done before the child process goes on its separate way
  -is setting up the page tables for the virtual memory.
  +  }</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +Notice that we use <CODE>CORE::exit()</CODE> and not <CODE>exit()</CODE>, which would be automatically overriden by <CODE>Apache::exit()</CODE> if used in conjunction with <CODE>Apache::Registry</CODE> and similar modules.
  +
  +<P>
  +In our example script the <CODE>fork()</CODE> call creates two execution
  +paths, one for the parent and the other for the child. The fork call
  +returns the PID of the spawned child to the parent process and the child
  +process receives 0. Therefore we can rewrite the example as:
  +
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  if ($pid = fork){
  +    # I'm parent
  +    print &quot;parent $pid\n&quot;;
  +    #do nothing
  +  } else {
  +    # I'm child
  +    print &quot;child $pid\n&quot;;
  +    system(&quot;echo&quot;,&quot;Hi&quot;);
  +    CORE::exit(0);
  +  }</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +For the sake of completeness, when you write a real code, you should check
  +the return value from <CODE>fork(),</CODE> since if it returns <CODE>undef</CODE> it means that the call was unsuccessful and no process was spawned.
  +Something that can happen when the system is running too many processes and
  +cannot spawn new ones.
  +
  +<P>
  +The child shares with parent its memory pages until it has to modify some
  +of them, which triggers a copy-on-write process which copies these pages to
  +the child's domain before the child is allowed to modify them. But this all
  +happens afterwards. At the moment the <CODE>fork()</CODE> call executed,
  +the only work to be done before the child process goes on its separate way
  +is setting up the page tables for the virtual memory, which imposes almost
  +no delay at all.
  +
  +<P>
  +Unfortunately mod_perl is a big process, with a big memory pages table.
  +When the child processes executes <CODE>system(),</CODE> lots of things get
  +loaded which creates a big overhead and tremendously slows down the request
  +processing. The whole point of mod_perl is to avoid having to
  +<CODE>fork()</CODE> on every request. Perl can do just about anything by
  +itself.
  +
  +<P>
  +Let's complete the explanation of our example: the parent will immediately
  +continue with the code that comes after the fork (none in our case), while
  +the forked (child) process will execute
  +system("echo","Hi") and then quit.
   
  -<P><LI>
  -<P><A NAME="anchor284"></A>
  -Next, Perl will find <CODE>/bin/echo</CODE> along the search path, and invoke it directly. Perl's <CODE>system()</CODE>
  -is <STRONG>not</STRONG> the <CODE>system(3)</CODE> call [C-library]. Only when the command has shell metacharacters (like
  -<CODE>*</CODE>,<CODE>?</CODE>) does Perl invoke a real shell (/bin/sh&nbsp;-c on Unix platforms). If there are no shell metacharacters in the argument,
  -it is split into words and passed directly to <CODE>execvp()</CODE>, which is more efficient.
  -
  -<P><A NAME="anchor285"></A>
  -That's a <EM>very</EM> nice optimization. In other words, only if you do:
  -
  -<P><A NAME="anchor286"></A>
  -<PRE>  system &quot;sh -c 'echo *'&quot;
  -</PRE>
  -<P><A NAME="anchor287"></A>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
  +<CENTER><H3><A NAME="Executing_system_in_the_Right_">Executing system() in the Right Way</A></H3></CENTER>
  +<P>
  +Let's reuse the last example and concentrate on this call:
  +
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  system(&quot;echo&quot;,&quot;Hi&quot;);</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +Perl will the first argument as a program to execute, find
  +<CODE>/bin/echo</CODE> along the search path, and invoke it directly.
  +
  +<P>
  +Perl's <CODE>system()</CODE> is <STRONG>not</STRONG> the <CODE>system(3)</CODE> call [C-library]. How the arguments to <CODE>system()</CODE> get
  +interpreted? When there is a single argument to <CODE>system(),</CODE>
  +it'll be checked for for having shell metacharacters
  +<CODE>first(like</CODE> <CODE>*</CODE>,<CODE>?</CODE>), and if there are any--perl interpreter invokes a real shell program (/bin/sh&nbsp;-c on Unix platforms) which adds another delay. If you pass a list of
  +arguments to <CODE>system(),</CODE> they will be not checked, but split
  +into words if required and passed directly to <CODE>execvp()</CODE>, which is more efficient. That's a <EM>very</EM> nice optimization. In other words, only if you do:
  +
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  system &quot;sh -c 'echo *'&quot;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   will the operating system actually <CODE>exec()</CODE> a copy of <CODE>/bin/sh</CODE> to parse your command. But since one is almost certainly already running
   somewhere, the system will notice that (via the disk inode reference) and
   replace your virtual memory page table with one pointing to the existing
   program code plus your data space.
  -
  -<P><LI>
  -<P><A NAME="anchor288"></A>
  -Then the shell parses the passed command.
  -
  -<P><A NAME="anchor289"></A>
  -Since it is the <CODE>echo</CODE> utility, it will execute it as a built-in in the latter example or as <CODE>/bin/echo</CODE> in the former and be done, but this is only an example. You aren't calling <CODE>system(&quot;echo Hi&quot;)</CODE> in your mod_perl scripts, right?
   
  -</OL>
  -<P><A NAME="anchor290"></A>
  -Most real programs (heavy programs executed as a subprocess) would involve
  -repeating the process to load the specified command or script. This might
  -involve some actual demand paging from the program file if you execute new
  -code.
  -
  -<P><A NAME="anchor291"></A>
  -The only place you will see real overhead from this scheme is when the
  -parent process is huge (unfortunately like mod_perl...) and the page table
  -becomes large as a side effect. The whole point of mod_perl is to avoid
  -having to <CODE>fork()</CODE> or <CODE>exec()</CODE> something on every
  -hit. Perl can do just about anything by itself.
  -
  -<P><A NAME="anchor292"></A>
  -Now let's get to the gory details of forking. Normally, every process has
  -its parent. Many processes are children of the <CODE>init</CODE> process, whose <CODE>PID</CODE> is <CODE>1</CODE>. When you fork a process you must <CODE>wait()</CODE> or
  -<CODE>waitpid()</CODE> for it to finish. If you don't wait for it, it
  -becomes a zombie.
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
  +<CENTER><H3><A NAME="Avoiding_Zombie_Processes">Avoiding Zombie Processes</A></H3></CENTER>
  +<P>
  +Now let's talk about zombie processes.
  +
  +<P>
  +Normally, every process has its parent. Many processes are children of the <CODE>init</CODE> process, whose <CODE>PID</CODE> is <CODE>1</CODE>. When you fork a process you must <CODE>wait()</CODE> or
  +<CODE>waitpid()</CODE> for it to finish. If you don't <CODE>wait()</CODE>
  +for it, it becomes a zombie.
   
  -<P><A NAME="anchor293"></A>
  +<P>
   A zombie is a process that doesn't have a parent. When the child quits, it
   reports the termination to its parent. If no parent <CODE>wait()s</CODE> to
  -collect the exit status of the child, it gets ``confused'' and becomes a
  -ghost process, that can be seen, but not killed. It will be killed only
  -when you stop the httpd process that spawned it!
  +collect the exit status of the child, it gets <EM>"confused"</EM> and becomes a ghost process, that can be seen as a process, but not killed.
  +It will be killed only when you stop the parent process that spawned it!
   
  -<P><A NAME="anchor294"></A>
  -Generally the <CODE>ps()</CODE> utility displays these processes with the
  +<P>
  +Generally the <CODE>ps(1)</CODE> utility displays these processes with the
   <CODE>&lt;defunc&gt;</CODE> tag, and you will see the zombies counter increment when doing
   <CODE>top().</CODE> These zombie processes can take up system resources and
   are generally undesirable.
   
  -<P><A NAME="anchor295"></A>
  +<P>
   So the proper way to do a fork is:
   
  -<P><A NAME="anchor296"></A>
  -<PRE>  print &quot;Content-type: text/plain\r\n\r\n&quot;;
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  my $r = shift;
  +  $r-&gt;send_http_header('text/plain');
     
     defined (my $kid = fork) or die &quot;Cannot fork: $!&quot;;
     if ($kid) {
  @@ -1834,54 +3604,78 @@
     } else {
         # do something
         CORE::exit(0);
  -  }
  -</PRE>
  -<P><A NAME="anchor297"></A>
  +  }</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   In most cases the only reason you would want to fork is when you need to
  -spawn a process that will take a long time to complete. So if the server
  -child that spawns this process has to wait for it to finish, you have
  -gained nothing. You can neither wait for its completion, nor continue
  -because you will get yet another zombie process. This is called a blocking
  -call, since the process is blocked to so anything else before this call
  -gets completed.
  -
  -<P><A NAME="anchor298"></A>
  -The simplest solution is to ignore your dead children. This doesn't work
  -everywhere, however.
  -
  -<P><A NAME="anchor299"></A>
  -META: do you know where? tell me!!! It works with linux!:)
  -
  -<P><A NAME="anchor300"></A>
  -<PRE>  $SIG{CHLD} = IGNORE;
  -</PRE>
  -<P><A NAME="anchor301"></A>
  -When you set the <CODE>CHLD</CODE> signal handler to <CODE>IGNORE</CODE>, all the processes will be collected by the <CODE>init</CODE> process and are therefore prevented from becoming zombies.
  +spawn a process that will take a long time to complete. So if the Apache
  +process that spawns this new child process has to wait for it to finish,
  +you have gained nothing. You can neither wait for its completion (because
  +you don't have the time to), nor continue because you will get yet another
  +zombie process. This is called a blocking call, since the process is
  +blocked to do anything else before this call gets completed.
  +
  +<P>
  +The simplest solution is to ignore your dead children. Just add this line
  +before the <CODE>fork()</CODE> call:
  +
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  $SIG{CHLD} = IGNORE;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +When you set the <CODE>CHLD</CODE> (<CODE>SIGCHLD</CODE> in C) signal handler to
  +<CODE>IGNORE</CODE>, all the processes will be collected by the <CODE>init</CODE> process and are therefore prevented from becoming zombies. This doesn't
  +work everywhere, however. It proved to work at least on Linux OS.
   
  -<P><A NAME="anchor302"></A>
  +<P>
   Note that you cannot localize this setting with <CODE>local()</CODE>. If you do, it won't have the desired effect.
   
  -<P><A NAME="anchor303"></A>
  -META: Anyone like to explain why it doesn't work?
  +<P>
  +[META: Anyone like to explain why it doesn't work?]
   
  -<P><A NAME="anchor304"></A>
  +<P>
   The other thing that you must do is to close all the pipes to the
  -connection socket that were opened by the parent process (<CODE>STDIN</CODE> and
  -<CODE>STDOUT</CODE>) and inherited by the child, so the parent will be able to complete the
  +connection socket that were opened by the parent process (i.e. <CODE>STDIN</CODE> and <CODE>STDOUT</CODE>) and inherited by the child, so the parent will be able to complete the
   request and free itself for serving other requests. You may need to close
  -and reopen the <CODE>STDERR</CODE> filehandle. It's opened to append to the <EM>error_log</EM> file as inherited by its parent, so chances are that you will want to leave
  -it untouched.
  +and reopen the
  +<CODE>STDERR</CODE> filehandle. It's opened to append to the <EM>error_log</EM> file as inherited from its parent, so chances are that you will want to
  +leave it untouched.
   
  -<P><A NAME="anchor305"></A>
  +<P>
   Of course if your child needs any of the <CODE>STDIN</CODE>, <CODE>STDOUT</CODE> or
   <CODE>STDERR</CODE> streams you should reopen them. But you must untie the parent process, so
   you should close them first.
   
  -<P><A NAME="anchor306"></A>
  +<P>
   So now the code would look like this:
  +
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
   
  -<P><A NAME="anchor307"></A>
  -<PRE>  print &quot;Content-type: text/plain\r\n\r\n&quot;;
  +	<td>
  +	  <pre>  my $r = shift;
  +  $r-&gt;send_http_header('text/plain');
     
     $SIG{CHLD} = IGNORE;
     
  @@ -1894,18 +3688,31 @@
         close STDERR;
         # do something time-consuming
         CORE::exit(0);
  -  }
  -</PRE>
  -<P><A NAME="anchor308"></A>
  -Note that <CODE>waitpid()</CODE> call has gone. The <CODE>$SIG{CHLD} = IGNORE;</CODE>
  +  }</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +Note that <CODE>waitpid()</CODE> call has gone. The $SIG{CHLD}&nbsp;=&nbsp;IGNORE;
   statement protects us from zombies, as explained above.
   
  -<P><A NAME="anchor309"></A>
  +<P>
   Another, more portable, but slightly more expensive solution is to use a
   double fork approach.
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor310"></A>
  -<PRE>  print &quot;Content-type: text/plain\r\n\r\n&quot;;
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  my $r = shift;
  +  $r-&gt;send_http_header('text/plain');
     
     defined (my $kid = fork) or die &quot;Cannot fork: $!\n&quot;;
     if ($kid) {
  @@ -1923,23 +3730,38 @@
         # do something long lasting
         CORE::exit(0);
       }
  -  }
  -</PRE>
  -<P><A NAME="anchor311"></A>
  -Grandkid becomes a <EM>"child of init"</EM>, i.e. the parent process ID is 1.
  +  }</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +Grandkid becomes a <EM>"child of init"</EM>, i.e. the child of the process whose PID is 1.
   
  -<P><A NAME="anchor312"></A>
  +<P>
   Note that the previous two solutions do allow you to know the exit status
  -of the process, but in our case we don't want to.
  +of the process, but in our example we didn't care about it.
   
  -<P><A NAME="anchor313"></A>
  +<P>
   Another solution is to use a different <EM>SIGCHLD</EM> handler:
  +
  +<P>
   
  -<P><A NAME="anchor314"></A>
  -<PRE>  use POSIX 'WNOHANG';
  -  $SIG{CHLD} = sub { while( waitpid(-1,WNOHANG)&gt;0 ) {} };
  -</PRE>
  -<P><A NAME="anchor315"></A>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  use POSIX 'WNOHANG';
  +  $SIG{CHLD} = sub { while( waitpid(-1,WNOHANG)&gt;0 ) {} };</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Which is useful when you <CODE>fork()</CODE> more than one process. The
   handler could call <CODE>wait()</CODE> as well, but for a variety of
   reasons involving the handling of stopped processes and the rare event in
  @@ -1949,48 +3771,50 @@
   to be no child ready for reaping. The handler will loop until
   <CODE>waitpid()</CODE> returns a negative number or zero, indicating that
   no more reapable children remain.
  +
  +<P>
  +While you test and debug your code that uses one of the above examples, You
  +might want to write some debug information to the error_log file so you
  +know what happens.
   
  -<P><A NAME="anchor316"></A>
  -You will probably want to open your own log file in the spawned process and
  -log some information (at least while debugging your code) so you know what
  -has happened.
  +<P>
  +Read <EM>perlipc</EM> manpage for more information about signal handlers.
   
  -<P><A NAME="anchor317"></A>
  +<P>
   Check also <A HREF="././modules.html#Apache_SubProcess">Apache::SubProcess</A> for better <CODE>system()</CODE> and <CODE>exec()</CODE> implementations
   for mod_perl.
   
  -<P><A NAME="anchor318"></A>
  +<P>
   META: why is it a better thing to use?
  -
  -<P><A NAME="anchor319"></A>
  -Read <EM>perlipc</EM> manpage for more information about signal handlers.
   
  -<P><A NAME="anchor320"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="OS_Specific_Parameters_for_Proxy">OS Specific Parameters for Proxying</A></H2></CENTER>
  -<P><A NAME="anchor321"></A>
  +<P>
   Most of the mod_perl enabled servers use a proxy front-end server. This is
   done in order to avoid serving static objects, and also so that generated
   output which might be received by slow clients does not cause the heavy but
   very fast mod_perl servers from idly waiting.
   
  -<P><A NAME="anchor322"></A>
  +<P>
   There are very important OS parameters that you might want to change in
   order to improve the server performance. This topic is discussed in the
   section: <A HREF="././scenario.html#Setting_the_Buffering_Limits_on_">Setting the Buffering Limits on Various OSes</A>
   
   
   
  -<P><A NAME="anchor323"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H1><A NAME="Performance_Tuning_by_Tweaking_A">Performance Tuning by Tweaking Apache Configuration</A></H1></CENTER>
  -<P><A NAME="anchor324"></A>
  +<P>
   Correct configuration of the <CODE>MinSpareServers</CODE>, <CODE>MaxSpareServers</CODE>,
   <CODE>StartServers</CODE>, <CODE>MaxClients</CODE>, and <CODE>MaxRequestsPerChild</CODE> parameters is very important. There are no defaults. If they are too low,
   you will under-use the system's capabilities. If they are too high, the
   chances are that the server will bring the machine to its knees.
   
  -<P><A NAME="anchor325"></A>
  +<P>
   All the above parameters should be specified on the basis of the resources
   you have. With a plain apache server, it's no big deal if you run many
   servers since the processes are about 1Mb and don't eat a lot of your RAM.
  @@ -2002,7 +3826,7 @@
   benchmarking the server. Again mod_perl processes can be of much smaller
   size with memory sharing.
   
  -<P><A NAME="anchor326"></A>
  +<P>
   Before you start this task you should be armed with the proper weapon. You
   need the <STRONG>crashme</STRONG> utility, which will load your server with the mod_perl scripts you possess.
   You need it to have the ability to emulate a multiuser environment and to
  @@ -2012,7 +3836,7 @@
   <A HREF="././performance.html#Tuning_with_ab_ApacheBench">ApacheBench</A>  <STRONG><CODE>ab</CODE></STRONG> utility which comes with the Apache distribution, the <A HREF="././performance.html#Tuning_with_the_crashme_Script">crashme script</A> which uses
   <CODE>LWP::Parallel::UserAgent</CODE> or <CODE>httperf</CODE> (see the <A HREF="././download.html#">Download page</A>).
   
  -<P><A NAME="anchor327"></A>
  +<P>
   It is important to make sure that you run the load generator (the client
   which generates the test requests) on a system that is more powerful than
   the system being tested. After all we are trying to simulate Internet
  @@ -2023,33 +3847,55 @@
   test results would be invalid. Clients will eat CPU and memory that should
   be dedicated to the server, and vice versa.
   
  -<P><A NAME="anchor328"></A>
  +<P>
   See also two tools for benchmarking:
   <A HREF="././performance.html#Tuning_with_ab_ApacheBench">ApacheBench</A> and <A HREF="././performance.html#Tuning_with_the_crashme_Script">crashme test</A>
   
   
   
  -<P><A NAME="anchor329"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="Tuning_with_ab_ApacheBench">Tuning with ab - ApacheBench</A></H2></CENTER>
  -<P><A NAME="anchor330"></A>
  +<P>
   ApacheBench (<STRONG>ab</STRONG>) is a tool for benchmarking your Apache HTTP server. It is designed to
   give you an idea of the performance that your current Apache installation
   can give. In particular, it shows you how many requests per second your
   Apache server is capable of serving. The <STRONG>ab</STRONG> tool comes bundled with the Apache source distribution, and it's free. :)
   
  -<P><A NAME="anchor331"></A>
  +<P>
   Let's try it. We will simulate 10 users concurrently requesting a very
   light script at <CODE>www.example.com:81/test/test.pl</CODE>. Each simulated user makes 10 requests.
   
  -<P><A NAME="anchor332"></A>
  -<PRE>  % ./ab -n 100 -c 10 www.example.com:81/test/test.pl
  -</PRE>
  -<P><A NAME="anchor333"></A>
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  % ./ab -n 100 -c 10 www.example.com:81/test/test.pl</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   The results are:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor334"></A>
  -<PRE>  Concurrency Level:      10
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  Concurrency Level:      10
     Time taken for tests:   0.715 seconds
     Complete requests:      100
     Failed requests:        0
  @@ -2063,72 +3909,147 @@
                   min   avg   max
     Connect:        0     0     3
     Processing:    13    67    71
  -  Total:         13    67    74
  -</PRE>
  -<P><A NAME="anchor335"></A>
  +  Total:         13    67    74</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   The only numbers we really care about are:
  +
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
   
  -<P><A NAME="anchor336"></A>
  -<PRE>  Complete requests:      100
  +	<td>
  +	  <pre>  Complete requests:      100
     Failed requests:        0
  -  Requests per second:    139.86
  -</PRE>
  -<P><A NAME="anchor337"></A>
  +  Requests per second:    139.86</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Let's raise the request load to 100 x 10 (10 users, each makes 100
   requests):
  +
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
   
  -<P><A NAME="anchor338"></A>
  -<PRE>  % ./ab -n 1000 -c 10 www.example.com:81/perl/access/access.cgi
  +	<td>
  +	  <pre>  % ./ab -n 1000 -c 10 www.example.com:81/perl/access/access.cgi
     Concurrency Level:      10
     Complete requests:      1000
     Failed requests:        0
  -  Requests per second:    139.76
  -</PRE>
  -<P><A NAME="anchor339"></A>
  +  Requests per second:    139.76</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   As expected, nothing changes -- we have the same 10 concurrent users. Now
   let's raise the number of concurrent users to 50:
   
  -<P><A NAME="anchor340"></A>
  -<PRE>  % ./ab -n 1000 -c 50 www.example.com:81/perl/access/access.cgi
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  % ./ab -n 1000 -c 50 www.example.com:81/perl/access/access.cgi
     Complete requests:      1000
     Failed requests:        0
  -  Requests per second:    133.01
  -</PRE>
  -<P><A NAME="anchor341"></A>
  +  Requests per second:    133.01</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   We see that the server is capable of serving 50 concurrent users at an
   amazing 133 requests per second! Let's find the upper limit. Using
   <CODE>-n 10000 -c 1000</CODE> failed to get results (Broken Pipe?). Using <CODE>-n
   10000 -c 500</CODE> resulted in 94.82 requests per second. The server's performance went down
   with the high load.
   
  -<P><A NAME="anchor342"></A>
  +<P>
   The above tests were performed with the following configuration:
  +
  +<P>
   
  -<P><A NAME="anchor343"></A>
  -<PRE>  MinSpareServers 8
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  MinSpareServers 8
     MaxSpareServers 6
     StartServers 10
     MaxClients 50
  -  MaxRequestsPerChild 1500
  -</PRE>
  -<P><A NAME="anchor344"></A>
  +  MaxRequestsPerChild 1500</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Now let's kill each child after it serves a single request. We will use the
   following configuration:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor345"></A>
  -<PRE>  MinSpareServers 8
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  MinSpareServers 8
     MaxSpareServers 6
     StartServers 10
     MaxClients 100
  -  MaxRequestsPerChild 1
  -</PRE>
  -<P><A NAME="anchor346"></A>
  +  MaxRequestsPerChild 1</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Simulate 50 users each generating a total of 20 requests:
  +
  +<P>
   
  -<P><A NAME="anchor347"></A>
  -<PRE>  % ./ab -n 1000 -c 50 www.example.com:81/perl/access/access.cgi
  -</PRE>
  -<P><A NAME="anchor348"></A>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  % ./ab -n 1000 -c 50 www.example.com:81/perl/access/access.cgi</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   The benchmark timed out with the above configuration.... I watched the
   output of <STRONG><CODE>ps</CODE></STRONG> as I ran it, the parent process just wasn't capable of respawning the
   killed children at that rate. When I raised the
  @@ -2136,30 +4057,42 @@
   can't benchmark the importance of the
   <CODE>MinSpareServers</CODE>, <CODE>MaxSpareServers</CODE> and <CODE>StartServers</CODE> with this kind of test.
   
  -<P><A NAME="anchor349"></A>
  +<P>
   Now let's reset <CODE>MaxRequestsPerChild</CODE> to 1500, but reduce
   <CODE>MaxClients</CODE> to 10 and run the same test:
  +
  +<P>
   
  -<P><A NAME="anchor350"></A>
  -<PRE>  MinSpareServers 8
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  MinSpareServers 8
     MaxSpareServers 6
     StartServers 10
     MaxClients 10
  -  MaxRequestsPerChild 1500
  -</PRE>
  -<P><A NAME="anchor351"></A>
  +  MaxRequestsPerChild 1500</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   I got 27.12 requests per second, which is better but still 4-5 times
   slower. (I got 133 with <CODE>MaxClients</CODE> set to 50.)
   
  -<P><A NAME="anchor352"></A>
  +<P>
   <STRONG>Summary:</STRONG> I have tested a few combinations of the server configuration variables (<CODE>MinSpareServers</CODE>, <CODE>MaxSpareServers</CODE>,
   <CODE>StartServers</CODE>, <CODE>MaxClients</CODE> and <CODE>MaxRequestsPerChild</CODE>). The results I got are as follows:
   
  -<P><A NAME="anchor353"></A>
  +<P>
   <CODE>MinSpareServers</CODE>, <CODE>MaxSpareServers</CODE> and <CODE>StartServers</CODE> are only important for user response times. Sometimes users will have to
   wait a bit.
   
  -<P><A NAME="anchor354"></A>
  +<P>
   The important parameters are <CODE>MaxClients</CODE> and <CODE>MaxRequestsPerChild</CODE>.
   <CODE>MaxClients</CODE> should be not too big, so it will not abuse your machine's memory
   resources, and not too small, for if it is your users will be forced to
  @@ -2169,73 +4102,121 @@
   leaking memory, thereby causing your server (and your service) to die very
   fast.
   
  -<P><A NAME="anchor355"></A>
  +<P>
   Also it is important to understand that we didn't test the response times
   in the tests above, but the ability of the server to respond under a heavy
   load of requests. If the test script was heavier, the numbers would be
   different but the conclusions very similar.
   
  -<P><A NAME="anchor356"></A>
  +<P>
   The benchmarks were run with:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor357"></A>
  -<PRE>  HW: RS6000, 1Gb RAM
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  HW: RS6000, 1Gb RAM
     SW: AIX 4.1.5 . mod_perl 1.16, apache 1.3.3
     Machine running only mysql, httpd docs and mod_perl servers.
  -  Machine was _completely_ unloaded during the benchmarking.
  -</PRE>
  -<P><A NAME="anchor358"></A>
  +  Machine was _completely_ unloaded during the benchmarking.</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   After each server restart when I changed the server's configuration, I made
   sure that the scripts were preloaded by fetching a script at least once for
   every child.
   
  -<P><A NAME="anchor359"></A>
  +<P>
   It is important to notice that none of the requests timed out, even if it
   was kept in the server's queue for more than a minute! That is the way <STRONG>ab</STRONG> works, which is OK for testing purposes but will be unacceptable in the
   real world - users will not wait for more than five to ten seconds for a
   request to complete, and the client (i.e. the browser) will time out in a
   few minutes.
   
  -<P><A NAME="anchor360"></A>
  +<P>
   Now let's take a look at some real code whose execution time is more than a
   few milliseconds. We will do some real testing and collect the data into
   tables for easier viewing.
   
  -<P><A NAME="anchor361"></A>
  +<P>
   I will use the following abbreviations:
  +
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
   
  -<P><A NAME="anchor362"></A>
  -<PRE>  NR    = Total Number of Request
  +	<td>
  +	  <pre>  NR    = Total Number of Request
     NC    = Concurrency
     MC    = MaxClients
     MRPC  = MaxRequestsPerChild
  -  RPS   = Requests per second
  -</PRE>
  -<P><A NAME="anchor363"></A>
  +  RPS   = Requests per second</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Running a mod_perl script with lots of mysql queries (the script under test
   is mysqld limited)
   (http://www.example.com:81/perl/access/access.cgi?do_sub=query_form), with
   the configuration:
   
  -<P><A NAME="anchor364"></A>
  -<PRE>  MinSpareServers        8
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  MinSpareServers        8
     MaxSpareServers       16
     StartServers          10
     MaxClients            50
  -  MaxRequestsPerChild 5000
  -</PRE>
  -<P><A NAME="anchor365"></A>
  +  MaxRequestsPerChild 5000</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   gives us:
   
  -<P><A NAME="anchor366"></A>
  -<PRE>     NR   NC    RPS     comment
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>     NR   NC    RPS     comment
     ------------------------------------------------
        10   10    3.33    # not a reliable figure
       100   10    3.94    
      1000   10    4.62    
  -   1000   50    4.09    
  -</PRE>
  -<P><A NAME="anchor367"></A>
  +   1000   50    4.09    </pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   <STRONG>Conclusions:</STRONG> Here I wanted to show that when the application is slow (not due to perl
   loading, code compilation and execution, but limited by some external
   operation) it almost does not matter what load we place on the server. The
  @@ -2244,20 +4225,41 @@
   that anything that goes into the queue means a waiting client and a client
   (browser) that might time out!
   
  -<P><A NAME="anchor368"></A>
  +<P>
   Now we will benchmark the same script without using the mysql (code limited
   by perl only): (http://www.example.com:81/perl/access/access.cgi), it's the
   same script but it just returns the HTML form, without making SQL queries.
  +
  +<P>
   
  -<P><A NAME="anchor369"></A>
  -<PRE>  MinSpareServers        8
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  MinSpareServers        8
     MaxSpareServers       16
     StartServers          10
     MaxClients            50
  -  MaxRequestsPerChild 5000
  -</PRE>
  -<P><A NAME="anchor370"></A>
  -<PRE>     NR   NC      RPS   comment
  +  MaxRequestsPerChild 5000</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>     NR   NC      RPS   comment
     ------------------------------------------------
        10   10    26.95   # not a reliable figure
       100   10    30.88   
  @@ -2265,9 +4267,12 @@
      1000   50    28.01
      1000  100    29.74
     10000  200    24.92
  - 100000  400    24.95
  -</PRE>
  -<P><A NAME="anchor371"></A>
  + 100000  400    24.95</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   <STRONG>Conclusions:</STRONG> This time the script we executed was pure perl (not limited by I/O or
   mysql), so we see that the server serves the requests much faster. You can
   see the number of requests per second is almost the same for any load, but
  @@ -2276,13 +4281,22 @@
   concurrent clients and 30 requests per second, the client will be served in
   3.5 seconds. Pretty good for a highly loaded server.
   
  -<P><A NAME="anchor372"></A>
  +<P>
   Now we will use the server to its full capacity, by keeping all
   <CODE>MaxClients</CODE> clients alive all the time and having a big
   <CODE>MaxRequestsPerChild</CODE>, so that no child will be killed during the benchmarking.
   
  -<P><A NAME="anchor373"></A>
  -<PRE>  MinSpareServers       50
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  MinSpareServers       50
     MaxSpareServers       50
     StartServers          50
     MaxClients            50
  @@ -2294,19 +4308,31 @@
      1000   10    33.14
      1000   50    33.17
      1000  100    31.72
  -  10000  200    31.60
  -</PRE>
  -<P><A NAME="anchor374"></A>
  +  10000  200    31.60</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Conclusion: In this scenario there is no overhead involving the parent
   server loading new children, all the servers are available, and the only
   bottleneck is contention for the CPU.
   
  -<P><A NAME="anchor375"></A>
  +<P>
   Now we will change <CODE>MaxClients</CODE> and watch the results: Let's reduce
   <CODE>MaxClients</CODE> to 10.
  +
  +<P>
   
  -<P><A NAME="anchor376"></A>
  -<PRE>  MinSpareServers        8
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  MinSpareServers        8
     MaxSpareServers       10
     StartServers          10
     MaxClients            10
  @@ -2320,9 +4346,12 @@
      1000   50    30.43
      1000  100    25.68
      1000  500    26.95
  -   2000  500    32.53
  -</PRE>
  -<P><A NAME="anchor377"></A>
  +   2000  500    32.53</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   <STRONG>Conclusions:</STRONG> Very little difference! Ten servers were able to serve almost with the same
   throughput as 50 servers. Why? My guess is because of CPU throttling. It
   seems that 10 servers were serving requests 5 times faster than when we
  @@ -2330,33 +4359,66 @@
   slice five times less frequently. So having a big value for <CODE>MaxClients</CODE>, doesn't mean that the performance will be better. You have just seen the
   numbers!
   
  -<P><A NAME="anchor378"></A>
  +<P>
   Now we will start drastically to reduce <CODE>MaxRequestsPerChild</CODE>:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor379"></A>
  -<PRE>  MinSpareServers        8
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  MinSpareServers        8
     MaxSpareServers       16
     StartServers          10
  -  MaxClients            50
  -</PRE>
  -<P><A NAME="anchor380"></A>
  -<PRE>     NR   NC    MRPC     RPS    comment
  +  MaxClients            50</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>     NR   NC    MRPC     RPS    comment
     ------------------------------------------------
       100   10      10    5.77 
       100   10       5    3.32
      1000   50      20    8.92
      1000   50      10    5.47
      1000   50       5    2.83
  -   1000  100      10    6.51
  -</PRE>
  -<P><A NAME="anchor381"></A>
  +   1000  100      10    6.51</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   <STRONG>Conclusions:</STRONG> When we drastically reduce <CODE>MaxRequestsPerChild</CODE>, the performance starts to become closer to plain mod_cgi. 
   
  -<P><A NAME="anchor382"></A>
  +<P>
   Here are the numbers of this run with mod_cgi, for comparison:
  +
  +<P>
   
  -<P><A NAME="anchor383"></A>
  -<PRE>  MinSpareServers        8
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  MinSpareServers        8
     MaxSpareServers       16
     StartServers          10
     MaxClients            50
  @@ -2365,30 +4427,46 @@
     ------------------------------------------------
       100   10    1.12
      1000   50    1.14
  -   1000  100    1.13
  -</PRE>
  -<P><A NAME="anchor384"></A>
  +   1000  100    1.13</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   <STRONG>Conclusion</STRONG>: mod_cgi is much slower. :) In the first test, when NR/NC was 100/10,
   mod_cgi was capable of 1.12 requests per second. In the same circumstances,
   mod_perl was capable of 32 requests per second, nearly 30 times faster! In
   the first test each client waited about 100 seconds to be served. In the
   second and third tests they waited 1000 seconds!
   
  -<P><A NAME="anchor385"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="Tuning_with_httperf">Tuning with httperf</A></H2></CENTER>
  -<P><A NAME="anchor386"></A>
  +<P>
   httperf is a utility written by David Mosberger. Just like ApacheBench, it
   measures the performance of the webserver.
   
  -<P><A NAME="anchor387"></A>
  +<P>
   A sample command line is shown below:
  +
  +<P>
   
  -<P><A NAME="anchor388"></A>
  -<PRE>  httperf --server hostname --port 80 --uri /test.html \
  -   --rate 150 --num-conn 27000 --num-call 1 --timeout 5
  -</PRE>
  -<P><A NAME="anchor389"></A>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  httperf --server hostname --port 80 --uri /test.html \
  +   --rate 150 --num-conn 27000 --num-call 1 --timeout 5</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   This command causes httperf to use the web server on the host with IP name
   hostname, running at port 80. The web page being retrieved is
   <EM>/test.html</EM> and, in this simple test, the same page is retrieved repeatedly. The rate
  @@ -2397,16 +4475,25 @@
   HTTP call is performed. A call consists of sending a request and receiving
   a reply.
   
  -<P><A NAME="anchor390"></A>
  +<P>
   The timeout option defines the number of seconds that the client is willing
   to wait to hear back from the server. If this timeout expires, the tool
   considers the corresponding call to have failed. Note that with a total of
   27,000 connections and a rate of 150 per second, the total test duration
   will be approximately 180 seconds (27,000/150), independently of what load
   the server can actually sustain. Here is a result that one might get:
  +
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
   
  -<P><A NAME="anchor391"></A>
  -<PRE>     Total: connections 27000 requests 26701 replies 26701 test-duration 179.996 s
  +	<td>
  +	  <pre>     Total: connections 27000 requests 26701 replies 26701 test-duration 179.996 s
       
        Connection rate: 150.0 conn/s (6.7 ms/conn, &lt;=47 concurrent connections)
        Connection time [ms]: min 1.1 avg 5.0 max 315.0 median 2.5 stddev 13.0
  @@ -2424,12 +4511,16 @@
        Net I/O: 190.9 KB/s (1.6*10^6 bps)
        
        Errors: total 299 client-timo 299 socket-timo 0 connrefused 0 connreset 0
  -     Errors: fd-unavail 0 addrunavail 0 ftab-full 0 other 0
  -</PRE>
  -<P><A NAME="anchor392"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +     Errors: fd-unavail 0 addrunavail 0 ftab-full 0 other 0</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="Tuning_with_the_crashme_Script">Tuning with the crashme Script</A></H2></CENTER>
  -<P><A NAME="anchor393"></A>
  +<P>
   This is another crashme suite originally written by Michael Schilli and
   located at <A
   HREF="http://www.linux-magazin.de/ausgabe.1998.08/Pounder/pounder.html">http://www.linux-magazin.de/ausgabe.1998.08/Pounder/pounder.html</A>
  @@ -2437,36 +4528,57 @@
   also allowed it to accept more than one url to test, since sometimes you
   want to test more than one script.
   
  -<P><A NAME="anchor394"></A>
  +<P>
   The tool provides the same results as <STRONG>ab</STRONG> above but it also allows you to set the timeout value, so requests will
   fail if not served within the time out period. You also get values for <STRONG>Latency</STRONG>
   (seconds per request) and <STRONG>Throughput</STRONG> (requests per second). It can do a complete simulation of your favorite
   Netscape browser :) and give you a better picture.
   
  -<P><A NAME="anchor395"></A>
  +<P>
   I have noticed while running these two benchmarking suites, that <STRONG>ab</STRONG>
   gave me results from two and a half to three times better. Both suites were
   run on the same machine, with the same load and the same parameters, but
   the implementations were different.
   
  -<P><A NAME="anchor396"></A>
  +<P>
   Sample output:
  +
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
   
  -<P><A NAME="anchor397"></A>
  -<PRE>  URL(s):          <A HREF="http://www.example.com:81/perl/access/access.cgi">http://www.example.com:81/perl/access/access.cgi</A>
  +	<td>
  +	  <pre>  URL(s):          <A HREF="http://www.example.com:81/perl/access/access.cgi">http://www.example.com:81/perl/access/access.cgi</A>
     Total Requests:  100
     Parallel Agents: 10
     Succeeded:       100 (100.00%)
     Errors:          NONE
     Total Time:      9.39 secs
     Throughput:      10.65 Requests/sec
  -  Latency:         0.85 secs/Request
  -</PRE>
  -<P><A NAME="anchor398"></A>
  +  Latency:         0.85 secs/Request</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   And the code:
   
  -<P><A NAME="anchor399"></A>
  -<PRE>  #!/usr/apps/bin/perl -w
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  #!/usr/apps/bin/perl -w
     
     use LWP::Parallel::UserAgent;
     use Time::HiRes qw(gettimeofday tv_interval);
  @@ -2605,12 +4717,16 @@
     
     while(($left, $right) = splice(@P, 0, 2)) {
       write;
  -  }
  -</PRE>
  -<P><A NAME="anchor400"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +  }</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="Choosing_MaxClients">Choosing MaxClients</A></H2></CENTER>
  -<P><A NAME="anchor401"></A>
  +<P>
   The <CODE>MaxClients</CODE> directive sets the limit on the number of simultaneous requests that can be
   supported. No more than this number of child server processes will be
   created. To configure more than 256 clients, you must edit the <CODE>HARD_SERVER_LIMIT</CODE> entry in <CODE>httpd.h</CODE>
  @@ -2618,34 +4734,58 @@
   possible, because in this way we can limit the resources used by the server
   children. Since we can restrict each child's process size (see
   <A HREF="././performance.html#Limiting_the_Size_of_the_Process">Limiting the size of the processes</A>), the calculation of <CODE>MaxClients</CODE> is pretty straightforward:
  +
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
   
  -<P><A NAME="anchor402"></A>
  -<PRE>               Total RAM Dedicated to the Webserver
  +	<td>
  +	  <pre>               Total RAM Dedicated to the Webserver
     MaxClients = ------------------------------------
  -                     MAX child's process size
  -</PRE>
  -<P><A NAME="anchor403"></A>
  +                     MAX child's process size</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   So if I have 400Mb left for the webserver to run with, I can set
   <CODE>MaxClients</CODE> to be of 40 if I know that each child is limited to 10Mb of memory (e.g.
   with
   <A HREF="././performance.html#Limiting_the_Size_of_the_Process"><CODE>Apache::SizeLimit</CODE></A>).
   
  -<P><A NAME="anchor404"></A>
  +<P>
   You will be wondering what will happen to your server if there are more
   concurrent users than <CODE>MaxClients</CODE> at any time. This situation is signified by the following warning message
   in the <CODE>error_log</CODE>:
   
  -<P><A NAME="anchor405"></A>
  -<PRE>  [Sun Jan 24 12:05:32 1999] [error] server reached MaxClients setting,
  -  consider raising the MaxClients setting
  -</PRE>
  -<P><A NAME="anchor406"></A>
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  [Sun Jan 24 12:05:32 1999] [error] server reached MaxClients setting,
  +  consider raising the MaxClients setting</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   There is no problem -- any connection attempts over the <CODE>MaxClients</CODE>
   limit will normally be queued, up to a number based on the
   <CODE>ListenBacklog</CODE> directive. When a child process is freed at the end of a different request,
   the connection will be served.
   
  -<P><A NAME="anchor407"></A>
  +<P>
   It <STRONG>is an error</STRONG> because clients are being put in the queue rather than getting served
   immediately, despite the fact that they do not get an error response. The
   error can be allowed to persist to balance available system resources and
  @@ -2654,101 +4794,186 @@
   condition reached at all, and if you reach it often you should start to
   worry about it.
   
  -<P><A NAME="anchor408"></A>
  +<P>
   It's important to understand how much real memory a child occupies. Your
   children can share memory between them when the OS supports that. You must
  -take action to allow the sharing to happen - See <A HREF="././performance.html#Preload_Perl_Modules_at_Server_S">Preload Perl modules at server startup</A>. If you do this, the chances are that your <CODE>MaxClients</CODE> can be even higher. But it seems that it's not so simple to calculate the
  +take action to allow the sharing to happen - See <A HREF="././performance.html#Preloading_Perl_Modules_at_Serve">Preload Perl modules at server startup</A>. If you do this, the chances are that your <CODE>MaxClients</CODE> can be even higher. But it seems that it's not so simple to calculate the
   absolute number. If you come up with a solution please let us know! If the
   shared memory was of the same size throughout the child's life, we could
   derive a much better formula:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor409"></A>
  -<PRE>               Total_RAM + Shared__RAM_per_Child * MaxClients
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>               Total_RAM + Shared__RAM_per_Child * MaxClients
     MaxClients = ---------------------------------------------
  -                        Max_Process_Size - 1
  -</PRE>
  -<P><A NAME="anchor410"></A>
  +                        Max_Process_Size - 1</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   which is:
  +
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
   
  -<P><A NAME="anchor411"></A>
  -<PRE>                    Total_RAM - Max_Process_Size
  +	<td>
  +	  <pre>                    Total_RAM - Max_Process_Size
     MaxClients = ---------------------------------------
  -               Max_Process_Size - Shared_RAM_per_Child
  -</PRE>
  -<P><A NAME="anchor412"></A>
  +               Max_Process_Size - Shared_RAM_per_Child</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Let's roll some calculations:
   
  -<P><A NAME="anchor413"></A>
  -<PRE>  Total_RAM            = 500Mb
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  Total_RAM            = 500Mb
     Max_Process_Size     =  10Mb
  -  Shared_RAM_per_Child =   4Mb
  -</PRE>
  -<P><A NAME="anchor414"></A>
  -<PRE>              500 - 10
  +  Shared_RAM_per_Child =   4Mb</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>              500 - 10
    MaxClients = --------- = 81
  -               10 - 4
  -</PRE>
  -<P><A NAME="anchor415"></A>
  +               10 - 4</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   With no sharing in place
   
  -<P><A NAME="anchor416"></A>
  -<PRE>                 500
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>                 500
    MaxClients = --------- = 50
  -                 10
  -</PRE>
  -<P><A NAME="anchor417"></A>
  +                 10</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   With sharing in place you can have 60% more servers without buying more
   RAM.
   
  -<P><A NAME="anchor418"></A>
  +<P>
   If you improve sharing and keep the sharing level, let's say:
  +
  +<P>
   
  -<P><A NAME="anchor419"></A>
  -<PRE>  Total_RAM            = 500Mb
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  Total_RAM            = 500Mb
     Max_Process_Size     =  10Mb
  -  Shared_RAM_per_Child =   8Mb
  -</PRE>
  -<P><A NAME="anchor420"></A>
  -<PRE>              500 - 10
  +  Shared_RAM_per_Child =   8Mb</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>              500 - 10
    MaxClients = --------- = 245
  -               10 - 8
  -</PRE>
  -<P><A NAME="anchor421"></A>
  +               10 - 8</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   390% more servers! Now you can feel the importance of having as much shared
   memory as possible.
   
  -<P><A NAME="anchor422"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="Choosing_MaxRequestsPerChild">Choosing MaxRequestsPerChild</A></H2></CENTER>
  -<P><A NAME="anchor423"></A>
  +<P>
   The <CODE>MaxRequestsPerChild</CODE> directive sets the limit on the number of requests that an individual child
   server process will handle. After
   <CODE>MaxRequestsPerChild</CODE> requests, the child process will die. If
   <CODE>MaxRequestsPerChild</CODE> is 0, then the process will live forever.
   
  -<P><A NAME="anchor424"></A>
  +<P>
   Setting <CODE>MaxRequestsPerChild</CODE> to a non-zero limit solves some memory leakage problems caused by sloppy
   programming practices, whereas a child process consumes more memory after
   each request.
   
  -<P><A NAME="anchor425"></A>
  +<P>
   If left unbounded, then after a certain number of requests the children
   will use up all the available memory and leave the server to die from
   memory starvation. Note that sometimes standard system libraries leak
   memory too, especially on OSes with bad memory management (e.g. Solaris 2.5
   on x86 arch).
   
  -<P><A NAME="anchor426"></A>
  +<P>
   If this is your case you can set <CODE>MaxRequestsPerChild</CODE> to a small number. This will allow the system to reclaim the memory that a
   greedy child process consumed, when it exits after
   <CODE>MaxRequestsPerChild</CODE> requests.
   
  -<P><A NAME="anchor427"></A>
  +<P>
   But beware -- if you set this number too low, you will lose some of the
   speed bonus you get from mod_perl. Consider using
   <CODE>Apache::PerlRun</CODE> if this is the case.
   
  -<P><A NAME="anchor428"></A>
  +<P>
   Another approach is to use the
   <A HREF="././performance.html#Limiting_the_Size_of_the_Process">Apache::SizeLimit</A> or the <A HREF="././performance.html#Keeping_the_Shared_Memory_Limit">Apache::GTopLimit</A>
   modules. By using either of these modules you should be able to discontinue
  @@ -2756,13 +4981,14 @@
   addition the latter module allows you to kill any servers whose shared
   memory size drops below a specified limit.
   
  -<P><A NAME="anchor429"></A>
  -See also <A HREF="././performance.html#Preload_Perl_Modules_at_Server_S">Preload Perl modules at server startup</A> and <A HREF="././performance.html#Sharing_Memory">Sharing Memory</A>. 
  +<P>
  +See also <A HREF="././performance.html#Preloading_Perl_Modules_at_Serve">Preload Perl modules at server startup</A> and <A HREF="././performance.html#Sharing_Memory">Sharing Memory</A>. 
   
  -<P><A NAME="anchor430"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="Choosing_MinSpareServers_MaxSpa">Choosing MinSpareServers, MaxSpareServers and StartServers</A></H2></CENTER>
  -<P><A NAME="anchor431"></A>
  +<P>
   With mod_perl enabled, it might take as much as 20 seconds from the time
   you start the server until it is ready to serve incoming requests. This
   delay depends on the OS, the number of preloaded modules and the process
  @@ -2772,7 +4998,7 @@
   immediately. With mod_perl, it's usually a good idea to raise all 3
   variables higher than normal.
   
  -<P><A NAME="anchor432"></A>
  +<P>
   In order to maximize the benefits of mod_perl, you don't want to kill
   servers when they are idle, rather you want them to stay up and available
   to handle new requests immediately. I think an ideal configuration is to
  @@ -2784,44 +5010,69 @@
   concurrent requests is not higher than
   <CODE>MaxClients</CODE>).
   
  -<P><A NAME="anchor433"></A>
  +<P>
   Let's try some numbers. For a heavily loaded web site and a dedicated
   machine I would think of (note 400Mb is just for example):
  +
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
   
  -<P><A NAME="anchor434"></A>
  -<PRE>  Available to webserver RAM:   400Mb
  +	<td>
  +	  <pre>  Available to webserver RAM:   400Mb
     Child's memory size bounded:  10Mb
     MaxClients:                   400/10 = 40 (larger with mem sharing)
     StartServers:                 20
     MinSpareServers:              20
  -  MaxSpareServers:              35
  -</PRE>
  -<P><A NAME="anchor435"></A>
  +  MaxSpareServers:              35</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   However if I want to use the server for many other tasks, but make it
   capable of handling a high load, I'd think of:
   
  -<P><A NAME="anchor436"></A>
  -<PRE>  Available to webserver RAM:   400Mb
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  Available to webserver RAM:   400Mb
     Child's memory size bounded:  10Mb
     MaxClients:                   400/10 = 40
     StartServers:                 5
     MinSpareServers:              5
  -  MaxSpareServers:              10
  -</PRE>
  -<P><A NAME="anchor437"></A>
  +  MaxSpareServers:              10</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   These numbers are taken off the top of my head, and shouldn't be used as a
   rule, but rather as examples to show you some possible scenarios. Use this
   information with caution!
   
  -<P><A NAME="anchor438"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="Summary_of_Benchmarking_to_tune_">Summary of Benchmarking to tune all 5 parameters</A></H2></CENTER>
  -<P><A NAME="anchor439"></A>
  +<P>
   OK, we've run various benchmarks -- let's summarize the conclusions:
   
   <UL>
   <P><LI><STRONG><A NAME="item_MaxRequestsPerChild">MaxRequestsPerChild</A></STRONG>
  -<P><A NAME="anchor440"></A>
  +<P>
   If your scripts are clean and don't leak memory, set this variable to a
   number as large as possible (10000?). If you use
   <CODE>Apache::SizeLimit</CODE>, you can set this parameter to 0 (treated as infinity). You will want this
  @@ -2830,14 +5081,14 @@
   comes into the picture with the shared memory limitation feature.
   
   <P><LI><STRONG><A NAME="item_StartServers">StartServers</A></STRONG>
  -<P><A NAME="anchor441"></A>
  +<P>
   If you keep a small number of servers active most of the time, keep this
   number low. Keep it low especially if <CODE>MaxSpareServers</CODE> is also low, as if there is no load Apache will kill its children before
   they have been utilized at all. If your service is heavily loaded, make
   this number close to <CODE>MaxClients</CODE>, and keep <CODE>MaxSpareServers</CODE> equal to <CODE>MaxClients</CODE>.
   
   <P><LI><STRONG><A NAME="item_MinSpareServers">MinSpareServers</A></STRONG>
  -<P><A NAME="anchor442"></A>
  +<P>
   If your server performs other work besides web serving, make this low so
   the memory of unused children will be freed when the load is light. If your
   server's load varies (you get loads in bursts) and you want fast response
  @@ -2846,12 +5097,12 @@
   requests.
   
   <P><LI><STRONG><A NAME="item_MaxSpareServers">MaxSpareServers</A></STRONG>
  -<P><A NAME="anchor443"></A>
  +<P>
   The logic is the same as for <CODE>MinSpareServers</CODE> - low if you need the machine for other tasks, high if it's a dedicated web
   host and you want a minimal delay between the request and the response.
   
   <P><LI><STRONG><A NAME="item_MaxClients">MaxClients</A></STRONG>
  -<P><A NAME="anchor444"></A>
  +<P>
   Not too low, so you don't get into a situation where clients are waiting
   for the server to start serving them (they might wait, but not for very
   long). However, do not set it too high. With a high MaxClients, if you get
  @@ -2864,7 +5115,7 @@
   is an emergency pool, not a resource to be used routinely. If you are low
   on memory and you badly need it, buy it. Memory is cheap.
   
  -<P><A NAME="anchor445"></A>
  +<P>
   But based on the test I conducted above, even if you have plenty of memory
   like I have (1Gb), increasing <CODE>MaxClients</CODE> sometimes will give you no improvement in performance. The more clients are
   running, the more CPU time will be required, the less CPU time slices each
  @@ -2878,50 +5129,75 @@
   make the measurements on a production server you will have the ability to
   tune them more precisely, since you will see the real numbers.
   
  -<P><A NAME="anchor446"></A>
  +<P>
   Don't forget that if you add more scripts, or even just modify the existing
   ones, the processes will grow in size as you compile in more code. Probably
   the parameters will need to be recalculated.
   
   </UL>
  -<P><A NAME="anchor447"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="KeepAlive">KeepAlive</A></H2></CENTER>
  -<P><A NAME="anchor448"></A>
  +<P>
   If your mod_perl server's <EM>httpd.conf</EM> includes the following directives:
  +
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
   
  -<P><A NAME="anchor449"></A>
  -<PRE>  KeepAlive On
  +	<td>
  +	  <pre>  KeepAlive On
     MaxKeepAliveRequests 100
  -  KeepAliveTimeout 15
  -</PRE>
  -<P><A NAME="anchor450"></A>
  +  KeepAliveTimeout 15</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   you have a real performance penalty, since after completing the processing
   for each request, the process will wait for
   <CODE>KeepAliveTimeout</CODE> seconds before closing the connection and will therefore not be serving
   other requests during this time. With this configuration you will need many
   more concurrent processes on a server with high traffic.
   
  -<P><A NAME="anchor451"></A>
  +<P>
   If you use some server status reporting tools, you will see the process in <EM>K</EM> status when it's in <CODE>KeepAlive</CODE> status.
   
  -<P><A NAME="anchor452"></A>
  +<P>
   The chances are that you don't want this feature enabled. Set it Off with:
   
  -<P><A NAME="anchor453"></A>
  -<PRE>  KeepAlive Off
  -</PRE>
  -<P><A NAME="anchor454"></A>
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  KeepAlive Off</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   the other two directives don't matter if <CODE>KeepAlive</CODE> is <CODE>Off</CODE>.
   
  -<P><A NAME="anchor455"></A>
  +<P>
   You might want to consider enabling this option if the client's browser
   needs to request more than one object from your server for a single HTML
   page. If this is the situation the by setting
   <CODE>KeepAlive</CODE>  <CODE>Off</CODE> then for each page you save the HTTP connection overhead for all requests
   but the first one.
   
  -<P><A NAME="anchor456"></A>
  +<P>
   For example if you have a page with 10 ad banners, which is not uncommon
   today, you server will work more effectively if a single process serves
   them all during a single connection. However, your client will see a
  @@ -2929,119 +5205,190 @@
   not concurrently as is the case if each
   <CODE>IMG</CODE> tag opens a separate connection.
   
  -<P><A NAME="anchor457"></A>
  +<P>
   Since keepalive connections will not incur the additional three-way TCP
   handshake, turning it off will be kinder to the network.
   
  -<P><A NAME="anchor458"></A>
  +<P>
   SSL connections benefit the most from <CODE>KeepAlive</CODE> in case you didn't configure the server to cache session ids.
   
  -<P><A NAME="anchor459"></A>
  +<P>
   You have probably followed the advice to send all the requests for static
   objects to a plain Apache server. Since most pages include more than one
   unique static image, you should keep the default
   <CODE>KeepAlive</CODE> setting of the non-mod_perl server, i.e. keep it <CODE>On</CODE>. It will probably be a good idea also to reduce the timeout a little.
   
  -<P><A NAME="anchor460"></A>
  +<P>
   One option would be for the proxy/accelerator to keep the connection open
   to the client but make individual connections to the server, read the
   response, buffer it for sending to the client and close the server
   connection. Obviously you would make new connections to the server as
   required by the client's requests.
   
  -<P><A NAME="anchor461"></A>
  +<P>
   Also you should know that <CODE>KeepAlive</CODE> requests only work with responses that contain a <CODE>Content-Length</CODE> header. To send this header do:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor462"></A>
  -<PRE>  $r-&gt;header_out('Content-Length', $length);
  -</PRE>
  -<P><A NAME="anchor463"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  $r-&gt;header_out('Content-Length', $length);</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="PerlSetupEnv_Off">PerlSetupEnv Off</A></H2></CENTER>
  -<P><A NAME="anchor464"></A>
  +<P>
   <CODE>PerlSetupEnv Off</CODE> is another optimization you might consider.
   
  -<P><A NAME="anchor465"></A>
  +<P>
   <EM>mod_perl</EM> fiddles with the environment to make it appear as if the script were being
   called under the CGI protocol. For example, the
   <CODE>$ENV{QUERY_STRING}</CODE> environment variable is initialized with the contents of <EM>Apache::args()</EM>, and the value returned by
   <EM>Apache::server_hostname()</EM> is put into <CODE>$ENV{SERVER_NAME}</CODE>.
   
  -<P><A NAME="anchor466"></A>
  +<P>
   But <CODE>%ENV</CODE> population is expensive. Those who have moved to the Perl Apache API no
   longer need this extra <CODE>%ENV</CODE> population, and can gain by turning it <STRONG>Off</STRONG>.
   
  -<P><A NAME="anchor467"></A>
  +<P>
   By default it is On.
   
  -<P><A NAME="anchor468"></A>
  +<P>
   Note that you can still set enviroment variables. For example when you use
   the following configuration:
  +
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
   
  -<P><A NAME="anchor469"></A>
  -<PRE>  PerlModule Apache::RegistryNG
  +	<td>
  +	  <pre>  PerlModule Apache::RegistryNG
     &lt;Location /perl&gt;
       PerlSetupEnv Off
       PerlSetEnv TEST hi
       SetHandler perl-script
       PerlHandler Apache::RegistryNG
       Options +ExecCGI
  -  &lt;/Location&gt;
  -</PRE>
  -<P><A NAME="anchor470"></A>
  +  &lt;/Location&gt;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   and you issue a request (for example <A
   HREF="http://localhost/perl/setupenvoff.pl">http://localhost/perl/setupenvoff.pl</A>)
   for this script:
   
  -<P><A NAME="anchor471"></A>
  -<PRE>  setupenvoff.pl
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  setupenvoff.pl
     --------------
     use Data::Dumper;
     my $r = Apache-&gt;request();
     $r-&gt;send_http_header('text/plain');
  -  print Dumper(\%ENV);
  -</PRE>
  -<P><A NAME="anchor472"></A>
  +  print Dumper(\%ENV);</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   you should see something like this:
  +
  +<P>
   
  -<P><A NAME="anchor473"></A>
  -<PRE>  $VAR1 = {
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  $VAR1 = {
               'GATEWAY_INTERFACE' =&gt; 'CGI-Perl/1.1',
               'MOD_PERL' =&gt; 'mod_perl/1.22',
               'PATH' =&gt; '/usr/lib/perl5/5.00503:... snipped ...',
               'TEST' =&gt; 'hi'
  -          };
  -</PRE>
  -<P><A NAME="anchor474"></A>
  +          };</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Notice that we have got the value of the environment variable <EM>TEST</EM>.
   
  -<P><A NAME="anchor475"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="Reducing_the_Number_of_stat_Ca">Reducing the Number of stat() Calls Made by Apache</A></H2></CENTER>
  -<P><A NAME="anchor476"></A>
  +<P>
   If you watch the system calls that your server makes (using <EM>truss</EM>
   or <EM>strace</EM> while processing a request, you will notice that a few <CODE>stat()</CODE>
   calls are made. For example when I fetch <A
   HREF="http://localhost/perl-status">http://localhost/perl-status</A> and I
   have my DocRoot set to
   <EM>/home/httpd/docs</EM> I see:
  +
  +<P>
   
  -<P><A NAME="anchor477"></A>
  -<PRE>  [snip]
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  [snip]
     stat(&quot;/home/httpd/docs/perl-status&quot;, 0xbffff8cc) = -1 
                         ENOENT (No such file or directory)
     stat(&quot;/home/httpd/docs&quot;, {st_mode=S_IFDIR|0755, 
                                    st_size=1024, ...}) = 0
  -  [snip]
  -</PRE>
  -<P><A NAME="anchor478"></A>
  +  [snip]</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   If you have some dynamic content and your virtual relative URI is something
   like <EM>/news/perl/mod_perl/summary</EM> (i.e., there is no such directory on the web server, the path components
   are only used for requesting a specific report), this will generate
   <CODE>five(!)</CODE> <CODE>stat()</CODE> calls, before the <CODE>DocumentRoot</CODE> is found. You will see something like this:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor479"></A>
  -<PRE>  stat(&quot;/home/httpd/docs/news/perl/mod_perl/summary&quot;, 0xbffff744) = -1 
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  stat(&quot;/home/httpd/docs/news/perl/mod_perl/summary&quot;, 0xbffff744) = -1 
                         ENOENT (No such file or directory)
     stat(&quot;/home/httpd/docs/news/perl/mod_perl&quot;,         0xbffff744) = -1
                         ENOENT (No such file or directory)
  @@ -3050,60 +5397,96 @@
     stat(&quot;/home/httpd/docs/news&quot;,                       0xbffff744) = -1
                         ENOENT (No such file or directory)
     stat(&quot;/home/httpd/docs&quot;, 
  -                      {st_mode=S_IFDIR|0755, st_size=1024, ...})  =  0
  -</PRE>
  -<P><A NAME="anchor480"></A>
  +                      {st_mode=S_IFDIR|0755, st_size=1024, ...})  =  0</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   You can blame the default installed <CODE>TransHandler</CODE> for this inefficiency. Of course you could supply your own, which will be
   smart enough not to look for this virtual path and immediately return
   <CODE>OK</CODE>. But in cases where you have a virtual host that serves only dynamically
   generated documents, you can override the default
   <CODE>PerlTransHandler</CODE> with this one:
  +
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
   
  -<P><A NAME="anchor481"></A>
  -<PRE>  &lt;VirtualHost 10.10.10.10:80&gt;
  +	<td>
  +	  <pre>  &lt;VirtualHost 10.10.10.10:80&gt;
       ...
       PerlTransHandler  Apache::OK
       ...
  -  &lt;/VirtualHost&gt;
  -</PRE>
  -<P><A NAME="anchor482"></A>
  +  &lt;/VirtualHost&gt;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   As you see it affects only this specific virtual host.
   
  -<P><A NAME="anchor483"></A>
  +<P>
   This has the effect of short circuiting the normal <CODE>TransHandler</CODE>
   processing of trying to find a filesystem component that matches the given
   URI -- no more 'stat's!
   
  -<P><A NAME="anchor484"></A>
  +<P>
   Watching your server under strace/truss can often reveal more performance
   hits than trying to optimize the code itself!
   
  -<P><A NAME="anchor485"></A>
  +<P>
   For example unless configured correctly, Apache might look for the
   <EM>.htaccess</EM> file in many places, if you don't have one and add many <CODE>open()</CODE>
   calls.
   
  -<P><A NAME="anchor486"></A>
  +<P>
   Let's start with this simple configuration, and will try to reduce the
   number of irrelevant system calls.
   
  -<P><A NAME="anchor487"></A>
  -<PRE>  DocumentRoot &quot;/home/httpd/docs&quot;
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  DocumentRoot &quot;/home/httpd/docs&quot;
     &lt;Location /foo/test&gt;
       SetHandler perl-script
       PerlHandler Apache::Foo
  -  &lt;/Location&gt;
  -</PRE>
  -<P><A NAME="anchor488"></A>
  +  &lt;/Location&gt;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   The above configuration allows us to make a request to <EM>/foo/test</EM>
   and the Perl <CODE>handler()</CODE> defined in <CODE>Apache::Foo</CODE> will be executed. Notice that in the test setup there is no file to be
   executed (like in <CODE>Apache::Registry</CODE>). There is no <EM>.htaccess</EM> file as well.
   
  -<P><A NAME="anchor489"></A>
  +<P>
   This is a typical generated trace.
  +
  +<P>
   
  -<P><A NAME="anchor490"></A>
  -<PRE>  stat(&quot;/home/httpd/docs/foo/test&quot;, 0xbffff8fc) = -1 ENOENT 
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  stat(&quot;/home/httpd/docs/foo/test&quot;, 0xbffff8fc) = -1 ENOENT 
           (No such file or directory)
     stat(&quot;/home/httpd/docs/foo&quot;,      0xbffff8fc) = -1 ENOENT 
           (No such file or directory)
  @@ -3120,21 +5503,45 @@
     stat(&quot;/home/httpd/docs/test&quot;, 0xbffff774)    = -1 ENOENT 
           (No such file or directory)
     stat(&quot;/home/httpd/docs&quot;, 
  -        {st_mode=S_IFDIR|0755, st_size=1024, ...}) = 0
  -</PRE>
  -<P><A NAME="anchor491"></A>
  +        {st_mode=S_IFDIR|0755, st_size=1024, ...}) = 0</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Now we modify the <CODE>&lt;Directory&gt;</CODE> entry and add AllowOverride&nbsp;None, which among other things disables <EM>.htaccess</EM> files and will not try to open them.
  +
  +<P>
   
  -<P><A NAME="anchor492"></A>
  -<PRE>  &lt;Directory /&gt;
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  &lt;Directory /&gt;
       AllowOverride None
  -  &lt;/Directory&gt;
  -</PRE>
  -<P><A NAME="anchor493"></A>
  +  &lt;/Directory&gt;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   We see that the four <CODE>open()</CODE> calls for <EM>.htaccess</EM> have gone.
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor494"></A>
  -<PRE>  stat(&quot;/home/httpd/docs/foo/test&quot;, 0xbffff8fc) = -1 ENOENT 
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  stat(&quot;/home/httpd/docs/foo/test&quot;, 0xbffff8fc) = -1 ENOENT 
           (No such file or directory)
     stat(&quot;/home/httpd/docs/foo&quot;,      0xbffff8fc) = -1 ENOENT 
           (No such file or directory)
  @@ -3143,122 +5550,252 @@
     stat(&quot;/home/httpd/docs/test&quot;, 0xbffff774)    = -1 ENOENT 
           (No such file or directory)
     stat(&quot;/home/httpd/docs&quot;, 
  -        {st_mode=S_IFDIR|0755, st_size=1024, ...}) = 0
  -</PRE>
  -<P><A NAME="anchor495"></A>
  +        {st_mode=S_IFDIR|0755, st_size=1024, ...}) = 0</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Let's try to shortcut the <EM>foo</EM> location with:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor496"></A>
  -<PRE>  Alias /foo /
  -</PRE>
  -<P><A NAME="anchor497"></A>
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  Alias /foo /</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Which makes Apache to look for the file in the <EM>/</EM> directory and not under <EM>/home/httpd/docs/foo</EM>. Let's run it:
   
  -<P><A NAME="anchor498"></A>
  -<PRE>  stat(&quot;//test&quot;, 0xbffff8fc) = -1 ENOENT (No such file or directory)
  -</PRE>
  -<P><A NAME="anchor499"></A>
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  stat(&quot;//test&quot;, 0xbffff8fc) = -1 ENOENT (No such file or directory)</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Wow, we've got only one stat call left!
   
  -<P><A NAME="anchor500"></A>
  +<P>
   Let's remove the last <CODE>Alias</CODE> setting and use:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor501"></A>
  -<PRE>    PerlTransHandler  Apache::OK
  -</PRE>
  -<P><A NAME="anchor502"></A>
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>    PerlTransHandler  Apache::OK</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   as explained above. When we issue the request, we see no
   <CODE>stat()</CODE> calls. But this is possible only if you serve only
   dynamically generated documents, i.e. no CGI scripts. Otherwise you will
   have to write your own <EM>PerlTransHandler</EM> to handle requests as desired.
   
  -<P><A NAME="anchor503"></A>
  +<P>
   For example this <EM>PerlTransHandler</EM> will not lookup the file on the filesystem if the URI starts with <EM>/foo</EM>, but will use the default
   <EM>PerlTransHandler</EM> otherwise:
   
  -<P><A NAME="anchor504"></A>
  -<PRE>  PerlTransHandler 'sub { return shift-&gt;uri() =~ m|^/foo| \
  -                        ? Apache::OK : Apache::DECLINED;}'
  -</PRE>
  -<P><A NAME="anchor505"></A>
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  PerlTransHandler 'sub { return shift-&gt;uri() =~ m|^/foo| \
  +                        ? Apache::OK : Apache::DECLINED;}'</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Let's see the same configuration using the <CODE>&lt;Perl&gt;</CODE> section and a dedicated package:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor506"></A>
  -<PRE>  &lt;Perl&gt;  
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  &lt;Perl&gt;  
       package My::Trans;
       use Apache::Constants qw(:common);
       sub handler{
          my $r = shift;
          return OK if $r-&gt;uri() =~ m|^/foo|;
          return DECLINED;
  -    }
  -</PRE>
  -<P><A NAME="anchor507"></A>
  -<PRE>    package Apache::ReadConfig;  
  +    }</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>    package Apache::ReadConfig;  
       $PerlTransHandler = &quot;My::Trans&quot;;
  -  &lt;/Perl&gt;
  -</PRE>
  -<P><A NAME="anchor508"></A>
  +  &lt;/Perl&gt;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   As you see we have defined the <CODE>My::Trans</CODE> package and implemented the <CODE>handler()</CODE> function. Then we have
   assigned this handler to the
   <CODE>PerlTransHandler</CODE>.
   
  -<P><A NAME="anchor509"></A>
  +<P>
   Of course you can move the code in the module into an external file, (e.g. <EM>My/Trans.pm</EM>) and configure the <CODE>PerlTransHandler</CODE> with 
   
  -<P><A NAME="anchor510"></A>
  -<PRE>  PerlTransHandler My::Trans
  -</PRE>
  -<P><A NAME="anchor511"></A>
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  PerlTransHandler My::Trans</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   in the normal way (no <CODE>&lt;Perl&gt;</CODE> section required.
   
  -<P><A NAME="anchor512"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<CENTER><H1><A NAME="TMTOWTDI_Convenience_and_Perfor">TMTOWTDI: Convenience and Performance</A></H1></CENTER>
  -<P><A NAME="anchor513"></A>
  -TMTOWTDI, or ``There Is More Than One Way To Do It'' is the main motto of
  -Perl. Unfortunately when you come to the point where performance is the
  -goal, you might have to learn what's more efficient and what's not. Of
  -course it might mean that you will have to use something that you don't
  -really like, it might be less convenient or it might be just a matter of
  -habit that one should change.
  -
  -<P><A NAME="anchor514"></A>
  -So this section is about performance trade-offs. For each comparison we
  -will provide the theoretical difference and then run benchmarks to support
  -the theory, since however good the theory its the numbers we get in
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
  +<CENTER><H1><A NAME="TMTOWTDI_Convenience_and_Habit_">TMTOWTDI: Convenience and Habit versus Performance</A></H1></CENTER>
  +<P>
  +TMTOWTDI (sometimes pronounced <EM>"tim toady"</EM>), or <EM>"There's More
  +Than One Way To Do It"</EM> is the main motto of Perl. In other words, you can gain the same goal by
  +coding in many different styles, using different modules and deploying the
  +same modules in different ways.
  +
  +<P>
  +Unfortunately when you come to the point where performance is the goal, you
  +might have to learn what's more efficient and what's not. Of course it
  +might mean that you will have to use something that you don't really like,
  +it might be less convenient or it might be just a matter of habit that one
  +should change.
  +
  +<P>
  +So this section is about performance trade-offs. For almost each comparison
  +we will provide the theoretical difference and then run benchmarks to
  +support the theory, since however good the theory its the numbers we get in
   practice that matter.
   
  -<P><A NAME="anchor515"></A>
  +<P>
   The following SW/HW is used for the benchmarking purposes:
  +
  +<P>
   
  -<P><A NAME="anchor516"></A>
  -<PRE>  HW: Dual Pentium II (Deschutes) 400Mhz 512 KB cache 256MB 
  -      RAM (DIMM PC100)
  -</PRE>
  -<P><A NAME="anchor517"></A>
  -<PRE>  SW: Linux (RH 6.1) Perl 5.005_03
  -      Apache/1.3.12 mod_perl/1.22 mod_ssl/2.6.2 OpenSSL/0.9.5
  -</PRE>
  -<P><A NAME="anchor518"></A>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  HW: Dual Pentium II (Deschutes) 400Mhz 512 KB cache 256MB 
  +      RAM (DIMM PC100)</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  SW: Linux (RH 6.1) Perl 5.005_03
  +      Apache/1.3.12 mod_perl/1.22 mod_ssl/2.6.2 OpenSSL/0.9.5</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   The relevant Apache configuration:
  +
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
   
  -<P><A NAME="anchor519"></A>
  -<PRE>  MinSpareServers 10
  +	<td>
  +	  <pre>  MinSpareServers 10
     MaxSpareServers 20
     StartServers 10
     MaxClients 20
  -  MaxRequestsPerChild 10000
  -</PRE>
  -<P><A NAME="anchor520"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +  MaxRequestsPerChild 10000</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="Apache_Registry_versus_pure_Per">Apache::Registry versus pure PerlHandler</A></H2></CENTER>
  -<P><A NAME="anchor521"></A>
  +<P>
   At some point you have to decide whether to use <CODE>Apache::Registry</CODE>
   and similar handlers and stick to writing scripts for the content
   generation or to write pure Perl handlers.
   
  -<P><A NAME="anchor522"></A>
  +<P>
   <CODE>Apache::Registry</CODE> maps a request to a file and generates a subroutine to run the code
   contained in that file. If you use a
   PerlHandler&nbsp;My::handler instead of <CODE>Apache::Registry</CODE>, you have a direct mapping from request to subroutine, without the steps
  @@ -3273,44 +5810,66 @@
   <P><DT><STRONG><A NAME="item_if">if modified or not compiled, compile the subroutine</A></STRONG><DD>
   <P><DT><STRONG>chdir $old_cwd</STRONG><DD>
   </DL>
  -<P><A NAME="anchor523"></A>
  +<P>
   If you cut out those steps, you cut out some overhead, plain and simple. Do
   you <EM>need</EM> to cut out that overhead? We don't know, your requirements determine that.
   
  -<P><A NAME="anchor524"></A>
  +<P>
   You should take a look at the sister <CODE>Apache::Registry</CODE> modules that don't perform all all these steps, so you can still choose to
   stick to using scripts to generate the content.
   
  -<P><A NAME="anchor525"></A>
  +<P>
   On the other hand, if you go the pure Perl handler way you will have to add
   a special configuration directives for each handler, something that you
   don't do when you go the ``scripts'' way.
   
  -<P><A NAME="anchor526"></A>
  +<P>
   Now let's run benchmarks and compare.
   
  -<P><A NAME="anchor527"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H3><A NAME="The_Light_Empty_Code">The Light (Empty) Code</A></H3></CENTER>
  -<P><A NAME="anchor528"></A>
  +<P>
   First lets see the overhead that <CODE>Apache::Registry</CODE> adds. In order to do that we will use an almost empty script, that only
   sends a basic header and one word as content.
   
  -<P><A NAME="anchor529"></A>
  +<P>
   The <EM>registry.pl</EM> script running under <CODE>Apache::Registry</CODE>:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor530"></A>
  -<PRE>  benchmarks/registry.pl
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  benchmarks/registry.pl
     ----------------------
     use strict;
     print &quot;Content-type: text/plain\r\n\r\n&quot;;
  -  print &quot;Hello&quot;;
  -</PRE>
  -<P><A NAME="anchor531"></A>
  +  print &quot;Hello&quot;;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   The Perl Content handler:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor532"></A>
  -<PRE>  Benchmark/Handler.pm
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  Benchmark/Handler.pm
     --------------------
     package Benchmark::Handler;
     use Apache::Constants qw(:common);
  @@ -3321,109 +5880,247 @@
       $r-&gt;print(&quot;Hello&quot;);
       return OK;
     }
  -  1;
  -</PRE>
  -<P><A NAME="anchor533"></A>
  +  1;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   with settings:
  +
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
   
  -<P><A NAME="anchor534"></A>
  -<PRE>  PerlModule Benchmark::Handler
  +	<td>
  +	  <pre>  PerlModule Benchmark::Handler
     &lt;Location /benchmark_handler&gt;
       SetHandler perl-script
       PerlHandler Benchmark::Handler
  -  &lt;/Location&gt;
  -</PRE>
  -<P><A NAME="anchor535"></A>
  +  &lt;/Location&gt;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   so we get <CODE>Benchmark::Handler</CODE> preloaded.
   
  -<P><A NAME="anchor536"></A>
  +<P>
   We will use the <CODE>Apache::RegistryLoader</CODE> to preload the script as well, so the benchmark will be fair and only the
   processing time will be measured. In the <EM>startup.pl</EM> we add:
   
  -<P><A NAME="anchor537"></A>
  -<PRE>  use Apache::RegistryLoader ();
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  use Apache::RegistryLoader ();
     Apache::RegistryLoader-&gt;new-&gt;handler(
                 &quot;/perl/benchmarks/registry.pl&quot;,
  -   &quot;/home/httpd/perl/benchmarks/registry.pl&quot;);
  -</PRE>
  -<P><A NAME="anchor538"></A>
  +   &quot;/home/httpd/perl/benchmarks/registry.pl&quot;);</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   And we if we check the <EM>Compiled Registry Scripts"</EM> section with the help of <A HREF="././debug.html#Apache_Status_Embedded_Inter">Apache::Status</A> ( <A
   HREF="http://localhost/perl-status?rgysubs">http://localhost/perl-status?rgysubs</A>
   ), where we see the listing of the already compiled scripts:
  +
  +<P>
   
  -<P><A NAME="anchor539"></A>
  -<PRE>  Apache::ROOT::perl::benchmarks::registry_2epl
  -</PRE>
  -<P><A NAME="anchor540"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  Apache::ROOT::perl::benchmarks::registry_2epl</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H3><A NAME="The_Heavy_Code">The Heavy Code</A></H3></CENTER>
  -<P><A NAME="anchor541"></A>
  +<P>
   We we will see that the overhead is insignificant when the code itself is
   significantly heavier and slower. Let's leave the above code examples
   umodified but add some CPU intensive processing operation (it can be also
   an IO operation or a database query.)
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor542"></A>
  -<PRE>  my $x = 100;
  -  my $y = log ($x ** 100)  for (0..10000);
  -</PRE>
  -<P><A NAME="anchor543"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  my $x = 100;
  +  my $y = log ($x ** 100)  for (0..10000);</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H3><A NAME="Processing_and_Results">Processing and Results</A></H3></CENTER>
  -<P><A NAME="anchor544"></A>
  +<P>
   So now we can proceed with the benchmark. We will generate 5000 request
   with 10 as a concurrency level (i.e. emulating 10 concurrent users):
  +
  +<P>
   
  -<P><A NAME="anchor545"></A>
  -<PRE>  % ab -n 5000 -c 10 <A HREF="http://localhost/perl/benchmarks/registry.pl">http://localhost/perl/benchmarks/registry.pl</A>
  -  % ab -n 5000 -c 10 <A HREF="http://localhost/benchmark_handler">http://localhost/benchmark_handler</A>
  -</PRE>
  -<P><A NAME="anchor546"></A>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  % ab -n 5000 -c 10 <A HREF="http://localhost/perl/benchmarks/registry.pl">http://localhost/perl/benchmarks/registry.pl</A>
  +  % ab -n 5000 -c 10 <A HREF="http://localhost/benchmark_handler">http://localhost/benchmark_handler</A></pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   And the results:
  +
  +<P>
   
  -<P><A NAME="anchor547"></A>
  -<PRE>  Light code:
  -</PRE>
  -<P><A NAME="anchor548"></A>
  -<PRE>    Type        RPS     Av.CTime
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  Light code:</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>    Type        RPS     Av.CTime
     -------       ---     -------
     Registry      561          16
  -  Handler       707          13
  -</PRE>
  -<P><A NAME="anchor549"></A>
  -<PRE>  Heavy code:
  -</PRE>
  -<P><A NAME="anchor550"></A>
  -<PRE>    Type        RPS     Av.CTime
  +  Handler       707          13</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  Heavy code:</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>    Type        RPS     Av.CTime
     -------       ---     -------
     Registry       68         146
  -  Handler        70         141
  -</PRE>
  -<P><A NAME="anchor551"></A>
  -<PRE>  Reports: 
  +  Handler        70         141</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  Reports: 
     -----------------------------------------------
     RPS       : Requests Per Second
  -  Av. CTime : Average request processing time (msec) as seen by client
  -</PRE>
  -<P><A NAME="anchor552"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +  Av. CTime : Average request processing time (msec) as seen by client</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H3><A NAME="Conclusions">Conclusions</A></H3></CENTER>
   <UL>
   <P><LI><STRONG><A NAME="item_The">The Light Code</A></STRONG>
  -<P><A NAME="anchor553"></A>
  +<P>
   We can see that the average overhead added by <CODE>Apache::Registry</CODE> is about:
  +
  +<P>
   
  -<P><A NAME="anchor554"></A>
  -<PRE>  16 - 13 = 3 milli-seconds
  -</PRE>
  -<P><A NAME="anchor555"></A>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  16 - 13 = 3 milli-seconds</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   per request.
   
  -<P><A NAME="anchor556"></A>
  +<P>
   Thus the difference in speed is about 19%.
   
   <P><LI><STRONG><A NAME="item_The">The Heavy Code</A></STRONG>
  -<P><A NAME="anchor557"></A>
  +<P>
   If we are looking at the average processing time, we see that the time
   delta between the two handlers is almost the same and has grown from 3 msec
   to 5 msec. Which means that the identical heavy code that has been added
  @@ -3432,11 +6129,20 @@
   this code to be completed in a multi-process environment where each process
   gets a time slice to use the CPU.
   
  -<P><A NAME="anchor558"></A>
  +<P>
   If we run this extra code under plain Benchmark:
  +
  +<P>
   
  -<P><A NAME="anchor559"></A>
  -<PRE>  benchmark.pl
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  benchmark.pl
     ------------
     use Benchmark;
     
  @@ -3444,45 +6150,108 @@
      sub {
       my $x = 100;
       my $y = log ($x ** 100)  for (0..10000);
  -  });
  -</PRE>
  -<P><A NAME="anchor560"></A>
  -<PRE>  % perl benchmark.pl
  -  timethis 1000: 25 wallclock secs (24.93 usr +  0.00 sys = 24.93 CPU)
  -</PRE>
  -<P><A NAME="anchor561"></A>
  +  });</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  % perl benchmark.pl
  +  timethis 1000: 25 wallclock secs (24.93 usr +  0.00 sys = 24.93 CPU)</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   We see that it takes about 25 CPU seconds to complete.
   
  -<P><A NAME="anchor562"></A>
  +<P>
   The interesting thing is that when the server under test runs on a slow
   machine the results are completely different. I'll present them here for
   comparison:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor563"></A>
  -<PRE>  Light code:
  -</PRE>
  -<P><A NAME="anchor564"></A>
  -<PRE>    Type        RPS     Av.CTime
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  Light code:</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>    Type        RPS     Av.CTime
     -------       ---     -------
     Registry       61         160
  -  Handler       196          50
  -</PRE>
  -<P><A NAME="anchor565"></A>
  -<PRE>  Heavy code:
  -</PRE>
  -<P><A NAME="anchor566"></A>
  -<PRE>    Type        RPS     Av.CTime
  +  Handler       196          50</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  Heavy code:</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>    Type        RPS     Av.CTime
     -------       ---     -------
     Registry       12         822
  -  Handler        67         149
  -</PRE>
  -<P><A NAME="anchor567"></A>
  +  Handler        67         149</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   You can see that adding the same CPU intensive code to the two handlers
   under test on the slow machine, enlarges the delta of the average
   processing time between the two handlers. We'd expect to see the same delta
   (of 110 msec) in this case, but that's not what's happenning.
   
  -<P><A NAME="anchor568"></A>
  +<P>
   The explanation lies in fact that the difference between the machines isn't
   merely the processor speed. It's possible that there are many other things
   that different. For example the size of the processor cache. If one machine
  @@ -3491,78 +6260,136 @@
   the CPU activity was dedicated to running the handler's code.
   
   </UL>
  -<P><A NAME="anchor569"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="CGI_pm_versus_Apache_Request">CGI.pm versus Apache::Request</A></H2></CENTER>
  -<P><A NAME="anchor570"></A>
  +<P>
   <CODE>CGI.pm</CODE> is a pure Perl implementation of the most used functions used in CGI
   coding. Mainly it has two parts -- input processing and HTML generation.
   
  -<P><A NAME="anchor571"></A>
  +<P>
   <CODE>Apache::Request</CODE>'s core is written in C, giving it a significant memory and performance
   benefit. It has all the functionality of
   <CODE>CGI.pm</CODE> except HTML generation functions.
   
  -<P><A NAME="anchor572"></A>
  +<P>
   <CODE>use CGI qw(-compile =</CODE> ':all')&gt; adds about 1Mb size to the server.
   <CODE>CGI.pm</CODE> pulls lots of stunts under the covers to provide both a method and function
   interface, etc.  <CODE>Apache::Request</CODE> is a very thin XS layer on top of a C library and only adds a few kbytes
   size to the server. this C code is much faster and lighter than the Perl
   equivalent used in <CODE>CGI.pm</CODE> or similar (e.g. CGI_Lite).
   
  -<P><A NAME="anchor573"></A>
  +<P>
   This difference might not matter much to you, depending on your
   requirements.
   
  -<P><A NAME="anchor574"></A>
  +<P>
   Let's write two registry scripts that use <CODE>CGI.pm</CODE> and
   <CODE>Apache::Request</CODE> to process a form's input and print it out. We will use the scripts to
   benchmark the modules.
  +
  +<P>
   
  -<P><A NAME="anchor575"></A>
  -<PRE>  benchmarks/cgi_pm.pl
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  benchmarks/cgi_pm.pl
     --------------------
     use strict;
     use CGI;
     my $q = new CGI;
     print $q-&gt;header('text/plain');
  -  print join &quot;\n&quot;, map {&quot;$_ =&gt; &quot;.$q-&gt;param($_) } $q-&gt;param;
  -</PRE>
  -<P><A NAME="anchor576"></A>
  -<PRE>  benchmarks/apache_request.pl
  +  print join &quot;\n&quot;, map {&quot;$_ =&gt; &quot;.$q-&gt;param($_) } $q-&gt;param;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  benchmarks/apache_request.pl
     ----------------------------
     use strict;
     use Apache::Request ();
     my $r = Apache-&gt;request;
     my $q = Apache::Request-&gt;new($r);
     $r-&gt;send_http_header('text/plain');
  -  print join &quot;\n&quot;, map {&quot;$_ =&gt; &quot;.$q-&gt;param($_) } $q-&gt;param;
  -</PRE>
  -<P><A NAME="anchor577"></A>
  +  print join &quot;\n&quot;, map {&quot;$_ =&gt; &quot;.$q-&gt;param($_) } $q-&gt;param;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   We preload both the modules that we are going to benchmark in the
   <EM>startup.pl</EM>:
  +
  +<P>
   
  -<P><A NAME="anchor578"></A>
  -<PRE>  use Apache::Request ();
  -  use CGI  qw(-compile :all);
  -</PRE>
  -<P><A NAME="anchor579"></A>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  use Apache::Request ();
  +  use CGI  qw(-compile :all);</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   We will preload the both scripts as well:
  +
  +<P>
   
  -<P><A NAME="anchor580"></A>
  -<PRE>  use Apache::RegistryLoader ();
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  use Apache::RegistryLoader ();
     Apache::RegistryLoader-&gt;new-&gt;handler(
                 &quot;/perl/benchmarks/cgi_pm.pl&quot;,
      &quot;/home/httpd/perl/benchmarks/cgi_pm.pl&quot;);
     Apache::RegistryLoader-&gt;new-&gt;handler(
                 &quot;/perl/benchmarks/apache_request.pl&quot;,
  -   &quot;/home/httpd/perl/benchmarks/apache_request.pl&quot;);
  -</PRE>
  -<P><A NAME="anchor581"></A>
  +   &quot;/home/httpd/perl/benchmarks/apache_request.pl&quot;);</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Now let's benchmark the two:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor582"></A>
  -<PRE>  % ab -n 1000 -c 10 \
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  % ab -n 1000 -c 10 \
      '<A HREF="http://localhost/perl/benchmarks/cgi_pm.pl?a=b&amp;c=+k+d+d+f&amp;d=asf&amp;as=+1+2+3+4">http://localhost/perl/benchmarks/cgi_pm.pl?a=b&amp;c=+k+d+d+f&amp;d=asf&amp;as=+1+2+3+4</A>'
     
     Time taken for tests:   23.950 seconds
  @@ -3571,10 +6398,22 @@
                   min   avg   max
     Connect:        0     0    45
     Processing:   204   238   274
  -  Total:        204   238   319
  -</PRE>
  -<P><A NAME="anchor583"></A>
  -<PRE>  % ab -n 1000 -c 10 \
  +  Total:        204   238   319</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  % ab -n 1000 -c 10 \
      '<A HREF="http://localhost/perl/benchmarks/apache_request.pl?a=b&amp;c=+k+d+d+f&amp;d=asf&amp;as=+1+2+3+4">http://localhost/perl/benchmarks/apache_request.pl?a=b&amp;c=+k+d+d+f&amp;d=asf&amp;as=+1+2+3+4</A>'
     
     Time taken for tests:   18.406 seconds
  @@ -3583,26 +6422,39 @@
                   min   avg   max
     Connect:        0     0    32
     Processing:   156   183   202
  -  Total:        156   183   234
  -</PRE>
  -<P><A NAME="anchor584"></A>
  +  Total:        156   183   234</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Apparently the latter script using <CODE>Apache::Request</CODE> is about 23% faster. If the input is going to be larger the percentage
   speed up grows as well.
   
  -<P><A NAME="anchor585"></A>
  +<P>
   In the above example we have benchmarked the CGI input processing. When the
   code is much heavier the overhead of using
   <CODE>CGI.pm</CODE> for input parsing becomes insignificant.
   
  -<P><A NAME="anchor586"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="_Bloatware_modules">&quot;Bloatware&quot; modules</A></H2></CENTER>
  -<P><A NAME="anchor587"></A>
  +<P>
   Perl modules like IO:: are very convenient, but let's see what it costs us
   to use them. (perl5.6.0 over OpenBSD)
  +
  +<P>
   
  -<P><A NAME="anchor588"></A>
  -<PRE>  % wc `perl -MIO -e 'print join(&quot;\n&quot;, sort values %INC, &quot;&quot;)'`
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  % wc `perl -MIO -e 'print join(&quot;\n&quot;, sort values %INC, &quot;&quot;)'`
      124     696    4166 /usr/local/lib/perl5/5.6.0/Carp.pm
      580    2465   17661 /usr/local/lib/perl5/5.6.0/Class/Struct.pm
      400    1495   10455 /usr/local/lib/perl5/5.6.0/Cwd.pm
  @@ -3632,17 +6484,32 @@
       79     370    2589 /usr/local/lib/perl5/5.6.0/vars.pm
      318    1124   11975 /usr/local/lib/perl5/5.6.0/warnings.pm
       30      85     722 /usr/local/lib/perl5/5.6.0/warnings/register.pm
  - 13733   48195  349869 total
  -</PRE>
  -<P><A NAME="anchor589"></A>
  + 13733   48195  349869 total</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Incredible. But it's half the size on linux:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor590"></A>
  -<PRE>  % wc `perl -MIO -e 'print join(&quot;\n&quot;, sort values %INC, &quot;&quot;)'`
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  % wc `perl -MIO -e 'print join(&quot;\n&quot;, sort values %INC, &quot;&quot;)'`
     [similar lines snipped]
  -  6618   25068  176740 total
  -</PRE>
  -<P><A NAME="anchor591"></A>
  +  6618   25068  176740 total</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Moreover, that requires 116 happy trips through the kernel's
   <CODE>namei().</CODE> It syscalls <CODE>open()</CODE> a remarkable 57
   times, 17 of which failed but leaving 38 that were successful. It also
  @@ -3650,194 +6517,376 @@
   total of 180,265 plump bytes. To top it off, this <STRONG><EM>increases your resident set size by two megabytes!</EM></STRONG>
   (1.5Mb on linux).
   
  -<P><A NAME="anchor592"></A>
  +<P>
   Happy mallocking...
   
  -<P><A NAME="anchor593"></A>
  +<P>
   It seems that <CODE>CGI.pm</CODE> suffers from the same disease:
  +
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
   
  -<P><A NAME="anchor594"></A>
  -<PRE>  % wc `perl -MCGI -le 'print for values %INC'`
  +	<td>
  +	  <pre>  % wc `perl -MCGI -le 'print for values %INC'`
     1368    6920   43710 /usr/local/lib/perl5/5.6.0/overload.pm
     6481   26122  200840 /usr/local/lib/perl5/5.6.0/CGI.pm
  -  7849   33042  244550 total
  -</PRE>
  -<P><A NAME="anchor595"></A>
  +  7849   33042  244550 total</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   You have 16 trips through namei, 7 successful opens, 2 unsuccessful ones,
   and 213k of data read in.
   
  -<P><A NAME="anchor596"></A>
  +<P>
   The following numbers show memory sizes (virtual and resident) for v5.6.0
   of Perl on four different operating systems, The three calls each are
   without any modules, with just -MCGI, and with -MIO (never with both):
   
  -<P><A NAME="anchor597"></A>
  -<PRE>              OpenBSD       FreeBSD      Redhat       Solaris
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>              OpenBSD       FreeBSD      Redhat       Solaris
                 vsz   rss     vsz  rss     vsz  rss    vsz    rss
     Raw Perl    736   772     832 1208    2412  980    2928  2272
     w/ CGI     1220  1464    1308 1828    2972 1768    3616  3232
  -  w/ IO      2292  2580    2456 3016    4080 2868    5384  4976
  -</PRE>
  -<P><A NAME="anchor598"></A>
  +  w/ IO      2292  2580    2456 3016    4080 2868    5384  4976</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Anybody who's thinking of choosing one of these might do well to stare at
   those numbers for a while.
   
  -<P><A NAME="anchor599"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="Apache_args_versus_Apache_Requ">Apache::args versus Apache::Request::params</A></H2></CENTER>
  -<P><A NAME="anchor600"></A>
  +<P>
   Let's write two registry scripts that use <CODE>Apache::args</CODE> and
   <CODE>Apache::Request::params</CODE> to process the form's input and print it out. Notice that <CODE>Apache::args</CODE> is considered identical to
   <CODE>Apache::Request::params</CODE> only when you have a single valued keys, in case of multivalued keys (e.g.
   when using checkbox groups) you will have to write some more code, since if
   you do a simple:
   
  -<P><A NAME="anchor601"></A>
  -<PRE>  %params = $r-&gt;args;
  -</PRE>
  -<P><A NAME="anchor602"></A>
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  %params = $r-&gt;args;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   only the last value will be stored and the rest will collapse, something
   that you will solve with <CODE>Apache::Request::params</CODE> as:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor603"></A>
  -<PRE>  @values = $q-&gt;params('key');
  -</PRE>
  -<P><A NAME="anchor604"></A>
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  @values = $q-&gt;params('key');</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   In addition <CODE>Apache::Request</CODE> has many more functions that ease input processing, like handling file
   uploads.
   
  -<P><A NAME="anchor605"></A>
  +<P>
   Therefore assuming that the only functionality that you need is the parsing
   of the key-value pairs, and assuming that every key has a single value, we
   will compare a slightly modified script from the previous section (<EM>apache_request.pl</EM>) and write a new one that uses
   <CODE>args()</CODE>:
   
  -<P><A NAME="anchor606"></A>
  -<PRE>  benchmarks/apache_request.pl
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  benchmarks/apache_request.pl
     ----------------------------
     use strict;
     use Apache::Request ();
     my $r = Apache-&gt;request;
     my $q = Apache::Request-&gt;new($r);
     $r-&gt;send_http_header('text/plain');
  -  print join &quot;\n&quot;, $q-&gt;param;
  -</PRE>
  -<P><A NAME="anchor607"></A>
  -<PRE>  benchmarks/apache_args.pl
  +  print join &quot;\n&quot;, $q-&gt;param;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  benchmarks/apache_args.pl
     -------------------------
     use strict;
     my $r = Apache-&gt;request;
     $r-&gt;send_http_header('text/plain');
  -  print join &quot;\n&quot;, $r-&gt;args;
  -</PRE>
  -<P><A NAME="anchor608"></A>
  +  print join &quot;\n&quot;, $r-&gt;args;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Now let's benchmark the two:
   
  -<P><A NAME="anchor609"></A>
  -<PRE>  % ab -n 1000 -c 10 \
  -  '<A HREF="http://localhost/perl/benchmarks/apache_request.pl?a=b&amp;c=k&amp;d=asf&amp;as=1">http://localhost/perl/benchmarks/apache_request.pl?a=b&amp;c=k&amp;d=asf&amp;as=1</A>'
  -</PRE>
  -<P><A NAME="anchor610"></A>
  -<PRE>  Time taken for tests:   16.961 seconds
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  % ab -n 1000 -c 10 \
  +  '<A HREF="http://localhost/perl/benchmarks/apache_request.pl?a=b&amp;c=k&amp;d=asf&amp;as=1">http://localhost/perl/benchmarks/apache_request.pl?a=b&amp;c=k&amp;d=asf&amp;as=1</A>'</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  Time taken for tests:   16.961 seconds
     Requests per second:    58.96
     Connnection Times (ms)
                   min   avg   max
     Connect:        0     0    20
     Processing:   150   168   343
  -  Total:        150   168   363
  -</PRE>
  -<P><A NAME="anchor611"></A>
  -<PRE>  % ab -n 1000 -c 10 \
  -  '<A HREF="http://localhost/perl/benchmarks/apache_args.pl?a=b&amp;c=k&amp;d=asf&amp;as=1">http://localhost/perl/benchmarks/apache_args.pl?a=b&amp;c=k&amp;d=asf&amp;as=1</A>'
  -</PRE>
  -<P><A NAME="anchor612"></A>
  -<PRE>  Time taken for tests:   17.154 seconds
  +  Total:        150   168   363</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  % ab -n 1000 -c 10 \
  +  '<A HREF="http://localhost/perl/benchmarks/apache_args.pl?a=b&amp;c=k&amp;d=asf&amp;as=1">http://localhost/perl/benchmarks/apache_args.pl?a=b&amp;c=k&amp;d=asf&amp;as=1</A>'</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  Time taken for tests:   17.154 seconds
     Requests per second:    58.30
     Connnection Times (ms)
                   min   avg   max
     Connect:        0     2   136
     Processing:    68   168   202
  -  Total:         68   170   338
  -</PRE>
  -<P><A NAME="anchor613"></A>
  +  Total:         68   170   338</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Apparently the two run at the same speed.
   
  -<P><A NAME="anchor614"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="Using_1_Under_mod_perl_and_Be">Using $|=1 Under mod_perl and Better print() Techniques.</A></H2></CENTER>
  -<P><A NAME="anchor615"></A>
  +<P>
   As you know, <CODE>local $|=1;</CODE> disables the buffering of the currently selected file handle (default is <CODE>STDOUT</CODE>). If you enable it,
   <CODE>ap_rflush()</CODE> is called after each <CODE>print()</CODE>, unbuffering Apache's IO.
   
  -<P><A NAME="anchor616"></A>
  +<P>
   If you are using multiple <CODE>print()</CODE> calls (_bad_ style in generating output) or if you just have too many of
   them, then you will experience a degradation in performance. The severity
   depends on the number of <CODE>print()</CODE> calls that you make.
   
  -<P><A NAME="anchor617"></A>
  +<P>
   Many old CGI scripts were written like this:
  +
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
   
  -<P><A NAME="anchor618"></A>
  -<PRE>  print &quot;&lt;BODY BGCOLOR=\&quot;black\&quot; TEXT=\&quot;white\&quot;&gt;&quot;;
  +	<td>
  +	  <pre>  print &quot;&lt;BODY BGCOLOR=\&quot;black\&quot; TEXT=\&quot;white\&quot;&gt;&quot;;
     print &quot;&lt;H1&gt;&quot;;
     print &quot;Hello&quot;;
     print &quot;&lt;/H1&gt;&quot;;
     print &quot;&lt;A HREF=\&quot;foo.html\&quot;&gt; foo &lt;/A&gt;&quot;;
  -  print &quot;&lt;/BODY&gt;&quot;;
  -</PRE>
  -<P><A NAME="anchor619"></A>
  +  print &quot;&lt;/BODY&gt;&quot;;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   This example has multiple <CODE>print()</CODE> calls, which will cause performance degradation with <CODE>$|=1</CODE>. It also uses too many backslashes. This makes the code less readable, and
   it is also more difficult to format the HTML so that it is easily readable
   as the script's output. The code below solves the problems:
   
  -<P><A NAME="anchor620"></A>
  -<PRE>  print qq{
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  print qq{
       &lt;BODY BGCOLOR=&quot;black&quot; TEXT=&quot;white&quot;&gt;
         &lt;H1&gt;
           Hello
         &lt;/H1&gt;
         &lt;A HREF=&quot;foo.html&quot;&gt; foo &lt;/A&gt;
       &lt;/BODY&gt;
  -  };
  -</PRE>
  -<P><A NAME="anchor621"></A>
  +  };</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   I guess you see the difference. Be careful though, when printing a
   <CODE>&lt;HTML&gt;</CODE> tag. The correct way is:
   
  -<P><A NAME="anchor622"></A>
  -<PRE>  print qq{&lt;HTML&gt;
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  print qq{&lt;HTML&gt;
       &lt;HEAD&gt;&lt;/HEAD&gt;
       &lt;BODY&gt;
  -  }
  -</PRE>
  -<P><A NAME="anchor623"></A>
  +  }</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   If you try the following:
   
  -<P><A NAME="anchor624"></A>
  -<PRE>  print qq{
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  print qq{
       &lt;HTML&gt;
       &lt;HEAD&gt;&lt;/HEAD&gt;
       &lt;BODY&gt;
  -  }
  -</PRE>
  -<P><A NAME="anchor625"></A>
  +  }</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Some older browsers expect the first characters after the headers and empty
   line to be <CODE>&lt;HTML&gt;</CODE> with <EM>no</EM> spaces before the opening left angle-bracket. If there are any other
   characters, they might not accept the output as HTML and print it as a
   plain text. Even if it works with your browser, it might not work for
   others.
   
  -<P><A NAME="anchor626"></A>
  +<P>
   One other approach is to use `here' documents, e.g.:
   
  -<P><A NAME="anchor627"></A>
  -<PRE>    print &lt;&lt;EOT;
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>    print &lt;&lt;EOT;
       &lt;HTML&gt;
       &lt;HEAD&gt;&lt;/HEAD&gt;
       &lt;BODY&gt;
  -    EOT
  -</PRE>
  -<P><A NAME="anchor628"></A>
  +    EOT</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Now let's go back to the <CODE>$|=1</CODE> topic. I still disable buffering, for two reasons:
   
   <UL>
  @@ -3854,16 +6903,25 @@
   if it's a few milliseconds faster - assuming the browser didn't time
   out during the wait.</A></STRONG>
   </UL>
  -<P><A NAME="anchor629"></A>
  +<P>
   An even better solution is to keep buffering enabled, and use a Perl API <CODE>rflush()</CODE> call to flush the buffers when needed. This way you can place the first
   part of the page that you are going to send to the user in the buffer, and
   flush it a moment before you are going to do some lenghty operation, like a
   DB query. So you kill two birds with one stone: you show some of the data
   to the user immediately, so she will feel that something is actually
   happening, and you have no performance hit from disabled buffering.
  +
  +<P>
   
  -<P><A NAME="anchor630"></A>
  -<PRE>  use CGI ();
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  use CGI ();
     my $r = shift;
     my $q = new CGI;
     print $q-&gt;header('text/html');
  @@ -3874,87 +6932,116 @@
     for (1..5) {
       sleep 1;
     }
  -  print $q-&gt;p(&quot;Done!&quot;);
  -</PRE>
  -<P><A NAME="anchor631"></A>
  +  print $q-&gt;p(&quot;Done!&quot;);</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   <STRONG>Conclusion</STRONG>: Do not blindly follow suggestions, but think what is best for you in each
   case.
   
  -<P><A NAME="anchor632"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<CENTER><H1><A NAME="Performance_Oriented_Perl_Coding">Performance Oriented Perl Coding</A></H1></CENTER>
  -<P><A NAME="anchor633"></A>
  -One of the components of the mod_perl server's performance is the Perl code
  -that you use. If you write code that runs slowly, the overall performance
  -is slower. This section is intended to give you some hints to make your
  -code, whose main purpose is to generate webpages, run faster. Bear in mind
  -that the performance considerations might be totally different when you use
  -Perl for other tasks.
  -
  -<P><A NAME="anchor634"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="Global_vs_Fully_Qualified_Variab">Global vs Fully Qualified Variables</A></H2></CENTER>
  -<P><A NAME="anchor635"></A>
  +<P>
   It's always a good idea to avoid global variables where possible. Some
   variables must be either global, such as a module's <CODE>@ISA</CODE> or
   <CODE>$VERSION</CODE> variables or else fully qualified such as
   <STRONG>@MyModule::ISA</STRONG>), so that Perl can see them.
   
  -<P><A NAME="anchor636"></A>
  +<P>
   A combination of <CODE>strict</CODE> and <CODE>vars</CODE> pragmas keeps modules clean and reduces a bit of noise. However, the <CODE>vars</CODE> pragma also creates aliases, as does <CODE>Exporter</CODE>, which eat up more memory. When possible, try to use fully qualified names
   instead of <CODE>use vars</CODE>.
   
  -<P><A NAME="anchor637"></A>
  +<P>
   For example write:
   
  -<P><A NAME="anchor638"></A>
  -<PRE>  package MyPackage;
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  package MyPackage;
     use strict;
     @MyPackage::ISA = qw(...);
  -  $MyPackage::VERSION = &quot;1.00&quot;;
  -</PRE>
  -<P><A NAME="anchor639"></A>
  +  $MyPackage::VERSION = &quot;1.00&quot;;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   instead of:
  +
  +<P>
   
  -<P><A NAME="anchor640"></A>
  -<PRE>  package MyPackage;
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  package MyPackage;
     use strict;
     use vars qw(@ISA $VERSION);
     @ISA = qw(...);
  -  $VERSION = &quot;1.00&quot;;
  -</PRE>
  -<P><A NAME="anchor641"></A>
  +  $VERSION = &quot;1.00&quot;;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Also see <A HREF="././perl.html#Using_Global_Variables_and_Shari">Using Global Variables and Sharing Them Between Modules/Packages</A>.
   
  -<P><A NAME="anchor642"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="Avoid_Importing_Functions">Avoid Importing Functions</A></H2></CENTER>
  -<P><A NAME="anchor643"></A>
  +<P>
   When possible, avoid importing a module's functions into your name space.
   The aliases which are created can take up quite a bit of memory. Try to use
   function interfaces and fully qualified names like
   <CODE>Package::function</CODE> or <CODE>$Package::variable</CODE> instead. For benchmarks see <A HREF="././performance.html#Object_Methods_Calls_Versus_Func">Object Methods Calls Versus Function Calls</A>.
   
  -<P><A NAME="anchor644"></A>
  +<P>
   Note: method interfaces are a little bit slower than function calls. You
   can use the <CODE>Benchmark</CODE> module to profile your specific code.
   
  -<P><A NAME="anchor645"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="Object_Methods_Calls_Versus_Func">Object Methods Calls Versus Function Calls</A></H2></CENTER>
  -<P><A NAME="anchor646"></A>
  +<P>
   Which subroutine calling form is more efficient: OOP methods or functions?
   
  -<P><A NAME="anchor647"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H3><A NAME="The_Overhead_with_Light_Subrouti">The Overhead with Light Subroutines</A></H3></CENTER>
  -<P><A NAME="anchor648"></A>
  +<P>
   Let's do some benchmarking. We will start doing it using empty methods,
   which will allow us to measure the real difference in the overhead each
   kind of call introduces. We will use this code:
  +
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
   
  -<P><A NAME="anchor649"></A>
  -<PRE>  bench_call1.pl
  +	<td>
  +	  <pre>  bench_call1.pl
     --------------
     package Foo;
     
  @@ -3966,27 +7053,42 @@
     timethese(50_000, {
                    method   =&gt; sub { Foo-&gt;bar()      },
                    function =&gt; sub { Foo::bar('Foo');},
  -                });
  -</PRE>
  -<P><A NAME="anchor650"></A>
  +                });</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   The two calls are equivalent, since both pass the class name as their first
   parameter; <EM>function</EM> does this explicitly, while <EM>method</EM> does this transparently.
   
  -<P><A NAME="anchor651"></A>
  +<P>
   The benchmarking result:
   
  -<P><A NAME="anchor652"></A>
  -<PRE>  Benchmark: timing 50000 iterations of function, method...
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  Benchmark: timing 50000 iterations of function, method...
       function:  0 wallclock secs ( 0.80 usr +  0.05 sys =  0.85 CPU)
  -      method:  1 wallclock secs ( 1.51 usr +  0.08 sys =  1.59 CPU)
  -</PRE>
  -<P><A NAME="anchor653"></A>
  +      method:  1 wallclock secs ( 1.51 usr +  0.08 sys =  1.59 CPU)</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   We are are interested in the 'total CPU times' and not the 'wallclock
   seconds'. It's possible that the load on the system was different for the
   two tests while benchmarking, so the wallclock times give us no useful
   information.
   
  -<P><A NAME="anchor654"></A>
  +<P>
   We see that the <EM>method</EM> calling type is almost twice as slow as the
   <EM>function</EM> call, 0.85 CPU compared to 1.59 CPU real execution time. Why does this
   happen? Because the difference between functions and methods is the time
  @@ -3995,15 +7097,16 @@
   pass, less stack operations, less time to get to the guts of the
   subroutine.
   
  -<P><A NAME="anchor655"></A>
  +<P>
   perl5.6+ does better method caching, <CODE>Foo-&gt;method()</CODE> is a little bit faster (some constant folding magic), but not
   <CODE>Foo-&gt;$method()</CODE>. And the improvement does not address the
   <CODE>@ISA</CODE> lookup that still happens in either case.
   
  -<P><A NAME="anchor656"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H3><A NAME="The_Overhead_with_Heavy_Subrouti">The Overhead with Heavy Subroutines</A></H3></CENTER>
  -<P><A NAME="anchor657"></A>
  +<P>
   But that doesn't mean that you shouldn't use methods. Generally your
   functions do something, and the more they do the less significant is the
   time to perform the call, because the calling time is effectively fixed and
  @@ -4012,8 +7115,17 @@
   function the smaller the relative overhead of the method call. The next
   benchmark proves this point:
   
  -<P><A NAME="anchor658"></A>
  -<PRE>  bench_call2.pl
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  bench_call2.pl
     --------------
     package Foo;
     
  @@ -4030,34 +7142,73 @@
     timethese(50_000, {
                    method   =&gt; sub { Foo-&gt;bar()      },
                    function =&gt; sub { Foo::bar('Foo');},
  -                });
  -</PRE>
  -<P><A NAME="anchor659"></A>
  +                });</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   We get a very close benchmarks!
  +
  +<P>
   
  -<P><A NAME="anchor660"></A>
  -<PRE>  function: 33 wallclock secs (15.81 usr +  1.12 sys = 16.93 CPU)
  -    method: 32 wallclock secs (18.02 usr +  1.34 sys = 19.36 CPU)
  -</PRE>
  -<P><A NAME="anchor661"></A>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  function: 33 wallclock secs (15.81 usr +  1.12 sys = 16.93 CPU)
  +    method: 32 wallclock secs (18.02 usr +  1.34 sys = 19.36 CPU)</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Let's make the subroutine <EM>bar</EM> even slower:
  +
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
   
  -<P><A NAME="anchor662"></A>
  -<PRE>  sub bar { 
  +	<td>
  +	  <pre>  sub bar { 
       my $class = shift;
     
       my ($x,$y) = (100,100);
       $y = log ($x ** 10)  for (0..40);
  -  };
  -</PRE>
  -<P><A NAME="anchor663"></A>
  +  };</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   And the result is amazing, the <EM>method</EM> call convention was faster than <EM>function</EM>:
  +
  +<P>
   
  -<P><A NAME="anchor664"></A>
  -<PRE>  function: 81 wallclock secs (25.63 usr +  1.84 sys = 27.47 CPU)
  -    method: 61 wallclock secs (19.69 usr +  1.49 sys = 21.18 CPU)
  -</PRE>
  -<P><A NAME="anchor665"></A>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  function: 81 wallclock secs (25.63 usr +  1.84 sys = 27.47 CPU)
  +    method: 61 wallclock secs (19.69 usr +  1.49 sys = 21.18 CPU)</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   In case your functions do very little, like the functions that generate
   HTML tags in <CODE>CGI.pm</CODE>, the overhead might become a significant one. If your goal is speed you
   might consider using the
  @@ -4066,35 +7217,69 @@
   saving programmer time which, over the life of a project may turn out to be
   the most significant cost factor.
   
  -<P><A NAME="anchor666"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H3><A NAME="Are_All_Methods_Slower_than_Func">Are All Methods Slower than Functions?</A></H3></CENTER>
  -<P><A NAME="anchor667"></A>
  +<P>
   Some modules' API is misleading, for example <CODE>CGI.pm</CODE> allows you to execute its subroutines as functions or as methods. As you
   will see in a moment its function form of the calls is slower than the
   method form because it does some voodoo work when the function form call is
   used.
   
  -<P><A NAME="anchor668"></A>
  -<PRE>  use CGI;
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  use CGI;
     my $q = new CGI;
     $q-&gt;param('x',5);
  -  my $x = $q-&gt;param('x');
  -</PRE>
  -<P><A NAME="anchor669"></A>
  +  my $x = $q-&gt;param('x');</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   versus
  +
  +<P>
   
  -<P><A NAME="anchor670"></A>
  -<PRE>  use CGI qw(:standard);
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  use CGI qw(:standard);
     param('x',5);
  -  my $x = param('x');
  -</PRE>
  -<P><A NAME="anchor671"></A>
  +  my $x = param('x');</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   As usual, let's benchmark some very light calls and compare. Ideally we
   would expect the <EM>methods</EM> to be slower than <EM>functions</EM> based on the previous benchmarks:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor672"></A>
  -<PRE>  bench_call3.pl
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  bench_call3.pl
     ---------------
     use Benchmark;
     
  @@ -4106,41 +7291,57 @@
       (20000, {
         method   =&gt; sub {$q-&gt;param('x',5); $x = $q-&gt;param('x'); },
         function =&gt; sub {    param('x',5); $x =     param('x'); },
  -     });
  -</PRE>
  -<P><A NAME="anchor673"></A>
  +     });</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   The benchmark is written is such a way that all the initializations are
   done at the beginning, so that we get as accurate performance figures as
   possible. Let's do it:
  +
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
   
  -<P><A NAME="anchor674"></A>
  -<PRE>  % ./bench_call3.pl
  +	<td>
  +	  <pre>  % ./bench_call3.pl
     
     function: 51 wallclock secs (28.16 usr +  2.58 sys = 30.74 CPU)
  -    method: 39 wallclock secs (21.88 usr +  1.74 sys = 23.62 CPU)
  -</PRE>
  -<P><A NAME="anchor675"></A>
  +    method: 39 wallclock secs (21.88 usr +  1.74 sys = 23.62 CPU)</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   As we can see methods are faster than functions, which seems to be wrong.
   The explanation lays in the way <CODE>CGI.pm</CODE> is implemented.
   <CODE>CGI.pm</CODE> uses some <EM>fancy</EM> tricks to make the same routine act both as a <EM>method</EM> and a plain <EM>function</EM>. The overhead of checking whether the arguments list looks like a <EM>method</EM> invocation or not, will mask the slight difference in time for the way the
   function was called.
   
  -<P><A NAME="anchor676"></A>
  +<P>
   If you are intrigued and want to investigate further by yourself the
   subroutine you want to explore is called <EM>self_or_default</EM>. The first line of this function short-circuits if you are using the
   object methods, but the whole function is called if you are using the
   functional forms. Therefore, the functional form should be slightly slower
   than the object form.
   
  -<P><A NAME="anchor677"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="Imported_Symbols_and_Memory_Usag">Imported Symbols and Memory Usage</A></H2></CENTER>
  -<P><A NAME="anchor678"></A>
  +<P>
   There is a real memory hit when you import all of the functions into your
   process' memory. This can significantly enlarge memory requirements,
   particularly when there are many child processes.
   
  -<P><A NAME="anchor679"></A>
  +<P>
   In addition to polluting the namespace, when a process imports symbols from
   any module or any script it grows by the size of the space allocated for
   those symbols. The more you import (e.g. <CODE>qw(:standard)</CODE> vs
  @@ -4149,90 +7350,185 @@
   function method interface, let's call that Y. Finally let's say that you
   have a number of processes equal to Z.
   
  -<P><A NAME="anchor680"></A>
  +<P>
   You will need X*Y*Z size of additional memory, taking X=10k, Y=10, Z=30, we
   get 10k*10*30 = 3Mb!!! Now you understand the difference.
   
  -<P><A NAME="anchor681"></A>
  +<P>
   Let's benchmark <CODE>CGI.pm</CODE> using <CODE>GTop.pm</CODE>. First we will try it with no exporting at all.
  +
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
   
  -<P><A NAME="anchor682"></A>
  -<PRE>  use GTop ();
  +	<td>
  +	  <pre>  use GTop ();
     use CGI ();
  -  print GTop-&gt;new-&gt;proc_mem($$)-&gt;size;
  -</PRE>
  -<P><A NAME="anchor683"></A>
  -<PRE>  1,949,696
  -</PRE>
  -<P><A NAME="anchor684"></A>
  +  print GTop-&gt;new-&gt;proc_mem($$)-&gt;size;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  1,949,696</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Now exporting a few dozens symbols:
   
  -<P><A NAME="anchor685"></A>
  -<PRE>  use GTop ();
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  use GTop ();
     use CGI qw(:standard);
  -  print GTop-&gt;new-&gt;proc_mem($$)-&gt;size;
  -</PRE>
  -<P><A NAME="anchor686"></A>
  -<PRE>  1,966,080
  -</PRE>
  -<P><A NAME="anchor687"></A>
  +  print GTop-&gt;new-&gt;proc_mem($$)-&gt;size;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  1,966,080</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   And finally exporting all the symbols (about 130)
  +
  +<P>
   
  -<P><A NAME="anchor688"></A>
  -<PRE>  use GTop ();
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  use GTop ();
     use CGI qw(:all);
  -  print GTop-&gt;new-&gt;proc_mem($$)-&gt;size;
  -</PRE>
  -<P><A NAME="anchor689"></A>
  -<PRE>  1,970,176
  -</PRE>
  -<P><A NAME="anchor690"></A>
  +  print GTop-&gt;new-&gt;proc_mem($$)-&gt;size;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  1,970,176</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Results:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor691"></A>
  -<PRE>  import symbols  size(bytes)  delta(bytes) relative to ()
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  import symbols  size(bytes)  delta(bytes) relative to ()
     --------------------------------------
     ()              1949696             0
     qw(:standard)   1966080         16384
  -  qw(:all)        1970176         20480
  -</PRE>
  -<P><A NAME="anchor692"></A>
  +  qw(:all)        1970176         20480</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   So in my example above X=20k =&gt; 20K*10*30 = 6Mb. You will need 6Mb more
   when importing all the <CODE>CGI.pm</CODE>'s symbols than when you import none at all.
   
  -<P><A NAME="anchor693"></A>
  +<P>
   Generally you use more than one script, run more than one process and
   probably import more symbols from the additional modules that you deploy.
   So the real numbers are much bigger.
   
  -<P><A NAME="anchor694"></A>
  +<P>
   The function method is faster in the general case, because of the time
   overhead to resolve the pointer from the object.
   
  -<P><A NAME="anchor695"></A>
  +<P>
   If you are looking for performance improvements, you will have to face the
   fact that having to type <CODE>My::Module::my_method</CODE> might save you a good chunk of memory if the above call must not be called
   with a reference to an object, but even then it can be passed by value.
   
  -<P><A NAME="anchor696"></A>
  +<P>
   I strongly endorse <A HREF="././modules.html#Apache_Request_libapreq_Gen">Apache::Request (libapreq) - Generic Apache Request Library</A>. Its core is written in C, giving it a significant memory and performance
   benefit. It has all the functionality of <CODE>CGI.pm</CODE> except the HTML generation functions.
   
  -<P><A NAME="anchor697"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="Concatenation_or_List">Concatenation or List</A></H2></CENTER>
  -<P><A NAME="anchor698"></A>
  +<P>
   When the strings are small, it's almost doesn't matter whether a
   concatination or a list is used:
   
  -<P><A NAME="anchor699"></A>
  -<PRE>  use Benchmark;
  -  
  -  open my $fh, '&gt;', '/dev/null';
  -  
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  use Benchmark;
  +  use Symbol;
  +  my $fh = gensym;
  +  open $fh, &quot;&gt;/dev/null&quot; or die;
  +    
     my($one, $two, $three, $four) = ('a'..'d');
     
  -  timethese(500_000,
  +  timethese(1_000_000,
             {
              concat =&gt; sub {
                print $fh &quot;$one$two$three$four&quot;;
  @@ -4240,24 +7536,37 @@
              list =&gt; sub {
                print $fh $one, $two, $three, $four;
              },
  -          });
  -</PRE>
  -<P><A NAME="anchor700"></A>
  -<PRE>  Benchmark: timing 500000 iterations of concat, list...
  -    concat:  8 wallclock secs ( 6.63 usr +  0.04 sys =  6.67 CPU)
  -      list:  8 wallclock secs ( 6.49 usr +  0.01 sys =  6.50 CPU)
  -</PRE>
  -<P><A NAME="anchor701"></A>
  +          });</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +Benchmark: timing 1000000 iterations of concat, list... concat: 5 wallclock
  +secs ( 4.76 usr + 0.00 sys = 4.76 CPU) list: 4 wallclock secs ( 4.30 usr +
  +0.00 sys = 4.30 CPU)
  +
  +<P>
   When the strings are big lists are faster:
   
  -<P><A NAME="anchor702"></A>
  -<PRE>  use Benchmark;
  -  
  -  open my $fh, '&gt;', '/dev/null';
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  use Benchmark;
  +  use Symbol;
  +  my $fh = gensym;
  +  open $fh, &quot;&gt;/dev/null&quot; or die;
     
     my($one, $two, $three, $four) = map { $_ x 1000 } ('a'..'d');
     
  -  timethese(100_000,
  +  timethese(500_000,
             {
              concat =&gt; sub {
                print $fh &quot;$one$two$three$four&quot;;
  @@ -4265,131 +7574,213 @@
              list =&gt; sub {
                print $fh $one, $two, $three, $four;
              },
  -          });
  -</PRE>
  -<P><A NAME="anchor703"></A>
  -<PRE>  Benchmark: timing 100000 iterations of concat, list...
  -    concat: 13 wallclock secs (11.88 usr +  0.51 sys = 12.39 CPU)
  -      list: 11 wallclock secs (10.13 usr +  0.21 sys = 10.34 CPU)
  -</PRE>
  -<P><A NAME="anchor704"></A>
  -A list is almost 17% faster than concatination.
  +          });</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  Benchmark: timing 500000 iterations of concat, list...
  +      concat: 10 wallclock secs ( 9.04 usr +  0.53 sys =  9.57 CPU)
  +        list:  6 wallclock secs ( 5.72 usr +  0.56 sys =  6.28 CPU)</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +A list is almost 50% faster than concatenation.
   
  -<P><A NAME="anchor705"></A>
  +<P>
   Also when you use <EM>"string"</EM> you use interpolation (since <CODE>&quot;&quot;</CODE> is an operator in Perl), which turns into concatination, which uses more
   memory and is slower than using a list. When you use <EM>'string'</EM> there is no interpolation, therefore it's faster and you have to use a list
   if you need to pass more than one argument.
   
  -<P><A NAME="anchor706"></A>
  +<P>
   There will be exceptions, like <EM>"string\n"</EM> where you cannot use single quotes. But if you do <EM>'string',"\n"</EM> readability gets hurt. And we want want our code to be readable and
   maintainable.
   
  -<P><A NAME="anchor707"></A>
  +<P>
   [ReaderMETA]: Please send more mod_perl relevant Perl performance hints
   
  -<P><A NAME="anchor708"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<CENTER><H2><A NAME="Cached_stat_Calls_by_Perl">Cached stat() Calls by Perl</A></H2></CENTER>
  -<P><A NAME="anchor709"></A>
  -When you do a <CODE>stat()</CODE> (or its variations <CODE>-M</CODE> -- last modification time, <CODE>-A</CODE> -- last access time, <CODE>-C</CODE> -- last inode-change time, etc), the information is cached. If you need to
  -make an additional check for the same file, use the <CODE>_</CODE> magic variable and save the overhead of an unnecessary <CODE>stat()</CODE>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
  +<CENTER><H2><A NAME="Using_Perl_stat_Call_s_Cached_">Using Perl stat() Call's Cached Results</A></H2></CENTER>
  +<P>
  +When you do a <CODE>stat()</CODE> (or its variations <CODE>-M</CODE> -- last modification time, <CODE>-A</CODE> -- last access time, <CODE>-C</CODE> -- last inode-change time, etc), the returned information is cached
  +internally. If you need to make an additional check for the same file, use
  +the <CODE>_</CODE> magic variable and save the overhead of an unnecessary <CODE>stat()</CODE>
   call. For example when testing for existence and read permissions you might
   use:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor710"></A>
  -<PRE>  my $filename = &quot;./test&quot;;
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  my $filename = &quot;./test&quot;;
       # three stat() calls
  -  print &quot;OK\n&quot; if -e $filename and -r $filename; 
  +  print &quot;OK\n&quot; if -e $filename and -r $filename;
     my $mod_time = (-M $filename) * 24 * 60 * 60;
  -  print &quot;$filename was modified $mod_time seconds before startup\n&quot;;
  -</PRE>
  -<P><A NAME="anchor711"></A>
  +  print &quot;$filename was modified $mod_time seconds before startup\n&quot;;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   or the more efficient:
  +
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
   
  -<P><A NAME="anchor712"></A>
  -<PRE>  my $filename = &quot;./test&quot;;
  +	<td>
  +	  <pre>  my $filename = &quot;./test&quot;;
       # one stat() call
     print &quot;OK\n&quot; if -e $filename and -r _;
     my $mod_time = (-M _) * 24 * 60 * 60;
  -  print &quot;$filename was modified $mod_time seconds before startup\n&quot;;
  -</PRE>
  -<P><A NAME="anchor713"></A>
  -Two <CODE>stat()</CODE> syscalls saved!
  +  print &quot;$filename was modified $mod_time seconds before startup\n&quot;;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +Two <CODE>stat()</CODE> calls saved!
   
  -<P><A NAME="anchor714"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H1><A NAME="Apache_Registry_and_Derivatives">Apache::Registry and Derivatives Specific Notes</A></H1></CENTER>
  -<P><A NAME="anchor715"></A>
  +<P>
   These are the sections that deal solely with <CODE>Apache::Registry</CODE> and derived modules, like <CODE>Apache::PerlRun</CODE> and <CODE>Apache::RegistryBB</CODE>. No Perl handlers code is discussed here, so if you don't use these
   modules, feel free to skip this section.
   
  -<P><A NAME="anchor716"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="Be_carefull_with_symbolic_links">Be carefull with symbolic links</A></H2></CENTER>
  -<P><A NAME="anchor717"></A>
  +<P>
   As you know <CODE>Apache::Registry</CODE> caches the scripts based on their URI. If you have the same script that can
   be reached by different URIs, which is possible if you have used symbolic
   links, you will get the same script cached twice!
   
  -<P><A NAME="anchor718"></A>
  +<P>
   For example:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor719"></A>
  -<PRE>  % ln -s /home/httpd/perl/news/news.pl /home/httpd/perl/news.pl
  -</PRE>
  -<P><A NAME="anchor720"></A>
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  % ln -s /home/httpd/perl/news/news.pl /home/httpd/perl/news.pl</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Now the script can be reached through the both URIs <CODE>/news/news.pl</CODE>
   and <CODE>/news.pl</CODE>. It doesn't really matter until you advertise the two URIs, and users
   reach the same script from both of them.
   
  -<P><A NAME="anchor721"></A>
  +<P>
   To detect this, use the
   <A HREF="././debug.html#Apache_Status_Embedded_Inter">/perl-status</A> handler to see all the compiled scripts and their packages. In our example,
   when requesting: <A
   HREF="http://localhost/perl-status?rgysubs">http://localhost/perl-status?rgysubs</A>
   you would see:
   
  -<P><A NAME="anchor722"></A>
  -<PRE>  Apache::ROOT::perl::news::news_2epl
  -  Apache::ROOT::perl::news_2epl
  -</PRE>
  -<P><A NAME="anchor723"></A>
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  Apache::ROOT::perl::news::news_2epl
  +  Apache::ROOT::perl::news_2epl</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   after both the URIs have been requested from the same child process that
   happened to serve your request. To make the debugging easier see
   <A HREF="././control.html#Running_a_Server_in_Single_Proce">run the server in single mode</A>.
   
  -<P><A NAME="anchor724"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H1><A NAME="Improving_Performance_by_Prevent">Improving Performance by Prevention</A></H1></CENTER>
  -<P><A NAME="anchor725"></A>
  +<P>
   There are two ways to improve performance: one is by tuning to squeeze the
   most out of your hardware and software; and the other is preventing certain
   bad things from happening, e.g. memory leaks, unshared memory, Denial of
   Service (DoS) attacks, etc.
   
  -<P><A NAME="anchor726"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="Memory_leakage">Memory leakage</A></H2></CENTER>
  -<P><A NAME="anchor727"></A>
  +<P>
   Scripts under mod_perl can very easily leak memory! Global variables stay
   around indefinitely, lexically scoped variables (declared with
   <CODE>my()</CODE>) are destroyed when they go out of scope, provided there are no references
   to them from outside that scope.
   
  -<P><A NAME="anchor728"></A>
  +<P>
   Perl doesn't return the memory it acquired from the kernel. It does reuse
   it though!
   
  -<P><A NAME="anchor729"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H3><A NAME="Reading_In_A_Whole_File">Reading In A Whole File</A></H3></CENTER>
  -<P><A NAME="anchor730"></A>
  -<PRE>  open IN, $file or die $!;
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  open IN, $file or die $!;
     local $/ = undef; # will read the whole file in
     $content = &lt;IN&gt;;
  -  close IN;
  -</PRE>
  -<P><A NAME="anchor731"></A>
  +  close IN;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   If your file is 5Mb, the child which served that script will grow by
   exactly that size. Now if you have 20 children, and all of them will serve
   this CGI, they will consume 20*5M = 100M of RAM in total! If that's the
  @@ -4398,10 +7789,11 @@
   modify the file itself, use a temporary file. When finished, overwrite the
   source file. Make sure you use a locking mechanism!
   
  -<P><A NAME="anchor732"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H3><A NAME="Copying_Variables_Between_Functi">Copying Variables Between Functions</A></H3></CENTER>
  -<P><A NAME="anchor733"></A>
  +<P>
   Now let's talk about passing variables by value. Let's use the example
   above, assuming we have no choice but to read the whole file before any
   data processing takes place. Now you have some imaginary
  @@ -4412,7 +7804,7 @@
   Whenever you think the variable can grow bigger than a few Kb, pass it by
   reference!
   
  -<P><A NAME="anchor734"></A>
  +<P>
   Once I wrote a script that passed the contents of a little flat file
   database to a function that processed it by value -- it worked and it was
   fast, but after a time the database became bigger, so passing it by value
  @@ -4423,66 +7815,127 @@
   bigger than you envisage at the time you code the program. There are a few
   approaches you can use to pass and use variables passed by reference. For
   example:
  +
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
   
  -<P><A NAME="anchor735"></A>
  -<PRE>  my $content = qq{foobarfoobar};
  +	<td>
  +	  <pre>  my $content = qq{foobarfoobar};
     process(\$content);
     sub process{
       my $r_var = shift; 
       $$r_var =~ s/foo/bar/gs;
         # nothing returned - the variable $content outside has already 
         # been modified
  -  }
  -</PRE>
  -<P><A NAME="anchor736"></A>
  +  }</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   If you work with arrays or hashes it's:
  +
  +<P>
   
  -<P><A NAME="anchor737"></A>
  -<PRE>  @{$var_lr}  dereferences an array
  -  %{$var_hr}  dereferences a hash
  -</PRE>
  -<P><A NAME="anchor738"></A>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  @{$var_lr}  dereferences an array
  +  %{$var_hr}  dereferences a hash</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   We can still access individual elements of arrays and hashes that we have a
   reference to without dereferencing them:
  +
  +<P>
   
  -<P><A NAME="anchor739"></A>
  -<PRE>  $var_lr-&gt;[$index]  get $index'th element of an array via a ref
  -  $var_hr-&gt;{$key}    get $key'th element of a hash via a ref
  -</PRE>
  -<P><A NAME="anchor740"></A>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  $var_lr-&gt;[$index]  get $index'th element of an array via a ref
  +  $var_hr-&gt;{$key}    get $key'th element of a hash via a ref</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   For more information see <CODE>perldoc perlref</CODE>.
   
  -<P><A NAME="anchor741"></A>
  +<P>
   Another approach would be to use the <CODE>@_</CODE> array directly. This has the effect of passing by reference:
  +
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
   
  -<P><A NAME="anchor742"></A>
  -<PRE>  process($content);
  +	<td>
  +	  <pre>  process($content);
     sub process{
       $_[0] =~ s/foo/bar/gs;
         # nothing returned - the variable $content outside has been
         # already modified
  -  }
  -</PRE>
  -<P><A NAME="anchor743"></A>
  +  }</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   From <CODE>perldoc perlsub</CODE>:
  +
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
   
  -<P><A NAME="anchor744"></A>
  -<PRE>      The array @_ is a local array, but its elements are aliases for
  +	<td>
  +	  <pre>      The array @_ is a local array, but its elements are aliases for
         the actual scalar parameters.  In particular, if an element
         $_[0] is updated, the corresponding argument is updated (or an
  -      error occurs if it is not possible to update)...
  -</PRE>
  -<P><A NAME="anchor745"></A>
  +      error occurs if it is not possible to update)...</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Be careful when you write this kind of subroutine, since it can confuse a
   potential user. It's not obvious that call like
   <CODE>process($content);</CODE> modifies the passed variable. Programmers (the users of your library in
   this case) are used to subroutines that either modify variables passed by
   reference or expressly return a result (e.g. <CODE>$content=process($content);</CODE>).
   
  -<P><A NAME="anchor746"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H3><A NAME="Work_With_Databases">Work With Databases</A></H3></CENTER>
  -<P><A NAME="anchor747"></A>
  +<P>
   If you do some DB processing, you will often encounter the need to read
   lots of records into your program, and then print them to the browser after
   they are formatted. I won't even mention the horrible case where
  @@ -4490,24 +7943,36 @@
   relational DB and let the SQL do the job, so you get only the records you
   need!
   
  -<P><A NAME="anchor748"></A>
  +<P>
   We will use <CODE>DBI</CODE> for this (assume that we are already connected to the DB--refer to <CODE>perldoc DBI</CODE> for a complete reference to the <CODE>DBI</CODE>
   module):
  +
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
   
  -<P><A NAME="anchor749"></A>
  -<PRE>  $sth-&gt;execute;
  +	<td>
  +	  <pre>  $sth-&gt;execute;
     while(@row_ary  = $sth-&gt;fetchrow_array;) {
           # do DB accumulation into some variable
     }
  -  # print the output using the the data returned from the DB
  -</PRE>
  -<P><A NAME="anchor750"></A>
  +  # print the output using the the data returned from the DB</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   In the example above the httpd_process will grow by the size of the
   variables that have been allocated for the records that matched the query.
   Again remember to multiply it by the number of the children your server
   runs!
   
  -<P><A NAME="anchor751"></A>
  +<P>
   A better approach is not to accumulate the records, but rather to print
   them as they are fetched from the DB. Moreover, we will use the
   <CODE>bind_col()</CODE> and <CODE>$sth-&gt;fetchrow_arrayref()</CODE> (aliased to
  @@ -4515,8 +7980,17 @@
   prints an HTML table with matched data, the only memory that is being used
   is a <CODE>@cols</CODE> array to hold temporary row values:
   
  -<P><A NAME="anchor752"></A>
  -<PRE>  my @select_fields = qw(a b c);
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  my @select_fields = qw(a b c);
         # create a list of cols values
     my @cols = ();
     @cols[0..$#select_fields] = ();
  @@ -4530,45 +8004,105 @@
              map(&quot;&lt;TD&gt;$_&lt;/TD&gt;&quot;, @cols),
              &quot;&lt;/TR&gt;&quot;;
     }
  -  print &quot;&lt;/TABLE&gt;&quot;;
  -</PRE>
  -<P><A NAME="anchor753"></A>
  +  print &quot;&lt;/TABLE&gt;&quot;;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Note: the above method doesn't allow you to know how many records have been
   matched. The workaround is to run an identical query before the code above
   where you use <CODE>SELECT count(*) ...</CODE> instead of <CODE>'SELECT *
   ...</CODE>, to get the number of matched records. It should be much faster, since you
   can remove any <STRONG>SORTBY</STRONG> and similar attributes.
   
  -<P><A NAME="anchor754"></A>
  +<P>
   For those who think that <STRONG>$sth-&gt;rows</STRONG> will do the job, here is the quote from the <CODE>DBI</CODE> manpage:
  +
  +<P>
   
  -<P><A NAME="anchor755"></A>
  -<PRE>  rows();
  -</PRE>
  -<P><A NAME="anchor756"></A>
  -<PRE>  $rv = $sth-&gt;rows;
  -</PRE>
  -<P><A NAME="anchor757"></A>
  -<PRE>  Returns the number of rows affected by the last database altering
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  rows();</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  $rv = $sth-&gt;rows;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  Returns the number of rows affected by the last database altering
     command, or -1 if not known or not available.  Generally you can
     only rely on a row count after a do or non-select execute (for some
     specific operations like update and delete) or after fetching all
  -  the rows of a select statement.
  -</PRE>
  -<P><A NAME="anchor758"></A>
  -<PRE>  For select statements it is generally not possible to know how many
  +  the rows of a select statement.</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  For select statements it is generally not possible to know how many
     rows will be returned except by fetching them all.  Some drivers
     will return the number of rows the application has fetched so far
     but others may return -1 until all rows have been fetched. So use of
  -  the rows method with select statements is not recommended.
  -</PRE>
  -<P><A NAME="anchor759"></A>
  +  the rows method with select statements is not recommended.</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   As a bonus, I wanted to write a single sub that flexibly processes any
   query. It would accept conditions, a call-back closure sub, select fields
   and restrictions.
  +
  +<P>
   
  -<P><A NAME="anchor760"></A>
  -<PRE>  # Usage:
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  # Usage:
     # $o-&gt;dump(\%conditions,\&amp;callback_closure,\@select_fields,@restrictions);
     #
     sub dump{
  @@ -4611,15 +8145,27 @@
         # according to the previous calls
       &amp;$rsub();
     
  -  } # end of sub dump
  -</PRE>
  -<P><A NAME="anchor761"></A>
  +  } # end of sub dump</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Now a callback closure sub can do lots of things. We need a closure to know
   what stage are we in: header, body or tail. For example, we want a callback
   closure for formatting the rows to print: 
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor762"></A>
  -<PRE>  my $rsub = eval {
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  my $rsub = eval {
         # make a copy of @fields list, since it might go
         # out of scope when this closure is called
       my @fields = @fields; 
  @@ -4666,79 +8212,122 @@
           }
     
         }  #  end of sub {}
  -  };  #  end of my $rsub = eval {
  -</PRE>
  -<P><A NAME="anchor763"></A>
  +  };  #  end of my $rsub = eval {</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   You might also want to check the section <A HREF="././performance.html#Limiting_the_Size_of_the_Process">Limiting the Size of the Processes</A>
   and <A HREF="././performance.html#Limiting_the_Resources_Used_by_h">Limiting the Resources Used by httpd children</A>.
   
  -<P><A NAME="anchor764"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="Limiting_the_Size_of_the_Process">Limiting the Size of the Processes</A></H2></CENTER>
  -<P><A NAME="anchor765"></A>
  +<P>
   <CODE>Apache::SizeLimit</CODE> allows you to kill off Apache httpd processes if they grow too large.  
   
  -<P><A NAME="anchor766"></A>
  +<P>
   Configuration:
   
  -<P><A NAME="anchor767"></A>
  +<P>
   In your <EM>startup.pl</EM>:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor768"></A>
  -<PRE>  use Apache::SizeLimit;
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  use Apache::SizeLimit;
     $Apache::SizeLimit::MAX_PROCESS_SIZE = 10000; 
  -  # in KB, so this is 10MB
  -</PRE>
  -<P><A NAME="anchor769"></A>
  +  # in KB, so this is 10MB</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   In your <EM>httpd.conf</EM>:
  +
  +<P>
   
  -<P><A NAME="anchor770"></A>
  -<PRE>  PerlFixupHandler Apache::SizeLimit
  -</PRE>
  -<P><A NAME="anchor771"></A>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  PerlFixupHandler Apache::SizeLimit</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   See perldoc <CODE>Apache::SizeLimit</CODE> for more details.
   
  -<P><A NAME="anchor772"></A>
  +<P>
   By using this module, you should be able to avoid using the Apache
   configuration directive <CODE>MaxRequestsPerChild</CODE>, although for some folks, using both in combination does the job.
   
  -<P><A NAME="anchor773"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="Keeping_the_Shared_Memory_Limit">Keeping the Shared Memory Limit</A></H2></CENTER>
  -<P><A NAME="anchor774"></A>
  +<P>
   <CODE>Apache::GTopLimit</CODE> module allows you to kill off Apache httpd processes if they grow too large
   (just like <CODE>Apache::SizeLimit</CODE>) or have too little shared memory left. See
   <A HREF="././modules.html#Apache_GTopLimit_Limit_Apache">Apache::GTopLimit</A>.
   
  -<P><A NAME="anchor775"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="Limiting_the_Resources_Used_by_h">Limiting the Resources Used by httpd Children</A></H2></CENTER>
  -<P><A NAME="anchor776"></A>
  +<P>
   <CODE>Apache::Resource</CODE> uses the <CODE>BSD::Resource</CODE> module, which in turn uses the C function <CODE>setrlimit()</CODE> to set limits on system resources such as memory and cpu usage.
  +
  +<P>
  +Configuration example:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor777"></A>
  -To configure:
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
   
  -<P><A NAME="anchor778"></A>
  -<PRE>  PerlModule Apache::Resource
  -    # set child memory limit in megabytes
  +	<td>
  +	  <pre>    # preload the module
  +  PerlModule Apache::Resource
  +  
  +    # set child memory limit (DATA segment) in megabytes
       # (default is 64 Meg)
     PerlSetEnv PERL_RLIMIT_DATA 32:48
  -  
       # set child CPU limit in seconds
       # (default is 360 seconds)
  -  PerlSetEnv PERL_RLIMIT_CPU 120
  +  PerlSetEnv PERL_RLIMIT_CPU 120:360
     
  -  PerlChildInitHandler Apache::Resource
  -</PRE>
  -<P><A NAME="anchor779"></A>
  +  PerlChildInitHandler Apache::Resource</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   If you configure <CODE>Apache::Status</CODE>, it will let you review the resources set in this way.
   
  -<P><A NAME="anchor780"></A>
  +<P>
   The following limit values are in megabytes: <CODE>DATA</CODE>, <CODE>RSS</CODE>,
   <CODE>STACK</CODE>, <CODE>FSIZE</CODE>, <CODE>CORE</CODE>, <CODE>MEMLOCK</CODE>; all others are treated as their natural unit. Prepend <CODE>PERL_RLIMIT_</CODE> for each one you want to use. Refer to the <CODE>setrlimit</CODE> man page on your OS for other possible resources.
   
  -<P><A NAME="anchor781"></A>
  +<P>
   A resource limit is specified as a soft limit and a hard limit. When a soft
   limit is exceeded a process may receive a signal (for example, if the CPU
   time or file size is exceeded), but it will be allowed to continue
  @@ -4746,14 +8335,15 @@
   The rlimit structure is used to specify the hard and soft limits on a
   resource. (See the manpage for <EM>setrlimit</EM> for your OS specific information.)
   
  -<P><A NAME="anchor782"></A>
  +<P>
   If the value of the variable is of the form <CODE>S:H</CODE>, <CODE>S</CODE> is treated as the soft limit, and <CODE>H</CODE> is the hard limit. If it is just a single number, it is used for both soft
   and hard limits.
   
  -<P><A NAME="anchor783"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H3><A NAME="OS_Specific_notes">OS Specific notes</A></H3></CENTER>
  -<P><A NAME="anchor784"></A>
  +<P>
   Note that under Linux <CODE>malloc()</CODE> uses <CODE>mmap()</CODE>
   instead of <CODE>brk().</CODE> This is done to conserve virtual memory -
   that is, when you malloc a large block of memory, it isn't actually given
  @@ -4761,72 +8351,122 @@
   syscall obeyed resource limits on data segment size as set in
   <CODE>setrlimit()</CODE> - <CODE>mmap()</CODE> doesn't.
   
  -<P><A NAME="anchor785"></A>
  +<P>
   <CODE>Apache::Resource</CODE>'s defaults put caps on data size and stack size. Linux's current memory
   allocation scheme doesn't honor these limits, so if you just do
   
  -<P><A NAME="anchor786"></A>
  -<PRE>  PerlSetEnv PERL_RLIMIT_DEFAULTS On
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  PerlSetEnv PERL_RLIMIT_DEFAULTS On
     PerlModule Apache::Resource
  -  PerlChildInitHandler Apache::Resource
  -</PRE>
  -<P><A NAME="anchor787"></A>
  +  PerlChildInitHandler Apache::Resource</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Your Apache processes are still free to use as much memory as they like.
   
  -<P><A NAME="anchor788"></A>
  +<P>
   However, <CODE>BSD::Resource</CODE> also has a limit called <CODE>RLIMIT_AS</CODE>
   (Address Space) which limits the total number of bytes of virtual memory
   assigned to a process. Happily, Linux's memory manager <EM>does</EM>
   honor this limit.
   
  -<P><A NAME="anchor789"></A>
  +<P>
   Therefore, you <EM>can</EM> limit memory usage under Linux with
   <CODE>Apache::Resource</CODE> -- simply add a line to <EM>httpd.conf</EM>:
  +
  +<P>
   
  -<P><A NAME="anchor790"></A>
  -<PRE>  PerlSetEnv PERL_RLIMIT_AS  67108864
  -</PRE>
  -<P><A NAME="anchor791"></A>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  PerlSetEnv PERL_RLIMIT_AS  67108864</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   This example sets a hard and soft limit of 64Mb of total address space.
   
  -<P><A NAME="anchor792"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H3><A NAME="Debug">Debug</A></H3></CENTER>
  -<P><A NAME="anchor793"></A>
  +<P>
   To debug add:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor794"></A>
  -<PRE>  &lt;Perl&gt;
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  &lt;Perl&gt;
       $Apache::Resource::Debug = 1;
       require Apache::Resource;
     &lt;/Perl&gt;
  -  PerlChildInitHandler Apache::Resource
  -</PRE>
  -<P><A NAME="anchor795"></A>
  +  PerlChildInitHandler Apache::Resource</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   and look in the <EM>error_log</EM> to see what it's doing.
   
  -<P><A NAME="anchor796"></A>
  +<P>
   Refer to <CODE>perldoc Apache::Resource</CODE> and <CODE>man 2 setrlimit</CODE> for more info.
   
  -<P><A NAME="anchor797"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="Limiting_the_Number_of_Processes">Limiting the Number of Processes Serving the Same Resource</A></H2></CENTER>
  -<P><A NAME="anchor798"></A>
  +<P>
   If you want to limit number of Apache children that could simultaneously be
   serving the (nearly) same resource, you should take a look at the <A HREF="././download.html#mod_throttle_access"><CODE>mod_throttle_access</CODE></A>
   module.
   
  -<P><A NAME="anchor799"></A>
  +<P>
   It solves the problem of too many concurrent request accessing the same
   URI, if for example it's very CPU intensive. For example you have three
   base URIs:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor800"></A>
  -<PRE>  /perl/news/
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  /perl/news/
     /perl/webmail/
  -  /perl/morphing/
  -</PRE>
  -<P><A NAME="anchor801"></A>
  +  /perl/morphing/</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   The first two URIs are response critical as people want to read news and
   their email. The third URI is very CPU and RAM intensive image morphing
   service, provided as a bonus to your users. Since you don't want users to
  @@ -4834,117 +8474,147 @@
   requests for this resource, since if you don't--the other two critical
   resources can be hurt.
   
  -<P><A NAME="anchor802"></A>
  +<P>
   The following setting:
  +
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
   
  -<P><A NAME="anchor803"></A>
  -<PRE>  &lt;Location &quot;/perl/morphing&quot;&gt;
  +	<td>
  +	  <pre>  &lt;Location &quot;/perl/morphing&quot;&gt;
       &lt;Limit PUT GET&gt;
         MaxConcurrentReqs 10
       &lt;/Limit&gt;
  -  &lt;/Location&gt; 
  -</PRE>
  -<P><A NAME="anchor804"></A>
  +  &lt;/Location&gt; </pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   will allow only 10 concurrent requests under the URI <EM>/perl/morphing</EM>
   and of methods PUT and GET to be processed at one time.
   
  -<P><A NAME="anchor805"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="Limiting_the_Request_Rate_Speed_">Limiting the Request Rate Speed (Robot Blocking)</A></H2></CENTER>
  -<P><A NAME="anchor806"></A>
  +<P>
   A limitation of using pattern matching to identify robots is that it only
   catches the robots that you know about, and then only those that identify
   themselves by name. A few devious robots masquerade as users by using user
   agent strings that identify themselves as conventional browsers. To catch
   such robots, you'll have to be more sophisticated.
   
  -<P><A NAME="anchor807"></A>
  +<P>
   <CODE>Apache::SpeedLimit</CODE> comes to your aid, see:
   
  -<P><A NAME="anchor808"></A>
  +<P>
   <A
   HREF="http://www.modperl.com/chapters/ch6.html#Blocking_Greedy_Clients">http://www.modperl.com/chapters/ch6.html#Blocking_Greedy_Clients</A>
   
   
  -<P><A NAME="anchor809"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H1><A NAME="Perl_Modules_for_Performance_Imp">Perl Modules for Performance Improvement</A></H1></CENTER>
  -<P><A NAME="anchor810"></A>
  +<P>
   These sections are about Perl modules that improve performance without
   requiring changes to your code. Mostly you just need to tweak the
   configuration file to plug these modules in.
   
  -<P><A NAME="anchor811"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="Sending_Plain_HTML_as_Compressed">Sending Plain HTML as Compressed Output</A></H2></CENTER>
  -<P><A NAME="anchor812"></A>
  +<P>
   See <A HREF="././modules.html#Apache_GzipChain_compress_HTM">Apache::GzipChain - compress HTML (or anything) in the OutputChain</A>
   
   
   
  -<P><A NAME="anchor813"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="Caching_Components_with_HTML_Ma">Caching Components with HTML::Mason</A></H2></CENTER>
  -<P><A NAME="anchor814"></A>
  +<P>
   META: complete the full description
   
  -<P><A NAME="anchor815"></A>
  +<P>
   <CODE>HTML::Mason</CODE> is a system that makes use of components to build HTML pages.
   
  -<P><A NAME="anchor816"></A>
  +<P>
   If most of your output is generated dynamically, but each finished page can
   be separated into different components, <CODE>HTML::Mason</CODE> can cache those components. This can really improve the performance of your
   service and reduce the load on the system.
   
  -<P><A NAME="anchor817"></A>
  +<P>
   Say for example that you have a page consisting of five components, each
   generated by a different SQL query, but for four of the five components
   it's the same four queries for each user so you don't have to rerun them
   again and again. Only one component is generated by a unique query and will
   not use the cache.
   
  -<P><A NAME="anchor818"></A>
  +<P>
   META: HTML::Mason docs (v 8.0) said Mason was 2-3 times slower than pure
   mod_perl, implying that the power &amp; convenience made up for this.
   
  -<P><A NAME="anchor819"></A>
  +<P>
   META: Should also mention Embperl (especially since its C + XS)
   
  -<P><A NAME="anchor820"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H1><A NAME="Efficient_Work_with_Databases_un">Efficient Work with Databases under mod_perl</A></H1></CENTER>
  -<P><A NAME="anchor821"></A>
  +<P>
   Most of the mod_perl enabled servers work with database engines, so in this
   section we will learn about two things: how mod_perl makes working with
   databases faster and a few tips for a more efficient DBI coding in Perl.
   (DBI provides an identical Perl interface to many database
   implementations.)
   
  -<P><A NAME="anchor822"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="Persistent_DB_Connections">Persistent DB Connections</A></H2></CENTER>
  -<P><A NAME="anchor823"></A>
  +<P>
   Another popular use of mod_perl is to take advantage of its ability to
   maintain persistent open database connections. The basic approach is as
   follows:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor824"></A>
  -<PRE>  # Apache::Registry script
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  # Apache::Registry script
     -------------------------
     use strict;
     use vars qw($dbh);
     
  -  $dbh ||= SomeDbPackage-&gt;connect(...);
  -</PRE>
  -<P><A NAME="anchor825"></A>
  +  $dbh ||= SomeDbPackage-&gt;connect(...);</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Since <CODE>$dbh</CODE> is a global variable for the child, once the child has opened the
   connection it will use it over and over again, unless you perform <CODE>disconnect()</CODE>.
   
  -<P><A NAME="anchor826"></A>
  +<P>
   Be careful to use different names for handlers if you open connections to
   different databases!
   
  -<P><A NAME="anchor827"></A>
  +<P>
   <CODE>Apache::DBI</CODE> allows you to make a persistent database connection. With this module
   enabled, every <CODE>connect()</CODE> request to the plain
   <CODE>DBI</CODE> module will be forwarded to the <CODE>Apache::DBI</CODE> module. This looks to see whether a database handle from a previous <CODE>connect()</CODE>
  @@ -4956,39 +8626,73 @@
   delete the <CODE>disconnect()</CODE> statements from your code</STRONG>. They will not do anything, the <CODE>Apache::DBI</CODE> module overloads the <CODE>disconnect()</CODE>
   method with a NOP. When a child exits there is no explicit disconnect, the
   child dies and so does the database connection. You may leave the <CODE>use DBI;</CODE> statement inside the scripts as well.
  +
  +<P>
  +The usage is simple -- add to <EM>httpd.conf</EM>:
   
  -<P><A NAME="anchor828"></A>
  -The usage is simple -- add to <CODE>httpd.conf</CODE>:
  +<P>
   
  -<P><A NAME="anchor829"></A>
  -<PRE>  PerlModule Apache::DBI
  -</PRE>
  -<P><A NAME="anchor830"></A>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  PerlModule Apache::DBI</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   It is important to load this module before any other <CODE>DBI</CODE>,
   <CODE>DBD::*</CODE> and <CODE>ApacheDBI*</CODE> modules!
  +
  +<P>
   
  -<P><A NAME="anchor831"></A>
  -<PRE>  db.pl
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  db.pl
     ------------
  -  use DBI;
  +  use DBI ();
     use strict;
     
     my $dbh = DBI-&gt;connect( 'DBI:mysql:database', 'user', 'password',
                             { autocommit =&gt; 0 }
                           ) || die $DBI::errstr;
     
  -  ...rest of the program
  -</PRE>
  -<P><A NAME="anchor832"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +  ...rest of the program</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H3><A NAME="Preopening_Connections_at_the_Ch">Preopening Connections at the Child Process' Fork Time</A></H3></CENTER>
  -<P><A NAME="anchor833"></A>
  +<P>
   If you use <CODE>DBI</CODE> for DB connections, and you use <CODE>Apache::DBI</CODE> to make them persistent, it also allows you to preopen connections to the
   DB for each child with the <CODE>connect_on_init()</CODE> method, thus saving a connection overhead on the very first request of
   every child.
  +
  +<P>
   
  -<P><A NAME="anchor834"></A>
  -<PRE>  use Apache::DBI ();
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  use Apache::DBI ();
     Apache::DBI-&gt;connect_on_init(&quot;DBI:mysql:test&quot;,
                                  &quot;login&quot;,
                                  &quot;passwd&quot;,
  @@ -4997,19 +8701,23 @@
                                   PrintError =&gt; 0,
                                   AutoCommit =&gt; 1,
                                  }
  -                              );
  -</PRE>
  -<P><A NAME="anchor835"></A>
  +                              );</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   This is a simple way to have Apache children establish connections on
   server startup. This call should be in a startup file <CODE>require()d</CODE>
   by <CODE>PerlRequire</CODE> or inside a &lt;Perl&gt; section. It will establish a connection when a child is started in
   that child process. See the
   <CODE>Apache::DBI</CODE> manpage for the requirements for this method.
   
  -<P><A NAME="anchor836"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H3><A NAME="Caching_prepare_Statements">Caching prepare() Statements</A></H3></CENTER>
  -<P><A NAME="anchor837"></A>
  +<P>
   You can also benefit from persistent connections by replacing
   <CODE>prepare()</CODE> with <CODE>prepare_cached().</CODE> That way you
   will always be sure that you have a good statement handle and you will get
  @@ -5017,37 +8725,40 @@
   parse your SQL and do a cache lookup every time you call
   <CODE>prepare_cached().</CODE>
   
  -<P><A NAME="anchor838"></A>
  +<P>
   Be warned that some databases (e.g PostgreSQL and Sybase) don't support
   caches of prepared plans. With Sybase you could open multiple connections
   to achieve the same result, although this is at the risk of getting
   deadlocks depending on what you are trying to do!
   
  -<P><A NAME="anchor839"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H3><A NAME="Handling_Timeouts">Handling Timeouts</A></H3></CENTER>
  -<P><A NAME="anchor840"></A>
  +<P>
   META: this is duplicated in the databases.pod -- should be resolved!
   
  -<P><A NAME="anchor841"></A>
  +<P>
   Some databases disconnect the client after a certain period of inactivity.
   This problem is known as the <STRONG>morning bug</STRONG>. The
   <CODE>ping()</CODE> method ensures that this will not happen. Some <CODE>DBD</CODE>
   drivers don't have this method, check the <CODE>Apache::DBI</CODE> manpage to see how to write a <CODE>ping()</CODE> method.
   
  -<P><A NAME="anchor842"></A>
  +<P>
   Another approach is to change the client's connection timeout. For mysql
   users, starting from mysql-3.22.x you can set a <CODE>wait_timeout</CODE>
   option at mysqld server startup to change the default value. Setting it to
   36 hours will fix the timeout problem in most cases.
   
  -<P><A NAME="anchor843"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="mod_perl_Database_Performance_Im">mod_perl Database Performance Improving</A></H2></CENTER>
  -<P><A NAME="anchor844"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H3><A NAME="Analysis_of_the_Problem">Analysis of the Problem</A></H3></CENTER>
  -<P><A NAME="anchor845"></A>
  +<P>
   A common web application architecture is one or more application servers
   which handle requests from client browsers by consulting one or more
   database servers and performing a transform on the data. When an
  @@ -5058,13 +8769,22 @@
   Apache, mod_perl, <CODE>DBI</CODE>, and Oracle will be considered. The application server uses Apache and
   mod_perl to service client requests, and <CODE>DBI</CODE> to communicate with a remote Oracle database.
   
  -<P><A NAME="anchor846"></A>
  +<P>
   In the course of servicing a typical client request, the application server
   must retrieve some data from the database and execute a stored procedure.
   There are several steps that need to be performed to complete the request:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor847"></A>
  -<PRE> 1: Connect to the database server
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre> 1: Connect to the database server
    2: Prepare a SQL SELECT statement
    3: Execute the SELECT statement
    4: Retrieve the results of the SELECT statement
  @@ -5073,21 +8793,34 @@
    7: Execute the stored procedure
    8: Release the stored procedure statement handle
    9: Commit or rollback
  - 10: Disconnect from the database server
  -</PRE>
  -<P><A NAME="anchor848"></A>
  + 10: Disconnect from the database server</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   In this document, an application will be described which achieves maximum
   performance by eliminating some of the steps above and optimizing others.
   
  -<P><A NAME="anchor849"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H3><A NAME="Optimizing_Database_Connections">Optimizing Database Connections</A></H3></CENTER>
  -<P><A NAME="anchor850"></A>
  +<P>
   A naive implementation would perform steps 1 through 10 from above on every
   request. A portion of the source code might look like this:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor851"></A>
  -<PRE>  # ...
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  # ...
     my $dbh = DBI-&gt;connect('dbi:Oracle:host', 'user', 'pass')
           || die $DBI::errstr;
     
  @@ -5124,23 +8857,38 @@
     }
     
     $dbh-&gt;disconnect;
  -  # ...
  -</PRE>
  -<P><A NAME="anchor852"></A>
  +  # ...</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   In practice, such an implementation would have hideous performance
   problems. The majority of the execution time of this program would likely
   be spent connecting to the database. An examination shows that step 1 is
   comprised of many smaller steps:
  +
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
   
  -<P><A NAME="anchor853"></A>
  -<PRE> 1: Connect to the database server
  +	<td>
  +	  <pre> 1: Connect to the database server
    1a: Build client-side data structures for an Oracle connection
    1b: Look up the server's alias in a file
    1c: Look up the server's hostname
    1d: Build a socket to the server
  - 1e: Build server-side data structures for this connection
  -</PRE>
  -<P><A NAME="anchor854"></A>
  + 1e: Build server-side data structures for this connection</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   The naive implementation waits for all of these steps to happen, and then
   throws away the database connection when it is done! This is obviously
   wasteful, and easily rectified. The best solution is to hoist the database
  @@ -5151,7 +8899,7 @@
   <CODE>Apache::DBI</CODE> module does this transparently and automatically with little effort on the
   part of the programmer.
   
  -<P><A NAME="anchor855"></A>
  +<P>
   <CODE>Apache::DBI</CODE> intercepts calls to <CODE>DBI</CODE>'s connect and disconnect methods and replaces them with its own.  <CODE>Apache::DBI</CODE> caches database connections when they are first opened, and it ignores
   disconnect commands. When an application tries to connect to the same
   database, <CODE>Apache::DBI</CODE> returns a cached connection, thus saving the significant time penalty of
  @@ -5159,48 +8907,85 @@
   
   
   
  -<P><A NAME="anchor856"></A>
  +<P>
   When <CODE>Apache::DBI</CODE> is in use, none of the code in the example needs to change. The code is
   upgraded from naive to respectable with the use of a simple module! The
   first and biggest database performance problem is quickly dispensed with.
   
  -<P><A NAME="anchor857"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H3><A NAME="Utilizing_the_Database_Server_s_">Utilizing the Database Server's Cache</A></H3></CENTER>
  -<P><A NAME="anchor858"></A>
  +<P>
   Most database servers, including Oracle, utilize a cache to improve the
   performance of recently seen queries. The cache is keyed on the SQL
   statement. If a statement is identical to a previously seen statement, the
   execution plan for the previous statement is reused. This can be a
   considerable improvement over building a new statement execution plan.
   
  -<P><A NAME="anchor859"></A>
  +<P>
   Our respectable implementation from the last section is not making use of
   this caching ability. It is preparing the statement: 
  +
  +<P>
   
  -<P><A NAME="anchor860"></A>
  -<PRE>  SELECT foo FROM bar WHERE baz = $baz
  -</PRE>
  -<P><A NAME="anchor861"></A>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  SELECT foo FROM bar WHERE baz = $baz</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   The problem is that <CODE>$baz</CODE> is being read from an HTML form, and is therefore likely to change on every
   request. When the database server sees this statement, it is going to look
   like:
  +
  +<P>
   
  -<P><A NAME="anchor862"></A>
  -<PRE>  SELECT foo FROM bar WHERE baz = 1
  -</PRE>
  -<P><A NAME="anchor863"></A>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  SELECT foo FROM bar WHERE baz = 1</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   and on the next request, the SQL will be:
  +
  +<P>
   
  -<P><A NAME="anchor864"></A>
  -<PRE>  SELECT foo FROM bar WHERE baz = 42
  -</PRE>
  -<P><A NAME="anchor865"></A>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  SELECT foo FROM bar WHERE baz = 42</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Since the statements are different, the database server will not be able to
   reuse its execution plan, and will proceed to make another one. This
   defeats the purpose of the SQL statement cache.
   
  -<P><A NAME="anchor866"></A>
  +<P>
   The application server needs to make sure that SQL statements which are the
   same look the same. The way to achieve this is to use placeholders and
   bound parameters. The placeholder is a blank in the SQL statement, which
  @@ -5208,24 +8993,45 @@
   parameter is the value which is inserted into the blank before the
   statement is executed.
   
  -<P><A NAME="anchor867"></A>
  +<P>
   With placeholders, the SQL statement looks like: 
  +
  +<P>
   
  -<P><A NAME="anchor868"></A>
  -<PRE>  SELECT foo FROM bar WHERE baz = :baz
  -</PRE>
  -<P><A NAME="anchor869"></A>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  SELECT foo FROM bar WHERE baz = :baz</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Regardless of whether <CODE>baz</CODE> is 1 or 42, the SQL always looks the same, and the database server can
   reuse its cached execution plan for this statement. This technique has
   eliminated the execution plan generation penalty from the per-request
   runtime. The potential performance improvement from this optimization could
   range from modest to very significant.
   
  -<P><A NAME="anchor870"></A>
  +<P>
   Here is the updated code fragment which employs this optimization:
  +
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
   
  -<P><A NAME="anchor871"></A>
  -<PRE>  # ...
  +	<td>
  +	  <pre>  # ...
     my $dbh = DBI-&gt;connect('dbi:Oracle:host', 'user', 'pass')
           || die $DBI::errstr;
     
  @@ -5262,12 +9068,16 @@
     if ($@) {
           $dbh-&gt;rollback;
     }
  -  # ...
  -</PRE>
  -<P><A NAME="anchor872"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +  # ...</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H3><A NAME="Eliminating_SQL_Statement_Parsin">Eliminating SQL Statement Parsing</A></H3></CENTER>
  -<P><A NAME="anchor873"></A>
  +<P>
   The example program has certainly come a long way and the performance is
   now probably much better than that of the first revision. However, there is
   still more speed that can be wrung out of this server architecture. The
  @@ -5277,7 +9087,7 @@
   statement. These things take time, and by eliminating these steps the time
   can be saved.
   
  -<P><A NAME="anchor874"></A>
  +<P>
   To get rid of the statement handle construction and statement parsing
   penalties, we could use <CODE>DBI</CODE>'s <CODE>prepare_cached()</CODE> method. This method compares the SQL
   statement to others that have already been executed. If there is a match,
  @@ -5290,7 +9100,7 @@
   immediately after the connection to the database is made, and they will be
   cached in package scalars to eliminate the method call.
   
  -<P><A NAME="anchor875"></A>
  +<P>
   What is needed is a routine that will connect to the database and prepare
   the statements. Since the statements are dependent upon the connection, the
   integrity of the connection needs to be checked before using the
  @@ -5299,14 +9109,23 @@
   <CODE>Apache::DBI</CODE> does, it does not use <CODE>Apache::DBI</CODE> and therefore has the added benefit of eliminating a cache lookup on the
   connection.
   
  -<P><A NAME="anchor876"></A>
  +<P>
   Here is an example of such a package:
  +
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
   
  -<P><A NAME="anchor877"></A>
  -<PRE>  package My::DB;
  +	<td>
  +	  <pre>  package My::DB;
     
     use strict;
  -  use DBI;
  +  use DBI ();
     
     sub connect {
           if (defined $My::DB::conn) {
  @@ -5343,13 +9162,25 @@
           return $My::DB::conn;
     }
     
  -  1;
  -</PRE>
  -<P><A NAME="anchor878"></A>
  +  1;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Now the example program needs to be modified to use this package.
   
  -<P><A NAME="anchor879"></A>
  -<PRE>  # ...
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  # ...
     my $dbh = My::DB-&gt;connect;
     
     my $baz = $r-&gt;param('baz');
  @@ -5372,206 +9203,434 @@
     if ($@) {
           $dbh-&gt;rollback;
     }
  -  # ...
  -</PRE>
  -<P><A NAME="anchor880"></A>
  +  # ...</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Notice that several improvements have been made. Since the statement
   handles have a longer life than the request, there is no need for each
   request to prepare the statement, and no need to call the statement
   handle's finish method. Since <CODE>Apache::DBI</CODE> and the <CODE>prepare_cached()</CODE> method are not used, no cache lookups
   are needed.
   
  -<P><A NAME="anchor881"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H3><A NAME="Conclusion">Conclusion</A></H3></CENTER>
  -<P><A NAME="anchor882"></A>
  +<P>
   The number of steps needed to service the request in the example system has
   been reduced significantly. In addition, the hidden cost of building and
   tearing down statement handles and of creating query execution plans is
   removed. Compare the new sequence with the original:
   
  -<P><A NAME="anchor883"></A>
  -<PRE> 1: Check connection to database
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre> 1: Check connection to database
    2: Bind parameter to SQL SELECT statement
    3: Execute SELECT statement
    4: Fetch rows
    5: Bind parameters to PL/SQL stored procedure
    6: Execute PL/SQL stored procedure
  - 7: Commit or rollback
  -</PRE>
  -<P><A NAME="anchor884"></A>
  + 7: Commit or rollback</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   It is probably possible to optimize this example even further, but I have
   not tried. It is very likely that the time could be better spent improving
   your database indexing scheme or web server buffering and load balancing.
   
  -<P><A NAME="anchor885"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H1><A NAME="Using_3rd_Party_Applications">Using 3rd Party Applications</A></H1></CENTER>
  -<P><A NAME="anchor886"></A>
  +<P>
   It's been said that no one can do everything well, but one can do something
   specific extremely well. This seems to be true for many software
   applications, when you don't try to do everything but instead concentrate
   on something specific you can do it really well.
   
  -<P><A NAME="anchor887"></A>
  +<P>
   Based on the above introduction, while the mod_perl server can do many many
   things, there are other applications (or Apache server modules) that can do
   some specific operations faster or do a really great job for the mod_perl
   server by unloading it when doing some operations by themselves.
   
  -<P><A NAME="anchor888"></A>
  +<P>
   Let's take a look at a few of these.
   
  -<P><A NAME="anchor889"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="Proxying_the_mod_perl_Server">Proxying the mod_perl Server</A></H2></CENTER>
  -<P><A NAME="anchor890"></A>
  +<P>
   Proxy gives you a great performance increase in most cases. It's discussed
   in the section <A HREF="././strategy.html#Adding_a_Proxy_Server_in_http_Ac">Adding a Proxy Server in http Accelerator Mode</A>.
   
  -<P><A NAME="anchor891"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="Upload_Download_of_Big_Files">Upload/Download of Big Files</A></H2></CENTER>
  -<P><A NAME="anchor892"></A>
  +<P>
   You don't want to tie up your precious mod_perl backend server children
   doing something as long and dumb as transfering a file. The user won't
   really see any important performance benefits from mod_perl anyway, since
   the upload may take up to several minutes, and the overhead saved by
   mod_perl is typically under one second.
   
  -<P><A NAME="anchor893"></A>
  +<P>
   If some particular script's main functionality is the uploading or
   downloading of big files, you probably want it to be executed on a plain
   apache server under mod_cgi.
   
  -<P><A NAME="anchor894"></A>
  +<P>
   This of course assumes that the script requires none of the functionality
   of the mod_perl server, such as custom authentication handlers.
  +
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
  +<CENTER><H1><A NAME="Apache_mod_perl_Build_Options">Apache/mod_perl Build Options</A></H1></CENTER>
  +<P>
  +It's important how you build mod_perl enabled Apache. It influences the
  +size of the httpd executable, some irrelevant modules might slow the
  +performance.
   
  -<P><A NAME="anchor895"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ReaderMETA: Any other building time things that influence performance?]
  +
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
  +<CENTER><H2><A NAME="mod_perl_Process_Size_as_a_Funct">mod_perl Process Size as a Function of Compiled in C Modules and mod_perl Features</A></H2></CENTER>
  +<P>
  +You might wonder whether it's better to compile in only the required
  +modules and mod_perl hooks, or it doesn't really matter. To answer on this
  +question lets first make a few compilation and compare the results.
  +
  +<P>
  +So we are going to build mod_perl starting with:
  +
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  % perl Makefile.PL APACHE_SRC=../apache_x.x.x/src \
  +         DO_HTTPD=1 USE_APACI=1</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +and followed by one of these option groups:
  +
  +<OL>
  +<P><LI><STRONG><A NAME="item_Default">Default</A></STRONG>
  +<P>
  +<EM>no arguments</EM>
  +
  +
  +
  +<P><LI><STRONG><A NAME="item_Minumum">Minumum</A></STRONG>
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  APACI_ARGS='--disable-module=env, \
  +              --disable-module=negotiation, \
  +              --disable-module=status, \
  +              --disable-module=info, \
  +              --disable-module=include, \
  +              --disable-module=autoindex, \
  +              --disable-module=dir, \
  +              --disable-module=cgi, \
  +              --disable-module=asis, \
  +              --disable-module=imap, \
  +              --disable-module=userdir, \
  +              --disable-module=access, \
  +              --disable-module=auth'</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P><LI><STRONG><A NAME="item_Everything">Everything</A></STRONG>
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  EVERYTHING=1</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P><LI><STRONG><A NAME="item_Everything_Debug">Everything + Debug</A></STRONG>
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  EVERYTHING=1 PERL_DEBUG=1</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    </OL>
  +<P>
  +After re-compiling with arguments of each of these groups, we can summarize
  +the results:
  +
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  Build group    httpd size (bytes)  Difference
  +  ---------------------------------------------
  +  Minumum              892928         +     0
  +  Default              994316         +101388
  +  Everything          1044432         +151504
  +  Everything+Debug    1162100         +269172</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +Indeed when you strip most of the default things, the server size is
  +slimmer. But the savings are insignificant since you don't muliply the
  +added size by the number of child processes if your OS supports sharing
  +memory. The parent processes is a little bigger, but it shares these memory
  +pages with its child processes. Of course not everything will be shared, if
  +some module you add does some process memory modification particular to the
  +process, but the most will.
  +
  +<P>
  +And of course this was just an example to show the difference is size. It
  +doesn't mean that you can everything away, since there will be Apache
  +modules and mod_perl options that you won't be able to work without.
  +
  +<P>
  +But as a good system administrator's rule says: <EM>"Run the absolute
  +minimum of the applications. If you don't know or need something,
  +disable it"</EM>. Following this rule to decide on the required Apache components and
  +disabling the unneeded default components, makes you a good Apache
  +administrator.
  +
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H1><A NAME="Perl_Build_Options">Perl Build Options</A></H1></CENTER>
  -<P><A NAME="anchor896"></A>
  -The perl interpreter lays in the brain of the mod_perl server and if we can
  +<P>
  +The Perl interpreter lays in the brain of the mod_perl server and if we can
   optimize perl into doing things faster under mod_perl we make the whole
  -server faster. Generally, optimizing the perl interpreter means enabling or
  +server faster. Generally, optimizing the Perl interpreter means enabling or
   disabling some command line options. Let's see a few important ones.
   
  -<P><A NAME="anchor897"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="_DTWO_POT_OPTIMIZE_and_DPACK_MA">-DTWO_POT_OPTIMIZE and -DPACK_MALLOC Perl Build Options</A></H2></CENTER>
  -<P><A NAME="anchor898"></A>
  +<P>
   Newer Perl versions also have build time options to reduce runtime memory
   consumption. These options might shrink the size of your httpd by about
   150k -- quite a big number if you remember to multiply it by the number of
   chidren you use.
   
  -<P><A NAME="anchor899"></A>
  +<P>
   The <CODE>-DTWO_POT_OPTIMIZE</CODE> macro improves allocations of data with size close to a power of two; but
   this works for big allocations (starting with 16K by default). Such
   allocations are typical for big hashes and special-purpose scripts,
   especially image processing.
   
  -<P><A NAME="anchor900"></A>
  +<P>
   Perl memory allocation is by bucket with sizes close to powers of two.
   Because of these the <CODE>malloc()</CODE> overhead may be big, especially
   for data of size exactly a power of two. If <CODE>PACK_MALLOC</CODE> is defined, perl uses a slightly different algorithm for small allocations
   (up to 64 bytes long), which makes it possible to have overhead down to 1
   byte for allocations which are powers of two (and appear quite often).
   
  -<P><A NAME="anchor901"></A>
  +<P>
   Expected memory savings (with 8-byte alignment in <CODE>alignbytes</CODE>) is about 20% for typical Perl usage. Expected slowdown due to additional
   <CODE>malloc()</CODE> overhead is in fractions of a percent and hard to
   measure, because of the effect of saved memory on speed.
   
  -<P><A NAME="anchor902"></A>
  +<P>
   You will find these and other memory improvement details in
   <CODE>perl5004delta.pod</CODE>.
   
  -<P><A NAME="anchor903"></A>
  +<P>
   Important: both options are On by default in perl versions 5.005 and
   higher.
   
  -<P><A NAME="anchor904"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="_Dusemymalloc_Perl_Build_Option">-Dusemymalloc Perl Build Option</A></H2></CENTER>
  -<P><A NAME="anchor905"></A>
  +<P>
   You have a choice to use the native or Perl's own <CODE>malloc()</CODE>
   implementation. The choice depends on your Operating System. Unless you
   know which of the two is better on yours, you better try both and compare
   the benchmarks.
   
  -<P><A NAME="anchor906"></A>
  +<P>
   To build without Perl's <CODE>malloc(),</CODE> you can use the Configure
   command:
   
  -<P><A NAME="anchor907"></A>
  -<PRE>  % sh Configure -Uusemymalloc&quot;
  -</PRE>
  -<P><A NAME="anchor908"></A>
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  % sh Configure -Uusemymalloc&quot;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Note that:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor909"></A>
  -<PRE>  -U == undefine usemymalloc (use system malloc)
  -  -D == define   usemymalloc (use Perl's malloc)
  -</PRE>
  -<P><A NAME="anchor910"></A>
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  -U == undefine usemymalloc (use system malloc)
  +  -D == define   usemymalloc (use Perl's malloc)</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   It seems that Linux still defaults to system malloc so you might want to
   configure Perl with -Dusemymalloc. Perl's malloc is not much of a win under
   linux, but makes a <STRONG>huge</STRONG> difference under Solaris.
   
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -	     The <a href="http://www.modperl.com/">
  -	     <B>Writing Apache Modules with Perl and C</B></a>
  -	     book can be purchased online from <a
  -	     href="http://www.ora.com/catalog/wrapmod/">O'Reilly </a>
  -	     and <a
  -	     href="http://www.amazon.com/exec/obidos/ASIN/156592567X/writinapachemodu">
  -	     Amazon.com</a>.
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   
  -	     <HR>
   
  -	     <B>Your corrections of either technical or grammatical
  +    <p>
  +    <div class="navbar">
  +      <a href="porting.html">Prev</a>                                 |
  +      <A HREF="index.html"         >Contents</A> |
  +      <A HREF="index.html#search"  >Search</A>   |
  +      <A HREF="index.html#download">Download</A> |
  +      <a href="frequent.html">Next</a>
  +    </div>
  +    <p>
  +
  +    <table width="60%" align="center">
  +
  +      <tr>
  +	<td>
  +	  <div class="notice">
  +	  <B>Your corrections of the technical and grammatical
   	     errors are very welcome. You are encouraged to help me
  -	     to improve this guide.  If you have something to
  -	     contribute please <A
  -	     HREF="help.html#Contacting_me"> send it
  +	     improve this guide.  If you have something to contribute
  +	     please <A HREF="help.html#Contacting_me"> send it
   	     directly to me</A>.</B>
  +	  </div>
  +	</td>
  +      </tr>
  +
  +      <tr>
  +	<td>
  +	  <div class="ad">
  +	    The <a href="http://www.modperl.com/">
  +	      <B>Writing Apache Modules with Perl and C</B></a>
  +	    book can be purchased online from <a
  +	      href="http://www.ora.com/catalog/wrapmod/">O'Reilly </a>
  +	    and <a
  +	    href="http://www.amazon.com/exec/obidos/ASIN/156592567X/writinapachemodu">
  +	      Amazon.com</a>.
  +	  </div>
  +	</td>
  +      </tr>
  +
  +</table>
  +
  +<center>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
  +<table cellspacing=2 cellpadding=2>
  +
  +<tr align=center valign=top>
  +<td align=center valign=center>
  +
  +<b><font size=-1>Written by <a
  +href="help.html#Contacting_me">Stas Bekman</a>.<br> Last Modified at 06/07/2000
  +</font></b>
  +<br>
  +
  +</td>
  +
  +<td>
  +
  +<a href="http://perl.apache.org"><img src="images/mod_perl2.jpg"  border=0 alt="mod_perl icon" border=0 height=59 width=150></a>
  +<br>
  +
  +</td>
  +
  +<td>
  +
  +<font size=-2>Use of the Camel for Perl is <br>
  +a trademark of <a href="http://www.ora.com">O'Reilly &amp; Associates</a>,<br>
  +and is used by permission. </font> 
  +<br>
   
  -	     <HR>
  +</td>
   
  -	     [    <A HREF="porting.html">Prev</A> |      <A HREF="index.html">Main Page</A> | <A HREF="frequent.html">Next</A>      ]
  +</tr>
  +</table>
  +</center>
   
  -<CENTER><TABLE CELLSPACING=2 CELLPADDING=2 WIDTH="100%" >
  -<TR ALIGN=CENTER VALIGN=TOP>
  -  <TD ALIGN=CENTER VALIGN=CENTER COLSPAN="3">
  -	     <HR>
  -  </TD>
  -</TR>
  -<TR ALIGN=CENTER VALIGN=TOP>
  -  <TD ALIGN=CENTER VALIGN=CENTER>
  -    <B>
  -      <FONT SIZE=-1>
  -	     Written by <A HREF="help.html#Contacting_me">Stas Bekman</A>.
  -	     <BR>Last Modified at 05/12/2000
  -      </FONT>
  -    </B>
  -  </TD>
  -
  -  <TD>
  -	     <A HREF="http://perl.apache.org"><IMG SRC="images/mod_perl2.jpg" ALT="Mod Perl Icon" BORDER=0 HEIGHT=59 WIDTH=150></A>
  -  </TD>
  -
  -  <TD>
  -    <FONT SIZE=-2>
  -	     Use of the Camel for Perl is <BR>
  -	     a trademark of <A HREF="http://www.ora.com">O'Reilly &amp; Associates</A>,<BR>
  -             and is used by permission. 
  -    </FONT> 
  -  </TD>
  -</TR>
  -</TABLE></CENTER>
  -
  -</BODY>
  -</HTML>
  -	    
  \ No newline at end of file
  +</body>
  +</html>
  
  
  
  1.13      +2716 -1030modperl-site/guide/perl.html
  
  Index: perl.html
  ===================================================================
  RCS file: /home/cvs/modperl-site/guide/perl.html,v
  retrieving revision 1.12
  retrieving revision 1.13
  diff -u -r1.12 -r1.13
  --- perl.html	2000/05/12 22:42:54	1.12
  +++ perl.html	2000/06/07 22:45:36	1.13
  @@ -1,29 +1,37 @@
   <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
  -<HTML>
  -<HEAD>
  -   <TITLE>mod_perl guide: Perl Reference</TITLE>
  -   <META NAME="GENERATOR" CONTENT="Pod2HTML [Perl/Linux]">
  -   <META NAME="Author" CONTENT="Stas Bekman">
  -   <META NAME="Description" CONTENT="All Apache/Perl related information: Hints, Guidelines, Scenarios and Troubleshottings">
  -   <META NAME="keywords" CONTENT="mod_perl modperl perl apache cgi webserver speed  fast guide mod_perl apache guide help info faq mod_perl installation cgi troubleshooting help no sex speedup free open source OSS mod_perl apache guide">
  -</HEAD>
  -     <LINK REL=STYLESHEET TYPE="text/css"
  -        HREF="style.css" TITLE="refstyle">
  -     <style type="text/css">
  -     <!-- 
  -        @import url(style.css);
  -     -->
  -     
  -     </style>
  -<BODY BGCOLOR="white">
  +<html>
  +  <head>
  +   <title>mod_perl guide: Perl Reference</title>
  +   <meta name="Author" content="Stas Bekman">
  +   <meta name="Description" content="All Apache/Perl related information: Hints, Guidelines, Scenarios and Troubleshottings">
  +   <meta name="keywords" content="mod_perl modperl perl cgi apache webserver speed fast guide mod_perl apache guide help info faq mod_perl installation cgi troubleshooting help no sex speedup free open source OSS mod_perl apache guide">
  +   <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
  +   <meta name="Classification" content="information">
  +   <link href="style.css" rel=stylesheet type="text/css" title="refstyle">
  +  </head>
  +  <body>
  +
  +    <h1 align=center>
  +      <a href="http://perl.apache.org"><img src="images/mod_perl.gif" alt="Mod Perl Icon" border=0 height=30 width=90 align=left></a>
  +      <a href="http://perl.apache.org"><img src="images/mod_perl.gif" alt="Mod Perl Icon" border=0 height=30 width=90 align=right></a>
  +      Perl Reference
  +    </h1>
  +    <hr>
  +    <p>
  +    <div class="navbar">
  +      <a href="start.html">Prev</a>                                 |
  +      <a href="index.html"         >Contents</a> |
  +      <a href="index.html#search"  >Search</a>   |
  +      <a href="index.html#download">Download</a> |
  +      <a href="install.html">Next</a>
  +    </div>
  +    <p>
  +
  +    <div class="toc">
  +      
   <A NAME="toc"></A>
  -<H1 ALIGN=CENTER>
  -<A HREF="http://perl.apache.org"><IMG SRC="images/mod_perl.gif" ALT="Mod Perl Icon" BORDER=0 HEIGHT=30 WIDTH=90 ALIGN=LEFT></A>
  -<A HREF="http://perl.apache.org"><IMG SRC="images/mod_perl.gif" ALT="Mod Perl Icon" BORDER=0 HEIGHT=30 WIDTH=90 ALIGN=RIGHT></A>
  -Perl Reference</H1>
  -<HR WIDTH="100%">
  -	    [    <A HREF="start.html">Prev</A> |      <A HREF="index.html">Main Page</A> | <A HREF="install.html">Next</A>      ]<HR><!-- INDEX BEGIN -->
  -<P><B><FONT SIZE=-1>Table of Contents:</FONT></B></P>
  +<P><B>Table of Contents:</B></P>
  +
   <UL>
   
   	<LI><A HREF="#A_Must_Read_">A Must Read!</A>
  @@ -60,7 +68,7 @@
   
   		<LI><A HREF="#The_INC_array">The @INC array</A>
   		<LI><A HREF="#The_INC_hash">The %INC hash</A>
  -		<LI><A HREF="#Modules_Libraries_and_Files">Modules, Libraries and Files</A>
  +		<LI><A HREF="#Modules_Libraries_and_Program_F">Modules, Libraries and Program Files</A>
   		<LI><A HREF="#require_">require()</A>
   		<LI><A HREF="#use_">use()</A>
   		<LI><A HREF="#do_">do()</A>
  @@ -97,122 +105,213 @@
   		</UL>
   
   		<LI><A HREF="#Some_Uses">Some Uses</A>
  +		<LI><A HREF="#A_Warning">A Warning</A>
   		<LI><A HREF="#Conclusions">Conclusions</A>
   		<LI><A HREF="#The_My_Exception_class_in_its_e">The My::Exception class in its entirety</A>
   		<LI><A HREF="#Other_Implementations">Other Implementations</A>
   	</UL>
   
   </UL>
  -<!-- INDEX END -->
   
  +    </div>
  +
  +    [ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
   <HR>
  +    <table width="60%" align="center">
  +
  +      <tr>
  +	<td>
  +	  <div class="ad">
  +	    The <a href="http://www.modperl.com/">
  +	      <B>Writing Apache Modules with Perl and C</B></a>
  +	    book can be purchased online from <a
  +	      href="http://www.ora.com/catalog/wrapmod/">O'Reilly </a>
  +	    and <a
  +	    href="http://www.amazon.com/exec/obidos/ASIN/156592567X/writinapachemodu">
  +	      Amazon.com</a>.
  +	  </div>
  +	</td>
  +      </tr>
  +
  +      <tr>
  +	<td>
  +	  <div class="notice">
  +	  <B>Your corrections of the technical and grammatical
  +	     errors are very welcome. You are encouraged to help me
  +	     improve this guide.  If you have something to contribute
  +	     please <A HREF="help.html#Contacting_me"> send it
  +	     directly to me</A>.</B>
  +	  </div>
  +	</td>
  +      </tr>
   
  -	     The <a href="http://www.modperl.com/">
  -	     <B>Writing Apache Modules with Perl and C</B></a>
  -	     book can be purchased online from <a
  -	     href="http://www.ora.com/catalog/wrapmod/">O'Reilly </a>
  -	     and <a
  -	     href="http://www.amazon.com/exec/obidos/ASIN/156592567X/writinapachemodu">
  -	     Amazon.com</a>.
  -
  -	     <HR>
  -
  -	       <B>Your corrections of either technical or grammatical
  -	       errors are very welcome. You are encouraged to help me
  -	       to improve this guide.  If you have something to
  -	       contribute please <A
  -	       HREF="help.html#Contacting_me"> send it
  -	       directly to me</A>.
  -	       </B>
  -	       <HR>
  +</table>
   
  -	      <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<P><A NAME="anchor0"></A>
  +    
  +
  +	    [ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
  +
  +<P>
   <CENTER><H1><A NAME="A_Must_Read_">A Must Read!</A></H1></CENTER>
  -<P><A NAME="anchor1"></A>
  +<P>
   This document was born because some users are reluctant to learn Perl,
   prior to jumping into mod_perl. I will try to cover some of the most
   frequent pure Perl questions being asked at the list.
   
  -<P><A NAME="anchor2"></A>
  +<P>
   Update: I'm moving most of the pure Perl related topics from everywhere in
   the Guide to this chapter. From now on other chapters will refer to
   sections in this chapter if required.
   
  -<P><A NAME="anchor3"></A>
  +<P>
   Before you decide to skip this chapter make sure you know all the
   information provided here. The rest of the Guide assumes that you have read
   this chapter and understood it.
   
  -<P><A NAME="anchor4"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H1><A NAME="perldoc_s_Rarely_Known_But_Very_">perldoc's Rarely Known But Very Useful Options</A></H1></CENTER>
  -<P><A NAME="anchor5"></A>
  +<P>
   First of all, I want to stress that you cannot become a Perl hacker without
   knowing how to read Perl documentation and search through it. Books are
  -good, but an easily accessible and searchable Perl reference is at your
  -fingertips and is a great time saver.
  +good, but an easily accessible and searchable Perl reference at your
  +fingertips is a great time saver. It always has the up-to-date information
  +for the version of perl you're using.
   
  -<P><A NAME="anchor6"></A>
  +<P>
   While you can use online Perl documentation at the Web, the <CODE>perldoc</CODE>
   utility provides you with access to the documentation installed on your
   system. To find out what Perl manpages are available execute:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor7"></A>
  -<PRE>  % perldoc perl
  -</PRE>
  -<P><A NAME="anchor8"></A>
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  % perldoc perl</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   To find what functions perl has, execute:
   
  -<P><A NAME="anchor9"></A>
  -<PRE>  % perldoc perlfunc
  -</PRE>
  -<P><A NAME="anchor10"></A>
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  % perldoc perlfunc</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   To learn the syntax and to find examples of a specific function, you would
   execute (e.g. for <CODE>open()</CODE>):
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor11"></A>
  -<PRE>  % perldoc -f open
  -</PRE>
  -<P><A NAME="anchor12"></A>
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  % perldoc -f open</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Note: In perl5.005_03 and earlier, there is a bug in this and the <CODE>-q</CODE> 
   options of <CODE>perldoc</CODE>. It won't call <CODE>pod2man</CODE>, but will display the section in POD format instead. Despite this bug it's
  -still readable and very useful.
  +still readable and very useful. 
   
  -<P><A NAME="anchor13"></A>
  +<P>
   The Perl FAQ (<EM>perlfaq</EM> manpage) is in several sections. To search through the sections for <CODE>open</CODE> you would execute:
   
  -<P><A NAME="anchor14"></A>
  -<PRE>  % perldoc -q open
  -</PRE>
  -<P><A NAME="anchor15"></A>
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  % perldoc -q open</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   This will show you all the matching Question and Answer sections, still in
   POD format.
   
  -<P><A NAME="anchor16"></A>
  +<P>
   To read the <EM>perldoc</EM> manpage you would execute:
  +
  +<P>
   
  -<P><A NAME="anchor17"></A>
  -<PRE>  % perldoc perldoc
  -</PRE>
  -<P><A NAME="anchor18"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  % perldoc perldoc</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H1><A NAME="Tracing_Warnings_Reports">Tracing Warnings Reports</A></H1></CENTER>
  -<P><A NAME="anchor19"></A>
  +<P>
   Sometimes it's very hard to understand what a warning is complaining about.
   You see the source code, but you cannot understand why some specific
   snippet produces that warning. The mystery often results from the fact that
   the code can be called from different places if it's located inside a
   subroutine.
   
  -<P><A NAME="anchor20"></A>
  +<P>
   Here is an example:
  +
  +<P>
   
  -<P><A NAME="anchor21"></A>
  -<PRE>  warnings.pl
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  warnings.pl
     -----------
     #!/usr/bin/perl -w
     
  +  use strict;
  +  
     correct();
     incorrect();
     
  @@ -227,45 +326,93 @@
     sub print_value{
       my $var = shift;
       print &quot;My value is $var\n&quot;;
  -  }
  -</PRE>
  -<P><A NAME="anchor22"></A>
  +  }</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   In the code above, <CODE>print_value()</CODE> prints the passed value.
   Subroutine <CODE>correct()</CODE> passes the value to print, but in
   subroutine <CODE>incorrect()</CODE> we forgot to pass it. When we run the
   script:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor23"></A>
  -<PRE>  % ./warnings.pl
  -</PRE>
  -<P><A NAME="anchor24"></A>
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  % ./warnings.pl</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   we get the warning:
   
  -<P><A NAME="anchor25"></A>
  -<PRE>  Use of uninitialized value at ./warnings.pl line 16.
  -</PRE>
  -<P><A NAME="anchor26"></A>
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  Use of uninitialized value at ./warnings.pl line 16.</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Perl complains about an undefined variable <CODE>$var</CODE> at the line that attempts to print its value:
  +
  +<P>
   
  -<P><A NAME="anchor27"></A>
  -<PRE>  print &quot;My value is $var\n&quot;;
  -</PRE>
  -<P><A NAME="anchor28"></A>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  print &quot;My value is $var\n&quot;;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   But how do we know why it is undefined? The reason here obviously is that
   the calling function didn't pass the argument. But how do we know who was
   the caller? In our example there are two possible callers, in the general
   case there can be many of them, perhaps located in other files.
   
  -<P><A NAME="anchor29"></A>
  +<P>
   We can use the <CODE>caller()</CODE> function, which tells who has called
   us, but even that might not be enough: it's possible to have a longer
   sequence of called subroutines, and not just two. For example, here it is
   sub <CODE>third()</CODE> which is at fault, and putting sub
   <CODE>caller()</CODE> in sub <CODE>second()</CODE> would not help us very
   much:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor30"></A>
  -<PRE>  sub third{
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  sub third{
       second();
     }
     sub second{
  @@ -275,22 +422,35 @@
     sub first{
       my $var = shift;
      print &quot;Var = $var\n&quot;
  -  }
  -</PRE>
  -<P><A NAME="anchor31"></A>
  +  }</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   The solution is quite simple. What we need is a full calls stack trace to
   the call that triggered the warning.
   
  -<P><A NAME="anchor32"></A>
  +<P>
   The <CODE>Carp</CODE> module comes to our aid with its <CODE>cluck()</CODE> function. Let's
   modify the script by adding a couple of lines. The rest of the script is
   unchanged.
  +
  +<P>
   
  -<P><A NAME="anchor33"></A>
  -<PRE>  warnings2.pl
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  warnings2.pl
     -----------
     #!/usr/bin/perl -w
     
  +  use strict;
     use Carp ();
     local $SIG{__WARN__} = \&amp;Carp::cluck;
     
  @@ -308,34 +468,61 @@
     sub print_value{
       my $var = shift;
       print &quot;My value is $var\n&quot;;
  -  }
  -</PRE>
  -<P><A NAME="anchor34"></A>
  +  }</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Now when we execute it, we see:
  +
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
   
  -<P><A NAME="anchor35"></A>
  -<PRE>  Use of uninitialized value at ./warnings2.pl line 19.
  +	<td>
  +	  <pre>  Use of uninitialized value at ./warnings2.pl line 19.
       main::print_value() called at ./warnings2.pl line 14
  -    main::incorrect() called at ./warnings2.pl line 7
  -</PRE>
  -<P><A NAME="anchor36"></A>
  +    main::incorrect() called at ./warnings2.pl line 7</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Take a moment to understand the calls stack trace. The deepest calls are
   printed first. So the second line tells us that the warning was triggered
   in <CODE>print_value();</CODE> the third, that <CODE>print_value()</CODE>
  -was called by <CODE>incorrect()</CODE> subroutine.
  +was called by subroutine, <CODE>incorrect().</CODE>
   
  -<P><A NAME="anchor37"></A>
  -<PRE>  script =&gt; incorrect() =&gt; print_value()
  -</PRE>
  -<P><A NAME="anchor38"></A>
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  script =&gt; incorrect() =&gt; print_value()</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   We go into <CODE>incorrect()</CODE> and indeed see that we forgot to pass the variable. Of course when you
   write a subroutine like <CODE>print_value</CODE> it would be a good idea to check the passed arguments before starting
   execution. We omitted that step to contrive an easily debugged example.
   
  -<P><A NAME="anchor39"></A>
  +<P>
   Sure, you say, I could find that problem by simple inspection of the code! 
   
  -<P><A NAME="anchor40"></A>
  +<P>
   Well, you're right. But I promise you that your task would be quite
   complicated and time consuming if your code has some thousands of lines. In
   addition, under mod_perl, certain uses of the <CODE>eval</CODE>
  @@ -343,137 +530,187 @@
   numbering, so the messages reporting warnings and errors can have incorrect
   line numbers. (See <A HREF="././debug.html#Finding_the_Line_Which_Triggered">Finding the Line Which Triggered the Error or Warning</A> for more information).
   
  -<P><A NAME="anchor41"></A>
  +<P>
   Getting the trace helps a lot.
   
  -<P><A NAME="anchor42"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H1><A NAME="Variables_Globally_Lexically_Sc">Variables Globally, Lexically Scoped And Fully Qualified</A></H1></CENTER>
  -<P><A NAME="anchor43"></A>
  +<P>
   META: this material is new and requires polishing so read with care.
   
  -<P><A NAME="anchor44"></A>
  +<P>
   You will hear a lot about namespaces, symbol tables and lexical scoping in
   Perl discussions, but little of it will make any sense without a few key
   facts:
   
  -<P><A NAME="anchor45"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="Symbols_Symbol_Tables_and_Packa">Symbols, Symbol Tables and Packages; Typeglobs</A></H2></CENTER>
  -<P><A NAME="anchor46"></A>
  -There are two important types of symbol: global and lexical. We will talk
  -about lexical symbols later, for now we will talk only about global
  -symbols.
  +<P>
  +There are two important types of symbol: package global and lexical. We
  +will talk about lexical symbols later, for now we will talk only about
  +package global symbols, which we will refer to simply as
  +<EM>global symbols</EM>.
   
  -<P><A NAME="anchor47"></A>
  +<P>
   The names of pieces of your code (subroutine names) and the names of your
   global variables are symbols. Global symbols reside in one symbol table or
  -another. The code itself and the data do not, the symbols are the names of
  +another. The code itself and the data do not; the symbols are the names of
   pointers which point (indirectly) to the memory areas which contain the
  -code and data.
  -
  -<P><A NAME="anchor48"></A>
  -There is one symbol table for each package.
  +code and data. (Note for C/C++ programmers: we use the term `pointer' in a
  +general sense of one piece of data referring to another piece of data not
  +in a specific sense as used in C or C++.)
  +
  +<P>
  +There is one symbol table for each package, (which is why <EM>global
  +symbols</EM> are really <EM>package global symbols</EM>).
   
  -<P><A NAME="anchor49"></A>
  +<P>
   You are always working in one package or another.
   
  -<P><A NAME="anchor50"></A>
  +<P>
   Like in C, where the first function you write must be called
   <CODE>main(),</CODE> the first statement of your first Perl script is in
   package <CODE>main::</CODE>
   which is the default package. Unless you say otherwise by using the
  -<CODE>package</CODE> statement, your symbols are all in package <CODE>main::</CODE>. The ideas of files and scripts really have nothing at all to do with
  -packages, you can have many packages in a single file but usually you
  -don't. Usually for convenience you have one file per package. All package
  -names end with the semi-colon. This is probably starting to sound familiar
  -to you.
  -
  -<P><A NAME="anchor51"></A>
  -When you create a symbol (variable, subroutine etc.) Perl uses the name of
  -the package in which you are currently working as a prefix to create the
  -fully qualified name of the symbol.
  -
  -<P><A NAME="anchor52"></A>
  -When you create a symbol, Perl gives you one each of scalar, array, hash,
  -subroutine (code), filehandle and format which all have the same name --
  -although you did not ask it to do that. This collection of pointers is
  -called a `typeglob' and it is very important in Perl. The items are
  -pointers, so you see now that there are two indirections for a global
  -variable: the symbol points to the typeglob and the typeglob points to the
  -data. The items in the typeglob are completely separate pointers which are
  -independent of each other. They just have the same name. Most of the time,
  -only one of them is used (yes, it's a bit wasteful). You will by now know
  -that you distinguish between them by using what the authors of the Camel
  -book call a <EM>funny character</EM>
  -which for a hash, say, is the percent sign. 
  -
  -<P><A NAME="anchor53"></A>
  -Global symbols can be referred to in one of two ways, either by the
  -abbreviated name (which is usually the name you gave when you created the
  -symbol, and which does not contain the package name) or the fully-
  -qualified name (which begins with the package name).
  -
  -<P><A NAME="anchor54"></A>
  -When you refer to a variable, if you do not give the package name then the
  -current package is assumed. This means that to refer to a variable in a
  -package other than the current one you must give the fully-qualified name.
  -It also means that most of the time you do not need to use the fully
  -qualified symbol name because most of the time you will refer to package
  -variables from within the package. This is very like C++ class variables.
  -You can work entirely within package
  -<CODE>main::</CODE> and never even know you are using a package, nor that the symbols have
  +<CODE>package</CODE> statement, your symbols are all in package <CODE>main::</CODE>. You should be aware straight away that files and packages are <EM>not
  +related</EM>. You can have any number of packages in a single file; and a single
  +package can be in one file or spread over many files. However it is very
  +common to have a single package in a single file. To declare a package you
  +write:
  +
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>    package mypackagename;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +From the following line you are in package <CODE>mypackagename</CODE> and any symbols you declare reside in that package. When you create a
  +symbol (variable, subroutine etc.) Perl uses the name of the package in
  +which you are currently working as a prefix to create the fully qualified
  +name of the symbol.
  +
  +<P>
  +When you create a symbol, Perl creates a symbol table entry for that symbol
  +in the current package's symbol table (by default
  +<CODE>main::</CODE>). Each symbol table entry is called a <EM>typeglob</EM>. Each typeglob can hold information on a scalar, an array, a hash, a
  +subroutine (code), a filehandle, a directory handle and a format, each of
  +which all have the same name. So you see now that there are two
  +indirections for a global variable: the symbol, (the thing's name), points
  +to its typeglob and the typeglob for the thing's type (scalar, array, etc.)
  +points to the data. If we had a scalar and an array with the same name
  +their name would point to the same typeglob, but for each type of data the
  +typeglob points to somewhere different and so the scalar's data and the
  +array's data are completely separate and independent, they just happen to
  +have the same name.
  +
  +<P>
  +Most of the time, only one part of a typeglob is used (yes, it's a bit
  +wasteful). You will by now know that you distinguish between them by using
  +what the authors of the Camel book call a <EM>funny character</EM>. So if we have a scalar called `<CODE>line</CODE>' we would refer to it in code as
  +<CODE>$line</CODE>, and if we had an array of the same name, that would be written, <CODE>@line</CODE>. Both would point to the same typeglob (which would be called <CODE>*line</CODE>), but because of the <EM>funny character</EM> (also known as <EM>decoration</EM>) perl won't confuse the two. Of course we might confuse ourselves, so some
  +programmers don't ever use the same name for more than one type of
  +variable.
  +
  +<P>
  +Every global symbol is in some package's symbol table. To refer to a global
  +symbol we could write the <EM>fully qualified</EM> name, e.g. <CODE>$main::line</CODE>. If we are in the same package as the symbol we can omit the package name,
  +e.g.  <CODE>$line</CODE> (unless you use the &lt;strict&gt; pragma and then you will have to predeclare the variable using
  +the
  +<CODE>vars</CODE> pragma). We can also omit the package name if we have imported the symbol
  +into our current package's namespace. If we want to refer to a symbol that
  +is in another package and which we haven't imported we must use the fully
  +qualified name, e.g. <CODE>$otherpkg::box</CODE>.
  +
  +<P>
  +Most of the time you do not need to use the fully qualified symbol name
  +because most of the time you will refer to package variables from within
  +the package. This is very like C++ class variables. You can work entirely
  +within package <CODE>main::</CODE> and never even know you are using a package, nor that the symbols have
   package names. In a way, this is a pity because you may fail to learn about
   packages and they are extremely useful.
   
  -<P><A NAME="anchor55"></A>
  +<P>
   The exception is when you <EM>import</EM> the variable from another package. This creates an alias for the variable
   in the <EM>current</EM> package, so that you can access it without using the fully qualified name.
   
  -<P><A NAME="anchor56"></A>
  -When you create a variable, the low-level business of allocating memory to
  -store the information is handled automatically by Perl. The intepreter
  -keeps track of the chunks of memory to which the pointers are pointing and
  -takes care of undefying variables, but not freeing the memory when you
  -cease to use it - which as far as Perl is concerned means when you cease to
  -have any symbol which points to it.
  +<P>
  +Whilst global variables are useful for sharing data and are necessary in
  +some contexts it is usually wisest to minimise their use and use <EM>lexical
  +variables</EM>, discussed next, instead.
  +
  +<P>
  +Note that when you create a variable, the low-level business of allocating
  +memory to store the information is handled automatically by Perl. The
  +intepreter keeps track of the chunks of memory to which the pointers are
  +pointing and takes care of undefining variables. When all references to a
  +variable have ceased to exist then the perl garbage collector is free to
  +take back the memory used ready for recycling. However perl almost never
  +returns back memory it has already used to the operating system during the
  +lifetime of the process.
   
  -<P><A NAME="anchor57"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H3><A NAME="Lexical_Variables_and_Symbols">Lexical Variables and Symbols</A></H3></CENTER>
  -<P><A NAME="anchor58"></A>
  -The symbols for lexical variables (i.e. those declared using the keyword <CODE>my</CODE>) are the only symbols which do NOT live in a symbol table. Because of
  -this, they are not available from outside the package in which they are
  -used. There is no typeglob associated with a lexical variable and a lexical
  -variable can refer only to a scalar, an array or a hash. 
  +<P>
  +The symbols for lexical variables (i.e. those declared using the keyword <CODE>my</CODE>) are the only symbols which do <EM>not</EM> live in a symbol table. Because of this, they are not available from
  +outside the block in which they are declared. There is no typeglob
  +associated with a lexical variable and a lexical variable can refer only to
  +a scalar, an array or a hash.
   
  -<P><A NAME="anchor59"></A>
  +<P>
   META: is the above right?
   
  -<P><A NAME="anchor60"></A>
  +<P>
   If you need access to the data from outside the package then you can return
   it from a subroutine, or you can create a global variable (i.e. one which
   has a package prefix) which points or refers to it and return that. The
   pointer or reference must be global so that you can refer to it by a fully
   qualified name. But just like in C try to avoid having global variables.
  -Using OO methods generally solve this problem, by providing methods to get
  +Using OO methods generally solves this problem, by providing methods to get
   and set the desired value within the object that can be lexically scoped
   inside the package and passed by reference.
   
  -<P><A NAME="anchor61"></A>
  +<P>
   The phrase ``lexical variable'' is a bit of a misnomer, we are really
   talking about ``lexical symbols''. The data can be referenced by a global
  -symbol too, and when the lexical symbol goes out of scope the data will
  -still be accessible through the global symbol. This is perfectly legitimate
  -and cannot be compared to the terrible mistake of taking a pointer to an
  -automatic C variable and returning it from a function - when the pointer is
  -dereferenced there will be a segfault.
  +symbol too, and in such cases when the lexical symbol goes out of scope the
  +data will still be accessible through the global symbol. This is perfectly
  +legitimate and cannot be compared to the terrible mistake of taking a
  +pointer to an automatic C variable and returning it from a function--when
  +the pointer is dereferenced there will be a segmentation fault. (Note for
  +C/C++ programmers: having a function return a pointer to an auto variable
  +is a disaster in C or C++; the perl equivalent, returning a reference to a
  +lexical variable created in a function is normal and useful.)
   
  -<P><A NAME="anchor62"></A>
  +<P>
   Also see the clarification of <CODE>my()</CODE> vs. <CODE>use vars</CODE> - Ken Williams writes:
   
  -<P><A NAME="anchor63"></A>
  -<PRE>  Yes, there is quite a bit of difference!  With use vars(), you are
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  Yes, there is quite a bit of difference!  With use vars(), you are
     making an entry in the symbol table, and you are telling the
     compiler that you are going to be referencing that entry without an
     explicit package name.
  @@ -481,13 +718,25 @@
     With my(), NO ENTRY IS PUT IN THE SYMBOL TABLE.  The compiler
     figures out C&lt;at compile time&gt; which my() variables (i.e. lexical
     variables) are the same as each other, and once you hit execute time
  -  you cannot go looking those variables up in the symbol table.
  -</PRE>
  -<P><A NAME="anchor64"></A>
  +  you cannot go looking those variables up in the symbol table.</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   And <CODE>my()</CODE> vs. <CODE>local()</CODE> - Randal Schwartz writes:
  +
  +<P>
   
  -<P><A NAME="anchor65"></A>
  -<PRE>  local() creates a temporal-limited package-based scalar, array,
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  local() creates a temporal-limited package-based scalar, array,
     hash, or glob -- when the scope of definition is exited at runtime,
     the previous value (if any) is restored.  References to such a
     variable are *also* global... only the value changes.  (Aside: that
  @@ -496,33 +745,48 @@
     my() creates a lexically-limited non-package-based scalar, array, or
     hash -- when the scope of definition is exited at compile-time, the
     variable ceases to be accessible.  Any references to such a variable
  -  at runtime turn into unique anonymous variables on each scope exit.
  -</PRE>
  -<P><A NAME="anchor66"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +  at runtime turn into unique anonymous variables on each scope exit.</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="Additional_reading_references">Additional reading references</A></H2></CENTER>
  -<P><A NAME="anchor67"></A>
  +<P>
   For more information see: <A HREF="././perl.html#Using_Global_Variables_and_Shari">Using global variables and sharing them between modules/packages</A> and an article by Mark-Jason Dominus about how Perl handles variables and
  -name-spaces, and the difference between <CODE>use vars()</CODE> and <CODE>my()</CODE> - <A
  +namespaces, and the difference between <CODE>use vars()</CODE> and <CODE>my()</CODE> - <A
   HREF="http://www.plover.com/~mjd/perl/FAQs/Namespaces.html">http://www.plover.com/~mjd/perl/FAQs/Namespaces.html</A>
   .
   
  -<P><A NAME="anchor68"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H1><A NAME="my_Scoped_Variable_in_Nested_S">my() Scoped Variable in Nested Subroutines</A></H1></CENTER>
  -<P><A NAME="anchor69"></A>
  +<P>
   Before we proceed let's make the assumption that we want to develop the
   code under the <CODE>strict</CODE> pragma. We will use lexically scoped variables (with help of the
   <CODE>my()</CODE> operator) whenever it's possible.
   
  -<P><A NAME="anchor70"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="The_Poison">The Poison</A></H2></CENTER>
  -<P><A NAME="anchor71"></A>
  +<P>
   Let's look at this code:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor72"></A>
  -<PRE>  nested.pl
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  nested.pl
     -----------
     #!/usr/bin/perl
     
  @@ -540,86 +804,183 @@
     }
     
     print_power_of_2(5);
  -  print_power_of_2(6);
  -</PRE>
  -<P><A NAME="anchor73"></A>
  -Don't let the weird subroutine names to fool you, the
  +  print_power_of_2(6);</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +Don't let the weird subroutine names fool you, the
   <CODE>print_power_of_2()</CODE> subroutine should print the square of the
  -passed number. Let's run the code and see whether it works:
  +number passed to it. Let's run the code and see whether it works:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor74"></A>
  -<PRE>  % ./nested.pl
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  % ./nested.pl
     
     5^2 = 25
  -  6^2 = 25
  -</PRE>
  -<P><A NAME="anchor75"></A>
  +  6^2 = 25</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Ouch, something is wrong. May be there is a bug in Perl and it doesn't work
  -correctly with number 6? Let's try again using the 5 and 7:
  +correctly with the number 6? Let's try again using 5 and 7:
  +
  +<P>
   
  -<P><A NAME="anchor76"></A>
  -<PRE>  print_power_of_2(5);
  -  print_power_of_2(7);
  -</PRE>
  -<P><A NAME="anchor77"></A>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  print_power_of_2(5);
  +  print_power_of_2(7);</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   And run it:
  +
  +<P>
   
  -<P><A NAME="anchor78"></A>
  -<PRE>  % ./nested.pl
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  % ./nested.pl
     
     5^2 = 25
  -  7^2 = 25
  -</PRE>
  -<P><A NAME="anchor79"></A>
  +  7^2 = 25</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Wow, does it works only for 5? How about using 3 and 5:
   
  -<P><A NAME="anchor80"></A>
  -<PRE>  print_power_of_2(3);
  -  print_power_of_2(5);
  -</PRE>
  -<P><A NAME="anchor81"></A>
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  print_power_of_2(3);
  +  print_power_of_2(5);</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   and the result is:
  +
  +<P>
   
  -<P><A NAME="anchor82"></A>
  -<PRE>  % ./nested.pl
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  % ./nested.pl
     
     3^2 = 9
  -  5^2 = 9
  -</PRE>
  -<P><A NAME="anchor83"></A>
  +  5^2 = 9</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Now we start to understand--only the first call to the
   <CODE>print_power_of_2()</CODE> function works correctly. Which makes us
  -think that our code has some kind of memory for results of the first
  +think that our code has some kind of memory for the results of the first
   execution, or it ignores the arguments in subsequent executions.
   
  -<P><A NAME="anchor84"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="The_Diagnosis">The Diagnosis</A></H2></CENTER>
  -<P><A NAME="anchor85"></A>
  +<P>
   Let's follow the guidelines and use the <CODE>-w</CODE> flag. Now execute the code:
   
  -<P><A NAME="anchor86"></A>
  -<PRE>  % ./nested.pl
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  % ./nested.pl
     
     Variable &quot;$x&quot; will not stay shared at ./nested.pl line 9.
     5^2 = 25
  -  6^2 = 25
  -</PRE>
  -<P><A NAME="anchor87"></A>
  +  6^2 = 25</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   We have never seen such a warning message before and we don't quite
   understand what it means. The <CODE>diagnostics</CODE> pragma will certainly help us. Let's prepend this pragma before the <CODE>strict</CODE> pragma in our code:
  +
  +<P>
   
  -<P><A NAME="anchor88"></A>
  -<PRE>  #!/usr/bin/perl -w
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  #!/usr/bin/perl -w
     
     use diagnostics;
  -  use strict;
  -</PRE>
  -<P><A NAME="anchor89"></A>
  +  use strict;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   And execute it:
   
  -<P><A NAME="anchor90"></A>
  -<PRE>  % ./nested.pl
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  % ./nested.pl
     
     Variable &quot;$x&quot; will not stay shared at ./nested.pl line 10 (#1)
       
  @@ -644,26 +1005,29 @@
       variables.
       
     5^2 = 25
  -  6^2 = 25
  -</PRE>
  -<P><A NAME="anchor91"></A>
  +  6^2 = 25</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Well, now everything is clear. We have the <STRONG>inner</STRONG> subroutine <CODE>power_of_2()</CODE> and the <STRONG>outer</STRONG> subroutine <CODE>print_power_of_2()</CODE> in our code.
   
  -<P><A NAME="anchor92"></A>
  +<P>
   When the inner <CODE>power_of_2()</CODE> subroutine is called for the first
   time, it sees the value of the outer <CODE>print_power_of_2()</CODE>
   subroutine's <CODE>$x</CODE>
  -variable. On subsequent calls the <CODE>$x</CODE> variable won't be updated, no matter what the value of it in the outer
  -subroutine. There are two copies of the <CODE>$x</CODE> variable, no longer a single one shared by the two routines.
  +variable. On subsequent calls the inner subroutine's <CODE>$x</CODE> variable won't be updated, no matter what new values are given to <CODE>$x</CODE> in the outer subroutine. There are two copies of the <CODE>$x</CODE> variable, no longer a single one shared by the two routines.
   
  -<P><A NAME="anchor93"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="The_Remedy">The Remedy</A></H2></CENTER>
  -<P><A NAME="anchor94"></A>
  +<P>
   The <CODE>diagnostics</CODE> pragma suggests that the problem can be solved by making the inner
   subroutine anonymous.
   
  -<P><A NAME="anchor95"></A>
  +<P>
   An anonymous subroutine can act as a <EM>closure</EM> with respect to lexically scoped variables. Basically this means that if
   you define a subroutine in a particular <STRONG>lexical</STRONG> context at a particular moment, then it will run in that same context
   later, even if called from outside that context. The upshot of this is that
  @@ -672,11 +1036,20 @@
   visible when the subroutine was <STRONG>defined</STRONG>. So you can pass arguments to a function when you define it, as well as
   when you invoke it.
   
  -<P><A NAME="anchor96"></A>
  +<P>
   Let's rewrite the code to use this technique:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor97"></A>
  -<PRE>  anonymous.pl
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  anonymous.pl
     --------------
     #!/usr/bin/perl
     
  @@ -694,131 +1067,215 @@
     }
     
     print_power_of_2(5);
  -  print_power_of_2(6);
  -</PRE>
  -<P><A NAME="anchor98"></A>
  +  print_power_of_2(6);</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Now <CODE>$func_ref</CODE> contains a reference to an anonymous function, which we later use when we
   need to get the power of two. (In Perl, a function is the same thing as a
   subroutine.) Since it is anonymous, the function will automatically be
  -rebound to the new value of the outer scoped variable $x, and the results
  -will now be as expected.
  +rebound to the new value of the outer scoped variable <CODE>$x</CODE>, and the results will now be as expected.
   
  -<P><A NAME="anchor99"></A>
  +<P>
   Let's verify:
  +
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
   
  -<P><A NAME="anchor100"></A>
  -<PRE>  % ./anonymous.pl
  +	<td>
  +	  <pre>  % ./anonymous.pl
     
     5^2 = 25
  -  6^2 = 36
  -</PRE>
  -<P><A NAME="anchor101"></A>
  -Indeed, <EM>anonymous.pl</EM> worked as we expected.
  +  6^2 = 36</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +So we can see that the problem is solved. 
   
  -<P><A NAME="anchor102"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H1><A NAME="When_You_Cannot_Get_Rid_of_The_I">When You Cannot Get Rid of The Inner Subroutine</A></H1></CENTER>
  -<P><A NAME="anchor103"></A>
  +<P>
   First you might wonder, why in the world will someone need to define an
   inner subroutine? Well, for example to reduce some of Perl's script startup
   overhead you might decide to write a daemon that will compile the scripts
   and modules only once, and cache the pre-compiled code in memory. When some
   script is to be executed, you just tell the daemon the name of the script
  -to run and it will do the rest and do it much faster.
  +to run and it will do the rest and do it much faster since compilation has
  +already taken place.
   
  -<P><A NAME="anchor104"></A>
  +<P>
   Seems like an easy task, and it is. The only problem is once the script is
   compiled, how do you execute it? Or let's put it the other way: after it
  -was executed for the first time and it stays compiled in the daemon memory,
  -how do you call it again? If you could get all developers to code the
  -scripts so each has a subroutine called <CODE>run()</CODE> that will
  -actually execute the code in the script then you have half of the problem
  -solved.
  +was executed for the first time and it stays compiled in the daemon's
  +memory, how do you call it again? If you could get all developers to code
  +their scripts so each has a subroutine called <CODE>run()</CODE> that will
  +actually execute the code in the script then we've solved half the problem.
   
  -<P><A NAME="anchor105"></A>
  +<P>
   But how does the daemon know to refer to some specific script if they all
   run in the <CODE>main::</CODE> name space? One solution might be to ask the developers to declare a
   package in each and every script, and for the package name to be derived
  -from the script name. However, since there is chance that there will be
  +from the script name. However, since there is a chance that there will be
   more than one script with the same name but residing in different
  -directories, then in order to prevent name-space collisions the directory
  -has to be a part of the package name too. And don't forget that script may
  -be moved from one directory to another, so you will have to make sure that
  -the package name is corrected every time the script gets moved.
  +directories, then in order to prevent namespace collisions the directory
  +has to be a part of the package name too. And don't forget that the script
  +may be moved from one directory to another, so you will have to make sure
  +that the package name is corrected every time the script gets moved.
   
  -<P><A NAME="anchor106"></A>
  +<P>
   But why enforce these strange rules on developers, when we can arrange for
  -our daemon to do this work? For every script that daemon is about to
  -execute for the first time, it should be wrapped inside the package whose
  -name is constructed from the mangled path to the script and a subroutine
  -called <CODE>run().</CODE> For example if the daemon is about to execute
  -the script <EM>/tmp/hello.pl</EM>:
  +our daemon to do this work? For every script that the daemon is about to
  +execute for the first time, the script should be wrapped inside the package
  +whose name is constructed from the mangled path to the script and a
  +subroutine called <CODE>run().</CODE> For example if the daemon is about to
  +execute the script <EM>/tmp/hello.pl</EM>:
  +
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
   
  -<P><A NAME="anchor107"></A>
  -<PRE>  hello.pl
  +	<td>
  +	  <pre>  hello.pl
     --------
     #!/usr/bin/perl
  -  print &quot;Hello\n&quot;;
  -</PRE>
  -<P><A NAME="anchor108"></A>
  +  print &quot;Hello\n&quot;;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Prior to running it, the daemon will change the code to be:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor109"></A>
  -<PRE>  wrapped_hello.pl
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  wrapped_hello.pl
     ----------------
     package cache::tmp::hello_2epl;
     
     sub run{
       #!/usr/bin/perl 
       print &quot;Hello\n&quot;;
  -  }
  -</PRE>
  -<P><A NAME="anchor110"></A>
  +  }</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   The package name is constructed from the prefix <CODE>cache::</CODE>, each directory separation slash is replaced with <CODE>::</CODE>, and non alphanumeric characters are encoded so that for example <CODE>.</CODE> (a dot) becomes <CODE>_2e</CODE> (an underscore followed by the ASCII code for a dot in hex representation).
  +
  +<P>
   
  -<P><A NAME="anchor111"></A>
  -<PRE> % perl -e 'printf &quot;%x&quot;,ord(&quot;.&quot;)'
  -</PRE>
  -<P><A NAME="anchor112"></A>
  -prints: <CODE>2e</CODE>. The underscore is the same you see in URL encoding where <CODE>%</CODE> character is used instead (<CODE>%2E</CODE>), but since <CODE>%</CODE> has a special meaning in Perl (prefix of hash variable) it couldn't be
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre> % perl -e 'printf &quot;%x&quot;,ord(&quot;.&quot;)'</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +prints: <CODE>2e</CODE>. The underscore is the same you see in URL encoding except the <CODE>%</CODE> character is used instead (<CODE>%2E</CODE>), but since <CODE>%</CODE> has a special meaning in Perl (prefix of hash variable) it couldn't be
   used.
   
  -<P><A NAME="anchor113"></A>
  +<P>
   Now when the daemon is requested to execute the script
   <EM>/tmp/hello.pl</EM>, all it has to do is to build the package name as before based on the
   location of the script and call its <CODE>run()</CODE> subroutine:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor114"></A>
  -<PRE>  use cache::tmp::hello_2epl;
  -  cache::tmp::hello_2epl::run();
  -</PRE>
  -<P><A NAME="anchor115"></A>
  -We have just written a partial prototype of the daemon we desired. The only
  -method now remaining undefined is how to pass the path to the script to the
  -daemon. This detail is left to the reader as an exercise.
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  use cache::tmp::hello_2epl;
  +  cache::tmp::hello_2epl::run();</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +We have just written a partial prototype of the daemon we wanted. The only
  +outstanding problem is how to pass the path to the script to the daemon.
  +This detail is left as an exercise for the reader.
   
  -<P><A NAME="anchor116"></A>
  +<P>
   If you are familiar with the <CODE>Apache::Registry</CODE> module, you know that it works in almost the same way. It uses a different
   package prefix and the generic function is called <CODE>handler()</CODE>
   and not <CODE>run().</CODE> The scripts to run are passed through the HTTP
   protocol's headers.
   
  -<P><A NAME="anchor117"></A>
  +<P>
   Now you understand that there are cases where your normal subroutines can
   become inner, since if your script was a simple:
   
  -<P><A NAME="anchor118"></A>
  -<PRE>  simple.pl
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  simple.pl
     ---------
     #!/usr/bin/perl 
     sub hello { print &quot;Hello&quot; }
  -  hello();
  -</PRE>
  -<P><A NAME="anchor119"></A>
  +  hello();</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Wrapped into a <CODE>run()</CODE> subroutine it becomes:
  +
  +<P>
   
  -<P><A NAME="anchor120"></A>
  -<PRE>  simple.pl
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  simple.pl
     ---------
     package cache::simple_2epl;
     
  @@ -826,30 +1283,43 @@
       #!/usr/bin/perl 
       sub hello { print &quot;Hello&quot; }
       hello();
  -  }
  -</PRE>
  -<P><A NAME="anchor121"></A>
  +  }</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Therefore, <CODE>hello()</CODE> is an inner subroutine and if you have used
   <CODE>my()</CODE> scoped variables defined and altered outside and used
   inside <CODE>hello(),</CODE> it won't work as you expect starting from the
   second call, as was explained in the previous section.
   
  -<P><A NAME="anchor122"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="Remedies_for_Inner_Subroutines">Remedies for Inner Subroutines</A></H2></CENTER>
  -<P><A NAME="anchor123"></A>
  +<P>
   First of all there is nothing to worry about, as long as you don't forget
   to turn the warnings On. If you do happen to have the ``<A HREF="././perl.html#my_Scoped_Variable_in_Nested_S">my() Scoped Variable in Nested  Subroutines</A>'' problem, Perl will always alert you.
   
  -<P><A NAME="anchor124"></A>
  +<P>
   Given that you have a script that has this problem, what are the ways to
   solve it? There are many of them and we will discuss some of them here.
   
  -<P><A NAME="anchor125"></A>
  +<P>
   We will use the following code to show the different solutions.
  +
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
   
  -<P><A NAME="anchor126"></A>
  -<PRE>  multirun.pl
  +	<td>
  +	  <pre>  multirun.pl
     -----------
     #!/usr/bin/perl -w
     
  @@ -860,7 +1330,7 @@
       run();
     }
     
  -  sub run {
  +  sub run{
     
       my $counter = 0;
     
  @@ -872,17 +1342,29 @@
         print &quot;Counter is equal to $counter !\n&quot;;
       }
     
  -  } # end of sub run
  -</PRE>
  -<P><A NAME="anchor127"></A>
  +  } # end of sub run</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   This code executes the <CODE>run()</CODE> subroutine three times, which in
  -turn initializes the <CODE>$counter</CODE> variable to 0, every time it executed and then calls the inner subroutine
  -<CODE>increment_counter()</CODE> twice. Sub
  +turn initializes the <CODE>$counter</CODE> variable to 0, every time it is executed and then calls the inner
  +subroutine <CODE>increment_counter()</CODE> twice. Sub
   <CODE>increment_counter()</CODE> prints <CODE>$counter</CODE>'s value after incrementing it. One might expect to see the following
   output:
  +
  +<P>
   
  -<P><A NAME="anchor128"></A>
  -<PRE>  run: [time 1]
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  run: [time 1]
     Counter is equal to 1 !
     Counter is equal to 2 !
     run: [time 2]
  @@ -890,17 +1372,41 @@
     Counter is equal to 2 !
     run: [time 3]
     Counter is equal to 1 !
  -  Counter is equal to 2 !
  -</PRE>
  -<P><A NAME="anchor129"></A>
  +  Counter is equal to 2 !</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   But as we have already learned from the previous sections, this is not what
   we are going to see. Indeed, when we run the script we see:
  +
  +<P>
   
  -<P><A NAME="anchor130"></A>
  -<PRE>  % ./multirun.pl
  -</PRE>
  -<P><A NAME="anchor131"></A>
  -<PRE>  Variable &quot;$counter&quot; will not stay shared at ./nested.pl line 18.
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  % ./multirun.pl</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  Variable &quot;$counter&quot; will not stay shared at ./nested.pl line 18.
     run: [time 1]
     Counter is equal to 1 !
     Counter is equal to 2 !
  @@ -909,19 +1415,31 @@
     Counter is equal to 4 !
     run: [time 3]
     Counter is equal to 5 !
  -  Counter is equal to 6 !
  -</PRE>
  -<P><A NAME="anchor132"></A>
  +  Counter is equal to 6 !</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Obviously, the <CODE>$counter</CODE> variable is not reinitialized on each execution of <CODE>run().</CODE> It
   retains its value from the previous execution, and sub
   <CODE>increment_counter()</CODE> increments that.
   
  -<P><A NAME="anchor133"></A>
  +<P>
   One of the workarounds is to use globally declared variables, with the
   <CODE>vars</CODE> pragma.
  +
  +<P>
   
  -<P><A NAME="anchor134"></A>
  -<PRE>  multirun1.pl
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  multirun1.pl
     -----------
     #!/usr/bin/perl -w
     
  @@ -945,14 +1463,26 @@
         print &quot;Counter is equal to $counter !\n&quot;;
       }
     
  -  } # end of sub run
  -</PRE>
  -<P><A NAME="anchor135"></A>
  +  } # end of sub run</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   If you run this and the other solutions offered below, the expected output
   will be generated:
  +
  +<P>
   
  -<P><A NAME="anchor136"></A>
  -<PRE>  % ./multirun1.pl
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  % ./multirun1.pl
     
     run: [time 1]
     Counter is equal to 1 !
  @@ -962,18 +1492,30 @@
     Counter is equal to 2 !
     run: [time 3]
     Counter is equal to 1 !
  -  Counter is equal to 2 !
  -</PRE>
  -<P><A NAME="anchor137"></A>
  +  Counter is equal to 2 !</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   By the way, the warning we saw before has gone, and so has the problem,
   since there is no <CODE>my()</CODE> (lexically defined) variable used in the nested subroutine.
   
  -<P><A NAME="anchor138"></A>
  +<P>
   Another approach is to use fully qualified variables. This is better, since
   less memory will be used, but it adds a typing overhead:
   
  -<P><A NAME="anchor139"></A>
  -<PRE>  multirun2.pl
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  multirun2.pl
     -----------
     #!/usr/bin/perl -w
     
  @@ -996,25 +1538,37 @@
         print &quot;Counter is equal to $main::counter !\n&quot;;
       }
     
  -  } # end of sub run
  -</PRE>
  -<P><A NAME="anchor140"></A>
  +  } # end of sub run</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   You can also pass the variable to the subroutine by value and make the
   subroutine return it after it was updated. This adds time and memory
   overheads, so it may not be good idea if the variable can be very large, or
   if speed of execution is an issue.
   
  -<P><A NAME="anchor141"></A>
  +<P>
   Don't rely on the fact that the variable is small during the development of
   the application, it can grow quite big in situations you don't expect. For
   example, a very simple HTML form text entry field can return a few
   megabytes of data if one of your users is bored and wants to test how good
  -is your code. It's not uncommon to see users Copy-and-Paste 10Mb core dump
  +your code is. It's not uncommon to see users copy-and-paste 10Mb core dump
   files into a form's text fields and then submit it for your script to
   process.
  +
  +<P>
   
  -<P><A NAME="anchor142"></A>
  -<PRE>  multirun3.pl
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  multirun3.pl
     -----------
     #!/usr/bin/perl -w
     
  @@ -1041,18 +1595,30 @@
         return $counter;
       }
     
  -  } # end of sub run
  -</PRE>
  -<P><A NAME="anchor143"></A>
  +  } # end of sub run</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Finally, you can use references to do the job. The version of
   <CODE>increment_counter()</CODE> below accepts a reference to the <CODE>$counter</CODE>
   variable and increments its value after first dereferencing it. When you
   use a reference, the variable you use inside the function is physically the
   same bit of memory as the one outside the function. This technique is often
   used to enable a called function to modify variables in a calling function.
  +
  +<P>
   
  -<P><A NAME="anchor144"></A>
  -<PRE>  multirun4.pl
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  multirun4.pl
     -----------
     #!/usr/bin/perl -w
     
  @@ -1077,17 +1643,30 @@
         print &quot;Counter is equal to $$r_counter !\n&quot;;
       }
     
  -  } # end of sub run
  -</PRE>
  -<P><A NAME="anchor145"></A>
  +  } # end of sub run</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Here is yet another and more obscure reference usage. We modify the value
   of <CODE>$counter</CODE> inside the subroutine by using the fact that variables in <CODE>@_</CODE> are aliases for the actual scalar parameters. Thus if you called a function
   with two arguments, those would be stored in
   <CODE>$_[0]</CODE> and <CODE>$_[1]</CODE>. In particular, if an element <CODE>$_[0]</CODE> is updated, the corresponding argument is updated (or an error occurs if it
  -is not updatable).
  +is not updatable as would be the case of calling the function with a
  +literal, e.g. <EM>increment_counter(5)</EM>).
  +
  +<P>
   
  -<P><A NAME="anchor146"></A>
  -<PRE>  multirun5.pl
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  multirun5.pl
     -----------
     #!/usr/bin/perl -w
     
  @@ -1109,324 +1688,716 @@
         $_[0]++;
         print &quot;Counter is equal to $_[0] !\n&quot;;
       }
  +  
  +  } # end of sub run</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +The approach given above is generally not recommended because most Perl
  +programmers will not expect <CODE>$counter</CODE> to be changed by the function; the example where we used <CODE>\$counter</CODE>, i.e. pass-by-reference would be preferred.
  +
  +<P>
  +Here is a solution that avoids the problem entirely by splitting the code
  +into two files; the first is really just a wrapper and loader, the second
  +file contains the heart of the code.
  +
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  multirun6.pl
  +  -----------
  +  #!/usr/bin/perl -w
     
  -  } # end of sub run
  -</PRE>
  -<P><A NAME="anchor147"></A>
  -Now you have at least five workarounds to choose from.
  +  use strict;
  +  require 'multirun6-lib.pl' ;
  +  
  +  for (1..3){
  +    print &quot;run: [time $_]\n&quot;;
  +    run();
  +  }</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +Separate file:
  +
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  multirun6-lib.pl
  +  ----------------
  +  use strict ;
  +  
  +  my $counter;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  sub run {
  +    $counter = 0;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
   
  -<P><A NAME="anchor148"></A>
  +	<td>
  +	  <pre>    increment_counter();
  +    increment_counter();
  +  }
  +  
  +  sub increment_counter{
  +    $counter++;
  +    print &quot;Counter is equal to $counter !\n&quot;;
  +  }
  +  
  +  1 ;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +Now you have at least six workarounds to choose from.
  +
  +<P>
   For more information please refer to perlref and perlsub manpages.
   
  -<P><A NAME="anchor149"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H1><A NAME="use_require_do_INC_and">use(), require(), do(), %INC and @INC Explained</A></H1></CENTER>
  -<P><A NAME="anchor150"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="The_INC_array">The @INC array</A></H2></CENTER>
  -<P><A NAME="anchor151"></A>
  +<P>
   <CODE>@INC</CODE> is a special Perl variable which is the equivalent of the shell's <CODE>PATH</CODE> variable. Whereas <CODE>PATH</CODE> contains a list of directories to search for executables, <CODE>@INC</CODE> contains a list of directories from which Perl modules and libraries can be
   loaded.
   
  -<P><A NAME="anchor152"></A>
  +<P>
   When you <CODE>use(),</CODE> <CODE>require()</CODE> or <CODE>do()</CODE> a
   filename or a module, Perl gets a list of directories from the <CODE>@INC</CODE> variable and searches them for the file it was requested to load. If the
   file that you want to load is not located in one of the listed directories,
   you have to tell Perl where to find the file. You can either provide a path
   relative to one of the directories in <CODE>@INC</CODE>, or you can provide the full path to the file.
   
  -<P><A NAME="anchor153"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="The_INC_hash">The %INC hash</A></H2></CENTER>
  -<P><A NAME="anchor154"></A>
  +<P>
   <CODE>%INC</CODE> is another special Perl variable that is used to cache the names of the
   files and the modules that were successfully loaded and compiled by
  -<CODE>use(),</CODE> <CODE>require()</CODE> or <CODE>do()</CODE> functions.
  +<CODE>use(),</CODE> <CODE>require()</CODE> or <CODE>do()</CODE> statements.
   Before attempting to load a file or a module, Perl checks whether it's
   already in the
   <CODE>%INC</CODE> hash. If it's there, the loading and therefore the compilation are not
   performed at all. Otherwise the file is loaded into memory and an attempt
  -is made to compiled it.
  +is made to compile it.
   
  -<P><A NAME="anchor155"></A>
  +<P>
   If the file is successfully loaded and compiled, a new key-value pair is
   added to <CODE>%INC</CODE>. The key is the name of the file or module as it was passed to the one of
   the three functions we have just mentioned, and if it was found in any of
   the <CODE>@INC</CODE> directories except <CODE>&quot;.&quot;</CODE>
   the value is the full path to it in the file system.
   
  -<P><A NAME="anchor156"></A>
  +<P>
   The following examples will make it easier to understand the logic.
   
  -<P><A NAME="anchor157"></A>
  +<P>
   First, let's see what are the contents of <CODE>@INC</CODE> on my system:
   
  -<P><A NAME="anchor158"></A>
  -<PRE>  % perl -e 'print join &quot;\n&quot;, @INC'
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  % perl -e 'print join &quot;\n&quot;, @INC'
     /usr/lib/perl5/5.00503/i386-linux
     /usr/lib/perl5/5.00503
     /usr/lib/perl5/site_perl/5.005/i386-linux
     /usr/lib/perl5/site_perl/5.005
  -  .
  -</PRE>
  -<P><A NAME="anchor159"></A>
  +  .</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Notice the <CODE>.</CODE> (current directory) is the last directory in the list.
   
  -<P><A NAME="anchor160"></A>
  +<P>
   Now let's load the module <CODE>strict.pm</CODE> and see the contents of <CODE>%INC</CODE>:
   
  -<P><A NAME="anchor161"></A>
  -<PRE>  % perl -e 'use strict; print map {&quot;$_ =&gt; $INC{$_}\n&quot;} keys %INC'
  -  
  -  strict.pm =&gt; /usr/lib/perl5/5.00503/strict.pm
  -</PRE>
  -<P><A NAME="anchor162"></A>
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  % perl -e 'use strict; print map {&quot;$_ =&gt; $INC{$_}\n&quot;} keys %INC'
  +  
  +  strict.pm =&gt; /usr/lib/perl5/5.00503/strict.pm</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Since <CODE>strict.pm</CODE> was found in <EM>/usr/lib/perl5/5.00503/</EM> directory and <EM>/usr/lib/perl5/5.00503/</EM> is a part of <CODE>@INC</CODE>, <CODE>%INC</CODE> includes the full path as the value for the key <CODE>strict.pm</CODE>.
   
  -<P><A NAME="anchor163"></A>
  +<P>
   Now let's create the simplest module in <CODE>/tmp/test.pm</CODE>:
   
  -<P><A NAME="anchor164"></A>
  -<PRE>  test.pm
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  test.pm
     -------
  -  1;
  -</PRE>
  -<P><A NAME="anchor165"></A>
  +  1;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   It does nothing, but returns a true value when loaded. Now let's load it in
   different ways:
  +
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
   
  -<P><A NAME="anchor166"></A>
  -<PRE>  % cd /tmp
  +	<td>
  +	  <pre>  % cd /tmp
     % perl -e 'use test; print map {&quot;$_ =&gt; $INC{$_}\n&quot;} keys %INC'
     
  -  test.pm =&gt; test.pm
  -</PRE>
  -<P><A NAME="anchor167"></A>
  +  test.pm =&gt; test.pm</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Since the file was found relative to <CODE>.</CODE> (the current directory), the relative path is inserted as the value. If we
   alter <CODE>@INC</CODE>, by adding
   <EM>/tmp</EM> to the end:
   
  -<P><A NAME="anchor168"></A>
  -<PRE>  % cd /tmp
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  % cd /tmp
     % perl -e 'BEGIN{push @INC, &quot;/tmp&quot;} use test; \
     print map {&quot;$_ =&gt; $INC{$_}\n&quot;} keys %INC'
     
  -  test.pm =&gt; test.pm
  -</PRE>
  -<P><A NAME="anchor169"></A>
  +  test.pm =&gt; test.pm</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Here we still get the relative path, since the module was found first
   relative to <CODE>&quot;.&quot;</CODE>. The directory <EM>/tmp</EM> was placed after <CODE>.</CODE> in the list. If we execute the same code from a different directory, the
   <CODE>&quot;.&quot;</CODE> directory won't match,
  +
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
   
  -<P><A NAME="anchor170"></A>
  -<PRE>  % cd /
  +	<td>
  +	  <pre>  % cd /
     % perl -e 'BEGIN{push @INC, &quot;/tmp&quot;} use test; \
     print map {&quot;$_ =&gt; $INC{$_}\n&quot;} keys %INC'
     
  -  test.pm =&gt; /tmp/test.pm
  -</PRE>
  -<P><A NAME="anchor171"></A>
  +  test.pm =&gt; /tmp/test.pm</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   so we get the full path. We can also prepend the path with
   <CODE>unshift(),</CODE> so it will be used for matching before <CODE>&quot;.&quot;</CODE> and therefore we will get the full path as well:
   
  -<P><A NAME="anchor172"></A>
  -<PRE>  % cd /tmp
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  % cd /tmp
     % perl -e 'BEGIN{unshift @INC, &quot;/tmp&quot;} use test; \
     print map {&quot;$_ =&gt; $INC{$_}\n&quot;} keys %INC'
     
  -  test.pm =&gt; /tmp/test.pm
  -</PRE>
  -<P><A NAME="anchor173"></A>
  +  test.pm =&gt; /tmp/test.pm</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   The code:
  +
  +<P>
   
  -<P><A NAME="anchor174"></A>
  -<PRE>  BEGIN{unshift @INC, &quot;/tmp&quot;}
  -</PRE>
  -<P><A NAME="anchor175"></A>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  BEGIN{unshift @INC, &quot;/tmp&quot;}</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   can be replaced with the more elegant:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor176"></A>
  -<PRE>  use lib &quot;/tmp&quot;;
  -</PRE>
  -<P><A NAME="anchor177"></A>
  -Which executes the BEGIN block above exactly.
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  use lib &quot;/tmp&quot;;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +Which is almost equivalent to our <CODE>BEGIN</CODE> block and is the recommended approach.
   
  -<P><A NAME="anchor178"></A>
  +<P>
   These approaches to modifying <CODE>@INC</CODE> can be labor intensive, since if you want to move the script around in the
   file-system you have to modify the path. This can be painful, for example,
   when you move your scripts from development to a production server.
   
  -<P><A NAME="anchor179"></A>
  +<P>
   There is a module called <CODE>FindBin</CODE> which solves this problem in the plain Perl world, but unfortunately it
   won't work under mod_perl, since it's a module and as any module it's
   loaded only once. So the first script using it will have all the settings
   correct, but the rest of the scripts will not if located in a different
   directory from the first.
   
  -<P><A NAME="anchor180"></A>
  -For a completeness of this section, I'll present this module anyway.
  +<P>
  +For the sake of completeness, I'll present this module anyway.
   
  -<P><A NAME="anchor181"></A>
  +<P>
   If you use this module, you don't need to write a hard coded path. The
   following snippet does all the work for you (the file is
   <EM>/tmp/load.pl</EM>):
   
  -<P><A NAME="anchor182"></A>
  -<PRE>  load.pl
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  load.pl
     -------
     #!/usr/bin/perl
     
     use FindBin ();
     use lib &quot;$FindBin::Bin&quot;;
     use test;
  -  print &quot;test.pm =&gt; $INC{'test.pm'}\n&quot;;
  -</PRE>
  -<P><A NAME="anchor183"></A>
  +  print &quot;test.pm =&gt; $INC{'test.pm'}\n&quot;;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   In the above example <CODE>$FindBin::Bin</CODE> is equal to <EM>/tmp</EM>. If we move the script somewhere else... e.g. <EM>/tmp/x</EM> in the code above
   <CODE>$FindBin::Bin</CODE> equals <EM>/home/x</EM>.
   
  -<P><A NAME="anchor184"></A>
  -<PRE>  % /tmp/load.pl
  -  
  -  test.pm =&gt; /tmp/test.pm
  -</PRE>
  -<P><A NAME="anchor185"></A>
  -Just like with <CODE>use lib</CODE> but no hard coded path required.
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  % /tmp/load.pl
  +  
  +  test.pm =&gt; /tmp/test.pm</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +This is just like <CODE>use lib</CODE> except that no hard coded path is required.
   
  -<P><A NAME="anchor186"></A>
  +<P>
   You can use this workaround to make it work under mod_perl.
   
  -<P><A NAME="anchor187"></A>
  -<PRE>  do 'FindBin.pm';
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  do 'FindBin.pm';
     unshift @INC, &quot;$FindBin::Bin&quot;;
     require test;
  -  #maybe test::import( ... ) here if need to import stuff
  -</PRE>
  -<P><A NAME="anchor188"></A>
  -You will have a slight overhead because you will load from disk and
  -recompile the <CODE>FindBin</CODE> module on each request. So it can be not worth it.
  -
  -<P><A NAME="anchor189"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<CENTER><H2><A NAME="Modules_Libraries_and_Files">Modules, Libraries and Files</A></H2></CENTER>
  -<P><A NAME="anchor190"></A>
  -Before we proceed, let's define what we mean by <EM>module</EM>, and
  -<EM>library</EM> or <EM>file</EM>.
  +  #maybe test::import( ... ) here if need to import stuff</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +This has a slight overhead because it will load from disk and recompile the <CODE>FindBin</CODE> module on each request. So it may not be worth it.
   
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
  +<CENTER><H2><A NAME="Modules_Libraries_and_Program_F">Modules, Libraries and Program Files</A></H2></CENTER>
  +<P>
  +Before we proceed, let's define what we mean by <EM>module</EM>, 
  +<EM>library</EM> and <EM>program file</EM>.
  +
   <UL>
  -<P><LI><STRONG><A NAME="item_The">The Library or the File</A></STRONG>
  -<P><A NAME="anchor191"></A>
  -A file which contains perl subroutines and other code. 
  +<P><LI><STRONG><A NAME="item_Libraries">Libraries</A></STRONG>
  +<P>
  +These are files which contain Perl subroutines and other code.
  +
  +<P>
  +When these are used to break up a large program into manageable chunks they
  +don't generally include a package declaration; when they are used as
  +subroutine libraries they often do have a package declaration.
  +
  +<P>
  +Their last statement returns true, a simple <CODE>1;</CODE> statement ensures that.
  +
  +<P>
  +They can be named in any way desired, but generally their extension is
  +<EM>.pl</EM>.
   
  -<P><A NAME="anchor192"></A>
  -It generally doesn't include a package declaration.  
  +<P>
  +Examples:
   
  -<P><A NAME="anchor193"></A>
  -Its last statement returns true.
  +<P>
   
  -<P><A NAME="anchor194"></A>
  -It can be named in any way desired, but generally its extension is
  -<EM>.pl</EM> or <EM>.ph</EM>.
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor195"></A>
  -Examples:
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
   
  -<P><A NAME="anchor196"></A>
  -<PRE>  config.pl
  +	<td>
  +	  <pre>  config.pl
     ----------
  +  # No package so defaults to main::
     $dir = &quot;/home/httpd/cgi-bin&quot;;
     $cgi = &quot;/cgi-bin&quot;;
  -  1;
  -</PRE>
  -<P><A NAME="anchor197"></A>
  -<PRE>  mysubs.pl
  +  1;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  mysubs.pl
     ----------
  +  # No package so defaults to main::
     sub print_header{
       print &quot;Content-type: text/plain\r\n\r\n&quot;;
     }
  -  1;
  -</PRE>
  -<P><LI><STRONG><A NAME="item_the">the Module</A></STRONG>
  -<P><A NAME="anchor198"></A>
  +  1;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  web.pl
  +  ------------
  +  package web ;
  +  # Call like this: web::print_with_class('loud',&quot;Don't shout!&quot;);
  +  sub print_with_class{
  +    my( $class, $text ) = @_ ;
  +    print qq{&lt;span class=&quot;$class&quot;&gt;$text&lt;/span&gt;};
  +  }
  +  1;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P><LI><STRONG><A NAME="item_Modules">Modules</A></STRONG>
  +<P>
   A file which contains perl subroutines and other code.
   
  -<P><A NAME="anchor199"></A>
  +<P>
   It generally declares a package name at the beginning of it.
   
  -<P><A NAME="anchor200"></A>
  +<P>
  +Modules are generally used either as function libraries (which <EM>.pl</EM>
  +files are still but less commonly used for), or as object libraries where a
  +module is used to define a class and its methods.
  +
  +<P>
   Its last statement returns true.
   
  -<P><A NAME="anchor201"></A>
  +<P>
   The naming convention requires it to have a <EM>.pm</EM> extension.
   
  -<P><A NAME="anchor202"></A>
  +<P>
   Example:
  +
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
   
  -<P><A NAME="anchor203"></A>
  -<PRE>  MyModule.pm
  +	<td>
  +	  <pre>  MyModule.pm
     -----------
     package My::Module;
     $My::Module::VERSION = 0.01;
     
     sub new{ return bless {}, shift;}
     END { print &quot;Quitting\n&quot;}
  -  1;
  -</PRE>
  +  1;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P><LI><STRONG><A NAME="item_Program">Program Files</A></STRONG>
  +<P>
  +Many Perl programs exist as a single file. Under Linux and other Unix-like
  +operating systems the file often has no suffix since the operating system
  +can determine that it is a perl script from the first line (shebang line)
  +or if it's Apache that executes the code, there is a variety of ways to
  +tell how and when the file should be executed. Under Windows a suffix is
  +normally used, for example <CODE>.pl</CODE> or
  +<CODE>.plx</CODE>.
  +
  +<P>
  +The program file will normally <CODE>require()</CODE> any libraries and <CODE>use()</CODE>
  +any modules it requires for execution.
  +
  +<P>
  +It will contain Perl code but won't usually have any package names.
  +
  +<P>
  +Its last statement may return anything or nothing.
  +
   </UL>
  -<P><A NAME="anchor204"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="require_">require()</A></H2></CENTER>
  -<P><A NAME="anchor205"></A>
  +<P>
   <CODE>require()</CODE> reads a file containing Perl code and compiles it.
   Before attempting to load the file it looks up the argument in <CODE>%INC</CODE> to see whether it has already been loaded. If it has,
   <CODE>require()</CODE> just returns without doing a thing. Otherwise an
   attempt will be made to load and compile the file.
   
  -<P><A NAME="anchor206"></A>
  +<P>
   <CODE>require()</CODE> has to find the file it has to load. If the argument
   is a full path to the file, it just tries to read it. For example:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor207"></A>
  -<PRE>  require &quot;/home/httpd/perl/mylibs.pl&quot;;
  -</PRE>
  -<P><A NAME="anchor208"></A>
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  require &quot;/home/httpd/perl/mylibs.pl&quot;;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   If the path is relative, <CODE>require()</CODE> will attempt to search for
   the file in all the directories listed in <CODE>@INC</CODE>. For example:
   
  -<P><A NAME="anchor209"></A>
  -<PRE>  require &quot;mylibs.pl&quot;;
  -</PRE>
  -<P><A NAME="anchor210"></A>
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  require &quot;mylibs.pl&quot;;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   If there is more than one occurrence of the file with the same name in the
   directories listed in <CODE>@INC</CODE> the first occurrence will be used.
   
  -<P><A NAME="anchor211"></A>
  +<P>
   The file must return <EM>TRUE</EM> as the last statement to indicate successful execution of any
   initialization code. Since you never know what changes the file will go
   through in the future, you cannot be sure that the last statement will
   always return <EM>TRUE</EM>. That's why the suggestion is to put ``<CODE>1;</CODE>'' at the end of file.
  +
  +<P>
  +Although you should use the real filename for most files, if the file is a <A HREF="././perl.html#Modules_Libraries_and_Program_F">module</A>, you may use the following convention instead:
   
  -<P><A NAME="anchor212"></A>
  -Although you should use the real filename for most files, if the file is a <A HREF="././perl.html#Modules_Libraries_and_Files">module</A>, you may use the following convention instead:
  +<P>
   
  -<P><A NAME="anchor213"></A>
  -<PRE>  require My::Module;
  -</PRE>
  -<P><A NAME="anchor214"></A>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  require My::Module;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   This is equal to:
  +
  +<P>
   
  -<P><A NAME="anchor215"></A>
  -<PRE>  require &quot;My/Module.pm&quot;;
  -</PRE>
  -<P><A NAME="anchor216"></A>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  require &quot;My/Module.pm&quot;;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   If <CODE>require()</CODE> fails to load the file, either because it
   couldn't find the file in question or the code failed to compile, or it
   didn't return <EM>TRUE</EM>, then the program would <CODE>die().</CODE> To prevent this the
   <CODE>require()</CODE> statement can be enclosed into an
  -<CODE>eval()</CODE> block, as in this example:
  +<CODE>eval()</CODE> exception-handling block, as in this example:
  +
  +<P>
   
  -<P><A NAME="anchor217"></A>
  -<PRE>  require.pl
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  require.pl
     ----------
     #!/usr/bin/perl -w
     
  @@ -1434,200 +2405,360 @@
     if ($@) {
       print &quot;Failed to load, because : $@&quot;
     }
  -  print &quot;\nHello\n&quot;;
  -</PRE>
  -<P><A NAME="anchor218"></A>
  +  print &quot;\nHello\n&quot;;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   When we execute the program:
  +
  +<P>
   
  -<P><A NAME="anchor219"></A>
  -<PRE>  % ./require.pl
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  % ./require.pl
     
     Failed to load, because : Can't locate /file/that/does/not/exists in
     @INC (@INC contains: /usr/lib/perl5/5.00503/i386-linux
     /usr/lib/perl5/5.00503 /usr/lib/perl5/site_perl/5.005/i386-linux
     /usr/lib/perl5/site_perl/5.005 .) at require.pl line 3.
     
  -  Hello
  -</PRE>
  -<P><A NAME="anchor220"></A>
  +  Hello</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   We see that the program didn't <CODE>die(),</CODE> because <EM>Hello</EM> was printed. This <EM>trick</EM> is useful when you want to check whether a user has some module installed,
   but if she hasn't it's not critical, perhaps the program can run without
   this module with reduced functionality.
   
  -<P><A NAME="anchor221"></A>
  +<P>
   If we remove the <CODE>eval()</CODE> part and try again:
  +
  +<P>
   
  -<P><A NAME="anchor222"></A>
  -<PRE>  require.pl
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  require.pl
     ----------
     #!/usr/bin/perl -w
     
     require &quot;/file/that/does/not/exists&quot;;
  -  print &quot;\nHello\n&quot;;
  -</PRE>
  -<P><A NAME="anchor223"></A>
  -<PRE>  % ./require1.pl
  +  print &quot;\nHello\n&quot;;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  % ./require1.pl
     
     Can't locate /file/that/does/not/exists in @INC (@INC contains:
     /usr/lib/perl5/5.00503/i386-linux /usr/lib/perl5/5.00503
     /usr/lib/perl5/site_perl/5.005/i386-linux
  -  /usr/lib/perl5/site_perl/5.005 .) at require1.pl line 3.
  -</PRE>
  -<P><A NAME="anchor224"></A>
  +  /usr/lib/perl5/site_perl/5.005 .) at require1.pl line 3.</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   The program just <CODE>die()s</CODE> in the last example, which is what you
   want in most cases.
   
  -<P><A NAME="anchor225"></A>
  +<P>
   For more information refer to the perlfunc manpage.
   
  -<P><A NAME="anchor226"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="use_">use()</A></H2></CENTER>
  -<P><A NAME="anchor227"></A>
  +<P>
   <CODE>use(),</CODE> just like <CODE>require(),</CODE> loads and compiles
  -files containing Perl code, but it works with <A HREF="././perl.html#Modules_Libraries_and_Files">modules</A>
  -only. The only way to pass a module to load is by its module name and not
  +files containing Perl code, but it works with
  +<A HREF="././perl.html#Modules_Libraries_and_Program_F">modules</A> only. The only way to pass a module to load is by its module name and not
   its filename. If the module is located in <EM>MyCode.pm</EM>, the correct way to <CODE>use()</CODE> it is:
  +
  +<P>
   
  -<P><A NAME="anchor228"></A>
  -<PRE>  use MyCode
  -</PRE>
  -<P><A NAME="anchor229"></A>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  use MyCode</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   and not:
  +
  +<P>
   
  -<P><A NAME="anchor230"></A>
  -<PRE>  use &quot;MyCode.pm&quot;
  -</PRE>
  -<P><A NAME="anchor231"></A>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  use &quot;MyCode.pm&quot;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   <CODE>use()</CODE> translates the passed argument into a file name
   replacing <CODE>::</CODE>
  -with <CODE>/</CODE> and appending <EM>.pm</EM> at the end. So <CODE>My::Module</CODE> becomes
  -<EM>My/Module.pm</EM>.
  +with the operating system's path separator (normally <CODE>/</CODE>) and appending <EM>.pm</EM> at the end. So <CODE>My::Module</CODE> becomes <EM>My/Module.pm</EM>.
   
  -<P><A NAME="anchor232"></A>
  +<P>
   <CODE>use()</CODE> is exactly equivalent to:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor233"></A>
  -<PRE> BEGIN { require Module; import Module LIST; }
  -</PRE>
  -<P><A NAME="anchor234"></A>
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre> BEGIN { require Module; Module-&gt;import(LIST); }</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Internally it calls <CODE>require()</CODE> to do the loading and
   compilation chores. When <CODE>require()</CODE> finishes its job,
   <CODE>import()</CODE> is called unless
   <CODE>()</CODE> is the second argument. The following pairs are equivalent:
   
  -<P><A NAME="anchor235"></A>
  -<PRE>  use MyModule;
  -  BEGIN {require MyModule; import MyModule; }
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  use MyModule;
  +  BEGIN {require MyModule; MyModule-&gt;import; }
     
     use MyModule qw(foo bar);
  -  BEGIN {require MyModule; import MyModule (&quot;foo&quot;,&quot;bar&quot;); }
  +  BEGIN {require MyModule; MyModule-&gt;import(&quot;foo&quot;,&quot;bar&quot;); }
     
     use MyModule ();
  -  BEGIN {require MyModule; }
  -</PRE>
  -<P><A NAME="anchor236"></A>
  -The first pair exports the default tags. This happens if the module sets <CODE>@EXPORT</CODE> to a list of tags to be exported by default. The module manpage generally
  -describes what modules are exported by default.
  -
  -<P><A NAME="anchor237"></A>
  -The second pair exports all the tags passed as arguments. No default tags
  -are exported unless explicitly told to.
  +  BEGIN {require MyModule; }</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +The first pair exports the default tags. This happens if the module sets <CODE>@EXPORT</CODE> to a list of tags to be exported by default. The module's manpage normally
  +describes what tags are exported by default.
  +
  +<P>
  +The second pair exports only the tags passed as arguments. 
   
  -<P><A NAME="anchor238"></A>
  +<P>
   The third pair describes the case where the caller does not want any
   symbols to be imported.
   
  -<P><A NAME="anchor239"></A>
  +<P>
   <CODE>import()</CODE> is not a builtin function, it's just an ordinary static method call into
   the ``<CODE>MyModule</CODE>'' package to tell the module to import the list of features back into the
   current package. See the Exporter manpage for more information.
   
  -<P><A NAME="anchor240"></A>
  +<P>
   When you write your own modules, always remember that it's better to use <CODE>@EXPORT_OK</CODE> instead of <CODE>@EXPORT</CODE>, since the former doesn't export symbols unless it was asked to. Exports
   pollute the namespace of the module user. Also avoid short or common symbol
   names to reduce the risk of name clashes.
   
  -<P><A NAME="anchor241"></A>
  +<P>
   When functions and variables aren't exported you can still access them
   using their full names, like <CODE>$My::Module::bar</CODE> or
   <CODE>$My::Module::foo()</CODE>. By convention you can use a leading underscore on names to informally
   indicate that they are <EM>internal</EM> and not for public use.
   
  -<P><A NAME="anchor242"></A>
  -There's a corresponding ``<CODE>no</CODE>'' command that un-imports symbols imported by <CODE>use</CODE>, i.e., it calls <CODE>unimport Module LIST</CODE> instead of
  -<CODE>import()</CODE>.
  +<P>
  +There's a corresponding ``<CODE>no</CODE>'' command that un-imports symbols imported by <CODE>use</CODE>, i.e., it calls <CODE>Module-&gt;unimport(LIST)</CODE>
  +instead of <CODE>import()</CODE>.
   
  -<P><A NAME="anchor243"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="do_">do()</A></H2></CENTER>
  -<P><A NAME="anchor244"></A>
  +<P>
   While <CODE>do()</CODE> behaves almost identically to
   <CODE>require(),</CODE> it reloads the file unconditionally. It doesn't
   check <CODE>%INC</CODE> to see whether the file was already loaded.
   
  -<P><A NAME="anchor245"></A>
  +<P>
   If <CODE>do()</CODE> cannot read the file, it returns <CODE>undef</CODE> and sets <CODE>$!</CODE> to report the error. If <CODE>do()</CODE> can read the file but cannot
  -compile it, it returns <CODE>undef</CODE> and sets an error message in <CODE>$@</CODE>. If the file is successfully compiled, <CODE>do()</CODE> returns the value
  +compile it, it returns <CODE>undef</CODE> and puts an error message in <CODE>$@</CODE>. If the file is successfully compiled, <CODE>do()</CODE> returns the value
   of the last expression evaluated.
   
  -<P><A NAME="anchor246"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H1><A NAME="Using_Global_Variables_and_Shari">Using Global Variables and Sharing Them Between Modules/Packages</A></H1></CENTER>
  -<P><A NAME="anchor247"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="Making_Variables_Global">Making Variables Global</A></H2></CENTER>
  -<P><A NAME="anchor248"></A>
  -When you first wrote <CODE>$x</CODE> in your code you created a global
  -variable. It is visible everywhere in the file you have used it. If you
  -defined it inside a package, it is visible inside the package. But it will
  -work only if you do not use <CODE>strict</CODE> pragma and you <STRONG>HAVE</STRONG> to use this pragma if you want to run your scripts under mod_perl. Read <A HREF="././porting.html#The_strict_pragma">The strict pragma</A> to find out why.
  +<P>
  +When you first wrote <CODE>$x</CODE> in your code you created a (package) global variable. It is visible
  +everywhere in your program, although if used in a package other than the
  +package in which it was declared (<CODE>main::</CODE> by default), it must be referred to with its fully qualified name, unless
  +you have imported this variable with <CODE>import().</CODE> This will work
  +only if you do not use <CODE>strict</CODE> pragma; but you <EM>have</EM> to use this pragma if you want to run your scripts under mod_perl. Read <A HREF="././porting.html#The_strict_pragma">The strict pragma</A> to find out why. 
   
  -<P><A NAME="anchor249"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="Making_Variables_Global_With_str">Making Variables Global With strict Pragma On</A></H2></CENTER>
  -<P><A NAME="anchor250"></A>
  +<P>
   First you use :
  +
  +<P>
   
  -<P><A NAME="anchor251"></A>
  -<PRE>  use strict;
  -</PRE>
  -<P><A NAME="anchor252"></A>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  use strict;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Then you use:
  +
  +<P>
   
  -<P><A NAME="anchor253"></A>
  -<PRE> use vars qw($scalar %hash @array);
  -</PRE>
  -<P><A NAME="anchor254"></A>
  -Starting from this moment the variables are global only in the package
  -where you defined them. If you want to share global variables between
  -packages, here is what you can do.
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor255"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre> use vars qw($scalar %hash @array);</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +This declares the named variables as package globals in the current
  +package. They may be referred to within the same file and package with
  +their unqualified names; and in different files/packages with their fully
  +qualified names. 
  +
  +<P>
  +With perl5.6 you can use the <CODE>our</CODE> operator instead:
  +
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  our qw($scalar %hash @array);</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +If you want to share package global variables between packages, here is
  +what you can do.
  +
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="Using_Exporter_pm_to_Share_Globa">Using Exporter.pm to Share Global Variables</A></H2></CENTER>
  -<P><A NAME="anchor256"></A>
  +<P>
   Assume that you want to share the <CODE>CGI.pm</CODE> object (I will use <CODE>$q</CODE>) between your modules. For example, you create it in <CODE>script.pl</CODE>, but you want it to be visible in <CODE>My::HTML</CODE>. First, you make <CODE>$q</CODE>
   global.
  +
  +<P>
   
  -<P><A NAME="anchor257"></A>
  -<PRE>  script.pl:
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  script.pl:
     ----------------
     use vars qw($q);
     use CGI;
     use lib qw(.); 
     use My::HTML qw($q); # My/HTML.pm is in the same dir as script.pl
  -  $q = new CGI;
  +  $q = CGI-&gt;new;
     
     My::HTML::printmyheader();
  -  ----------------
  -</PRE>
  -<P><A NAME="anchor258"></A>
  +  ----------------</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Note that we have imported <CODE>$q</CODE> from <CODE>My::HTML</CODE>. And <CODE>My::HTML</CODE>
   does the export of <CODE>$q</CODE>:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor259"></A>
  -<PRE>  My/HTML.pm
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  My/HTML.pm
     ----------------
     package My::HTML;
     use strict;
  @@ -1648,36 +2779,72 @@
       print $q-&gt;header();
     }
     1;
  -  -------------------
  -</PRE>
  -<P><A NAME="anchor260"></A>
  +  -------------------</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   So the <CODE>$q</CODE> is shared between the <CODE>My::HTML</CODE> package and
   <CODE>script.pl</CODE>. It will work vice versa as well, if you create the object in <CODE>My::HTML</CODE> but use it in <CODE>script.pl</CODE>. You have true sharing, since if you change <CODE>$q</CODE> in <CODE>script.pl</CODE>, it will be changed in <CODE>My::HTML</CODE> as well.
   
  -<P><A NAME="anchor261"></A>
  +<P>
   What if you need to share <CODE>$q</CODE> between more than two packages? For example you want My::Doc to share <CODE>$q</CODE> as well.
   
  -<P><A NAME="anchor262"></A>
  +<P>
   You leave <CODE>My::HTML</CODE> untouched, and modify <EM>script.pl</EM> to include:
  +
  +<P>
   
  -<P><A NAME="anchor263"></A>
  -<PRE> use My::Doc qw($q);
  -</PRE>
  -<P><A NAME="anchor264"></A>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre> use My::Doc qw($q);</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Then you write <CODE>My::Doc</CODE> exactly like <CODE>My::HTML</CODE> - except of course that the content is different :).
   
  -<P><A NAME="anchor265"></A>
  +<P>
   One possible pitfall is when you want to use <CODE>My::Doc</CODE> in both
   <CODE>My::HTML</CODE> and <EM>script.pl</EM>. Only if you add
  +
  +<P>
   
  -<P><A NAME="anchor266"></A>
  -<PRE>  use My::Doc qw($q);
  -</PRE>
  -<P><A NAME="anchor267"></A>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  use My::Doc qw($q);</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   into <CODE>My::HTML</CODE> will <CODE>$q</CODE> be shared. Otherwise <CODE>My::Doc</CODE> will not share <CODE>$q</CODE> any more. To make things clear here is the code:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor268"></A>
  -<PRE>  script.pl:
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  script.pl:
     ----------------
     use vars qw($q);
     use CGI;
  @@ -1687,10 +2854,22 @@
     $q = new CGI;
     
     My::HTML::printmyheader();
  -  ----------------
  -</PRE>
  -<P><A NAME="anchor269"></A>
  -<PRE>  My/HTML.pm
  +  ----------------</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  My/HTML.pm
     ----------------
     package My::HTML;
     use strict;
  @@ -1714,10 +2893,22 @@
       My::Doc::printtitle('Guide');
     }
     1;
  -  -------------------
  -</PRE>
  -<P><A NAME="anchor270"></A>
  -<PRE>  My/Doc.pm
  +  -------------------</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  My/Doc.pm
     ----------------
     package My::Doc;
     use strict;
  @@ -1739,50 +2930,72 @@
       print $q-&gt;h1($title);
     }
     1;
  -  -------------------
  -</PRE>
  -<P><A NAME="anchor271"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +  -------------------</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="Using_the_Perl_Aliasing_Feature_">Using the Perl Aliasing Feature to Share Global Variables</A></H2></CENTER>
  -<P><A NAME="anchor272"></A>
  +<P>
   As the title says you can import a variable into a script or module without
   using <CODE>Exporter.pm</CODE>. I have found it useful to keep all the configuration variables in one
   module <CODE>My::Config</CODE>. But then I have to export all the variables in order to use them in other
   modules, which is bad for two reasons: polluting other packages' name
  -spaces with extra tags which increase the memory requirements; and adding
  +spaces with extra tags which increases the memory requirements; and adding
   the overhead of keeping track of what variables should be exported from the
   configuration module and what imported, for some particular package. I
   solve this problem by keeping all the variables in one hash <CODE>%c</CODE> and exporting that. Here is an example of <CODE>My::Config</CODE>:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor273"></A>
  -<PRE>  package My::Config;
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  package My::Config;
     use strict;
     use vars qw(%c);
     %c = (
       # All the configs go here
       scalar_var =&gt; 5,
     
  -    array_var  =&gt; [
  -                   foo,
  -                   bar,
  -                  ],
  +    array_var  =&gt; [qw(foo bar)],
     
       hash_var   =&gt; {
                      foo =&gt; 'Foo',
                      bar =&gt; 'BARRR',
                     },
     );
  -  1;
  -</PRE>
  -<P><A NAME="anchor274"></A>
  +  1;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Now in packages that want to use the configuration variables I have either
   to use the fully qualified names like <CODE>$My::Config::test</CODE>, which I dislike or import them as described in the previous section. But
   hey, since we have only one variable to handle, we can make things even
   simpler and save the loading of the <CODE>Exporter.pm</CODE> package. We will use the Perl aliasing feature for exporting and saving the
   keystrokes:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor275"></A>
  -<PRE>  package My::HTML;
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  package My::HTML;
     use strict;
     use lib qw(.);
       # Global Configuration now aliased to global %c
  @@ -1791,197 +3004,353 @@
     *c = \%My::Config::c;
     
       # Now you can access the variables from the My::Config
  -  print $c{scalar_val};
  -  print $c{array_val}[0];
  -  print $c{hash_val}{foo};
  -</PRE>
  -<P><A NAME="anchor276"></A>
  +  print $c{scalar_var};
  +  print $c{array_var}[0];
  +  print $c{hash_var}{foo};</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Of course <CODE>$c</CODE> is global everywhere you use it as described
   above, and if you change it somewhere it will affect any other packages you
   have aliased <CODE>$My::Config::c</CODE> to.
   
  -<P><A NAME="anchor277"></A>
  +<P>
   Note that aliases work either with global or <CODE>local()</CODE> vars - you cannot write:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor278"></A>
  -<PRE>  my *c = \%My::Config::c;
  -</PRE>
  -<P><A NAME="anchor279"></A>
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  my *c = \%My::Config::c; # ERROR!</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Which is an error. But you can write:
   
  -<P><A NAME="anchor280"></A>
  -<PRE>  local *c = \%My::Config::c;
  -</PRE>
  -<P><A NAME="anchor281"></A>
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  local *c = \%My::Config::c;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   For more information about aliasing, refer to the Camel book, second
   edition, pages 51-52.
   
  -<P><A NAME="anchor282"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H1><A NAME="The_Scope_of_the_Special_Perl_Va">The Scope of the Special Perl Variables</A></H1></CENTER>
  -<P><A NAME="anchor283"></A>
  -Special Perl variables like <CODE>$|</CODE> (buffering), <CODE>$^T</CODE> (time), <CODE>$^W</CODE>
  -(warnings), <CODE>$/</CODE> (input record separator), <CODE>$\</CODE> (output record separator) and many more are all global variables. This
  -means that you cannot scope them with <CODE>my().</CODE> Only
  -<CODE>local()</CODE> is permitted to do that. Since the child server
  +<P>
  +Special Perl variables like <CODE>$|</CODE> (buffering), <CODE>$^T</CODE> (script's start time), <CODE>$^W</CODE> (warnings mode), <CODE>$/</CODE> (input record separator), <CODE>$\</CODE>
  +(output record separator) and many more are all true global variables; they
  +do not belong to any particular package (not even <CODE>main::</CODE>) and are universally available. This means that if you change them, you
  +change them anywhere across the entire program; furthermore you cannot
  +scope them with <CODE>my().</CODE> However you can <CODE>local()ise</CODE>
  +them which means that any changes you apply will only last until the end of
  +the enclosing scope. In the mod_perl situation where the child server
   doesn't usually exit, if in one of your scripts you modify a global
   variable it will be changed for the rest of the process' life and will
  -affect all the scripts executed by the same process.
  +affect all the scripts executed by the same process. Therefore localising
  +these variables is highly recommended, I'd say mandatory.
   
  -<P><A NAME="anchor284"></A>
  +<P>
   We will demonstrate the case on the input record separator variable. If you
  -undefine this variable, a diamond operator will suck in the whole file at
  -once if you have enough memory. Remembering this you should never write
  -code like the example below.
  +undefine this variable, the diamond operator (readline) will suck in the
  +whole file at once if you have enough memory. Remembering this you should
  +never write code like the example below.
  +
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
   
  -<P><A NAME="anchor285"></A>
  -<PRE>  $/ = undef; 
  +	<td>
  +	  <pre>  $/ = undef; # BAD!
     open IN, &quot;file&quot; ....
       # slurp it all into a variable
  -  $all_the_file = &lt;IN&gt;;
  -</PRE>
  -<P><A NAME="anchor286"></A>
  +  $all_the_file = &lt;IN&gt;;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   The proper way is to have a <CODE>local()</CODE> keyword before the special
   variable is changed, like this:
   
  -<P><A NAME="anchor287"></A>
  -<PRE>  local $/ = undef; 
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  local $/ = undef; 
     open IN, &quot;file&quot; ....
       # slurp it all inside a variable
  -  $all_the_file = &lt;IN&gt;;
  -</PRE>
  -<P><A NAME="anchor288"></A>
  +  $all_the_file = &lt;IN&gt;;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   But there is a catch. <CODE>local()</CODE> will propagate the changed value
  -to any of the code below it. The modified value will be in effect until the
  -script terminates, unless it is changed again somewhere else in the script.
  +to the code below it. The modified value will be in effect until the script
  +terminates, unless it is changed again somewhere else in the script.
   
  -<P><A NAME="anchor289"></A>
  +<P>
   A cleaner approach is to enclose the whole of the code that is affected by
   the modified variable in a block, like this:
  +
  +<P>
   
  -<P><A NAME="anchor290"></A>
  -<PRE>  {
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  {
       local $/ = undef; 
       open IN, &quot;file&quot; ....
         # slurp it all inside a variable
       $all_the_file = &lt;IN&gt;;
  -  }
  -</PRE>
  -<P><A NAME="anchor291"></A>
  +  }</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   That way when Perl leaves the block it restores the original value of the <CODE>$/</CODE> variable, and you don't need to worry elsewhere in your program about its
   value being changed here.
   
  -<P><A NAME="anchor292"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +Note that if you call a subroutine after you've set a global variable but
  +within the enclosing block, the global variable will be visible with its
  +new value inside the subroutine.
  +
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H1><A NAME="Compiled_Regular_Expressions">Compiled Regular Expressions</A></H1></CENTER>
  -<P><A NAME="anchor293"></A>
  +<P>
   When using a regular expression that contains an interpolated Perl
   variable, if it is known that the variable (or variables) will not change
   during the execution of the program, a standard optimization technique is
  -to add the <CODE>/o</CODE> modifier to the regexp pattern. This directs the compiler to build the
  +to add the <CODE>/o</CODE> modifier to the regex pattern. This directs the compiler to build the
   internal table once, for the entire lifetime of the script, rather than
   every time the pattern is executed. Consider:
  +
  +<P>
   
  -<P><A NAME="anchor294"></A>
  -<PRE>  my $pat = '^foo$'; # likely to be input from an HTML form field
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  my $pat = '^foo$'; # likely to be input from an HTML form field
     foreach( @list ) {
       print if /$pat/o;
  -  }
  -</PRE>
  -<P><A NAME="anchor295"></A>
  -This is usually a big win in loops over lists, or when using <CODE>grep()</CODE>
  -or <CODE>map()</CODE> operators.
  -
  -<P><A NAME="anchor296"></A>
  -In long-lived mod_perl scripts, however, the variable can change according
  -to the invocation and this can pose a problem. The first invocation of a
  -fresh httpd child will compile the regex and perform the search correctly.
  +  }</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +This is usually a big win in loops over lists, or when using the
  +<CODE>grep()</CODE> or <CODE>map()</CODE> operators.
  +
  +<P>
  +In long-lived mod_perl scripts, however, the variable may change with each
  +invocation and this can pose a problem. The first invocation of a fresh
  +httpd child will compile the regex and perform the search correctly.
   However, all subsequent uses by that child will continue to match the
   original pattern, regardless of the current contents of the Perl variables
   the pattern is supposed to depend on. Your script will appear to be broken.
   
  -<P><A NAME="anchor297"></A>
  +<P>
   There are two solutions to this problem:
   
  -<P><A NAME="anchor298"></A>
  +<P>
   The first is to use <CODE>eval q//</CODE>, to force the code to be evaluated each time. Just make sure that the eval
   block covers the entire loop of processing, and not just the pattern match
   itself.
   
  -<P><A NAME="anchor299"></A>
  +<P>
   The above code fragment would be rewritten as: 
   
  -<P><A NAME="anchor300"></A>
  -<PRE>  my $pat = '^foo$';
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  my $pat = '^foo$';
     eval q{
       foreach( @list ) {
         print if /$pat/o;
       }
  -  }
  -</PRE>
  -<P><A NAME="anchor301"></A>
  +  }</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Just saying:
  +
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
   
  -<P><A NAME="anchor302"></A>
  -<PRE>  foreach( @list ) {
  +	<td>
  +	  <pre>  foreach( @list ) {
       eval q{ print if /$pat/o; };
  -  }
  -</PRE>
  -<P><A NAME="anchor303"></A>
  -is going to be a horribly expensive proposition. 
  +  }</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +means that we recompile the regex for every element in the list even though
  +the regex doesn't change.
   
  -<P><A NAME="anchor304"></A>
  +<P>
   You can use this approach if you require more than one pattern match
   operator in a given section of code. If the section contains only one
   operator (be it an <CODE>m//</CODE> or <CODE>s///</CODE>), you can rely on the property of the null pattern, that reuses the last
   pattern seen. This leads to the second solution, which also eliminates the
   use of eval.
   
  -<P><A NAME="anchor305"></A>
  +<P>
   The above code fragment becomes: 
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor306"></A>
  -<PRE>  my $pat = '^foo$';
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  my $pat = '^foo$';
     &quot;something&quot; =~ /$pat/; # dummy match (MUST NOT FAIL!)
     foreach( @list ) {
       print if //;
  -  }
  -</PRE>
  -<P><A NAME="anchor307"></A>
  +  }</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   The only gotcha is that the dummy match that boots the regular expression
   engine must absolutely, positively succeed, otherwise the pattern will not
   be cached, and the <CODE>//</CODE> will match everything. If you can't count on fixed text to ensure the match
   succeeds, you have two possibilities.
   
  -<P><A NAME="anchor308"></A>
  +<P>
   If you can guarantee that the pattern variable contains no meta-characters
   (things like *, +, ^, $...), you can use the dummy match:
  +
  +<P>
   
  -<P><A NAME="anchor309"></A>
  -<PRE>  &quot;$pat&quot; =~ /\Q$pat\E/; # guaranteed if no meta-characters present
  -</PRE>
  -<P><A NAME="anchor310"></A>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  $pat =~ /\Q$pat\E/; # guaranteed if no meta-characters present</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   If there is a possibility that the pattern can contain meta-characters, you
   should search for the pattern or the non-searchable \377 character as
   follows:
  +
  +<P>
   
  -<P><A NAME="anchor311"></A>
  -<PRE>  &quot;\377&quot; =~ /$pat|^\377$/; # guaranteed if meta-characters present
  -</PRE>
  -<P><A NAME="anchor312"></A>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  &quot;\377&quot; =~ /$pat|^\377$/; # guaranteed if meta-characters present</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Another approach:
   
  -<P><A NAME="anchor313"></A>
  -It depends on the complexity of the regexp to which you apply this
  -technique. One common usage where a compiled regexp is usually more
  +<P>
  +It depends on the complexity of the regex to which you apply this
  +technique. One common usage where a compiled regex is usually more
   efficient is to ``<EM>match any one of a group of patterns</EM>'' over and over again.
   
  -<P><A NAME="anchor314"></A>
  +<P>
   Maybe with a helper routine, it's easier to remember. Here is one slightly
  -modified from Jeffery Friedl's example in his book ``<EM>Mastering Regex</EM>''.
  +modified from Jeffery Friedl's example in his book ``<EM>Mastering Regular Expressions</EM>''.
  +
  +<P>
   
  -<P><A NAME="anchor315"></A>
  -<PRE>  #####################################################
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  #####################################################
     # Build_MatchMany_Function
     # -- Input:  list of patterns
     # -- Output: A code ref which matches its $_[0]
  @@ -1994,13 +3363,25 @@
       my $matchsub = eval &quot;sub { $expr }&quot;;
       die &quot;Failed in building regex @R: $@&quot; if $@;
       $matchsub;
  -  }
  -</PRE>
  -<P><A NAME="anchor316"></A>
  +  }</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Example usage:
   
  -<P><A NAME="anchor317"></A>
  -<PRE>  @some_browsers = qw(Mozilla Lynx MSIE AmigaVoyager lwp libwww);
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  @some_browsers = qw(Mozilla Lynx MSIE AmigaVoyager lwp libwww);
     $Known_Browser=Build_MatchMany_Function(@some_browsers);
     
     while (&lt;ACCESS_LOG&gt;) {
  @@ -2010,39 +3391,54 @@
         print STDERR &quot;Unknown Browser: $browser\n&quot;;
       }
       # ...
  -  }
  -</PRE>
  -<P><A NAME="anchor318"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +  }</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H1><A NAME="Exception_Handling_for_mod_perl">Exception Handling for mod_perl</A></H1></CENTER>
  -<P><A NAME="anchor319"></A>
  -Provided here are some guidelines for clean(er) exception handling for mod_perl usage, although the technique presented
  -here applies to all of your Perl programming.
  +<P>
  +Here are some guidelines for clean(er) exception handling in mod_perl, although the technique presented can be
  +applied to all of your Perl programming.
   
  -<P><A NAME="anchor320"></A>
  +<P>
   The reasoning behind this document is the current broken status of
  -<CODE>$SIG{__DIE__}</CODE> in the perl core - see both the perl5-porters and mod_perl mailing list
  +<CODE>$SIG{__DIE__}</CODE> in the perl core - see both the perl5-porters and the mod_perl mailing list
   archives for details on this discussion. (It's broken in at least Perl
   v5.6.0 and probably in later versions as well.)
   
  -<P><A NAME="anchor321"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="Trapping_Exceptions_in_Perl">Trapping Exceptions in Perl</A></H2></CENTER>
  -<P><A NAME="anchor322"></A>
  +<P>
   To trap an exception in Perl we use the <CODE>eval{}</CODE> construct. Many people initially make the mistake that this is the same as
   the <CODE>eval
   EXPR</CODE> construct, which compiles and executes code at run time, but that's not the
   case. <CODE>eval{}</CODE> compiles at compile time, just like the rest of your code, and has next to
   zero run-time penalty.
   
  -<P><A NAME="anchor323"></A>
  -When in an eval block, if the code executing <CODE>die()'s</CODE> for some
  -reason, rather than terminating your code, the exception is <EM>caught</EM> and the program is allowed to examine that exception and make decisions
  -based on it. The full construct looks like this:
  +<P>
  +When in an eval block, if the code being executed <CODE>die()'s</CODE> for
  +any reason, an exception is thrown. This exception can be caught by
  +examining the <CODE>$@</CODE> variable immediately after the eval block; if
  +<CODE>$@</CODE> is true then an exception occurred and <CODE>$@</CODE> contains the exception in the form of a string. The full construct looks
  +like this:
  +
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
   
  -<P><A NAME="anchor324"></A>
  -<PRE>  eval 
  -  {
  +	<td>
  +	  <pre>  eval {
         # Some code here
     }; # Note important semi-colon there
     if ($@) # $@ contains the exception that was thrown
  @@ -2052,35 +3448,104 @@
     else # optional
     {
         # No exception was thrown
  -  }
  -</PRE>
  -<P><A NAME="anchor325"></A>
  +  }</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Most of the time when you see these exception handlers there is no else
   block, because it tends to be OK if the code didn't throw an exception.
   
  -<P><A NAME="anchor326"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +Perl's exception handling is similar to that of other languages, though it
  +may not seem so at first sight:
  +
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  Perl                             Other language
  +  -------------------------------  ------------------------------------
  +  eval {                           try {
  +    # execute here                   // execute here
  +    # raise our own exception:       // raise our own exception:
  +    die &quot;Oops&quot; if /error/;           if(oops==1){throw Exception.Oops;}
  +    # execute more                   // execute more
  +  } ;                              }
  +  if($@) {                         catch {
  +    # handle exceptions              switch( Exception.id ) {
  +    if( $@ =~ /Fail/ ) {               Fail : fprintf( stderr, &quot;Failed\n&quot; ) ;
  +        print &quot;Failed\n&quot; ;                    break ;
  +    }
  +    elsif( $@ =~ /Oops/ ) {            Oops : throw Exception ;
  +        # Pass it up the chain                 
  +        die if $@ =~ /Oops/;
  +    }
  +    else {                             default :
  +        # handle all other           }
  +        # exceptions here          }
  +    }                              // If we got here all is OK or handled
  +  }
  +  else { # optional
  +    # all is well
  +  }
  +  # all is well or has been handled</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="Alternative_Exception_Handling_T">Alternative Exception Handling Techniques</A></H2></CENTER>
  -<P><A NAME="anchor327"></A>
  +<P>
   An often suggested method for handling global exceptions in mod_perl, and
  -other perl programs in general, is a <STRONG>__DIE__</STRONG> handler, which can be setup by either assigning a function name as a string
  -to
  +other perl programs in general, is a <STRONG>__DIE__</STRONG> handler, which can be set up by either assigning a function name as a
  +string to
   <CODE>$SIG{__DIE__}</CODE> (not particularly recommended, because of the possible namespace clashes)
   or assigning a code reference to
  -<CODE>$SIG{__DIE__}</CODE>, the usual way of doing so is to use an anonymous subroutine:
  +<CODE>$SIG{__DIE__}</CODE>. The usual way of doing so is to use an anonymous subroutine:
   
  -<P><A NAME="anchor328"></A>
  -<PRE>  $SIG{__DIE__} = sub { print &quot;Eek - we died with:\n&quot;, $_[0]; };
  -</PRE>
  -<P><A NAME="anchor329"></A>
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  $SIG{__DIE__} = sub { print &quot;Eek - we died with:\n&quot;, $_[0]; };</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   The current problem with this is that <CODE>$SIG{__DIE__}</CODE> is a global setting in your script, so while you can potentially hide away
   your exceptions in some external module, the execution of <CODE>$SIG{__DIE__}</CODE>
   is fairly magical, and interferes not just with your code, but with all
   code in every module you import. Beyond the magic involved,
   <CODE>$SIG{__DIE__}</CODE> actually interferes with perl's normal exception handling mechanism, the <CODE>eval{}</CODE> construct. Witness:
  +
  +<P>
   
  -<P><A NAME="anchor330"></A>
  -<PRE>  $SIG{__DIE__} = sub { print &quot;handler\n&quot;; };
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  $SIG{__DIE__} = sub { print &quot;handler\n&quot;; };
     
     eval {
         print &quot;In eval\n&quot;;
  @@ -2088,49 +3553,89 @@
     };
     if ($@) {
         print &quot;Caught exception: $@&quot;;
  -  }
  -</PRE>
  -<P><A NAME="anchor331"></A>
  +  }</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   The code unfortunately prints out:
   
  -<P><A NAME="anchor332"></A>
  -<PRE>  In eval
  -  handler
  -</PRE>
  -<P><A NAME="anchor333"></A>
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  In eval
  +  handler</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Which isn't quite what you would expect, especially if that
   <CODE>$SIG{__DIE__}</CODE> handler is hidden away deep in some other module that you didn't know
   about. There are work arounds however. One is to localise <CODE>$SIG{__DIE__}</CODE> in every exception trap you write:
  +
  +<P>
   
  -<P><A NAME="anchor334"></A>
  -<PRE>  eval {
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  eval {
         local $SIG{__DIE__};
         ...
  -  };
  -</PRE>
  -<P><A NAME="anchor335"></A>
  +  };</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Obviously this just doesn't scale - you don't want to be doing that for
   every exception trap in your code, and it's a slow down. A second work
   around is to check in your handler if you are trying to catch this
   exception:
  +
  +<P>
   
  -<P><A NAME="anchor336"></A>
  -<PRE>  $SIG{__DIE__} = sub {
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  $SIG{__DIE__} = sub {
         die $_[0] if $^S;
         print &quot;handler\n&quot;;
  -  };
  -</PRE>
  -<P><A NAME="anchor337"></A>
  +  };</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   However this won't work under <CODE>Apache::Registry</CODE> - you're always in an eval block there!
   
  -<P><A NAME="anchor338"></A>
  +<P>
   You should warn people about this danger of <CODE>$SIG{__DIE__}</CODE> and inform them of better ways to code. The following material is an
  -attempt to just that.
  +attempt to do just that.
   
  -<P><A NAME="anchor339"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="Better_Exception_Handling">Better Exception Handling</A></H2></CENTER>
  -<P><A NAME="anchor340"></A>
  +<P>
   The <CODE>eval{}</CODE> construct in itself is a fairly weak way to handle exceptions as strings.
   There's no way to pass more information in your exception, so you have to
   handle your exception in more than one place - at the location the error
  @@ -2139,16 +3644,17 @@
   (unless of course all you want your exception handler to do is dump the
   error to the browser).
   
  -<P><A NAME="anchor341"></A>
  +<P>
   A little known fact about exceptions in perl 5.005 is that you can call die
   with an object. The exception handler receives that object in
   <CODE>$@</CODE>. This is how you are advised to handle exceptions now, as it provides an
   extremely flexible and scalable exceptions solution.
   
  -<P><A NAME="anchor342"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H3><A NAME="A_Little_Housekeeping">A Little Housekeeping</A></H3></CENTER>
  -<P><A NAME="anchor343"></A>
  +<P>
   First though, before we delve into the details, a little housekeeping is in
   order. Most, if not all, mod_perl programs consist of a main routine that
   is entered, and then dispatches itself to a routine depending on the
  @@ -2156,16 +3662,25 @@
   your <CODE>main()</CODE> function, in a mod_perl handler this is your
   <CODE>handler()</CODE> function/method.
   
  -<P><A NAME="anchor344"></A>
  -In order for you to be able to use exception handling to its best extent
  +<P>
  +In order for you to be able to use exception handling to its best advantage
   you need to change your script to have some sort of global exception
   handling. This is much more trivial than it sounds. If you're using <CODE>Apache::Registry</CODE> to emulate CGI you might consider wrapping your entire script in one big
   eval block, but I would discourage that. A better method would be to
   modularise your script into discrete function calls, one of which should be
   a dispatch routine:
  +
  +<P>
   
  -<P><A NAME="anchor345"></A>
  -<PRE>  #!/usr/bin/perl -w
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  #!/usr/bin/perl -w
     # Apache::Registry script
     
     eval {
  @@ -2180,14 +3695,26 @@
     sub catch {
         my $exception = shift;
         ...
  -  }
  -</PRE>
  -<P><A NAME="anchor346"></A>
  +  }</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   This is easier with an ordinary mod_perl handler as it is natural to have
   separate functions, rather than a long run-on script:
   
  -<P><A NAME="anchor347"></A>
  -<PRE>  MyHandler.pm
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  MyHandler.pm
     ------------
     sub handler {
         my $r = shift;
  @@ -2206,23 +3733,36 @@
     sub catch {
         my $exception = shift;
         ...
  -  }
  -</PRE>
  -<P><A NAME="anchor348"></A>
  +  }</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Now that the skeleton code is setup, let's create an exception class,
   making use of Perl 5.005's ability to throw exception objects.
   
  -<P><A NAME="anchor349"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H3><A NAME="An_Exception_Class">An Exception Class</A></H3></CENTER>
  -<P><A NAME="anchor350"></A>
  +<P>
   This is a really simple exception class, that does nothing but contain
   information. A better implementation would probably also handle its own
   exception conditions, but that would be more complex, requiring separate
   packages for each exception type.
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor351"></A>
  -<PRE>  My/Exception.pm
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  My/Exception.pm
     ---------------
     package My::Exception;
     
  @@ -2248,60 +3788,97 @@
         }
     }
     
  -  1;
  -</PRE>
  -<P><A NAME="anchor352"></A>
  +  1;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   OK, so this is all highly magical, but what does it do? It creates a simple
   package that we can import and use as follows:
   
  -<P><A NAME="anchor353"></A>
  -<PRE>  use My::Exception;
  -  
  -  die My::Exception-&gt;SomeException( foo =&gt; &quot;bar&quot; );
  -</PRE>
  -<P><A NAME="anchor354"></A>
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  use My::Exception;
  +  
  +  die My::Exception-&gt;SomeException( foo =&gt; &quot;bar&quot; );</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   The exception class tracks exactly where we died from using the
   <CODE>caller()</CODE> mechanism, it also caches exception classes so that
   <CODE>AUTOLOAD</CODE> is only called the first time (in a given process) an exception of a
   particular type is thrown (particularly relevant under mod_perl).
   
  -<P><A NAME="anchor355"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="Catching_Uncaught_Exceptions">Catching Uncaught Exceptions</A></H2></CENTER>
  -<P><A NAME="anchor356"></A>
  +<P>
   What about exceptions that are thrown outside of your control? We can fix
   this using one of two possible methods. The first is to override die
   globally using the old magical <CODE>$SIG{__DIE__}</CODE>, and the second, is the cleaner non-magical method of overriding the
   global <CODE>die()</CODE> method to your own <CODE>die()</CODE> method that
   throws an exception that makes sense to your application.
   
  -<P><A NAME="anchor357"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H3><A NAME="Using_SIG_DIE_">Using $SIG{__DIE__}</A></H3></CENTER>
  -<P><A NAME="anchor358"></A>
  +<P>
   Overloading using <CODE>$SIG{__DIE__}</CODE> in this case is rather simple, here's some code:
  +
  +<P>
   
  -<P><A NAME="anchor359"></A>
  -<PRE>  $SIG{__DIE__} = sub {
  -      my $err = shift;
  -      if(!ref $err) {
  -          $err = My::Exception-&gt;UnCaught(text =&gt; $err);
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  $SIG{__DIE__} = sub {
  +      if(!ref($_[0])) {
  +          $err = My::Exception-&gt;UnCaught(text =&gt; join('', @_));
         }
         die $err;
  -  };
  -</PRE>
  -<P><A NAME="anchor360"></A>
  +  };</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   All this does is catch your exception and re-throw it. It's not as
   dangerous as we stated earlier that <CODE>$SIG{__DIE__}</CODE> can be, because we're actually re-throwing the exception, rather than
   catching it and stopping there.
   
  -<P><A NAME="anchor361"></A>
  +<P>
   There's only one slight buggette left, and that's if some external code
   <CODE>die()'ing</CODE> catches the exception and tries to do string
   comparisons on the exception, as in:
  +
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
   
  -<P><A NAME="anchor362"></A>
  -<PRE>  eval {
  +	<td>
  +	  <pre>  eval {
         ... # some code
         die &quot;FATAL ERROR!\n&quot;;
     };
  @@ -2309,89 +3886,144 @@
         if ($@ =~ /^FATAL ERROR/) {
             die $@;
         }
  -  }
  -</PRE>
  -<P><A NAME="anchor363"></A>
  +  }</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   In order to deal with this, we can overload stringification for our
   <CODE>My::Exception::UnCaught</CODE> class:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor364"></A>
  -<PRE>  {
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  {
         package My::Exception::UnCaught;
         use overload '&quot;&quot;' =&gt; \&amp;str;
     
         sub str {
             shift-&gt;{text};
         }
  -  }
  -</PRE>
  -<P><A NAME="anchor365"></A>
  +  }</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   We can now let other code happily continue.
   
  -<P><A NAME="anchor366"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H3><A NAME="Overriding_the_Core_die_Functi">Overriding the Core die() Function</A></H3></CENTER>
  -<P><A NAME="anchor367"></A>
  +<P>
   So what if we don't want to touch <CODE>$SIG{__DIE__}</CODE> at all? We can overcome this by overriding the core die function. This is
   slightly more complex than implementing a <CODE>$SIG{__DIE__}</CODE> handler, but is far less magical, and is the right thing to do, according
   to the
   <A HREF="././help.html#Get_help_with_Perl">perl5-porters mailing list</A>.
   
  -<P><A NAME="anchor368"></A>
  +<P>
   Overriding core functions has to be done from an external package/module.
   So we're going to add that to our <CODE>My::Exception</CODE>
   module. Here's the relevant parts:
   
  -<P><A NAME="anchor369"></A>
  -<PRE>  use vars qw/@ISA @EXPORT/;
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  use vars qw/@ISA @EXPORT/;
     use Exporter;
     
     @EXPORT = qw/die/;
     @ISA = 'Exporter';
     
  +  sub die (@); # prototype to match CORE::die
  +  
     sub import {
         my $pkg = shift;
         $pkg-&gt;export('CORE::GLOBAL', 'die');
         Exporter::import($pkg,@_);
     }
     
  -  sub die {
  +  sub die (@) {
         if (!ref($_[0])) {
             CORE::die My::Exception-&gt;UnCaught(text =&gt; join('', @_));
         }
         CORE::die $_[0];
  -  }
  -</PRE>
  -<P><A NAME="anchor370"></A>
  +  }</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   That wasn't so bad, was it? We're relying on Exporter's export function to
   do the hard work for us, exporting the <CODE>die()</CODE> function into the <CODE>CORE::GLOBAL</CODE> namespace. Along with the above overloaded stringification, we now have a
   complete exception system (well, mostly complete. Exception die-hards would
   argue that there's no ``finally'' clause, and no exception stack, but
   that's another topic for another time).
   
  -<P><A NAME="anchor371"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="Some_Uses">Some Uses</A></H2></CENTER>
  -<P><A NAME="anchor372"></A>
  +<P>
   I'm going to come right out and say now: I abuse this system horribly! I
   throw exceptions all over my code, not because I've hit an exceptional bit
   of code, but because I want to get straight back out of the current
   function, without having to have every single level of function call check
   error codes. One way I use this is to return Apache return codes:
  +
  +<P>
   
  -<P><A NAME="anchor373"></A>
  -<PRE>  # paranoid security check
  -  die My::Exception-&gt;RetCode(code =&gt; 204);
  -</PRE>
  -<P><A NAME="anchor374"></A>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  # paranoid security check
  +  die My::Exception-&gt;RetCode(code =&gt; 204);</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Returns a 204 error code (<CODE>HTTP_NO_CONTENT</CODE>), which is caught at my top level exception handler:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor375"></A>
  -<PRE>  if ($@-&gt;isa('My::Exception::RetCode')) {
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  if ($@-&gt;isa('My::Exception::RetCode')) {
         return $@-&gt;{code};
  -  }
  -</PRE>
  -<P><A NAME="anchor376"></A>
  +  }</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   That last return statement is in my <CODE>handler()</CODE> method, so
   that's the return code that Apache actually sends. I have other exception
   handlers in place for sending Basic Authentication headers and Redirect
  @@ -2399,46 +4031,74 @@
   class, which gives me a way to back out completely from where I am, but
   register that as an OK thing to do.
   
  -<P><A NAME="anchor377"></A>
  +<P>
   Why do I go to these extents? After all, code like slashcode (the code
   behind <A HREF="http://slashdot.org">http://slashdot.org</A>) doesn't need
   this sort of thing, so why should my web site? Well it's just a matter of
  -scalability and programmer style really. There's lots of literature out
  +scalability and programmer style really. There's a lot of literature out
   there about exception handling, so I suggest doing some research.
  +
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
  +<CENTER><H2><A NAME="A_Warning">A Warning</A></H2></CENTER>
  +<P>
  +Just a brief warning about this system. Because mod_perl can run several
  +different applications at once, it becomes very important that you only
  +have one exception class that either sets <CODE>$SIG{__DIE__}</CODE>, or overloads <CODE>CORE::die</CODE>. This can be quite problematic, because several different modules might
  +set their own <CODE>$SIG{__DIE__}</CODE>
  +handler, or maybe even overload <CODE>CORE::die</CODE>. For this reason I suggest that you very carefully consider your options
  +for blessing uncaught exceptions into your own exceptions class. Also note
  +that the last module to be imported that overloads <CODE>CORE::die</CODE> will be the one used. In short: Make sure you have a tight policy for
  +controlling exceptions not just for your application--but for your entire
  +server.
   
  -<P><A NAME="anchor378"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="Conclusions">Conclusions</A></H2></CENTER>
  -<P><A NAME="anchor379"></A>
  +<P>
   Here I've demonstrated a simple and scalable (and useful) exception
   handling mechanism, that fits perfectly with your current code, and
  -provides the programmer with excellent means to determine what has happened
  -in his code. Some users might be worried about the overhead of such code.
  -However in use I've found accessing the database to be a much more
  -significant overhead, and this is used in some code delivering to thousands
  -of users.
  +provides the programmer with an excellent means to determine what has
  +happened in his code. Some users might be worried about the overhead of
  +such code. However in use I've found accessing the database to be a much
  +more significant overhead, and this is used in some code delivering to
  +thousands of users.
   
  -<P><A NAME="anchor380"></A>
  +<P>
   For similar exception handling techniques, see the section ``<A HREF="././perl.html#Other_Implementations">Other Implementations</A>''.
   
  -<P><A NAME="anchor381"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="The_My_Exception_class_in_its_e">The My::Exception class in its entirety</A></H2></CENTER>
  -<P><A NAME="anchor382"></A>
  -<PRE>  package My::Exception
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  package My::Exception
     
     use vars qw/@ISA @EXPORT $AUTOLOAD/;
     use Exporter;
     @ISA = 'Exporter';
     @EXPORT = qw/die/;
     
  +  sub die (@);
  +  
     sub import {
         my $pkg = shift;
         $pkg-&gt;export('CORE::GLOBAL', 'die');
         Exporter::import($pkg,@_);
     }
       
  -  sub die {
  +  sub die (@) {
         if (!ref($_[0])) {
             CORE::die My::Exception-&gt;UnCaught(text =&gt; join('', @_));
         }
  @@ -2447,11 +4107,7 @@
     
     {
         package My::Exception::UnCaught;
  -      use overload '&quot;&quot;' =&gt; \&amp;str;
  -  
  -      sub str {
  -          shift-&gt;{text};
  -      }
  +      use overload '&quot;&quot;' =&gt; sub { shift-&gt;{text} } ; 
     }
     
     sub AUTOLOAD {
  @@ -2476,96 +4132,126 @@
         }
     }
     
  -  1;
  -</PRE>
  -<P><A NAME="anchor383"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +  1;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="Other_Implementations">Other Implementations</A></H2></CENTER>
  -<P><A NAME="anchor384"></A>
  -Some users might find it very useful to have a more C++/Java like interface
  -of try/catch functions. These are available in several forms that all work
  -in slightly different ways. See the documentation for each module for
  -details:
  +<P>
  +Some users might find it very useful to have the more C++/Java like
  +interface of try/catch functions. These are available in several forms that
  +all work in slightly different ways. See the documentation for each module
  +for details:
   
   <UL>
   <P><LI><STRONG><A NAME="item_Error">Error.pm</A></STRONG>
  -<P><A NAME="anchor385"></A>
  +<P>
   Graham Barr's excellent OO styled ``try, throw, catch'' module (from
   <A HREF="././download.html#Perl">CPAN</A>).
   
   <P><LI><STRONG><A NAME="item_Exception">Exception.pm and StackTrace.pm</A></STRONG>
  -<P><A NAME="anchor386"></A>
  +<P>
   by Autarch (from <A
   HREF="ftp://ftp.urth.org/pub/">ftp://ftp.urth.org/pub/</A>).
   
  -<P><A NAME="anchor387"></A>
  +<P>
   <CODE>Exception</CODE> a bit cleaner than the AUTOLOAD method from the above examples as it can
   catch typos later on. Plus it lets you create actual class hierarchies for
   your exceptions, which could be nice if you want to create exception
   classes that do more stuff and then inherit from them.
   
   <P><LI><STRONG><A NAME="item_Try">Try.pm</A></STRONG>
  -<P><A NAME="anchor388"></A>
  +<P>
   Tony Olekshy's. Adds an unwind stack. Not on CPAN (yet?).
   
   <P><LI><STRONG><A NAME="item_Exceptions">Exceptions.pm</A></STRONG>
  -<P><A NAME="anchor389"></A>
  -Peter Seibel's <CODE>Exceptions</CODE> module is totally non-functional with modern Perl and has been superseded
  -by Graham Barr's <CODE>Error</CODE> module.
  +<P>
  +Peter Seibel's <CODE>Exceptions</CODE> module doesn't work with modern Perl and has been superceded by Graham
  +Barr's <CODE>Error</CODE> module.
   
   </UL>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -	     The <a href="http://www.modperl.com/">
  -	     <B>Writing Apache Modules with Perl and C</B></a>
  -	     book can be purchased online from <a
  -	     href="http://www.ora.com/catalog/wrapmod/">O'Reilly </a>
  -	     and <a
  -	     href="http://www.amazon.com/exec/obidos/ASIN/156592567X/writinapachemodu">
  -	     Amazon.com</a>.
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   
  -	     <HR>
   
  -	     <B>Your corrections of either technical or grammatical
  +    <p>
  +    <div class="navbar">
  +      <a href="start.html">Prev</a>                                 |
  +      <A HREF="index.html"         >Contents</A> |
  +      <A HREF="index.html#search"  >Search</A>   |
  +      <A HREF="index.html#download">Download</A> |
  +      <a href="install.html">Next</a>
  +    </div>
  +    <p>
  +
  +    <table width="60%" align="center">
  +
  +      <tr>
  +	<td>
  +	  <div class="notice">
  +	  <B>Your corrections of the technical and grammatical
   	     errors are very welcome. You are encouraged to help me
  -	     to improve this guide.  If you have something to
  -	     contribute please <A
  -	     HREF="help.html#Contacting_me"> send it
  +	     improve this guide.  If you have something to contribute
  +	     please <A HREF="help.html#Contacting_me"> send it
   	     directly to me</A>.</B>
  +	  </div>
  +	</td>
  +      </tr>
  +
  +      <tr>
  +	<td>
  +	  <div class="ad">
  +	    The <a href="http://www.modperl.com/">
  +	      <B>Writing Apache Modules with Perl and C</B></a>
  +	    book can be purchased online from <a
  +	      href="http://www.ora.com/catalog/wrapmod/">O'Reilly </a>
  +	    and <a
  +	    href="http://www.amazon.com/exec/obidos/ASIN/156592567X/writinapachemodu">
  +	      Amazon.com</a>.
  +	  </div>
  +	</td>
  +      </tr>
  +
  +</table>
  +
  +<center>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
  +<table cellspacing=2 cellpadding=2>
  +
  +<tr align=center valign=top>
  +<td align=center valign=center>
  +
  +<b><font size=-1>Written by <a
  +href="help.html#Contacting_me">Stas Bekman</a>.<br> Last Modified at 06/05/2000
  +</font></b>
  +<br>
  +
  +</td>
  +
  +<td>
  +
  +<a href="http://perl.apache.org"><img src="images/mod_perl2.jpg"  border=0 alt="mod_perl icon" border=0 height=59 width=150></a>
  +<br>
  +
  +</td>
  +
  +<td>
  +
  +<font size=-2>Use of the Camel for Perl is <br>
  +a trademark of <a href="http://www.ora.com">O'Reilly &amp; Associates</a>,<br>
  +and is used by permission. </font> 
  +<br>
   
  -	     <HR>
  +</td>
   
  -	     [    <A HREF="start.html">Prev</A> |      <A HREF="index.html">Main Page</A> | <A HREF="install.html">Next</A>      ]
  +</tr>
  +</table>
  +</center>
   
  -<CENTER><TABLE CELLSPACING=2 CELLPADDING=2 WIDTH="100%" >
  -<TR ALIGN=CENTER VALIGN=TOP>
  -  <TD ALIGN=CENTER VALIGN=CENTER COLSPAN="3">
  -	     <HR>
  -  </TD>
  -</TR>
  -<TR ALIGN=CENTER VALIGN=TOP>
  -  <TD ALIGN=CENTER VALIGN=CENTER>
  -    <B>
  -      <FONT SIZE=-1>
  -	     Written by <A HREF="help.html#Contacting_me">Stas Bekman</A>.
  -	     <BR>Last Modified at 05/04/2000
  -      </FONT>
  -    </B>
  -  </TD>
  -
  -  <TD>
  -	     <A HREF="http://perl.apache.org"><IMG SRC="images/mod_perl2.jpg" ALT="Mod Perl Icon" BORDER=0 HEIGHT=59 WIDTH=150></A>
  -  </TD>
  -
  -  <TD>
  -    <FONT SIZE=-2>
  -	     Use of the Camel for Perl is <BR>
  -	     a trademark of <A HREF="http://www.ora.com">O'Reilly &amp; Associates</A>,<BR>
  -             and is used by permission. 
  -    </FONT> 
  -  </TD>
  -</TR>
  -</TABLE></CENTER>
  -
  -</BODY>
  -</HTML>
  -	    
  \ No newline at end of file
  +</body>
  +</html>
  
  
  
  1.28      +3224 -1225modperl-site/guide/porting.html
  
  Index: porting.html
  ===================================================================
  RCS file: /home/cvs/modperl-site/guide/porting.html,v
  retrieving revision 1.27
  retrieving revision 1.28
  diff -u -r1.27 -r1.28
  --- porting.html	2000/05/12 22:42:54	1.27
  +++ porting.html	2000/06/07 22:45:36	1.28
  @@ -1,29 +1,37 @@
   <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
  -<HTML>
  -<HEAD>
  -   <TITLE>mod_perl guide: CGI to mod_perl Porting. mod_perl Coding guidelines.</TITLE>
  -   <META NAME="GENERATOR" CONTENT="Pod2HTML [Perl/Linux]">
  -   <META NAME="Author" CONTENT="Stas Bekman">
  -   <META NAME="Description" CONTENT="All Apache/Perl related information: Hints, Guidelines, Scenarios and Troubleshottings">
  -   <META NAME="keywords" CONTENT="mod_perl modperl perl apache cgi webserver speed  fast guide mod_perl apache guide help info faq mod_perl installation cgi troubleshooting help no sex speedup free open source OSS mod_perl apache guide">
  -</HEAD>
  -     <LINK REL=STYLESHEET TYPE="text/css"
  -        HREF="style.css" TITLE="refstyle">
  -     <style type="text/css">
  -     <!-- 
  -        @import url(style.css);
  -     -->
  -     
  -     </style>
  -<BODY BGCOLOR="white">
  +<html>
  +  <head>
  +   <title>mod_perl guide: CGI to mod_perl Porting. mod_perl Coding guidelines.</title>
  +   <meta name="Author" content="Stas Bekman">
  +   <meta name="Description" content="All Apache/Perl related information: Hints, Guidelines, Scenarios and Troubleshottings">
  +   <meta name="keywords" content="mod_perl modperl perl cgi apache webserver speed fast guide mod_perl apache guide help info faq mod_perl installation cgi troubleshooting help no sex speedup free open source OSS mod_perl apache guide">
  +   <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
  +   <meta name="Classification" content="information">
  +   <link href="style.css" rel=stylesheet type="text/css" title="refstyle">
  +  </head>
  +  <body>
  +
  +    <h1 align=center>
  +      <a href="http://perl.apache.org"><img src="images/mod_perl.gif" alt="Mod Perl Icon" border=0 height=30 width=90 align=left></a>
  +      <a href="http://perl.apache.org"><img src="images/mod_perl.gif" alt="Mod Perl Icon" border=0 height=30 width=90 align=right></a>
  +      CGI to mod_perl Porting. mod_perl Coding guidelines.
  +    </h1>
  +    <hr>
  +    <p>
  +    <div class="navbar">
  +      <a href="scenario.html">Prev</a>                                 |
  +      <a href="index.html"         >Contents</a> |
  +      <a href="index.html#search"  >Search</a>   |
  +      <a href="index.html#download">Download</a> |
  +      <a href="performance.html">Next</a>
  +    </div>
  +    <p>
  +
  +    <div class="toc">
  +      
   <A NAME="toc"></A>
  -<H1 ALIGN=CENTER>
  -<A HREF="http://perl.apache.org"><IMG SRC="images/mod_perl.gif" ALT="Mod Perl Icon" BORDER=0 HEIGHT=30 WIDTH=90 ALIGN=LEFT></A>
  -<A HREF="http://perl.apache.org"><IMG SRC="images/mod_perl.gif" ALT="Mod Perl Icon" BORDER=0 HEIGHT=30 WIDTH=90 ALIGN=RIGHT></A>
  -CGI to mod_perl Porting. mod_perl Coding guidelines.</H1>
  -<HR WIDTH="100%">
  -	    [    <A HREF="scenario.html">Prev</A> |      <A HREF="index.html">Main Page</A> | <A HREF="performance.html">Next</A>      ]<HR><!-- INDEX BEGIN -->
  -<P><B><FONT SIZE=-1>Table of Contents:</FONT></B></P>
  +<P><B>Table of Contents:</B></P>
  +
   <UL>
   
   	<LI><A HREF="#Document_Coverage">Document Coverage</A>
  @@ -72,7 +80,7 @@
   	<LI><A HREF="#I_O_is_different">I/O is different</A>
   	<LI><A HREF="#STDIN_STDOUT_and_STDERR_streams">STDIN, STDOUT and STDERR streams</A>
   	<LI><A HREF="#Apache_print_and_CORE_print_">Apache::print() and CORE::print()</A>
  -	<LI><A HREF="#Global_Variables_Persistance">Global Variables Persistance</A>
  +	<LI><A HREF="#Global_Variables_Persistence">Global Variables Persistence</A>
   	<LI><A HREF="#Generating_correct_HTTP_Headers">Generating correct HTTP Headers</A>
   	<LI><A HREF="#NPH_Non_Parsed_Headers_scripts">NPH (Non Parsed Headers) scripts</A>
   	<LI><A HREF="#BEGIN_blocks">BEGIN blocks </A>
  @@ -105,58 +113,74 @@
   	</UL>
   
   </UL>
  -<!-- INDEX END -->
   
  +    </div>
  +
  +    [ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
   <HR>
  +    <table width="60%" align="center">
  +
  +      <tr>
  +	<td>
  +	  <div class="ad">
  +	    The <a href="http://www.modperl.com/">
  +	      <B>Writing Apache Modules with Perl and C</B></a>
  +	    book can be purchased online from <a
  +	      href="http://www.ora.com/catalog/wrapmod/">O'Reilly </a>
  +	    and <a
  +	    href="http://www.amazon.com/exec/obidos/ASIN/156592567X/writinapachemodu">
  +	      Amazon.com</a>.
  +	  </div>
  +	</td>
  +      </tr>
  +
  +      <tr>
  +	<td>
  +	  <div class="notice">
  +	  <B>Your corrections of the technical and grammatical
  +	     errors are very welcome. You are encouraged to help me
  +	     improve this guide.  If you have something to contribute
  +	     please <A HREF="help.html#Contacting_me"> send it
  +	     directly to me</A>.</B>
  +	  </div>
  +	</td>
  +      </tr>
  +
  +</table>
   
  -	     The <a href="http://www.modperl.com/">
  -	     <B>Writing Apache Modules with Perl and C</B></a>
  -	     book can be purchased online from <a
  -	     href="http://www.ora.com/catalog/wrapmod/">O'Reilly </a>
  -	     and <a
  -	     href="http://www.amazon.com/exec/obidos/ASIN/156592567X/writinapachemodu">
  -	     Amazon.com</a>.
  -
  -	     <HR>
  -
  -	       <B>Your corrections of either technical or grammatical
  -	       errors are very welcome. You are encouraged to help me
  -	       to improve this guide.  If you have something to
  -	       contribute please <A
  -	       HREF="help.html#Contacting_me"> send it
  -	       directly to me</A>.
  -	       </B>
  -	       <HR>
  +    
  +
  +	    [ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   
  -	      <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<P><A NAME="anchor0"></A>
  +<P>
   <CENTER><H1><A NAME="Document_Coverage">Document Coverage</A></H1></CENTER>
  -<P><A NAME="anchor1"></A>
  +<P>
   This chapter is relevant to both writing a new CGI script or perl handler
   from scratch and migrating an application from plain CGI to mod_perl.
   
  -<P><A NAME="anchor2"></A>
  +<P>
   It also addresses the situation where the CGI script being ported does the
   job, but is too dirty to be altered easily to run as a mod_perl program. (<CODE>Apache::PerlRun</CODE> mode)
   
  -<P><A NAME="anchor3"></A>
  +<P>
   If you are at the porting stage, you can use this chapter as a reference
   for possible problems you might encounter when running an existing CGI
   script in the new mode.
   
  -<P><A NAME="anchor4"></A>
  +<P>
   If your project schedule is tight, I would suggest converting to mod_perl
   in the following steps: Initially, run all the scripts in the
   <CODE>Apache::PerlRun</CODE> mode. Then as time allows, move them into
   <CODE>Apache::Registry</CODE> mode. Later if you need Apache Perl API functionality you can always add
   it.
   
  -<P><A NAME="anchor5"></A>
  +<P>
   If you are about to write a new CGI script from scratch, it would be a good
   idea to learn about possible mod_perl related pitfalls and to avoid them in
   the first place.
   
  -<P><A NAME="anchor6"></A>
  +<P>
   If you don't need mod_cgi compatibility, it's a good idea to start writing
   using the mod_perl API in first place. This will make your application a
   little bit more efficient and it will be easier to use the full mod_perl
  @@ -164,39 +188,40 @@
   functions and overriden Perl core functions that were reimplemented to work
   better in mod_perl environment.
   
  -<P><A NAME="anchor7"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H1><A NAME="Before_you_start_to_code">Before you start to code</A></H1></CENTER>
  -<P><A NAME="anchor8"></A>
  +<P>
   It can be a good idea to tighten up some of your Perl programming
   practices, since mod_perl doesn't tolerate sloppy programming.
   
  -<P><A NAME="anchor9"></A>
  +<P>
   This chapter relies on a certain level of Perl knowledge. Please read
   through the <A HREF="././perl.html#">Perl Reference</A> chapter and make sure you know the material covered there. This will allow
   me to concentrate on pure mod_perl issues and make them more prominent to
   the experinced Perl programmer, which would otherwise be lost in the sea of
   Perl background notes.
   
  -<P><A NAME="anchor10"></A>
  +<P>
   Additional resources:
   
   <UL>
   <P><LI><STRONG><A NAME="item_Perl">Perl Module Mechanics</A></STRONG>
  -<P><A NAME="anchor11"></A>
  +<P>
   This page describes the mechanics of creating, compiling, releasing, and
   maintaining Perl modules. <A
   HREF="http://world.std.com/~swmcd/steven/perl/module_mechanics.html">http://world.std.com/~swmcd/steven/perl/module_mechanics.html</A>
   
   
  -<P><A NAME="anchor12"></A>
  +<P>
   The information is very relevant to a mod_perl developer.
   
   <P><LI><STRONG><A NAME="item_The">The Eagle Book</A></STRONG>
  -<P><A NAME="anchor13"></A>
  +<P>
   ``Writing Apache Modules with Perl and C'' is a ``must have'' book!
   
  -<P><A NAME="anchor14"></A>
  +<P>
   See the details at <A
   HREF="http://www.modperl.com">http://www.modperl.com</A> .
   
  @@ -204,18 +229,28 @@
   <P><LI><STRONG><A NAME="item__Perl_Cookbook_Book">&quot;Perl Cookbook&quot; Book</A></STRONG>
   <P><LI><STRONG><A NAME="item__Object_Oriented_Perl_Book">&quot;Object Oriented Perl&quot; Book</A></STRONG>
   </UL>
  -<P><A NAME="anchor15"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H1><A NAME="Exposing_Apache_Registry_secret">Exposing Apache::Registry secrets</A></H1></CENTER>
  -<P><A NAME="anchor16"></A>
  +<P>
   Let's start with some simple code and see what can go wrong with it, detect
   bugs and debug them, discuss possible pitfalls and how to avoid them.
   
  -<P><A NAME="anchor17"></A>
  +<P>
   I will use a simple CGI script, that initializes a <CODE>$counter</CODE> to 0, and prints its value to the browser while incrementing it.
  +
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
   
  -<P><A NAME="anchor18"></A>
  -<PRE>  counter.pl:
  +	<td>
  +	  <pre>  counter.pl:
     ----------
     #!/usr/bin/perl -w
     use strict;
  @@ -231,61 +266,101 @@
     sub increment_counter{
       $counter++;
       print &quot;Counter is equal to $counter !\r\n&quot;;
  -  }
  -</PRE>
  -<P><A NAME="anchor19"></A>
  +  }</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   You would expect to see the output:
  +
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
   
  -<P><A NAME="anchor20"></A>
  -<PRE>  Counter is equal to 1 !
  +	<td>
  +	  <pre>  Counter is equal to 1 !
     Counter is equal to 2 !
     Counter is equal to 3 !
     Counter is equal to 4 !
  -  Counter is equal to 5 !
  -</PRE>
  -<P><A NAME="anchor21"></A>
  +  Counter is equal to 5 !</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   And that's what you see when you execute this script the first time. But
   let's reload it a few times... See, suddenly after a few reloads the
   counter doesn't start its count from 1 any more. We continue to reload and
   see that it keeps on growing, but not steadily starting almost randomly at
   10, 10, 10, 15, 20... Weird...
   
  -<P><A NAME="anchor22"></A>
  -<PRE>  Counter is equal to 6 !
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  Counter is equal to 6 !
     Counter is equal to 7 !
     Counter is equal to 8 !
     Counter is equal to 9 !
  -  Counter is equal to 10 !
  -</PRE>
  -<P><A NAME="anchor23"></A>
  +  Counter is equal to 10 !</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   We saw two anomalies in this very simple script: Unexpected increment of
   our counter over 5 and inconsistent growth over reloads. Let's investigate
   this script.
   
  -<P><A NAME="anchor24"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="The_First_Mystery">The First Mystery</A></H2></CENTER>
  -<P><A NAME="anchor25"></A>
  +<P>
   First let's peek into the <CODE>error_log</CODE> file. Since we have enabled the warnings what we see is:
   
  -<P><A NAME="anchor26"></A>
  -<PRE>  Variable &quot;$counter&quot; will not stay shared 
  -  at /home/httpd/perl/conference/counter.pl line 13.
  -</PRE>
  -<P><A NAME="anchor27"></A>
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  Variable &quot;$counter&quot; will not stay shared 
  +  at /home/httpd/perl/conference/counter.pl line 13.</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   The <EM>Variable "$counter" will not stay shared</EM> warning is generated when the script contains a named nested subroutine (a
   named - as opposed to anonymous - subroutine defined inside another
   subroutine) that refers to a lexically scoped variable defined outside this
   nested subroutine. This effect is explained in <A HREF="././perl.html#my_Scoped_Variable_in_Nested_S">my() Scoped Variable in Nested Subroutines</A>.
   
  -<P><A NAME="anchor28"></A>
  +<P>
   Do you see a nested named subroutine in my script? I don't! What's going
   on? Maybe it's a bug? But wait, maybe the perl interpreter sees the script
   in a different way, maybe the code goes through some changes before it
   actually gets executed? The easiest way to check what's actually happening
   is to run the script with a debugger.
   
  -<P><A NAME="anchor29"></A>
  +<P>
   But since we must debug it when it's being executed by the webserver, a
   normal debugger won't help, because the debugger has to be invoked from
   within the webserver. Luckily Doug MacEachern wrote the
  @@ -293,11 +368,20 @@
   <CODE>Apache::DB</CODE> allows you to debug the code interactively, we will do it
   non-interactively.
   
  -<P><A NAME="anchor30"></A>
  +<P>
   Modify the <CODE>httpd.conf</CODE> file in the following way:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor31"></A>
  -<PRE>  PerlSetEnv PERLDB_OPTS &quot;NonStop=1 LineInfo=/tmp/db.out AutoTrace=1 frame=2&quot;
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  PerlSetEnv PERLDB_OPTS &quot;NonStop=1 LineInfo=/tmp/db.out AutoTrace=1 frame=2&quot;
     PerlModule Apache::DB
     &lt;Location /perl&gt;
       PerlFixupHandler Apache::DB
  @@ -305,25 +389,37 @@
       PerlHandler Apache::Registry
       Options ExecCGI
       PerlSendHeader On
  -  &lt;/Location&gt;
  -</PRE>
  -<P><A NAME="anchor32"></A>
  +  &lt;/Location&gt;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Restart the server and issue a request to <EM>counter.pl</EM> as before. On the surface nothing has changed--we still see the correct
   output as before, but two things happened in the background:
   
  -<P><A NAME="anchor33"></A>
  +<P>
   Firstly, the file <EM>/tmp/db.out</EM> was written, with a complete trace of the code that was executed.
   
  -<P><A NAME="anchor34"></A>
  +<P>
   Secondly, <EM>error_log</EM> now contains the real code that was actually executed. This is produced as
   a side effect of reporting the
   <EM>Variable "$counter" will not stay shared at...</EM> warning that we saw earlier.
   
  -<P><A NAME="anchor35"></A>
  +<P>
   Here is the code that was actually executed:
  +
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
   
  -<P><A NAME="anchor36"></A>
  -<PRE>  package Apache::ROOT::perl::conference::counter_2epl;
  +	<td>
  +	  <pre>  package Apache::ROOT::perl::conference::counter_2epl;
     use Apache qw(exit);
     sub handler {
       BEGIN {
  @@ -345,50 +441,74 @@
         $counter++;
         print &quot;Counter is equal to $counter !\r\n&quot;;
       }
  -  }
  -</PRE>
  -<P><A NAME="anchor37"></A>
  +  }</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   The code in the <EM>error.log</EM> wasn't indented. I've indented it for you to stress that the code was
   wrapped inside the <CODE>handler()</CODE> subroutine.
   
  -<P><A NAME="anchor38"></A>
  +<P>
   What do we learn from this?
   
  -<P><A NAME="anchor39"></A>
  +<P>
   Well firstly that every CGI script is cached under a package whose name is
   formed from the <CODE>Apache::ROOT::</CODE> prefix and the relative part of the script's URL (<CODE>perl::conference::counter_2epl</CODE>) by replacing all occurrences of <CODE>/</CODE> with <CODE>::</CODE> and <CODE>.</CODE> with <CODE>_2e</CODE>. That's how mod_perl knows what script should be fetched from the
   cache--each script is just a package with a single subroutine named <CODE>handler</CODE>.
   
  -<P><A NAME="anchor40"></A>
  +<P>
   If we were to add <CODE>use diagnostics</CODE> to the script we would also see a reference in the error text to an inner
   (nested) subroutine--<CODE>increment_counter</CODE> is actually a nested subroutine.
   
  -<P><A NAME="anchor41"></A>
  +<P>
   With mod_perl, each subroutine in every <CODE>Apache::Registry</CODE> script is nested inside the <CODE>handler</CODE> subroutine.
   
  -<P><A NAME="anchor42"></A>
  +<P>
   It's important to understand that the <EM>inner subroutine</EM> effect happens only with code that <CODE>Apache::Registry</CODE> wraps with a declaration of the <CODE>handler</CODE> subroutine. If you put your code into a library or module, which the main
   script <CODE>require()'s</CODE> or <CODE>use()'s,</CODE> this effect
   doesn't occur.
   
  -<P><A NAME="anchor43"></A>
  +<P>
   For example if we put the subroutine <CODE>increment_counter()</CODE> into
   <CODE>mylib.pl</CODE>, save it in the same directory as the main script and
   <CODE>require()</CODE> it, there will be no problem at all. (Don't forget
   the <CODE>1;</CODE>
   at the end of the library or the <CODE>require()</CODE> might fail.)
  +
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
   
  -<P><A NAME="anchor44"></A>
  -<PRE>  mylib.pl:
  +	<td>
  +	  <pre>  mylib.pl:
     ---------
     sub increment_counter{
       $counter++;
       print &quot;Counter is equal to $counter !\r\n&quot;;
     }
  -  1;
  -</PRE>
  -<P><A NAME="anchor45"></A>
  -<PRE>  counter.pl:
  +  1;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  counter.pl:
     ----------
     #!/usr/bin/perl -w
     
  @@ -401,34 +521,58 @@
     
     for (1..5) {
       increment_counter();
  -  }
  -</PRE>
  -<P><A NAME="anchor46"></A>
  +  }</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Unless the script is very short, I tend to write all the code in external
   libraries, and to have only a few lines in the main script. Generally the
   main script simply calls the main function of my library. Usually I call it <CODE>init()</CODE>. I don't worry about nested subroutine effects anymore (unless I create
   them myself :).
   
  -<P><A NAME="anchor47"></A>
  +<P>
   The section '<A HREF="././perl.html#Remedies_for_Inner_Subroutines">Remedies for Inner Subroutines</A>' discusses other possible workarounds for this problem.
   
  -<P><A NAME="anchor48"></A>
  +<P>
   You shouldn't be intimidated by this issue at all, since Perl is your
   friend. Just keep the warnings mode <STRONG>On</STRONG> and Perl will gladly tell you whenever you have this effect, by saying:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor49"></A>
  -<PRE>  Variable &quot;$counter&quot; will not stay shared at ...[snipped]
  -</PRE>
  -<P><A NAME="anchor50"></A>
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  Variable &quot;$counter&quot; will not stay shared at ...[snipped]</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Just don't forget to check your <EM>error_log</EM> file, before going into production!
   
  -<P><A NAME="anchor51"></A>
  +<P>
   By the way, the above example was pretty boring. In my first days of using
   mod_perl, I wrote a simple user registration program. I'll give a very
   simple representation of this program.
   
  -<P><A NAME="anchor52"></A>
  -<PRE>  use CGI;
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  use CGI;
     $q = CGI-&gt;new;
     my $name = $q-&gt;param('name');
     print_response();
  @@ -436,59 +580,63 @@
     sub print_response{
       print &quot;Content-type: text/plain\r\n\r\n&quot;;
       print &quot;Thank you, $name!&quot;;
  -  }
  -</PRE>
  -<P><A NAME="anchor53"></A>
  +  }</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   My boss and I checked the program at the development server and it worked
   OK. So we decided to put it in production. Everything was OK, but my boss
   decided to keep on checking by submitting variations of his profile.
   Imagine the surprise when after submitting his name (let's say ``The Boss''
   :), he saw the response ``Thank you, Stas Bekman!''.
   
  -<P><A NAME="anchor54"></A>
  +<P>
   What happened is that I tried the production system as well. I was new to
   mod_perl stuff, and was so excited with the speed improvement that I didn't
   notice the nested subroutine problem. It hit me. At first I thought that
   maybe Apache had started to confuse connections, returning responses from
   other people's requests. I was wrong of course.
   
  -<P><A NAME="anchor55"></A>
  +<P>
   Why didn't we notice this when we were trying the software on our
   development server? Keep reading and you will understand why.
   
  -<P><A NAME="anchor56"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="The_Second_Mystery">The Second Mystery</A></H2></CENTER>
  -<P><A NAME="anchor57"></A>
  +<P>
   Let's return to our original example and proceed with the second mystery we
   noticed. Why did we see inconsistent results over numerous reloads?
   
  -<P><A NAME="anchor58"></A>
  +<P>
   That's very simple. Every time a server gets a request to process, it hands
   it over one of the children, generally in a round robin fashion. So if you
   have 10 httpd children alive, the first 10 reloads might seem to be correct
   because the effect we've just talked about starts to appear from the second
   re-invocation. Subsequent reloads then return unexpected results.
   
  -<P><A NAME="anchor59"></A>
  +<P>
   Moreover, requests can appear at random and children don't always run the
   same scripts. At any given moment one of the children could have served the
   same script more times than any other, and another may never have run it.
   That's why we saw the strange behavior.
   
  -<P><A NAME="anchor60"></A>
  +<P>
   Now you see why we didn't notice the problem with the user registration
   system in the example. First, we didn't look at the
   <CODE>error_log</CODE>. (As a matter of fact we did, but there were so many warnings in there
   that we couldn't tell what were the important ones and what were not).
   Second, we had too many server children running to notice the problem.
   
  -<P><A NAME="anchor61"></A>
  +<P>
   A workaround is to run the server as a single process. You achieve this by
   invoking the server with the <CODE>-X</CODE> parameter (<CODE>httpd -X</CODE>). Since there are no other servers (children) running, you will see the
   problem on the second reload.
   
  -<P><A NAME="anchor62"></A>
  +<P>
   But before that, let the <CODE>error_log</CODE> help you detect most of the possible errors--most of the warnings can
   become errors, so you should make sure to check every warning that is
   detected by perl, and probably you should write your code in such a way
  @@ -497,49 +645,60 @@
   production server you'll soon run out of disk space if your site is
   popular.
   
  -<P><A NAME="anchor63"></A>
  +<P>
   Of course none of the warnings will be reported if the warning mechanism is
   not turned <STRONG>On</STRONG>. Refer to the section ``<A HREF="././perl.html#Tracing_Warnings_Reports">Tracing Warnings Reports</A>'' to learn about warnings in general and to the ``<A HREF="././porting.html#Warnings">Warnings</A>'' section to learn how to turn them on and off under mod_perl.
   
  -<P><A NAME="anchor64"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H1><A NAME="Sometimes_it_Works_Sometimes_it">Sometimes it Works, Sometimes it Doesn't</A></H1></CENTER>
  -<P><A NAME="anchor65"></A>
  +<P>
   When you start running your scripts under mod_perl, you might find yourself
   in a situation where a script seems to work, but sometimes it screws up.
   And the more it runs without a restart, the more it screws up. Often the
   problem is easily detectable and solvable. You have to test your script
   under a server running in single process mode (<CODE>httpd -X</CODE>).
   
  -<P><A NAME="anchor66"></A>
  +<P>
   Generally the problem is the result of using global variables. Because
   global variables don't change from one script invocation to another unless
   you change them, you can find your scripts do strange things.
   
  -<P><A NAME="anchor67"></A>
  +<P>
   Let's look at three real world examples:
   
  -<P><A NAME="anchor68"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="An_Easy_Break_in">An Easy Break-in</A></H2></CENTER>
  -<P><A NAME="anchor69"></A>
  +<P>
   The first example is amazing--Web Services. Imagine that you enter some
   site where you have an account, perhaps a free email account. Having read
   your own mail you decide to take a look at someone else's.
   
  -<P><A NAME="anchor70"></A>
  +<P>
   You type in the username you want to peek at and a dummy password and try
   to enter the account. On some services this will work!!!
   
  -<P><A NAME="anchor71"></A>
  +<P>
   You say, why in the world does this happen? The answer is simple:
   <STRONG>Global Variables</STRONG>. You have entered the account of someone who happened to be served by the
   same server child as you. Because of sloppy programming, a global variable
   was not reset at the beginning of the program and voila, you can easily
   peek into someone else's email! Here is an example of sloppy code:
  +
  +<P>
   
  -<P><A NAME="anchor72"></A>
  -<PRE>  use vars ($authenticated);
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  use vars ($authenticated);
     my $q = new CGI;
     my $username = $q-&gt;param('username');
     my $passwd   = $q-&gt;param('passwd');
  @@ -556,21 +715,33 @@
       my ($username,$passwd) = @_;
           # some checking
       $authenticated = 1 if SOME_USER_PASSWD_CHECK_IS_OK;
  -  }
  -</PRE>
  -<P><A NAME="anchor73"></A>
  +  }</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Do you see the catch? With the code above, I can type in any valid username
  -and any dummy password and enter that user's account, providing she has
  +and any dummy password and enter that user's account, provided she has
   successfully entered her account before me using the same child process!
   Since <CODE>$authenticated</CODE> is global--if it becomes 1 once, it'll stay 1 for the remainder of the
   child's life!!! The solution is trivial--reset <CODE>$authenticated</CODE> to 0 at the beginning of the program.
   
  -<P><A NAME="anchor74"></A>
  +<P>
   A cleaner solution of course is not to rely on global variables, but rely
   on the return value from the function.
  +
  +<P>
   
  -<P><A NAME="anchor75"></A>
  -<PRE>  my $q = CGI-&gt;new;
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  my $q = CGI-&gt;new;
     my $username = $q-&gt;param('username');
     my $passwd   = $q-&gt;param('passwd');
     my $authenticated = authenticate($username,$passwd);
  @@ -586,37 +757,66 @@
       my ($username,$passwd) = @_;
           # some checking
       return (SOME_USER_PASSWD_CHECK_IS_OK) ? 1 : 0;
  -  }
  -</PRE>
  -<P><A NAME="anchor76"></A>
  +  }</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Of course this example is trivial--but believe me it happens!
   
  -<P><A NAME="anchor77"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="Thinking_mod_cgi">Thinking mod_cgi</A></H2></CENTER>
  -<P><A NAME="anchor78"></A>
  +<P>
   Just another little one liner that can spoil your day, assuming you forgot
   to reset the <CODE>$allowed</CODE> variable. It works perfectly OK in plain mod_cgi:
   
  -<P><A NAME="anchor79"></A>
  -<PRE>  $allowed = 1 if $username eq 'admin';
  -</PRE>
  -<P><A NAME="anchor80"></A>
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  $allowed = 1 if $username eq 'admin';</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   But using mod_perl, and if your system administrator with superuser access
   rights has previously used the system, anybody who is lucky enough to be
   served later by the same child which served your administrator will happen
   to gain the same rights.
   
  -<P><A NAME="anchor81"></A>
  +<P>
   The obvious fix is:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor82"></A>
  -<PRE>  $allowed = $username eq 'admin' ? 1 : 0;
  -</PRE>
  -<P><A NAME="anchor83"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  $allowed = $username eq 'admin' ? 1 : 0;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="Regular_Expression_Memory">Regular Expression Memory</A></H2></CENTER>
  -<P><A NAME="anchor84"></A>
  +<P>
   Another good example is usage of the <STRONG>/o</STRONG> regular expression modifier, which compiles a regular expression once, on
   its first execution, and never compiles it again. This problem can be
   difficult to detect, as after restarting the server each request you make
  @@ -628,93 +828,156 @@
   get a child that has already cached the regex and won't recompile because
   of the <STRONG>/o</STRONG> modifier.
   
  -<P><A NAME="anchor85"></A>
  +<P>
   An example of such a case would be:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor86"></A>
  -<PRE>  my $pat = $q-&gt;param(&quot;keyword&quot;);
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  my $pat = $q-&gt;param(&quot;keyword&quot;);
     foreach( @list ) {
       print if /$pat/o;
  -  }
  -</PRE>
  -<P><A NAME="anchor87"></A>
  +  }</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   To make sure you don't miss these bugs always test your CGI in
   <A HREF="././control.html#Running_a_Server_in_Single_Proce">single process mode</A>.
   
  -<P><A NAME="anchor88"></A>
  +<P>
   To solve this particular <STRONG>/o</STRONG> modifier problem refer to <A HREF="././perl.html#Compiled_Regular_Expressions">Compiled Regular Expressions</A>.
   
  -<P><A NAME="anchor89"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H1><A NAME="Script_s_name_space">Script's name space</A></H1></CENTER>
  -<P><A NAME="anchor90"></A>
  +<P>
   Scripts under <CODE>Apache::Registry</CODE> do not run in package <CODE>main</CODE>, they run in a unique name space based on the requested URI. For example,
   if your URI is <CODE>/perl/test.pl</CODE> the package will be called
   <CODE>Apache::ROOT::perl::test_2epl</CODE>.
   
  -<P><A NAME="anchor91"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H1><A NAME="_INC_and_mod_perl">@INC and mod_perl</A></H1></CENTER>
  -<P><A NAME="anchor92"></A>
  +<P>
   The basic Perl <CODE>@INC</CODE> behaviour is explained in section <A HREF="././perl.html#use_require_do_INC_and">use(), require(), do(), %INC and @INC Explained</A>.
   
  -<P><A NAME="anchor93"></A>
  +<P>
   When running under mod_perl, once the server is up <CODE>@INC</CODE> is frozen and cannot be updated. The only opportunity to <STRONG>temporarily</STRONG> modify
   <CODE>@INC</CODE> is while the script or the module are loaded and compiled for the first
   time. After that its value is reset to the original one. The only way to
   change <CODE>@INC</CODE> permanently is to modify it at Apache startup.
   
  -<P><A NAME="anchor94"></A>
  +<P>
   Two ways to alter <CODE>@INC</CODE> at server startup:
   
   <UL>
   <P><LI>
  -<P><A NAME="anchor95"></A>
  +<P>
   In the configuration file. For example add:
   
  -<P><A NAME="anchor96"></A>
  -<PRE>  PerlSetEnv PERL5LIB /home/httpd/perl
  -</PRE>
  -<P><A NAME="anchor97"></A>
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  PerlSetEnv PERL5LIB /home/httpd/perl</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   or
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor98"></A>
  -<PRE>  PerlSetEnv PERL5LIB /home/httpd/perl:/home/httpd/mymodules
  -</PRE>
  -<P><A NAME="anchor99"></A>
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  PerlSetEnv PERL5LIB /home/httpd/perl:/home/httpd/mymodules</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Note that this setting will be ignored if you have the
   <CODE>PerlTaintMode</CODE> mode turned on.
   
   <P><LI>
  -<P><A NAME="anchor100"></A>
  +<P>
   In the startup file directly alter the <CODE>@INC</CODE>. For example
   
  -<P><A NAME="anchor101"></A>
  -<PRE>  startup.pl
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  startup.pl
     ----------
  -  use lib qw(/home/httpd/perl /home/httpd/mymodules);
  -</PRE>
  -<P><A NAME="anchor102"></A>
  +  use lib qw(/home/httpd/perl /home/httpd/mymodules);</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   and load the startup file from the configuration file by:
   
  -<P><A NAME="anchor103"></A>
  -<PRE>  PerlRequire /path/to/startup.pl
  -</PRE>
  -</UL>
  -<P><A NAME="anchor104"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  PerlRequire /path/to/startup.pl</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    </UL>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H1><A NAME="Reloading_Modules_and_Required_F">Reloading Modules and Required Files</A></H1></CENTER>
  -<P><A NAME="anchor105"></A>
  +<P>
   You might want to read the ``<A HREF="././perl.html#use_require_do_INC_and">use(), require(), do(), %INC and @INC Explained</A>'' before you proceed with this section.
   
  -<P><A NAME="anchor106"></A>
  +<P>
   When you develop plain CGI scripts, you can just change the code, and rerun
   the CGI from your browser. Since the script isn't cached in memory, the
   next time you call it the server starts up a new perl process, which
   recompiles it from scratch. The effects of any modifications you've applied
   are immediately present.
   
  -<P><A NAME="anchor107"></A>
  +<P>
   The situation is different with <CODE>Apache::Registry</CODE>, since the whole idea is to get maximum performance from the server. By
   default, the server won't spend time checking whether any included library
   modules have been changed. It assumes that they weren't, thus saving a few
  @@ -722,7 +985,7 @@
   many modules/libraries you <CODE>use()</CODE> and/or <CODE>require()</CODE>
   in your script.)
   
  -<P><A NAME="anchor108"></A>
  +<P>
   The only check that is done is to see whether your main script has been
   changed. So if you have only scripts which do not <CODE>use()</CODE> or
   <CODE>require()</CODE> other perl modules or packages, there is nothing to
  @@ -730,41 +993,64 @@
   modules, the files you <CODE>use()</CODE> or <CODE>require()</CODE> aren't
   checked for modification and you need to do something about that.
   
  -<P><A NAME="anchor109"></A>
  +<P>
   So how do we get our modperl-enabled server to recognize changes in library
   modules? Well, there are a couple of techniques:
   
  -<P><A NAME="anchor110"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="Restarting_the_server">Restarting the server</A></H2></CENTER>
  -<P><A NAME="anchor111"></A>
  +<P>
   The simplest approach is to restart the server each time you apply some
  -change to your code. See <A HREF="././control.html#Restarting_techniques">Server Restarting techniques</A>.
  +change to your code. See <A HREF="././control.html#Restarting_Techniques">Server Restarting techniques</A>.
   
  -<P><A NAME="anchor112"></A>
  +<P>
   After restarting the server about 100 times, you will tire of it and you
   will look for other solutions.
   
  -<P><A NAME="anchor113"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="Using_Apache_StatINC_for_the_De">Using Apache::StatINC for the Development Process</A></H2></CENTER>
  -<P><A NAME="anchor114"></A>
  +<P>
   Help comes from the <CODE>Apache::StatINC</CODE> module. When Perl pulls a file via <CODE>require(),</CODE> it stores the
   full pathname as a value in the global hash <CODE>%INC</CODE> with the file name as the key.  <CODE>Apache::StatINC</CODE> looks through <CODE>%INC</CODE> and immediately reloads any files that have been updated on disk.
   
  -<P><A NAME="anchor115"></A>
  +<P>
   To enable this module just add two lines to <CODE>httpd.conf</CODE>.
  +
  +<P>
   
  -<P><A NAME="anchor116"></A>
  -<PRE>  PerlModule Apache::StatINC
  -  PerlInitHandler Apache::StatINC
  -</PRE>
  -<P><A NAME="anchor117"></A>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  PerlModule Apache::StatINC
  +  PerlInitHandler Apache::StatINC</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   To be sure it really works, turn on debug mode on your development box by
   adding <CODE>PerlSetVar StatINCDebug On</CODE> to your config file. You end up with something like this:
  +
  +<P>
   
  -<P><A NAME="anchor118"></A>
  -<PRE>  PerlModule Apache::StatINC
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  PerlModule Apache::StatINC
     &lt;Location /perl&gt;
       SetHandler perl-script
       PerlHandler Apache::Registry
  @@ -772,85 +1058,123 @@
       PerlSendHeader On
       PerlInitHandler Apache::StatINC
       PerlSetVar StatINCDebug On
  -  &lt;/Location&gt;
  -</PRE>
  -<P><A NAME="anchor119"></A>
  +  &lt;/Location&gt;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Be aware that only the modules located in <CODE>@INC</CODE> are reloaded on change, and you can change <CODE>@INC</CODE> only before the server has been started (in the startup file).
   
  -<P><A NAME="anchor120"></A>
  +<P>
   Nothing you do in your scripts and modules which are pulled in with
   <CODE>require()</CODE> after server startup will have any effect on <CODE>@INC</CODE>.
   
  -<P><A NAME="anchor121"></A>
  +<P>
   When you write:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor122"></A>
  -<PRE>  use lib qw(foo/bar);
  -</PRE>
  -<P><A NAME="anchor123"></A>
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  use lib qw(foo/bar);</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   <CODE>@INC</CODE> is changed only for the time the code is being parsed and compiled. When
   that's done, <CODE>@INC</CODE> is reset to its original value.
   
  -<P><A NAME="anchor124"></A>
  +<P>
   To make sure that you have set <CODE>@INC</CODE> correctly, configure
   <A HREF="././debug.html#Apache_Status_Embedded_Inter">/perl-status location</A>, fetch <A
   HREF="http://www.example.com/perl-status?inc">http://www.example.com/perl-status?inc</A>
   and look at the bottom of the page, where the contents of <CODE>@INC</CODE> will be shown.
   
  -<P><A NAME="anchor125"></A>
  +<P>
   Notice the following trap:
   
  -<P><A NAME="anchor126"></A>
  +<P>
   While ``<CODE>.</CODE>'' is in <CODE>@INC</CODE>, perl knows to <CODE>require()</CODE> files with pathnames given relative
   to the current (script) directory. After the script has been parsed, the
   server doesn't remember the path!
   
  -<P><A NAME="anchor127"></A>
  +<P>
   So you can end up with a broken entry in <CODE>%INC</CODE> like this:
   
  -<P><A NAME="anchor128"></A>
  -<PRE>  $INC{bar.pl} eq &quot;bar.pl&quot;
  -</PRE>
  -<P><A NAME="anchor129"></A>
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  $INC{bar.pl} eq &quot;bar.pl&quot;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   If you want Apache::StatINC to reload your script--modify <CODE>@INC</CODE> at server startup, or use a full path in the <CODE>require()</CODE> call.
   
  -<P><A NAME="anchor130"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="Configuration_Files_Writing_Dy">Configuration Files: Writing, Dynamically Updating and Reloading</A></H2></CENTER>
  -<P><A NAME="anchor131"></A>
  +<P>
   Checking all the modules in <STRONG>%INC</STRONG> on every request can add a large overhead to server response times, and you
   certainly would not want the <CODE>Apache::StatINC</CODE> module to be enabled in your production site's configuration. But sometimes
   you want a configuration file reloaded when it is updated, without
   restarting the server.
   
  -<P><A NAME="anchor132"></A>
  +<P>
   This is an especially important feature if for example you have a person
   that is allowed to modify some of the tool configuration, but for security
   reasons it's undesirable for him to telnet to the server to restart it.
   
  -<P><A NAME="anchor133"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H3><A NAME="Writing_Configuration_Files">Writing Configuration Files</A></H3></CENTER>
  -<P><A NAME="anchor134"></A>
  +<P>
   Since we are talking about configuration files, I would like to show you
   some good and bad approaches to configuration file writing.
   
  -<P><A NAME="anchor135"></A>
  +<P>
   If you have a configuration file of just a few variables, it doesn't really
   matter how you do it. But generally this is not the case. Configuration
   files tend to grow as a project grows. It's very relevant to projects that
   generate HTML files, since they tend to demand many easily configurable
   parameters, like headers, footers, colors and so on.
   
  -<P><A NAME="anchor136"></A>
  +<P>
   So let's start with the approach that is most often taken by CGI scripts
   writers. All configuration variables are defined in a separate file.
   
  -<P><A NAME="anchor137"></A>
  +<P>
   For example:
  +
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
   
  -<P><A NAME="anchor138"></A>
  -<PRE>  $cgi_dir = &quot;/home/httpd/perl&quot;;
  +	<td>
  +	  <pre>  $cgi_dir = &quot;/home/httpd/perl&quot;;
     $cgi_url = &quot;/perl&quot;;
     $docs_dir = &quot;/home/httpd/docs&quot;;
     $docs_url = &quot;/&quot;;
  @@ -859,43 +1183,70 @@
     ... many more config params here ...
     $color_hint   = &quot;#777777&quot;;
     $color_warn   = &quot;#990066&quot;;
  -  $color_normal = &quot;#000000&quot;;
  -</PRE>
  -<P><A NAME="anchor139"></A>
  +  $color_normal = &quot;#000000&quot;;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   The <CODE>use strict;</CODE> pragma demands that all the variables be declared. When we want to use
   these variables in a mod_perl script we must declare them with <CODE>use vars</CODE> in the script. (Under Perl v5.6.0
   <CODE>our()</CODE> has replaced <CODE>use vars</CODE>.)
   
  -<P><A NAME="anchor140"></A>
  +<P>
   So we start the script with:
   
  -<P><A NAME="anchor141"></A>
  -<PRE>  use strict;
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  use strict;
     use vars qw($cgi_dir $cgi_url $docs_dir $docs_url 
                 ... many more config params here ....
                 $color_hint  $color_warn $color_normal
  -             );
  -</PRE>
  -<P><A NAME="anchor142"></A>
  +             );</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   It is a nightmare to maintain such a script, especially if not all the
   features have been coded yet. You have to keep adding and removing variable
   names. But that's not a big deal.
   
  -<P><A NAME="anchor143"></A>
  +<P>
   Since we want our code clean, we start the configuration file with
   <CODE>use strict;</CODE> as well, so we have to list the variables with <CODE>use
   vars</CODE> pragma here as well. A second list of variables to maintain.
   
  -<P><A NAME="anchor144"></A>
  +<P>
   If you have many scripts, you may get collisions between configuration
   files. One of the best solutions is to declare packages, with unique names
   of course. For example for our configuration file we might declare the
   following package name:
   
  -<P><A NAME="anchor145"></A>
  -<PRE>  package My::Config;
  -</PRE>
  -<P><A NAME="anchor146"></A>
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  package My::Config;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   The moment you add a package declaration and think that you are done, you
   realize that the nightmare has just begun. When you have declared the
   package, you cannot just <CODE>require()</CODE> the file and use the
  @@ -904,7 +1255,7 @@
   <CODE>$My::Config::cgi_url</CODE> instead of just <CODE>$cgi_url</CODE> or to import the needed variables into any script that is going to use
   them.
   
  -<P><A NAME="anchor147"></A>
  +<P>
   Since you don't want to do the extra typing to make the variables fully
   qualified, you'd go for importing approach. But your configuration package
   has to export them first. That means that you have to list all the
  @@ -913,9 +1264,18 @@
   variables. And that's when you have only one script that uses the
   configuration file, in the general case you have many of them. So now our
   example configuration file looks like this:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor148"></A>
  -<PRE>  package My::Config;
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  package My::Config;
     use strict;
     
     BEGIN {
  @@ -942,13 +1302,25 @@
     ... many more config params here ...
     $color_hint   = &quot;#777777&quot;;
     $color_warn   = &quot;#990066&quot;;
  -  $color_normal = &quot;#000000&quot;;
  -</PRE>
  -<P><A NAME="anchor149"></A>
  +  $color_normal = &quot;#000000&quot;;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   And in the code:
  +
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
   
  -<P><A NAME="anchor150"></A>
  -<PRE>  use strict;
  +	<td>
  +	  <pre>  use strict;
     use My::Config qw($cgi_dir $cgi_url $docs_dir $docs_url 
                       ... many more config params here ....
                       $color_hint  $color_warn $color_normal
  @@ -956,30 +1328,54 @@
     use vars       qw($cgi_dir $cgi_url $docs_dir $docs_url 
                       ... many more config params here ....
                       $color_hint  $color_warn $color_normal
  -                   );
  -</PRE>
  -<P><A NAME="anchor151"></A>
  +                   );</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   This approach is especially bad in the context of mod_perl, since exported
   variables add a memory overhead. The more variables exported the more
   memory you use. If we multiply this overhead by the number of servers we
   are going to run, we get a pretty big number which could be used to run a
   few more servers instead.
   
  -<P><A NAME="anchor152"></A>
  +<P>
   As a matter of fact things aren't so bad. You can group your variables, and
   call the groups by special names called tags, which can later be used as
   arguments to the <CODE>import()</CODE> or <CODE>use()</CODE> calls. You are
   probably familiar with:
  +
  +<P>
   
  -<P><A NAME="anchor153"></A>
  -<PRE>  use CGI qw(:standard :html);
  -</PRE>
  -<P><A NAME="anchor154"></A>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  use CGI qw(:standard :html);</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   We can implement this quite easily, with the help of
   <CODE>export_ok_tags()</CODE> from <CODE>Exporter</CODE>. For example:
  +
  +<P>
   
  -<P><A NAME="anchor155"></A>
  -<PRE>  BEGIN {
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  BEGIN {
       use Exporter ();
       use vars qw( @ISA @EXPORT @EXPORT_OK %EXPORT_TAGS);
       @ISA         = qw(Exporter);
  @@ -992,48 +1388,84 @@
       );
       Exporter::export_ok_tags('vars');
       Exporter::export_ok_tags('subs');
  -  }
  -</PRE>
  -<P><A NAME="anchor156"></A>
  +  }</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   You export subroutines exactly like variables, since what's actually being
   exported is a symbol. The definition of these subroutines is not shown
   here.
   
  -<P><A NAME="anchor157"></A>
  +<P>
   Notice that we didn't use <CODE>export_tags(),</CODE> as it exports the
   variables automatically without the user asking for them in first place,
   which is considered bad style. If a module automatically exports variables
   with <CODE>export_tags()</CODE> you can stop this by not exporting at all:
  +
  +<P>
   
  -<P><A NAME="anchor158"></A>
  -<PRE>  use My::Config ();
  -</PRE>
  -<P><A NAME="anchor159"></A>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  use My::Config ();</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   In your code you can now write:
  +
  +<P>
   
  -<P><A NAME="anchor160"></A>
  -<PRE>  use My::Config qw(:subs :vars);
  -</PRE>
  -<P><A NAME="anchor161"></A>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  use My::Config qw(:subs :vars);</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Groups of group tags:
   
  -<P><A NAME="anchor162"></A>
  +<P>
   The <CODE>:all</CODE> tag from <CODE>CGI.pm</CODE> is a group tag of all other groups. It will require a little more effort to
   implement, but you can always save time by looking at the solution in <CODE>CGI.pm</CODE>'s code. It's just a matter of a little code to expand all the groups
   recursively.
   
  -<P><A NAME="anchor163"></A>
  +<P>
   After going through the pain of maintaining a list of variables in a big
   project with a huge configuration file (more than 100 variables) and many
   files actually using them, I came up with a much simpler solution: keeping
   all the variables in a single hash, which is built from references to other
   anonymous scalars, arrays and hashes.
   
  -<P><A NAME="anchor164"></A>
  +<P>
   Now my configuration file looks like this:
  +
  +<P>
   
  -<P><A NAME="anchor165"></A>
  -<PRE>  package My::Config;
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  package My::Config;
     use strict;
     
     BEGIN {
  @@ -1063,29 +1495,44 @@
                  warn   =&gt; &quot;#990066&quot;,
                  normal =&gt; &quot;#000000&quot;,
                 },
  -    );
  -</PRE>
  -<P><A NAME="anchor166"></A>
  +    );</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Good perl style suggests keeping a comma at the end of lists. That's
   because additional items tend to be added to the end of the list. If you
   keep that last comma in place, you don't have to remember to add one when
   you add a new item.
   
  -<P><A NAME="anchor167"></A>
  +<P>
   So now the script looks like this:
  +
  +<P>
   
  -<P><A NAME="anchor168"></A>
  -<PRE>  use strict;
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  use strict;
     use My::Config qw(%c);
     use vars       qw(%c)
     print &quot;Content-type: text/plain\r\n\r\n&quot;;
  -  print &quot;My url docs root: $c{url}{docs}\n&quot;;
  -</PRE>
  -<P><A NAME="anchor169"></A>
  +  print &quot;My url docs root: $c{url}{docs}\n&quot;;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Do you see the difference? The whole mess has gone, there is only one
   variable to worry about.
   
  -<P><A NAME="anchor170"></A>
  +<P>
   There is one small downside to taking this approach: auto-vivification. For
   example, if we wrote <CODE>$c{url}{doc}</CODE> by mistake, perl would silently create this element for us with the value
   <EM>undef</EM>. When we <CODE>use strict;</CODE> Perl will tell us about any misspelling of this kind for a simple scalar,
  @@ -1094,13 +1541,22 @@
   solution to this is to use pseudo-hashes, but they are still considered
   experimental so we won't cover them here.
   
  -<P><A NAME="anchor171"></A>
  +<P>
   The benefits of the hash approach are significant and we can make do even
   better. I would like to get rid of the <CODE>Exporter</CODE> stuff completely. I remove all the exporting code so my config file now
   looks like:
  +
  +<P>
   
  -<P><A NAME="anchor172"></A>
  -<PRE>  package My::Config;
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  package My::Config;
     use strict;
     use vars qw(%c);
     
  @@ -1121,56 +1577,116 @@
                  warn   =&gt; &quot;#990066&quot;,
                  normal =&gt; &quot;#000000&quot;,
                 },
  -    );
  -</PRE>
  -<P><A NAME="anchor173"></A>
  +    );</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   And the code:
  +
  +<P>
   
  -<P><A NAME="anchor174"></A>
  -<PRE>  use strict;
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  use strict;
     use My::Config ();
     print &quot;Content-type: text/plain\r\n\r\n&quot;;
  -  print &quot;My url docs root: $My::Config::c{url}{docs}\n&quot;;
  -</PRE>
  -<P><A NAME="anchor175"></A>
  +  print &quot;My url docs root: $My::Config::c{url}{docs}\n&quot;;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Since we still want to save lots of typing, and since now we need to use a
   fully qualified notation like <CODE>$My::Config::c{url}{docs}</CODE>, let's use the magical Perl aliasing feature. I'll modify the code to be:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor176"></A>
  -<PRE>  use strict;
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  use strict;
     use My::Config ();
     use vars qw(%c);
     *c = \%My::Config::c;
     print &quot;Content-type: text/plain\r\n\r\n&quot;;
  -  print &quot;My url docs root: $c{url}{docs}\n&quot;;
  -</PRE>
  -<P><A NAME="anchor177"></A>
  +  print &quot;My url docs root: $c{url}{docs}\n&quot;;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   I have aliased the <CODE>*c</CODE> glob with <CODE>\%My::Config::c</CODE>, a reference to a hash. From now on, <CODE>%My::Config::c</CODE> and <CODE>%c</CODE> are the same hash and you can read from or modify either of them.
   
  -<P><A NAME="anchor178"></A>
  +<P>
   Just one last little point. Sometimes you see a lot of redundancy in the
   configuration variables, for example:
  +
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
   
  -<P><A NAME="anchor179"></A>
  -<PRE>  $cgi_dir  = &quot;/home/httpd/perl&quot;;
  +	<td>
  +	  <pre>  $cgi_dir  = &quot;/home/httpd/perl&quot;;
     $docs_dir = &quot;/home/httpd/docs&quot;;
  -  $img_dir  = &quot;/home/httpd/docs/images&quot;;
  -</PRE>
  -<P><A NAME="anchor180"></A>
  +  $img_dir  = &quot;/home/httpd/docs/images&quot;;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Now if you want to move the base path <CODE>&quot;/home/httpd&quot;</CODE> into a new place, it demands lots of typing. Of course the solution is:
   
  -<P><A NAME="anchor181"></A>
  -<PRE>  $base     = &quot;/home/httpd&quot;;
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  $base     = &quot;/home/httpd&quot;;
     $cgi_dir  = &quot;$base/perl&quot;;
     $docs_dir = &quot;$base/docs&quot;;
  -  $img_dir  = &quot;$docs_dir/images&quot;;
  -</PRE>
  -<P><A NAME="anchor182"></A>
  +  $img_dir  = &quot;$docs_dir/images&quot;;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   You cannot do the same trick with a hash, since you cannot refer to its
   values before the definition is finished. So this wouldn't work:
  +
  +<P>
   
  -<P><A NAME="anchor183"></A>
  -<PRE>  %c =
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  %c =
       (
        base =&gt; &quot;/home/httpd&quot;,
        dir =&gt; {
  @@ -1178,14 +1694,26 @@
                docs =&gt; &quot;$c{base}/docs&quot;,
                img  =&gt; &quot;$c{base}{docs}/images&quot;,
               },
  -    );
  -</PRE>
  -<P><A NAME="anchor184"></A>
  +    );</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   But nothing stops us from adding additional variables, which are lexically
   scoped with <CODE>my().</CODE> The following code is correct.
  +
  +<P>
   
  -<P><A NAME="anchor185"></A>
  -<PRE>  my $base = &quot;/home/httpd&quot;;
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  my $base = &quot;/home/httpd&quot;;
     %c =
       (
        dir =&gt; {
  @@ -1193,29 +1721,42 @@
                docs =&gt; &quot;$base/docs&quot;,
                img  =&gt; &quot;$base/docs/images&quot;,
               },
  -    );
  -</PRE>
  -<P><A NAME="anchor186"></A>
  +    );</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   You have just learned how to make configuration files easily maintainable,
   and how to save memory by avoiding the export of variables into a script's
   namespace.
   
  -<P><A NAME="anchor187"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H3><A NAME="Reloading_Configuration_Files">Reloading Configuration Files</A></H3></CENTER>
  -<P><A NAME="anchor188"></A>
  +<P>
   First, lets look at a simple case, when we just have to look after a simple
   configuration file like the one below. Imagine a script that tells you who
   is the patch pumpkin of the current Perl release.
   
  -<P><A NAME="anchor189"></A>
  +<P>
   Sidenote: &lt;Pumpkin&gt; A humorous term for the token (notional or real)
   that gives its possessor (the ``pumpking'' or the ``pumpkineer'') exclusive
   access to something, e.g. applying patches to a master copy of some source
   (for which the token is called the ``patch pumpkin'').
   
  -<P><A NAME="anchor190"></A>
  -<PRE>  use CGI ();
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  use CGI ();
     use strict;
     
     my $fname = &quot;Larry&quot;;
  @@ -1224,23 +1765,38 @@
     
     print $q-&gt;header(-type=&gt;'text/html');
     print $q-&gt;p(qq{$fname $lname holds the patch pumpkin
  -               for this perl release.});
  -</PRE>
  -<P><A NAME="anchor191"></A>
  +               for this perl release.});</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   The script has a hardcoded value for the name. It's very simple: initialize
   the CGI object, print the proper HTTP header and tell the world who is the
   current patch pumpkin.
   
  -<P><A NAME="anchor192"></A>
  +<P>
   When the patch pumpkin changes we don't want to modify the script.
   Therefore, we put the <CODE>$fname</CODE> and <CODE>$lname</CODE> variables into a configuration file.
  +
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
   
  -<P><A NAME="anchor193"></A>
  -<PRE>  $fname = &quot;Gurusamy&quot;;
  +	<td>
  +	  <pre>  $fname = &quot;Gurusamy&quot;;
     $lname = &quot;Sarathy&quot;;
  -  1;
  -</PRE>
  -<P><A NAME="anchor194"></A>
  +  1;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Please note that there is no package declaration in the above file, so the
   code will be evaluated in the caller's package or in the <CODE>main::</CODE>
   package if none was declared. This means that the variables <CODE>$fname</CODE>
  @@ -1249,7 +1805,7 @@
   only--you cannot update variables defined lexically (with
   <CODE>my())</CODE> using this technique.
   
  -<P><A NAME="anchor195"></A>
  +<P>
   You have started the server and everything is working properly. After a
   while you decide to modify the configuration. How do you let your running
   server know that the configuration was modified without restarting it?
  @@ -1261,7 +1817,7 @@
   the configuration <CODE>reread_conf()</CODE> and have it accept a single
   argument, which is the relative path to the configuration file.
   
  -<P><A NAME="anchor196"></A>
  +<P>
   <CODE>Apache::Registry</CODE> calls a <CODE>chdir()</CODE> to the script's directory before it starts the
   script's execution. So if your CGI script is invoked under the <CODE>Apache::Registry</CODE> handler you can put the configuration file in the same directory as the
   script. Alternatively you can put the file in a directory below that and
  @@ -1269,8 +1825,17 @@
   file will be found, somehow. Be aware that <CODE>do()</CODE> searches the
   libraries in the directories in <CODE>@INC</CODE>.
   
  -<P><A NAME="anchor197"></A>
  -<PRE>  use vars qw(%MODIFIED);
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  use vars qw(%MODIFIED);
     sub reread_conf{
       my $file = shift;
       return unless $file;
  @@ -1284,13 +1849,16 @@
         }
         $MODIFIED{$file} =  -M _; # Update the MODIFICATION times
       }
  -  } # end of reread_conf
  -</PRE>
  -<P><A NAME="anchor198"></A>
  +  } # end of reread_conf</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Notice that we use the <CODE>==</CODE> comparison operator when checking file's modification timestamp, because
   all we want to know whether the file was changed or not.
   
  -<P><A NAME="anchor199"></A>
  +<P>
   When the <CODE>require(),</CODE> <CODE>use()</CODE> and <CODE>do()</CODE>
   operators successfully return, the file that was passed as an argument is
   inserted into <CODE>%INC</CODE> (the key is the name of the file and the value the path to it).
  @@ -1300,14 +1868,14 @@
   returns true, Perl saves the overhead of code re-reading and re-compiling;
   however calling <CODE>do()</CODE> will (re)load regardless.
   
  -<P><A NAME="anchor200"></A>
  +<P>
   You generally don't notice with plain perl scripts, but in mod_perl it's
   used all the time; after the first request served by a process all the
   files loaded by <CODE>require()</CODE> stay in memory. If the file is
   preloaded at server startup, even the first request doesn't have the
   loading overhead.
   
  -<P><A NAME="anchor201"></A>
  +<P>
   We use <CODE>do()</CODE> to reload the code in this file and not
   <CODE>require()</CODE> because while <CODE>do()</CODE> behaves almost
   indentically to <CODE>require(),</CODE> it reloads the file
  @@ -1316,7 +1884,7 @@
   compile it, it returns <CODE>undef</CODE> and sets an error message in <CODE>$@</CODE>. If the file is successfully compiled, <CODE>do()</CODE> returns the value
   of the last expression evaluated.
   
  -<P><A NAME="anchor202"></A>
  +<P>
   The configuration file can be broken if someone has incorrectly modified
   it. We don't want the whole service that uses that file to be broken, just
   because of that. We trap the possible failure to <CODE>do()</CODE> the file
  @@ -1324,12 +1892,12 @@
   <CODE>do()</CODE> fails to load the file it might be a good idea to send an
   email to the system administrator about the problem.
   
  -<P><A NAME="anchor203"></A>
  +<P>
   Notice however, that since <CODE>do()</CODE> updates <CODE>%INC</CODE> like <CODE>require()</CODE> does, if you are using <CODE>Apache::StatINC</CODE> it will attempt to reload this file before the <CODE>reread_conf()</CODE>
   call. So if the file wouldn't compile, the request will be aborted.  <CODE>Apache::StatINC</CODE> shouldn't be used in production (because it slows things down by
   <CODE>stat()'ing</CODE> all the files listed in <CODE>%INC</CODE>) so this shouldn't be a problem.
   
  -<P><A NAME="anchor204"></A>
  +<P>
   Note that we assume that the entire purpose of this function is to reload
   the configuration if it was changed. This is fail-safe, because if
   something goes wrong we just return without modifying the server
  @@ -1338,7 +1906,7 @@
   of <CODE>return()</CODE> and <CODE>warn()</CODE> with <CODE>die().</CODE>
   If you do that, take a look at the section ``<A HREF="././snippets.html#Redirecting_Errors_to_the_Client">Redirecting Errors to the Client instead of error_log</A>''.
   
  -<P><A NAME="anchor205"></A>
  +<P>
   I used the above approach when I had a huge configuration file that was
   loaded only at server startup, and another little configuration file that
   included only a few variables that could be updated by hand or through the
  @@ -1349,11 +1917,20 @@
   we will see a simple web interface which allows us to modify the
   configuration file without actually breaking it.
   
  -<P><A NAME="anchor206"></A>
  +<P>
   A sample script using the presented subroutine would be:
  +
  +<P>
   
  -<P><A NAME="anchor207"></A>
  -<PRE>  use vars qw(%MODIFIED $fname $lname);
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  use vars qw(%MODIFIED $fname $lname);
     use CGI ();
     use strict;
     
  @@ -1377,25 +1954,29 @@
         }
         $MODIFIED{$file} =  -M _; # Update the MODIFICATION times
       }
  -  } # end of reread_conf
  -</PRE>
  -<P><A NAME="anchor208"></A>
  +  } # end of reread_conf</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Remember that you should be using <CODE>(stat $file)[9]</CODE> instead of <CODE>-M
   $file</CODE> if you are modifying the <CODE>$^M</CODE> variable. In some of my scripts, I reset <CODE>$^M</CODE> to the time of the script invocation with
   <CODE>&quot;$^M = time()&quot;</CODE>. That way I can perform <CODE>-M</CODE> and the similar (<CODE>-A</CODE>, <CODE>-C</CODE>) file status tests relative to the script invocation time, and not the
   time the process was started.
   
  -<P><A NAME="anchor209"></A>
  +<P>
   If your configuration file is more sophisticated and it declares a package
   and exports variables, the above code will work just as well. Even if you
   think that you will have to <CODE>import()</CODE> variables again, when
   <CODE>do()</CODE> recompiles the script the originally imported variables
   get updated with the values from the reloaded code.
   
  -<P><A NAME="anchor210"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H3><A NAME="Dynamically_updating_configurati">Dynamically updating configuration files</A></H3></CENTER>
  -<P><A NAME="anchor211"></A>
  +<P>
   The CGI script below allows a system administrator to dynamically update a
   configuration file through the web interface. Combining this with the code
   we have just seen to reload the modified files, you get a system which is
  @@ -1403,11 +1984,20 @@
   Configuration can be performed from any machine having just a web interface
   (a simple browser connected to the Internet).
   
  -<P><A NAME="anchor212"></A>
  +<P>
   Let's say you have a configuration file like this:
  +
  +<P>
   
  -<P><A NAME="anchor213"></A>
  -<PRE>  package MainConfig;
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  package MainConfig;
     
     use strict;
     use vars qw(%c);
  @@ -1425,16 +2015,19 @@
     
           array    =&gt; [qw( a b c)],
     
  -       );
  -</PRE>
  -<P><A NAME="anchor214"></A>
  +       );</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   You want to make the variables <CODE>name</CODE>, <CODE>release</CODE> and <CODE>comments</CODE>
   dynamically configurable. You want to have a web interface with an input
   form that allows you to modify these variables. Once modified you want to
   update the configuration file and propagate the changes to all the
   currently running processes. Quite a simple task.
   
  -<P><A NAME="anchor215"></A>
  +<P>
   Let's look at the main stages of the implementation. Create a form with
   preset current values of the variables. Let the administrator modify it and
   submit the changes. Validate the submitted information (numeric fields
  @@ -1442,13 +2035,13 @@
   Update the modified value in the memory of the current process. Present the
   form as before but with updated fields if any.
   
  -<P><A NAME="anchor216"></A>
  +<P>
   The only part that seems to be complicated to implement is a configuration
   file update, for a couple of reasons. If updating the file breaks it, the
   whole service won't work. If the file is very big and includes comments and
   complex data structures, parsing the file can be quite a challenge.
   
  -<P><A NAME="anchor217"></A>
  +<P>
   So let's simplify the task. If all we want is to update a few variables,
   why don't we create a tiny configuration file with just those variables? It
   can be modified through the web interface and overwritten each time there
  @@ -1456,7 +2049,7 @@
   updating it. If the main configuration file is changed we don't care, we
   don't depend on it any more.
   
  -<P><A NAME="anchor218"></A>
  +<P>
   The dynamically updated variables are duplicated, they will be in the main
   file and in the dynamic file. We do this to simplify maintainance. When a
   new release is installed the dynamic configuration file won't exist at all.
  @@ -1464,16 +2057,25 @@
   change in the main code is to add a snippet to load this file if it exists
   and was changed.
   
  -<P><A NAME="anchor219"></A>
  +<P>
   This additional code must be executed after the main configuration file has
   been loaded. That way the updated variables will override the default
   values in the main file.
   
  -<P><A NAME="anchor220"></A>
  +<P>
   META: extend on the comments:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor221"></A>
  -<PRE>  # remember to run this code in taint mode
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  # remember to run this code in taint mode
     
     use strict;
     use vars qw($q %c $dynamic_config_file %vars_to_change %validation_rules);
  @@ -1530,10 +2132,22 @@
     # Note that we cannot trust the previous values of the variables
     # since they were presented to the user as hidden form variables,
     # and the user can mangle those. We don't care: it cannot do any
  -  # damage, as we verify each variable by rules which we define.
  -</PRE>
  -<P><A NAME="anchor222"></A>
  -<PRE>  # Process if there is something to process. Will be not called if
  +  # damage, as we verify each variable by rules which we define.</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  # Process if there is something to process. Will be not called if
     # it's invoked a first time to display the form or when the form
     # was submitted but the values weren't modified (we know that by
     # comparing with the previous values of the variables, which are
  @@ -1690,123 +2304,236 @@
           $q-&gt;hr,&quot;\n&quot;,
           $q-&gt;end_html;
     
  -  } # end sub conf_modification_form
  -</PRE>
  -<P><A NAME="anchor223"></A>
  +  } # end sub conf_modification_form</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Once updated the script generates a file like:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor224"></A>
  -<PRE>  $c{release}  =  '5.6';
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  $c{release}  =  '5.6';
     
     $c{name}  =  'Gurusamy Sarathy';
     
     $c{comments}  =  'Perl rules the world!';
     
  -  1;
  -</PRE>
  -<P><A NAME="anchor225"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +  1;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="Reloading_handlers">Reloading handlers</A></H2></CENTER>
  -<P><A NAME="anchor226"></A>
  +<P>
   If you want to reload a perlhandler on each invocation, the following trick
   will do it:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor227"></A>
  -<PRE>  PerlHandler &quot;sub { do 'MyTest.pm'; MyTest::handler(shift) }&quot;
  -</PRE>
  -<P><A NAME="anchor228"></A>
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  PerlHandler &quot;sub { do 'MyTest.pm'; MyTest::handler(shift) }&quot;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   <CODE>do()</CODE> reloads <CODE>MyTest.pm</CODE> on every request.
   
  -<P><A NAME="anchor229"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H1><A NAME="Name_collisions_with_Modules_and">Name collisions with Modules and libs</A></H1></CENTER>
  -<P><A NAME="anchor230"></A>
  -This sections requires an in-depth understanding of <A HREF="././perl.html#use_require_do_INC_and">use(), require(), do(), %INC and @INC </A>.
  +<P>
  +This section requires an in-depth understanding of <A HREF="././perl.html#use_require_do_INC_and">use(), require(), do(), %INC and @INC </A>.
   
  -<P><A NAME="anchor231"></A>
  +<P>
   To make things clear before we go into details: each child process has its
   own <CODE>%INC</CODE> hash which is used to store information about its compiled modules. The
   keys of the hash are the names of the modules and files passed as arguments
   to <CODE>require()</CODE> and <CODE>use().</CODE> The values are the full
   or relative paths to these modules and files.
   
  -<P><A NAME="anchor232"></A>
  +<P>
   Suppose we have <CODE>my-lib.pl</CODE> and <CODE>MyModule.pm</CODE> both located at
   <CODE>/home/httpd/perl/my/</CODE>.
   
   <UL>
   <P><LI>
  -<P><A NAME="anchor233"></A>
  +<P>
   <CODE>/home/httpd/perl/my/</CODE> is in <CODE>@INC</CODE> at server startup.
  +
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
   
  -<P><A NAME="anchor234"></A>
  -<PRE>  require &quot;my-lib.pl&quot;;
  +	<td>
  +	  <pre>  require &quot;my-lib.pl&quot;;
     use MyModule.pm;
     print $INC{&quot;my-lib.pl&quot;},&quot;\n&quot;;
  -  print $INC{&quot;MyModule.pm&quot;},&quot;\n&quot;;
  -</PRE>
  -<P><A NAME="anchor235"></A>
  +  print $INC{&quot;MyModule.pm&quot;},&quot;\n&quot;;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   prints:
   
  -<P><A NAME="anchor236"></A>
  -<PRE>  /home/httpd/perl/my/my-lib.pl
  -  /home/httpd/perl/my/MyModule.pm
  -</PRE>
  -<P><A NAME="anchor237"></A>
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  /home/httpd/perl/my/my-lib.pl
  +  /home/httpd/perl/my/MyModule.pm</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Adding <CODE>use lib</CODE>:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor238"></A>
  -<PRE>  use lib qw(.);
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  use lib qw(.);
     require &quot;my-lib.pl&quot;;
     use MyModule.pm;
     print $INC{&quot;my-lib.pl&quot;},&quot;\n&quot;;
  -  print $INC{&quot;MyModule.pm&quot;},&quot;\n&quot;;
  -</PRE>
  -<P><A NAME="anchor239"></A>
  +  print $INC{&quot;MyModule.pm&quot;},&quot;\n&quot;;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   prints:
   
  -<P><A NAME="anchor240"></A>
  -<PRE>  my-lib.pl
  -  MyModule.pm
  -</PRE>
  -<P><LI>
  -<P><A NAME="anchor241"></A>
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  my-lib.pl
  +  MyModule.pm</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P><LI>
  +<P>
   <CODE>/home/httpd/perl/my/</CODE> isn't in <CODE>@INC</CODE> at server startup.
  +
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
   
  -<P><A NAME="anchor242"></A>
  -<PRE>  require &quot;my-lib.pl&quot;;
  +	<td>
  +	  <pre>  require &quot;my-lib.pl&quot;;
     use MyModule.pm;
     print $INC{&quot;my-lib.pl&quot;},&quot;\n&quot;;
  -  print $INC{&quot;MyModule.pm&quot;},&quot;\n&quot;;
  -</PRE>
  -<P><A NAME="anchor243"></A>
  +  print $INC{&quot;MyModule.pm&quot;},&quot;\n&quot;;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   wouldn't work, since perl cannot find the modules.
   
  -<P><A NAME="anchor244"></A>
  +<P>
   Adding <CODE>use lib</CODE>:
   
  -<P><A NAME="anchor245"></A>
  -<PRE>  use lib qw(.);
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  use lib qw(.);
     require &quot;my-lib.pl&quot;;
     use MyModule.pm;
     print $INC{&quot;my-lib.pl&quot;},&quot;\n&quot;;
  -  print $INC{&quot;MyModule.pm&quot;},&quot;\n&quot;;
  -</PRE>
  -<P><A NAME="anchor246"></A>
  +  print $INC{&quot;MyModule.pm&quot;},&quot;\n&quot;;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   prints:
   
  -<P><A NAME="anchor247"></A>
  -<PRE>  my-lib.pl
  -  MyModule.pm
  -</PRE>
  -</UL>
  -<P><A NAME="anchor248"></A>
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  my-lib.pl
  +  MyModule.pm</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    </UL>
  +<P>
   Let's look at three scripts with faults related to name space. For the
   following discussion we will consider just one individual child process.
   
   <DL>
   <P><DT><STRONG><A NAME="item_Scenario">Scenario 1</A></STRONG><DD>
  -<P><A NAME="anchor249"></A>
  +<P>
   First, You can't have two identical module names running on the same
   server! Only the first one found in a <CODE>use()</CODE> or
   <CODE>require()</CODE> statement will be compiled into the package, the
  @@ -1814,98 +2541,218 @@
   that it's already compiled. This is a direct result of using <CODE>%INC</CODE>, which has keys equal to the names of the modules. Two identical names
   will refer to the same key in the hash. (Refer to the section '<A HREF="././debug.html#Looking_inside_the_server">Looking inside the server</A>' to find out how you can know what is loaded and where.)
   
  -<P><A NAME="anchor250"></A>
  +<P>
   So if you have two different <CODE>Foo</CODE> modules in two different directories and two scripts <CODE>script1.pl</CODE> and <CODE>script2.pl</CODE>, placed like this:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor251"></A>
  -<PRE>  ./tool1/Foo.pm
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  ./tool1/Foo.pm
     ./tool1/tool1.pl
     ./tool2/Foo.pm
  -  ./tool2/tool2.pl
  -</PRE>
  -<P><A NAME="anchor252"></A>
  +  ./tool2/tool2.pl</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Where some sample code could be:
  +
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
   
  -<P><A NAME="anchor253"></A>
  -<PRE>  ./tool1/tool1.pl
  +	<td>
  +	  <pre>  ./tool1/tool1.pl
     ----------------
     use Foo;
     print &quot;Content-type: text/plain\r\n\r\n&quot;;
     print &quot;I'm Script number One\n&quot;;
  -  foo();
  -</PRE>
  -<P><A NAME="anchor254"></A>
  -<PRE>  ./tool1/Foo.pm
  +  foo();</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  ./tool1/Foo.pm
     --------------
     sub foo{
       print &quot;&lt;B&gt;I'm Tool Number One!&lt;/B&gt;\n&quot;;
     }
  -  1;
  -</PRE>
  -<P><A NAME="anchor255"></A>
  -<PRE>  ./tool2/tool2.pl
  +  1;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  ./tool2/tool2.pl
     ----------------
     use Foo;
     print &quot;Content-type: text/plain\r\n\r\n&quot;;
     print &quot;I'm Script number Two\n&quot;;
  -  foo();
  -</PRE>
  -<P><A NAME="anchor256"></A>
  -<PRE>  ./tool2/Foo.pm
  +  foo();</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  ./tool2/Foo.pm
     --------------
     sub foo{
       print &quot;&lt;B&gt;I'm Tool Number Two!&lt;/B&gt;\n&quot;;
     }
  -  1;
  -</PRE>
  -<P><A NAME="anchor257"></A>
  +  1;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Both scripts call <CODE>use Foo;</CODE>. Only the first one called will know about <CODE>Foo</CODE>. When you call the second script it will not know about
   <CODE>Foo</CODE> at all--it's like you've forgotten to write <CODE>use Foo;</CODE>. Run the server in <A HREF="././control.html#Running_a_Server_in_Single_Proce">single server mode</A> to detect this kind of bug immediately.
   
  -<P><A NAME="anchor258"></A>
  +<P>
   You will see the following in the error_log file:
  +
  +<P>
   
  -<P><A NAME="anchor259"></A>
  -<PRE>  Undefined subroutine
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  Undefined subroutine
     &amp;Apache::ROOT::perl::tool2::tool2_2epl::foo called at
  -  /home/httpd/perl/tool2/tool2.pl line 4.
  -</PRE>
  -<P><DT><STRONG>Scenario 2</STRONG><DD>
  -<P><A NAME="anchor260"></A>
  +  /home/httpd/perl/tool2/tool2.pl line 4.</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P><DT><STRONG>Scenario 2</STRONG><DD>
  +<P>
   If the files do not declare a package, the above is true for libraries
   (i.e. <EM>my-lib.pl"</EM>) you <CODE>require()</CODE> as well:
   
  -<P><A NAME="anchor261"></A>
  +<P>
   Suppose that you have a directory structure like this:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor262"></A>
  -<PRE>  ./tool1/config.pl
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  ./tool1/config.pl
     ./tool1/tool1.pl
     ./tool2/config.pl
  -  ./tool2/tool2.pl
  -</PRE>
  -<P><A NAME="anchor263"></A>
  +  ./tool2/tool2.pl</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   and both scripts contain:
  +
  +<P>
   
  -<P><A NAME="anchor264"></A>
  -<PRE>  use lib qw(.);
  -  require &quot;config.pl&quot;;
  -</PRE>
  -<P><A NAME="anchor265"></A>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  use lib qw(.);
  +  require &quot;config.pl&quot;;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   while <EM>./tool1/config.pl</EM> can be something like this:
  +
  +<P>
   
  -<P><A NAME="anchor266"></A>
  -<PRE>  $foo = 0;
  -  1;
  -</PRE>
  -<P><A NAME="anchor267"></A>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  $foo = 0;
  +  1;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   and <EM>./tool2/config.pl</EM>:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor268"></A>
  -<PRE>  $foo = 1;
  -  1;
  -</PRE>
  -<P><A NAME="anchor269"></A>
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  $foo = 1;
  +  1;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   The second scenario is not different from the first, there is almost no
   difference between <CODE>use()</CODE> and <CODE>require()</CODE> if you
   don't have to import some symbols into a calling script. Only the first
  @@ -1914,94 +2761,178 @@
   <CODE>%INC</CODE> already includes the key <EM>"config.pl"</EM>!
   
   <P><DT><STRONG>Scenario 3</STRONG><DD>
  -<P><A NAME="anchor270"></A>
  +<P>
   It is interesting that the following scenario will fail too!
   
  -<P><A NAME="anchor271"></A>
  -<PRE>  ./tool/config.pl
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  ./tool/config.pl
     ./tool/tool1.pl
  -  ./tool/tool2.pl
  -</PRE>
  -<P><A NAME="anchor272"></A>
  +  ./tool/tool2.pl</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   where <CODE>tool1.pl</CODE> and <CODE>tool2.pl</CODE> both <CODE>require()</CODE> the <STRONG>same</STRONG>
   
   <CODE>config.pl</CODE>.
   
   </DL>
  -<P><A NAME="anchor273"></A>
  +<P>
   There are three solutions for this:
   
   <DL>
   <P><DT><STRONG><A NAME="item_Solution">Solution 1</A></STRONG><DD>
  -<P><A NAME="anchor274"></A>
  +<P>
   The first two faulty scenarios can be solved by placing your library
   modules in a subdirectory structure so that they have different path
   prefixes. The file system layout will be something like:
  +
  +<P>
   
  -<P><A NAME="anchor275"></A>
  -<PRE>  ./tool1/Tool1/Foo.pm
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  ./tool1/Tool1/Foo.pm
     ./tool1/tool1.pl
     ./tool2/Tool2/Foo.pm
  -  ./tool2/tool2.pl
  -</PRE>
  -<P><A NAME="anchor276"></A>
  +  ./tool2/tool2.pl</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   And modify the scripts:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor277"></A>
  -<PRE>  use Tool1::Foo;
  -  use Tool2::Foo;
  -</PRE>
  -<P><A NAME="anchor278"></A>
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  use Tool1::Foo;
  +  use Tool2::Foo;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   For <CODE>require()</CODE> (scenario number 2) use the following:
   
  -<P><A NAME="anchor279"></A>
  -<PRE>  ./tool1/tool1-lib/config.pl
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  ./tool1/tool1-lib/config.pl
     ./tool1/tool1.pl
     ./tool2/tool2-lib/config.pl
  -  ./tool2/tool2.pl
  -</PRE>
  -<P><A NAME="anchor280"></A>
  +  ./tool2/tool2.pl</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   And each script contains respectively:
  +
  +<P>
   
  -<P><A NAME="anchor281"></A>
  -<PRE>  use lib qw(.);
  -  require &quot;tool1-lib/config.pl&quot;;
  -</PRE>
  -<P><A NAME="anchor282"></A>
  -<PRE>  use lib qw(.);
  -  require &quot;tool2-lib/config.pl&quot;;
  -</PRE>
  -<P><A NAME="anchor283"></A>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  use lib qw(.);
  +  require &quot;tool1-lib/config.pl&quot;;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  use lib qw(.);
  +  require &quot;tool2-lib/config.pl&quot;;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   This solution isn't good, since while it might work for you now, if you add
   another script that wants to use the same module or
   <CODE>config.pl</CODE> file, it would fail as we saw in the third scenario.
   
  -<P><A NAME="anchor284"></A>
  +<P>
   Let's see some better solutions.
   
   <P><DT><STRONG>Solution 2</STRONG><DD>
  -<P><A NAME="anchor285"></A>
  +<P>
   Another option is to use a full path to the script, so it will be used as a
   key in <CODE>%INC</CODE>;
  +
  +<P>
   
  -<P><A NAME="anchor286"></A>
  -<PRE>  require &quot;/full/path/to/the/config.pl&quot;;
  -</PRE>
  -<P><A NAME="anchor287"></A>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  require &quot;/full/path/to/the/config.pl&quot;;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   This solution solves the problem of the first two scenarios. I was
   surprised that it worked for the third scenario as well!
   
  -<P><A NAME="anchor288"></A>
  +<P>
   With this solution you lose some portability. If you move the tool around
   in the file system you will have to change the base directory or write some
   additional script that will automatically update the hardcoded path after
   it was moved. Of course you will have to remember to invoke it.
   
   <P><DT><STRONG>Solution 3</STRONG><DD>
  -<P><A NAME="anchor289"></A>
  +<P>
   Make sure you read all of this solution.
   
  -<P><A NAME="anchor290"></A>
  +<P>
   Declare a package name in the required files! It should be unique in
   relation to the rest of the package names you use.  <CODE>%INC</CODE> will then use the unique package name for the key. It's a good idea to use
   at least two-level package names for your private modules, e.g. <CODE>MyProject::Carp</CODE> and not <CODE>Carp</CODE>, since the latter will collide with an existing standard package. Even
  @@ -2009,484 +2940,820 @@
   may come along in a later distribution which collides with a name you've
   chosen. Using a two part package name will help avoid this problem.
   
  -<P><A NAME="anchor291"></A>
  +<P>
   Even a better approach is to use three level naming, like
   <CODE>CompanyName::ProjectName::Module</CODE>, which is most unlikely to have conflicts with later Perl releases.
   Foresee problems like this and save yourself future trouble.
   
  -<P><A NAME="anchor292"></A>
  +<P>
   What are the implications of package declaration?
   
  -<P><A NAME="anchor293"></A>
  +<P>
   Without package declarations, it is very convenient to <CODE>use()</CODE>
   or <CODE>require()</CODE> files because all the variables and subroutines
   are part of the <CODE>main::</CODE> package. Any of them can be used as if they are part of the main script.
   With package declarations things are more awkward. You have to use the <CODE>Package::function()</CODE> method to call a subroutine from <CODE>Package</CODE> and to access a global variable <CODE>$foo</CODE> inside the same package you have to write <CODE>$Package::foo</CODE>.
   
  -<P><A NAME="anchor294"></A>
  +<P>
   Lexically defined variables, those declared with <CODE>my()</CODE> inside <CODE>Package</CODE>
   will be inaccessible from outside the package.
   
  -<P><A NAME="anchor295"></A>
  +<P>
   You can leave your scripts unchanged if you import the names of the global
   variables and subroutines into the namespace of package
   <STRONG>main::</STRONG> like this:
  +
  +<P>
   
  -<P><A NAME="anchor296"></A>
  -<PRE>  use Module qw(:mysubs sub_b $var1 :myvars);
  -</PRE>
  -<P><A NAME="anchor297"></A>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  use Module qw(:mysubs sub_b $var1 :myvars);</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   You can export both subroutines and global variables. Note however that
   this method has the disadvantage of consuming more memory for the current
   process.
   
  -<P><A NAME="anchor298"></A>
  +<P>
   See <CODE>perldoc Exporter</CODE> for information about exporting other variables and symbols.
   
  -<P><A NAME="anchor299"></A>
  +<P>
   This completely covers the third scenario. When you use different module
   names in package declarations, as explained above, you cover the first two
   as well.
   
   </DL>
  -<P><A NAME="anchor300"></A>
  +<P>
   See also the <CODE>perlmodlib</CODE> and <CODE>perlmod</CODE> manpages.
   
  -<P><A NAME="anchor301"></A>
  +<P>
   From the above discussion it should be clear that you cannot run
   development and production versions of the tools using the same apache
   server! You have to run a separate server for each. They can be on the same
   machine, but the servers will use different ports.
   
  -<P><A NAME="anchor302"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H1><A NAME="More_package_name_related_issues">More package name related issues</A></H1></CENTER>
  -<P><A NAME="anchor303"></A>
  +<P>
   If you have the following:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor304"></A>
  -<PRE>  PerlHandler Apache::Work::Foo
  -  PerlHandler Apache::Work::Foo::Bar
  -</PRE>
  -<P><A NAME="anchor305"></A>
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  PerlHandler Apache::Work::Foo
  +  PerlHandler Apache::Work::Foo::Bar</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   And you make a request that pulls in <CODE>Apache/Work/Foo/Bar.pm</CODE> first, then the <CODE>Apache::Work::Foo</CODE> package gets defined, so mod_perl does not try to pull in <CODE>Apache/Work/Foo.pm</CODE>
   
   
   
  -<P><A NAME="anchor306"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H1><A NAME="_END_and_DATA_tokens">__END__ and __DATA__ tokens</A></H1></CENTER>
  -<P><A NAME="anchor307"></A>
  +<P>
   <CODE>Apache::Registry</CODE> scripts cannot contain <CODE>__END__</CODE> or <CODE>__DATA__</CODE>
   tokens.
   
  -<P><A NAME="anchor308"></A>
  +<P>
   Why? Because <CODE>Apache::Registry</CODE> scripts are being wrapped into a subroutine called <CODE>handler</CODE>, like the script at URI <CODE>/perl/test.pl</CODE>:
   
  -<P><A NAME="anchor309"></A>
  -<PRE>  print &quot;Content-type: text/plain\r\n\r\n&quot;;
  -  print &quot;Hi&quot;;
  -</PRE>
  -<P><A NAME="anchor310"></A>
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  print &quot;Content-type: text/plain\r\n\r\n&quot;;
  +  print &quot;Hi&quot;;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   When the script is being executed under <CODE>Apache::Registry</CODE> handler, it actually becomes:
   
  -<P><A NAME="anchor311"></A>
  -<PRE>  package Apache::ROOT::perl::test_2epl;
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  package Apache::ROOT::perl::test_2epl;
     use Apache qw(exit);
     sub handler {
       print &quot;Content-type: text/plain\r\n\r\n&quot;;
       print &quot;Hi&quot;;
  -  }
  -</PRE>
  -<P><A NAME="anchor312"></A>
  +  }</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   So if you happen to put an <CODE>__END__</CODE> tag, like:
  +
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
   
  -<P><A NAME="anchor313"></A>
  -<PRE>  print &quot;Content-type: text/plain\r\n\r\n&quot;;
  +	<td>
  +	  <pre>  print &quot;Content-type: text/plain\r\n\r\n&quot;;
     print &quot;Hi&quot;;
     __END__
  -  Some text that wouldn't be normally executed
  -</PRE>
  -<P><A NAME="anchor314"></A>
  +  Some text that wouldn't be normally executed</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   it will be turned into:
   
  -<P><A NAME="anchor315"></A>
  -<PRE>  package Apache::ROOT::perl::test_2epl;
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  package Apache::ROOT::perl::test_2epl;
     use Apache qw(exit);
     sub handler {
       print &quot;Content-type: text/plain\r\n\r\n&quot;;
       print &quot;Hi&quot;;
       __END__
       Some text that wouldn't be normally executed
  -  }
  -</PRE>
  -<P><A NAME="anchor316"></A>
  -and you try to execute this script, you will receive the following warning:
  -
  -<P><A NAME="anchor317"></A>
  -<PRE>  Missing right bracket at .... line 4, at end of line
  -</PRE>
  -<P><A NAME="anchor318"></A>
  +  }</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +and you try to execute this script, you will receive the following error:
  +
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  Missing right bracket at .... line 4, at end of line</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Perl cuts everything after the <CODE>__END__</CODE> tag. The same applies to the <CODE>__DATA__</CODE> tag.
   
  -<P><A NAME="anchor319"></A>
  +<P>
   Also, rememeber that whatever applies to <CODE>Apache::Registry</CODE> scripts, in most cases applies to <CODE>Apache::PerlRun</CODE> scripts.
   
  -<P><A NAME="anchor320"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H1><A NAME="Output_from_system_calls">Output from system calls</A></H1></CENTER>
  -<P><A NAME="anchor321"></A>
  +<P>
   The output of <CODE>system()</CODE>, <CODE>exec()</CODE>, and <CODE>open(PIPE,&quot;|program&quot;)</CODE> calls will not be sent to the browser unless your Perl was configured with
   <CODE>sfio</CODE>.
   
  -<P><A NAME="anchor322"></A>
  +<P>
   You can use backticks as a possible workaround:
  +
  +<P>
   
  -<P><A NAME="anchor323"></A>
  -<PRE>  print `command here`;
  -</PRE>
  -<P><A NAME="anchor324"></A>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  print `command here`;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   But you're throwing performance out the window either way. It's best not to
   fork at all if you can avoid it. See the ``<A HREF="././performance.html#Forking_and_Executing_Subprocess">Forking or Executing subprocesses from mod_perl</A>'' section to learn about implications of forking.
   
  -<P><A NAME="anchor325"></A>
  +<P>
   Also read about <A HREF="././modules.html#Apache_SubProcess">Apache::SubProcess</A> for overriden <CODE>system()</CODE> and <CODE>exec()</CODE> implementations
   that work with mod_perl.
   
  -<P><A NAME="anchor326"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H1><A NAME="Using_format_and_write_">Using format() and write()</A></H1></CENTER>
  -<P><A NAME="anchor327"></A>
  +<P>
   The interface to filehandles which are linked to variables with Perl's
   <CODE>tie()</CODE> function is not yet complete. The <CODE>format()</CODE>
   and <CODE>write()</CODE> functions are missing. If you configure Perl with <CODE>sfio</CODE>, <CODE>write()</CODE> and <CODE>format()</CODE> should work just fine.
   
  -<P><A NAME="anchor328"></A>
  +<P>
   Otherwise you could use <CODE>sprintf()</CODE> to replace
   <CODE>format():</CODE> <CODE>##.##</CODE>
   becomes <CODE>%2.2f</CODE> and <CODE>####.##</CODE> becomes <CODE>%4.2f</CODE>.
   
  -<P><A NAME="anchor329"></A>
  +<P>
   Pad all strings with ("&nbsp;"&nbsp;x&nbsp;80) before using, and set their length with: %.25s for a max 25 char string. Or prefix the string with
   ("&nbsp;"&nbsp;x&nbsp;80) for right-justifying.
   
  -<P><A NAME="anchor330"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H1><A NAME="Terminating_requests_and_process">Terminating requests and processes, the exit() and child_terminate() functions</A></H1></CENTER>
  -<P><A NAME="anchor331"></A>
  +<P>
   Perl's <CODE>exit()</CODE> built-in function cannot be used in mod_perl scripts. Calling it causes the
   mod_perl process to exit (which defeats the purpose of using mod_perl). The <CODE>Apache::exit()</CODE> function should be used instead.
   
  -<P><A NAME="anchor332"></A>
  +<P>
   You might start your scripts by overriding the <CODE>exit()</CODE>
   subroutine (if you use <CODE>Apache::exit()</CODE> directly, you will have a problem testing the script from the shell, unless
   you put <CODE>use Apache ();</CODE> into your code.) I use the following code:
  +
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
   
  -<P><A NAME="anchor333"></A>
  -<PRE>  use subs qw(exit);
  +	<td>
  +	  <pre>  use subs qw(exit);
     # Select the correct exit function
  -  *exit = $ENV{MOD_PERL} ? \&amp;Apache::exit : sub { CORE::exit };
  -</PRE>
  -<P><A NAME="anchor334"></A>
  +  *exit = $ENV{MOD_PERL} ? \&amp;Apache::exit : sub { CORE::exit };</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Now the correct <CODE>exit()</CODE> will always be chosen, whether you run the script under mod_perl, ordinary
   CGI or from the shell.
   
  -<P><A NAME="anchor335"></A>
  +<P>
   Note that if you run the script under <CODE>Apache::Registry</CODE>, <STRONG>The
   Apache function <CODE>exit()</CODE> overrides the Perl core built-in
   function</STRONG>. While you see <CODE>exit()</CODE> listed in the <CODE>@EXPORT_OK</CODE> list of the Apache package, <CODE>Apache::Registry</CODE> does something you don't see and imports this function for you. This means
   that if your script is running under the <CODE>Apache::Registry</CODE> handler you don't have to worry about <CODE>exit().</CODE> The same applies
   to <CODE>Apache::PerlRun</CODE>.
   
  -<P><A NAME="anchor336"></A>
  +<P>
   If you use <CODE>CORE::exit()</CODE> in scripts running under mod_perl, the child will exit, but neither a
   proper exit nor logging will happen on the way. <CODE>CORE::exit()</CODE> cuts off the server's legs.
   
  -<P><A NAME="anchor337"></A>
  +<P>
   Note that <CODE>Apache::exit(Apache::Constants::DONE)</CODE> will cause the server to exit gracefully, completing the logging functions
   and protocol requirements etc. ( Apache::Constants::DONE == -2,
   Apache::Constants::OK == 0.)
   
  -<P><A NAME="anchor338"></A>
  +<P>
   If you need to shut down the child cleanly after the request was completed,
   use the <CODE>$r-&gt;child_terminate</CODE> method. You can call it anywhere in the code, and not just at the ``end''.
   This sets the value of the <CODE>MaxRequestsPerChild</CODE> configuration variable to 1 and clears the <CODE>keepalive</CODE> flag. After the request is serviced, the current connection is broken,
   because of the <CODE>keepalive</CODE> flag, and the parent tells the child to cleanly quit, because <CODE>MaxRequestsPerChild</CODE> is smaller than the number of requests served.
   
  -<P><A NAME="anchor339"></A>
  +<P>
   In an <CODE>Apache::Registry</CODE> script you would do:
   
  -<P><A NAME="anchor340"></A>
  -<PRE>  Apache-&gt;request-&gt;child_terminate;
  -</PRE>
  -<P><A NAME="anchor341"></A>
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  Apache-&gt;request-&gt;child_terminate;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   or in httpd.conf:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor342"></A>
  -<PRE>  PerlFixupHandler &quot;sub { shift-&gt;child_terminate }&quot;
  -</PRE>
  -<P><A NAME="anchor343"></A>
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  PerlFixupHandler &quot;sub { shift-&gt;child_terminate }&quot;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   You would want to use the latter example only if you wanted the child to
   terminate every time the registered handler is called. Probably this is not
   what you want.
   
  -<P><A NAME="anchor344"></A>
  +<P>
   Even if you don't need to call <CODE>child_terminate()</CODE> at the end of
   the request if you want the process to quit afterwards, here is an example
   of assigning the postprocessing handler. You might do this if you wanted to
   execute your own code a moment before the process quits.
   
  -<P><A NAME="anchor345"></A>
  -<PRE>  my $r = shift;
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  my $r = shift;
     $r-&gt;post_connection(\&amp;exit_child);
     sub exit_child{
        # some logic here if needed
       $r-&gt;child_terminate;
  -  }
  -</PRE>
  -<P><A NAME="anchor346"></A>
  +  }</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   The above is the code that is used by the <CODE>Apache::SizeLimit</CODE> module which terminates processes that grow bigger than a value you choose.
   
  -<P><A NAME="anchor347"></A>
  +<P>
   <A HREF="././modules.html#Apache_GTopLimit_Limit_Apache">Apache::GTopLimit</A> (based on
   <EM>libgtop</EM> and <CODE>GTop.pm</CODE>) is a similar module. It does the same thing, plus you can configure it to
   terminate processes when their shared memory shrinks below some specified
   size.
   
  -<P><A NAME="anchor348"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H1><A NAME="die_and_mod_perl">die() and mod_perl</A></H1></CENTER>
  -<P><A NAME="anchor349"></A>
  +<P>
   When you write:
  +
  +<P>
   
  -<P><A NAME="anchor350"></A>
  -<PRE>  open FILE, &quot;foo&quot; or die &quot;Cannot open foo file for reading: $!&quot;;
  -</PRE>
  -<P><A NAME="anchor351"></A>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  open FILE, &quot;foo&quot; or die &quot;Cannot open foo file for reading: $!&quot;;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   in a perl script and execute it--the script would <CODE>die()</CODE> if it
   is unable to open the file, by aborting the script execution, printing the
   death reason and quitting the Perl interpreter.
   
  -<P><A NAME="anchor352"></A>
  +<P>
   You will hardly find a properly written Perl script that doesn't have at
   least one <CODE>die()</CODE> statement in it, if it has to cope with system
   calls and the like.
   
  -<P><A NAME="anchor353"></A>
  +<P>
   A CGI script running under mod_cgi exits on its completion. The Perl
   interperter exits as well. So it doesn't really matter whether the
   interpreter quits because the script died by natural death (when the last
   statement was executed) or was aborted by a <CODE>die()</CODE> statement.
   
  -<P><A NAME="anchor354"></A>
  +<P>
   In mod_perl we don't want the interpreter to quit. We already know that
   when the script completes its chores the interpeter won't quit. There is no
   reason why it should quit when the script has stopped because of
   <CODE>die().</CODE> As a result calling <CODE>die()</CODE> won't quit the
   process.
   
  -<P><A NAME="anchor355"></A>
  +<P>
   And this is how it works--when the <CODE>die()</CODE> gets triggered, it's
   mod_perl's <CODE>$SIG{__DIE__}</CODE> handler that logs the error message and calls Apache::exit() instead of
   CORE::die(). Thus the script stops, but the process doesn't quit.
   
  -<P><A NAME="anchor356"></A>
  +<P>
   Here is an example of such trapping code, although it isn't the real code:
  +
  +<P>
   
  -<P><A NAME="anchor357"></A>
  -<PRE>  $SIG{__DIE__} = sub { print STDERR @_; Apache::exit(); }
  -</PRE>
  -<P><A NAME="anchor358"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  $SIG{__DIE__} = sub { print STDERR @_; Apache::exit(); }</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H1><A NAME="Testing_the_Code_from_the_Shell">Testing the Code from the Shell</A></H1></CENTER>
  -<P><A NAME="anchor359"></A>
  +<P>
   Your CGI scripts will <STRONG>not</STRONG> yet run from the command line unless you use <CODE>CGI::Switch</CODE> or <CODE>CGI.pm</CODE> and have Perl 5.004 or later. They must not make any direct calls to
   Apache's Perl API methods.
   
  -<P><A NAME="anchor360"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H1><A NAME="I_O_is_different">I/O is different</A></H1></CENTER>
  -<P><A NAME="anchor361"></A>
  +<P>
   If you are using Perl 5.004 or later, most CGI scripts can run under
   mod_perl untouched. 
   
  -<P><A NAME="anchor362"></A>
  +<P>
   If you're using 5.003, Perl's built-in <CODE>read()</CODE> and <CODE>print()</CODE>
   functions do not work as they do under CGI. If you're using <CODE>CGI.pm</CODE>, use <CODE>$query-&gt;print</CODE> instead of plain ol' <CODE>print()</CODE>.
   
  -<P><A NAME="anchor363"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H1><A NAME="STDIN_STDOUT_and_STDERR_streams">STDIN, STDOUT and STDERR streams</A></H1></CENTER>
  -<P><A NAME="anchor364"></A>
  +<P>
   In mod_perl both <CODE>STDIN</CODE> and <CODE>STDOUT</CODE> are tied to the socket the request came from. <CODE>STDERR</CODE> is tied to the <EM>error_log</EM> file.
   
  -<P><A NAME="anchor365"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H1><A NAME="Apache_print_and_CORE_print_">Apache::print() and CORE::print()</A></H1></CENTER>
  -<P><A NAME="anchor366"></A>
  +<P>
   Under mod_perl <CODE>CORE::print()</CODE> will redirect its data to
   <CODE>Apache::print()</CODE> since the STDOUT filehandle is tied to the
   <EM>Apache</EM> module. This allows us to run CGI scripts unmodified under
   <CODE>Apache::Registry</CODE> by chaining the output of one content handler to the input of the other
   handler.
   
  -<P><A NAME="anchor367"></A>
  +<P>
   <CODE>Apache::print()</CODE> behaves mostly like the built-in <EM>print()</EM>
   function. In addition it sets a timeout so that if the client connection is
   broken the handler won't wait forever trying to print data downstream to
   the client.
   
  -<P><A NAME="anchor368"></A>
  +<P>
   There is also an optimization built into <CODE>Apache::print()</CODE>. If any of the arguments to the method are scalar references to strings,
   they are automatically dereferenced for you. This avoids needless copying
   of large strings when passing them to subroutines. For example:
  +
  +<P>
   
  -<P><A NAME="anchor369"></A>
  -<PRE> $long_string = &quot;A&quot; x 10000000;
  - $r-&gt;print(\$long_string);
  -</PRE>
  -<P><A NAME="anchor370"></A>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre> $long_string = &quot;A&quot; x 10000000;
  + $r-&gt;print(\$long_string);</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   If you still want to print the reference you can always call:
  +
  +<P>
   
  -<P><A NAME="anchor371"></A>
  -<PRE>  $r-&gt;print(\\$foo);
  -</PRE>
  -<P><A NAME="anchor372"></A>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  $r-&gt;print(\\$foo);</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   or by forcing it into a scalar context:
  +
  +<P>
   
  -<P><A NAME="anchor373"></A>
  -<PRE>  print(scalar($foo));
  -</PRE>
  -<P><A NAME="anchor374"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<CENTER><H1><A NAME="Global_Variables_Persistance">Global Variables Persistance</A></H1></CENTER>
  -<P><A NAME="anchor375"></A>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  print(scalar($foo));</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
  +<CENTER><H1><A NAME="Global_Variables_Persistence">Global Variables Persistence</A></H1></CENTER>
  +<P>
   Since the child process generally doesn't exit before it has serviced
   several requests, global variables persist inside the same process from
   request to request. This means that you must never rely on the value of the
   global variable if it wasn't initialized at the beginning of the request
   processing. See ``<A HREF="././perl.html#Variables_Globally_Lexically_Sc">Variables globally, lexically scoped and fully qualified</A>'' for more info.
   
  -<P><A NAME="anchor376"></A>
  +<P>
   You should avoid using global variables unless it's impossible without
   them, because it will make code development harder and you will have to
   make certain that all the variables are initialized before they are used.
   Use <CODE>my()</CODE> scoped variables wherever you can.
   
  -<P><A NAME="anchor377"></A>
  +<P>
   You should be especially careful with <A HREF="././perl.html#The_Scope_of_the_Special_Perl_Va">Perl Special Variables</A> which cannot be lexically scoped. You have to use <CODE>local()</CODE>
   instead.
   
  -<P><A NAME="anchor378"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H1><A NAME="Generating_correct_HTTP_Headers">Generating correct HTTP Headers</A></H1></CENTER>
  -<P><A NAME="anchor379"></A>
  +<P>
   A HTTP response header consists of at least two fields. HTTP response and
   MIME type header <CODE>Content-type</CODE>:
  +
  +<P>
   
  -<P><A NAME="anchor380"></A>
  -<PRE>  HTTP/1.0 200 OK
  -  Content-Type: text/plain
  -</PRE>
  -<P><A NAME="anchor381"></A>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  HTTP/1.0 200 OK
  +  Content-Type: text/plain</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   After adding one more new line, you can start printing the content. A more
   complete response includes the date timestamp and server type, for example:
  +
  +<P>
   
  -<P><A NAME="anchor382"></A>
  -<PRE>  HTTP/1.0 200 OK
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  HTTP/1.0 200 OK
     Date: Tue, 28 Dec 1999 18:47:58 GMT
     Server: Apache/1.3.10-dev (Unix) mod_perl/1.21_01-dev
  -  Content-Type: text/plain
  -</PRE>
  -<P><A NAME="anchor383"></A>
  +  Content-Type: text/plain</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   To notify that the server was configured with KeepAlive Off, you need to
   tell the client that the connection was closed, with:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor384"></A>
  -<PRE>  Connection: close
  -</PRE>
  -<P><A NAME="anchor385"></A>
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  Connection: close</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   There can be other headers as well, like caching control and others
   specified by the HTTP protocol. You can code the response header with a
   single <CODE>print():</CODE>
   
  -<P><A NAME="anchor386"></A>
  -<PRE>    print qq{HTTP/1.1 200 OK    
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>    print qq{HTTP/1.1 200 OK    
     Date: Tue, 28 Dec 1999 18:49:41 GMT
     Server: Apache/1.3.10-dev (Unix) mod_perl/1.21_01-dev
     Connection: close
     Content-type: text/plain
     
  -    };
  -</PRE>
  -<P><A NAME="anchor387"></A>
  +    };</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   or with a <EM>"here"</EM> style print:
   
  -<P><A NAME="anchor388"></A>
  -<PRE>    print &lt;&lt;EOT;
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>    print &lt;&lt;EOT;
     HTTP/1.1 200 OK    
     Date: Tue, 28 Dec 1999 18:49:41 GMT
     Server: Apache/1.3.10-dev (Unix) mod_perl/1.21_01-dev
     Connection: close
     Content-type: text/plain
     
  -  EOT
  -</PRE>
  -<P><A NAME="anchor389"></A>
  +  EOT</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Notice the double new line at the end. But you have to prepare a timestamp
   string (<CODE>Apache::Util::ht_time()</CODE> does just this) and to know what server you are running under. You needed
   to send only the response MIME type (<CODE>Content-type</CODE>) under mod_cgi, so why would you want to do this manually under mod_perl? 
   
  -<P><A NAME="anchor390"></A>
  +<P>
   Actually sometimes you do want to set some headers manually, but not every
   time. So mod_perl gives you the default set of headers, just like in the
   example above. And if you want to override or add more headers you can do
   that as well. Let's see how to do that.
   
  -<P><A NAME="anchor391"></A>
  +<P>
   When writing your own handlers and scripts with the Perl Apache API the
   proper way to send the HTTP header is with the
   <CODE>send_http_header()</CODE> method. If you need to add or override
   methods you can use the <CODE>headers_out()</CODE> method:
  +
  +<P>
   
  -<P><A NAME="anchor392"></A>
  -<PRE>  $r-&gt;headers_out(&quot;Server&quot; =&gt; &quot;Apache Next Generation 10.0&quot;);
  -  $r-&gt;headers_out(&quot;Date&quot; =&gt; &quot;Tue, 28 Dec 1999 18:49:41 GMT&quot;);
  -</PRE>
  -<P><A NAME="anchor393"></A>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  $r-&gt;headers_out(&quot;Server&quot; =&gt; &quot;Apache Next Generation 10.0&quot;);
  +  $r-&gt;headers_out(&quot;Date&quot; =&gt; &quot;Tue, 28 Dec 1999 18:49:41 GMT&quot;);</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   When you have prepared all the headers you send them with:
  +
  +<P>
   
  -<P><A NAME="anchor394"></A>
  -<PRE>  $r-&gt;send_http_header;
  -</PRE>
  -<P><A NAME="anchor395"></A>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  $r-&gt;send_http_header;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Some headers have special aliases:
  +
  +<P>
   
  -<P><A NAME="anchor396"></A>
  -<PRE>  $r-&gt;content_type('text/plain');
  -</PRE>
  -<P><A NAME="anchor397"></A>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  $r-&gt;content_type('text/plain');</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   is the same as:
  +
  +<P>
   
  -<P><A NAME="anchor398"></A>
  -<PRE> headers_out(&quot;Content-type&quot; =&gt; &quot;text/plain&quot;);
  -</PRE>
  -<P><A NAME="anchor399"></A>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre> headers_out(&quot;Content-type&quot; =&gt; &quot;text/plain&quot;);</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   A typical handler looks like this:
  +
  +<P>
   
  -<P><A NAME="anchor400"></A>
  -<PRE>  $r-&gt;content_type('text/plain');
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  $r-&gt;content_type('text/plain');
     $r-&gt;send_http_header;
  -  return OK if $r-&gt;header_only;
  -</PRE>
  -<P><A NAME="anchor401"></A>
  +  return OK if $r-&gt;header_only;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   If the client issues an HTTP <CODE>HEAD</CODE> request rather than the usual
   <CODE>GET</CODE>, to be compliant with the HTTP protocol we should not send the document
   body, but only the HTTP header. When Apache receives a <CODE>HEAD</CODE>
   request, <EM>header_only()</EM> returns <EM>true</EM>. If we see that this has happened, we return from the handler immediately
   with an <CODE>OK</CODE> status code.
   
  -<P><A NAME="anchor402"></A>
  +<P>
   Generally, you don't need the explicit content type setting, since Apache
   does this for you, by looking up the MIME type of the request and by
   matching the extension of the URI in the MIME tables (from the
  @@ -2495,118 +3762,202 @@
   mapped by a known extension, you should set the appropriate type by using
   <CODE>content_type()</CODE> method.
   
  -<P><A NAME="anchor403"></A>
  +<P>
   The situation is a little bit different with <CODE>Apache::Registry</CODE> and similar handlers. If you take a basic CGI script like this:
  +
  +<P>
   
  -<P><A NAME="anchor404"></A>
  -<PRE>  print &quot;Content-type: text/plain\r\n\r\n&quot;;
  -  print &quot;Hello world&quot;;
  -</PRE>
  -<P><A NAME="anchor405"></A>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  print &quot;Content-type: text/plain\r\n\r\n&quot;;
  +  print &quot;Hello world&quot;;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   it wouldn't work, because the HTTP header will not be sent out. By default,
   mod_perl does not send any headers itself. You may wish to change this by
   adding
  +
  +<P>
   
  -<P><A NAME="anchor406"></A>
  -<PRE>  PerlSendHeader On
  -</PRE>
  -<P><A NAME="anchor407"></A>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  PerlSendHeader On</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   in the <CODE>Apache::Registry</CODE>  <CODE>&lt;Location&gt;</CODE> section of your configuration. Now, the response line and common headers
   will be sent as they are by mod_cgi. Just as with mod_cgi, <CODE>PerlSendHeader</CODE> will not send the MIME type and a terminating double newline. Your script
   must send that itself, e.g.:
  +
  +<P>
   
  -<P><A NAME="anchor408"></A>
  -<PRE>  print &quot;Content-type: text/html\r\n\r\n&quot;;
  -</PRE>
  -<P><A NAME="anchor409"></A>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  print &quot;Content-type: text/html\r\n\r\n&quot;;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   According to HTTP specs, you should send ``\cM\cJ'', ``\015\012'' or
   ``\0x0D\0x0A'' string. The ``\r\n'' is the way to do that on UNIX and
   MS-DOS/Windows machines. However, on a Mac ``\r\n'' eq ``\012\015'',
   exactly the other way around.
   
  -<P><A NAME="anchor410"></A>
  +<P>
   Note, that in most UNIX CGI scripts, developers use a simpler ``\n\n'' and
   not ``\r\n\r\n''. There are occasions where sending ``\n'' without ``\r''
   can cause problems, make it a habit to always send ``\r\n'' every time.
   
  -<P><A NAME="anchor411"></A>
  +<P>
   If you use an OS which uses the EBCDIC as character set (e.g.
   BS2000-Posix), you should use this method to send the Content-type header:
  +
  +<P>
   
  -<P><A NAME="anchor412"></A>
  -<PRE>  shift-&gt;send_http_header('text/html');
  -</PRE>
  -<P><A NAME="anchor413"></A>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  shift-&gt;send_http_header('text/html');</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   The <CODE>PerlSendHeader On</CODE> directive tells mod_perl to intercept anything that looks like a header
   line (such as <CODE>Content-Type:
   text/plain</CODE>) and automatically turn it into a correctly formatted HTTP/1.0 header, the
   same way it happens with CGI scripts running under mod_cgi. This allows you
   to keep your CGI scripts unmodified.
   
  -<P><A NAME="anchor414"></A>
  +<P>
   You can use <CODE>$ENV{PERL_SEND_HEADER}</CODE> to find out whether
   <CODE>PerlSendHeader</CODE> is <STRONG>On</STRONG> or <STRONG>Off</STRONG>. You use it in your module like this:
  +
  +<P>
   
  -<P><A NAME="anchor415"></A>
  -<PRE> if($ENV{PERL_SEND_HEADER}) {
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre> if($ENV{PERL_SEND_HEADER}) {
        print &quot;Content-type: text/html\r\n\r\n&quot;;
    }
    else {
        my $r = Apache-&gt;request;
        $r-&gt;content_type('text/html');
        $r-&gt;send_http_header;
  - }
  -</PRE>
  -<P><A NAME="anchor416"></A>
  + }</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Note that you can always use the code in the else part of the above
   example, no matter whether the <CODE>PerlSendHeader</CODE> directive is On or Off.
   
  -<P><A NAME="anchor417"></A>
  +<P>
   If you use <CODE>CGI.pm</CODE>'s <CODE>header()</CODE> function to generate HTTP headers, you do not need to activate this
   directive because <CODE>CGI.pm</CODE> detects
   <EM>mod_perl</EM> and calls <CODE>send_http_header()</CODE> for you.
   
  -<P><A NAME="anchor418"></A>
  +<P>
   There is no free lunch--you get the mod_cgi behavior at the expense of the
   small but finite overhead of parsing the text that is sent. Note that
   mod_perl makes the assumption that individual headers are not split across
   print statements.
   
  -<P><A NAME="anchor419"></A>
  +<P>
   The <CODE>Apache::print()</CODE> routine has to gather up the headers that your script outputs, in order to
   pass them to <CODE>$r-&gt;send_http_header</CODE>. This happens in <CODE>src/modules/perl/Apache.xs</CODE> (<CODE>print</CODE>) and
   <CODE>Apache/Apache.pm</CODE> (<CODE>send_cgi_header</CODE>). There is a shortcut in there, namely the assumption that each print
   statement contains one or more complete headers. If for example you
   generate a
   <CODE>Set-Cookie</CODE> header by multiple <CODE>print()</CODE> statements, like this:
  +
  +<P>
   
  -<P><A NAME="anchor420"></A>
  -<PRE>   print &quot;Content-type: text/plain\n&quot;;
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>   print &quot;Content-type: text/plain\n&quot;;
      print &quot;Set-Cookie: iscookietext\; &quot;;
      print &quot;expires=Wednesday, 09-Nov-1999 00:00:00 GMT\; &quot;;
      print &quot;path=\/\; &quot;;
      print &quot;domain=\.mmyserver.com\; &quot;;
      print &quot;\r\n\r\n&quot;;
  -   print &quot;hello&quot;;
  -</PRE>
  -<P><A NAME="anchor421"></A>
  +   print &quot;hello&quot;;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Your generated <CODE>Set-Cookie</CODE> header is split over a number of <CODE>print()</CODE> statements and gets
   lost. The above example wouldn't work! Try this instead:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor422"></A>
  -<PRE>   my $cookie = &quot;Set-Cookie: iscookietext\; &quot;;
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>   my $cookie = &quot;Set-Cookie: iscookietext\; &quot;;
      $cookie .= &quot;expires=Wednesday, 09-Nov-1999 00:00:00 GMT\; &quot;;
      $cookie .= &quot;path=\/\; &quot;;
      $cookie .= &quot;domain=\.mmyserver.com\; &quot;;
      print &quot;Content-type: text/plain\n&quot;,
      print &quot;$cookie\r\n\r\n&quot;;
  -   print &quot;hello&quot;;
  -</PRE>
  -<P><A NAME="anchor423"></A>
  +   print &quot;hello&quot;;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Of course using a special purpose cookie generator modules, like
   <CODE>Apache::Cookie</CODE>, <CODE>CGI::Cookie</CODE> etc is an even cleaner solution.
   
  -<P><A NAME="anchor424"></A>
  +<P>
   Sometimes when you call a script you see an ugly "Content-Type:
   text/html" displayed at the top of the page, and of course the rest of the HTML code
   won't be rendered correctly by the browser. As you have seen above, this
  @@ -2616,15 +3967,24 @@
   
   <CODE>$q-&gt;header</CODE> method or mod_perl's <CODE>$r-&gt;send_http_header</CODE>.
   
  -<P><A NAME="anchor425"></A>
  +<P>
   If you have a complicated application where the header might be generated
   from many different places, depending on the calling logic, you might want
   to write a special subroutine that sends a header, and keeps track of
   whether the header has been already sent. Of course you can use a global
   variable to flag that the header has already been sent:
  +
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
   
  -<P><A NAME="anchor426"></A>
  -<PRE>  use strict;
  +	<td>
  +	  <pre>  use strict;
     use vars qw{$header_printed};
     $header_printed = 0;
     
  @@ -2640,9 +4000,12 @@
         $r-&gt;content_type($type);
         $r-&gt;send_http_header;
       }
  -  }
  -</PRE>
  -<P><A NAME="anchor427"></A>
  +  }</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   <CODE>$header_printed</CODE> is the variable that flags whether the header was sent or not and it gets
   initialized to false (0) at the beginning of each code invocation. Note
   that the second invocation of <CODE>print_header()</CODE> within the same
  @@ -2650,12 +4013,21 @@
   <CODE>$header_printed</CODE> will become true after <CODE>print_header()</CODE> will be executed for the
   first time.
   
  -<P><A NAME="anchor428"></A>
  +<P>
   A solution that is a little bit more memory friendly is to use a fully
   qualified variable instead:
  +
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
   
  -<P><A NAME="anchor429"></A>
  -<PRE>  use strict;
  +	<td>
  +	  <pre>  use strict;
     $main::header_printed = 0;
     
     print_header(&quot;text/plain&quot;);
  @@ -2670,21 +4042,33 @@
         $r-&gt;content_type($type);
         $r-&gt;send_http_header;
       }
  -  }
  -</PRE>
  -<P><A NAME="anchor430"></A>
  +  }</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   We just removed the global variable predeclaration, which allowed us to use <CODE>$header_printed</CODE> under <CODE>&quot;use strict&quot;</CODE> and replaced
   <CODE>$header_printed</CODE> with <CODE>$main::header_printed</CODE>;
   
  -<P><A NAME="anchor431"></A>
  +<P>
   You may become tempted to use a more elegant Perl solution--the nested
   subroutine effect which seems to be a natural approach to take here.
   Unfortunately it will not work. If the process was starting fresh for each
   script or handler, like with plain mod_cgi scripts, it would work just
   fine:
  +
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
   
  -<P><A NAME="anchor432"></A>
  -<PRE>  use strict;
  +	<td>
  +	  <pre>  use strict;
     
     print_header(&quot;text/plain&quot;);
     print &quot;It worked!\n&quot;;
  @@ -2701,14 +4085,17 @@
           $r-&gt;send_http_header;
         }
       }
  -  }
  -</PRE>
  -<P><A NAME="anchor433"></A>
  +  }</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   In this code <CODE>$header_printed</CODE> is declared as lexically scoped (with <CODE>my())</CODE> outside the
   subroutine <CODE>print_header()</CODE> and modified inside of it. Curly
   braces define the block which limits the scope of the lexically variable.
   
  -<P><A NAME="anchor434"></A>
  +<P>
   This means that once <CODE>print_header()</CODE> sets it to 1, it will stay
   1 as long as the code is running. So all subsequent calls to this
   subroutine will just return without doing a thing. This would serve our
  @@ -2719,49 +4106,75 @@
   value of <CODE>$header_printed</CODE> is equal to 1--it won't be reinitialized, since the subroutine won't be
   recompiled.
   
  -<P><A NAME="anchor435"></A>
  +<P>
   Why can't we use a lexical without hitting the nested subroutine effect?
   Because when we've discussed <A HREF="././porting.html#Exposing_Apache_Registry_secret">Apache::Registry secrets</A> we have seen that the code is wrapped in a <CODE>handler</CODE> routine, effectively turning any subroutines within the file a script
   resides in into nested subroutines. Hence we are forced to use a global in
   this situation.
   
  -<P><A NAME="anchor436"></A>
  +<P>
   Let's make our smart method more elaborate with respect to the
   <CODE>PerlSendHeader</CODE> directive, so that it always does the right thing. It's especially
   important if you write an application that you are going to distribute,
   hopefully under one of the Open Source or GPL licences.
   
  -<P><A NAME="anchor437"></A>
  +<P>
   You can continue to improve this subroutine even further to handle
   additional headers, such as cookies.
   
  -<P><A NAME="anchor438"></A>
  +<P>
   See also <A HREF="././correct_headers.html#">Correct Headers--A quick guide for mod_perl users</A>
   
   
   
  -<P><A NAME="anchor439"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H1><A NAME="NPH_Non_Parsed_Headers_scripts">NPH (Non Parsed Headers) scripts</A></H1></CENTER>
  -<P><A NAME="anchor440"></A>
  +<P>
   To run a Non Parsed Header CGI script under mod_perl, simply add to your
   code:
  +
  +<P>
   
  -<P><A NAME="anchor441"></A>
  -<PRE>  local $| = 1;
  -</PRE>
  -<P><A NAME="anchor442"></A>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  local $| = 1;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   And if you normally set <CODE>PerlSendHeader On</CODE>, add this to your server's configuration file:
  +
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
   
  -<P><A NAME="anchor443"></A>
  -<PRE>  &lt;Files */nph-*&gt;
  +	<td>
  +	  <pre>  &lt;Files */nph-*&gt;
       PerlSendHeader Off
  -  &lt;/Files&gt;
  -</PRE>
  -<P><A NAME="anchor444"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +  &lt;/Files&gt;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H1><A NAME="BEGIN_blocks">BEGIN blocks</A></H1></CENTER>
  -<P><A NAME="anchor445"></A>
  +<P>
   Perl executes <CODE>BEGIN</CODE> blocks as soon as possible, at the time of compiling the code. The same is
   true under mod_perl. However, since mod_perl normally only compiles scripts
   and modules once, either in the parent server or once per-child, <CODE>BEGIN</CODE> blocks in that code will only be run once. As the <CODE>perlmod</CODE> manpage explains, once a <CODE>BEGIN</CODE>
  @@ -2769,97 +4182,99 @@
   this means that <CODE>BEGIN</CODE> blocks will not be run during the response to an incoming request unless
   that request happens to be the one that causes the compilation of the code.
   
  -<P><A NAME="anchor446"></A>
  +<P>
   <CODE>BEGIN</CODE> blocks in modules and files pulled in via <CODE>require()</CODE> or
   <CODE>use()</CODE> will be executed:
   
   <UL>
   <P><LI>
  -<P><A NAME="anchor447"></A>
  +<P>
   Only once, if pulled in by the parent process.
   
   <P><LI>
  -<P><A NAME="anchor448"></A>
  +<P>
   Once per-child process if not pulled in by the parent process.
   
   <P><LI>
  -<P><A NAME="anchor449"></A>
  +<P>
   An additional time, once per child process if the module is pulled in off
   disk again via <CODE>Apache::StatINC</CODE>.
   
   <P><LI>
  -<P><A NAME="anchor450"></A>
  +<P>
   An additional time, in the parent process on each restart if
   <CODE>PerlFreshRestart</CODE> is <CODE>On</CODE>.
   
   <P><LI>
  -<P><A NAME="anchor451"></A>
  +<P>
   Unpredictable if you fiddle with <CODE>%INC</CODE> yourself.
   
   </UL>
  -<P><A NAME="anchor452"></A>
  +<P>
   <CODE>BEGIN</CODE> blocks in <CODE>Apache::Registry</CODE> scripts will be executed, as above plus:
   
   <UL>
   <P><LI>
  -<P><A NAME="anchor453"></A>
  +<P>
   Only once, if pulled in by the parent process via
   
  -<P><A NAME="anchor454"></A>
  +<P>
   <CODE>Apache::RegistryLoader</CODE>.
   
   <P><LI>
  -<P><A NAME="anchor455"></A>
  +<P>
   Once per-child process if not pulled in by the parent process.
   
   <P><LI>
  -<P><A NAME="anchor456"></A>
  +<P>
   An additional time, once per child process, each time the script file
   changes on disk.
   
   <P><LI>
  -<P><A NAME="anchor457"></A>
  +<P>
   An additional time, in the parent process on each restart if pulled in by
   the parent process via <CODE>Apache::RegistryLoader</CODE> and
   <CODE>PerlFreshRestart</CODE> is <CODE>On</CODE>.
   
   </UL>
  -<P><A NAME="anchor458"></A>
  +<P>
   Make sure you read <A HREF="././troubleshooting.html#Evil_things_might_happen_when_us">Evil things might happen when using PerlFreshRestart</A>.
   
  -<P><A NAME="anchor459"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H1><A NAME="END_blocks">END blocks</A></H1></CENTER>
  -<P><A NAME="anchor460"></A>
  +<P>
   As the <CODE>perlmod</CODE> manpage explains, an <CODE>END</CODE> subroutine is executed as late as possible, that is, when the interpreter
   exits. In the mod_perl environment, the interpreter does not exit until the
   server shuts down. However, mod_perl does make a special case for
   <CODE>Apache::Registry</CODE> scripts.
   
  -<P><A NAME="anchor461"></A>
  +<P>
   Normally, <CODE>END</CODE> blocks are executed by Perl during its <STRONG>perl_run()</STRONG>
   function. This is called once each time the Perl program is executed, i.e.
   under mod_cgi, once per invocation of the CGI script. However, mod_perl
   only calls <STRONG>perl_run()</STRONG> once, during server startup. Any
   <CODE>END</CODE> blocks encountered during main server startup, i.e. those pulled in by the <CODE>PerlRequire</CODE> or by any <CODE>PerlModule</CODE>, are suspended.
   
  -<P><A NAME="anchor462"></A>
  +<P>
   Except during the cleanup phase, any <CODE>END</CODE> blocks encountered during compilation of <CODE>Apache::Registry</CODE> scripts, including subsequent invocations when the script is cached in
   memory, are called after the script has completed.
   
  -<P><A NAME="anchor463"></A>
  +<P>
   All other <CODE>END</CODE> blocks encountered during other <CODE>Perl*Handler</CODE>
   call-backs, e.g. <CODE>PerlChildInitHandler</CODE>, will be suspended while the process is running and called during <CODE>child_exit()</CODE> when the process is shutting down. Module authors might wish to use
   <CODE>$r-&gt;register_cleanup()</CODE> as an alternative to <CODE>END</CODE> blocks if this behavior is not desirable. <CODE>$r-&gt;register_cleanup()</CODE> is called at the CleanUp processing phase of each request and thus can be
   used to emulate plain perl's <CODE>END{}</CODE> block behavior.
   
  -<P><A NAME="anchor464"></A>
  +<P>
   The last paragraph is very important for handling the case of <A HREF="././debug.html#Handling_the_User_pressed_Stop_">'User Pressed the Stop Button'</A>.
   
  -<P><A NAME="anchor465"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H1><A NAME="Command_line_Switches_w_T_e">Command line Switches (-w, -T, etc)</A></H1></CENTER>
  -<P><A NAME="anchor466"></A>
  +<P>
   Normally when you run perl from the command line, you have the shell invoke
   it with <CODE>#!/bin/perl</CODE> (sometimes referred to as the shebang line). In scripts running under
   mod_cgi, you may use perl execution switch arguments as described in the <CODE>perlrun</CODE> manpage, such as
  @@ -2867,97 +4282,171 @@
   switches except <CODE>-w</CODE> are ignored by mod_perl. This feature was added for a backward
   compatibility with CGI scripts.
   
  -<P><A NAME="anchor467"></A>
  +<P>
   Most command line switches have a special variable equivalent which allows
   them to be set/unset in code. Consult the <CODE>perlvar</CODE> manpage for more details.
   
  -<P><A NAME="anchor468"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="Warnings">Warnings</A></H2></CENTER>
  -<P><A NAME="anchor469"></A>
  +<P>
   There are three ways to enable warnings:
   
   <UL>
   <P><LI><STRONG><A NAME="item_Globally">Globally to all Processes</A></STRONG>
  -<P><A NAME="anchor470"></A>
  +<P>
   Setting:
   
  -<P><A NAME="anchor471"></A>
  -<PRE>  PerlWarn On
  -</PRE>
  -<P><A NAME="anchor472"></A>
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  PerlWarn On</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   in <CODE>httpd.conf</CODE> will turn warnings <STRONG>On</STRONG> in any script.
   
  -<P><A NAME="anchor473"></A>
  +<P>
   You can then fine tune your code, turning warnings <STRONG>Off</STRONG> and <STRONG>On</STRONG> by setting the <CODE>$^W</CODE> variable in your scripts.
   
   <P><LI><STRONG><A NAME="item_Locally">Locally to a script</A></STRONG>
  -<P><A NAME="anchor474"></A>
  -<PRE>  #!/usr/bin/perl -w
  -</PRE>
  -<P><A NAME="anchor475"></A>
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  #!/usr/bin/perl -w</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   will turn warnings <STRONG>On</STRONG> for the scope of the script. You can turn them <STRONG>Off</STRONG> and <STRONG>On</STRONG> in the script by setting the <CODE>$^W</CODE> variable as noted above.
   
   <P><LI><STRONG><A NAME="item_Locally">Locally to a block</A></STRONG>
  -<P><A NAME="anchor476"></A>
  +<P>
   This code turns warnings mode <STRONG>On</STRONG> for the scope of the block.
   
  -<P><A NAME="anchor477"></A>
  -<PRE>  {
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  {
       local $^W = 1;
       # some code
     }
  -  # $^W assumes its previous value here
  -</PRE>
  -<P><A NAME="anchor478"></A>
  +  # $^W assumes its previous value here</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   This turns it <STRONG>Off</STRONG>:
  +
  +<P>
   
  -<P><A NAME="anchor479"></A>
  -<PRE>  {
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  {
       local $^W = 0;
       # some code
     }
  -  # $^W assumes its previous value here
  -</PRE>
  -<P><A NAME="anchor480"></A>
  +  # $^W assumes its previous value here</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Note, that if you forget the <CODE>local</CODE> operator this code will affect the child processing the current request,
   and all the subsequent requests processed by that child. Thus
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor481"></A>
  -<PRE>  $^W = 0;
  -</PRE>
  -<P><A NAME="anchor482"></A>
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  $^W = 0;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   will turn the warnings <EM>Off</EM>, no matter what.
   
  -<P><A NAME="anchor483"></A>
  +<P>
   If you want to turn warnings <EM>On</EM> for the scope of the whole file, as in the previous item, you can do this
   by adding:
   
  -<P><A NAME="anchor484"></A>
  -<PRE>  local $^W = 1;
  -</PRE>
  -<P><A NAME="anchor485"></A>
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  local $^W = 1;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   at the beginning of the file. Since a file is effectively a block, file
   scope behaves like a block's curly braces <CODE>{ }</CODE> and <CODE>local $^W</CODE>
   at the start of the file will be effective for the whole file.
   
   </UL>
  -<P><A NAME="anchor486"></A>
  +<P>
   While having warning mode turned <STRONG>On</STRONG> is essential for a development server, you should turn it globally <STRONG>Off</STRONG> in a production server, since, for example, if every served request
   generates only one warning, and your server serves millions of requests per
   day, your log file will eat up all of your disk space and your system will
   die.
   
  -<P><A NAME="anchor487"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="Taint_Mode">Taint Mode</A></H2></CENTER>
  -<P><A NAME="anchor488"></A>
  +<P>
   Perl's <CODE>-T</CODE> switch enables <EM>Taint</EM> mode. (META: Link to security chapter). If you aren't forcing all your
   scripts to run under <STRONG>Taint</STRONG>
   mode you are looking for trouble from malicious users. (See the
   <EM>perlsec</EM> manpage for more information)
   
  -<P><A NAME="anchor489"></A>
  +<P>
   If you have some scripts that won't run under Taint mode, run only the ones
   that run under mod_perl with Taint mode enabled and the rest on another
   server with Taint mode disabled -- this can be either a mod_cgi in the
  @@ -2965,179 +4454,282 @@
   mod_rewrite module and redirect requests based on the file extensions. For
   example you can use <EM>.tcgi</EM> for the taint-clean scripts, and <EM>cgi</EM> for the rest.
   
  -<P><A NAME="anchor490"></A>
  +<P>
   When you have this setup you can start working toward cleaning the rest of
   the scripts, to make them run under the Taint mode. Just because you have a
   few dirty scripts doesn't mean that you should jeopardize your whole
   service.
   
  -<P><A NAME="anchor491"></A>
  +<P>
   Since the <CODE>-T</CODE> switch doesn't have an equivalent perl variable, mod_perl provides the <CODE>PerlTaintCheck</CODE> directive to turn on taint checks. In
   <CODE>httpd.conf</CODE>, enable this mode with:
  +
  +<P>
   
  -<P><A NAME="anchor492"></A>
  -<PRE>  PerlTaintCheck On
  -</PRE>
  -<P><A NAME="anchor493"></A>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  PerlTaintCheck On</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Now any code compiled inside httpd will be taint checked.
   
  -<P><A NAME="anchor494"></A>
  +<P>
   If you use the <CODE>-T</CODE> switch, Perl will warn you that you should use the <CODE>PerlTaintCheck</CODE> configuration directive and will otherwise ignore it.
   
  -<P><A NAME="anchor495"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="Other_switches">Other switches</A></H2></CENTER>
  -<P><A NAME="anchor496"></A>
  +<P>
   Finally, if you still need to to set additional perl startup flags such as <CODE>-d</CODE> and <CODE>-D</CODE>, you can use an environment variable
   <CODE>PERL5OPT</CODE>. Switches in this variable are treated as if they were on every Perl
   command line.
   
  -<P><A NAME="anchor497"></A>
  +<P>
   Only the <CODE>-[DIMUdmw]</CODE> switches are allowed.
   
  -<P><A NAME="anchor498"></A>
  +<P>
   When the <CODE>PerlTaintCheck</CODE> variable is turned on, the value of
   <CODE>PERL5OPT</CODE> will be ignored.
   
  -<P><A NAME="anchor499"></A>
  +<P>
   See also
   <A HREF="././modules.html#Apache_PerlRun_Run_unaltered_">Apache::PerlRun</A>.
   
  -<P><A NAME="anchor500"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H1><A NAME="The_strict_pragma">The strict pragma</A></H1></CENTER>
  -<P><A NAME="anchor501"></A>
  +<P>
   It's _absolutely_ mandatory (at least for development) to start all your
   scripts with:
  +
  +<P>
   
  -<P><A NAME="anchor502"></A>
  -<PRE>  use strict;
  -</PRE>
  -<P><A NAME="anchor503"></A>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  use strict;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   If needed, you can always turn off the 'strict' pragma or a part of it
   inside the block, e.g:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor504"></A>
  -<PRE>  {
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  {
       no strict 'refs';
       ... some code
  -  }
  -</PRE>
  -<P><A NAME="anchor505"></A>
  +  }</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   It's more important to have the <CODE>strict</CODE> pragma enabled under mod_perl than anywhere else. While it's not required
   by the language, its use cannot be too strongly recommended. It will save
   you a great deal of time. And, of course, clean scripts will still run
   under mod_cgi (plain CGI)!
   
  -<P><A NAME="anchor506"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H1><A NAME="Passing_ENV_variables_to_CGI">Passing ENV variables to CGI</A></H1></CENTER>
  -<P><A NAME="anchor507"></A>
  +<P>
   META: you have a duplication with config.pod here.
   
  -<P><A NAME="anchor508"></A>
  +<P>
   To pass an environment variable from a configuration file, add to it:
  +
  +<P>
   
  -<P><A NAME="anchor509"></A>
  -<PRE>  PerlSetEnv key val
  -  PerlPassEnv key
  -</PRE>
  -<P><A NAME="anchor510"></A>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  PerlSetEnv key val
  +  PerlPassEnv key</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   e.g.:
  +
  +<P>
   
  -<P><A NAME="anchor511"></A>
  -<PRE>  PerlSetEnv PERLDB_OPTS &quot;NonStop=1 LineInfo=/tmp/db.out AutoTrace=1&quot;
  -</PRE>
  -<P><A NAME="anchor512"></A>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  PerlSetEnv PERLDB_OPTS &quot;NonStop=1 LineInfo=/tmp/db.out AutoTrace=1&quot;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   will set <CODE>$ENV{PERLDB_OPTS}</CODE>, and it will be accessible in every child.
   
  -<P><A NAME="anchor513"></A>
  +<P>
   <CODE>%ENV</CODE> is only set up for CGI emulation. If you are using the API, you should use <CODE>$r-&gt;subprocess_env</CODE>, <CODE>$r-&gt;notes</CODE> or
   <CODE>$r-&gt;pnotes</CODE> for passing data around between handlers. <CODE>%ENV</CODE> is slow because it must update the underlying C environment table. This
   also exposes the data on systems which allow users to see the environment
   with <CODE>ps</CODE>.
   
  -<P><A NAME="anchor514"></A>
  +<P>
   In any case, <CODE>%ENV</CODE> and the tables used by those methods are all cleared after the request is
   served so that <CODE>$ENV{SESSION_ID}</CODE> will not be swapped or reused by different http requests.
   
  -<P><A NAME="anchor515"></A>
  +<P>
   See also <A HREF="././performance.html#PerlSetupEnv_Off">PerlSetupEnv</A> which can enable/disable environment variables settings.
   
  -<P><A NAME="anchor516"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H1><A NAME="_M_and_other_time_file_tests_u">-M and other time() file tests under mod_perl</A></H1></CENTER>
  -<P><A NAME="anchor517"></A>
  +<P>
   Under mod_perl, files that have been created after the server's (child)
   startup are reported as having a negative age with <CODE>-M</CODE>
   (<CODE>-C</CODE>  <CODE>-A</CODE>) test. This is obvious if you remember that you will get the negative
   result if the server was started before the file was created. It's normal
   behavior with perl.
   
  -<P><A NAME="anchor518"></A>
  +<P>
   If you want to have <CODE>-M</CODE> report the time relative to the current request, you should reset the <CODE>$^T</CODE> variable just as with any other perl script. Add <CODE>$^T=time;</CODE> at the beginning of the script.
   
  -<P><A NAME="anchor519"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H1><A NAME="Apache_and_syslog">Apache and syslog</A></H1></CENTER>
  -<P><A NAME="anchor520"></A>
  +<P>
   When native syslog support is enabled, the stderr stream will be redirected
   to <CODE>/dev/null</CODE>!
   
  -<P><A NAME="anchor521"></A>
  +<P>
   It has nothing to do with mod_perl (plain Apache does the same). Doug wrote
   the <A HREF="././modules.html#Apache_LogSTDERR">Apache::LogSTDERR</A> module to work around this.
   
  -<P><A NAME="anchor522"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H1><A NAME="File_tests_operators">File tests operators</A></H1></CENTER>
  -<P><A NAME="anchor523"></A>
  +<P>
   Remember that with mod_perl you might get negative times when you use file
   test operators like <CODE>-M</CODE> -- last modification time, <CODE>-A</CODE> -- last access time, <CODE>-C</CODE> -- last inode-change time, and others.  <CODE>-M</CODE>
   returns the difference in time between the modification time of the file
   and the time the script was started. Because the <CODE>^T</CODE> variable is not reset on each script invocation, and is equal to the time
   when the process was forked, you might want to perform:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor524"></A>
  -<PRE>  $^T = time;
  -</PRE>
  -<P><A NAME="anchor525"></A>
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  $^T = time;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   at the beginning of your scripts to simulate the regular perl script
   behaviour of file tests.
   
  -<P><A NAME="anchor526"></A>
  +<P>
   META: Above is near duplicate of ``-M and other <CODE>time()</CODE> file
   tests under mod_perl'' make a link instead
   
  -<P><A NAME="anchor527"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H1><A NAME="Filehandlers_and_locks_leakages">Filehandlers and locks leakages</A></H1></CENTER>
  -<P><A NAME="anchor528"></A>
  +<P>
   META: duplication at debug.pod: =head3 Safe Resource Locking
   
  -<P><A NAME="anchor529"></A>
  +<P>
   When you write a script running under mod_cgi, you can get away with sloppy
   programming, like opening a file and letting the interpreter close it for
   you when the script had finished its run:
  +
  +<P>
   
  -<P><A NAME="anchor530"></A>
  -<PRE>  open IN, &quot;in.txt&quot; or die &quot;Cannot open in.txt for reading : $!\n&quot;;
  -</PRE>
  -<P><A NAME="anchor531"></A>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  open IN, &quot;in.txt&quot; or die &quot;Cannot open in.txt for reading : $!\n&quot;;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   For mod_perl, before the end of the script you <STRONG>must</STRONG>  <CODE>close()</CODE> any files you opened!
  +
  +<P>
   
  -<P><A NAME="anchor532"></A>
  -<PRE>  close IN;
  -</PRE>
  -<P><A NAME="anchor533"></A>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  close IN;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   If you forget to <CODE>close()</CODE>, you might get file descriptor leakage and (if you <CODE>flock()ed</CODE> on this file descriptor) also unlock problems.
   
  -<P><A NAME="anchor534"></A>
  +<P>
   Even if you do call <CODE>close(),</CODE> if for some reason the
   interpreter was stopped before the <CODE>close()</CODE> call, the leakage will still happen. See for example <A HREF="././debug.html#Handling_the_User_pressed_Stop_">Handling the 'User pressed Stop button' case</A>. After a long run without restarting Apache your machine might run out of
   file descriptors, and worse, files might be left locked and unusable.
   
  -<P><A NAME="anchor535"></A>
  +<P>
   What can you do? Use <CODE>IO::File</CODE> (and the other <CODE>IO::*</CODE> modules). This allows you to assign the file handler to variable which can
   be
   <CODE>my()</CODE> (lexically) scoped. When this variable goes out of scope the file or other
  @@ -3146,63 +4738,122 @@
   script's invocation even if it was aborted in the middle. If the variable
   was defined inside some internal block, it will go out of scope at the end
   of the block. For example:
  +
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
   
  -<P><A NAME="anchor536"></A>
  -<PRE>  {
  +	<td>
  +	  <pre>  {
       my $fh = IO::File-&gt;new(&quot;filename&quot;) or die $!;
       # read from $fh
  -  } # ...$fh is closed automatically at end of block, without leaks.
  -</PRE>
  -<P><A NAME="anchor537"></A>
  +  } # ...$fh is closed automatically at end of block, without leaks.</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   As I have just mentioned, you don't have to create a special block for this
   purpose. A script in a file is effectively written in a block with the same
   scope as the file, so you can simply write:
   
  -<P><A NAME="anchor538"></A>
  -<PRE>  my $fh = IO::File-&gt;new(&quot;filename&quot;) or die $!;
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  my $fh = IO::File-&gt;new(&quot;filename&quot;) or die $!;
       # read from $fh
  -    # ...$fh is closed automatically at end of script, without leaks.
  -</PRE>
  -<P><A NAME="anchor539"></A>
  +    # ...$fh is closed automatically at end of script, without leaks.</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Using a <CODE>{ BLOCK }</CODE>) makes sure is that the file is closed the moment that the end of the
   block is reached.
   
  -<P><A NAME="anchor540"></A>
  +<P>
   An even faster and lighter technique is to use <CODE>Symbol.pm</CODE>:
  +
  +<P>
   
  -<P><A NAME="anchor541"></A>
  -<PRE>  my $fh = Symbol::gensym();
  -  open $fh, &quot;filename&quot; or die $!;
  -</PRE>
  -<P><A NAME="anchor542"></A>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  my $fh = Symbol::gensym();
  +  open $fh, &quot;filename&quot; or die $!;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Use these approaches to ensure you have no leakages, but don't be too lazy
   to write <CODE>close()</CODE> statements. Make it a habit.
   
  -<P><A NAME="anchor543"></A>
  +<P>
   Under perl 5.6.0 we can do this instead:
  +
  +<P>
   
  -<P><A NAME="anchor544"></A>
  -<PRE>  open my $fh, $filename or die $! ;
  -</PRE>
  -<P><A NAME="anchor545"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  open my $fh, $filename or die $! ;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H1><A NAME="Code_has_been_changed_but_it_se">Code has been changed, but it seems the script is running the old code</A></H1></CENTER>
  -<P><A NAME="anchor546"></A>
  +<P>
   Files pulled in via <STRONG>use</STRONG> or <STRONG>require</STRONG> statements are not automatically reloaded when they change on disk. See <A HREF="#Reloading_Modules_and_Required_F">Reloading Modules and Required Files</A> for more info.
   
  -<P><A NAME="anchor547"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H1><A NAME="The_Script_Is_Too_Dirty_But_It_">The Script Is Too Dirty, But It Does The Job And I Cannot Afford To Rewrite It.</A></H1></CENTER>
  -<P><A NAME="anchor548"></A>
  +<P>
   You still can win from using mod_perl. 
   
  -<P><A NAME="anchor549"></A>
  +<P>
   One approach is to replace the <CODE>Apache::Registry</CODE> handler with
   <CODE>Apache::PerlRun</CODE> and define a new location. The script can reside in the same directory on
   the disk.
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor550"></A>
  -<PRE>  # httpd.conf
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  # httpd.conf
     Alias /cgi-perl/ /home/httpd/cgi/
     
     &lt;Location /cgi-perl&gt;
  @@ -3212,14 +4863,17 @@
       Options ExecCGI
       allow from all
       PerlSendHeader On
  -  &lt;/Location&gt;
  -</PRE>
  -<P><A NAME="anchor551"></A>
  +  &lt;/Location&gt;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   See <A HREF="#Apache_PerlRun_a_closer_look">Apache::PerlRun--a closer look</A>
   
   
   
  -<P><A NAME="anchor552"></A>
  +<P>
   Another ``bad'', but workable method is to set <CODE>MaxRequestsPerChild</CODE> to 1, which will force each child to exit after serving only one request.
   You will get the preloaded modules, etc., but the script will be compiled
   for each request, then be thrown away. This isn't good for ``high-traffic''
  @@ -3229,10 +4883,11 @@
   killed one will immediately be replaced with a fresh one. Probably that's
   not what you want.
   
  -<P><A NAME="anchor553"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H1><A NAME="Apache_PerlRun_a_closer_look">Apache::PerlRun--a closer look</A></H1></CENTER>
  -<P><A NAME="anchor554"></A>
  +<P>
   <CODE>Apache::PerlRun</CODE> gives you the benefit of preloaded Perl and its modules. This module's
   handler emulates the CGI environment, allowing programmers to write scripts
   that run under CGI or mod_perl without any change. Unlike <CODE>Apache::Registry</CODE>, the <CODE>Apache::PerlRun</CODE>
  @@ -3244,7 +4899,7 @@
   modules, you will see no difference between
   <CODE>Apache::PerlRun</CODE> and <CODE>Apache::Registry</CODE>!.
   
  -<P><A NAME="anchor555"></A>
  +<P>
   Be aware though, that if you use packages that use internal variables that
   have circular references, they will be not flushed!!!
   <CODE>Apache::PerlRun</CODE> only flushes your script's name space, which does not include any other
  @@ -3252,9 +4907,18 @@
   eval scope (of <CODE>Apache::PerlRun</CODE>), that cleanup might not be taken care of until the server is shutdown and
   <CODE>perl_destruct()</CODE> is run, which always happens after running command line scripts. Consider
   this example:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor556"></A>
  -<PRE>  package Foo;
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  package Foo;
     sub new { bless {} }
     sub DESTROY {
       warn &quot;Foo-&gt;DESTROY\n&quot;;
  @@ -3267,88 +4931,139 @@
     EOF
     
     print $@ if $@;
  -  print &quot;Done with script\n&quot;;
  -</PRE>
  -<P><A NAME="anchor557"></A>
  +  print &quot;Done with script\n&quot;;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   When executed as a plain script you'll see:
  +
  +<P>
   
  -<P><A NAME="anchor558"></A>
  -<PRE>  Foo-&gt;DESTROY
  -  Done with script
  -</PRE>
  -<P><A NAME="anchor559"></A>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  Foo-&gt;DESTROY
  +  Done with script</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Then, uncomment the line where <CODE>$self</CODE> makes a circular reference, and you'll see:
  +
  +<P>
   
  -<P><A NAME="anchor560"></A>
  -<PRE>  Done with script
  -  Foo-&gt;DESTROY
  -</PRE>
  -<P><A NAME="anchor561"></A>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  Done with script
  +  Foo-&gt;DESTROY</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   If you run this example with the circular reference enabled under mod_perl
   you won't see <CODE>Foo-&gt;DESTROY</CODE> until server shutdown, or until your module properly takes care of things.
   Note that the <CODE>warn()</CODE> call logs its messages to the <EM>error_log</EM> file, so you should expect the output there and not together with STDOUT.
   
  -<P><A NAME="anchor562"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H1><A NAME="Sharing_variables_between_proces">Sharing variables between processes</A></H1></CENTER>
  -<P><A NAME="anchor563"></A>
  +<P>
   META: to be completed
   
   <UL>
   <P><LI>
  -<P><A NAME="anchor564"></A>
  +<P>
   Global variables initialized at server startup, through the Perl startup
   file, can be shared between processes, until modified by some of the
   processes. e.g. when you write:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor565"></A>
  -<PRE>  $My::debug = 1;
  -</PRE>
  -<P><A NAME="anchor566"></A>
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  $My::debug = 1;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   all processes will read the same value. If one of the processes changes
   that value to <CODE>0</CODE>, it will still be equal to <CODE>1</CODE> for any other process, but not for the one which actually made the change.
   When a process modifies a shared variable, it becomes the process' private
   copy.
   
   <P><LI>
  -<P><A NAME="anchor567"></A>
  +<P>
   <CODE>IPC::Shareable</CODE> can be used to share variables between children.
   
   <P><LI>
  -<P><A NAME="anchor568"></A>
  +<P>
   libmm
   
   <P><LI>
  -<P><A NAME="anchor569"></A>
  +<P>
   other methods?
   
   </UL>
  -<P><A NAME="anchor570"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H1><A NAME="Transitioning_from_Apache_Regis">Transitioning from Apache::Registry to Apache handlers</A></H1></CENTER>
  -<P><A NAME="anchor571"></A>
  +<P>
   Even if you are a CGI script die-hard at some point you might want to move
   a few or all your scripts to Apache Perl handlers. Actually this is an easy
   task, since we saw already what <CODE>Apache::Registry</CODE> makes our scripts appear to Apache to be Perl handlers.
   
  -<P><A NAME="anchor572"></A>
  +<P>
   When you no longer need backward mod_cgi compatibility you can benefit from
   the Perl libraries working only under mod_perl. We will see why in a
   moment.
   
  -<P><A NAME="anchor573"></A>
  +<P>
   Let's see an example. We will start with a mod_cgi compatible CGI script
   running under <CODE>Apache::Registry</CODE>, transpose it into a Perl content handler and then convert it to use <CODE>Apache::Request</CODE> and
   <CODE>Apache::Cookie</CODE>.
   
  -<P><A NAME="anchor574"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="Starting_with_mod_cgi_Compatible">Starting with mod_cgi Compatible Script</A></H2></CENTER>
  -<P><A NAME="anchor575"></A>
  +<P>
   This is the original script's code we are going to work with:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor576"></A>
  -<PRE>  cookie_script.pl
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  cookie_script.pl
     ----------------
     use strict;
     use CGI;
  @@ -3435,14 +5150,17 @@
     ########################
     sub generate_sessionID {
       return scalar localtime;
  -  } # end of sub generate_sessionID
  -</PRE>
  -<P><A NAME="anchor577"></A>
  +  } # end of sub generate_sessionID</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   The code is very simple. It creates a session if you've pressed the
   <EM>'Start'</EM> button or deletes it if you've pressed the the <EM>'Stop'</EM>
   button. The session is stored and retrieved using the cookies technique.
   
  -<P><A NAME="anchor578"></A>
  +<P>
   Note that we have split the obviously simple and short code into three
   logical units, by putting the code into three subroutines.
   <CODE>init()</CODE> to initialize global variables and parse incoming data,
  @@ -3451,56 +5169,78 @@
   Later we will see that this logical separation will allow us an easy
   conversion to Perl content handler code.
   
  -<P><A NAME="anchor579"></A>
  +<P>
   We have used global variables for a few variables since we didn't want to
   pass them from function to function. In a big project you should be very
   restrictive about what variables should be allowed to be global, if any at
   all. In any case, the <CODE>init()</CODE> subroutine makes sure all these
   variables are re-initialized for each code reinvocation.
   
  -<P><A NAME="anchor580"></A>
  +<P>
   Note that we have used a very simple <CODE>generate_sessionID()</CODE>
   function that returns a date string (i.e. Wed&nbsp;Apr&nbsp;12&nbsp;15:02:23&nbsp;2000) as a session ID. You want to replace this one with code which generates a
   unique session every time it was called. And it should be secure, i.e.
   users will not be able to forge one and do nasty things.
   
  -<P><A NAME="anchor581"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="Converting_into_Perl_Content_Han">Converting into Perl Content Handler</A></H2></CENTER>
  -<P><A NAME="anchor582"></A>
  +<P>
   Now let's convert this script into a content handler. There are two parts
   to this task; the first one is to configure Apache to run the new code as a
   Perl handler, the second one is to modify the code itself.
   
  -<P><A NAME="anchor583"></A>
  +<P>
   First we add the following snippet to <EM>httpd.conf</EM>:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor584"></A>
  -<PRE>  PerlModule Test::Cookie
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  PerlModule Test::Cookie
     &lt;Location /test/cookie&gt;
       SetHandler perl-script
       PerlHandler Test::Cookie
  -  &lt;/Location&gt;
  -</PRE>
  -<P><A NAME="anchor585"></A>
  +  &lt;/Location&gt;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   After we restart the server, when there is a request whose URI starts with <EM>/test/cookie</EM>, Apache will execute the <CODE>Test::Cookie::handler()</CODE>
   subroutine as a content handler. We made sure to preload the
   <CODE>Test::Cookie</CODE> module at server start-up, with the <CODE>PerlModule</CODE>
   directive.
   
  -<P><A NAME="anchor586"></A>
  +<P>
   Now we are going to modify the script itself. We copy the content to the
   file <EM>Cookie.pm</EM> and place it into one of the directories listed in <CODE>@INC</CODE>. For example if <EM>/home/httpd/perl</EM> is a part of <CODE>@INC</CODE>
   and since we want to call this package <CODE>Test::Cookie</CODE>, we can put
   <EM>/Cookie.pm</EM> into the <EM>/home/httpd/perl/Test/</EM> directory.
   
  -<P><A NAME="anchor587"></A>
  +<P>
   So this is the new code. Notice that all the subroutines were left
   unmodified from the original script, so to make the differences clear we do
   not repeat them here.
  +
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
   
  -<P><A NAME="anchor588"></A>
  -<PRE>  Test/Cookie.pm
  +	<td>
  +	  <pre>  Test/Cookie.pm
     --------------
     package Test::Cookie;
     use Apache::Constants qw(:common);
  @@ -3524,30 +5264,66 @@
     ### &lt;-- subroutines --&gt; ###
     # all subroutines as before
     
  -  1;
  -</PRE>
  -<P><A NAME="anchor589"></A>
  +  1;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   As you see there are two lines added to the beginning of the code:
   
  -<P><A NAME="anchor590"></A>
  -<PRE>  package Test::Cookie;
  -  use Apache::Constants qw(:common);
  -</PRE>
  -<P><A NAME="anchor591"></A>
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  package Test::Cookie;
  +  use Apache::Constants qw(:common);</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   The first one declares the package name and the second one imports some
   symbols commonly used in Perl handlers to return status codes.
  +
  +<P>
   
  -<P><A NAME="anchor592"></A>
  -<PRE>  use strict;
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  use strict;
     use CGI;
     use CGI::Cookie;
  -  use vars qw($q $switch $status $sessionID);
  -</PRE>
  -<P><A NAME="anchor593"></A>
  +  use vars qw($q $switch $status $sessionID);</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   This code is left unchanged just as before.
   
  -<P><A NAME="anchor594"></A>
  -<PRE>  sub handler{
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  sub handler{
       my $r = shift;
       Apache-&gt;request($r);
     
  @@ -3556,89 +5332,161 @@
       print_status();
     
       return OK;
  -  }
  -</PRE>
  -<P><A NAME="anchor595"></A>
  +  }</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Each content handler (and any other handler) should begin with a subroutine
   called <CODE>handler().</CODE> This subroutine is called when a request's
   URI starts with <EM>/test/cookie</EM> as per our configuration. Of course you can choose a different name, for
   example <CODE>execute(),</CODE> but then you must explicitly use it in the
   configuration directives in the following way:
   
  -<P><A NAME="anchor596"></A>
  -<PRE>  PerlModule Test::Cookie
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  PerlModule Test::Cookie
     &lt;Location /test/cookie&gt;
       SetHandler perl-script
       PerlHandler Test::Cookie::execute
  -  &lt;/Location&gt;
  -</PRE>
  -<P><A NAME="anchor597"></A>
  +  &lt;/Location&gt;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   But we will use the default name, <CODE>handler().</CODE> 
   
  -<P><A NAME="anchor598"></A>
  +<P>
   The <CODE>handler()</CODE> subroutine is just like any other subroutine,
   but generally it has the following structure:
  +
  +<P>
   
  -<P><A NAME="anchor599"></A>
  -<PRE>  sub handler{
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  sub handler{
       my $r = shift;
      
       # the code
     
       # status (OK, DECLINED or else)
       return OK;
  -  }
  -</PRE>
  -<P><A NAME="anchor600"></A>
  +  }</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   First we get the request object by shifting it from <CODE>@_</CODE> and assigning it to the <CODE>$r</CODE> variable.
   
  -<P><A NAME="anchor601"></A>
  +<P>
   Second we write the code that does the processing of the request.
   
  -<P><A NAME="anchor602"></A>
  +<P>
   Third we return the status of the execution. There are many possible
   statuses, the most commonly used are <CODE>OK</CODE> and <CODE>DECLINED</CODE>, which tell the server whether they have completed the request phase that
   the handler was assigned to do or not. If not, another handler must
   complete the processing. <CODE>Apache::Constants</CODE> imports these two and other some commonly used status codes.
   
  -<P><A NAME="anchor603"></A>
  +<P>
   So in our example all we had to do was to wrap the three calls:
  +
  +<P>
   
  -<P><A NAME="anchor604"></A>
  -<PRE>    init();
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>    init();
       print_header();
  -    print_status();
  -</PRE>
  -<P><A NAME="anchor605"></A>
  +    print_status();</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   inside:
  +
  +<P>
   
  -<P><A NAME="anchor606"></A>
  -<PRE>  sub handler{
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  sub handler{
       my $r = shift;
       Apache-&gt;request($r);
     
       return OK;
  -  }
  -</PRE>
  -<P><A NAME="anchor607"></A>
  +  }</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   There is one line we didn't discuss:
  +
  +<P>
   
  -<P><A NAME="anchor608"></A>
  -<PRE>    Apache-&gt;request($r);
  -</PRE>
  -<P><A NAME="anchor609"></A>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>    Apache-&gt;request($r);</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Since we use &lt;CGI.pm&gt;, it relies on the fact that <CODE>$r</CODE> was set in the
   <A HREF="#item_Apache">Apache</A> module. <CODE>Apache::Registry</CODE> did that behind the scenes. Since we don't use <CODE>Apache::Registry</CODE> here, we have to do that ourselves.
   
  -<P><A NAME="anchor610"></A>
  +<P>
   The one last thing we should do is to add <CODE>1;</CODE> at the end of the module, just like with any Perl module, so <CODE>PerlModule</CODE> will not fail when it tries to load <CODE>Test::Cookie</CODE>.
   
  -<P><A NAME="anchor611"></A>
  +<P>
   So to summarise, we took the original script's code and added the following
   eight lines:
  +
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
   
  -<P><A NAME="anchor612"></A>
  -<PRE>  package Test::Cookie;
  +	<td>
  +	  <pre>  package Test::Cookie;
     use Apache::Constants qw(:common);
     
     sub handler{
  @@ -3647,58 +5495,119 @@
     
       return OK;
     }
  -  1;
  -</PRE>
  -<P><A NAME="anchor613"></A>
  +  1;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   and now we have a fully fledged Perl Content Handler.
   
  -<P><A NAME="anchor614"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="Converting_to_use_Apache_Perl_Mo">Converting to use Apache Perl Modules</A></H2></CENTER>
  -<P><A NAME="anchor615"></A>
  +<P>
   So now we have a complete PerlHandler, let's convert it to use Apache Perl
   modules. This breaks the backward compatibility, but gives us better
   performance, mainly because the internals of many of these Perl modules are
   implemented in C, therefore we should get a significant improvement in
  -speed. The section ``<A HREF="././performance.html#TMTOWTDI_Convenience_and_Perfor">TMTOWTDI: Convenience and Performance</A>'' compares the three approaches.
  +speed. The section ``<A HREF="././performance.html#TMTOWTDI_Convenience_and_Habit_">TMTOWTDI: Convenience and Performance</A>'' compares the three approaches.
   
  -<P><A NAME="anchor616"></A>
  +<P>
   What we are going to do is to replace <CODE>CGI.pm</CODE> and <CODE>CGI::Cookie</CODE>
   with <CODE>Apache::Request</CODE> and <CODE>Apache::Cookie</CODE> respectively. The two modules are written in C with the XS interface to
   Perl, which makes code much faster if it utilizes any of these modules a
   lot.
   <CODE>Apache::Request</CODE> uses an API similar to the one <CODE>CGI</CODE> uses, the same goes for <CODE>Apache::Cookie</CODE> and <CODE>CGI::Cookie</CODE>. This allows an easy porting process. Basically we just replace:
  +
  +<P>
   
  -<P><A NAME="anchor617"></A>
  -<PRE>  use CGI;
  -  $q = new CGI;
  -</PRE>
  -<P><A NAME="anchor618"></A>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  use CGI;
  +  $q = new CGI;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   with:
  +
  +<P>
   
  -<P><A NAME="anchor619"></A>
  -<PRE>  use Apache::Request ();
  -  my $q = Apache::Request-&gt;new($r);
  -</PRE>
  -<P><A NAME="anchor620"></A>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  use Apache::Request ();
  +  my $q = Apache::Request-&gt;new($r);</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   and
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor621"></A>
  -<PRE>  use CGI::Cookie ();
  -  my $cookie = CGI::Cookie-&gt;new(...)
  -</PRE>
  -<P><A NAME="anchor622"></A>
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  use CGI::Cookie ();
  +  my $cookie = CGI::Cookie-&gt;new(...)</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   with
   
  -<P><A NAME="anchor623"></A>
  -<PRE>  use Apache::Cookie ();
  -  my $cookie = Apache::Cookie-&gt;new($r, ...);
  -</PRE>
  -<P><A NAME="anchor624"></A>
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  use Apache::Cookie ();
  +  my $cookie = Apache::Cookie-&gt;new($r, ...);</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   This is the new code for <CODE>Test::Cookie2</CODE>:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor625"></A>
  -<PRE>  Test/Cookie2.pm
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  Test/Cookie2.pm
     --------------
     package Test::Cookie2;
     use Apache::Constants qw(:common);
  @@ -3799,115 +5708,205 @@
       return scalar localtime;
     }
     
  -  1;
  -</PRE>
  -<P><A NAME="anchor626"></A>
  +  1;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   The only other changes are in the <CODE>print_header()</CODE> function,
   where instead of passing the cookie code to the <CODE>CGI</CODE>'s <CODE>header()</CODE> to return a proper HTTP header:
  +
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
   
  -<P><A NAME="anchor627"></A>
  -<PRE>    print $q-&gt;header
  +	<td>
  +	  <pre>    print $q-&gt;header
         (-type   =&gt; 'text/html',
  -       -cookie =&gt; $c);
  -</PRE>
  -<P><A NAME="anchor628"></A>
  +       -cookie =&gt; $c);</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   we do it in two stages.
  +
  +<P>
   
  -<P><A NAME="anchor629"></A>
  -<PRE>    $c-&gt;bake;
  -</PRE>
  -<P><A NAME="anchor630"></A>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>    $c-&gt;bake;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Adds a <CODE>Set-Cookie</CODE> header to the outgoing headers table, and:
  +
  +<P>
   
  -<P><A NAME="anchor631"></A>
  -<PRE>    $r-&gt;send_http_header('text/html');
  -</PRE>
  -<P><A NAME="anchor632"></A>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>    $r-&gt;send_http_header('text/html');</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   sends out the header itself. We have also eliminated:
  +
  +<P>
   
  -<P><A NAME="anchor633"></A>
  -<PRE>    Apache-&gt;request($r);
  -</PRE>
  -<P><A NAME="anchor634"></A>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>    Apache-&gt;request($r);</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   since we don't rely on <CODE>CGI.pm</CODE> any more and in this case we don't need it.
   
  -<P><A NAME="anchor635"></A>
  +<P>
   The rest of the code is unchanged.
   
  -<P><A NAME="anchor636"></A>
  +<P>
   Of course we add the following snippet to <EM>httpd.conf</EM>:
  +
  +<P>
   
  -<P><A NAME="anchor637"></A>
  -<PRE>  PerlModule Test::Cookie2
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  PerlModule Test::Cookie2
     &lt;Location /test/cookie2&gt;
       SetHandler perl-script
       PerlHandler Test::Cookie2
  -  &lt;/Location&gt;
  -</PRE>
  -<P><A NAME="anchor638"></A>
  +  &lt;/Location&gt;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   So now the magic URI that will trigger the above code execution will be the
   one starting with <EM>/test/cookie2</EM> . We save the code in the file <EM>/home/httpd/perl/Test/Cookie2.pm</EM> since we have called this package <CODE>Test::Cookie2</CODE>.
   
  -<P><A NAME="anchor639"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="Conclusion">Conclusion</A></H2></CENTER>
  -<P><A NAME="anchor640"></A>
  +<P>
   If your took care to write the original plain CGI script's code in a clean
   and modular way, you can see that the transition is a very simple one and
   doesn't take a lot of effort. Almost no code was modified.
   
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -	     The <a href="http://www.modperl.com/">
  -	     <B>Writing Apache Modules with Perl and C</B></a>
  -	     book can be purchased online from <a
  -	     href="http://www.ora.com/catalog/wrapmod/">O'Reilly </a>
  -	     and <a
  -	     href="http://www.amazon.com/exec/obidos/ASIN/156592567X/writinapachemodu">
  -	     Amazon.com</a>.
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   
  -	     <HR>
   
  -	     <B>Your corrections of either technical or grammatical
  +    <p>
  +    <div class="navbar">
  +      <a href="scenario.html">Prev</a>                                 |
  +      <A HREF="index.html"         >Contents</A> |
  +      <A HREF="index.html#search"  >Search</A>   |
  +      <A HREF="index.html#download">Download</A> |
  +      <a href="performance.html">Next</a>
  +    </div>
  +    <p>
  +
  +    <table width="60%" align="center">
  +
  +      <tr>
  +	<td>
  +	  <div class="notice">
  +	  <B>Your corrections of the technical and grammatical
   	     errors are very welcome. You are encouraged to help me
  -	     to improve this guide.  If you have something to
  -	     contribute please <A
  -	     HREF="help.html#Contacting_me"> send it
  +	     improve this guide.  If you have something to contribute
  +	     please <A HREF="help.html#Contacting_me"> send it
   	     directly to me</A>.</B>
  +	  </div>
  +	</td>
  +      </tr>
  +
  +      <tr>
  +	<td>
  +	  <div class="ad">
  +	    The <a href="http://www.modperl.com/">
  +	      <B>Writing Apache Modules with Perl and C</B></a>
  +	    book can be purchased online from <a
  +	      href="http://www.ora.com/catalog/wrapmod/">O'Reilly </a>
  +	    and <a
  +	    href="http://www.amazon.com/exec/obidos/ASIN/156592567X/writinapachemodu">
  +	      Amazon.com</a>.
  +	  </div>
  +	</td>
  +      </tr>
  +
  +</table>
  +
  +<center>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
  +<table cellspacing=2 cellpadding=2>
  +
  +<tr align=center valign=top>
  +<td align=center valign=center>
  +
  +<b><font size=-1>Written by <a
  +href="help.html#Contacting_me">Stas Bekman</a>.<br> Last Modified at 06/07/2000
  +</font></b>
  +<br>
  +
  +</td>
  +
  +<td>
  +
  +<a href="http://perl.apache.org"><img src="images/mod_perl2.jpg"  border=0 alt="mod_perl icon" border=0 height=59 width=150></a>
  +<br>
  +
  +</td>
  +
  +<td>
  +
  +<font size=-2>Use of the Camel for Perl is <br>
  +a trademark of <a href="http://www.ora.com">O'Reilly &amp; Associates</a>,<br>
  +and is used by permission. </font> 
  +<br>
   
  -	     <HR>
  +</td>
   
  -	     [    <A HREF="scenario.html">Prev</A> |      <A HREF="index.html">Main Page</A> | <A HREF="performance.html">Next</A>      ]
  +</tr>
  +</table>
  +</center>
   
  -<CENTER><TABLE CELLSPACING=2 CELLPADDING=2 WIDTH="100%" >
  -<TR ALIGN=CENTER VALIGN=TOP>
  -  <TD ALIGN=CENTER VALIGN=CENTER COLSPAN="3">
  -	     <HR>
  -  </TD>
  -</TR>
  -<TR ALIGN=CENTER VALIGN=TOP>
  -  <TD ALIGN=CENTER VALIGN=CENTER>
  -    <B>
  -      <FONT SIZE=-1>
  -	     Written by <A HREF="help.html#Contacting_me">Stas Bekman</A>.
  -	     <BR>Last Modified at 05/13/2000
  -      </FONT>
  -    </B>
  -  </TD>
  -
  -  <TD>
  -	     <A HREF="http://perl.apache.org"><IMG SRC="images/mod_perl2.jpg" ALT="Mod Perl Icon" BORDER=0 HEIGHT=59 WIDTH=150></A>
  -  </TD>
  -
  -  <TD>
  -    <FONT SIZE=-2>
  -	     Use of the Camel for Perl is <BR>
  -	     a trademark of <A HREF="http://www.ora.com">O'Reilly &amp; Associates</A>,<BR>
  -             and is used by permission. 
  -    </FONT> 
  -  </TD>
  -</TR>
  -</TABLE></CENTER>
  -
  -</BODY>
  -</HTML>
  -	    
  \ No newline at end of file
  +</body>
  +</html>
  
  
  
  1.26      +2300 -1008modperl-site/guide/scenario.html
  
  Index: scenario.html
  ===================================================================
  RCS file: /home/cvs/modperl-site/guide/scenario.html,v
  retrieving revision 1.25
  retrieving revision 1.26
  diff -u -r1.25 -r1.26
  --- scenario.html	2000/05/12 22:42:55	1.25
  +++ scenario.html	2000/06/07 22:45:36	1.26
  @@ -1,29 +1,37 @@
   <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
  -<HTML>
  -<HEAD>
  -   <TITLE>mod_perl guide: Real World Scenarios</TITLE>
  -   <META NAME="GENERATOR" CONTENT="Pod2HTML [Perl/Linux]">
  -   <META NAME="Author" CONTENT="Stas Bekman">
  -   <META NAME="Description" CONTENT="All Apache/Perl related information: Hints, Guidelines, Scenarios and Troubleshottings">
  -   <META NAME="keywords" CONTENT="mod_perl modperl perl apache cgi webserver speed  fast guide mod_perl apache guide help info faq mod_perl installation cgi troubleshooting help no sex speedup free open source OSS mod_perl apache guide">
  -</HEAD>
  -     <LINK REL=STYLESHEET TYPE="text/css"
  -        HREF="style.css" TITLE="refstyle">
  -     <style type="text/css">
  -     <!-- 
  -        @import url(style.css);
  -     -->
  -     
  -     </style>
  -<BODY BGCOLOR="white">
  +<html>
  +  <head>
  +   <title>mod_perl guide: Real World Scenarios</title>
  +   <meta name="Author" content="Stas Bekman">
  +   <meta name="Description" content="All Apache/Perl related information: Hints, Guidelines, Scenarios and Troubleshottings">
  +   <meta name="keywords" content="mod_perl modperl perl cgi apache webserver speed fast guide mod_perl apache guide help info faq mod_perl installation cgi troubleshooting help no sex speedup free open source OSS mod_perl apache guide">
  +   <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
  +   <meta name="Classification" content="information">
  +   <link href="style.css" rel=stylesheet type="text/css" title="refstyle">
  +  </head>
  +  <body>
  +
  +    <h1 align=center>
  +      <a href="http://perl.apache.org"><img src="images/mod_perl.gif" alt="Mod Perl Icon" border=0 height=30 width=90 align=left></a>
  +      <a href="http://perl.apache.org"><img src="images/mod_perl.gif" alt="Mod Perl Icon" border=0 height=30 width=90 align=right></a>
  +      Real World Scenarios
  +    </h1>
  +    <hr>
  +    <p>
  +    <div class="navbar">
  +      <a href="strategy.html">Prev</a>                                 |
  +      <a href="index.html"         >Contents</a> |
  +      <a href="index.html#search"  >Search</a>   |
  +      <a href="index.html#download">Download</a> |
  +      <a href="porting.html">Next</a>
  +    </div>
  +    <p>
  +
  +    <div class="toc">
  +      
   <A NAME="toc"></A>
  -<H1 ALIGN=CENTER>
  -<A HREF="http://perl.apache.org"><IMG SRC="images/mod_perl.gif" ALT="Mod Perl Icon" BORDER=0 HEIGHT=30 WIDTH=90 ALIGN=LEFT></A>
  -<A HREF="http://perl.apache.org"><IMG SRC="images/mod_perl.gif" ALT="Mod Perl Icon" BORDER=0 HEIGHT=30 WIDTH=90 ALIGN=RIGHT></A>
  -Real World Scenarios</H1>
  -<HR WIDTH="100%">
  -	    [    <A HREF="strategy.html">Prev</A> |      <A HREF="index.html">Main Page</A> | <A HREF="porting.html">Next</A>      ]<HR><!-- INDEX BEGIN -->
  -<P><B><FONT SIZE=-1>Table of Contents:</FONT></B></P>
  +<P><B>Table of Contents:</B></P>
  +
   <UL>
   
   	<LI><A HREF="#Standalone_mod_perl_Enabled_Apac">Standalone mod_perl Enabled Apache Server</A>
  @@ -76,7 +84,7 @@
   		<LI><A HREF="#Buffering_Feature">Buffering Feature</A>
   		<UL>
   
  -			<LI><A HREF="#Setting_the_Buffering_Limits_on_">Setting the Buffering Limits on Various OSes</A>
  +			<LI><A HREF="#Setting_the_Buffering_Limits_on_">Setting the Buffering Limits on Various OSs</A>
   			<UL>
   
   				<LI><A HREF="#IOBUFSIZE_Source_Code_Definition">IOBUFSIZE Source Code Definition</A>
  @@ -87,7 +95,7 @@
   		</UL>
   
   		<LI><A HREF="#Caching">Caching</A>
  -		<LI><A HREF="#Building_process">Building process</A>
  +		<LI><A HREF="#Build_process">Build process</A>
   	</UL>
   
   	<LI><A HREF="#Front_end_Back_end_Proxying_with">Front-end Back-end Proxying with Virtual Hosts</A>
  @@ -98,48 +106,74 @@
   		<LI><A HREF="#Use">Use</A>
   		<LI><A HREF="#Security">Security</A>
   		<LI><A HREF="#Caveats">Caveats</A>
  -		<LI><A HREF="#mod_proxy_add_forward_Module_s_O">mod_proxy_add_forward Module's Order Precedence Importance</A>
  +		<LI><A HREF="#mod_proxy_add_forward_Module_s_O">mod_proxy_add_forward Module's Order Precedence</A>
   	</UL>
   
   	<LI><A HREF="#HTTP_Authentication_With_Two_Ser">HTTP Authentication With Two Servers Plus a Proxy</A>
   	<LI><A HREF="#mod_rewrite_Examples">mod_rewrite Examples</A>
   	<LI><A HREF="#Caching_in_mod_proxy">Caching in mod_proxy</A>
   </UL>
  -<!-- INDEX END -->
   
  +    </div>
  +
  +    [ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
   <HR>
  +    <table width="60%" align="center">
  +
  +      <tr>
  +	<td>
  +	  <div class="ad">
  +	    The <a href="http://www.modperl.com/">
  +	      <B>Writing Apache Modules with Perl and C</B></a>
  +	    book can be purchased online from <a
  +	      href="http://www.ora.com/catalog/wrapmod/">O'Reilly </a>
  +	    and <a
  +	    href="http://www.amazon.com/exec/obidos/ASIN/156592567X/writinapachemodu">
  +	      Amazon.com</a>.
  +	  </div>
  +	</td>
  +      </tr>
  +
  +      <tr>
  +	<td>
  +	  <div class="notice">
  +	  <B>Your corrections of the technical and grammatical
  +	     errors are very welcome. You are encouraged to help me
  +	     improve this guide.  If you have something to contribute
  +	     please <A HREF="help.html#Contacting_me"> send it
  +	     directly to me</A>.</B>
  +	  </div>
  +	</td>
  +      </tr>
  +
  +</table>
   
  -	     The <a href="http://www.modperl.com/">
  -	     <B>Writing Apache Modules with Perl and C</B></a>
  -	     book can be purchased online from <a
  -	     href="http://www.ora.com/catalog/wrapmod/">O'Reilly </a>
  -	     and <a
  -	     href="http://www.amazon.com/exec/obidos/ASIN/156592567X/writinapachemodu">
  -	     Amazon.com</a>.
  -
  -	     <HR>
  -
  -	       <B>Your corrections of either technical or grammatical
  -	       errors are very welcome. You are encouraged to help me
  -	       to improve this guide.  If you have something to
  -	       contribute please <A
  -	       HREF="help.html#Contacting_me"> send it
  -	       directly to me</A>.
  -	       </B>
  -	       <HR>
  +    
   
  -	      <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<P><A NAME="anchor0"></A>
  +	    [ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
  +
  +<P>
   <CENTER><H1><A NAME="Standalone_mod_perl_Enabled_Apac">Standalone mod_perl Enabled Apache Server</A></H1></CENTER>
  -<P><A NAME="anchor1"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="Installation_in_10_lines">Installation in 10 lines</A></H2></CENTER>
  -<P><A NAME="anchor2"></A>
  +<P>
   The Installation is very very simple. This example shows installation on
   the Linux operating system.
   
  -<P><A NAME="anchor3"></A>
  -<PRE>  % cd /usr/src
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  % cd /usr/src
     % lwp-download <A HREF="http://www.apache.org/dist/apache_x.x.x.tar.gz">http://www.apache.org/dist/apache_x.x.x.tar.gz</A>
     % lwp-download <A HREF="http://perl.apache.org/dist/mod_perl-x.xx.tar.gz">http://perl.apache.org/dist/mod_perl-x.xx.tar.gz</A>
     % tar xzvf apache_x.x.x.tar.gz
  @@ -149,149 +183,283 @@
       DO_HTTPD=1 USE_APACI=1 EVERYTHING=1
     % make &amp;&amp; make test &amp;&amp; make install
     % cd ../apache_x.x.x
  -  % make install
  -</PRE>
  -<P><A NAME="anchor4"></A>
  +  % make install</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   That's all!
   
  -<P><A NAME="anchor5"></A>
  +<P>
   Notes: Replace x.xx and x.x.x with the real version numbers of mod_perl and
   Apache respectively. The <CODE>z</CODE> flag tells Gnu <CODE>tar</CODE> to uncompress the archive as well as extract the files. You might need
   superuser permissions to do the make install steps.
   
  -<P><A NAME="anchor6"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="Installation_in_10_paragraphs">Installation in 10 paragraphs</A></H2></CENTER>
  -<P><A NAME="anchor7"></A>
  +<P>
   If you have the <CODE>lwp-download</CODE> utility installed, you can use it to download the sources of both packages:
   
  -<P><A NAME="anchor8"></A>
  -<PRE>  % lwp-download <A HREF="http://www.apache.org/dist/apache_x.x.x.tar.gz">http://www.apache.org/dist/apache_x.x.x.tar.gz</A>
  -  % lwp-download <A HREF="http://perl.apache.org/dist/mod_perl-x.xx.tar.gz">http://perl.apache.org/dist/mod_perl-x.xx.tar.gz</A>
  -</PRE>
  -<P><A NAME="anchor9"></A>
  -<CODE>lwp-download</CODE> is a part of the LWP module (from <CODE>libwww</CODE> package), you will need to have it installed in order for mod_perl's <CODE>make
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  % lwp-download <A HREF="http://www.apache.org/dist/apache_x.x.x.tar.gz">http://www.apache.org/dist/apache_x.x.x.tar.gz</A>
  +  % lwp-download <A HREF="http://perl.apache.org/dist/mod_perl-x.xx.tar.gz">http://perl.apache.org/dist/mod_perl-x.xx.tar.gz</A></pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +<CODE>lwp-download</CODE> is a part of the LWP module (from the <CODE>libwww</CODE> package), and you will need to have it installed in order for mod_perl's <CODE>make
   test</CODE> step to pass.
   
  -<P><A NAME="anchor10"></A>
  -Extract both sources. Usually I open all the sources in <EM>/usr/src/</EM>, but your mileage may vary. So move the sources and <CODE>chdir</CODE> to the directory that you want to put the sources in. If you have a non-gnu
  -<CODE>tar</CODE> utility it will be unable to decompress so you will do it in two steps:
  -first uncompress the packages with:
  -
  -<P><A NAME="anchor11"></A>
  -<PRE>  gzip -d apache_x.x.x.tar.gz
  -  gzip -d mod_perl-x.xx.tar.gz
  -</PRE>
  -<P><A NAME="anchor12"></A>
  +<P>
  +Extract both sources. Usually I open all the sources in <EM>/usr/src/</EM>, but your mileage may vary. So move the sources and <CODE>chdir</CODE> to the directory that you want to put the sources in. If you have a non-GNU
  +<CODE>tar</CODE> utility it will be unable to decompress so you will have to unpack in two
  +steps: first uncompress the packages with:
  +
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  gzip -d apache_x.x.x.tar.gz
  +  gzip -d mod_perl-x.xx.tar.gz</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   then un-tar them with:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor13"></A>
  -<PRE>  tar xvf apache_x.x.x.tar 
  -  tar xvf mod_perl-x.xx.tar
  -</PRE>
  -<P><A NAME="anchor14"></A>
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  tar xvf apache_x.x.x.tar 
  +  tar xvf mod_perl-x.xx.tar</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   You can probably use gunzip instead of gzip -d if you prefer.
   
  -<P><A NAME="anchor15"></A>
  -<PRE>  % cd /usr/src
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  % cd /usr/src
     % tar xzvf apache_x.x.x.tar.gz
  -  % tar xzvf mod_perl-x.xx.tar.gz
  -</PRE>
  -<P><A NAME="anchor16"></A>
  +  % tar xzvf mod_perl-x.xx.tar.gz</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   <CODE>chdir</CODE> to the mod_perl source directory:
  +
  +<P>
   
  -<P><A NAME="anchor17"></A>
  -<PRE>  % cd mod_perl-x.xx
  -</PRE>
  -<P><A NAME="anchor18"></A>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  % cd mod_perl-x.xx</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Now build the Makefile. For your first installation and most basic work the
   parameters in the example below are the only ones you will need.  <CODE>APACHE_SRC</CODE> tells the Makefile.PL where to find the Apache
  -<EM>src</EM> directory. If you have followed my suggestion and have extracted the both
  +<EM>src</EM> directory. If you have followed my suggestion and have extracted both
   sources under the directory <EM>/usr/src</EM>, then issue the command:
   
  -<P><A NAME="anchor19"></A>
  -<PRE>  % perl Makefile.PL APACHE_SRC=../apache_x.x.x/src \
  -    DO_HTTPD=1 USE_APACI=1 EVERYTHING=1
  -</PRE>
  -<P><A NAME="anchor20"></A>
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  % perl Makefile.PL APACHE_SRC=../apache_x.x.x/src \
  +    DO_HTTPD=1 USE_APACI=1 EVERYTHING=1</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   There are many additional optional parameters. You can find some of them
   later in this section and in the <A HREF="././config.html#">Server Configuration</A>
   section.
   
  -<P><A NAME="anchor21"></A>
  +<P>
   While running <CODE>perl Makefile.PL ...</CODE> the process will check for prerequisites and tell you if something is
   missing. If you are missing some of the perl packages or other software,
   you will have to install them before you proceed.
   
  -<P><A NAME="anchor22"></A>
  +<P>
   Next <CODE>make</CODE> the project. The command <CODE>make</CODE> builds the mod_perl extension and also calls <CODE>make</CODE> in the Apache source directory to build <CODE>httpd</CODE>. Then we run the <EM>test</EM> suite, and finally <EM>install</EM>
   the mod_perl modules in their proper places.
  +
  +<P>
   
  -<P><A NAME="anchor23"></A>
  -<PRE>  % make &amp;&amp; make test &amp;&amp; make install
  -</PRE>
  -<P><A NAME="anchor24"></A>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  % make &amp;&amp; make test &amp;&amp; make install</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Note that if <CODE>make</CODE> fails, neither <CODE>make test</CODE> nor <CODE>make install</CODE>
   will be executed. If <CODE>make test</CODE> fails, <CODE>make install</CODE> will be not executed.
   
  -<P><A NAME="anchor25"></A>
  +<P>
   Now change to the Apache source directory and run <CODE>make install</CODE>. This will install Apache's headers, default configuration files, build
   the Apache directory tree and put <CODE>httpd</CODE> in it.
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor26"></A>
  -<PRE>  % cd ../apache_x.x.x
  -  % make install
  -</PRE>
  -<P><A NAME="anchor27"></A>
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  % cd ../apache_x.x.x
  +  % make install</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   When you execute the above command, the Apache installation process will
   tell you how to start a freshly built webserver (you need to know the path
   of <CODE>apachectl</CODE>, more about that later) and where to find the configuration files. Write
   down both, since you will need this information very soon. On my machine
   the two important paths are:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor28"></A>
  -<PRE>  /usr/local/apache/bin/apachectl
  -  /usr/local/apache/conf/httpd.conf
  -</PRE>
  -<P><A NAME="anchor29"></A>
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  /usr/local/apache/bin/apachectl
  +  /usr/local/apache/conf/httpd.conf</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Now the build and installation processes are complete.
   
  -<P><A NAME="anchor30"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="Configuration">Configuration</A></H2></CENTER>
  -<P><A NAME="anchor31"></A>
  -First, a simple configuration. Configure apache as you usually would (set <CODE>Port</CODE>, <CODE>User</CODE>, <CODE>Group</CODE>, <CODE>ErrorLog</CODE>, other file paths etc).
  +<P>
  +First, a simple configuration. Configure Apache as you usually would (set <CODE>Port</CODE>, <CODE>User</CODE>, <CODE>Group</CODE>, <CODE>ErrorLog</CODE>, other file paths etc).
   
  -<P><A NAME="anchor32"></A>
  +<P>
   Start the server and make sure it works, then shut it down. The
   <CODE>apachectl</CODE> utility can be used to start and stop the server:
  +
  +<P>
   
  -<P><A NAME="anchor33"></A>
  -<PRE>  % /usr/local/apache/bin/apachectl start
  -  % /usr/local/apache/bin/apachectl stop
  -</PRE>
  -<P><A NAME="anchor34"></A>
  -Now we will configure Apache to run perl CGI scripts under
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  % /usr/local/apache/bin/apachectl start
  +  % /usr/local/apache/bin/apachectl stop</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +Now we will configure Apache to run perl CGI scripts under the
   <CODE>Apache::Registry</CODE> handler.
   
  -<P><A NAME="anchor35"></A>
  -You can add configuration directives to a separate file and tell
  +<P>
  +You can put configuration directives in a separate file and tell
   <EM>httpd.conf</EM> to include it, but for now we will simply add them to the main
   configuration file. We will add the mod_perl configuration directives to
   the end of <EM>httpd.conf</EM>. In fact you can place them anywhere in the file, but they are easier to
   find at the end.
   
  -<P><A NAME="anchor36"></A>
  +<P>
   For the moment we will assume that you will put all the scripts which you
   want to be executed by the mod_perl enabled server under the directory <EM>/home/httpd/perl</EM>. We will alias this directory to the URI <EM>/perl</EM>
   
   
   
  -<P><A NAME="anchor37"></A>
  +<P>
   Add the following configuration directives to <EM>httpd.conf</EM>:
  +
  +<P>
   
  -<P><A NAME="anchor38"></A>
  -<PRE>  Alias /perl/ /home/httpd/perl/
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  Alias /perl/ /home/httpd/perl/
     
     PerlModule Apache::Registry
     &lt;Location /perl&gt;
  @@ -300,119 +468,231 @@
       Options ExecCGI
       PerlSendHeader On
       allow from all
  -  &lt;/Location&gt;
  -</PRE>
  -<P><A NAME="anchor39"></A>
  +  &lt;/Location&gt;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Now create a four-line test script in <EM>/home/httpd/perl/</EM>:
  +
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
   
  -<P><A NAME="anchor40"></A>
  -<PRE>  test.pl
  +	<td>
  +	  <pre>  test.pl
     -------
     #!/usr/bin/perl -w
     use strict;
     print &quot;Content-type: text/html\r\n\r\n&quot;;
  -  print &quot;It worked!!!\n&quot;;
  -</PRE>
  -<P><A NAME="anchor41"></A>
  +  print &quot;It worked!!!\n&quot;;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Note that the server is probably running as a user with a restricted set of
   privileges, perhaps as user <CODE>nobody</CODE> or <CODE>www</CODE>. Look for the
   <CODE>User</CODE> directive in <EM>httpd.conf</EM> to find the userid of the server.
   
  -<P><A NAME="anchor42"></A>
  +<P>
   Make sure that you have read and execute permissions for <EM>test.pl</EM>.
   
  -<P><A NAME="anchor43"></A>
  -<PRE>  % chmod u+rx /home/httpd/perl/test.pl
  -</PRE>
  -<P><A NAME="anchor44"></A>
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  % chmod u+rx /home/httpd/perl/test.pl</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Test that the script works from the command line, by executing it:
  +
  +<P>
   
  -<P><A NAME="anchor45"></A>
  -<PRE>  % /home/httpd/perl/test.pl
  -</PRE>
  -<P><A NAME="anchor46"></A>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  % /home/httpd/perl/test.pl</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   You should see:
   
  -<P><A NAME="anchor47"></A>
  -<PRE>  Content-type: text/html
  -  
  -  It worked!!!
  -</PRE>
  -<P><A NAME="anchor48"></A>
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  Content-type: text/html
  +  
  +  It worked!!!</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Assuming that the server's userid is <CODE>nobody</CODE>, make the script owned by this user. We already made it executable and
   readable by user.
  +
  +<P>
   
  -<P><A NAME="anchor49"></A>
  -<PRE>  % chown nobody /home/httpd/perl/test.pl
  -</PRE>
  -<P><A NAME="anchor50"></A>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  % chown nobody /home/httpd/perl/test.pl</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Now it is time to test that mod_perl enabled Apache can execute the script.
   
  -<P><A NAME="anchor51"></A>
  +<P>
   Start the server ('<CODE>apachectl start</CODE>'). Check in <EM>logs/error_log</EM>
  -to see that indeed the server has started--verify the correct date and time
  +to see that the server has indeed started--verify the correct date and time
   of the log entry.
   
  -<P><A NAME="anchor52"></A>
  +<P>
   To get Apache to execute the script we simply fetch its URI. Assuming that
   your <EM>httpd.conf</EM> has been configured with the directive <CODE>Port
   80</CODE>, start your favorite browser and fetch the following URI:
  +
  +<P>
   
  -<P><A NAME="anchor53"></A>
  -<PRE>  <A HREF="http://www.example.com/perl/test.pl">http://www.example.com/perl/test.pl</A>
  -</PRE>
  -<P><A NAME="anchor54"></A>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  <A HREF="http://www.example.com/perl/test.pl">http://www.example.com/perl/test.pl</A></pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   If you have the loop-back device (127.0.0.1) configured, you can use the
   URI:
  +
  +<P>
   
  -<P><A NAME="anchor55"></A>
  -<PRE>  <A HREF="http://localhost/perl/test.pl">http://localhost/perl/test.pl</A>
  -</PRE>
  -<P><A NAME="anchor56"></A>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  <A HREF="http://localhost/perl/test.pl">http://localhost/perl/test.pl</A></pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   In either case, you should see:
  +
  +<P>
   
  -<P><A NAME="anchor57"></A>
  -<PRE>  It worked!!!
  -</PRE>
  -<P><A NAME="anchor58"></A>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  It worked!!!</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   If your server is listening on a port other than 80, for example 8000, then
   fetch the URI:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor59"></A>
  -<PRE>  <A HREF="http://www.example.com:8000/perl/test.pl">http://www.example.com:8000/perl/test.pl</A>
  -</PRE>
  -<P><A NAME="anchor60"></A>
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  <A HREF="http://www.example.com:8000/perl/test.pl">http://www.example.com:8000/perl/test.pl</A></pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   or whatever is appropriate.
   
  -<P><A NAME="anchor61"></A>
  +<P>
   If something went wrong, go through the installation process again, and
   make sure you didn't make a mistake. If that doesn't help, read the <CODE>INSTALL</CODE> pod document (<CODE>perlpod INSTALL</CODE>) in the mod_perl distribution directory.
   
  -<P><A NAME="anchor62"></A>
  +<P>
   Now that your mod_perl server is working, copy some of your Perl CGI
   scripts into the directory <EM>/home/httpd/perl/</EM> or below it.
   
  -<P><A NAME="anchor63"></A>
  +<P>
   If your programming techniques are good, chances are that your scripts will
   work with no modifications at all. With the mod_perl enabled server you
   will see them working very much faster.
   
  -<P><A NAME="anchor64"></A>
  +<P>
   If your programming techniques are sloppy, some of your scripts will not
   work and they may exhibit strange behaviour. Depending on the degree of
   sloppiness they may need anything from minor tweaking to a major rewrite to
   make them work properly. (See <A HREF="././debug.html#Sometimes_My_Script_Works_Somet">Sometimes My Script Works, Sometimes It Does Not</A> )
   
  -<P><A NAME="anchor65"></A>
  +<P>
   The above setup is very basic, but as with Perl, you can start to benefit
   from mod_perl from the very first moment you try it. As you become more
   familiar with mod_perl you will want to start writing Apache handlers and
   make more use of its power.
   
  -<P><A NAME="anchor66"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H1><A NAME="One_Plain_and_One_mod_perl_enabl">One Plain and One mod_perl enabled Apache Servers</A></H1></CENTER>
  -<P><A NAME="anchor67"></A>
  +<P>
   Since we are going to run two Apache servers we will need two complete (and
   different) sets of configuration, log and other files. We need a special
   directory layout. While some of the directories can be shared between the
  @@ -421,89 +701,182 @@
   these two servers as <STRONG>httpd_docs</STRONG> (plain Apache) and
   <STRONG>httpd_perl</STRONG> (Apache/mod_perl).
   
  -<P><A NAME="anchor68"></A>
  +<P>
   For this illustration, we will use <EM>/usr/local</EM> as our <EM>root</EM>
   directory. The Apache installation directories will be stored under this
   root. (<EM>/usr/local/bin</EM>, <EM>/usr/local/lib</EM> and so on.)
   
  -<P><A NAME="anchor69"></A>
  +<P>
   First let's prepare the sources. We will assume that all the sources go
   into the <EM>/usr/src</EM> directory. Since you will probably want to tune each copy of Apache
   separately, it is better to use two separate copies of the Apache source
   for this configuration. For example you might want only the httpd_docs
   server to be built with the mod_rewrite module.
   
  -<P><A NAME="anchor70"></A>
  +<P>
   Having two independent source trees will prove helpful unless you use
   dynamically shared objects (<CODE>DSO</CODE>) which is covered later in this section.
   
  -<P><A NAME="anchor71"></A>
  +<P>
   Make two subdirectories:
  +
  +<P>
   
  -<P><A NAME="anchor72"></A>
  -<PRE>  % mkdir /usr/src/httpd_docs
  -  % mkdir /usr/src/httpd_perl
  -</PRE>
  -<P><A NAME="anchor73"></A>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  % mkdir /usr/src/httpd_docs
  +  % mkdir /usr/src/httpd_perl</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Next put a set of the Apache sources into the <EM>/usr/src/httpd_docs</EM>
   directory (replace the directory <EM>/tmp</EM> with the path to the downloaded file and <CODE>x.x.x</CODE> with the version of Apache that you have downloaded):
   
  -<P><A NAME="anchor74"></A>
  -<PRE>  % cd /usr/src/httpd_docs
  -  % gzip -dc /tmp/apache_x.x.x.tar.gz | tar xvf -
  -</PRE>
  -<P><A NAME="anchor75"></A>
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  % cd /usr/src/httpd_docs
  +  % gzip -dc /tmp/apache_x.x.x.tar.gz | tar xvf -</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   or if you have GNU tar:
  +
  +<P>
   
  -<P><A NAME="anchor76"></A>
  -<PRE>  % tar xvzf /tmp/apache_x.x.x.tar.gz
  -</PRE>
  -<P><A NAME="anchor77"></A>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  % tar xvzf /tmp/apache_x.x.x.tar.gz</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Just to check we have extracted in the right way:
   
  -<P><A NAME="anchor78"></A>
  -<PRE>  % ls -l
  -  drwxr-xr-x  8 stas  stas 2048 Apr 29 17:38 apache_x.x.x/
  -</PRE>
  -<P><A NAME="anchor79"></A>
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  % ls -l
  +  drwxr-xr-x  8 stas  stas 2048 Apr 29 17:38 apache_x.x.x/</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Now prepare the httpd_perl server sources:
  +
  +<P>
   
  -<P><A NAME="anchor80"></A>
  -<PRE>  % cd /usr/src/httpd_perl
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  % cd /usr/src/httpd_perl
     % gzip -dc /tmp/apache_x.x.x.tar.gz | tar xvf -
     % gzip -dc /tmp/modperl-x.xx.tar.gz | tar xvf -
     
     % ls -l
     drwxr-xr-x  8 stas  stas 2048 Apr 29 17:38 apache_x.x.x/
  -  drwxr-xr-x  8 stas  stas 2048 Apr 29 17:38 modperl-x.xx/
  -</PRE>
  -<P><A NAME="anchor81"></A>
  +  drwxr-xr-x  8 stas  stas 2048 Apr 29 17:38 modperl-x.xx/</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Time to decide on the desired directory structure layout (where the Apache
   files go):
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor82"></A>
  -<PRE>  ROOT = /usr/local
  -</PRE>
  -<P><A NAME="anchor83"></A>
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  ROOT = /usr/local</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   The two servers can share the following directories (so we will not
   duplicate data):
   
  -<P><A NAME="anchor84"></A>
  -<PRE>  /usr/local/bin/
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  /usr/local/bin/
     /usr/local/lib
     /usr/local/include/
     /usr/local/man/
  -  /usr/local/share/
  -</PRE>
  -<P><A NAME="anchor85"></A>
  +  /usr/local/share/</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   <STRONG>Important:</STRONG> we assume that both servers are built from the same Apache source version.
   
  -<P><A NAME="anchor86"></A>
  +<P>
   The two servers will store their specific files in either the
   <EM>httpd_docs/</EM> or the <EM>httpd_perl/</EM> sub-directories:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor87"></A>
  -<PRE>  /usr/local/etc/httpd_docs/
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  /usr/local/etc/httpd_docs/
                    httpd_perl/
     
     /usr/local/sbin/httpd_docs/
  @@ -514,37 +887,51 @@
                               run/
                    httpd_perl/logs/
                               proxy/
  -                            run/
  -</PRE>
  -<P><A NAME="anchor88"></A>
  +                            run/</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   After completion of the compilation and the installation of both servers,
   you will need to configure them.
   
  -<P><A NAME="anchor89"></A>
  +<P>
   To make things clear before we proceed to the details, you should for
   example configure the plain Apache server (<EM>/usr/local/etc/httpd_docs/httpd.conf</EM>) to listen to <CODE>Port 80</CODE>. Configure the mod_perl Apache server (<EM>/usr/local/etc/httpd_perl/httpd.conf</EM>) with a different <CODE>Port</CODE>
   (e.g. 8080) from the one which the plain Apache server listens to. The port
   numbers issue will be discussed later.
   
  -<P><A NAME="anchor90"></A>
  +<P>
   The next step is to configure and compile the sources: Below are the
   procedures to compile both servers, using the directory layout I have just
   suggested.
   
  -<P><A NAME="anchor91"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="Configuration_and_Compilation_of">Configuration and Compilation of the Sources.</A></H2></CENTER>
  -<P><A NAME="anchor92"></A>
  +<P>
   I will use x.x.x instead of real version numbers so this document will
   never become obsolete :).
   
  -<P><A NAME="anchor93"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H3><A NAME="Building_the_httpd_docs_Server">Building the httpd_docs Server</A></H3></CENTER>
   <DL>
   <P><DT><STRONG><A NAME="item_Sources">Sources Configuration:</A></STRONG><DD>
  -<P><A NAME="anchor94"></A>
  -<PRE>  % cd /usr/src/httpd_docs/apache_x.x.x
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  % cd /usr/src/httpd_docs/apache_x.x.x
     % make clean
     % env CC=gcc \
     ./configure --prefix=/usr/local \
  @@ -553,72 +940,136 @@
       --localstatedir=/usr/local/var/httpd_docs \
       --runtimedir=/usr/local/var/httpd_docs/run \
       --logfiledir=/usr/local/var/httpd_docs/logs \
  -    --proxycachedir=/usr/local/var/httpd_docs/proxy
  -</PRE>
  -<P><A NAME="anchor95"></A>
  +    --proxycachedir=/usr/local/var/httpd_docs/proxy</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Notice that you actually don't have to enlist all these options, it's
   enough to replace them all with <CODE>--target=httpd_docs</CODE>.
  +
  +<P>
   
  -<P><A NAME="anchor96"></A>
  -<PRE>  % ./configure --prefix=/usr/local \
  -    --target=httpd_docs
  -</PRE>
  -<P><A NAME="anchor97"></A>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  % ./configure --prefix=/usr/local \
  +    --target=httpd_docs</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   This will use the default directory layout, but will replace <EM>apache</EM>
   with <EM>httpd_docs</EM> everywhere. It'll even rename <EM>apachectl</EM> to be
   <EM>httpd_docsctl</EM>. But we will continue with the manual directory tuning in the scenario
   below.
   
  -<P><A NAME="anchor98"></A>
  +<P>
   If you need some other modules, such as mod_rewrite and mod_include (SSI),
   add them to the end of this list:
  +
  +<P>
   
  -<P><A NAME="anchor99"></A>
  -<PRE>    ....
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>    ....
       ....
       --proxycachedir=/usr/local/var/httpd_docs/proxy \
  -    --enable-module=include --enable-module=rewrite
  -</PRE>
  -<P><A NAME="anchor100"></A>
  +    --enable-module=include --enable-module=rewrite</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   OS specific note: The httpd executable is at least 100K smaller if compiled
  -by <CODE>gcc</CODE> than if compiled <CODE>cc</CODE> on AIX. Remove the line
  +by <CODE>gcc</CODE> than if compiled with <CODE>cc</CODE> on AIX. Remove the line
   <CODE>env CC=gcc</CODE> if you want to use the default compiler. If you want to use it and you are
   a (ba)?sh user you will not need the <CODE>env</CODE>
   function, t?csh users will have to keep it. 
   
  -<P><A NAME="anchor101"></A>
  +<P>
   It's very important to use the same compiler you build the perl with. See
   the section '<A HREF="././install.html#What_Compiler_Should_Be_Used_to_">What Compiler Should Be Used to Build mod_perl</A>' for more information.
   
  -<P><A NAME="anchor102"></A>
  +<P>
   Note: Add <CODE>--layout</CODE> to see the resulting directories' layout without actually running the
   configuration process.
   
   <P><DT><STRONG><A NAME="item_Source">Source Compilation:</A></STRONG><DD>
  -<P><A NAME="anchor103"></A>
  -<PRE>  % make
  -  % make install
  -</PRE>
  -<P><A NAME="anchor104"></A>
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  % make
  +  % make install</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Rename <CODE>httpd</CODE> to <CODE>http_docs</CODE>:
   
  -<P><A NAME="anchor105"></A>
  -<PRE>  % mv /usr/local/sbin/httpd_docs/httpd \
  -  /usr/local/sbin/httpd_docs/httpd_docs
  -</PRE>
  -<P><A NAME="anchor106"></A>
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  % mv /usr/local/sbin/httpd_docs/httpd \
  +  /usr/local/sbin/httpd_docs/httpd_docs</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Now modify the <STRONG>apachectl</STRONG> utility to point to the renamed httpd via your favorite text editor or by
   using perl:
  +
  +<P>
   
  -<P><A NAME="anchor107"></A>
  -<PRE>  % perl -p -i -e 's|httpd_docs/httpd|httpd_docs/httpd_docs|' \
  -  /usr/local/sbin/httpd_docs/apachectl
  -</PRE>
  -</DL>
  -<P><A NAME="anchor108"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  % perl -p -i -e 's|httpd_docs/httpd|httpd_docs/httpd_docs|' \
  +  /usr/local/sbin/httpd_docs/apachectl</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    </DL>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H3><A NAME="Building_the_httpd_perl_Server">Building the httpd_perl Server</A></H3></CENTER>
  -<P><A NAME="anchor109"></A>
  +<P>
   Before you start to configure the mod_perl sources, you should be aware
   that there are a few Perl modules that have to be installed before building
   mod_perl. You will be alerted if any required modules are missing when you
  @@ -626,84 +1077,144 @@
   nearest CPAN repository (if you do not know what that is, pay a visit to <A
   HREF="http://www.perl.com/CPAN">http://www.perl.com/CPAN</A>) or run the <CODE>CPAN</CODE> interactive shell via the command line <CODE>perl -MCPAN -e shell</CODE>.
   
  -<P><A NAME="anchor110"></A>
  +<P>
   Make sure the sources are clean:
   
  -<P><A NAME="anchor111"></A>
  -<PRE>  % cd /usr/src/httpd_perl/apache_x.x.x
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  % cd /usr/src/httpd_perl/apache_x.x.x
     % make clean
     % cd /usr/src/httpd_perl/mod_perl-x.xx
  -  % make clean
  -</PRE>
  -<P><A NAME="anchor112"></A>
  +  % make clean</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   It is important to <STRONG>make clean</STRONG> since some of the versions are not binary compatible (e.g apache 1.3.3 vs
   1.3.4) so any ``third-party'' C modules need to be re-compiled against the
   latest header files.
  +
  +<P>
   
  -<P><A NAME="anchor113"></A>
  -<PRE>  % cd /usr/src/httpd_perl/mod_perl-x.xx
  -</PRE>
  -<P><A NAME="anchor114"></A>
  -<PRE>  % /usr/local/bin/perl Makefile.PL \
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  % cd /usr/src/httpd_perl/mod_perl-x.xx</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  % /usr/local/bin/perl Makefile.PL \
     APACHE_PREFIX=/usr/local \
     APACHE_SRC=../apache_x.x.x/src \
     DO_HTTPD=1 \
     USE_APACI=1 \
     PERL_STACKED_HANDLERS=1 \
     ALL_HOOKS=1 \
  -  APACI_ARGS=--sbindir=/usr/local/sbin/httpd_perl, \
  +  APACI_ARGS='--sbindir=/usr/local/sbin/httpd_perl, \
            --sysconfdir=/usr/local/etc/httpd_perl, \
            --localstatedir=/usr/local/var/httpd_perl, \
            --runtimedir=/usr/local/var/httpd_perl/run, \
            --logfiledir=/usr/local/var/httpd_perl/logs, \
  -         --proxycachedir=/usr/local/var/httpd_perl/proxy
  -</PRE>
  -<P><A NAME="anchor115"></A>
  +         --proxycachedir=/usr/local/var/httpd_perl/proxy'</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Notice that <STRONG>all</STRONG>  <CODE>APACI_ARGS</CODE> (above) must be passed as one long line if you work with <CODE>t?csh</CODE>!!! However with <CODE>(ba)?sh</CODE> it works correctly the way it is shown above, breaking the long lines with
   '<CODE>\</CODE>'. When <CODE>t?csh</CODE> passes the <CODE>APACI_ARGS</CODE> arguments to
   <CODE>./configure</CODE> it does not alter the newlines, but it strips the backslashes, thus
   breaking the configuration process.
   
  -<P><A NAME="anchor116"></A>
  +<P>
   Notice that just like in httpd_docs configuration you can use
   <CODE>--target=httpd_perl</CODE> instead of specifying each directory separately. Note that this option has
   to be the very last argument in
   <CODE>APACI_ARGS</CODE>, otherwise 'make test' tries to run ``httpd_perl,'' which fails.
   
  -<P><A NAME="anchor117"></A>
  +<P>
   This will use the default directory layout, but will replace <EM>apache</EM>
  -with <EM>httpd_docs</EM> everywhere. It'll even rename <EM>apachectl</EM> to be
  -<EM>httpd_docsctl</EM>. But we will continue with the manual directory tuning in the scenario
  +with <EM>httpd_perl</EM> everywhere. It'll even rename <EM>apachectl</EM> to be
  +<EM>httpd_perlctl</EM>. But we will continue with the manual directory tuning in the scenario
   below.
   
  -<P><A NAME="anchor118"></A>
  +<P>
   As with httpd_docs you might need other modules such as
   <CODE>mod_rewrite</CODE>, so add them at the end of this list:
  +
  +<P>
   
  -<P><A NAME="anchor119"></A>
  -<PRE>         ....
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>         ....
            ....
            --proxycachedir=/usr/local/var/httpd_perl/proxy, \
  -         --enable-module=rewrite
  -</PRE>
  -<P><A NAME="anchor120"></A>
  +         --enable-module=rewrite</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Note: <CODE>PERL_STACKED_HANDLERS=1</CODE> is needed for <CODE>Apache::DBI</CODE>
   
   
   
  -<P><A NAME="anchor121"></A>
  +<P>
   Now, build, test and install the <CODE>httpd_perl</CODE>.
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor122"></A>
  -<PRE>  % make &amp;&amp; make test &amp;&amp; make install
  -</PRE>
  -<P><A NAME="anchor123"></A>
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  % make &amp;&amp; make test &amp;&amp; make install</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Note: Apache puts a stripped version of <CODE>httpd</CODE> at
   <EM>/usr/local/sbin/httpd_perl/httpd</EM>. The original version which includes debugging symbols (if you need to run
   a debugger on this executable) is located at
   <EM>/usr/src/httpd_perl/apache_x.x.x/src/httpd</EM>.
   
  -<P><A NAME="anchor124"></A>
  +<P>
   Note: You may have noticed that we did not run <CODE>make install</CODE> in the Apache source directory. When <CODE>USE_APACI</CODE> is enabled,
   <CODE>APACHE_PREFIX</CODE> will specify the <CODE>--prefix</CODE> option for Apache's
   <CODE>configure</CODE> utility, which gives the installation path for Apache. When this option is
  @@ -711,38 +1222,64 @@
   install</CODE> for Apache, installing the httpd binary, the support tools, and the
   configuration, log and document trees.
   
  -<P><A NAME="anchor125"></A>
  +<P>
   If <CODE>make test</CODE> fails, look into <CODE>t/logs</CODE> and see what is in there. Also see <A HREF="././install.html#make_test_fails">make test fails</A>.
   
  -<P><A NAME="anchor126"></A>
  +<P>
   While doing <CODE>perl Makefile.PL ...</CODE> mod_perl might complain by warning you about a missing library <CODE>libgdbm</CODE>. This is a crucial warning. See
   <A HREF="././install.html#Missing_or_Misconfigured_libgdbm">Missing or Misconfigured libgdbm.so</A> for more info.
   
  -<P><A NAME="anchor127"></A>
  +<P>
   Now rename <CODE>httpd</CODE> to <CODE>httpd_perl</CODE>:
   
  -<P><A NAME="anchor128"></A>
  -<PRE>  % mv /usr/local/sbin/httpd_perl/httpd \
  -  /usr/local/sbin/httpd_perl/httpd_perl
  -</PRE>
  -<P><A NAME="anchor129"></A>
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  % mv /usr/local/sbin/httpd_perl/httpd \
  +  /usr/local/sbin/httpd_perl/httpd_perl</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Update the apachectl utility to drive the renamed httpd:
  +
  +<P>
   
  -<P><A NAME="anchor130"></A>
  -<PRE>  % perl -p -i -e 's|httpd_perl/httpd|httpd_perl/httpd_perl|' \
  -  /usr/local/sbin/httpd_perl/apachectl
  -</PRE>
  -<P><A NAME="anchor131"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  % perl -p -i -e 's|httpd_perl/httpd|httpd_perl/httpd_perl|' \
  +  /usr/local/sbin/httpd_perl/apachectl</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="Configuration_of_the_servers">Configuration of the servers</A></H2></CENTER>
  -<P><A NAME="anchor132"></A>
  +<P>
   Now when we have completed the building process, the last stage before
   running the servers is to configure them.
   
  -<P><A NAME="anchor133"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H3><A NAME="Basic_httpd_docs_Server_Configur">Basic httpd_docs Server Configuration</A></H3></CENTER>
  -<P><A NAME="anchor134"></A>
  +<P>
   Configuring of the <CODE>httpd_docs</CODE> server is a very easy task. Starting from version 1.3.4 of Apache, there is
   only one file to edit. Open
   <EM>/usr/local/etc/httpd_docs/httpd.conf</EM> in your favorite text editor and configure it as you usually would, except
  @@ -750,203 +1287,336 @@
   and so on) and the other paths according to the layout you have decided to
   use.
   
  -<P><A NAME="anchor135"></A>
  +<P>
   Start the server with:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor136"></A>
  -<PRE>  /usr/local/sbin/httpd_docs/apachectl start
  -</PRE>
  -<P><A NAME="anchor137"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  /usr/local/sbin/httpd_docs/apachectl start</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H3><A NAME="Basic_httpd_perl_Server_Configur">Basic httpd_perl Server Configuration</A></H3></CENTER>
  -<P><A NAME="anchor138"></A>
  +<P>
   Edit the <EM>/usr/local/etc/httpd_perl/httpd.conf</EM>. As with the
   <CODE>httpd_docs</CODE> server configuration, make sure that <CODE>ErrorLog</CODE> and other file location directives are set to point to the right places,
   according to the chosen directory layout.
   
  -<P><A NAME="anchor139"></A>
  +<P>
   The first thing to do is to set a <CODE>Port</CODE> directive - it should be different from that used by the plain Apache
   server (<CODE>Port 80</CODE>) since we cannot bind two servers to the same port number on the same
   machine. Here we will use <CODE>8080</CODE>. Some developers use port <CODE>81</CODE>, but you can bind to ports below 1024 only if the server has root
  -permissions. If you are running on multiuser machine, there is a chance
  -someone already uses that port, or will start using it in the future, which
  -could cause problems. If you are the only user on your machine, basically
  -you can pick any unused port number. Many organizations use firewalls which
  -may block some of the ports, so port number choice can be a controversial
  -topic. From my experience the most popular port numbers are: <CODE>80</CODE>, <CODE>81</CODE>, <CODE>8000</CODE> and <CODE>8080</CODE>. Personally, I prefer the port <CODE>8080</CODE>. Of course with the two server scenario you can hide the nonstandard port
  +permissions. If you are running on a multiuser machine, there is a chance
  +that someone already uses that port, or will start using it in the future,
  +which could cause problems. If you are the only user on your machine,
  +basically you can pick any unused port number. Many organizations use
  +firewalls which may block some of the ports, so port number choice can be a
  +controversial topic. From my experience the most popular port numbers are: <CODE>80</CODE>, <CODE>81</CODE>, <CODE>8000</CODE> and <CODE>8080</CODE>. Personally, I prefer the port <CODE>8080</CODE>. Of course with the two server scenario you can hide the nonstandard port
   number from firewalls and users, by using either mod_proxy's <CODE>ProxyPass</CODE> directive or a proxy server like Squid.
   
  -<P><A NAME="anchor140"></A>
  +<P>
   For more details see <A HREF="././config.html#Publishing_Port_Numbers_other_th">Publishing Port Numbers other than 80</A>, <A HREF="././scenario.html#Running_One_Webserver_and_Squid_">Running One Webserver and Squid in httpd Accelerator Mode</A>, <A HREF="././scenario.html#Running_Two_webservers_and_Squid">Running Two Webservers and Squid in httpd Accelerator Mode</A> and <A HREF="././scenario.html#mod_proxy">Using mod_proxy</A>.
   
  -<P><A NAME="anchor141"></A>
  +<P>
   Now we proceed to the mod_perl specific directives. It will be a good idea
   to add them all at the end of <CODE>httpd.conf</CODE>, since you are going to fiddle about with them a lot in the early stages.
   
  -<P><A NAME="anchor142"></A>
  +<P>
   First, you need to specify the location where all mod_perl scripts will be
   located.
   
  -<P><A NAME="anchor143"></A>
  +<P>
   Add the following configuration directive:
  +
  +<P>
   
  -<P><A NAME="anchor144"></A>
  -<PRE>    # mod_perl scripts will be called from
  -  Alias /perl/ /usr/local/myproject/perl/
  -</PRE>
  -<P><A NAME="anchor145"></A>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>    # mod_perl scripts will be called from
  +  Alias /perl/ /usr/local/myproject/perl/</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   From now on, all requests for URIs starting with <EM>/perl</EM> will be executed under mod_perl and will be mapped to the files in
   <EM>/usr/local/myproject/perl/</EM>.
   
  -<P><A NAME="anchor146"></A>
  +<P>
   Now we configure the <EM>/perl</EM> location.
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor147"></A>
  -<PRE>  PerlModule Apache::Registry
  -</PRE>
  -<P><A NAME="anchor148"></A>
  -<PRE>  &lt;Location /perl&gt;
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  PerlModule Apache::Registry</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  &lt;Location /perl&gt;
       #AllowOverride None
       SetHandler perl-script
       PerlHandler Apache::Registry
       Options ExecCGI
       allow from all
       PerlSendHeader On
  -  &lt;/Location&gt;
  -</PRE>
  -<P><A NAME="anchor149"></A>
  +  &lt;/Location&gt;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   This configuration causes any script that is called with a path prefixed
   with <EM>/perl</EM> to be executed under the <CODE>Apache::Registry</CODE>
   module and as a CGI (hence the <CODE>ExecCGI</CODE>--if you omit this option the script will be printed to the user's browser
   as plain text or will possibly trigger a '<STRONG>Save-As</STRONG>' window). The <CODE>Apache::Registry</CODE>
  -module lets you run your (carefully written) Perl CGI scripts almost
  -completely unchanged under mod_perl. The <CODE>PerlModule</CODE> directive is the equivalent of Perl's <CODE>require().</CODE> We load the <CODE>Apache::Registry</CODE>
  +module lets you run your (carefully written) Perl CGI scripts virtually
  +unchanged under mod_perl. The <CODE>PerlModule</CODE> directive is the equivalent of Perl's <CODE>require().</CODE> We load the <CODE>Apache::Registry</CODE>
   module before we use it by giving the <CODE>PerlHandler</CODE>
   
   <CODE>Apache::Registry</CODE> directive.
   
  -<P><A NAME="anchor150"></A>
  +<P>
   <CODE>PerlSendHeader On</CODE> tells the server to send an HTTP header to the browser on every script
   invocation. You will want to turn this off for nph (non-parsed-headers)
   scripts.
   
  -<P><A NAME="anchor151"></A>
  +<P>
   This is only a very basic configuration. The <A HREF="././config.html#">Server Configuration</A> section covers the rest of the details.
   
  -<P><A NAME="anchor152"></A>
  +<P>
   Now start the server with:
  +
  +<P>
   
  -<P><A NAME="anchor153"></A>
  -<PRE>  /usr/local/sbin/httpd_perl/apachectl start
  -</PRE>
  -<P><A NAME="anchor154"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  /usr/local/sbin/httpd_perl/apachectl start</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H1><A NAME="Running_Two_webservers_and_Squid">Running Two webservers and Squid in httpd Accelerator Mode</A></H1></CENTER>
  -<P><A NAME="anchor155"></A>
  +<P>
   While I have detailed the mod_perl server installation, you are on your own
   with installing the Squid server (See <A HREF="././help.html#">Getting Helped</A> for more details). I run Linux, so I downloaded the RPM package, installed
   it, configured the <EM>/etc/squid/squid.conf</EM>, fired off the server and all was set.
   
  -<P><A NAME="anchor156"></A>
  +<P>
   Basically once you have Squid installed, you just need to modify the
   default <CODE>squid.conf</CODE> as I will explain below, then you are ready to run it.
   
  -<P><A NAME="anchor157"></A>
  +<P>
   First, let's take a look at what we have already running and what we want
   from squid.
   
  -<P><A NAME="anchor158"></A>
  +<P>
   We have the <CODE>httpd_docs</CODE> and <CODE>httpd_perl</CODE> servers listening on ports 80 and 8080. We want squid to listen on port 80,
   to forward requests for static objects (plain HTML pages, images and so on)
   to the port which the httpd_docs server listens to, and dynamic requests to
   httpd_perl's port. This is known as <CODE>httpd accelerator mode</CODE> in proxy dialect.
   
  -<P><A NAME="anchor159"></A>
  +<P>
   Our httpd_docs is listening to port 80, so we will have to reconfigure it
   to listen to port 81, since port 80 will be taken by Squid. Both copies of
   Apache will reside on the same machine as Squid. A proxy server makes all
  -the magic behind it transparent to user. Both Apache servers return the
  +the magic behind it transparent to users. Both Apache servers return the
   data to Squid (unless it was already cached by Squid). The client never
   sees the other ports and never knows that there might be more than one
   server running. Do not confuse this scenario with <STRONG>mod_rewrite</STRONG>, where a server redirects the request somewhere according to the rewrite
   rules and forgets all about it.
   
  -<P><A NAME="anchor160"></A>
  +<P>
   Squid can be used as a straightforward proxy server. ISPs and other
   companies generally use it to cut down the incoming traffic by caching the
   most popular requests. However we want to run it in <CODE>httpd
   accelerator mode</CODE>. Two directives (<CODE>httpd_accel_host</CODE> and
   <CODE>httpd_accel_port</CODE>) enable this mode. We will see more details shortly.  
   
  -<P><A NAME="anchor161"></A>
  +<P>
   If you are currently using Squid in the regular proxy mode, you can extend
   its functionality by running both modes concurrently. To accomplish this,
   you can extend the existing Squid configuration with
   <STRONG>httpd accelerator mode</STRONG>'s related directives or you can just create one from scratch.
   
  -<P><A NAME="anchor162"></A>
  +<P>
   Now that you have Squid listening to port 80, you have to move the
   httpd_docs server to listen for example to port 81 (your mileage may vary
   :). So you have to modify httpd_docs/conf/httpd.conf and restart the
   httpd_docs server. But if you are working on a production server, do not do
   this before we get Squid running!
   
  -<P><A NAME="anchor163"></A>
  +<P>
   Let's go through the changes we should make to the default configuration
   file. Since this file (<EM>/etc/squid/squid.conf</EM>) is huge (about 60k+) and we will not alter 95% of its default settings,
   my suggestion is to write a new one including only the modified directives.
   
  -<P><A NAME="anchor164"></A>
  +<P>
   We want to enable the redirect feature, to be able to serve requests by
   more than one server (in our case we have two: the httpd_docs and
   httpd_perl servers). So we specify <CODE>httpd_accel_host</CODE> as virtual. This assumes that your server has multiple interfaces - Squid
   will bind to all of them.
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor165"></A>
  -<PRE>  httpd_accel_host virtual
  -</PRE>
  -<P><A NAME="anchor166"></A>
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  httpd_accel_host virtual</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Then we define the default port the requests will be sent to, unless
   redirected. We assume that most requests will be for static documents (also
  -it's easier to define redirect rules for mod_perl server because of the URI
  -that starts with <EM>perl</EM> or similar). We have our httpd_docs listening on port 81. Therefore we made
  -this part particular choice.
  -
  -<P><A NAME="anchor167"></A>
  -<PRE>  httpd_accel_port 81
  -</PRE>
  -<P><A NAME="anchor168"></A>
  +it's easier to define redirect rules for the mod_perl server because of the
  +URI that starts with <EM>perl</EM> or similar). We have our httpd_docs listening on port 81:
  +
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  httpd_accel_port 81</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   And as described before, squid listens to port 80.
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor169"></A>
  -<PRE>  http_port 80
  -</PRE>
  -<P><A NAME="anchor170"></A>
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  http_port 80</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   We do not use <CODE>icp</CODE> (<CODE>icp</CODE> is used for cache sharing between neighboring machines, which is more
   relevant in the proxy mode).
   
  -<P><A NAME="anchor171"></A>
  -<PRE>  icp_port 0
  -</PRE>
  -<P><A NAME="anchor172"></A>
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  icp_port 0</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   <CODE>hierarchy_stoplist</CODE> defines a list of words which, if found in a URL, causes the object to be
   handled directly by the cache. In other words, use this cache and do not
   query neighboring caches for certain objects. Note that I have configured
   the <EM>/cgi-bin</EM> and <EM>/perl</EM>
   aliases for my dynamic documents, if you named them in a different way,
   make sure you use the correct aliases here.
  +
  +<P>
   
  -<P><A NAME="anchor173"></A>
  -<PRE>  hierarchy_stoplist /cgi-bin /perl
  -</PRE>
  -<P><A NAME="anchor174"></A>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  hierarchy_stoplist /cgi-bin /perl</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Now we tell squid not to cache dynamic pages.
   
  -<P><A NAME="anchor175"></A>
  -<PRE>  acl QUERY urlpath_regex /cgi-bin /perl
  -  no_cache deny QUERY
  -</PRE>
  -<P><A NAME="anchor176"></A>
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  acl QUERY urlpath_regex /cgi-bin /perl
  +  no_cache deny QUERY</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Please note that the last two directives are controversial ones. If you
   want your scripts to be more compliant with the HTTP standards, according
   to the HTTP specs the headers of your scripts should carry the <EM>Caching Directives</EM>: <CODE>Last-Modified</CODE> and <CODE>Expires</CODE>. What are they for? (*) If you set the headers correctly, there is no need
  @@ -958,30 +1628,42 @@
   half as much work to do as they did before you installed Squid (or
   mod_proxy). But this is only possible if you set the headers correctly.
   
  -<P><A NAME="anchor177"></A>
  +<P>
   For more information, refere to the chapter <A HREF="././correct_headers.html#">Correct Headers - A quick guide for mod_perl users</A>.
   
  -<P><A NAME="anchor178"></A>
  +<P>
   Even if you insert a user-ID and date in your page, caching can save
   resources when you set the expiration time to 1 second. A user might double
   click where a single click would do, thus sending two requests in parallel.
   Squid could serve the second request.
   
  -<P><A NAME="anchor179"></A>
  +<P>
   But if you are lazy, or just have too many things to deal with, you can
   leave the above directives the way I described. Just keep in mind that one
   day you will want to reread this snippet and <A HREF="././correct_headers.html#">the headers generation tutorial</A> to squeeze even more power from your servers without investing money in
   more memory and better hardware.
   
  -<P><A NAME="anchor180"></A>
  +<P>
   While testing you might want to enable the debugging options and watch the
   log files in <EM>/var/log/squid/</EM>. But turn debugging off in your production server. Below I show it
   commented out. The parameter 28 means access control routes.
  +
  +<P>
   
  -<P><A NAME="anchor181"></A>
  -<PRE>  # debug_options ALL, 1, 28, 9
  -</PRE>
  -<P><A NAME="anchor182"></A>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  # debug_options ALL, 1, 28, 9</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   We need to provide a way for squid to dispatch requests to the correct
   servers. Static object requests should be redirected to httpd_docs unless
   they are already cached, while requests for dynamic documents should go to
  @@ -989,26 +1671,59 @@
   redirect daemons at the specified path of the redirect daemon and (as
   suggested by Squid's documentation) disables rewriting of any <CODE>Host:</CODE> headers in redirected requests. The redirection daemon script is listed
   below.
  +
  +<P>
   
  -<P><A NAME="anchor183"></A>
  -<PRE>  redirect_program /usr/lib/squid/redirect.pl
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  redirect_program /usr/lib/squid/redirect.pl
     redirect_children 10
  -  redirect_rewrites_host_header off
  -</PRE>
  -<P><A NAME="anchor184"></A>
  +  redirect_rewrites_host_header off</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   The maximum allowed request size is in kilobytes. This one is pretty
   obvious. If you are using <CODE>POST</CODE> to upload files, then set this to the largest file's size plus a few extra
   kbytes.
  +
  +<P>
   
  -<P><A NAME="anchor185"></A>
  -<PRE>  request_size 1000 KB
  -</PRE>
  -<P><A NAME="anchor186"></A>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  request_size 1000 KB</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Then we have access permissions, which I will not explain. You might want
   to read the documentation, so as to avoid any security problems.
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor187"></A>
  -<PRE>  acl all src 0.0.0.0/0.0.0.0
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  acl all src 0.0.0.0/0.0.0.0
     acl manager proto cache_object
     acl localhost src 127.0.0.1/255.255.255.255
     acl myserver src 127.0.0.1/255.255.255.255
  @@ -1021,45 +1736,129 @@
     http_access deny manager
     http_access deny !Safe_ports
     http_access deny CONNECT !SSL_ports
  -  # http_access allow all
  -</PRE>
  -<P><A NAME="anchor188"></A>
  +  # http_access allow all</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Since Squid should be run as a non-root user, you need these if you are
   invoking the Squid as root.
   
  -<P><A NAME="anchor189"></A>
  -<PRE>  cache_effective_user squid
  -  cache_effective_group squid
  -</PRE>
  -<P><A NAME="anchor190"></A>
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  cache_effective_user squid
  +  cache_effective_group squid</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Now configure a memory size to be used for caching. The Squid documentation
   warns that the actual size of Squid can grow to be three times larger than
   the value you set.
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor191"></A>
  -<PRE>  cache_mem 20 MB
  -</PRE>
  -<P><A NAME="anchor192"></A>
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  cache_mem 20 MB</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Keep pools of allocated (but unused) memory available for future use. Read
   more about it in the Squid documents.
   
  -<P><A NAME="anchor193"></A>
  -<PRE>  memory_pools on
  -</PRE>
  -<P><A NAME="anchor194"></A>
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  memory_pools on</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Now tighten the runtime permissions of the cache manager CGI script (<CODE>cachemgr.cgi</CODE>, which comes bundled with squid) on your production server.
  +
  +<P>
   
  -<P><A NAME="anchor195"></A>
  -<PRE>  cachemgr_passwd disable shutdown
  -  #cachemgr_passwd none all
  -</PRE>
  -<P><A NAME="anchor196"></A>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  cachemgr_passwd disable shutdown
  +  #cachemgr_passwd none all</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Now the redirection daemon script (you should put it at the location you
   have specified in the <CODE>redirect_program</CODE> parameter in the config file above, and make it executable by the webserver
   of course):
  +
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  #!/usr/local/bin/perl -p
  +  BEGIN{ $|=1 }
  +  s|www.example.com(?::81)?/perl/|www.example.com:8080/perl/|o ;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +Here is what the regular expression from above does; it matches all the
  +URIs that include either the string <EM>www.example.com/perl/</EM> or the string <EM>www.example.com:81/perl/</EM> and replaces either of these strings with <EM>www.example.com:8080/perl</EM>. No matter whether the regular expression worked or not, the <CODE>$_</CODE> variable is automagically printed.
  +
  +<P>
  +We can write the above code as the following code as well:
   
  -<P><A NAME="anchor197"></A>
  -<PRE>  #!/usr/local/bin/perl
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  #!/usr/local/bin/perl
     
     $|=1;
     
  @@ -1067,27 +1866,22 @@
         # redirect to mod_perl server (httpd_perl)
       print($_), next 
         if s|www.example.com(:81)?/perl/|www.example.com:8080/perl/|o;
  -</PRE>
  -<P><A NAME="anchor198"></A>
  -<PRE>      # send it unchanged to plain apache server (http_docs)
  +  
  +      # send it unchanged to plain apache server (http_docs)
       print;
  -  }
  -</PRE>
  -<P><A NAME="anchor199"></A>
  -Here is what the regular expression from above does; it matches all the
  -URIs that include either <EM>www.example.com/perl/</EM> or
  -<EM>www.example.com:81/perl/</EM> strings in them and replaces it with
  -<EM>www.example.com:8080</EM>. When the match-n-replace is completed and it was successful, the
  -resulting URI is printed. Otherwise the original URI is printed.
  -
  -<P><A NAME="anchor200"></A>
  +  }</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   The above redirector can be more complex of course, but you know Perl,
   right?
   
  -<P><A NAME="anchor201"></A>
  +<P>
   A few notes regarding the redirector script:
   
  -<P><A NAME="anchor202"></A>
  +<P>
   You must disable buffering.  <CODE>$|=1;</CODE> does the job. If you do not disable buffering, <CODE>STDOUT</CODE> will be flushed only when its buffer becomes full--and its default size is
   about 4096 characters. So if you have an average URL of 70 chars, only
   after about 59 (4096/70) requests will the buffer be flushed, and the
  @@ -1095,82 +1889,130 @@
   unless you have hundreds requests per second and then the buffer will be
   flushed very frequently because it'll get full very fast.
   
  -<P><A NAME="anchor203"></A>
  +<P>
   If you think that this is a very ineffective way to redirect, I'll try to
  -prove you the opposite. The redirector runs as a daemon, it fires up N
  -redirect daemons, so there is no problem with Perl interpreter loading.
  -Exactly as with mod_perl, perl is loaded all the time and the code has
  -already been compiled, so the redirect is very fast (not much slower than
  -if the redirector was written in C). Squid keeps an open pipe to each
  -redirect daemon, thus there is not even the overhead of the system calls.
  +prove otherwise. The redirector runs as a daemon, it fires up N redirect
  +daemons, so there is no problem with Perl interpreter loading. Exactly as
  +with mod_perl, perl is loaded all the time and the code has already been
  +compiled, so the redirect is very fast (not much slower than if the
  +redirector was written in C). Squid keeps an open pipe to each redirect
  +daemon, thus there is not even the overhead of the system calls.
   
  -<P><A NAME="anchor204"></A>
  +<P>
   Now it is time to restart the server, at linux I do it with:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor205"></A>
  -<PRE>  /etc/rc.d/init.d/squid restart
  -</PRE>
  -<P><A NAME="anchor206"></A>
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  /etc/rc.d/init.d/squid restart</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Now the setup is complete ...
   
  -<P><A NAME="anchor207"></A>
  +<P>
   Almost... When you try the new setup, you will be surprised and upset to
   discover port 81 showing up in the URLs of the static objects (like htmls).
   Hey, we did not want the user to see the port 81 and use it instead of 80,
   since then it will bypass the squid server and the hard work we went
   through was just a waste of time!
   
  -<P><A NAME="anchor208"></A>
  +<P>
   The solution is to make both squid and httpd_docs listen to the same port.
   This can be accomplished by binding each one to a specific interface (so
   they are listening to different <STRONG>sockets</STRONG>). Modify
   <CODE>httpd.conf</CODE> in the <CODE>httpd_docs</CODE> configuration directory:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor209"></A>
  -<PRE>  Port 80
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  Port 80
     BindAddress 127.0.0.1
  -  Listen 127.0.0.1:80
  -</PRE>
  -<P><A NAME="anchor210"></A>
  +  Listen 127.0.0.1:80</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Modify <EM>squid.conf</EM>:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor211"></A>
  -<PRE>  http_port 80
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  http_port 80
     tcp_incoming_address 123.123.123.3
     tcp_outgoing_address 127.0.0.1
     httpd_accel_host 127.0.0.1
  -  httpd_accel_port 80
  -</PRE>
  -<P><A NAME="anchor212"></A>
  +  httpd_accel_port 80</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Where <CODE>123.123.123.3</CODE> should be replaced with the IP address of your main server. Now restart
   squid and httpd_docs (it doesn't matter which one you start first), and
   voila--the port number has gone.
   
  -<P><A NAME="anchor213"></A>
  +<P>
   You must also have in the <EM>/etc/hosts</EM> an entry (chances are that it's already there):
   
  -<P><A NAME="anchor214"></A>
  -<PRE>  127.0.0.1 localhost.localdomain localhost
  -</PRE>
  -<P><A NAME="anchor215"></A>
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  127.0.0.1 localhost.localdomain localhost</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Now if your scripts are generating HTML including fully qualified self
  -references, using the 8080 or other port, you should fix them to generate
  +references, using 8080 or the other port, you should fix them to generate
   links to point to port 80 (which means not using the port at all in the
   URI). If you do not do this, users will bypass Squid and will make direct
   requests to the mod_perl server's port.
   
  -<P><A NAME="anchor216"></A>
  +<P>
   The only question left is what to do with users who bookmarked your
  -services and they still have the port 8080 inside the URL. Do not worry
  -about it. The most important thing is for your scripts to return full URLs,
  -so if the user comes from the link with 8080 port inside, let it be. Just
  -make sure that all the subsequent calls to your server will be rewritten
  -correctly. After a time users will change their bookmarks. You can send
  -them an email if you know the address, or you could leave a note on your
  -pages asking users to update their bookmarks. You will avoid this problem
  -if you do not publish non-80 ports in the first place. See <A HREF="././config.html#Publishing_Port_Numbers_other_th">Publishing Port Numbers other than 80</A>.
  +services and who still have port 8080 inside their bookmark URLs. Do not
  +worry about it. The most important thing is for your scripts to return full
  +URLs, so if the user comes from the link with 8080 port inside, let it be.
  +Just make sure that all the subsequent calls to your server will be
  +rewritten correctly. After a time users will change their bookmarks. You
  +can send them an email if you know the address, or you could leave a note
  +on your pages asking users to update their bookmarks. You will avoid this
  +problem if you do not publish non-80 ports in the first place. See <A HREF="././config.html#Publishing_Port_Numbers_other_th">Publishing Port Numbers other than 80</A>.
   
  -<P><A NAME="anchor217"></A>
  +<P>
   &lt;META&gt; Need to write up a section about server logging with squid.
   One thing I sure would like to know is how requests are logged with this
   setup. I have, as most everyone I imagine, log rotation, analysis,
  @@ -1180,14 +2022,23 @@
   server + squid) ? Even when squid responds to a request out of its cache
   I'd still want the thing to be logged. &lt;/META&gt;
   
  -<P><A NAME="anchor218"></A>
  +<P>
   See <A HREF="././scenario.html#mod_proxy">Using mod_proxy</A> for information about <CODE>X-Forwarded-For</CODE>.
   
  -<P><A NAME="anchor219"></A>
  +<P>
   To save you some keystrokes, here is the whole modified <CODE>squid.conf</CODE>:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor220"></A>
  -<PRE>  http_port 80
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  http_port 80
     tcp_incoming_address 123.123.123.3
     tcp_outgoing_address 127.0.0.1
     httpd_accel_host 127.0.0.1
  @@ -1229,60 +2080,73 @@
     
     memory_pools on
     
  -  cachemgr_passwd disable shutdown
  -</PRE>
  -<P><A NAME="anchor221"></A>
  +  cachemgr_passwd disable shutdown</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Note that all directives should start at the beginning of the line, so if
   you cut and paste from the text make sure you remove the leading whitespace
   from each line.
   
  -<P><A NAME="anchor222"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H1><A NAME="Running_One_Webserver_and_Squid_">Running One Webserver and Squid in httpd Accelerator Mode</A></H1></CENTER>
  -<P><A NAME="anchor223"></A>
  +<P>
   When I was first told about Squid, I thought: ``Hey, now I can drop the
   <CODE>httpd_docs</CODE> server and have just Squid and the <CODE>httpd_perl</CODE>
   servers``. Since all my static objects will be cached by squid, I do not
   need the light <CODE>httpd_docs</CODE> server.
   
  -<P><A NAME="anchor224"></A>
  +<P>
   But I was a wrong. Why? Because I still have the overhead of loading the
   objects into Squid the first time. If a site has many of them, unless a
   huge chunk of memory is devoted to Squid they won't all be cached and the
   heavy mod_perl server will still have the task of serving static objects.
   
  -<P><A NAME="anchor225"></A>
  -How one would measure the overhead? The difference between the two servers
  -is in memory consumption, everything else (e.g. I/O) should be equal. So
  -you have to estimate the time needed for first time fetching of each static
  -object at a peak period and thus the number of additional servers you need
  +<P>
  +How do we measure the overhead? The difference between the two servers is
  +in memory consumption, everything else (e.g. I/O) should be equal. So you
  +have to estimate the time needed to fetch each static object for the first
  +time at a peak period and thus the number of additional servers you need
   for serving the static objects. This will allow you to calculate the
   additional memory requirements. I imagine that this amount could be
   significant in some installations.
   
  -<P><A NAME="anchor226"></A>
  +<P>
   So I have decided to have even more administration overhead and to stick
   with the squid, httpd_docs and httpd_perl scenario, where I can optimize
   and fine tune everything. Of course this may not be your situation. If you
  -are feeling that the scenario from the previous section is too complicated
  -for you, make it simpler. Have only one server with mod_perl built in and
  -let Squid to do most of the job that plain light apache used to do. As I
  -have explained in the previous paragraph, you should pick this lighter
  -setup only if you can make Squid cache most of your static objects. If it
  -cannot, your mod_perl server will have to do work we do not want it to do.
  +feel that the scenario from the previous section is too complicated for
  +you, make it simpler. Have only one server with mod_perl built in and let
  +Squid to do most of the job that plain light apache used to do. As I have
  +explained in the previous paragraph, you should pick this lighter setup
  +only if you can make Squid cache most of your static objects. If it cannot,
  +your mod_perl server will have to do work we do not want it to do.
   
  -<P><A NAME="anchor227"></A>
  -If you are still with me, install apache with mod_perl and Squid. Then use
  +<P>
  +If you are still with me, install Apache with mod_perl and Squid. Then use
   a configuration similar to the previous section, but now httpd_docs is not
   there anymore. Also we do not need the redirector anymore and we specify <CODE>httpd_accel_host</CODE> as a name of the server and not <CODE>virtual</CODE>. Because we do not redirect there is no need to bind two servers on the
   same port so there are neither <CODE>Bind</CODE> nor
   <CODE>Listen</CODE> directives in <CODE>httpd.conf</CODE>.
   
  -<P><A NAME="anchor228"></A>
  +<P>
   The modified configuration (see the explanations in the previous section):
  +
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
   
  -<P><A NAME="anchor229"></A>
  -<PRE>  httpd_accel_host put.your.hostname.here
  +	<td>
  +	  <pre>  httpd_accel_host put.your.hostname.here
     httpd_accel_port 8080
     http_port 80
     icp_port 0
  @@ -1321,84 +2185,150 @@
     
     memory_pools on
     
  -  cachemgr_passwd disable shutdown
  -</PRE>
  -<P><A NAME="anchor230"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +  cachemgr_passwd disable shutdown</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H1><A NAME="One_Light_and_One_Heavy_Server_w">One Light and One Heavy Server where All HTML is Perl-generated</A></H1></CENTER>
  -<P><A NAME="anchor231"></A>
  +<P>
   META: a lot of info duplication in tricks section! remove/modify/merge it.
   
  -<P><A NAME="anchor232"></A>
  +<P>
   Instead of keeping all your Perl scripts in <EM>/perl</EM> and your static content everywhere else, you could keep your static content
   in special directories and keep your Perl scripts everywhere else. You can
   still use the light/heavy apache separation approach described above, with
   a few minor modifications.
   
  -<P><A NAME="anchor233"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="Installation_and_Configuration">Installation and Configuration</A></H2></CENTER>
  -<P><A NAME="anchor234"></A>
  +<P>
   First you need to compile your light Apache with mod_proxy and mod_rewrite:
  +
  +<P>
   
  -<P><A NAME="anchor235"></A>
  -<PRE>  % ./configure --prefix=[snip...] --enable-module=rewrite \
  -                                   --enable-module=proxy
  -</PRE>
  -<P><A NAME="anchor236"></A>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  % ./configure --prefix=[snip...] --enable-module=rewrite \
  +                                   --enable-module=proxy</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   In the <EM>light</EM> Apache's <CODE>httpd.conf</CODE> file, turn rewriting on:
  +
  +<P>
   
  -<P><A NAME="anchor237"></A>
  -<PRE>  RewriteEngine on
  -</PRE>
  -<P><A NAME="anchor238"></A>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  RewriteEngine on</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   and list the static directories something like this:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor239"></A>
  -<PRE>  RewriteRule ^/img - [L]
  -  RewriteRule ^/style - [L]
  -</PRE>
  -<P><A NAME="anchor240"></A>
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  RewriteRule ^/img - [L]
  +  RewriteRule ^/style - [L]</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   The <CODE>[L]</CODE> means that the rewrite engine should stop if it has a match. This is
   necessary because the very last rewrite rule proxies everything to the <EM>heavy</EM> server:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor241"></A>
  -<PRE>  RewriteRule ^/(.*) <A HREF="http://www.example.com:8080/">http://www.example.com:8080/</A>$1 [P]
  -</PRE>
  -<P><A NAME="anchor242"></A>
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  RewriteRule ^/(.*) <A HREF="http://www.example.com:8080/">http://www.example.com:8080/</A>$1 [P]</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   This line (<STRONG>which must be the last <CODE>RewriteRule</CODE></STRONG>) is the difference between a server for which static content is the
   default and one for which dynamic (perlish) content is the default.
   
  -<P><A NAME="anchor243"></A>
  +<P>
   The above <CODE>RewriteRule</CODE> assumes that the heavy server runs on the same machine as the light server.
   You can just insert a different URL if the heavy Apache is elsewhere, but
   keeping the two servers on the one machine and treating them as one has
   some advantages, as you will see later.
   
  -<P><A NAME="anchor244"></A>
  +<P>
   You should also add the <EM>reverse rewrite rule</EM>:
   
  -<P><A NAME="anchor245"></A>
  -<PRE>  ProxyPassReverse / <A HREF="http://www.example.com/">http://www.example.com/</A>
  -</PRE>
  -<P><A NAME="anchor246"></A>
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  ProxyPassReverse / <A HREF="http://www.example.com/">http://www.example.com/</A></pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   so that the user doesn't see the port number <CODE>:8080</CODE> in her browser's location window.
   
  -<P><A NAME="anchor247"></A>
  +<P>
   Of course <CODE>www.example.com</CODE> should be replaced with your own domain name.
   
  -<P><A NAME="anchor248"></A>
  +<P>
   It is possible to use <CODE>localhost</CODE> in the <CODE>RewriteRule</CODE> above if the heavy and light servers are on the same machine, but your
   heavy server might accidentally say <CODE>localhost</CODE> in a client redirect (see below) which would not be good. Also, if your
   heavy server understands virtual hosts, you probably don't want to use the
   name <CODE>localhost</CODE>.
   
  -<P><A NAME="anchor249"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="Tricks_Traps_and_Gotchas">Tricks, Traps and Gotchas</A></H2></CENTER>
   <UL>
   <P><LI><STRONG><A NAME="item__Closing_your_shutters_temporar">'Closing your shutters' temporarily</A></STRONG>
  -<P><A NAME="anchor250"></A>
  +<P>
   Very occasionally, your mod_perl server will suffer glitches. Perhaps you
   changed a module and restarted your mod_perl httpd when a <CODE>perl
   -cw</CODE> would have given you some very interesting information! Since all your html
  @@ -1407,39 +2337,51 @@
   <STRONG>Unable to contact upstream server</STRONG> error messages on a grey background, not the nice customised error messages
   you generate with Perl.
   
  -<P><A NAME="anchor251"></A>
  +<P>
   If you insert a line into the light Apache's <CODE>httpd.conf</CODE> file:
  +
  +<P>
   
  -<P><A NAME="anchor252"></A>
  -<PRE>  RewriteRule ^/(.*) /sorry.html [L]
  -</PRE>
  -<P><A NAME="anchor253"></A>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  RewriteRule ^/(.*) /sorry.html [L]</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   <EM>after</EM> the list of static directories but <EM>before</EM> the rule that proxies everything else to the heavy apache, your users now
   get a (relatively) nice `Sorry for the inconvenience' message instead of
   the cryptic message described above. What's more, because this
   <EM>sorry.html</EM>  <CODE>RewriteRule</CODE> is listed <EM>after</EM> the image directory, you can refer to your images in it. Now all you have
   to do is figure out how to fix the module you broke.
   
  -<P><A NAME="anchor254"></A>
  +<P>
   Of course you need to prepare the file <EM>sorry.html</EM> in advance of all this. When you alter the configuration you will have to
   restart the light server for the changes to take effect, and when you have
   fixed all the errors in the mod_perl server you must remove the change and
   restart the light server again too.
   
  -<P><A NAME="anchor255"></A>
  +<P>
   This situation is easy to prevent. See <A HREF="././control.html#Safe_Code_Updates_on_a_Live_Prod">Safe Code Updates on a Live Production Server</A> for more info.
   
   <P><LI><STRONG><A NAME="item_Logging">Logging</A></STRONG>
  -<P><A NAME="anchor256"></A>
  +<P>
   There are a number of different ways to maintain logs of your hits. The
  -easiest way is to let both Apaches log to their own <CODE>access_log</CODE>
  -file. Unfortunately, this means that many requests will be logged twice,
  +easiest way is to let both Apaches log to their own <EM>access_log</EM>
  +files. Unfortunately, this means that many requests will be logged twice,
   which makes it tricky to merge the two logfiles, should you want to. Also,
   as far as the heavy Apache is concerned, all requests will appear to come
   from the IP address of the machine on which the light apache is running. If
   you are logging IP addresses as part of your <CODE>access_log</CODE> the logs written by the heavy Apache will be fairly meaningless.
   
  -<P><A NAME="anchor257"></A>
  +<P>
   One solution is to tell the heavy Apache not to bother logging requests
   that seem to come from the light Apache's machine. You might do this by
   installing a custom <CODE>PerlLogHandler</CODE> or just piping to
  @@ -1450,29 +2392,29 @@
   <CODE>access_log</CODE>, but you need to look for any direct accesses to the heavy server in case
   the proxy server is sometimes bypassed.
   
  -<P><A NAME="anchor258"></A>
  +<P>
   Note that you don't want to pipe the <CODE>access_log</CODE> from the heavy Apache to <EM>/dev/null</EM>. If you do this, you won't be able to see any requests that bypass the
   lightweight Apache and come straight in on the port to which the heavy
   server is listening. Every time you see one of these requests you should
   ask yourself <EM>Why?</EM> and take steps to eliminate it.
   
  -<P><A NAME="anchor259"></A>
  +<P>
   It's easy to get the logger to log the original client's IP address and not
  -the one that comes from proxy server. Look for
  +the one that comes from the proxy server. Look for
   <CODE>mod_proxy_add_forward</CODE> at <A HREF="././scenario.html#mod_proxy">Building and Using mod_proxy</A> for hints.
   
   <P><LI><STRONG><A NAME="item_Eliminating">Eliminating :8080's</A></STRONG>
  -<P><A NAME="anchor260"></A>
  +<P>
   By 8080 we mean the port your mod_perl enabled Apache is listening to.
   Substitute whatever port you have chosen.
   
  -<P><A NAME="anchor261"></A>
  +<P>
   There are a number of ways in which the user can somehow be directed to
   URLs which have <CODE>:8080</CODE> in them. If you are running the heavy Apache on a different machine from
   that of the light Apache, then provided that the heavy Apache has the same <CODE>ServerName</CODE> as the light Apache this will be less of a problem, but this section may
   still apply to you.
   
  -<P><A NAME="anchor262"></A>
  +<P>
   If the user requests a URL that maps to a directory without a trailing
   slash (<EM>/</EM>), apache will issue a client redirect (301?) to the
   <EM>correct</EM> URL. Unfortunately the Apache that will issue this redirect will most
  @@ -1483,34 +2425,46 @@
   header, of the data returned to the user's browser. This means that the <CODE>ProxyPassReverse</CODE> in the light Apache's configuration file which is supposed to catch such
   things will be unable to catch this. :-(
   
  -<P><A NAME="anchor263"></A>
  +<P>
   Since this will tend only to be a problem when the heavy and light Apaches
   are running on different ports on the same machine, if the light and heavy
  -apaches have the same <CODE>DocumentRoot</CODE> we can have the
  -<EM>light</EM> apache figure out that a request is for a directory without a trailing
  +Apaches have the same <CODE>DocumentRoot</CODE> we can have the
  +<EM>light</EM> Apache figure out that a request is for a directory without a trailing
   slash. Then it can do the redirect itself, before the heavy Apache finds
   out about it:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor264"></A>
  -<PRE>    RewriteCond /www/shop%{SCRIPT_FILENAME} -d
  -    RewriteRule ^(.+[^/])$ $1/ [R]   
  -</PRE>
  -<P><A NAME="anchor265"></A>
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>    RewriteCond /www/shop%{SCRIPT_FILENAME} -d
  +    RewriteRule ^(.+[^/])$ $1/ [R]   </pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Note that these two lines should be <EM>after</EM> the <CODE>RewriteRule</CODE>s for the static directories but <EM>before</EM> the final all-encompassing
   <CODE>RewriteRule</CODE> that proxies everything else to the heavy Apache.
   
  -<P><A NAME="anchor266"></A>
  +<P>
   Beware: if you put these two lines in the light <EM>httpd.conf</EM> before the static directories are mentioned, then in this setup the light
   httpd may find itself in an infinite loop if somebody were to request for
   example <EM>&lt;/img&gt;</EM>.
   
  -<P><A NAME="anchor267"></A>
  +<P>
   Another way in which <CODE>:8080</CODE>'s can creep into URLs is if you have Perl code which issues a redirect to <CODE>http://$ENV{HTTP_HOST}/...</CODE>. If you are migrating from one heavy server to one heavy and one light,
   you may find a few of these. If you replace <CODE>HTTP_HOST</CODE> with
   <CODE>SERVER_NAME</CODE>, all should be well. Note that you may need to do this whether or not the
   light and heavy servers are on the same machine.
   
  -<P><A NAME="anchor268"></A>
  +<P>
   The <CODE>:8080</CODE> effect can be insidious. Once a user gets a URL with
   <CODE>:8080</CODE> in it, odd things will happen. If the heavy and light Apaches have the same <CODE>DocumentRoot</CODE> (normal if they are on the same machine) and/or the heavy Apache is able to
   deliver the same static content as the light Apache, the user's browser
  @@ -1522,89 +2476,103 @@
   normal. If the request is in a password-protected area, then the user may
   have to log in twice.
   
  -<P><A NAME="anchor269"></A>
  +<P>
   If the heavy and light Apaches do not share the same <CODE>DocumentRoot</CODE>
   (normal if they are on different servers) and/or the heavy Apache cannot
   serve images, then all your pages will be imageless. This is a fairly
   compelling reason to run your light and heavy servers on the same machine
  -and to have them share a <CODE>DocumentRoot</CODE>.
  +and to have them share the same <CODE>DocumentRoot</CODE>.
   
  -<P><A NAME="anchor270"></A>
  +<P>
   Regardless of how hard you try to eliminate <CODE>:8080</CODE>s, they will crop up from time to time. You should occasionally examine the
   access_log of the heavy Apache. Assuming you aren't bothering to log
   requests that come via the light Apache, any requests that appear should be
   investigated.
   
  -<P><A NAME="anchor271"></A>
  +<P>
   Interestingly, if the final catch-all <CODE>RedirectRule</CODE> is to
   <CODE>localhost:8080</CODE>, it is possible that <CODE>localhost</CODE> will leak into stray client redirects. Moral: use your server's name in
   redirects, unless you have a very good reason not to.
   
   <P><LI><STRONG><A NAME="item_Security">Security</A></STRONG>
  -<P><A NAME="anchor272"></A>
  +<P>
   Because all http requests will appear to your Perl scripts to be coming
   from the light httpd, you must be careful not to authenticate based on the
   IP address from which a request came. This can be easy to overlook if you
   are moving from a single-server to a dual-server configuration.
   
  -<P><A NAME="anchor273"></A>
  +<P>
   The URLs that return the <EM>/server-status</EM> and <EM>/perl-status</EM> of your Apache servers are often protected based on IP address. The
   <EM>/server-status</EM> URL for the heavy server is probably safe if the light Apache also defines
   an identical <EM>/server-status</EM> URL, but the
   <EM>/perl-status</EM> URL should be protected.
   
  -<P><A NAME="anchor274"></A>
  +<P>
   If you must authenticate based on IP address, you should either make sure
   that the light Apache's IP address is not in any way privileged or you
   should block access to port <CODE>8080</CODE> from anywhere except the light Apache's IP address.
   
  -<P><A NAME="anchor275"></A>
  +<P>
   If your heavy and light httpds can both serve static content (where
   <CODE>:8080</CODE>s only affect URLs - not content), then blocking port <CODE>8080</CODE>
   is not recommended. After all, if a user gets onto port <CODE>8080</CODE> in this scenario, the worst that will happen is that URLs will look odd.
   
  -<P><A NAME="anchor276"></A>
  +<P>
   Note that if you are using the
   <A HREF="././scenario.html#mod_proxy"><CODE>X-Forwarded-For</CODE></A> HTTP header, then this subsection is of limited relevance to you.
   
   </UL>
  -<P><A NAME="anchor277"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H1><A NAME="mod_proxy">mod_proxy</A></H1></CENTER>
  -<P><A NAME="anchor278"></A>
  +<P>
   mod_proxy implements a proxy/cache for Apache. It implements proxying
   capability for FTP, CONNECT (for SSL), HTTP/0.9, and HTTP/1.0. The module
   can be configured to connect to other proxy modules for these and other
   protocols.
   
  -<P><A NAME="anchor279"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="Concepts_and_Configuration_Direc">Concepts and Configuration Directives</A></H2></CENTER>
  -<P><A NAME="anchor280"></A>
  +<P>
   In the following explanation, we will use <EM>www.example.com</EM> as the main server users access when they want to get some kind of service
   and <EM>backend.example.com</EM> as a machine that does the heavy work. The main and the back-end are
  -different servers, they may coexist on the same machine and may not.
  +different servers, they may or may not coexist on the same machine.
   
  -<P><A NAME="anchor281"></A>
  -The mod_proxy module is built into the server that answers to requests to
  -the <EM>www.example.com</EM> hostname. It doesn't matter what functionality is built into the <EM>backend.example.com</EM> server.
  +<P>
  +The mod_proxy module is built into the server that answers requests to the <EM>www.example.com</EM> hostname. It doesn't matter what functionality is built into the <EM>backend.example.com</EM> server.
   
  -<P><A NAME="anchor282"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H3><A NAME="ProxyPass">ProxyPass</A></H3></CENTER>
  -<P><A NAME="anchor283"></A>
  -You can use <CODE>ProxyPass</CODE> configuration directive for mapping remote hosts into the space of the
  +<P>
  +You can use the <CODE>ProxyPass</CODE> configuration directive for mapping remote hosts into the space of the
   local server; the local server does not act as a proxy in the conventional
   sense, but appears to be a mirror of the remote server.
   
  -<P><A NAME="anchor284"></A>
  +<P>
   Let's explore what this rule does:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor285"></A>
  -<PRE>  ProxyPass   /modperl/ <A HREF="http://backend.example.com/modperl/">http://backend.example.com/modperl/</A>
  -</PRE>
  -<P><A NAME="anchor286"></A>
  -When user initiates a request to <A
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  ProxyPass   /modperl/ <A HREF="http://backend.example.com/modperl/">http://backend.example.com/modperl/</A></pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +When a user initiates a request to <A
   HREF="http://www.example.com/modperl/foo.pl">http://www.example.com/modperl/foo.pl</A>,
   the request will be redirected to <A
   HREF="http://backend.example.com/modperl/foo.pl">http://backend.example.com/modperl/foo.pl</A>,
  @@ -1613,185 +2581,263 @@
   location window, instead of <A
   HREF="http://www.example.com/.">http://www.example.com/.</A>
   
  -<P><A NAME="anchor287"></A>
  -You have probably noticed many examples from the real life Internet
  -deployment. Free-email service providers and other similar heavy online
  -services display the login or the main page from their main server, and
  -then when you log-in you see something like
  +<P>
  +You have probably noticed many examples of this from real life Internet
  +sites you've visited. Free-email service providers and other similar heavy
  +online services display the login or the main page from their main server,
  +and then when you log-in you see something like
   <EM>x11.example.com</EM>, then <EM>w59.example.com</EM>, etc. These are the back-end servers that do the actual work.
   
  -<P><A NAME="anchor288"></A>
  -Obviously this is not quite nice solution, but usually users don't really
  +<P>
  +Obviously this is not an ideal solution, but usually users don't really
   care about what they see in the location window. So you can get away with
   this approach. As I'll show in a minute there is a better solution which
   removes this caveat and provides even more useful functionalities.
   
  -<P><A NAME="anchor289"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H3><A NAME="ProxyPassReverse">ProxyPassReverse</A></H3></CENTER>
  -<P><A NAME="anchor290"></A>
  -This directive lets Apache adjust the URL in the <CODE>Location</CODE> header on HTTP redirect responses. For instance this is essential when
  +<P>
  +This directive lets Apache adjust the URL in the <CODE>Location</CODE> header on HTTP redirect responses. This is essential for example, when
   Apache is used as a reverse proxy to avoid by-passing the reverse proxy
   because of HTTP redirects on the back-end servers which stay behind the
  -reverse proxy. Generally used in conjunction with <CODE>ProxyPass</CODE>
  +reverse proxy. Generally used in conjunction with the <CODE>ProxyPass</CODE>
   directive to build a complete front-end proxy server.
  +
  +<P>
   
  -<P><A NAME="anchor291"></A>
  -<PRE>  ProxyPass          /modperl/  <A HREF="http://backend.example.com/modperl/">http://backend.example.com/modperl/</A>
  -  ProxyPassReverse   /modperl/  <A HREF="http://backend.example.com/modperl/">http://backend.example.com/modperl/</A>
  -</PRE>
  -<P><A NAME="anchor292"></A>
  -When user initiates a request to <A
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  ProxyPass          /modperl/  <A HREF="http://backend.example.com/modperl/">http://backend.example.com/modperl/</A>
  +  ProxyPassReverse   /modperl/  <A HREF="http://backend.example.com/modperl/">http://backend.example.com/modperl/</A></pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +When a user initiates a request to <A
   HREF="http://www.example.com/modperl/foo.pl">http://www.example.com/modperl/foo.pl</A>,
   the request will be redirected to <A
   HREF="http://backend.example.com/modperl/foo.pl">http://backend.example.com/modperl/foo.pl</A>
   but on the way back
   <CODE>ProxyPassReverse</CODE> will correct the location URL to become <A
   HREF="http://www.example.com/modperl/foo.pl">http://www.example.com/modperl/foo.pl</A>
  -. This happens absolutely transparently to user. User will never know that
  +. This happens completely transparently. The end user will never know that
   something has happened to his request behind the scenes.
   
  -<P><A NAME="anchor293"></A>
  +<P>
   Note that this <CODE>ProxyPassReverse</CODE> directive can also be used in conjunction with the proxy pass-through
   feature:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor294"></A>
  -<PRE>  RewriteRule ... [P]
  -</PRE>
  -<P><A NAME="anchor295"></A>
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  RewriteRule ... [P]</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   from mod_rewrite because its doesn't depend on a corresponding
   <CODE>ProxyPass</CODE> directive.
   
  -<P><A NAME="anchor296"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H3><A NAME="Security_Issues">Security Issues</A></H3></CENTER>
  -<P><A NAME="anchor297"></A>
  -Whenever you use mod_proxy you want to make sure that your server will not
  -become a proxy for some free riders. To block this you should have this
  -setting:
  -
  -<P><A NAME="anchor298"></A>
  -<PRE>  RewriteRule ^proxy:.*  -  [F]
  -</PRE>
  -<P><A NAME="anchor299"></A>
  -which makes sure that request of type proxy:http://www.example.com wouldn't
  -keep your processes busy and return the status <EM>Forbidden</EM>.
  +<P>
  +Whenever you use mod_proxy you need to make sure that your server will not
  +become a proxy for free riders. To block this you should have this setting:
  +
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  RewriteRule ^proxy:.*  -  [F]</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +which makes sure that requests of type proxy:http://www.example.com
  +wouldn't keep your processes busy and will return the status <EM>Forbidden</EM>.
   
  -<P><A NAME="anchor300"></A>
  +<P>
   Start by testing your own server, by telnetting to the port the server is
   listening on and issuing an external proxy request:
  +
  +<P>
   
  -<P><A NAME="anchor301"></A>
  -<PRE>  % telnet www.example.com 80
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  % telnet www.example.com 80
   Trying 128.9.176.32...
   Connected to www.example.com
   Escape character is '^]'.
   HEAD <A HREF="http://www.example.org/">http://www.example.org/</A> HTTP/1.1
  -Host: www.example.org
  -</PRE>
  -<P><A NAME="anchor302"></A>
  +Host: www.example.org</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   HTTP/1.0 403 Forbidden Date: Mon, 10 Apr 2000 08:42:31 GMT Server:
   Apache/1.3.13-dev (Unix) Connection: close Content-Type: text/html;
   charset=iso-8859-1
   
  -<P><A NAME="anchor303"></A>
  +<P>
   Connection closed by foreign host.
   
  -<P><A NAME="anchor304"></A>
  -As you see that we are dissalowed to make a proxy request to a different
  -server, just as we wanted it to be. It means that this particular hole has
  -been secured on our box.
  +<P>
  +As you can see we are not allowed to make a proxy request to a different
  +server, so our <EM>lock down</EM> has worked. It means that this particular hole has been secured on our box.
   
  -<P><A NAME="anchor305"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="Buffering_Feature">Buffering Feature</A></H2></CENTER>
  -<P><A NAME="anchor306"></A>
  -In addition to the correcting the URI on its way back from the back-end
  -server feature, mod_proxy provides a buffering services, mod_perl and
  -similar heavy modules benefit from. The buffering feature allows mod_perl
  -to pass the generated data to mod_proxy and move on serving new requests,
  -instead of waiting for a possibly slow client to receive all the data.
  +<P>
  +In addition to correcting the URI on its way back from the back-end server,
  +mod_proxy also provides buffering services which mod_perl and similar heavy
  +modules benefit from. The buffering feature allows mod_perl to pass the
  +generated data to mod_proxy and move on to serve new requests, instead of
  +waiting for a possibly slow client to receive all the data.
   
  -<P><A NAME="anchor307"></A>
  +<P>
   This figure depicts this feature:
  +
  +<P>
   
  -<P><A NAME="anchor308"></A>
  -<PRE>                [socket]                   wire     `o'
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>                [socket]                   wire     `o'
     [mod_perl] =&gt; [      ] =&gt; [mod_proxy] =&gt; ____ =&gt;  /|\
  -                [buffer]                            / \
  -</PRE>
  -<P><A NAME="anchor309"></A>
  +                [buffer]                            / \</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   From looking at this figure it's easy to see that the bottleneck is the
   socket buffer; it has to be able to absorb all the data that mod_perl has
  -generated in order to untie the mod_perl process immediately.
  +generated in order to free the mod_perl process immediately; mod_proxy will
  +take the data as fast as mod_perl can deliver it, freeing the mod_perl
  +server to service new requests as soon as possible while mod_proxy feeds
  +the client at whatever rate the client requires.
   
  -<P><A NAME="anchor310"></A>
  +<P>
   <CODE>ProxyReceiveBufferSize</CODE> is the name of the parameter that specifies the size of the socket buffer.
   Configuring:
  +
  +<P>
   
  -<P><A NAME="anchor311"></A>
  -<PRE>  ProxyReceiveBufferSize 16384
  -</PRE>
  -<P><A NAME="anchor312"></A>
  -will create a buffer of 16k in size. If mod_perl generates output which
  -size is under 16k, the process will be immediately untied and allowed to
  -serve new requests, if the output is bigger than 16k, the following process
  -is taking place:
  +    <table>
  +      <tr>
   
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  ProxyReceiveBufferSize 16384</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +will create a buffer of 16k in size. If mod_perl generates output which is
  +less than 16k, the process will be immediately untied and allowed to serve
  +new requests, if the output is bigger than 16k, the following process will
  +take place:
  +
   <OL>
   <P><LI>
  -<P><A NAME="anchor313"></A>
  +<P>
   The first 16k will enter the system buffer.
   
   <P><LI>
  -<P><A NAME="anchor314"></A>
  -mod_proxy picks the first 8k and sends down the wire.
  +<P>
  +mod_proxy picks the first 8k and sends it down the wire.
   
   <P><LI>
  -<P><A NAME="anchor315"></A>
  +<P>
   mod_perl writes the next 8k into the place of the 8k of data that was just
  -picked by mod_proxy.
  +sent off by mod_proxy.
   
   </OL>
  -<P><A NAME="anchor316"></A>
  -Stages 2 and 3 get repeated until mod_perl has run out of data it has to
  -send. When this happens, it goes on its own business and the stage 2 is
  -repeated until all the data was picked from the system buffer and sent down
  -the wire.
  -
  -<P><A NAME="anchor317"></A>
  -Of course you want to set the buffer size as bigger as possible, since you
  -want the heavy mod_perl processes to be utilized in the most effective way,
  -so you don't want them waste their time waiting for a client to receive the
  -data, especially if a client has a slow downstream connection.
  +<P>
  +Stages 2 and 3 are repeated until mod_perl has no more data to send. When
  +this happens, mod_perl can serve a new request while stage 2 is repeated
  +until all the data was picked from the system buffer and sent down the
  +wire.
  +
  +<P>
  +Of course you want to set the buffer size as large as possible, since you
  +want the heavy mod_perl processes to be utilized in the most efficient way,
  +so you don't want them to waste their time waiting for a client to receive
  +the data, especially if a client has a slow downstream connection.
   
  -<P><A NAME="anchor318"></A>
  +<P>
   As the <CODE>ProxyReceiveBufferSize</CODE> name states, its buffering feature applies only to <EM>downstream data</EM> (coming from the origin server to the proxy) and not upstream data. There
   is no buffering of data uploaded from the client browser to the proxy, thus
   you cannot use this technique to prevent the heavy mod_perl server from
   being tied up during a large POST such as a file upload. Falling back to
   mod_cgi seems to be the best solution for these specific scripts whose
  -major function is getting a big upstream.
  +major function is receiving large amounts of upstream data.
  +
  +<P>
  +&lt;META: check this ---&gt; 
   
  -<P><A NAME="anchor319"></A>
  -&lt;META: check this ---&gt; Of course just like mod_perl, mod_proxy writes
  -the data it proxy-passes into its outgoing socket buffer, therefore the
  -mod_proxy process gets released as soon as the last chuck of data was
  -deposited into this buffer, even if the client didn't completed the
  -downloading. The OS worries to complete the transfer and release the TCP
  -socket used for this transfer.
  -
  -<P><A NAME="anchor320"></A>
  -Therefore if you don't use mod_proxy and mod_perl send its data directly to
  -the client, and you have a big socket buffer, the mod_perl process will be
  -released as soon as the last chunk of data will enter the buffer. Just like
  -with mod_proxy, OS will worry to complete the data transfer.
  +<P>
  +Of course just like mod_perl, mod_proxy writes the data it proxy-passes
  +into its outgoing socket buffer, therefore the mod_proxy process gets
  +released as soon as the last chunk of data is deposited into this buffer,
  +even if the client didn't complete the download. Its the OS's problem to
  +complete the transfer and release the TCP socket used for this transfer.
  +
  +<P>
  +Therefore if you don't use mod_proxy and mod_perl sends its data directly
  +to the client, and you have a big socket buffer, the mod_perl process will
  +be released as soon as the last chunk of data enters the buffer. Just like
  +with mod_proxy, the OS will deal with completing the data transfer.
   
  -<P><A NAME="anchor321"></A>
  +<P>
   &lt;based on this comment&gt; yes, too (but receive and transmit buffer may
   be of different size, depending on the OS)
   
  -<P><A NAME="anchor322"></A>
  +<P>
   The problem I don't know is, does the call to close the socket wait, until
   all data is actually send successfully or not. If it doesn't wait, you may
   not be noticed of any failure, but because the proxing Apache can write as
  @@ -1802,218 +2848,309 @@
   wait until the client returns the success of data transmission. (The last,
   is the part I am not sure on)
   
  -<P><A NAME="anchor323"></A>
  +<P>
   &lt;/META&gt;
   
  -<P><A NAME="anchor324"></A>
  +<P>
   Unfortunately you cannot set the socket buffer size as large as you want
  -because there is a limit of the available physical memory and OS has its
  -own upper limits on the possible buffer size.
  +because there is a limit of the available physical memory and OSs have
  +their own upper limits on the possible buffer size.
   
  -<P><A NAME="anchor325"></A>
  -It doesn't mean that you cannot change the OS imposed limits, but to do
  +<P>
  +This doesn't mean that you cannot change the OS imposed limits, but to do
   that you have to know the techniques for doing that. In the next section we
  -will present a few OSes and the ways to achieve the upper limit rise.
  +will present a few OSs and the ways to increase their socket buffer sizes.
   
  -<P><A NAME="anchor326"></A>
  -To solve the physical memory limits you just have to add more memory.
  +<P>
  +To increase the physical memory limits you just have to add more memory.
   
  -<P><A NAME="anchor327"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<CENTER><H3><A NAME="Setting_the_Buffering_Limits_on_">Setting the Buffering Limits on Various OSes</A></H3></CENTER>
  -<P><A NAME="anchor328"></A>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
  +<CENTER><H3><A NAME="Setting_the_Buffering_Limits_on_">Setting the Buffering Limits on Various OSs</A></H3></CENTER>
  +<P>
   As we just saw there are a few kinds of parameters we might want to adjust
   for our needs.
   
  -<P><A NAME="anchor329"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H4><A NAME="IOBUFSIZE_Source_Code_Definition">IOBUFSIZE Source Code Definition</A></H4></CENTER>
  -<P><A NAME="anchor330"></A>
  -The first one is the parameter that use by
  -<EM>proxy_util.c:ap_proxy_send_fb()</EM> to loop over content being proxy passed in 8K chunks (as of this writing),
  +<P>
  +The first parameter is used by <EM>proxy_util.c:ap_proxy_send_fb()</EM> to loop over content being proxy passed in 8K chunks (as of this writing),
   passing that on to the client. In other words it specifies the size of the
  -data that is sent downstream the wire.
  +data that is sent down the wire.
   
  -<P><A NAME="anchor331"></A>
  +<P>
   This parameter is defined by the <CODE>IOBUFSIZE</CODE>:
  +
  +<P>
   
  -<P><A NAME="anchor332"></A>
  -<PRE>  #define IOBUFSIZE 8192
  -</PRE>
  -<P><A NAME="anchor333"></A>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  #define IOBUFSIZE 8192</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   You have no control over this setting in the server configuration file,
   therefore you might want to change it in the source files, before you
   compile the server.
   
  -<P><A NAME="anchor334"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H4><A NAME="ProxyReceiveBufferSize_Configura">ProxyReceiveBufferSize Configuration Directive</A></H4></CENTER>
  -<P><A NAME="anchor335"></A>
  -You can control the socket buffer size with <CODE>ProxyReceiveBufferSize</CODE>
  -directive:
  -
  -<P><A NAME="anchor336"></A>
  -<PRE>  ProxyReceiveBufferSize 16384
  -</PRE>
  -<P><A NAME="anchor337"></A>
  -The above setting will set a buffer size to be of 16Kb. If it is not set
  -explicitly or if it is set to 0 then the default buffer size is used. The
  +<P>
  +You can control the socket buffer size with the
  +<CODE>ProxyReceiveBufferSize</CODE> directive:
  +
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  ProxyReceiveBufferSize 16384</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +The above setting will set a buffer size of 16Kb. If it is not set
  +explicitly, or if it is set to 0, then the default buffer size is used. The
   number should be an integral multiple of 512.
   
  -<P><A NAME="anchor338"></A>
  -Note that if you set the value of <CODE>ProxyReceiveBufferSize</CODE> bigger than the OS limit, the default value will be used.
  +<P>
  +Note that if you set the value of <CODE>ProxyReceiveBufferSize</CODE> larger than the OS limit, the default value will be used.
   
  -<P><A NAME="anchor339"></A>
  +<P>
   Both the default and the maximum possible value of
   <CODE>ProxyReceiveBufferSize</CODE> depend on the Operating System.
   
   <UL>
   <P><LI><STRONG><A NAME="item_Linux">Linux</A></STRONG>
  -<P><A NAME="anchor340"></A>
  -For 2.2 kernels the max limit is in <EM>/proc/sys/net/core/rmem_max</EM> and the default value is in <EM>/proc/sys/net/core/rmem_default</EM>. If you want to increase <CODE>RCVBUF</CODE> size above 65535, the default max value, you have to raise first the
  +<P>
  +For 2.2 kernels the maximum limit is in <EM>/proc/sys/net/core/rmem_max</EM>
  +and the default value is in <EM>/proc/sys/net/core/rmem_default</EM>. If you want to increase <CODE>RCVBUF</CODE> size above 65535, the default maximum value, you have to raise first the
   absolute limit in
   <EM>/proc/sys/net/core/rmem_max</EM>. To do that at the run time, execute this command to raise it to 128k:
   
  -<P><A NAME="anchor341"></A>
  -<PRE>  % echo 131072 &gt; /proc/sys/net/core/rmem_max
  -</PRE>
  -<P><A NAME="anchor342"></A>
  -You probably want to put this command into <EM>/etc/rc.d/rc.local</EM> so the change would take effect at the system reboot.
  +<P>
   
  -<P><A NAME="anchor343"></A>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  % echo 131072 &gt; /proc/sys/net/core/rmem_max</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +You probably want to put this command into <EM>/etc/rc.d/rc.local</EM> so the change will take effect at system reboot.
  +
  +<P>
   On Linux OS with kernel 2.2.5 the maximum and default values are either 32k
  -or 64k. You can also change the default and maximum values during the
  -kernel compilation, for that you should alter the
  -<CODE>SK_RMEM_DEFAULT</CODE> and <CODE>SK_RMEM_MAX</CODE> definitions respectively.
  +or 64k. You can also change the default and maximum values during kernel
  +compilation; for that you should alter the
  +<CODE>SK_RMEM_DEFAULT</CODE> and <CODE>SK_RMEM_MAX</CODE> definitions respectively. (Since sources tend to change use
  +<CODE>grep(1)</CODE> utility to find the files, these defined at)
   
   <P><LI><STRONG><A NAME="item_FreeBSD">FreeBSD</A></STRONG>
  -<P><A NAME="anchor344"></A>
  +<P>
   Under FreeBSD it's possible to configure the kernel to have bigger socket
   buffers:
  +
  +<P>
   
  -<P><A NAME="anchor345"></A>
  -<PRE> % sysctl -w kern.ipc.maxsockbuf=2621440
  -</PRE>
  -<P><LI><STRONG><A NAME="item_Solaris">Solaris</A></STRONG>
  -<P><A NAME="anchor346"></A>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre> % sysctl -w kern.ipc.maxsockbuf=2621440</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P><LI><STRONG><A NAME="item_Solaris">Solaris</A></STRONG>
  +<P>
   Under Solaris this upper limit is specified by <EM>tcp_max_buf</EM>
  -parameter and equals to 256k as reported.
  +parameter and is 256k as reported.
   
  -<P><LI><STRONG><A NAME="item_Non">Non Listed OSes</A></STRONG>
  -<P><A NAME="anchor347"></A>
  -If you use OS that is not listed here and know the required for this
  -section details, please submit them to me.
  +<P><LI><STRONG><A NAME="item_Other">Other OSs</A></STRONG>
  +<P>
  +[ReaderMeta]: If you use an OS that is not listed here and know how to
  +increase the socket buffer size please let me know.
   
   </UL>
  -<P><A NAME="anchor348"></A>
  +<P>
   When you tell the kernel to use bigger sockets you can set bigger values
   for <EM>ProxyReceiveBufferSize</EM>. e.g. 1Mb (1048576).
   
  -<P><A NAME="anchor349"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H4><A NAME="Hacking_the_Code">Hacking the Code</A></H4></CENTER>
  -<P><A NAME="anchor350"></A>
  +<P>
   Some folks have patched the Apache source code to make the application
  -buffer configurable as well. After the patch there were two configuration
  +buffer configurable as well. After the patch there are two configuration
   directives available:
   
   <UL>
   <P><LI>
  -<P><A NAME="anchor351"></A>
  +<P>
   ProxyReceiveBufferSize -- sets the socket buffer size
   
   <P><LI>
  -<P><A NAME="anchor352"></A>
  -ProxyInternalBufferSize sets the application buffer size
  +<P>
  +ProxyInternalBufferSize -- sets the application buffer size
   
   </UL>
  -<P><A NAME="anchor353"></A>
  -To patch the source rename <CODE>ap_breate()</CODE> to
  +<P>
  +To patch the source, rename <CODE>ap_breate()</CODE> to
   <CODE>ap_bcreate_size()</CODE> and add a size parameter, which defaults to <EM>IOBUFSIZE</EM> if 0 is passed. Then add
   
  -<P><A NAME="anchor354"></A>
  -<PRE>  #define ap_bcreate(p,flags) ap_bcreate(p,flags,0)
  -</PRE>
  -<P><A NAME="anchor355"></A>
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  #define ap_bcreate(p,flags) ap_bcreate(p,flags,0)</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   and add a new <CODE>ap_bcreate()</CODE> which calls
   <CODE>ap_bcreate_size()</CODE> for binary compatibility.
   
  -<P><A NAME="anchor356"></A>
  +<P>
   Actually the <CODE>ProxyReceiveBufferSize</CODE> should be called
   <CODE>ProxySocketBufferSize</CODE>. This would also remove some of the confusion about what it actually does.
   
  -<P><A NAME="anchor357"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="Caching">Caching</A></H2></CENTER>
  -<P><A NAME="anchor358"></A>
  +<P>
   META: complete the conf details
   
  -<P><A NAME="anchor359"></A>
  +<P>
   Apache does caching as well. It's relevant to mod_perl only if you produce
   proper headers, so your scripts' output can be cached. See the Apache
  -documentation for more details on configuration of this capability.
  +documentation for more details on the configuration of this capability.
   
  -<P><A NAME="anchor360"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<CENTER><H2><A NAME="Building_process">Building process</A></H2></CENTER>
  -<P><A NAME="anchor361"></A>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
  +<CENTER><H2><A NAME="Build_process">Build process</A></H2></CENTER>
  +<P>
   To build mod_proxy into Apache just add <STRONG>--enable-module=proxy</STRONG>
   during the Apache <STRONG>./configure</STRONG> stage.
   
  -<P><A NAME="anchor362"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H1><A NAME="Front_end_Back_end_Proxying_with">Front-end Back-end Proxying with Virtual Hosts</A></H1></CENTER>
  -<P><A NAME="anchor363"></A>
  +<P>
   This section explains a configuration setup for proxying your back-end
   mod_perl servers when you need to use Virtual Hosts.
   
  -<P><A NAME="anchor364"></A>
  -The approach is to use unique port number for each virtual host at the
  +<P>
  +The approach is to use a unique port number for each virtual host at the
   back-end server, so you can redirect from the front-end server to
  -localhost::1234, and name-based virtual servers on the front end, though
  -any technique on the front-end will do.
  +localhost:1234, and name-based virtual servers on the front end, though any
  +technique on the front-end will do.
   
  -<P><A NAME="anchor365"></A>
  +<P>
   If you run the front-end and the back-end servers on the same machine you
   can prevent any direct outside connections to the back-end server if you
   bind tightly to address <CODE>127.0.0.1</CODE> (<EM>localhost</EM>) as you will see in the following configuration example.
   
  -<P><A NAME="anchor366"></A>
  +<P>
   The front-end (light) server configuration:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor367"></A>
  -<PRE>  &lt;VirtualHost 10.10.10.10&gt;
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  &lt;VirtualHost 10.10.10.10&gt;
       ServerName www.example.com
       ServerAlias example.com
       RewriteEngine On
       RewriteOptions 'inherit'
       RewriteRule \.(gif|jpg|png|txt)$ - [last]
       RewriteRule ^/(.*)$ <A HREF="http://localhost:4077/">http://localhost:4077/</A>$1 [proxy]
  -  &lt;/VirtualHost&gt;
  -</PRE>
  -<P><A NAME="anchor368"></A>
  -<PRE>  &lt;VirtualHost 10.10.10.10&gt;
  +  &lt;/VirtualHost&gt;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  &lt;VirtualHost 10.10.10.10&gt;
       ServerName foo.example.com
       RewriteEngine On
       RewriteOptions 'inherit'
       RewriteRule \.(gif|jpg|png|txt)$ - [last]
       RewriteRule ^/(.*)$ <A HREF="http://localhost:4078/">http://localhost:4078/</A>$1 [proxy]
  -  &lt;/VirtualHost&gt;
  -</PRE>
  -<P><A NAME="anchor369"></A>
  +  &lt;/VirtualHost&gt;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   The above front-end configuration handles two virtual hosts:
   <EM>www.example.com</EM> and <EM>foo.example.com</EM>. The two setups are almost identical.
   
  -<P><A NAME="anchor370"></A>
  +<P>
   The front-end server will handle files with the extensions <EM>.gif</EM>,
  -<EM>.jpg</EM>, <EM>.png</EM> and <EM>.txt</EM> internally, the rest will be proxified to be handled by the back-end
  -server.
  +<EM>.jpg</EM>, <EM>.png</EM> and <EM>.txt</EM> internally, the rest will be proxied to be handled by the back-end server.
   
  -<P><A NAME="anchor371"></A>
  +<P>
   The only difference between the two virtual hosts settings is that the
  -former rewrites requests to the port <CODE>4077</CODE> at the back-end machine and the latter to the port <CODE>4078</CODE>.
  +former rewrites requests to port <CODE>4077</CODE> at the back-end machine and the latter to port <CODE>4078</CODE>.
   
  -<P><A NAME="anchor372"></A>
  +<P>
   If your server is configured to run traditional CGI scripts (mod_cgi) as
   well as mod_perl CGI programs, then it would be beneficial to configure the
   front-end server to run the traditional CGI scripts directly. This can be
  @@ -2022,11 +3159,20 @@
   <EM>Rewrite</EM> rule to add <CODE>|cgi</CODE> at the end, or adding a new rule to handle all <CODE>/cgi-bin/*</CODE> locations locally. Similarly, static HTML pages can be served by the
   front-end server by adding <CODE>|html</CODE> to the rule.
   
  -<P><A NAME="anchor373"></A>
  +<P>
   The back-end (heavy) server configuration:
  +
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
   
  -<P><A NAME="anchor374"></A>
  -<PRE>  Port 80
  +	<td>
  +	  <pre>  Port 80
     
     PerlPostReadRequestHandler My::ProxyRemoteAddr
     
  @@ -2042,80 +3188,118 @@
       ServerName foo.example.com
       DocumentRoot /home/httpd/docs/foo.example.com
       DirectoryIndex index.shtml index.html
  -  &lt;/VirtualHost&gt;
  -</PRE>
  -<P><A NAME="anchor375"></A>
  +  &lt;/VirtualHost&gt;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   The back-end server knows to tell which virtual host the request is made
  -to, by checking the port number the request was proxified to and using the
  +to, by checking the port number the request was proxied to and using the
   appropriate virtual host section to handle it.
   
  -<P><A NAME="anchor376"></A>
  +<P>
   We set "Port&nbsp;80" so that any redirects don't get sent directly to the back-end port.
   
  -<P><A NAME="anchor377"></A>
  +<P>
   To get the <EM>real</EM> remote IP addresses from proxy, the
   <A HREF="././scenario.html#Getting_the_Remote_Server_IP_in_">My::ProxyRemoteAddr</A>
  -handler is used based on the <CODE>mod_proxy_add_forward</CODE> Apache module. Prior to mod_perl 1.22+ this setting must have been set
  +handler is used based on the <CODE>mod_proxy_add_forward</CODE> Apache module. Prior to mod_perl 1.22 this setting must have been set
   per-virtual host, since it wasn't inherited by the virtual hosts.
   
  -<P><A NAME="anchor378"></A>
  +<P>
   The following configuration is yet another useful example showing the other
  -way around. It specifies what to be proxified and than the rest is served
  -by the front end:
  +way around. It specifies what to be proxied and then the rest is served by
  +the front end:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor379"></A>
  -<PRE>  RewriteEngine     on
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  RewriteEngine     on
     RewriteLogLevel   0
     RewriteRule       ^/(perl.*)$  <A HREF="http://127.0.0.1:8052/">http://127.0.0.1:8052/</A>$1   [P,L]
     RewriteRule       ^proxy:.*       -                         [F]
     ProxyRequests     on
     NoCache           *
  -  ProxyPassReverse  /  <A HREF="http://www.example.com/">http://www.example.com/</A>
  -</PRE>
  -<P><A NAME="anchor380"></A>
  -So we don't have to specify the rule for the static object to be served by
  -the front-end as we did in the previous example to handle files with the
  -extensions <EM>.gif</EM>, <EM>.jpg</EM>, <EM>.png</EM> and <EM>.txt</EM>
  -internally.
  +  ProxyPassReverse  /  <A HREF="http://www.example.com/">http://www.example.com/</A></pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +So we don't have to specify the rule for static objects to be served by the
  +front-end as we did in the previous example to handle files with the
  +extensions <EM>.gif</EM>, <EM>.jpg</EM>, <EM>.png</EM> and <EM>.txt</EM> internally.
   
  -<P><A NAME="anchor381"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H1><A NAME="Getting_the_Remote_Server_IP_in_">Getting the Remote Server IP in the Back-end server in the Proxy Setup</A></H1></CENTER>
  -<P><A NAME="anchor382"></A>
  +<P>
   Ask Bjoern Hansen has written the <CODE>mod_proxy_add_forward</CODE> module for Apache. It sets the <CODE>X-Forwarded-For</CODE> field when doing a
   <CODE>ProxyPass</CODE>, similar to what Squid can do. Its location is specified in the <A HREF="././download.html#mod_proxy_add_forward">download</A> section.
   
  -<P><A NAME="anchor383"></A>
  +<P>
   Basically, this module adds an extra HTTP header to proxying requests. You
   can access that header in the mod_perl-enabled server, and set the IP
   address of the remote server. You won't need to compile anything into the
   back-end server.
   
  -<P><A NAME="anchor384"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="Build">Build</A></H2></CENTER>
  -<P><A NAME="anchor385"></A>
  +<P>
   Download the module and use its location as a value of the
  -<EM>--activate-module</EM> argument for <EM>./configure</EM> utility within the Apache source code, so the module could be found.
  +<EM>--activate-module</EM> argument for the <EM>./configure</EM> utility within the Apache source code, so the module can be found.
  +
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
   
  -<P><A NAME="anchor386"></A>
  -<PRE>  ./configure \
  +	<td>
  +	  <pre>  ./configure \
     &quot;--with-layout=Apache&quot; \
     &quot;--activate-module=src/modules/extra/mod_proxy_add_forward.c&quot; \
     &quot;--enable-module=proxy_add_forward&quot; \
  -  ... other options ...
  -</PRE>
  -<P><A NAME="anchor387"></A>
  +  ... other options ...</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   <EM>--enable-module=proxy_add_forward</EM> enables this module as you have guessed already.
   
  -<P><A NAME="anchor388"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="Use">Use</A></H2></CENTER>
  -<P><A NAME="anchor389"></A>
  +<P>
   If you are using <CODE>Apache::{Registry,PerlRun}</CODE> just put something like the following into <EM>startup.pl</EM>:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor390"></A>
  -<PRE>  sub My::ProxyRemoteAddr ($) {
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  sub My::ProxyRemoteAddr ($) {
       my $r = shift;
      
       # we'll only look at the X-Forwarded-For header if the requests
  @@ -2128,28 +3312,43 @@
       }
           
       return OK;
  -  }
  -</PRE>
  -<P><A NAME="anchor391"></A>
  +  }</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   And in <CODE>httpd.conf</CODE>:
  +
  +<P>
   
  -<P><A NAME="anchor392"></A>
  -<PRE>  PerlPostReadRequestHandler My::ProxyRemoteAddr
  -</PRE>
  -<P><A NAME="anchor393"></A>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  PerlPostReadRequestHandler My::ProxyRemoteAddr</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Otherwise you retrieve it directly in your code.
   
  -<P><A NAME="anchor394"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="Security">Security</A></H2></CENTER>
  -<P><A NAME="anchor395"></A>
  +<P>
   Different sites have different needs. If you use the header to set the IP
   address, Apache believes it. This is reflected in the logging for example.
  -You really don't want anyone but your own system to set the header, that's
  -why the above ``recommended code'' checks where the request really came
  -from before changing <CODE>remote_ip</CODE>.
  +You really don't want anyone but your own system to set the header, which
  +is why the <EM>recommended code</EM> above checks where the request really came from before changing <CODE>remote_ip</CODE>.
   
  -<P><A NAME="anchor396"></A>
  +<P>
   Generally you shouldn't trust the <CODE>X-Forwarded-For</CODE> header. You only want to rely on <CODE>X-Forwarded-For</CODE> headers from proxies you control yourself. If you know how to spoof a
   cookie you've probably got the general idea on making HTTP headers and can
   spoof the
  @@ -2157,78 +3356,94 @@
   is the one from
   <CODE>r-&gt;connection-&gt;remote_ip</CODE>.
   
  -<P><A NAME="anchor397"></A>
  +<P>
   From that point on, the remote IP address is correct. You should be able to
   access <CODE>REMOTE_ADDR</CODE> as usual.
   
  -<P><A NAME="anchor398"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="Caveats">Caveats</A></H2></CENTER>
  -<P><A NAME="anchor399"></A>
  +<P>
   It was reported that Ben Laurie's Apache-SSL does not seem to put the IP
  -addresses in the <CODE>X-Forwarded-For</CODE> header--it does not set up such a header at all. However, the <CODE>REMOTE_ADDR</CODE> it sets up and contains the IP address of the original client machine.
  +addresses in the <CODE>X-Forwarded-For</CODE> header--it does not set up such a header at all. However, the <CODE>REMOTE_ADDR</CODE> it sets up contains the IP address of the original client machine.
   
  -<P><A NAME="anchor400"></A>
  +<P>
   You could do the same thing with other environment variables, although I
   think several of them are preserved. You should run some tests or, maybe
   better, inspect the code to see which.
   
  -<P><A NAME="anchor401"></A>
  -Prior to mod_perl 1.22+ there was a need to repeat
  -PerlPostReadRequestHandler&nbsp;My::ProxyRemoteAddr directive per each virtual host, since it wasn't inherited by the virtual
  +<P>
  +Prior to mod_perl 1.22 there was a need to repeat the
  +PerlPostReadRequestHandler&nbsp;My::ProxyRemoteAddr directive for each virtual host, since it wasn't inherited by the virtual
   hosts.
   
  -<P><A NAME="anchor402"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<CENTER><H2><A NAME="mod_proxy_add_forward_Module_s_O">mod_proxy_add_forward Module's Order Precedence Importance</A></H2></CENTER>
  -<P><A NAME="anchor403"></A>
  -Some users report that they cannot get this module to work as advertised;
  -they verify that the module is built in, but the front-end server is not
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
  +<CENTER><H2><A NAME="mod_proxy_add_forward_Module_s_O">mod_proxy_add_forward Module's Order Precedence</A></H2></CENTER>
  +<P>
  +Some users report that they cannot get this module to work as advertised.
  +They verify that the module is built in, but the front-end server is not
   generating the X-Forwarded-For header when requests are being proxied to
  -the back-end server, and as a result, the back-end server has no idea what
  -the remote IP is.
  +the back-end server. As a result, the back-end server has no idea what the
  +remote IP is.
   
  -<P><A NAME="anchor404"></A>
  +<P>
   As it turns out, <EM>mod_proxy_add_forward</EM> needs to be configured in Apache before <EM>mod_proxy</EM> in order to operate properly, since Apache gives highest precedence to the
   last defined module.
   
  -<P><A NAME="anchor405"></A>
  +<P>
   Moving the two build options required to enable mod_proxy_add_forward while
   compiling Apache build appears to have no effect on the default
   configuration order of modules, since in each case, the builds show
   mod_proxy_add_forward last in the list (or first via <EM>/server-info</EM>).
   
  -<P><A NAME="anchor406"></A>
  +<P>
   The solution is to explicitly define the configuration order in the
   <EM>http.conf</EM> file, so that mod_proxy_add_forward appears before mod_proxy, and therefore
   gets executed after mod_proxy. (Modules are being executed in <EM>reverse</EM> order, i.e. module that was <EM>Added</EM>
   first will be executed last.)
   
  -<P><A NAME="anchor407"></A>
  +<P>
   Obviously, this list would need to be tailored to match the build
  -environment, but to easy this task just insert <CODE>AddModule</CODE> directive before each entry reported by <CODE>httpd -l</CODE> (and removing
  +environment, but to ease this task just insert an <CODE>AddModule</CODE>
  +directive before each entry reported by <CODE>httpd -l</CODE> (and removing
   <EM>httpd_core.c</EM>, of course):
  +
  +<P>
   
  -<P><A NAME="anchor408"></A>
  -<PRE>  ClearModuleList
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  ClearModuleList
     AddModule mod_env.c
     [more modules snipped]
     AddModule mod_proxy_add_forward.c
     AddModule mod_proxy.c
     AddModule mod_rewrite.c
  -  AddModule mod_setenvif.c
  -</PRE>
  -<P><A NAME="anchor409"></A>
  +  AddModule mod_setenvif.c</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Note that the above snippet is added to <EM>httpd.conf</EM>.
   
  -<P><A NAME="anchor410"></A>
  +<P>
   With this change, the <CODE>X-Forwarded-For</CODE> header is now being sent to the back-end server, and the remote IP appears
   in the back-end server's access log.
   
  -<P><A NAME="anchor411"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H1><A NAME="HTTP_Authentication_With_Two_Ser">HTTP Authentication With Two Servers Plus a Proxy</A></H1></CENTER>
  -<P><A NAME="anchor412"></A>
  +<P>
   Assuming that you have a setup of one ``front-end'' server, which proxies
   the ``back-end'' (mod_perl) server, if you need to perform authentication
   in the ``back-end'' server it should handle all authentication itself. If
  @@ -2236,130 +3451,207 @@
   information, making the ``front-end'' Apache somewhat ``dumb'', as it does
   nothing but pass through the information.
   
  -<P><A NAME="anchor413"></A>
  +<P>
   In the configuration file your <CODE>Auth</CODE> stuff needs to be inside
   <CODE>&lt;Directory ...&gt;</CODE> ... <CODE>&lt;/Directory&gt;</CODE> sections because if you use a <CODE>&lt;Location ...&gt;</CODE>
   ... <CODE>&lt;/Location&gt;</CODE> section the proxy server will take the authentication information for
   itself and not pass it on.
   
  -<P><A NAME="anchor414"></A>
  +<P>
   The same applies to mod_ssl, if plugged into a front-end server. It will
   properly encode/decode all the SSL requests.
   
  -<P><A NAME="anchor415"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H1><A NAME="mod_rewrite_Examples">mod_rewrite Examples</A></H1></CENTER>
  -<P><A NAME="anchor416"></A>
  +<P>
   In the mod_proxy + mod_perl servers scenario, <CODE>ProxyPass</CODE> was used to redirect all requests to the mod_perl server, by matching the
   beginning of the relative URI (e.g. <EM>/perl</EM>). What should you do if you want everything, but files with extensions
   like <EM>.gif</EM> or
   <EM>.cgi</EM>, to be proxypassed to the mod_perl server. These files are to to be served
  -by the light Apache server which carries the mod_procy module.
  +by the light Apache server which carries the mod_proxy module.
  +
  +<P>
   
  -<P><A NAME="anchor417"></A>
  -<PRE>  RewriteEngine On
  -  # handle GIF and JPG images, traditional CGI's directly
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  RewriteEngine On
  +  # handle GIF and JPG images and traditional CGI's directly
     RewriteRule \.(gif|jpg|png|css|txt|cgi)$ - [last]
     RewriteRule ^/cgi-bin - [last]
     # pass off everything but images to the heavy-weight server via proxy
  -  RewriteRule ^/(.*)$ <A HREF="http://localhost:4077/">http://localhost:4077/</A>$1 [proxy]
  -</PRE>
  -<P><A NAME="anchor418"></A>
  -The following example rewrites everything to mod_perl server. It handles
  -locally all the requests to the files with extensions <EM>gif,
  -jpg, png, css, txt, cgi</EM> and relative URIs starting with <EM>/cgi-bin</EM>
  +  RewriteRule ^/(.*)$ <A HREF="http://localhost:4077/">http://localhost:4077/</A>$1 [proxy]</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +The following example rewrites everything to the mod_perl server. It
  +locally handles all requests for files with extensions <EM>gif, jpg,
  +png, css, txt, cgi</EM> and relative URIs starting with <EM>/cgi-bin</EM>
   (e.g. if you want some scripts to be executed under mod_cgi)
   
  -<P><A NAME="anchor419"></A>
  +<P>
   That is, first, handle locally what you want to handle locally, then hand
   off everything else to the back-end guy.
  +
  +<P>
  +This is the configuration of the logging facilities. 
  +
  +<P>
   
  -<P><A NAME="anchor420"></A>
  -These is the configuration of the logging facilities. 
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor421"></A>
  -<PRE>  RewriteLogLevel 1
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  RewriteLogLevel 1
     RewriteLog &quot;| /usr/local/apache_proxy/bin/rotatelogs \
  -  /usr/local/apache-common/logs/r_log 86400&quot;
  -</PRE>
  -<P><A NAME="anchor422"></A>
  -It says: log all the rewrites thru the pipe to <CODE>rotatelogs</CODE> utility which will rotate the logs every 2 hours (86400 secs).
  +  /usr/local/apache-common/logs/r_log 86400&quot;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +It says: log all the rewrites thru the pipe to the <CODE>rotatelogs</CODE>
  +utility which will rotate the logs every 2 hours (86400 secs).
   
  -<P><A NAME="anchor423"></A>
  +<P>
   More examples:
  +
  +<P>
  +Redirect all those IE5 requests for <EM>favicon.ico</EM> to a central image:
  +
  +<P>
   
  -<P><A NAME="anchor424"></A>
  -Redirect all those ie5 requests for <EM>favicon.ico</EM> to a central image:
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor425"></A>
  -<PRE>  RewriteRule .*favicon.ico /wherever/favicon.ico [PT,NS]
  -</PRE>
  -<P><A NAME="anchor426"></A>
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  RewriteRule .*favicon.ico /wherever/favicon.ico [PT,NS]</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   A quick way to make dynamic pages look static:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor427"></A>
  -<PRE>  RewriteRule ^/wherever/([a-zA-Z]+).html /perl-bin/$1.cgi [PT]
  -</PRE>
  -<P><A NAME="anchor428"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  RewriteRule ^/wherever/([a-zA-Z]+).html /perl-bin/$1.cgi [PT]</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H1><A NAME="Caching_in_mod_proxy">Caching in mod_proxy</A></H1></CENTER>
  -<P><A NAME="anchor429"></A>
  -This is not really a mod_perl related, so I'll just stress one point. If
  -you want the caching to work the following HTTP headers should be supplied: <CODE>Last-Modified</CODE>, <CODE>Content-Length</CODE> and
  +<P>
  +This is not really mod_perl related, so I'll just stress one point. If you
  +want the caching to work the following HTTP headers should be supplied: <CODE>Last-Modified</CODE>, <CODE>Content-Length</CODE> and
   <CODE>Expires</CODE>.
   
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -	     The <a href="http://www.modperl.com/">
  -	     <B>Writing Apache Modules with Perl and C</B></a>
  -	     book can be purchased online from <a
  -	     href="http://www.ora.com/catalog/wrapmod/">O'Reilly </a>
  -	     and <a
  -	     href="http://www.amazon.com/exec/obidos/ASIN/156592567X/writinapachemodu">
  -	     Amazon.com</a>.
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   
  -	     <HR>
   
  -	     <B>Your corrections of either technical or grammatical
  +    <p>
  +    <div class="navbar">
  +      <a href="strategy.html">Prev</a>                                 |
  +      <A HREF="index.html"         >Contents</A> |
  +      <A HREF="index.html#search"  >Search</A>   |
  +      <A HREF="index.html#download">Download</A> |
  +      <a href="porting.html">Next</a>
  +    </div>
  +    <p>
  +
  +    <table width="60%" align="center">
  +
  +      <tr>
  +	<td>
  +	  <div class="notice">
  +	  <B>Your corrections of the technical and grammatical
   	     errors are very welcome. You are encouraged to help me
  -	     to improve this guide.  If you have something to
  -	     contribute please <A
  -	     HREF="help.html#Contacting_me"> send it
  +	     improve this guide.  If you have something to contribute
  +	     please <A HREF="help.html#Contacting_me"> send it
   	     directly to me</A>.</B>
  +	  </div>
  +	</td>
  +      </tr>
  +
  +      <tr>
  +	<td>
  +	  <div class="ad">
  +	    The <a href="http://www.modperl.com/">
  +	      <B>Writing Apache Modules with Perl and C</B></a>
  +	    book can be purchased online from <a
  +	      href="http://www.ora.com/catalog/wrapmod/">O'Reilly </a>
  +	    and <a
  +	    href="http://www.amazon.com/exec/obidos/ASIN/156592567X/writinapachemodu">
  +	      Amazon.com</a>.
  +	  </div>
  +	</td>
  +      </tr>
  +
  +</table>
  +
  +<center>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
  +<table cellspacing=2 cellpadding=2>
  +
  +<tr align=center valign=top>
  +<td align=center valign=center>
  +
  +<b><font size=-1>Written by <a
  +href="help.html#Contacting_me">Stas Bekman</a>.<br> Last Modified at 05/31/2000
  +</font></b>
  +<br>
  +
  +</td>
  +
  +<td>
  +
  +<a href="http://perl.apache.org"><img src="images/mod_perl2.jpg"  border=0 alt="mod_perl icon" border=0 height=59 width=150></a>
  +<br>
  +
  +</td>
  +
  +<td>
  +
  +<font size=-2>Use of the Camel for Perl is <br>
  +a trademark of <a href="http://www.ora.com">O'Reilly &amp; Associates</a>,<br>
  +and is used by permission. </font> 
  +<br>
   
  -	     <HR>
  +</td>
   
  -	     [    <A HREF="strategy.html">Prev</A> |      <A HREF="index.html">Main Page</A> | <A HREF="porting.html">Next</A>      ]
  +</tr>
  +</table>
  +</center>
   
  -<CENTER><TABLE CELLSPACING=2 CELLPADDING=2 WIDTH="100%" >
  -<TR ALIGN=CENTER VALIGN=TOP>
  -  <TD ALIGN=CENTER VALIGN=CENTER COLSPAN="3">
  -	     <HR>
  -  </TD>
  -</TR>
  -<TR ALIGN=CENTER VALIGN=TOP>
  -  <TD ALIGN=CENTER VALIGN=CENTER>
  -    <B>
  -      <FONT SIZE=-1>
  -	     Written by <A HREF="help.html#Contacting_me">Stas Bekman</A>.
  -	     <BR>Last Modified at 05/09/2000
  -      </FONT>
  -    </B>
  -  </TD>
  -
  -  <TD>
  -	     <A HREF="http://perl.apache.org"><IMG SRC="images/mod_perl2.jpg" ALT="Mod Perl Icon" BORDER=0 HEIGHT=59 WIDTH=150></A>
  -  </TD>
  -
  -  <TD>
  -    <FONT SIZE=-2>
  -	     Use of the Camel for Perl is <BR>
  -	     a trademark of <A HREF="http://www.ora.com">O'Reilly &amp; Associates</A>,<BR>
  -             and is used by permission. 
  -    </FONT> 
  -  </TD>
  -</TR>
  -</TABLE></CENTER>
  -
  -</BODY>
  -</HTML>
  -	    
  \ No newline at end of file
  +</body>
  +</html>
  
  
  
  1.12      +268 -153  modperl-site/guide/security.html
  
  Index: security.html
  ===================================================================
  RCS file: /home/cvs/modperl-site/guide/security.html,v
  retrieving revision 1.11
  retrieving revision 1.12
  diff -u -r1.11 -r1.12
  --- security.html	2000/05/12 22:42:55	1.11
  +++ security.html	2000/06/07 22:45:37	1.12
  @@ -1,29 +1,37 @@
   <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
  -<HTML>
  -<HEAD>
  -   <TITLE>mod_perl guide: Protecting Your Site</TITLE>
  -   <META NAME="GENERATOR" CONTENT="Pod2HTML [Perl/Linux]">
  -   <META NAME="Author" CONTENT="Stas Bekman">
  -   <META NAME="Description" CONTENT="All Apache/Perl related information: Hints, Guidelines, Scenarios and Troubleshottings">
  -   <META NAME="keywords" CONTENT="mod_perl modperl perl apache cgi webserver speed  fast guide mod_perl apache guide help info faq mod_perl installation cgi troubleshooting help no sex speedup free open source OSS mod_perl apache guide">
  -</HEAD>
  -     <LINK REL=STYLESHEET TYPE="text/css"
  -        HREF="style.css" TITLE="refstyle">
  -     <style type="text/css">
  -     <!-- 
  -        @import url(style.css);
  -     -->
  -     
  -     </style>
  -<BODY BGCOLOR="white">
  +<html>
  +  <head>
  +   <title>mod_perl guide: Protecting Your Site</title>
  +   <meta name="Author" content="Stas Bekman">
  +   <meta name="Description" content="All Apache/Perl related information: Hints, Guidelines, Scenarios and Troubleshottings">
  +   <meta name="keywords" content="mod_perl modperl perl cgi apache webserver speed fast guide mod_perl apache guide help info faq mod_perl installation cgi troubleshooting help no sex speedup free open source OSS mod_perl apache guide">
  +   <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
  +   <meta name="Classification" content="information">
  +   <link href="style.css" rel=stylesheet type="text/css" title="refstyle">
  +  </head>
  +  <body>
  +
  +    <h1 align=center>
  +      <a href="http://perl.apache.org"><img src="images/mod_perl.gif" alt="Mod Perl Icon" border=0 height=30 width=90 align=left></a>
  +      <a href="http://perl.apache.org"><img src="images/mod_perl.gif" alt="Mod Perl Icon" border=0 height=30 width=90 align=right></a>
  +      Protecting Your Site
  +    </h1>
  +    <hr>
  +    <p>
  +    <div class="navbar">
  +      <a href="correct_headers.html">Prev</a>                                 |
  +      <a href="index.html"         >Contents</a> |
  +      <a href="index.html#search"  >Search</a>   |
  +      <a href="index.html#download">Download</a> |
  +      <a href="databases.html">Next</a>
  +    </div>
  +    <p>
  +
  +    <div class="toc">
  +      
   <A NAME="toc"></A>
  -<H1 ALIGN=CENTER>
  -<A HREF="http://perl.apache.org"><IMG SRC="images/mod_perl.gif" ALT="Mod Perl Icon" BORDER=0 HEIGHT=30 WIDTH=90 ALIGN=LEFT></A>
  -<A HREF="http://perl.apache.org"><IMG SRC="images/mod_perl.gif" ALT="Mod Perl Icon" BORDER=0 HEIGHT=30 WIDTH=90 ALIGN=RIGHT></A>
  -Protecting Your Site</H1>
  -<HR WIDTH="100%">
  -	    [    <A HREF="correct_headers.html">Prev</A> |      <A HREF="index.html">Main Page</A> | <A HREF="databases.html">Next</A>      ]<HR><!-- INDEX BEGIN -->
  -<P><B><FONT SIZE=-1>Table of Contents:</FONT></B></P>
  +<P><B>Table of Contents:</B></P>
  +
   <UL>
   
   	<LI><A HREF="#The_Importance_of_Your_site_s_Se">The Importance of Your site's Security</A>
  @@ -41,57 +49,73 @@
   	</UL>
   
   </UL>
  -<!-- INDEX END -->
   
  +    </div>
  +
  +    [ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
   <HR>
  +    <table width="60%" align="center">
   
  -	     The <a href="http://www.modperl.com/">
  -	     <B>Writing Apache Modules with Perl and C</B></a>
  -	     book can be purchased online from <a
  -	     href="http://www.ora.com/catalog/wrapmod/">O'Reilly </a>
  -	     and <a
  -	     href="http://www.amazon.com/exec/obidos/ASIN/156592567X/writinapachemodu">
  -	     Amazon.com</a>.
  -
  -	     <HR>
  -
  -	       <B>Your corrections of either technical or grammatical
  -	       errors are very welcome. You are encouraged to help me
  -	       to improve this guide.  If you have something to
  -	       contribute please <A
  -	       HREF="help.html#Contacting_me"> send it
  -	       directly to me</A>.
  -	       </B>
  -	       <HR>
  +      <tr>
  +	<td>
  +	  <div class="ad">
  +	    The <a href="http://www.modperl.com/">
  +	      <B>Writing Apache Modules with Perl and C</B></a>
  +	    book can be purchased online from <a
  +	      href="http://www.ora.com/catalog/wrapmod/">O'Reilly </a>
  +	    and <a
  +	    href="http://www.amazon.com/exec/obidos/ASIN/156592567X/writinapachemodu">
  +	      Amazon.com</a>.
  +	  </div>
  +	</td>
  +      </tr>
  +
  +      <tr>
  +	<td>
  +	  <div class="notice">
  +	  <B>Your corrections of the technical and grammatical
  +	     errors are very welcome. You are encouraged to help me
  +	     improve this guide.  If you have something to contribute
  +	     please <A HREF="help.html#Contacting_me"> send it
  +	     directly to me</A>.</B>
  +	  </div>
  +	</td>
  +      </tr>
   
  -	      <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<P><A NAME="anchor0"></A>
  +</table>
  +
  +    
  +
  +	    [ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
  +
  +<P>
   <CENTER><H1><A NAME="The_Importance_of_Your_site_s_Se">The Importance of Your site's Security</A></H1></CENTER>
  -<P><A NAME="anchor1"></A>
  +<P>
   Let's face it, your site or service can easily become a target for Internet
   ``terrorists''. It can be because of something you said, the success of
   your site, or for no obvious reason whatever. If your site security is
   compromised, all your data can be deleted or important information can be
   stolen. You may risk legal action or the sack if this happens.
   
  -<P><A NAME="anchor2"></A>
  +<P>
   Your site can be paralyzed through a _simple_ <EM>denial of service</EM>
   (DoS) attack.
   
  -<P><A NAME="anchor3"></A>
  +<P>
   Whatever you do, as long as you are connected to the network your site will
   be vulnerable. Cut the connections, turn off your machine and put it into a
   safe. Now it is protected--but useless.
   
  -<P><A NAME="anchor4"></A>
  +<P>
   So what can you do?
   
  -<P><A NAME="anchor5"></A>
  +<P>
   Let's first get acquainted with some security related terminology:
   
   <DL>
   <P><DT><STRONG><A NAME="item_Authentication">Authentication</A></STRONG><DD>
  -<P><A NAME="anchor6"></A>
  +<P>
   When you want to make sure that a user is who he claims to be, you
   generally ask her for a username and a password. Once you have both, you
   can check them against your <A HREF="././databases.html#">database of username/password pairs</A>. If they match, the user has passed the
  @@ -99,7 +123,7 @@
   <A HREF="././modules.html#Apache_Session_Maintain_sessi">session</A> open all you need to do is to remember the username.
   
   <P><DT><STRONG><A NAME="item_Authorization">Authorization</A></STRONG><DD>
  -<P><A NAME="anchor7"></A>
  +<P>
   You might want to allow user <STRONG>foo</STRONG> to have access to some resource, but restrict her from accessing another
   resource, which in turn is accessible only for user <STRONG>bar</STRONG>. The process of checking access rights is called <STRONG>Authorization</STRONG>. For <STRONG>Authorization</STRONG> all you need is an authenticated username or some other attribute which you
   can authorize against. For example, you can authorize upon IP number,
  @@ -109,35 +133,37 @@
   <STRONG>Authorization</STRONG> without <STRONG>Authentication</STRONG>.
   
   </DL>
  -<P><A NAME="anchor8"></A>
  +<P>
   Actually you've been familiar with both these concepts for a while.
   
  -<P><A NAME="anchor9"></A>
  +<P>
   When you telnet to your account on some machine you go through a login
   process (<STRONG>Authentication</STRONG>).
   
  -<P><A NAME="anchor10"></A>
  +<P>
   When you try to read some file from your file systems, the kernel checks
   the permissions on this file (<STRONG>Authorization</STRONG>). You may hear about <STRONG>Access control</STRONG> which is another name for the same thing.
   
  -<P><A NAME="anchor11"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H1><A NAME="Illustrated_Security_Scenarios">Illustrated Security Scenarios</A></H1></CENTER>
  -<P><A NAME="anchor12"></A>
  +<P>
   I am going to present some real world security requirements and their
   implementations.
   
  -<P><A NAME="anchor13"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="Non_authenticated_access_for_int">Non authenticated access for internal IPs, Authenticated for external IPs</A></H2></CENTER>
  -<P><A NAME="anchor14"></A>
  +<P>
   An <STRONG>Extranet</STRONG> is very similar to an <STRONG>Intranet</STRONG>, but at least partly accessible from outside your organization. If you run
   an Extranet you might want to let your internal users have unrestricted
   access to your web server. If these same users call from outside your
   organization you might want to make sure that they are in fact your
   employees.
   
  -<P><A NAME="anchor15"></A>
  +<P>
   These requirements are achieved very simply by putting the IP patterns of
   the organization in a Perl Access Handler in an
   <CODE>.htaccess</CODE> file. This sets the REMOTE_USER environment variable to the organization's
  @@ -145,32 +171,53 @@
   <CODE>REMOTE_USER</CODE> environment variable to determine whether to allow unrestricted access or
   else to require authentication.
   
  -<P><A NAME="anchor16"></A>
  +<P>
   Once user passes the authentication stage, either bypassing it because of
   his IP address or after entering a correct login/password pair, the
   <CODE>REMOTE_USER</CODE> variable is set. Then we can talk about authorization.
   
  -<P><A NAME="anchor17"></A>
  +<P>
   Let's see the implementation of the authentication stage. First we modify
   &lt;httpd.conf&gt;:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor18"></A>
  -<PRE>  PerlModule My::Auth
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  PerlModule My::Auth
     
     &lt;Location /private&gt;
       PerlAccessHandler My::Auth::access_handler
  -    PerlSetVar Intranet &quot;100.100.100.1 =&gt; userA, 100.100.100.2 =&gt; userB&quot;
  +    PerlSetVar Intranet &quot;10.10.10.1 =&gt; userA, 10.10.10.2 =&gt; userB&quot;
       PerlAuthenHandler My::Auth::authen_handler
       AuthName realm
       AuthType Basic
       Require valid-user
  -  &lt;/Location&gt;
  -</PRE>
  -<P><A NAME="anchor19"></A>
  +  &lt;/Location&gt;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Now the code of My/Auth.pm:
  +
  +<P>
   
  -<P><A NAME="anchor20"></A>
  -<PRE>    sub access_handler {
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>    sub access_handler {
     
           my $r = shift;
     
  @@ -221,149 +268,217 @@
     
         return &quot;Failed for X reason&quot;;
     
  -    }
  -</PRE>
  -<P><A NAME="anchor21"></A>
  +    }</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   You can implement your own <CODE>authen_dbi()</CODE> routine, or you can replace
   <CODE>authen_handler()</CODE> with an existing authentication handler such as
   <CODE>Apache::AuthenDBI</CODE>.
   
  -<P><A NAME="anchor22"></A>
  +<P>
   If one of the IP addresses is matched, <CODE>access_handler()</CODE> sets
   <CODE>REMOTE_USER</CODE> to be either <CODE>userA</CODE> or <CODE>userB</CODE>.
   
  -<P><A NAME="anchor23"></A>
  +<P>
   If neither IP address is matched, <CODE>PerlAuthenHandler</CODE> will not be set to OK, and the Authentication stage will ask the user for a
   login and password.
   
  -<P><A NAME="anchor24"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H1><A NAME="Authentication_code_snippets">Authentication code snippets</A></H1></CENTER>
  -<P><A NAME="anchor25"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="Forcing_re_authentication">Forcing re-authentication</A></H2></CENTER>
  -<P><A NAME="anchor26"></A>
  +<P>
   To force authenticated user to reauthenticate just send the following
   header to the browser:
   
  -<P><A NAME="anchor27"></A>
  -<PRE>  WWW-Authenticate: Basic realm=&quot;My Realm&quot;
  -  HTTP/1.0 401 Unauthorized
  -</PRE>
  -<P><A NAME="anchor28"></A>
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  WWW-Authenticate: Basic realm=&quot;My Realm&quot;
  +  HTTP/1.0 401 Unauthorized</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   This will pop-up (in Netscape at least) a window saying
   <STRONG>Authorization Failed.  Retry?</STRONG> with <STRONG>OK</STRONG> and a <STRONG>Cancel</STRONG> buttons. When that window pops up you know that the password has been
   discarded. If the user hits the <STRONG>Cancel</STRONG> button the username will also be discarded. If she hits the <STRONG>OK</STRONG> button, the authentication window will be brought up again with the
   previous username already in place.
   
  -<P><A NAME="anchor29"></A>
  +<P>
   In the Perl API you would use <CODE>note_basic_auth_failure()</CODE> method
   to force reauthentication.
   
  -<P><A NAME="anchor30"></A>
  +<P>
   This may not work! The browser's behaviour is in no way guaranteed.
   
  -<P><A NAME="anchor31"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="OK_AUTH_REQUIRED_and_FORBIDDEN_">OK, AUTH_REQUIRED and FORBIDDEN in Authentication handlers</A></H2></CENTER>
  -<P><A NAME="anchor32"></A>
  +<P>
   When your authentication handler returns OK, it means that user has
   correctly authenticated and now <CODE>$r-&gt;connection-&gt;user</CODE> will have the username set for subsequent requests. For <CODE>Apache::Registry</CODE>
   and friends, where the environment variable settings weren't erased, an
   equivalent <CODE>$ENV{REMOTE_USER}</CODE> variable will be available. 
   
  -<P><A NAME="anchor33"></A>
  +<P>
   The password is available only through the Perl API with the help of the
   <CODE>get_basic_auth_pw()</CODE> method.
   
  -<P><A NAME="anchor34"></A>
  +<P>
   If there is a failure, unless it's the first time the <CODE>AUTH_REQUIRED</CODE>
   flag will tell the browser to pop up an authentication window, to try
   again. For example:
  +
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
   
  -<P><A NAME="anchor35"></A>
  -<PRE>   my($status, $sent_pw) = $r-&gt;get_basic_auth_pw;
  +	<td>
  +	  <pre>   my($status, $sent_pw) = $r-&gt;get_basic_auth_pw;
      unless($r-&gt;connection-&gt;user and $sent_pw) {
          $r-&gt;note_basic_auth_failure;
          $r-&gt;log_reason(&quot;Both a username and password must be provided&quot;);
          return AUTH_REQUIRED;
  -   }
  -</PRE>
  -<P><A NAME="anchor36"></A>
  +   }</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Let's say that you have a mod_perl authentication handler, where the user's
   credentials are checked against a database. It returns either
   <CODE>OK</CODE> or <CODE>AUTH_REQUIRED</CODE>. One of the possible authentication failure case might happen when the
   username/password are correct, but the user's account has been suspended
   temporarily.
   
  -<P><A NAME="anchor37"></A>
  +<P>
   If this is the case you would like to make the user aware of this, by
   displaying a page, instead of having the browser pop up the authentication
   dialog again. You will also refuse authentication, of course.
   
  -<P><A NAME="anchor38"></A>
  +<P>
   The solution is to return <CODE>FORBIDDEN</CODE>, but before that you should set a custom error page for this specific
   handler, with help of
   <CODE>$r-&gt;custom_response</CODE>. It looks something like this:
   
  -<P><A NAME="anchor39"></A>
  -<PRE>  use Apache::Constants qw(:common);
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  use Apache::Constants qw(:common);
     $r-&gt;custom_response(SERVER_ERROR, &quot;/errors/suspended_account.html&quot;);
      
  -  return FORBIDDEN if $suspended;
  -</PRE>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -	     The <a href="http://www.modperl.com/">
  -	     <B>Writing Apache Modules with Perl and C</B></a>
  -	     book can be purchased online from <a
  -	     href="http://www.ora.com/catalog/wrapmod/">O'Reilly </a>
  -	     and <a
  -	     href="http://www.amazon.com/exec/obidos/ASIN/156592567X/writinapachemodu">
  -	     Amazon.com</a>.
  +  return FORBIDDEN if $suspended;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    [ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   
  -	     <HR>
   
  -	     <B>Your corrections of either technical or grammatical
  +    <p>
  +    <div class="navbar">
  +      <a href="correct_headers.html">Prev</a>                                 |
  +      <A HREF="index.html"         >Contents</A> |
  +      <A HREF="index.html#search"  >Search</A>   |
  +      <A HREF="index.html#download">Download</A> |
  +      <a href="databases.html">Next</a>
  +    </div>
  +    <p>
  +
  +    <table width="60%" align="center">
  +
  +      <tr>
  +	<td>
  +	  <div class="notice">
  +	  <B>Your corrections of the technical and grammatical
   	     errors are very welcome. You are encouraged to help me
  -	     to improve this guide.  If you have something to
  -	     contribute please <A
  -	     HREF="help.html#Contacting_me"> send it
  +	     improve this guide.  If you have something to contribute
  +	     please <A HREF="help.html#Contacting_me"> send it
   	     directly to me</A>.</B>
  +	  </div>
  +	</td>
  +      </tr>
  +
  +      <tr>
  +	<td>
  +	  <div class="ad">
  +	    The <a href="http://www.modperl.com/">
  +	      <B>Writing Apache Modules with Perl and C</B></a>
  +	    book can be purchased online from <a
  +	      href="http://www.ora.com/catalog/wrapmod/">O'Reilly </a>
  +	    and <a
  +	    href="http://www.amazon.com/exec/obidos/ASIN/156592567X/writinapachemodu">
  +	      Amazon.com</a>.
  +	  </div>
  +	</td>
  +      </tr>
  +
  +</table>
  +
  +<center>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
  +<table cellspacing=2 cellpadding=2>
  +
  +<tr align=center valign=top>
  +<td align=center valign=center>
  +
  +<b><font size=-1>Written by <a
  +href="help.html#Contacting_me">Stas Bekman</a>.<br> Last Modified at 05/27/2000
  +</font></b>
  +<br>
  +
  +</td>
  +
  +<td>
  +
  +<a href="http://perl.apache.org"><img src="images/mod_perl2.jpg"  border=0 alt="mod_perl icon" border=0 height=59 width=150></a>
  +<br>
  +
  +</td>
  +
  +<td>
  +
  +<font size=-2>Use of the Camel for Perl is <br>
  +a trademark of <a href="http://www.ora.com">O'Reilly &amp; Associates</a>,<br>
  +and is used by permission. </font> 
  +<br>
   
  -	     <HR>
  +</td>
   
  -	     [    <A HREF="correct_headers.html">Prev</A> |      <A HREF="index.html">Main Page</A> | <A HREF="databases.html">Next</A>      ]
  +</tr>
  +</table>
  +</center>
   
  -<CENTER><TABLE CELLSPACING=2 CELLPADDING=2 WIDTH="100%" >
  -<TR ALIGN=CENTER VALIGN=TOP>
  -  <TD ALIGN=CENTER VALIGN=CENTER COLSPAN="3">
  -	     <HR>
  -  </TD>
  -</TR>
  -<TR ALIGN=CENTER VALIGN=TOP>
  -  <TD ALIGN=CENTER VALIGN=CENTER>
  -    <B>
  -      <FONT SIZE=-1>
  -	     Written by <A HREF="help.html#Contacting_me">Stas Bekman</A>.
  -	     <BR>Last Modified at 12/28/1999
  -      </FONT>
  -    </B>
  -  </TD>
  -
  -  <TD>
  -	     <A HREF="http://perl.apache.org"><IMG SRC="images/mod_perl2.jpg" ALT="Mod Perl Icon" BORDER=0 HEIGHT=59 WIDTH=150></A>
  -  </TD>
  -
  -  <TD>
  -    <FONT SIZE=-2>
  -	     Use of the Camel for Perl is <BR>
  -	     a trademark of <A HREF="http://www.ora.com">O'Reilly &amp; Associates</A>,<BR>
  -             and is used by permission. 
  -    </FONT> 
  -  </TD>
  -</TR>
  -</TABLE></CENTER>
  -
  -</BODY>
  -</HTML>
  -	    
  \ No newline at end of file
  +</body>
  +</html>
  
  
  
  1.24      +1337 -485 modperl-site/guide/snippets.html
  
  Index: snippets.html
  ===================================================================
  RCS file: /home/cvs/modperl-site/guide/snippets.html,v
  retrieving revision 1.23
  retrieving revision 1.24
  diff -u -r1.23 -r1.24
  --- snippets.html	2000/05/12 22:42:55	1.23
  +++ snippets.html	2000/06/07 22:45:37	1.24
  @@ -1,29 +1,37 @@
   <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
  -<HTML>
  -<HEAD>
  -   <TITLE>mod_perl guide: Code Snippets</TITLE>
  -   <META NAME="GENERATOR" CONTENT="Pod2HTML [Perl/Linux]">
  -   <META NAME="Author" CONTENT="Stas Bekman">
  -   <META NAME="Description" CONTENT="All Apache/Perl related information: Hints, Guidelines, Scenarios and Troubleshottings">
  -   <META NAME="keywords" CONTENT="mod_perl modperl perl apache cgi webserver speed  fast guide mod_perl apache guide help info faq mod_perl installation cgi troubleshooting help no sex speedup free open source OSS mod_perl apache guide">
  -</HEAD>
  -     <LINK REL=STYLESHEET TYPE="text/css"
  -        HREF="style.css" TITLE="refstyle">
  -     <style type="text/css">
  -     <!-- 
  -        @import url(style.css);
  -     -->
  -     
  -     </style>
  -<BODY BGCOLOR="white">
  +<html>
  +  <head>
  +   <title>mod_perl guide: Code Snippets</title>
  +   <meta name="Author" content="Stas Bekman">
  +   <meta name="Description" content="All Apache/Perl related information: Hints, Guidelines, Scenarios and Troubleshottings">
  +   <meta name="keywords" content="mod_perl modperl perl cgi apache webserver speed fast guide mod_perl apache guide help info faq mod_perl installation cgi troubleshooting help no sex speedup free open source OSS mod_perl apache guide">
  +   <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
  +   <meta name="Classification" content="information">
  +   <link href="style.css" rel=stylesheet type="text/css" title="refstyle">
  +  </head>
  +  <body>
  +
  +    <h1 align=center>
  +      <a href="http://perl.apache.org"><img src="images/mod_perl.gif" alt="Mod Perl Icon" border=0 height=30 width=90 align=left></a>
  +      <a href="http://perl.apache.org"><img src="images/mod_perl.gif" alt="Mod Perl Icon" border=0 height=30 width=90 align=right></a>
  +      Code Snippets
  +    </h1>
  +    <hr>
  +    <p>
  +    <div class="navbar">
  +      <a href="modules.html">Prev</a>                                 |
  +      <a href="index.html"         >Contents</a> |
  +      <a href="index.html#search"  >Search</a>   |
  +      <a href="index.html#download">Download</a> |
  +      <a href="hardware.html">Next</a>
  +    </div>
  +    <p>
  +
  +    <div class="toc">
  +      
   <A NAME="toc"></A>
  -<H1 ALIGN=CENTER>
  -<A HREF="http://perl.apache.org"><IMG SRC="images/mod_perl.gif" ALT="Mod Perl Icon" BORDER=0 HEIGHT=30 WIDTH=90 ALIGN=LEFT></A>
  -<A HREF="http://perl.apache.org"><IMG SRC="images/mod_perl.gif" ALT="Mod Perl Icon" BORDER=0 HEIGHT=30 WIDTH=90 ALIGN=RIGHT></A>
  -Code Snippets</H1>
  -<HR WIDTH="100%">
  -	    [    <A HREF="modules.html">Prev</A> |      <A HREF="index.html">Main Page</A> | <A HREF="hardware.html">Next</A>      ]<HR><!-- INDEX BEGIN -->
  -<P><B><FONT SIZE=-1>Table of Contents:</FONT></B></P>
  +<P><B>Table of Contents:</B></P>
  +
   <UL>
   
   	<LI><A HREF="#Redirecting_Errors_to_the_Client">Redirecting Errors to the Client Instead of error_log</A>
  @@ -55,35 +63,52 @@
   	<LI><A HREF="#Getting_the_Front_end_Server_s_N">Getting the Front-end Server's Name in the Back-end Server</A>
   	<LI><A HREF="#Authentication_Snippets">Authentication Snippets</A>
   	<LI><A HREF="#Using_DESTROY_to_Finalize_Output">Using DESTROY to Finalize Output</A>
  +	<LI><A HREF="#Setting_Environment_Variables_Fo">Setting Environment Variables For Scripts Called From CGI.</A>
   	<LI><A HREF="#Mysql_Backup_and_Restore_Scripts">Mysql Backup and Restore Scripts</A>
   </UL>
  -<!-- INDEX END -->
   
  +    </div>
  +
  +    [ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
   <HR>
  +    <table width="60%" align="center">
  +
  +      <tr>
  +	<td>
  +	  <div class="ad">
  +	    The <a href="http://www.modperl.com/">
  +	      <B>Writing Apache Modules with Perl and C</B></a>
  +	    book can be purchased online from <a
  +	      href="http://www.ora.com/catalog/wrapmod/">O'Reilly </a>
  +	    and <a
  +	    href="http://www.amazon.com/exec/obidos/ASIN/156592567X/writinapachemodu">
  +	      Amazon.com</a>.
  +	  </div>
  +	</td>
  +      </tr>
  +
  +      <tr>
  +	<td>
  +	  <div class="notice">
  +	  <B>Your corrections of the technical and grammatical
  +	     errors are very welcome. You are encouraged to help me
  +	     improve this guide.  If you have something to contribute
  +	     please <A HREF="help.html#Contacting_me"> send it
  +	     directly to me</A>.</B>
  +	  </div>
  +	</td>
  +      </tr>
  +
  +</table>
   
  -	     The <a href="http://www.modperl.com/">
  -	     <B>Writing Apache Modules with Perl and C</B></a>
  -	     book can be purchased online from <a
  -	     href="http://www.ora.com/catalog/wrapmod/">O'Reilly </a>
  -	     and <a
  -	     href="http://www.amazon.com/exec/obidos/ASIN/156592567X/writinapachemodu">
  -	     Amazon.com</a>.
  -
  -	     <HR>
  -
  -	       <B>Your corrections of either technical or grammatical
  -	       errors are very welcome. You are encouraged to help me
  -	       to improve this guide.  If you have something to
  -	       contribute please <A
  -	       HREF="help.html#Contacting_me"> send it
  -	       directly to me</A>.
  -	       </B>
  -	       <HR>
  +    
  +
  +	    [ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   
  -	      <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<P><A NAME="anchor0"></A>
  +<P>
   <CENTER><H1><A NAME="Redirecting_Errors_to_the_Client">Redirecting Errors to the Client Instead of error_log</A></H1></CENTER>
  -<P><A NAME="anchor1"></A>
  +<P>
   Many error conditions result in an <EM>exception</EM> (or <EM>signal</EM> -- same thing) which is <EM>raised</EM> in order to tell the operating system that a condition has arisen which
   needs more urgent attention than can be given by other means. One of the
   most familiar ways of raising a signal is to hit <CODE>Ctrl-C</CODE> on your terminal's keyboard. The signal interrupts the processor. In the
  @@ -91,32 +116,44 @@
   <EM>signal handler</EM> supplied by OS, which causes the operating system to stop the process
   currently attached to the terminal.
   
  -<P><A NAME="anchor2"></A>
  +<P>
   Under mod_perl, a Perl runtime error causes an exception. By default this
   exception is trapped by default mod_perl handler. The handler logs
   information about the error (such as the date and time that the error
   occurred) to <EM>error_log</EM>. If you want to redirect this information to the client instead of to <EM>error_log</EM> you have to take the responsibility yourself, by writing your own exception
   handler to implement this behaviour. See the section ``<A HREF="././perl.html#Exception_Handling_for_mod_perl">Exception Handling for mod_perl</A>'' for more information.
   
  -<P><A NAME="anchor3"></A>
  +<P>
   The code examples below can be useful with your own exception handlers as
   well as with the default handlers.
   
  -<P><A NAME="anchor4"></A>
  +<P>
   META: Integrate the 2 sections
   
  -<P><A NAME="anchor5"></A>
  +<P>
   The CGI::Carp package implements handlers for signals. To trap (almost) all
   Perl run-time errors and send the output to the client instead of to
   Apache's <CODE>error_log</CODE> add this line to your script:
  +
  +<P>
   
  -<P><A NAME="anchor6"></A>
  -<PRE>  use CGI::Carp qw(fatalsToBrowser);
  -</PRE>
  -<P><A NAME="anchor7"></A>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  use CGI::Carp qw(fatalsToBrowser);</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Refer to the <CODE>CGI::Carp</CODE> man page for more detailed information.
   
  -<P><A NAME="anchor8"></A>
  +<P>
   You can trap individual exceptions: for example you can write custom
   <CODE>__DIE__</CODE> and <CODE>__WARN__</CODE> signal handlers. The special <CODE>%SIG</CODE> hash contains references to signal handlers. The signal handler is just a
   subroutine, in the example below it is called ``mydie''. To install the
  @@ -125,13 +162,13 @@
   <CODE>mydie(error_message)</CODE> whenever the <CODE>die()</CODE> sub is called as a result of something which happened when our script was
   executing.
   
  -<P><A NAME="anchor9"></A>
  +<P>
   Do not forget the <CODE>local</CODE> keyword! If you do, then after the signal handler has been loaded it will
   be called whenever <CODE>die()</CODE> is called by <EM>any</EM> script executed by the same process. Probably that's not what you want. If
   it is, you can put the assignment statement in any module, as long as it
   will be executed at the right time.
   
  -<P><A NAME="anchor10"></A>
  +<P>
   Here is an example of a handler which I wrote because I wanted users to
   know that there was an error, without displaying the error message, but
   instead email it to me. If the error is caused by user (e.g. uploading
  @@ -140,21 +177,42 @@
   correctly when called from the shell. The code shown below is a
   stripped-down version with additional comments.
   
  -<P><A NAME="anchor11"></A>
  +<P>
   The following code must be added to the script:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor12"></A>
  -<PRE>  # Using the local() keyword restricts the scope of the directive to 
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  # Using the local() keyword restricts the scope of the directive to 
     # the block in which it is found, so this line must be added at the 
     # right place in the right script.  It will not affect other blocks 
     # unless the local() keyword is removed.  Usually you will want the 
     # directive to affect the entire script, so you just place it near 
     # the beginning of the file, where the innermost enclosing block is 
     # the file itself.
  -  local $SIG{__DIE__} = \&amp;mydie;
  -</PRE>
  -<P><A NAME="anchor13"></A>
  -<PRE>  # The line above assumes that the subroutine &quot;mydie&quot; is in the same script.
  +  local $SIG{__DIE__} = \&amp;mydie;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  # The line above assumes that the subroutine &quot;mydie&quot; is in the same script.
     # Alternatively you can create a separate module for the error handler.
     # If you put the signal handler in a separate module, e.g. Error.pm,
     # you must explicitly give the package name to set the handler in your
  @@ -164,14 +222,38 @@
     
     # Do not forget the C&lt;local()&gt;, unless you want this signal handler to
     # be invoked every time any scripts dies (including events where this
  -  # treatment may be undesirable).
  -</PRE>
  -<P><A NAME="anchor14"></A>
  -<PRE>  my $max_image_size = 100*1024; # 100k
  -  my $admin_email    = 'foo@example.com';
  -</PRE>
  -<P><A NAME="anchor15"></A>
  -<PRE>  # and the handler itself
  +  # treatment may be undesirable).</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  my $max_image_size = 100*1024; # 100k
  +  my $admin_email    = 'foo@example.com';</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  # and the handler itself
     # Here is the handler itself:
     # The handler is called with a text message in a scalar argument
     sub mydie{
  @@ -265,65 +347,103 @@
     
       exit 1;
     }                             # end of sub mydie
  -  
  -</PRE>
  -<P><A NAME="anchor16"></A>
  +  </pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   You may have noticed that I trap the CGI.pm's <CODE>die()</CODE> calls
   here, I don't see any reason why my users should see ugly error messages,
   but that's the way CGI.pm written. The workaround is to trap them yourself.
   
  -<P><A NAME="anchor17"></A>
  +<P>
   Please note that as of version 2.49, CGI.pm provides the
   <CODE>cgi_error()</CODE> method to print the errors and won't
   <CODE>die()</CODE> unless you want it to.
   
  -<P><A NAME="anchor18"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H1><A NAME="Emulating_the_Authentication_Mec">Emulating the Authentication Mechanism</A></H1></CENTER>
  -<P><A NAME="anchor19"></A>
  +<P>
   You can provide your own mechanism to authenticate users, instead of the
   standard one. If you want to make Apache think that the user was
   authenticated by the standard mechanism, set the username with:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor20"></A>
  -<PRE>  $r-&gt;connection-&gt;user('username');
  -</PRE>
  -<P><A NAME="anchor21"></A>
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  $r-&gt;connection-&gt;user('username');</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Now you can use this information for example during the logging, so that
   you can have your ``username'' passed as if it was transmitted to Apache
   through HTTP authentication.
   
  -<P><A NAME="anchor22"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H1><A NAME="Caching_POSTed_Data">Caching POSTed Data</A></H1></CENTER>
  -<P><A NAME="anchor23"></A>
  +<P>
   What happens if you need to access the POSTed data more than once, say to
   reuse it on subsequent requests? POSTed data comes directly from the
   socket, and at the low level data can only be read from a socket once. So
   you have to store it to make it available for reuse.  
   
  -<P><A NAME="anchor24"></A>
  +<P>
   There is an experimental option for <CODE>Makefile.PL</CODE> called 
   <CODE>PERL_STASH_POST_DATA</CODE>. If you turn it on, you can get at it again with <CODE>$r-&gt;subprocess_env("POST_DATA")</CODE>. This is not on by default because it adds overhead.
   
  -<P><A NAME="anchor25"></A>
  +<P>
   And what do we do with large multipart file uploads? Because <CODE>POST</CODE> 
   data is not all read in one clump, it's a problem that's not easy to solve
   in a general way. You might try the following approach:
   
  -<P><A NAME="anchor26"></A>
  +<P>
   In httpd.conf:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor27"></A>
  -<PRE>  &lt;Limit POST&gt;
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  &lt;Limit POST&gt;
        PerlFixupHandler    My::fixup_handler
  -  &lt;/Limit&gt;
  -</PRE>
  -<P><A NAME="anchor28"></A>
  +  &lt;/Limit&gt;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   In your script:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor29"></A>
  -<PRE>  use Apache::Constants;
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  use Apache::Constants;
     sub My::fixup_handler {
       my $r = shift;
       return DECLINED unless $r-&gt;method eq &quot;POST&quot;;
  @@ -332,51 +452,101 @@
       $r-&gt;method_number(M_GET);
       $r-&gt;headers_in-&gt;unset('Content-length');
       OK;
  -  }
  -</PRE>
  -<P><A NAME="anchor30"></A>
  +  }</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Now when <CODE>CGI.pm</CODE>, <CODE>Apache::Request</CODE> or whatever parses the client data, it can do so more than once since <CODE>$r-&gt;args</CODE> doesn't go away (unless you make it go away).
   
  -<P><A NAME="anchor31"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H1><A NAME="Cache_Control_for_Regular_and_Er">Cache Control for Regular and Error Modes</A></H1></CENTER>
  -<P><A NAME="anchor32"></A>
  +<P>
   To disable caching you should use the headers:
  +
  +<P>
   
  -<P><A NAME="anchor33"></A>
  -<PRE>  Pragma: no-cache
  -  Cache-control: no-cache
  -</PRE>
  -<P><A NAME="anchor34"></A>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  Pragma: no-cache
  +  Cache-control: no-cache</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   For normally generated response use:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor35"></A>
  -<PRE>  $r-&gt;header_out(&quot;Pragma&quot;,&quot;no-cache&quot;);
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  $r-&gt;header_out(&quot;Pragma&quot;,&quot;no-cache&quot;);
     $r-&gt;header_out(&quot;Cache-control&quot;,&quot;no-cache&quot;);
  -  $r-&gt;no_cache(1);
  -</PRE>
  -<P><A NAME="anchor36"></A>
  +  $r-&gt;no_cache(1);</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   If for some reason you need to use them in Error control code use:
  +
  +<P>
   
  -<P><A NAME="anchor37"></A>
  -<PRE>  $r-&gt;err_header_out(&quot;Pragma&quot;,&quot;no-cache&quot;);
  -  $r-&gt;err_header_out(&quot;Cache-control&quot;,&quot;no-cache&quot;);
  -</PRE>
  -<P><A NAME="anchor38"></A>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  $r-&gt;err_header_out(&quot;Pragma&quot;,&quot;no-cache&quot;);
  +  $r-&gt;err_header_out(&quot;Cache-control&quot;,&quot;no-cache&quot;);</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   META: $r-&gt;no_cache(1); ?
   
  -<P><A NAME="anchor39"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H1><A NAME="Convert_a_POST_Request_into_a_GE">Convert a POST Request into a GET Request</A></H1></CENTER>
  -<P><A NAME="anchor40"></A>
  +<P>
   Remember that <STRONG>you can only read POST data from the socket once</STRONG>. If you need to use it more than once, you need to save it somewhere.
   
  -<P><A NAME="anchor41"></A>
  +<P>
   A transparent way to do this is to switch the request method from POST to
   GET, and store the POST data in the query string:
  +
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
   
  -<P><A NAME="anchor42"></A>
  -<PRE>  package Apache::POST2GET;
  +	<td>
  +	  <pre>  package Apache::POST2GET;
     use Apache::Constants qw(M_GET);
     
     sub handler {
  @@ -389,137 +559,230 @@
          $r-&gt;headers_in-&gt;unset('Content-length');
       }
     }
  -  __END__
  -</PRE>
  -<P><A NAME="anchor43"></A>
  +  __END__</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Then add this directive to <EM>httpd.conf</EM>:
   
  -<P><A NAME="anchor44"></A>
  -<PRE>  PerlInitHandler Apache::POST2GET
  -</PRE>
  -<P><A NAME="anchor45"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  PerlInitHandler Apache::POST2GET</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H1><A NAME="Redirect_a_POST_Request_Forward">Redirect a POST Request, Forwarding the Content</A></H1></CENTER>
  -<P><A NAME="anchor46"></A>
  +<P>
   With mod_perl you can easily redirect a POST request to some other
   location. All you have to do is read in the contents, set the method to <CODE>GET</CODE>, populate <CODE>args()</CODE> with the content to be forwarded and finally do the redirect:
  +
  +<P>
   
  -<P><A NAME="anchor47"></A>
  -<PRE>  my $r = shift;
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  my $r = shift;
     my $content = $r-&gt;content;
     $r-&gt;method(&quot;GET&quot;);
     $r-&gt;method_number(M_GET);
     $r-&gt;headers_in-&gt;unset(&quot;Content-length&quot;);
     $r-&gt;args($content);
  -  $r-&gt;internal_redirect_handler(&quot;/new/url&quot;);
  -</PRE>
  -<P><A NAME="anchor48"></A>
  +  $r-&gt;internal_redirect_handler(&quot;/new/url&quot;);</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Of course that last line can be any other kind of redirect.
   
  -<P><A NAME="anchor49"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H1><A NAME="Reading_POST_Data_then_Redirect">Reading POST Data, then Redirecting or Doing Something Else</A></H1></CENTER>
  -<P><A NAME="anchor50"></A>
  +<P>
   If you read POST data, then redirect, you need to do this before the
   redirect or apache will hang:
   
  -<P><A NAME="anchor51"></A>
  -<PRE>  $r-&gt;method_number(M_GET);
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  $r-&gt;method_number(M_GET);
     $r-&gt;method('GET');
     $r-&gt;headers_in-&gt;unset('Content-length');
     $r-&gt;header_out('Location' =&gt; $ENV{SCRIPT_NAME});
     $r-&gt;status(REDIRECT);
  -  $r-&gt;send_http_header;
  -</PRE>
  -<P><A NAME="anchor52"></A>
  +  $r-&gt;send_http_header;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   After the first time you read POST data, you need the code above to prevent
   somebody else from trying to read post data that's already been read.
   
  -<P><A NAME="anchor53"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H1><A NAME="Redirecting_While_Maintaining_En">Redirecting While Maintaining Environment Variables</A></H1></CENTER>
  -<P><A NAME="anchor54"></A>
  +<P>
   Let's say you have a module that sets some environment variables.
   
  -<P><A NAME="anchor55"></A>
  +<P>
   If you redirect, that's most likely telling the web browser to fetch the
   new page. This makes it a totally new request, so no environment variables
   are preserved.
   
  -<P><A NAME="anchor56"></A>
  +<P>
   However, if you're using <CODE>internal_redirect(),</CODE> then
   <CODE>subprocess_env()</CODE> should do the trick, but the <CODE>%ENV</CODE> keys will be prefixed with
   <CODE>REDIRECT_</CODE>.
   
  -<P><A NAME="anchor57"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H1><A NAME="Terminating_a_Child_Process_on_R">Terminating a Child Process on Request Completion</A></H1></CENTER>
  -<P><A NAME="anchor58"></A>
  +<P>
   If you want to terminate the child process serving the current request,
   upon completion of processing anywhere in the code call:
   
  -<P><A NAME="anchor59"></A>
  -<PRE>  $r-&gt;child_terminate;
  -</PRE>
  -<P><A NAME="anchor60"></A>
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  $r-&gt;child_terminate;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Apache won't actually terminate the child until everything it needs to do
   is done and the connection is closed.
   
  -<P><A NAME="anchor61"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H1><A NAME="More_on_Relative_Paths">More on Relative Paths</A></H1></CENTER>
  -<P><A NAME="anchor62"></A>
  +<P>
   Many people use relative paths for <CODE>require</CODE>, <CODE>use</CODE>, etc., and when they open files in their scripts they make assumptions
   about the current directory. This will fail if you don't <A HREF="#item_chdir">chdir()</A> to the correct directory first (as could easily happen if you have another
   script which calls the first script by its full path).
   
  -<P><A NAME="anchor63"></A>
  +<P>
   For example:
  +
  +<P>
   
  -<P><A NAME="anchor64"></A>
  -<PRE>  /home/httpd/perl/test.pl:
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  /home/httpd/perl/test.pl:
     -------------------------
     #!/usr/bin/perl
     open IN, &quot;./foo.txt&quot;;
  -  -------------------------
  -</PRE>
  -<P><A NAME="anchor65"></A>
  +  -------------------------</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   This snippet would work if we call the script like this:
   
  -<P><A NAME="anchor66"></A>
  -<PRE>  % chdir /home/httpd/perl
  -  % ./test.pl
  -</PRE>
  -<P><A NAME="anchor67"></A>
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  % chdir /home/httpd/perl
  +  % ./test.pl</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   since <CODE>foo.txt</CODE> is located in the current directory. But when the current directory isn't <EM>/home/httpd/perl</EM>, if we call the script like this:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor68"></A>
  -<PRE>  % /home/httpd/perl/test.pl
  -</PRE>
  -<P><A NAME="anchor69"></A>
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  % /home/httpd/perl/test.pl</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   then the script will fail to find <CODE>foo.txt</CODE>. Think about 
   <CODE>crontab</CODE>s!
   
  -<P><A NAME="anchor70"></A>
  +<P>
   Notice that you cannot use the <CODE>FindBin.pm</CODE> package, something that you'd do in the regular Perl scripts, because it
   relies on the BEGIN block it won't work under mod_perl. It's loaded and
   executed only for the first script executed inside the process, all the
   others will use the cached value, which would be probably incorrect. Aargh.
   
  -<P><A NAME="anchor71"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H1><A NAME="Watching_the_error_log_File_With">Watching the error_log File Without Telneting to the Server</A></H1></CENTER>
  -<P><A NAME="anchor72"></A>
  +<P>
   I wrote this script a long time ago, when I had to debug my CGI scripts but
   didn't have access to the <CODE>error_log</CODE> file. I asked the admin to install this script and have used it happily
   since then.
   
  -<P><A NAME="anchor73"></A>
  +<P>
   If your scripts are running on these 'Get-free-site' servers, and you
   cannot debug your script because you can't telnet to the server or can't
   see the <CODE>error_log</CODE>, you can ask your sysadmin to install this script.
   
  -<P><A NAME="anchor74"></A>
  +<P>
   Note, that it was written for plain Apache, and isn't prepared to handle
   the complex multiline error and warning messages generated by mod_perl. It
   also uses a <CODE>system()</CODE> call to do the main work with the
  @@ -527,11 +790,20 @@
   is due (take a look at <CODE>File::Tail</CODE> module). You are welcome to fix it and contribute it back to mod_perl
   community. Thank you!
   
  -<P><A NAME="anchor75"></A>
  +<P>
   Here is the code:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor76"></A>
  -<PRE>  # !/usr/bin/perl -Tw
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  # !/usr/bin/perl -Tw
     
     use strict;
     
  @@ -605,37 +877,63 @@
       return exists $colors{$type}
           ? qq{&lt;B&gt;&lt;FONT COLOR=&quot;$colors{$type}&quot;&gt;$context&lt;/FONT&gt;&lt;/B&gt;}
           : $context;
  -  }
  -</PRE>
  -<P><A NAME="anchor77"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +  }</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H1><A NAME="Accessing_Variables_from_the_Cal">Accessing Variables from the Caller's Package</A></H1></CENTER>
  -<P><A NAME="anchor78"></A>
  +<P>
   Sometimes you want to access variables from the caller's package. One way
   is to do something like this:
  +
  +<P>
   
  -<P><A NAME="anchor79"></A>
  -<PRE>  {
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  {
       no strict 'vars' ;
       my $caller = caller;
       print qq[$caller --- ${&quot;${caller}::var&quot;}];
  -  }
  -</PRE>
  -<P><A NAME="anchor80"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +  }</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H1><A NAME="Handling_Cookies">Handling Cookies</A></H1></CENTER>
  -<P><A NAME="anchor81"></A>
  +<P>
   Unless you use some well known module like <CODE>CGI.pm</CODE>, handle cookies yourself.
   
  -<P><A NAME="anchor82"></A>
  +<P>
   Cookies come in the <CODE>$ENV{HTTP_COOKIE}</CODE> variable. You can print the raw cookie string as <CODE>$ENV{HTTP_COOKIE}</CODE>.
   
  -<P><A NAME="anchor83"></A>
  +<P>
   Here is a fairly well-known bit of code to take cookie values and put them
   into a hash:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor84"></A>
  -<PRE>  sub get_cookies {
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  sub get_cookies {
         # cookies are seperated by a semicolon and a space, this will
         # split them and return a hash of cookies
       local(@rawCookies) = split (/; /,$ENV{'HTTP_COOKIE'});
  @@ -647,72 +945,139 @@
       }
     
       return %cookies;
  -  }
  -</PRE>
  -<P><A NAME="anchor85"></A>
  +  }</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Or a slimmer version:
  +
  +<P>
   
  -<P><A NAME="anchor86"></A>
  -<PRE>    sub get_cookies {
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>    sub get_cookies {
           map { split /=/, $_, 2 } split /; /, $ENV{'HTTP_COOKIE'} ;
       }
  -        
  -</PRE>
  -<P><A NAME="anchor87"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +        </pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H1><A NAME="Sending_Multiple_Cookies_with_th">Sending Multiple Cookies with the Perl API</A></H1></CENTER>
  -<P><A NAME="anchor88"></A>
  +<P>
   Given that you have prepared your cookies in <CODE>@cookies</CODE>, the following would do:
  +
  +<P>
   
  -<P><A NAME="anchor89"></A>
  -<PRE>  for(@cookies){
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  for(@cookies){
      $r-&gt;headers_out-&gt;add( 'Set-Cookie' =&gt; $_ );
  - }
  -</PRE>
  -<P><A NAME="anchor90"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  + }</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H1><A NAME="Sending_Cookies_in_REDIRECT_Resp">Sending Cookies in REDIRECT Response</A></H1></CENTER>
  -<P><A NAME="anchor91"></A>
  +<P>
   You should use <CODE>err_headers_out()</CODE> and not
   <CODE>headers_out()</CODE> when you want to send cookies in the <CODE>REDIRECT</CODE> response.
   
  -<P><A NAME="anchor92"></A>
  -<PRE>  my $r = shift;
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  my $r = shift;
     $r-&gt;err_headers_out-&gt;add('Set-Cookie' =&gt; $cookie);
     $r-&gt;headers_out(Location =&gt; $location);
     $r-&gt;status(REDIRECT);
     $r-&gt;send_http_header;
  -  return OK;
  -</PRE>
  -<P><A NAME="anchor93"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +  return OK;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H1><A NAME="Passing_and_Preserving_Custom_Da">Passing and Preserving Custom Data Structures Between Handlers</A></H1></CENTER>
  -<P><A NAME="anchor94"></A>
  +<P>
   Let's say that you wrote a few handlers to process a request, and they all
   need to share some custom Perl data structure. The <CODE>pnotes()</CODE>
   method comes to your rescue. Given that one of the handlers stored some
   data in a hash <CODE>%my_data</CODE>, then before it terminates:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor95"></A>
  -<PRE>   # First handler:
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>   # First handler:
      my %my_data = qw(foo =&gt; 1, bar =&gt; 2);
  -   $r-&gt;pnotes('my_data' =&gt; \%my_data);
  -</PRE>
  -<P><A NAME="anchor96"></A>
  +   $r-&gt;pnotes('my_data' =&gt; \%my_data);</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   All the subsequent handlers will be able to retrieve the stored data with:
  +
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
   
  -<P><A NAME="anchor97"></A>
  -<PRE>   # Later handler:
  +	<td>
  +	  <pre>   # Later handler:
      my $info = $r-&gt;pnotes('my_data');
  -   print $info-&gt;{foo};
  -</PRE>
  -<P><A NAME="anchor98"></A>
  +   print $info-&gt;{foo};</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   The stored information will be destroyed at the end of the request.
   
  -<P><A NAME="anchor99"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H1><A NAME="Passing_Notes_Between_mod_perl_a">Passing Notes Between mod_perl and other (non-Perl) Apache Modules</A></H1></CENTER>
  -<P><A NAME="anchor100"></A>
  +<P>
   the <CODE>notes()</CODE> method can be used to make various Apache modules
   talk to each other. In this snippet the php application calls the mod_perl
   application by marking up a bunch of notes in its own request and then
  @@ -720,11 +1085,20 @@
   gets this internal sub-request reads those notes and writes its replies in
   the same place.
   
  -<P><A NAME="anchor101"></A>
  +<P>
   First you read the request with (the following code is in PHP):
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor102"></A>
  -<PRE>  if (isset($user) &amp;&amp; substr($user,0,1) == &quot;+&quot;) {
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  if (isset($user) &amp;&amp; substr($user,0,1) == &quot;+&quot;) {
       apache_note(&quot;imp_euser&quot;, substr($user,1));
       virtual(&quot;/internal/getquota&quot;);
       $quota      = apache_note(&quot;imp_quota&quot;);
  @@ -733,30 +1107,55 @@
       $percent_pp = apache_note(&quot;imp_percent_pp&quot;);
       if ($quota)
         $message .= &quot; | Using $percent_pp% of $quota_pp limit&quot;;
  -  }
  -</PRE>
  -<P><A NAME="anchor103"></A>
  +  }</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   and then you read and write the notes with <CODE>$r-&gt;main-&gt;notes</CODE>
   from mod_perl.
   
  -<P><A NAME="anchor104"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H1><A NAME="Passing_Environment_Variables_Be">Passing Environment Variables Between Handlers</A></H1></CENTER>
  -<P><A NAME="anchor105"></A>
  +<P>
   A simple example of passing environment variables between handlers:
   
  -<P><A NAME="anchor106"></A>
  +<P>
   Having a configuration:
   
  -<P><A NAME="anchor107"></A>
  -<PRE>  PerlAccessHandler My::Access
  -  PerlLogHandler My::Log
  -</PRE>
  -<P><A NAME="anchor108"></A>
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  PerlAccessHandler My::Access
  +  PerlLogHandler My::Log</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   and in <EM>startup.pl</EM>:
  +
  +<P>
   
  -<P><A NAME="anchor109"></A>
  -<PRE>  sub My::Access::handler {
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  sub My::Access::handler {
       my $r = shift;
       $r-&gt;subprocess_env(TICKET =&gt; $$);
       $r-&gt;notes(TICKET =&gt; $$);
  @@ -767,32 +1166,58 @@
       my $env = $r-&gt;subprocess_env('TICKET');
       my $note = $r-&gt;notes('TICKET');
       warn &quot;env=$env, note=$note\n&quot;;
  -  }
  -</PRE>
  -<P><A NAME="anchor110"></A>
  +  }</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Adding <CODE>%{TICKET}e</CODE> and <CODE>%{TICKET}n</CODE> to the <CODE>LogFormat</CODE> for access_log works fine too.
   
  -<P><A NAME="anchor111"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H1><A NAME="CGI_params_in_the_mod_perl_ish_">CGI::params in the mod_perl-ish Way</A></H1></CENTER>
  -<P><A NAME="anchor112"></A>
  +<P>
   Extracting request parameters in the mod_perl-ish way:
   
  -<P><A NAME="anchor113"></A>
  -<PRE>  my $r = shift;  # or $r = Apache-&gt;request
  -  my %params = $r-&gt;method eq 'POST' ? $r-&gt;content : $r-&gt;args;
  -</PRE>
  -<P><A NAME="anchor114"></A>
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  my $r = shift;  # or $r = Apache-&gt;request
  +  my %params = $r-&gt;method eq 'POST' ? $r-&gt;content : $r-&gt;args;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Also take a look at <CODE>Apache::Request</CODE> which has the same API for extracting and setting parameters.
   
  -<P><A NAME="anchor115"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H1><A NAME="Subclassing_Apache_Request">Subclassing Apache::Request</A></H1></CENTER>
  -<P><A NAME="anchor116"></A>
  +<P>
   To subclass a package you simply modify @ISA, for example:
   
  -<P><A NAME="anchor117"></A>
  -<PRE>  package My::TestAPR;
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  package My::TestAPR;
       
     use strict;
     use vars qw/@ISA/;
  @@ -822,18 +1247,22 @@
           $sum;
     }
     1;
  -  __END__
  -</PRE>
  -<P><A NAME="anchor118"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +  __END__</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H1><A NAME="Sending_Email_from_mod_perl">Sending Email from mod_perl</A></H1></CENTER>
  -<P><A NAME="anchor119"></A>
  +<P>
   There is nothing special about sending email from mod_perl, it's just that
   we do it a lot. There are a few important issues. The most widely used
   approach is starting a <CODE>sendmail</CODE> process and piping the headers and the body to it. The problem is that 
   <CODE>sendmail</CODE> is a very heavy process and it makes mod_perl processes less efficient.
   
  -<P><A NAME="anchor120"></A>
  +<P>
   If you don't want your process to wait until delivery is complete, you can
   tell <CODE>sendmail</CODE> not to deliver the email straight away, but either do it in the background
   or just queue the job until the next queue run. This can significantly
  @@ -842,29 +1271,38 @@
   
   <UL>
   <P><LI>
  -<P><A NAME="anchor121"></A>
  +<P>
   <CODE>-odb</CODE> (deliver in the background)
   
   <P><LI>
  -<P><A NAME="anchor122"></A>
  +<P>
   <CODE>-odq</CODE> (queue-only) or
   
   <P><LI>
  -<P><A NAME="anchor123"></A>
  +<P>
   <CODE>-odd</CODE> (queue, and also defer the DNS/NIS lookups).
   
   </UL>
  -<P><A NAME="anchor124"></A>
  +<P>
   Some people prefer using lighter mail delivery programs like
   <CODE>qmail</CODE>.
   
  -<P><A NAME="anchor125"></A>
  +<P>
   The most efficient approach is to talk directly to the SMTP server. Luckily <CODE>Net::SMTP</CODE> modules makes this very easy. The only problem is when &lt;Net::SMTP&gt; fails to deliver the mail, because the destination peer
   server is temporarily down. But from the other side <CODE>Net::SMTP</CODE> allows you to send email much much faster, since you don't have to invoke a
   dedicated process. Here is an example of a subroutine that sends email.
  +
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
   
  -<P><A NAME="anchor126"></A>
  -<PRE>  use Net::SMTP ();
  +	<td>
  +	  <pre>  use Net::SMTP ();
     use Carp qw(carp verbose);
     
     #
  @@ -874,10 +1312,22 @@
     # Alternatively you can hardcode it here, look for $smtp_server below 
     #
     sub send_mail{
  -    my ($from, $to, $subject, $body) = @_;
  -</PRE>
  -<P><A NAME="anchor127"></A>
  -<PRE>    carp &quot;From missing&quot; unless defined $from ; # Prefer to exit early if errors
  +    my ($from, $to, $subject, $body) = @_;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>    carp &quot;From missing&quot; unless defined $from ; # Prefer to exit early if errors
       carp &quot;To missing&quot;   unless defined $to ;
     
       my $mail_message = &lt;&lt;__END_OF_MAIL__;
  @@ -907,16 +1357,29 @@
     
       $smtp-&gt;quit or carp (&quot;Failed to quit\n&quot;);
     
  -  } #  end of sub send_mail
  -</PRE>
  -<P><A NAME="anchor128"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +  } #  end of sub send_mail</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H1><A NAME="A_Simple_Handler_To_Print_The_En">A Simple Handler To Print The Environment Variables</A></H1></CENTER>
  -<P><A NAME="anchor129"></A>
  +<P>
   The code:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor130"></A>
  -<PRE>  package MyEnv;
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  package MyEnv;
     use Apache;
     use Apache::Constants;
     sub handler{ 
  @@ -925,37 +1388,74 @@
       print map {&quot;$_ =&gt; $ENV{$_}\n&quot;} keys %ENV;
       return OK;
     }
  -  1;
  -</PRE>
  -<P><A NAME="anchor131"></A>
  +  1;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   The configuration:
  +
  +<P>
   
  -<P><A NAME="anchor132"></A>
  -<PRE>  PerlModule MyEnv
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  PerlModule MyEnv
     &lt;Location /env&gt;
       SetHandler perl-script
       PerlHandler MyEnv
  -  &lt;/Location&gt;
  -</PRE>
  -<P><A NAME="anchor133"></A>
  +  &lt;/Location&gt;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   The invocation:
  +
  +<P>
   
  -<P><A NAME="anchor134"></A>
  -<PRE>  <A HREF="http://localhost/env">http://localhost/env</A>
  -</PRE>
  -<P><A NAME="anchor135"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  <A HREF="http://localhost/env">http://localhost/env</A></pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H1><A NAME="mod_rewrite_Based_On_Query_Strin">mod_rewrite Based On Query String and URI Implemented in Perl</A></H1></CENTER>
  -<P><A NAME="anchor136"></A>
  +<P>
   The task: we need to perform a redirect based on the query string and the
   logical path (URI).
   
  -<P><A NAME="anchor137"></A>
  +<P>
   The solution: we write a PerlTransHandler that does what mod_rewrite does.
   You can get the query string from <CODE>$r-&gt;args</CODE> and send redirect headers.
  +
  +<P>
   
  -<P><A NAME="anchor138"></A>
  -<PRE>  package Apache::Redirect::Based::On::Query::String::Plus::URI;
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  package Apache::Redirect::Based::On::Query::String::Plus::URI;
     use Apache::Constants 'OK','REDIRECT';
     use constant DEFAULT_URI =&gt; '<A HREF="http://www.boston.com">http://www.boston.com</A>'; # shameless plug!
     
  @@ -973,29 +1473,66 @@
       $r-&gt;send_http_header;
     
       return OK;
  -  }
  -</PRE>
  -<P><A NAME="anchor139"></A>
  +  }</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Set it up in <EM>httpd.conf</EM> as:
  +
  +<P>
   
  -<P><A NAME="anchor140"></A>
  -<PRE>  PerlTransHandler Apache::Redirect::Based::On::Query::String::Plus::URI
  -</PRE>
  -<P><A NAME="anchor141"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  PerlTransHandler Apache::Redirect::Based::On::Query::String::Plus::URI</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H1><A NAME="PerlTransHandler_example">PerlTransHandler example</A></H1></CENTER>
  -<P><A NAME="anchor142"></A>
  +<P>
   Suppose that before a content handler is invoked you want make this
   translation:
  +
  +<P>
   
  -<P><A NAME="anchor143"></A>
  -<PRE>  /articles/10/index.html  =&gt;  /articles/index.html?id=10
  -</PRE>
  -<P><A NAME="anchor144"></A>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  /articles/10/index.html  =&gt;  /articles/index.html?id=10</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   This <EM>TransHandler</EM> will do that for you:
  +
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
   
  -<P><A NAME="anchor145"></A>
  -<PRE>  My/Trans.pm
  +	<td>
  +	  <pre>  My/Trans.pm
     -----------
     package My::Trans;
     use Apache::Constants qw(:common);
  @@ -1007,74 +1544,164 @@
       $r-&gt;args(&quot;id=$id&quot;);
       return DECLINED;
     }
  -  1;
  -</PRE>
  -<P><A NAME="anchor146"></A>
  +  1;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   and in <EM>httpd.conf</EM>:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor147"></A>
  -<PRE>  PerlModule My::Trans 
  -  PerlTransHandler My::Trans
  -</PRE>
  -<P><A NAME="anchor148"></A>
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  PerlModule My::Trans 
  +  PerlTransHandler My::Trans</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Notice the technique to set the <EM>args</EM>. By the time the apache-request object has been created, args are handled
   in a separate slot, so you cannot just push them into the original URI.
   
  -<P><A NAME="anchor149"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +Also notice that the handler returns <CODE>DECLINED</CODE> so the default Apache transhandler will take care of URI to filename
  +remapping.
  +
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H1><A NAME="Setting_PerlHandler_Based_on_MIM">Setting PerlHandler Based on MIME Type</A></H1></CENTER>
  -<P><A NAME="anchor150"></A>
  +<P>
   Q: Is there a way to set a PerlHandler for a specific MIME type? Something
   like <EM>"PerlTypeHandler text/html HTML::Template"</EM>? (One can use a <CODE>&lt;Files&gt;</CODE> section. Not quite as slick, and that mucks up
   <CODE>$r-&gt;location</CODE>.)
   
  -<P><A NAME="anchor151"></A>
  +<P>
   A: There's no built-in configuration directive like that, though you could
   do magic with directive handlers. Otherwise, something like this should
   work:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor152"></A>
  -<PRE>  package My::MimeTypeDispatch;
  -</PRE>
  -<P><A NAME="anchor153"></A>
  -<PRE>  my %mime_types = (
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  package My::MimeTypeDispatch;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  my %mime_types = (
       'text/html' =&gt; \&amp;HTML::Template::handler,
  -  );
  -</PRE>
  -<P><A NAME="anchor154"></A>
  -<PRE>  sub handler {
  +  );</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  sub handler {
       my $r = shift;
       if (my $h = $mime_types{$r-&gt;content_type}) {
         $r-&gt;push_handlers(PerlHandler =&gt; $h);
         $r-&gt;handler('perl-script');
       }
     }
  -  __END__
  -</PRE>
  -<P><A NAME="anchor155"></A>
  +  __END__</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   And in <EM>httpd.conf</EM>:
  +
  +<P>
   
  -<P><A NAME="anchor156"></A>
  -<PRE>  PerlFixupHandler My::MimeTypeDispatch
  -</PRE>
  -<P><A NAME="anchor157"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  PerlFixupHandler My::MimeTypeDispatch</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H1><A NAME="SSI_and_Embperl_Doing_Both">SSI and Embperl -- Doing Both</A></H1></CENTER>
  -<P><A NAME="anchor158"></A>
  +<P>
   This handler lets you use both SSI and Embperl in the same request:
   
  -<P><A NAME="anchor159"></A>
  +<P>
   Use it in a <CODE>&lt;FilesMatch&gt;</CODE> Section or similar:
  +
  +<P>
   
  -<P><A NAME="anchor160"></A>
  -<PRE>  PerlModule Apache::EmbperlFilter Apache::SSI
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  PerlModule Apache::EmbperlFilter Apache::SSI
     &lt;FilesMatch &quot;\.epl&quot;&gt;
        PerlSetVar Filter On
        PerlHandler Apache::EmbperlFilter Apache::SSI
  -  &lt;/FilesMatch&gt;
  -</PRE>
  -<P><A NAME="anchor161"></A>
  -<PRE>  package Apache::EmbperlFilter;
  +  &lt;/FilesMatch&gt;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  package Apache::EmbperlFilter;
     
     use Apache::Util qw(parsedate);
     use HTML::Embperl;
  @@ -1116,60 +1743,99 @@
     }
     
     1;
  -  __END__
  -</PRE>
  -<P><A NAME="anchor162"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +  __END__</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H1><A NAME="Getting_the_Front_end_Server_s_N">Getting the Front-end Server's Name in the Back-end Server</A></H1></CENTER>
  -<P><A NAME="anchor163"></A>
  +<P>
   Assume that you have more than one front-end server, and you want to
   dynamically figure out the front-end server name in the back-end server.
   mod_proxy and mod_rewrite provide the solution.
   
  -<P><A NAME="anchor164"></A>
  +<P>
   Compile apache with both mod_proxy and mod_rewrite, then use a directive
   something like this
  +
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
   
  -<P><A NAME="anchor165"></A>
  -<PRE>  RewriteEngine On
  +	<td>
  +	  <pre>  RewriteEngine On
     RewriteLog /somewhere/rewrite.log
     RewriteLogLevel 3
     RewriteRule ^/foo/bar(.*)$ \
  -  <A HREF="http://example.com:8080/foo/bar/">http://example.com:8080/foo/bar/</A>$1?IP=%{REMOTE_HOST} [QSA,P]
  -</PRE>
  -<P><A NAME="anchor166"></A>
  +  <A HREF="http://example.com:8080/foo/bar/">http://example.com:8080/foo/bar/</A>$1?IP=%{REMOTE_HOST} [QSA,P]</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   This will have all the urls starting with <EM>/some/url</EM> proxied off to the other server at the same url. It will append the <CODE>REMOTE_HOST</CODE>
   header as a query string arguement. (QSA = Query String Append, P = Proxy).
   There is probably a way to remap it as an X-Header of some sort, but if
   query string is good enough for you, then this should work really nicely.
   
  -<P><A NAME="anchor167"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H1><A NAME="Authentication_Snippets">Authentication Snippets</A></H1></CENTER>
  -<P><A NAME="anchor168"></A>
  +<P>
   Getting the authenticated username: <CODE>$r-&gt;connection-&gt;user()</CODE>, or
   <CODE>$ENV{REMOTE_USER}</CODE> if you're in a CGI emulation.
   
  -<P><A NAME="anchor169"></A>
  +<P>
   Example:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor170"></A>
  -<PRE>  my $r = shift;
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  my $r = shift;
     
     my ($res, $sent_pwd) = $r-&gt;get_basic_auth_pw;
     return $res if $res; #decline if not Basic
     
  -  my $user = $r-&gt;connection-&gt;user;
  -</PRE>
  -<P><A NAME="anchor171"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +  my $user = $r-&gt;connection-&gt;user;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H1><A NAME="Using_DESTROY_to_Finalize_Output">Using DESTROY to Finalize Output</A></H1></CENTER>
  -<P><A NAME="anchor172"></A>
  +<P>
   Well, as always with Perl -- TMTOWTDI (There's More Than One Way To Do It),
   one of the readers is using <CODE>DESTROY</CODE> to finalize output, and as a cheap means of buffering.
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor173"></A>
  -<PRE>  package buffer;
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  package buffer;
     use Apache;
     
     sub new {
  @@ -1194,38 +1860,74 @@
           $self-&gt;{apr}-&gt;send_http_header;
           $self-&gt;{apr}-&gt;print($self-&gt;{message});
     }
  -  1;
  -</PRE>
  -<P><A NAME="anchor174"></A>
  +  1;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Now you can have perl scripts like:
  +
  +<P>
   
  -<P><A NAME="anchor175"></A>
  -<PRE>  use buffer;
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  use buffer;
     my $b = new buffer(shift);
     
     $b-&gt;message(p(&quot;Hello World&quot;));
  -  # end
  -</PRE>
  -<P><A NAME="anchor176"></A>
  +  # end</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   and save a bunch of duplicate code across otherwise inconvenient gaggles of
   small scripts.
   
  -<P><A NAME="anchor177"></A>
  +<P>
   But suppose you also want to redirect the client under some circumstances,
   and send the HTTP status code 302. You might try this:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor178"></A>
  -<PRE>  sub redir {
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  sub redir {
           my $self = shift;
           $self-&gt;{redirect} = shift;
           exit;
  -  }
  -</PRE>
  -<P><A NAME="anchor179"></A>
  +  }</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   and re-code <CODE>DESTROY</CODE> as:
  +
  +<P>
   
  -<P><A NAME="anchor180"></A>
  -<PRE>  sub DESTROY {
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  sub DESTROY {
           my $self = shift;
           if ($self-&gt;{redirect}) {
                   $self-&gt;{apr}-&gt;status{REDIRECT};
  @@ -1236,21 +1938,33 @@
                   $self-&gt;{apr}-&gt;send_http_header;
                   $self-&gt;{apr}-&gt;print($self-&gt;{message});
           }
  -  }
  -</PRE>
  -<P><A NAME="anchor181"></A>
  +  }</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   But you'll find that while the browser redirects itself, mod_perl logs the
   result code as 200. It turns out that <CODE>status()</CODE> only touches
   the Apache response, and the log message is determined by the Apache return
   code.
   
  -<P><A NAME="anchor182"></A>
  +<P>
   Aha! So we'll change the <CODE>exit()</CODE> in <CODE>redir()</CODE> to
   <CODE>exit(REDIRECT).</CODE> This fixes the log code, but causes a bogus <EM>"[error] 302"</EM> line in the
   <EM>error_log</EM>. That comes from <CODE>Apache::Registry</CODE>:
  +
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
   
  -<P><A NAME="anchor183"></A>
  -<PRE>  my $errsv = &quot;&quot;;
  +	<td>
  +	  <pre>  my $errsv = &quot;&quot;;
     if($@) {
         $errsv = $@;
         $@ = ''; #XXX fix me, if we don't do this Apache::exit() breaks
  @@ -1261,35 +1975,59 @@
         $r-&gt;log_error($errsv);
         return SERVER_ERROR unless $Debug &amp;&amp; $Debug &amp; 2;
         return Apache::Debug::dump($r, SERVER_ERROR);
  -  }
  -</PRE>
  -<P><A NAME="anchor184"></A>
  +  }</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   So you see that any time the return code causes <CODE>$@</CODE> to return true, we'll get an error line. Not wanting this, what can we do?
   
  -<P><A NAME="anchor185"></A>
  +<P>
   We can hope that a future version of mod_perl will allow us to set the HTTP
   result code independent from the handler return code (perhaps a
   <CODE>log_status()</CODE> method? or at least an <CODE>Apache::LOG_HANDLER_RESULT</CODE>
   config variable?).
   
  -<P><A NAME="anchor186"></A>
  +<P>
   In the meantime, there's
   <A HREF="././modules.html#Apache_RedirectLogFix">Apache::RedirectLogFix</A>.
  +
  +<P>
  +Put this in your <EM>httpd.conf</EM>
  +
  +
   
  -<P><A NAME="anchor187"></A>
  -Put this in your <EM>httpd.conf</EM> 
  +<P>
   
  - 
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor188"></A>
  -<PRE>  PerlLogHandler Apache::RedirectLogFix
  -</PRE>
  -<P><A NAME="anchor189"></A>
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  PerlLogHandler Apache::RedirectLogFix</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   and take a look at the source code below. Note that it requires us to
   return the HTTP status code 200.
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor190"></A>
  -<PRE>  package Apache::RedirectLogFix;
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  package Apache::RedirectLogFix;
     
     use Apache::Constants qw(OK DECLINED REDIRECT);
     
  @@ -1306,34 +2044,110 @@
        return DECLINED;
     }
     
  -  1;
  -</PRE>
  -<P><A NAME="anchor191"></A>
  +  1;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Now, if we wanted to do the same sort of thing for an error 500 handler, we
   could write another <CODE>PerlLogHandler</CODE> (call it
   <CODE>ServerErrorLogFix</CODE>). But we'll leave that as an exercise for the reader, and hope that it
   won't be needed in the next mod_perl release. After all, it's a little
   awkward to need a <CODE>LogHandler</CODE> to clean up after ourselves....
  +
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
  +<CENTER><H1><A NAME="Setting_Environment_Variables_Fo">Setting Environment Variables For Scripts Called From CGI.</A></H1></CENTER>
  +<P>
  +Perl uses <CODE>sh()</CODE> for its <CODE>system()</CODE> and <CODE>open()</CODE> calls. So if you want to set a temporary variable when you call a script
  +from your CGI you do something like this:
  +
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre> open UTIL, &quot;USER=stas ; script.pl | &quot; or die &quot;...: $!\n&quot;;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +or
  +
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  system &quot;USER=stas ; script.pl&quot;;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +This is useful, for example, if you need to invoke a script that uses
  +CGI.pm from within a mod_perl script. We are tricking the Perl script into
  +thinking it's a simple CGI, which is not running under mod_perl.
  +
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  open(PUBLISH, &quot;GATEWAY_INTERFACE=CGI/1.1 ; script.cgi
  +       \&quot;param1=value1&amp;param2=value2\&quot; |&quot;) or die &quot;...: $!\n&quot;;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +Make sure that the parameters you pass are shell safe -- all ``unsafe''
  +characters like single-quote and back-tick should be properly escaped.
  +
  +<P>
  +Unfortunately mod_perl uses <CODE>fork()</CODE> to run the script, so you
  +have probably thrown out the window most of the performance gained from
  +using mod_perl. To avoid the fork, change script.cgi to a module containing
  +a subroutine which you can then call directly from your mod_perl script.
   
  -<P><A NAME="anchor192"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H1><A NAME="Mysql_Backup_and_Restore_Scripts">Mysql Backup and Restore Scripts</A></H1></CENTER>
  -<P><A NAME="anchor193"></A>
  +<P>
   This is somewhat off-topic, but since many of us use mysql or some other
   RDBMS in their work with mod_perl driven sites, it's good to know how to
   backup and restore the databases in case of database corruption.
   
  -<P><A NAME="anchor194"></A>
  +<P>
   First we should tell mysql to log all the clauses that modify the databases
   (we don't care about SELECT queries for database backups). Modify the <CODE>safe_mysql</CODE> script by adding the
   <EM>--log-update</EM> options to the <CODE>mysql</CODE> server startup parameters and restart the server. From now on all the
   non-select queries will be logged to the <EM>/var/lib/mysql/www.bar.com</EM> logfile. Your hostname will show up instead of <EM>www.bar.com</EM>.
   
  -<P><A NAME="anchor195"></A>
  +<P>
   Now create a <EM>dump</EM> directory under <EM>/var/lib/mysql/</EM>. That's where the backups will be stored (you can name the directory as
   you wish of course).
   
  -<P><A NAME="anchor196"></A>
  +<P>
   Prepare the backup script and store it in a file, e.g:
   <EM>/usr/local/sbin/mysql/mysql.backup.pl</EM>
   
  @@ -1352,16 +2166,28 @@
   You might need to change the executable paths according to your system.
   List the names of the databases you want to backup using the <CODE>db_names</CODE> array.
   
  -<P><A NAME="anchor197"></A>
  +<P>
   Now make the script executable and arrange the crontab entry to run the
   backup script nightly. Note that the disk space used by the backups will
   grow without bound and you should remove the old backups. Here is a sample
   crontab entry to run the script at 4am every day:
  +
  +<P>
   
  -<P><A NAME="anchor198"></A>
  -<PRE>  0 4 * * * /usr/local/sbin/mysql/mysql.backup.pl &gt; /dev/null 2&gt;&amp;1
  -</PRE>
  -<P><A NAME="anchor199"></A>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  0 4 * * * /usr/local/sbin/mysql/mysql.backup.pl &gt; /dev/null 2&gt;&amp;1</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   So now at any moment we have the dump of the databases from the last
   execution of the backup script and the log file of all the clauses that
   have updated the databases since then. If the database gets corrupted we
  @@ -1383,58 +2209,84 @@
   These are kinda dirty scripts, but they work... if you come up with cleaner
   scripts, please contribute them... thanks
   
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -	     The <a href="http://www.modperl.com/">
  -	     <B>Writing Apache Modules with Perl and C</B></a>
  -	     book can be purchased online from <a
  -	     href="http://www.ora.com/catalog/wrapmod/">O'Reilly </a>
  -	     and <a
  -	     href="http://www.amazon.com/exec/obidos/ASIN/156592567X/writinapachemodu">
  -	     Amazon.com</a>.
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   
  -	     <HR>
   
  -	     <B>Your corrections of either technical or grammatical
  +    <p>
  +    <div class="navbar">
  +      <a href="modules.html">Prev</a>                                 |
  +      <A HREF="index.html"         >Contents</A> |
  +      <A HREF="index.html#search"  >Search</A>   |
  +      <A HREF="index.html#download">Download</A> |
  +      <a href="hardware.html">Next</a>
  +    </div>
  +    <p>
  +
  +    <table width="60%" align="center">
  +
  +      <tr>
  +	<td>
  +	  <div class="notice">
  +	  <B>Your corrections of the technical and grammatical
   	     errors are very welcome. You are encouraged to help me
  -	     to improve this guide.  If you have something to
  -	     contribute please <A
  -	     HREF="help.html#Contacting_me"> send it
  +	     improve this guide.  If you have something to contribute
  +	     please <A HREF="help.html#Contacting_me"> send it
   	     directly to me</A>.</B>
  +	  </div>
  +	</td>
  +      </tr>
  +
  +      <tr>
  +	<td>
  +	  <div class="ad">
  +	    The <a href="http://www.modperl.com/">
  +	      <B>Writing Apache Modules with Perl and C</B></a>
  +	    book can be purchased online from <a
  +	      href="http://www.ora.com/catalog/wrapmod/">O'Reilly </a>
  +	    and <a
  +	    href="http://www.amazon.com/exec/obidos/ASIN/156592567X/writinapachemodu">
  +	      Amazon.com</a>.
  +	  </div>
  +	</td>
  +      </tr>
  +
  +</table>
  +
  +<center>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
  +<table cellspacing=2 cellpadding=2>
  +
  +<tr align=center valign=top>
  +<td align=center valign=center>
  +
  +<b><font size=-1>Written by <a
  +href="help.html#Contacting_me">Stas Bekman</a>.<br> Last Modified at 05/27/2000
  +</font></b>
  +<br>
  +
  +</td>
  +
  +<td>
  +
  +<a href="http://perl.apache.org"><img src="images/mod_perl2.jpg"  border=0 alt="mod_perl icon" border=0 height=59 width=150></a>
  +<br>
  +
  +</td>
  +
  +<td>
  +
  +<font size=-2>Use of the Camel for Perl is <br>
  +a trademark of <a href="http://www.ora.com">O'Reilly &amp; Associates</a>,<br>
  +and is used by permission. </font> 
  +<br>
   
  -	     <HR>
  +</td>
   
  -	     [    <A HREF="modules.html">Prev</A> |      <A HREF="index.html">Main Page</A> | <A HREF="hardware.html">Next</A>      ]
  +</tr>
  +</table>
  +</center>
   
  -<CENTER><TABLE CELLSPACING=2 CELLPADDING=2 WIDTH="100%" >
  -<TR ALIGN=CENTER VALIGN=TOP>
  -  <TD ALIGN=CENTER VALIGN=CENTER COLSPAN="3">
  -	     <HR>
  -  </TD>
  -</TR>
  -<TR ALIGN=CENTER VALIGN=TOP>
  -  <TD ALIGN=CENTER VALIGN=CENTER>
  -    <B>
  -      <FONT SIZE=-1>
  -	     Written by <A HREF="help.html#Contacting_me">Stas Bekman</A>.
  -	     <BR>Last Modified at 05/12/2000
  -      </FONT>
  -    </B>
  -  </TD>
  -
  -  <TD>
  -	     <A HREF="http://perl.apache.org"><IMG SRC="images/mod_perl2.jpg" ALT="Mod Perl Icon" BORDER=0 HEIGHT=59 WIDTH=150></A>
  -  </TD>
  -
  -  <TD>
  -    <FONT SIZE=-2>
  -	     Use of the Camel for Perl is <BR>
  -	     a trademark of <A HREF="http://www.ora.com">O'Reilly &amp; Associates</A>,<BR>
  -             and is used by permission. 
  -    </FONT> 
  -  </TD>
  -</TR>
  -</TABLE></CENTER>
  -
  -</BODY>
  -</HTML>
  -	    
  \ No newline at end of file
  +</body>
  +</html>
  
  
  
  1.22      +166 -121  modperl-site/guide/start.html
  
  Index: start.html
  ===================================================================
  RCS file: /home/cvs/modperl-site/guide/start.html,v
  retrieving revision 1.21
  retrieving revision 1.22
  diff -u -r1.21 -r1.22
  --- start.html	2000/05/12 22:42:55	1.21
  +++ start.html	2000/06/07 22:45:37	1.22
  @@ -1,88 +1,112 @@
   <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
  -<HTML>
  -<HEAD>
  -   <TITLE>mod_perl guide: Guide's Overview</TITLE>
  -   <META NAME="GENERATOR" CONTENT="Pod2HTML [Perl/Linux]">
  -   <META NAME="Author" CONTENT="Stas Bekman">
  -   <META NAME="Description" CONTENT="All Apache/Perl related information: Hints, Guidelines, Scenarios and Troubleshottings">
  -   <META NAME="keywords" CONTENT="mod_perl modperl perl apache cgi webserver speed  fast guide mod_perl apache guide help info faq mod_perl installation cgi troubleshooting help no sex speedup free open source OSS mod_perl apache guide">
  -</HEAD>
  -     <LINK REL=STYLESHEET TYPE="text/css"
  -        HREF="style.css" TITLE="refstyle">
  -     <style type="text/css">
  -     <!-- 
  -        @import url(style.css);
  -     -->
  -     
  -     </style>
  -<BODY BGCOLOR="white">
  +<html>
  +  <head>
  +   <title>mod_perl guide: Guide's Overview</title>
  +   <meta name="Author" content="Stas Bekman">
  +   <meta name="Description" content="All Apache/Perl related information: Hints, Guidelines, Scenarios and Troubleshottings">
  +   <meta name="keywords" content="mod_perl modperl perl cgi apache webserver speed fast guide mod_perl apache guide help info faq mod_perl installation cgi troubleshooting help no sex speedup free open source OSS mod_perl apache guide">
  +   <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
  +   <meta name="Classification" content="information">
  +   <link href="style.css" rel=stylesheet type="text/css" title="refstyle">
  +  </head>
  +  <body>
  +
  +    <h1 align=center>
  +      <a href="http://perl.apache.org"><img src="images/mod_perl.gif" alt="Mod Perl Icon" border=0 height=30 width=90 align=left></a>
  +      <a href="http://perl.apache.org"><img src="images/mod_perl.gif" alt="Mod Perl Icon" border=0 height=30 width=90 align=right></a>
  +      Guide's Overview
  +    </h1>
  +    <hr>
  +    <p>
  +    <div class="navbar">
  +      <a href="intro.html">Prev</a>                                 |
  +      <a href="index.html"         >Contents</a> |
  +      <a href="index.html#search"  >Search</a>   |
  +      <a href="index.html#download">Download</a> |
  +      <a href="perl.html">Next</a>
  +    </div>
  +    <p>
  +
  +    <div class="toc">
  +      
   <A NAME="toc"></A>
  -<H1 ALIGN=CENTER>
  -<A HREF="http://perl.apache.org"><IMG SRC="images/mod_perl.gif" ALT="Mod Perl Icon" BORDER=0 HEIGHT=30 WIDTH=90 ALIGN=LEFT></A>
  -<A HREF="http://perl.apache.org"><IMG SRC="images/mod_perl.gif" ALT="Mod Perl Icon" BORDER=0 HEIGHT=30 WIDTH=90 ALIGN=RIGHT></A>
  -Guide's Overview</H1>
  -<HR WIDTH="100%">
  -	    [    <A HREF="intro.html">Prev</A> |      <A HREF="index.html">Main Page</A> | <A HREF="perl.html">Next</A>      ]<HR><!-- INDEX BEGIN -->
  -<P><B><FONT SIZE=-1>Table of Contents:</FONT></B></P>
  +<P><B>Table of Contents:</B></P>
  +
   <UL>
   
   	<LI><A HREF="#What_s_inside_">What's inside?</A>
   </UL>
  -<!-- INDEX END -->
   
  +    </div>
  +
  +    [ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
   <HR>
  +    <table width="60%" align="center">
  +
  +      <tr>
  +	<td>
  +	  <div class="ad">
  +	    The <a href="http://www.modperl.com/">
  +	      <B>Writing Apache Modules with Perl and C</B></a>
  +	    book can be purchased online from <a
  +	      href="http://www.ora.com/catalog/wrapmod/">O'Reilly </a>
  +	    and <a
  +	    href="http://www.amazon.com/exec/obidos/ASIN/156592567X/writinapachemodu">
  +	      Amazon.com</a>.
  +	  </div>
  +	</td>
  +      </tr>
  +
  +      <tr>
  +	<td>
  +	  <div class="notice">
  +	  <B>Your corrections of the technical and grammatical
  +	     errors are very welcome. You are encouraged to help me
  +	     improve this guide.  If you have something to contribute
  +	     please <A HREF="help.html#Contacting_me"> send it
  +	     directly to me</A>.</B>
  +	  </div>
  +	</td>
  +      </tr>
   
  -	     The <a href="http://www.modperl.com/">
  -	     <B>Writing Apache Modules with Perl and C</B></a>
  -	     book can be purchased online from <a
  -	     href="http://www.ora.com/catalog/wrapmod/">O'Reilly </a>
  -	     and <a
  -	     href="http://www.amazon.com/exec/obidos/ASIN/156592567X/writinapachemodu">
  -	     Amazon.com</a>.
  -
  -	     <HR>
  -
  -	       <B>Your corrections of either technical or grammatical
  -	       errors are very welcome. You are encouraged to help me
  -	       to improve this guide.  If you have something to
  -	       contribute please <A
  -	       HREF="help.html#Contacting_me"> send it
  -	       directly to me</A>.
  -	       </B>
  -	       <HR>
  +</table>
   
  -	      <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<P><A NAME="anchor0"></A>
  +    
  +
  +	    [ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
  +
  +<P>
   <CENTER><H1><A NAME="What_s_inside_">What's inside?</A></H1></CENTER>
  -<P><A NAME="anchor1"></A>
  +<P>
   Before you start with mod_perl installation, you should have an overall
   picture of this wonderful technology. There is more than one way to use a
   mod_perl-enabled webserver. You have to decide what mod_perl scheme you
   want to use. <A HREF="././strategy.html#">Picking the Right Strategy</A> chapter presents various approaches and discusses their pros and cons.
   
  -<P><A NAME="anchor2"></A>
  +<P>
   Once you know what fits your requirements the best, you should proceed to <A HREF="././scenario.html#">Real World Scenarios Implementation</A>. This chapter provides very detailed scenarios of the schemes discussed in
   the
   <A HREF="././strategy.html#">Picking the Right Strategy</A> chapter.
   
  -<P><A NAME="anchor3"></A>
  +<P>
   The <A HREF="././install.html#">Server Installation</A> chapter follows on to the <A HREF="././scenario.html#">Real World Scenarios Implementaion</A> chapter by providing more in-depth installation details.
   
  -<P><A NAME="anchor4"></A>
  +<P>
   The <A HREF="././config.html#">Server Configuration</A> chapter adds to the basic configurations presented in the <A HREF="././scenario.html#">Real World Scenarios Implementaion</A> chapter with extended configurations and various configuration examples.
   
  -<P><A NAME="anchor5"></A>
  +<P>
   The <A HREF="././frequent.html#">Frequent mod_perl problems</A> chapter just collects links to other chapters. It is an attempt to stress
   some of the most frequently encountered mod_perl problems. So this is the
   first place you should check if you have got a problem.
   
  -<P><A NAME="anchor6"></A>
  +<P>
   Probably the most important chapter is <A HREF="././porting.html#">CGI to mod_perl Porting. mod_perl Coding guidelines</A>. It explains the differences between scripts running under mod_cgi and
   mod_perl, and what should be done in order to make existing scripts run
   under mod_perl. Along with the porting notes it provides guidelines for
   proper mod_perl programming.
   
  -<P><A NAME="anchor7"></A>
  +<P>
   <A HREF="././performance.html#">Performance. Benchmarks</A> is the biggest and a very important chapter. It explains the details of
   tuning mod_perl and the scripts running under it, so you can squeeze every
   ounce of the power from your server. A large part of the chapter is
  @@ -93,29 +117,24 @@
   is a very hard task, and demands a lot of understanding and experience. But
   once you acquire this knowledge you can make magic with your server.
   
  -<P><A NAME="anchor8"></A>
  -The <A HREF="././obvious.html#">Things obvious to others, but not to you</A> chapter is exactly what it claims to be. Some people have been in this
  -business too long, and many things have become too obvious to them. This is
  -not true for a newbie, so this chapter talks about such things.
  -
  -<P><A NAME="anchor9"></A>
  +<P>
   While developing your mod_perl applications, you will begin to understand
   that an <CODE>error_log</CODE> file is your best friend. It tells you all the intimate details of what is
   happening to your scripts. But the problem is that it speaks a secret
   language. To learn the alphabet and the grammar of this language, refer to
   the chapter <A HREF="././troubleshooting.html#">Warnings and Errors: Where and Why</A>.
   
  -<P><A NAME="anchor10"></A>
  +<P>
   <A HREF="././security.html#">Protecting Your Site</A> - All about security.
   
  -<P><A NAME="anchor11"></A>
  +<P>
   If you are into driving relational databases with your cgi scripts, the <A HREF="././databases.html#">mod_perl and Relational Databases</A> chapter will tell you all about the database-related goodies mod_perl has
   prepared for you.
   
  -<P><A NAME="anchor12"></A>
  +<P>
   If you are using good old dbm files for your databases, the <A HREF="././dbm.html#">mod_perl and dbm files</A> chapter explains how to utilize them better under mod_perl.
   
  -<P><A NAME="anchor13"></A>
  +<P>
   More and more Internet Service Providers (ISPs) are evaluating the
   possibility of providing mod_perl services to their users. Is this
   possible? Is it secure? Will it work? What resources does it take? The <A HREF="././multiuser.html#">mod_perl for ISPs. mod_perl and Virtual Hosts</A>
  @@ -124,13 +143,13 @@
   learn how to do it yourself, or maybe to persuade your ISP to provide this
   service.
   
  -<P><A NAME="anchor14"></A>
  +<P>
   If you have to administer your Apache mod_perl server the
   <A HREF="././control.html#">Controlling and Monitoring the Server</A> chapter is for you. Among the topics are: server restarting and monitoring
   techniques, preventing the server from eating up all your disk space in a
   matter of minutes, and more.
   
  -<P><A NAME="anchor15"></A>
  +<P>
   (META: fix this) The <A HREF="././config.html#">mod_perl Status. Peeking into the Server's Perl Innards</A>
   chapter shows you the ways you can peek at what is going on in a
   mod_perl-enabled server while it is running. Like looking at the value of
  @@ -138,23 +157,23 @@
   modules were loaded and their paths, what is the value of
   <CODE>@INC</CODE>, and much more.
   
  -<P><A NAME="anchor16"></A>
  +<P>
   Every programmer needs to know how to debug her program. It is an _easy_
   task with plain Perl. Just invoke the program with the <CODE>-d</CODE>
   flag and debug it. Is it possible to do the same under mod_perl? After all
   you cannot debug every CGI script by executing it from the command line:
   some scripts will not run from the command line. The <A HREF="././debug.html#">Debugging mod_perl</A> chapter proves debugging under mod_perl is possible and real.
   
  -<P><A NAME="anchor17"></A>
  +<P>
   Sometimes browsers that interact with our servers have bugs, which cause
   big headaches for CGI developers. Preventing these bugs from happening is
   discussed in the <A HREF="././browserbugs.html#">Workarounds for some known bugs in browsers</A> chapter.
   
  -<P><A NAME="anchor18"></A>
  +<P>
   Many modules were written to extend the mod_perl's core functionality. Some
   important modules are covered in the <A HREF="././modules.html#">Apache::* modules</A> chapter.
   
  -<P><A NAME="anchor19"></A>
  +<P>
   Some folks decide to go with mod_perl, but they are missing a basic
   understanding of Perl, which is absolutely not tolerated by mod_perl. If
   you are such a person, there is nothing to be ashamed of; we all went
  @@ -162,78 +181,104 @@
   <A HREF="././perl.html#">Perl Reference</A> chapter gives some basic perl lessons, delivering the knowledge without
   which you cannot start to program mod_perl scripts.
   
  -<P><A NAME="anchor20"></A>
  +<P>
   The <A HREF="././snippets.html#">Code Snippets</A> chapter is just a collection of code snippets I have found useful while
   writing the scripts.
   
  -<P><A NAME="anchor21"></A>
  +<P>
   The <A HREF="././hardware.html#">Choosing an Operating System and Hardware</A> chapter gives you an idea on how to choose the SW and HW for the webserver.
   
  -<P><A NAME="anchor22"></A>
  +<P>
   The <A HREF="././advocacy.html#">mod_perl Advocacy</A> tries to help to make it easier to advocate mod_perl around the world.
   
  -<P><A NAME="anchor23"></A>
  +<P>
   The <A HREF="././help.html#">Getting Help and Further Learning</A> chapter refers you to other related information resources, like learning
   Perl programming and SQL, understanding security, building databases, and
   more.
   
  -<P><A NAME="anchor24"></A>
  +<P>
   <A HREF="././download.html#">Appendix A: Downloading software and documentation</A>
   includes pointers to the software that was explained and/or mentioned in
   this guide.
   
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -	     The <a href="http://www.modperl.com/">
  -	     <B>Writing Apache Modules with Perl and C</B></a>
  -	     book can be purchased online from <a
  -	     href="http://www.ora.com/catalog/wrapmod/">O'Reilly </a>
  -	     and <a
  -	     href="http://www.amazon.com/exec/obidos/ASIN/156592567X/writinapachemodu">
  -	     Amazon.com</a>.
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   
  -	     <HR>
   
  -	     <B>Your corrections of either technical or grammatical
  +    <p>
  +    <div class="navbar">
  +      <a href="intro.html">Prev</a>                                 |
  +      <A HREF="index.html"         >Contents</A> |
  +      <A HREF="index.html#search"  >Search</A>   |
  +      <A HREF="index.html#download">Download</A> |
  +      <a href="perl.html">Next</a>
  +    </div>
  +    <p>
  +
  +    <table width="60%" align="center">
  +
  +      <tr>
  +	<td>
  +	  <div class="notice">
  +	  <B>Your corrections of the technical and grammatical
   	     errors are very welcome. You are encouraged to help me
  -	     to improve this guide.  If you have something to
  -	     contribute please <A
  -	     HREF="help.html#Contacting_me"> send it
  +	     improve this guide.  If you have something to contribute
  +	     please <A HREF="help.html#Contacting_me"> send it
   	     directly to me</A>.</B>
  +	  </div>
  +	</td>
  +      </tr>
  +
  +      <tr>
  +	<td>
  +	  <div class="ad">
  +	    The <a href="http://www.modperl.com/">
  +	      <B>Writing Apache Modules with Perl and C</B></a>
  +	    book can be purchased online from <a
  +	      href="http://www.ora.com/catalog/wrapmod/">O'Reilly </a>
  +	    and <a
  +	    href="http://www.amazon.com/exec/obidos/ASIN/156592567X/writinapachemodu">
  +	      Amazon.com</a>.
  +	  </div>
  +	</td>
  +      </tr>
  +
  +</table>
  +
  +<center>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
  +<table cellspacing=2 cellpadding=2>
  +
  +<tr align=center valign=top>
  +<td align=center valign=center>
  +
  +<b><font size=-1>Written by <a
  +href="help.html#Contacting_me">Stas Bekman</a>.<br> Last Modified at 05/27/2000
  +</font></b>
  +<br>
  +
  +</td>
  +
  +<td>
  +
  +<a href="http://perl.apache.org"><img src="images/mod_perl2.jpg"  border=0 alt="mod_perl icon" border=0 height=59 width=150></a>
  +<br>
  +
  +</td>
  +
  +<td>
  +
  +<font size=-2>Use of the Camel for Perl is <br>
  +a trademark of <a href="http://www.ora.com">O'Reilly &amp; Associates</a>,<br>
  +and is used by permission. </font> 
  +<br>
   
  -	     <HR>
  +</td>
   
  -	     [    <A HREF="intro.html">Prev</A> |      <A HREF="index.html">Main Page</A> | <A HREF="perl.html">Next</A>      ]
  +</tr>
  +</table>
  +</center>
   
  -<CENTER><TABLE CELLSPACING=2 CELLPADDING=2 WIDTH="100%" >
  -<TR ALIGN=CENTER VALIGN=TOP>
  -  <TD ALIGN=CENTER VALIGN=CENTER COLSPAN="3">
  -	     <HR>
  -  </TD>
  -</TR>
  -<TR ALIGN=CENTER VALIGN=TOP>
  -  <TD ALIGN=CENTER VALIGN=CENTER>
  -    <B>
  -      <FONT SIZE=-1>
  -	     Written by <A HREF="help.html#Contacting_me">Stas Bekman</A>.
  -	     <BR>Last Modified at 02/09/2000
  -      </FONT>
  -    </B>
  -  </TD>
  -
  -  <TD>
  -	     <A HREF="http://perl.apache.org"><IMG SRC="images/mod_perl2.jpg" ALT="Mod Perl Icon" BORDER=0 HEIGHT=59 WIDTH=150></A>
  -  </TD>
  -
  -  <TD>
  -    <FONT SIZE=-2>
  -	     Use of the Camel for Perl is <BR>
  -	     a trademark of <A HREF="http://www.ora.com">O'Reilly &amp; Associates</A>,<BR>
  -             and is used by permission. 
  -    </FONT> 
  -  </TD>
  -</TR>
  -</TABLE></CENTER>
  -
  -</BODY>
  -</HTML>
  -	    
  \ No newline at end of file
  +</body>
  +</html>
  
  
  
  1.15      +751 -544  modperl-site/guide/strategy.html
  
  Index: strategy.html
  ===================================================================
  RCS file: /home/cvs/modperl-site/guide/strategy.html,v
  retrieving revision 1.14
  retrieving revision 1.15
  diff -u -r1.14 -r1.15
  --- strategy.html	2000/05/12 22:42:55	1.14
  +++ strategy.html	2000/06/07 22:45:37	1.15
  @@ -1,29 +1,37 @@
   <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
  -<HTML>
  -<HEAD>
  -   <TITLE>mod_perl guide: Choosing the Right Strategy</TITLE>
  -   <META NAME="GENERATOR" CONTENT="Pod2HTML [Perl/Linux]">
  -   <META NAME="Author" CONTENT="Stas Bekman">
  -   <META NAME="Description" CONTENT="All Apache/Perl related information: Hints, Guidelines, Scenarios and Troubleshottings">
  -   <META NAME="keywords" CONTENT="mod_perl modperl perl apache cgi webserver speed  fast guide mod_perl apache guide help info faq mod_perl installation cgi troubleshooting help no sex speedup free open source OSS mod_perl apache guide">
  -</HEAD>
  -     <LINK REL=STYLESHEET TYPE="text/css"
  -        HREF="style.css" TITLE="refstyle">
  -     <style type="text/css">
  -     <!-- 
  -        @import url(style.css);
  -     -->
  -     
  -     </style>
  -<BODY BGCOLOR="white">
  +<html>
  +  <head>
  +   <title>mod_perl guide: Choosing the Right Strategy</title>
  +   <meta name="Author" content="Stas Bekman">
  +   <meta name="Description" content="All Apache/Perl related information: Hints, Guidelines, Scenarios and Troubleshottings">
  +   <meta name="keywords" content="mod_perl modperl perl cgi apache webserver speed fast guide mod_perl apache guide help info faq mod_perl installation cgi troubleshooting help no sex speedup free open source OSS mod_perl apache guide">
  +   <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
  +   <meta name="Classification" content="information">
  +   <link href="style.css" rel=stylesheet type="text/css" title="refstyle">
  +  </head>
  +  <body>
  +
  +    <h1 align=center>
  +      <a href="http://perl.apache.org"><img src="images/mod_perl.gif" alt="Mod Perl Icon" border=0 height=30 width=90 align=left></a>
  +      <a href="http://perl.apache.org"><img src="images/mod_perl.gif" alt="Mod Perl Icon" border=0 height=30 width=90 align=right></a>
  +      Choosing the Right Strategy
  +    </h1>
  +    <hr>
  +    <p>
  +    <div class="navbar">
  +      <a href="control.html">Prev</a>                                 |
  +      <a href="index.html"         >Contents</a> |
  +      <a href="index.html#search"  >Search</a>   |
  +      <a href="index.html#download">Download</a> |
  +      <a href="scenario.html">Next</a>
  +    </div>
  +    <p>
  +
  +    <div class="toc">
  +      
   <A NAME="toc"></A>
  -<H1 ALIGN=CENTER>
  -<A HREF="http://perl.apache.org"><IMG SRC="images/mod_perl.gif" ALT="Mod Perl Icon" BORDER=0 HEIGHT=30 WIDTH=90 ALIGN=LEFT></A>
  -<A HREF="http://perl.apache.org"><IMG SRC="images/mod_perl.gif" ALT="Mod Perl Icon" BORDER=0 HEIGHT=30 WIDTH=90 ALIGN=RIGHT></A>
  -Choosing the Right Strategy</H1>
  -<HR WIDTH="100%">
  -	    [    <A HREF="control.html">Prev</A> |      <A HREF="index.html">Main Page</A> | <A HREF="scenario.html">Next</A>      ]<HR><!-- INDEX BEGIN -->
  -<P><B><FONT SIZE=-1>Table of Contents:</FONT></B></P>
  +<P><B>Table of Contents:</B></P>
  +
   <UL>
   
   	<LI><A HREF="#Do_it_like_I_do_it_">Do it like I do it!?</A>
  @@ -60,57 +68,73 @@
   	</UL>
   
   	<LI><A HREF="#Do_Not_Run_Everything_on_One_mod">Do Not Run Everything on One mod_perl Server</A>
  -	<LI><A HREF="#Do_Not_Put_mod_ssl_into_mod_perl">Do Not Put mod_ssl into mod_perl Server</A>
  +	<LI><A HREF="#Do_Not_Put_mod_ssl_into_a_mod_pe">Do Not Put mod_ssl into a mod_perl Server</A>
   	<LI><A HREF="#Pros_and_Cons_of_Building_mod_pe">Pros and Cons of Building mod_perl as DSO</A>
   </UL>
  -<!-- INDEX END -->
   
  +    </div>
  +
  +    [ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
   <HR>
  +    <table width="60%" align="center">
  +
  +      <tr>
  +	<td>
  +	  <div class="ad">
  +	    The <a href="http://www.modperl.com/">
  +	      <B>Writing Apache Modules with Perl and C</B></a>
  +	    book can be purchased online from <a
  +	      href="http://www.ora.com/catalog/wrapmod/">O'Reilly </a>
  +	    and <a
  +	    href="http://www.amazon.com/exec/obidos/ASIN/156592567X/writinapachemodu">
  +	      Amazon.com</a>.
  +	  </div>
  +	</td>
  +      </tr>
  +
  +      <tr>
  +	<td>
  +	  <div class="notice">
  +	  <B>Your corrections of the technical and grammatical
  +	     errors are very welcome. You are encouraged to help me
  +	     improve this guide.  If you have something to contribute
  +	     please <A HREF="help.html#Contacting_me"> send it
  +	     directly to me</A>.</B>
  +	  </div>
  +	</td>
  +      </tr>
  +
  +</table>
  +
  +    
   
  -	     The <a href="http://www.modperl.com/">
  -	     <B>Writing Apache Modules with Perl and C</B></a>
  -	     book can be purchased online from <a
  -	     href="http://www.ora.com/catalog/wrapmod/">O'Reilly </a>
  -	     and <a
  -	     href="http://www.amazon.com/exec/obidos/ASIN/156592567X/writinapachemodu">
  -	     Amazon.com</a>.
  -
  -	     <HR>
  -
  -	       <B>Your corrections of either technical or grammatical
  -	       errors are very welcome. You are encouraged to help me
  -	       to improve this guide.  If you have something to
  -	       contribute please <A
  -	       HREF="help.html#Contacting_me"> send it
  -	       directly to me</A>.
  -	       </B>
  -	       <HR>
  +	    [ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   
  -	      <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<P><A NAME="anchor0"></A>
  +<P>
   <CENTER><H1><A NAME="Do_it_like_I_do_it_">Do it like I do it!?</A></H1></CENTER>
  -<P><A NAME="anchor1"></A>
  -There is no such thing as the <STRONG>RIGHT</STRONG> strategy in the web server business, although there are many wrong ones.
  +<P>
  +There is no such thing as the <STRONG>right</STRONG> strategy in the web server business, although there are many wrong ones.
   Never believe a person who says: <EM>"Do it this way, this is the best!"</EM>. As the old saying goes: <EM>"Trust but verify"</EM>. There are too many technologies out there to choose from, and it would
   take an enormous investment of time and money to try to validate each one
   before deciding which is the best choice for your situation.
   
  -<P><A NAME="anchor2"></A>
  +<P>
   With this in mind, I will present some ways of using standalone mod_perl,
   and some combinations of mod_perl and other technologies. I'll describe how
  -these things work together, and offer my opinions on the pros and cons of
  -each, the relative degree of difficulty in installing and maintaining them,
  -and some hints on approaches that should be used and things to avoid.
  +these things work together, offer my opinions on the pros and cons of each,
  +the relative degree of difficulty in installing and maintaining them, and
  +some hints on approaches that should be used and things to avoid.
   
  -<P><A NAME="anchor3"></A>
  +<P>
   To be clear, I will not address all technologies and tools, but limit this
   discussion to those complementing mod_perl.
   
  -<P><A NAME="anchor4"></A>
  -Please let me stress it again: <STRONG>DO NOT</STRONG> blindly copy someone's setup and hope for a good result. Choose what is
  +<P>
  +Please let me stress it again: <STRONG>do not</STRONG> blindly copy someone's setup and hope for a good result. Choose what is
   best for your situation -- it might take <STRONG>some</STRONG> effort to find out what that is.
   
  -<P><A NAME="anchor5"></A>
  +<P>
   In this chapter we will discuss
   
   <UL>
  @@ -118,36 +142,37 @@
   <P><LI><STRONG><A NAME="item_Alternative">Alternative architectures for running one and two servers.</A></STRONG>
   <P><LI><STRONG><A NAME="item_Proxy">Proxy servers (Squid, and Apache's mod_proxy).</A></STRONG>
   </UL>
  -<P><A NAME="anchor6"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H1><A NAME="mod_perl_Deployment_Overview">mod_perl Deployment Overview</A></H1></CENTER>
  -<P><A NAME="anchor7"></A>
  +<P>
   There are several different ways to build, configure and deploy your
   mod_perl enabled server. Some of them are:
   
   <OL>
   <P><LI>
  -<P><A NAME="anchor8"></A>
  +<P>
   Having one binary and one configuration file (one big binary for mod_perl).
   
   <P><LI>
  -<P><A NAME="anchor9"></A>
  +<P>
   Having two binaries and two configuration files (one big binary for
   mod_perl and one small binary for static objects like images.)
   
   <P><LI>
  -<P><A NAME="anchor10"></A>
  +<P>
   Having one DSO-style binary and two configuration files, with mod_perl
   available as a loadable object.
   
   <P><LI>
  -<P><A NAME="anchor11"></A>
  +<P>
   Any of the above plus a reverse proxy server in http accelerator mode.
   
   </OL>
  -<P><A NAME="anchor12"></A>
  +<P>
   If you are a newbie, I would recommend that you start with the first option
  -and work on getting your feet wet with apache and mod_perl. Later, you can
  +and work on getting your feet wet with Apache and mod_perl. Later, you can
   decide whether to move to the second one which allows better tuning at the
   expense of more complicated administration, or to the third option -- the
   more state-of-the-art-yet-suspiciously-new DSO system, or to the fourth
  @@ -155,68 +180,69 @@
   
   <OL>
   <P><LI>
  -<P><A NAME="anchor13"></A>
  +<P>
   The first option will kill your production site if you serve a lot of
   static data from large (4 to 15MB) webserver processes. On the other hand,
   while testing you will have no other server interaction to mask or add to
   your errors.
   
   <P><LI>
  -<P><A NAME="anchor14"></A>
  +<P>
   This option allows you to tune the two servers individually, for maximum
   performance.
   
  -<P><A NAME="anchor15"></A>
  +<P>
   However, you need to choose between running the two servers on multiple
   ports, multiple IPs, etc., and you have the burden of administering more
   than one server. You have to deal with proxying or fancy site design to
   keep the two servers in synchronization.
   
   <P><LI>
  -<P><A NAME="anchor16"></A>
  +<P>
   With DSO, modules can be added and removed without recompiling the server,
   and their code is even shared among multiple servers.
   
  -<P><A NAME="anchor17"></A>
  +<P>
   You can compile just once and yet have more than one binary, by using
   different configuration files to load different sets of modules. The
   different Apache servers loaded in this way can run simultaneously to give
   a setup such as described in the second option above.
   
  -<P><A NAME="anchor18"></A>
  +<P>
   On the down side, you are playing at the bleeding edge.
   
  -<P><A NAME="anchor19"></A>
  +<P>
   You are dealing with a new solution that has weak documentation and is
   still subject to change. It is still somewhat platform specific. Your
   mileage may vary.
   
  -<P><A NAME="anchor20"></A>
  +<P>
   The DSO module (<CODE>mod_so</CODE>) adds size and complexity to your binaries.
   
  -<P><A NAME="anchor21"></A>
  +<P>
   Refer to the section <A HREF="././strategy.html#Pros_and_Cons_of_Building_mod_pe">"Pros and Cons of Building mod_perl as DSO</A> for more information.
   
  -<P><A NAME="anchor22"></A>
  +<P>
   Build details: <A HREF="././install.html#Build_mod_perl_as_a_DSO_inside_t">Build mod_perl as DSO inside Apache source tree via APACI</A>
   
   
   
   <P><LI>
  -<P><A NAME="anchor23"></A>
  +<P>
   The fourth option (proxy in http accelerator mode), once correctly
   configured and tuned, improves the performance of any of the above three
   options by caching and buffering page results.
   
   </OL>
  -<P><A NAME="anchor24"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H1><A NAME="Alternative_architectures_for_ru">Alternative architectures for running one and two servers</A></H1></CENTER>
  -<P><A NAME="anchor25"></A>
  +<P>
   The next part of this chapter discusses the pros and the cons of each of
   these presented configurations.  <A HREF="././scenario.html#">Real World Scenarios Implementaion</A> describes the implementation techniques of these schemes.
   
  -<P><A NAME="anchor26"></A>
  +<P>
   We will look at the following installations:
   
   <UL>
  @@ -225,48 +251,49 @@
   <P><LI><STRONG><A NAME="item_One">One light non-Apache and One mod_perl enabled Apache Servers</A></STRONG>
   <P><LI><STRONG><A NAME="item_Adding">Adding a Proxy Server in http Accelerator Mode</A></STRONG>
   </UL>
  -<P><A NAME="anchor27"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="Standalone_mod_perl_Enabled_Apac">Standalone mod_perl Enabled Apache Server</A></H2></CENTER>
  -<P><A NAME="anchor28"></A>
  +<P>
   The first approach is to implement a straightforward mod_perl server. Just
  -take your plain apache server and add mod_perl, like you add any other
  -apache module. You continue to run it at the port it was running before.
  -You probably want to try this before you proceed to more sophisticated and
  +take your plain Apache server and add mod_perl, like you add any other
  +Apache module. You continue to run it at the port it was using before. You
  +probably want to try this before you proceed to more sophisticated and
   complex techniques.
   
  -<P><A NAME="anchor29"></A>
  +<P>
   The advantages:
   
   <UL>
   <P><LI>
  -<P><A NAME="anchor30"></A>
  +<P>
   Simplicity. You just follow the installation instructions, configure it,
   restart the server and you are done.
   
   <P><LI>
  -<P><A NAME="anchor31"></A>
  +<P>
   No network changes. You do not have to worry about using additional ports
   as we will see later.
   
   <P><LI>
  -<P><A NAME="anchor32"></A>
  -Speed. You get a very fast server, you see an enormous speedup from the
  +<P>
  +Speed. You get a very fast server and you see an enormous speedup from the
   first moment you start to use it.
   
   </UL>
  -<P><A NAME="anchor33"></A>
  +<P>
   The disadvantages:
   
   <UL>
   <P><LI>
  -<P><A NAME="anchor34"></A>
  +<P>
   The process size of a mod_perl-enabled Apache server is huge (maybe 4Mb at
   startup and growing to 10Mb and more, depending on how you use it) compared
  -to the typical plain Apache. Of course if memory sharing is in place, RAM
  +to typical plain Apache. Of course if memory sharing is in place, RAM
   requirements will be smaller.
   
  -<P><A NAME="anchor35"></A>
  +<P>
   You probably have a few tens of child processes. The additional memory
   requirements add up in direct relation to the number of child processes.
   Your memory demands are growing by an order of magnitude, but this is the
  @@ -275,13 +302,13 @@
   consider the dramatic performance boost mod_perl gives to your services
   with every 100Mb of RAM you add.
   
  -<P><A NAME="anchor36"></A>
  +<P>
   While you will be happy to have these monster processes serving your
   scripts with monster speed, you should be very worried about having them
   serve static objects such as images and html files. Each static request
   served by a mod_perl-enabled server means another large process running,
   competing for system resources such as memory and CPU cycles. The real
  -overhead depends on static objects request rate. Remember that if your
  +overhead depends on the static object request rate. Remember that if your
   mod_perl code produces HTML code which includes images, each one will turn
   into another static object request. Having another plain webserver to serve
   the static objects solves this unpleasant obstacle. Having a proxy server
  @@ -289,7 +316,7 @@
   processes from this burden is another solution. We will discuss both below.
   
   <P><LI>
  -<P><A NAME="anchor37"></A>
  +<P>
   Another drawback of this approach is that when serving output to a client
   with a slow connection, the huge mod_perl-enabled server process (with all
   of its system resources) will be tied up until the response is completely
  @@ -299,187 +326,191 @@
   connection client. As in the previous drawback, a proxy solution can solve
   this problem. More on proxies later.
   
  -<P><A NAME="anchor38"></A>
  +<P>
   Proxying dynamic content is not going to help much if all the clients are
   on a fast local net (for example, if you are administering an Intranet.) On
   the contrary, it can decrease performance. Still, remember that some of
   your Intranet users might work from home through slow modem links.
   
   </UL>
  -<P><A NAME="anchor39"></A>
  +<P>
   If you are new to mod_perl, this is probably the best way to get yourself
   started.
   
  -<P><A NAME="anchor40"></A>
  +<P>
   And of course, if your site is serving only mod_perl scripts (close to zero
   static objects, like images), this might be the perfect choice for you!
   
  -<P><A NAME="anchor41"></A>
  -For implementation notes see the ``<A HREF="././scenario.html#One_Plain_and_One_mod_perl_enabl">One Plain and One mod_perl enabled Apache Servers</A>'' section in implementations chapter.
  +<P>
  +For implementation notes, see the ``<A HREF="././scenario.html#One_Plain_and_One_mod_perl_enabl">One Plain and One mod_perl enabled Apache Servers</A>'' section in the implementations chapter.
   
  -<P><A NAME="anchor42"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="One_Plain_Apache_and_One_mod_per">One Plain Apache and One mod_perl-enabled Apache Servers</A></H2></CENTER>
  -<P><A NAME="anchor43"></A>
  -As I have mentioned before, when running scripts under mod_perl, you will
  -notice that the httpd processes consume a huge amount of virtual memory,
  +<P>
  +As I have mentioned before, when running scripts under mod_perl you will
  +notice that the httpd processes consume a huge amount of virtual memory --
   from 5Mb to 15Mb and even more. That is the price you pay for the enormous
   speed improvements under mod_perl. (Again -- shared memory keeps the real
   memory that is being used much smaller :)
   
  -<P><A NAME="anchor44"></A>
  +<P>
   Using these large processes to serve static objects like images and html
   documents is overkill. A better approach is to run two servers: a very
  -light, plain apache server to serve static objects and a heavier
  -mod_perl-enabled apache server to serve requests for dynamic (generated)
  +light, plain Apache server to serve static objects and a heavier
  +mod_perl-enabled Apache server to serve requests for dynamic (generated)
   objects (aka CGI).
   
  -<P><A NAME="anchor45"></A>
  +<P>
   From here on, I will refer to these two servers as <STRONG>httpd_docs</STRONG>
  -(vanilla apache) and <STRONG>httpd_perl</STRONG> (mod_perl enabled apache).
  +(vanilla Apache) and <STRONG>httpd_perl</STRONG> (mod_perl enabled Apache).
   
  -<P><A NAME="anchor46"></A>
  +<P>
   The advantages:
   
   <UL>
   <P><LI>
  -<P><A NAME="anchor47"></A>
  +<P>
   The heavy mod_perl processes serve only dynamic requests, which allows the
   deployment of fewer of these large servers.
   
   <P><LI>
  -<P><A NAME="anchor48"></A>
  +<P>
   <CODE>MaxClients</CODE>, <CODE>MaxRequestsPerChild</CODE> and related parameters can now be optimally tuned for both <CODE>httpd_docs</CODE> and <CODE>httpd_perl</CODE> servers, something we could not do before. This allows us to fine tune the
  -memory usage and get a better server performance.
  +memory usage and get better server performance.
   
  -<P><A NAME="anchor49"></A>
  +<P>
   Now we can run many lightweight <CODE>httpd_docs</CODE> servers and just a few heavy <CODE>httpd_perl</CODE> servers.
   
   </UL>
  -<P><A NAME="anchor50"></A>
  +<P>
   An <STRONG>important</STRONG> note: When a user browses static pages and the base URL in the <STRONG>Location</STRONG> window points to the static server, for example
   <CODE>http://www.nowhere.com/index.html</CODE> -- all relative URLs (e.g. <CODE>&lt;A
  -HREF="/main/download.html"&gt;</CODE>) are being served by the light plain apache server. But this is not the
  +HREF="/main/download.html"&gt;</CODE>) are being served by the light plain Apache server. But this is not the
   case with dynamically generated pages. For example when the base URL in the <STRONG>Location</STRONG> window points to the dynamic server -- (e.g. <CODE>http://www.nowhere.com:8080/perl/index.pl</CODE>) all relative URLs in the dynamically generated HTML will be served by the
   heavy mod_perl processes. You must use fully qualified URLs and not
   relative ones!
   <CODE>http://www.nowhere.com/icons/arrow.gif</CODE> is a full URL, while
   <CODE>/icons/arrow.gif</CODE> is a relative one. Using <CODE>&lt;BASE
  -HREF="http://www.nowhere.com/"&gt;</CODE> in the generated HTML is another way to handle this problem. Also the <CODE>httpd_perl</CODE> server could rewrite the requests back to <CODE>httpd_docs</CODE> (much slower) and you still need the attention of the heavy servers. This
  +HREF="http://www.nowhere.com/"&gt;</CODE> in the generated HTML is another way to handle this problem. Also, the <CODE>httpd_perl</CODE> server could rewrite the requests back to <CODE>httpd_docs</CODE> (much slower) and you still need the attention of the heavy servers. This
   is not an issue if you hide the internal port implementations, so the
   client sees only one server running on port <CODE>80</CODE>. (See <A HREF="././config.html#Publishing_Port_Numbers_other_th">Publishing Port Numbers other than 80</A>)
   
  -<P><A NAME="anchor51"></A>
  +<P>
   The disadvantages:
   
   <UL>
   <P><LI>
  -<P><A NAME="anchor52"></A>
  +<P>
   An administration overhead.
   
   <UL>
   <P><LI>
  -<P><A NAME="anchor53"></A>
  +<P>
   The need for two different sets of configuration, log and other files. We
   need a special directory layout to manage these. While some directories can
   be shared between the two servers (like the <CODE>include</CODE>
  -directory, containing the apache include files -- assuming that both are
  +directory, containing the Apache include files -- assuming that both are
   built from the same source distribution), most of them should be separated
   and the configuration files updated to reflect the changes.
   
   <P><LI>
  -<P><A NAME="anchor54"></A>
  +<P>
   The need for two sets of controlling scripts (startup/shutdown) and
   watchdogs.
   
   <P><LI>
  -<P><A NAME="anchor55"></A>
  +<P>
   If you are processing log files, now you probably will have to merge the
   two separate log files into one before processing them.
   
   </UL>
   <P><LI>
  -<P><A NAME="anchor56"></A>
  +<P>
   Just as in the one server approach, we still have the problem of a mod_perl
   process spending its precious time serving slow clients, when the
   processing portion of the request was completed a long time ago. Deploying
   a proxy solves this, and will be covered in the next section.
   
  -<P><A NAME="anchor57"></A>
  +<P>
   As with the single server approach, this is not a major disadvantage if you
   are on a fast network (i.e. Intranet). It is likely that you do not want a
   buffering server in this case.
   
   </UL>
  -<P><A NAME="anchor58"></A>
  +<P>
   Before you go on with this solution you really want to look at the
   <A HREF="././strategy.html#Adding_a_Proxy_Server_in_http_Ac">Adding a Proxy Server in http Accelerator Mode</A> section.
   
  -<P><A NAME="anchor59"></A>
  +<P>
   For implementation notes see the ``<A HREF="././scenario.html#One_Plain_and_One_mod_perl_enabl">One Plain and One mod_perl enabled Apache Servers</A>'' section in implementations chapter.
   
  -<P><A NAME="anchor60"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="One_light_non_Apache_and_One_mod">One light non-Apache and One mod_perl enabled Apache Servers</A></H2></CENTER>
  -<P><A NAME="anchor61"></A>
  +<P>
   If the only requirement from the light server is for it to serve static
  -objects, then you can get away with non-apache servers having an even
  -smaller memory footprint. <CODE>thttpd</CODE> has been reported to be about 5 times faster then apache (especially under
  -a heavy load), since it is very simple and uses almost no memory (260k) and
  +objects, then you can get away with non-Apache servers having an even
  +smaller memory footprint. <CODE>thttpd</CODE> has been reported to be about 5 times faster then Apache (especially under
  +a heavy load), since it is very simple and uses almost no memory (260K) and
   does not spawn child processes.
   
  -<P><A NAME="anchor62"></A>
  +<P>
   Meta: Hey, No personal experience here, only rumours. Please let me know if
   I have missed some pros/cons here. Thanks!
   
  -<P><A NAME="anchor63"></A>
  +<P>
   The Advantages:
   
   <UL>
   <P><LI>
  -<P><A NAME="anchor64"></A>
  +<P>
   All the advantages of the 2 servers scenario.
   
   <P><LI>
  -<P><A NAME="anchor65"></A>
  -More memory saving. Apache is about 4 times bigger then <STRONG>thttpd</STRONG>, if you spawn 30 children you use about 30M of memory, while <STRONG>thttpd</STRONG>
  -uses only 260k - 100 times less! You could use the 30M you've saved to run
  +<P>
  +More memory saving. Apache is about 4 times bigger than <STRONG>thttpd</STRONG>, if you spawn 30 children you use about 30M of memory, while <STRONG>thttpd</STRONG>
  +uses only 260K - 100 times less! You could use the 30M you've saved to run
   a few more mod_perl servers.
   
  -<P><A NAME="anchor66"></A>
  +<P>
   The memory savings are significantly smaller if your OS supports memory
   sharing with Dynamically Shared Objects (DSO) and you have configured
  -apache to use it. If you do allow memory sharing, 30 light apache servers
  +Apache to use it. If you do allow memory sharing, 30 light Apache servers
   ought to use only about 3 to 4Mb, because most of it will be shared. There
  -is no memory sharing if apache modules are statically compiled into httpd.
  +is no memory sharing if Apache modules are statically compiled into the
  +httpd executable.
   
   <P><LI>
  -<P><A NAME="anchor67"></A>
  -Reported to be about 5 times faster then plain apache serving static
  +<P>
  +Reported to be about 5 times faster then plain Apache serving static
   objects.
   
   </UL>
  -<P><A NAME="anchor68"></A>
  +<P>
   The Disadvantages:
   
   <UL>
   <P><LI>
  -<P><A NAME="anchor69"></A>
  -Lacks some of apache's features, like access control, error redirection,
  +<P>
  +Lacks some of Apache's features, like access control, error redirection,
   customizable log file formats, and so on.
   
   </UL>
  -<P><A NAME="anchor70"></A>
  +<P>
   META: It seems that khttpd, or Phhttpd should be even faster for static
   content serving, add more info about these two!
   
  -<P><A NAME="anchor71"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H1><A NAME="Adding_a_Proxy_Server_in_http_Ac">Adding a Proxy Server in http Accelerator Mode</A></H1></CENTER>
  -<P><A NAME="anchor72"></A>
  -At the beginning there were 2 servers: one plain apache server, which was <EM>very light</EM>, and configured to serve static objects, the other mod_perl enabled (<EM>very heavy</EM>) and configured to serve mod_perl scripts. We named them <CODE>httpd_docs</CODE> and <CODE>httpd_perl</CODE> respectively.
  +<P>
  +At the beginning there were two servers: one plain Apache server, which was <EM>very light</EM>, and configured to serve static objects, the other mod_perl enabled (<EM>very heavy</EM>) and configured to serve mod_perl scripts. We named them <CODE>httpd_docs</CODE> and <CODE>httpd_perl</CODE> respectively.
   
  -<P><A NAME="anchor73"></A>
  +<P>
   The two servers coexist at the same IP address by listening to different
   ports: <CODE>httpd_docs</CODE> listens to port 80 (e.g. <A
   HREF="http://www.nowhere.com/images/test.gif">http://www.nowhere.com/images/test.gif</A>)
  @@ -491,32 +522,32 @@
   first example, since port 80 is the default port for the http service.
   Later on, I will be changing the configuration of the <CODE>httpd_docs</CODE> server to make it listen to port 81.
   
  -<P><A NAME="anchor74"></A>
  +<P>
   Now I am going to convince you that you <STRONG>want</STRONG> to use a proxy server (in the http accelerator mode). The advantages are:
   
   <UL>
   <P><LI>
  -<P><A NAME="anchor75"></A>
  +<P>
   Allow serving of static objects from the proxy's cache (objects that
   previously were entirely served by the <CODE>httpd_docs</CODE> server).
   
   <P><LI>
  -<P><A NAME="anchor76"></A>
  +<P>
   You get less I/O activity reading static objects from the disk (proxy
   serves the most ``popular'' objects from RAM - of course you benefit more
   if you allow the proxy server to consume more RAM). Since you do not wait
  -for the I/O to be completed you are able to serve static objects much
  +for the I/O to be completed, you are able to serve static objects much
   faster.
   
   <P><LI>
  -<P><A NAME="anchor77"></A>
  +<P>
   The proxy server acts as a sort of output buffer for the dynamic content.
   The mod_perl server sends the entire response to the proxy and is then free
   to deal with other requests. The proxy server is responsible for sending
   the response to the browser. So if the transfer is over a slow link, the
   mod_perl server is not waiting around for the data to move.
   
  -<P><A NAME="anchor78"></A>
  +<P>
   Using numbers is always more convincing :) Let's take a user connected to
   your site with 28.8 kbps (bps == bits/sec) modem. It means that the speed
   of the user's link is 28.8/8 = 3.6 kbytes/sec. I assume an average
  @@ -527,35 +558,35 @@
   (40kb/3.6kb), when it could serve another 11 (12/1-1) dynamic requests in
   this time.
   
  -<P><A NAME="anchor79"></A>
  +<P>
   This very simple example shows us that we need only one twelfth the number
   of children running, which means that we will need only one twelfth of the
   memory (not quite true because some parts of the code are shared).
   
  -<P><A NAME="anchor80"></A>
  +<P>
   But you know that nowadays scripts often return pages which are blown up
  -with javascript code and similar, which can make them of 100kb size and the
  +with javascript code and similar, which can make them 100kb size and the
   download time will be of the order of... (This calculation is left to you
   as an exercise :)
   
  -<P><A NAME="anchor81"></A>
  +<P>
   Many users like to open many browser windows and do many things at once
   (download files and browse graphically <EM>heavy</EM> sites). So the speed of 3.6kb/sec we were assuming before, may often be
   5-10 times slower.
   
   <P><LI>
  -<P><A NAME="anchor82"></A>
  +<P>
   We are going to hide the details of the server's implementation. Users will
   never see ports in the URLs (more on that topic later). You can have a few
   boxes serving the requests, and only one serving as a front end, which
   spreads the jobs between the servers in a way that you can control. You can
   actually shut down a server, without the user even noticing, because the
  -front end server will dispatch the jobs to other servers. (This is called a
  -Load Ballancing and it's a pretty big issue, which will not be discussed in
  +front end server will dispatch the jobs to other servers. (This is called
  +Load Balancing and it's a pretty big issue, which will not be discussed in
   this document. For more information see <A HREF="././download.html#High_Availability_Linux_Project">'High-Availability Linux Project'</A>)
   
   <P><LI>
  -<P><A NAME="anchor83"></A>
  +<P>
   For security reasons, using any httpd accelerator (or a proxy in httpd
   accelerator mode) is essential because you do not let your internal server
   get directly attacked by arbitrary packets from whomever. The httpd
  @@ -564,12 +595,12 @@
   hosed in a successful attack, while leaving your internal data safe.
   
   </UL>
  -<P><A NAME="anchor84"></A>
  +<P>
   The disadvantages are:
   
   <UL>
   <P><LI>
  -<P><A NAME="anchor85"></A>
  +<P>
   Of course there are drawbacks. Luckily, these are not functionality
   drawbacks, but they are more administration hassle. You have another daemon
   to worry about, and while proxies are generally stable, you have to make
  @@ -578,44 +609,46 @@
   run a watchdog script.
   
   <P><LI>
  -<P><A NAME="anchor86"></A>
  -Proxy servers can be configured to be light or heavy, the admin must decide
  -what gives the highest performance for his application. A proxy server like
  -squid is light in the concept of having only one process serving all
  -requests. But it can appear pretty heavy when it loads objects into memory
  -for faster service.
  +<P>
  +Proxy servers can be configured to be light or heavy. The administrator
  +must decide what gives the highest performance for his application. A proxy
  +server like squid is light in the sense of having only one process serving
  +all requests. But it can appear pretty heavy when it loads objects into
  +memory for faster service.
   
   </UL>
  -<P><A NAME="anchor87"></A>
  +<P>
   Have I succeeded in convincing you that you want a proxy server?
   
  -<P><A NAME="anchor88"></A>
  +<P>
   If you are on a local area network (LAN), then the big benefit of the proxy
   buffering the output and feeding a slow client is gone. You are probably
   better off sticking with a straight mod_perl server in this case.
   
  -<P><A NAME="anchor89"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H1><A NAME="Implementations_of_Proxy_Servers">Implementations of Proxy Servers</A></H1></CENTER>
  -<P><A NAME="anchor90"></A>
  +<P>
   As of this writing, two proxy implementations are known to be widely used
  -with mod_perl - <STRONG>squid</STRONG> proxy server and <STRONG>mod_proxy</STRONG> which is a part of the apache server. Let's compare them.
  +with mod_perl, the <STRONG>squid</STRONG> proxy server and <STRONG>mod_proxy</STRONG> which is a part of the Apache server. Let's compare them.
   
  -<P><A NAME="anchor91"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="The_Squid_Server">The Squid Server</A></H2></CENTER>
  -<P><A NAME="anchor92"></A>
  +<P>
   The Advantages:
   
   <UL>
   <P><LI>
  -<P><A NAME="anchor93"></A>
  +<P>
   Caching of static objects. These are served much faster, assuming that your
   cache size is big enough to keep the most frequently requested objects in
   the cache.
   
   <P><LI>
  -<P><A NAME="anchor94"></A>
  +<P>
   Buffering of dynamic content, by taking the burden of returning the content
   generated by mod_perl servers to slow clients, thus freeing mod_perl
   servers from waiting for the slow clients to download the data. Freed
  @@ -623,71 +656,72 @@
   required servers goes down dramatically.
   
   <P><LI>
  -<P><A NAME="anchor95"></A>
  +<P>
   Non-linear URL space / server setup. You can use Squid to play some tricks
   with the URL space and/or domain based virtual server support.
   
   </UL>
  -<P><A NAME="anchor96"></A>
  +<P>
   The Disadvantages:
   
   <UL>
   <P><LI>
  -<P><A NAME="anchor97"></A>
  +<P>
   Proxying dynamic content is not going to help much if all the clients are
   on a fast local net. Also, a message on the squid mailing list implied that
  -squid only buffers in 16k chunks so it would not allow a mod_perl to
  -complete immediately if the output is larger.
  +squid only buffers in 16k chunks so it would not allow mod_perl to complete
  +immediately if the output is larger.
   
   <P><LI>
  -<P><A NAME="anchor98"></A>
  +<P>
   Speed. Squid is not very fast today when compared with the plain file based
   web servers available. Only if you are using a lot of dynamic features such
   as mod_perl or similar is there a reason to use Squid, and then only if the
   application and the server are designed with caching in mind.
   
   <P><LI>
  -<P><A NAME="anchor99"></A>
  +<P>
   Memory usage. Squid uses quite a bit of memory.
   
  -<P><A NAME="anchor100"></A>
  +<P>
   META: more details?
   
   <P><LI>
  -<P><A NAME="anchor101"></A>
  +<P>
   HTTP protocol level. Squid is pretty much a <CODE>HTTP/1.0</CODE> server, which seriously limits the deployment of <CODE>HTTP/1.1</CODE> features.
   
   <P><LI>
  -<P><A NAME="anchor102"></A>
  +<P>
   HTTP headers, dates and freshness. The squid server might give out stale
  -pages, confusing downstream/client caches.(You update some documents on the
  -site, but squid will still serve the old ones.)
  +pages, confusing downstream/client caches. (You update some documents on
  +the site, but squid will still serve the old ones.)
   
   <P><LI>
  -<P><A NAME="anchor103"></A>
  +<P>
   Stability. Compared to plain web servers, Squid is not the most stable.
   
   </UL>
  -<P><A NAME="anchor104"></A>
  +<P>
   The pros and cons presented above lead to the idea that you might want to
   use squid for its dynamic content buffering features, but only if your
   server serves mostly dynamic requests. So in this situation, when
  -performance is the goal, it is better to have a plain apache server serving
  +performance is the goal, it is better to have a plain Apache server serving
   static objects, and squid proxying the mod_perl enabled server only.
   
  -<P><A NAME="anchor105"></A>
  -For implementation details see the sections <A HREF="././scenario.html#Running_One_Webserver_and_Squid_">Running One Webserver and Squid in httpd Accelerator Mode</A> and the <A HREF="././scenario.html#Running_Two_webservers_and_Squid">Running Two Webservers and Squid in httpd Accelerator Mode</A> in the implementations chapter.
  +<P>
  +For implementation details, see the sections <A HREF="././scenario.html#Running_One_Webserver_and_Squid_">Running One Webserver and Squid in httpd Accelerator Mode</A> and <A HREF="././scenario.html#Running_Two_webservers_and_Squid">Running Two Webservers and Squid in httpd Accelerator Mode</A> in the implementations chapter.
   
  -<P><A NAME="anchor106"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="Apache_s_mod_proxy">Apache's mod_proxy</A></H2></CENTER>
  -<P><A NAME="anchor107"></A>
  -I do not think the difference in speed between apache's <STRONG>mod_proxy</STRONG>
  +<P>
  +I do not think the difference in speed between Apache's <STRONG>mod_proxy</STRONG>
   and <STRONG>squid</STRONG> is relevant for most sites, since the real value of what they do is
   buffering for slow client connections. However, squid runs as a single
   process and probably consumes fewer system resources.
   
  -<P><A NAME="anchor108"></A>
  +<P>
   The trade-off is that mod_rewrite is easy to use if you want to spread
   parts of the site across different back end servers, while mod_proxy knows
   how to fix up redirects containing the back-end server's idea of the
  @@ -695,7 +729,7 @@
   one back end, but there is a problem in fixing redirects in a way that
   keeps the client's view of both server names and port numbers in all cases.
   
  -<P><A NAME="anchor109"></A>
  +<P>
   The difficult case is where:
   
   <UL>
  @@ -705,208 +739,259 @@
   <P><LI><STRONG><A NAME="item_You">You want to keep the specific name the browser has already
   sent, so that it does not change in the client's Location window.</A></STRONG>
   </UL>
  -<P><A NAME="anchor110"></A>
  +<P>
   The Advantages:
   
   <UL>
   <P><LI>
  -<P><A NAME="anchor111"></A>
  +<P>
   No additional server is needed. We keep the one plain plus one mod_perl
  -enabled apache servers. All you need is to enable
  +enabled Apache servers. All you need is to enable
   <CODE>mod_proxy</CODE> in the <CODE>httpd_docs</CODE> server and add a few lines to
   <CODE>httpd.conf</CODE> file.
   
   <P><LI>
  -<P><A NAME="anchor112"></A>
  +<P>
   The <CODE>ProxyPass</CODE> and <CODE>ProxyPassReverse</CODE> directives allow you to hide the internal redirects, so if <CODE>http://nowhere.com/modperl/</CODE> is actually <CODE>http://localhost:81/modperl/</CODE>, it will be absolutely transparent to the user. <CODE>ProxyPass</CODE> redirects the request to the mod_perl server, and when it gets the
   response, <CODE>ProxyPassReverse</CODE>
   rewrites the URL back to the original one, e.g:
   
  -<P><A NAME="anchor113"></A>
  -<PRE>  ProxyPass        /modperl/ <A HREF="http://localhost:81/modperl/">http://localhost:81/modperl/</A>
  -  ProxyPassReverse /modperl/ <A HREF="http://localhost:81/modperl/">http://localhost:81/modperl/</A>
  -</PRE>
  -<P><LI>
  -<P><A NAME="anchor114"></A>
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  ProxyPass        /modperl/ <A HREF="http://localhost:81/modperl/">http://localhost:81/modperl/</A>
  +  ProxyPassReverse /modperl/ <A HREF="http://localhost:81/modperl/">http://localhost:81/modperl/</A></pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P><LI>
  +<P>
   It does mod_perl output buffering like squid does. See the <A HREF="././scenario.html#mod_proxy">Using mod_proxy</A> notes for more details.
   
   <P><LI>
  -<P><A NAME="anchor115"></A>
  +<P>
   It even does caching. You have to produce correct <CODE>Content-Length</CODE>,
   <CODE>Last-Modified</CODE> and <CODE>Expires</CODE> http headers for it to work. If some of your dynamic content does not
   change frequently, you can dramatically increase performance by caching it
   with <CODE>ProxyPass</CODE>.
   
   <P><LI>
  -<P><A NAME="anchor116"></A>
  +<P>
   <CODE>ProxyPass</CODE> happens before the authentication phase, so you do not have to worry about
   authenticating twice.
   
   <P><LI>
  -<P><A NAME="anchor117"></A>
  +<P>
   Apache is able to accelerate secure HTTP requests completely, while also
   doing accelerated HTTP. With Squid you have to use an external redirection
   program for that.
   
   <P><LI>
  -<P><A NAME="anchor118"></A>
  -The latest (apache 1.3.6 and later) Apache proxy accelerated mode is
  +<P>
  +The latest (Apache 1.3.6 and later) Apache proxy accelerated mode is
   reported to be very stable.
   
   </UL>
  -<P><A NAME="anchor119"></A>
  +<P>
   The Disadvantages:
   
   <UL>
   <P><LI>
  -<P><A NAME="anchor120"></A>
  +<P>
   Users have reported that it might be a bit slow, but the latest version is
   fast enough. 
   
  -<P><A NAME="anchor121"></A>
  +<P>
   (META: How fast is enough? :) Any figures here? 
   
   </UL>
  -<P><A NAME="anchor122"></A>
  +<P>
   For implementation see the ``<A HREF="././scenario.html#mod_proxy">Using mod_proxy</A>'' section in the implementation chapter.
   
  -<P><A NAME="anchor123"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H1><A NAME="When_One_Machine_is_not_Enough_f">When One Machine is not Enough for SQL DB and mod_perl</A></H1></CENTER>
  -<P><A NAME="anchor124"></A>
  -You have begun your business as a small service providing web-site. After a
  -while your business becomes very popular and at some point you understand
  +<P>
  +You have started your business as a small service providing web-site. After
  +a while your business becomes very popular and at some point you understand
   that it has outgrown the capacity of your machine and you have moved
  -everything onto a stronger machine with more memory, a stronger CPU and a
  +everything onto a stronger machine with more memory, a faster CPU and a
   faster hard disk.
   
  -<P><A NAME="anchor125"></A>
  -The situation comes back to normal but not for a long, as a demand for your
  -services keeps on growing and just a little time after you've upgraded your
  -machine, it cannot stand the load again. Should you buy an even stronger
  -and very expensive machine or start looking for another solution?
  +<P>
  +The situation goes back to normal but not for a long, as the demand for
  +your services keeps on growing and just a little time after you've upgraded
  +your machine, once again it cannot cope the load. Should you buy an even
  +stronger and very expensive machine or start looking for another solution?
   
  -<P><A NAME="anchor126"></A>
  +<P>
   A typical web service consists of two main software components, the
   database server and the web server.
   
  -<P><A NAME="anchor127"></A>
  +<P>
   A typical user-server interaction consists of accepting the query
  -parameters filled into an HTML form and submitted to the web server by a
  +parameters entered into an HTML form and submitted to the web server by a
   user, converting these parameters into a database query, sending it to the
   database server, accepting the results of the executed query, formatting
   them into a nice HTML page, and sending it to a user's Internet browser or
   another application that created the request.
   
  -<P><A NAME="anchor128"></A>
  +<P>
   This figure depicts the above description:
  +
  +<P>
   
  -<P><A NAME="anchor129"></A>
  -<PRE>             1                      2
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>             1                      2
     [      ] ====&gt; [               ] ====&gt; [                 ]
     [ User ]       [ Apache Server ]       [ Database Server ]
     [      ] &lt;==== [               ] &lt;==== [                 ]
  -             4                       3
  -</PRE>
  -<P><A NAME="anchor130"></A>
  +             4                       3</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   This schema is known as a 3-tier architecture in the computing world.
   
  -<P><A NAME="anchor131"></A>
  -3-tier architecture means splitting up several processes of your computing
  -solution between different machines.
  +<P>
  +A 3-tier architecture means splitting up several processes of your
  +computing solution between different machines.
   
  -<P><A NAME="anchor132"></A>
  +<P>
   1st you have the client, who will see the data on its screen and can give
  -instruction to modify or process the data. In our case, an Internet
  +instructions to modify or process the data. In our case, an Internet
   browser.
   
  -<P><A NAME="anchor133"></A>
  +<P>
   2nd you have the application server, which does the actual processing of
   the data and sends it back to the client. In our case, a mod_perl enabled
  -apache server.
  +Apache server.
   
  -<P><A NAME="anchor134"></A>
  +<P>
   3rd you have the database server, which stores and retrieves all the data
   for the application server.
   
  -<P><A NAME="anchor135"></A>
  -+We are interested only in the 2nd and the 3rd tiers; we don't specify user
  +<P>
  +We are interested only in the 2nd and the 3rd tiers; we don't specify user
   machine requirements, since mod_perl is all about server side programming.
   The only thing the user should be able to do is to render the generated
   HTML from the response, which any simple browser will do. Of course I'm not
   talking about the case where you return some heavy Java applets, but that
   movie is screened in another theater.
   
  -<P><A NAME="anchor136"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="Servers_Requirements">Servers' Requirements</A></H2></CENTER>
  -<P><A NAME="anchor137"></A>
  +<P>
   Let's first understand what kind of software the web and database servers
  -are, what do they need to run fast and what implications they have on the
  -rest of the system software.
  +are, what they need to run fast and what implications they have on the rest
  +of the system software.
   
  -<P><A NAME="anchor138"></A>
  +<P>
   The three important machine components are the hard disk, the amount of RAM
   and the CPU type.
   
  -<P><A NAME="anchor139"></A>
  -In the average case the mod_perl server is mostly RAM hungry, while SQL
  -database server needs a very fast hard-disk the most. Of course if your
  -mod_perl process reads a lot from the disk (which is a quite infrequent
  -phenomenon) you will need a fast disk too. And if your database server has
  -to do a lot of sorting of the big tables and do lots of big table joins,
  -you will need a lot of RAM too.
  +<P>
  +Typically the mod_perl server is mostly RAM hungry, while the SQL database
  +server mostly needs a very fast hard-disk. Of course if your mod_perl
  +process reads a lot from the disk (which is a quite infrequent phenomenon)
  +you will need a fast disk too. And if your database server has to do a lot
  +of sorting of big tables and do lots of big table joins, you will need a
  +lot of RAM too.
   
  -<P><A NAME="anchor140"></A>
  +<P>
   If we would specify average ``virtual'' requirements for each machine,
   that's what we'd get:
   
  -<P><A NAME="anchor141"></A>
  +<P>
   An <EM>"ideal"</EM> mod_perl machine:
   
  -<P><A NAME="anchor142"></A>
  -<PRE>  * HD:  low-end (no real IO, mostly logging)
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  * HD:  low-end (no real IO, mostly logging)
     * RAM: the more the better
  -  * CPU: medium-high (according to needs)
  -</PRE>
  -<P><A NAME="anchor143"></A>
  +  * CPU: medium to high (according to needs)</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   An <EM>"ideal"</EM> database server machine:
  +
  +<P>
   
  -<P><A NAME="anchor144"></A>
  -<PRE>  * HD:  high-end
  -  * RAM: big amount   (big joins, sorting of many records)
  -         small amount (otherwise)
  -  * CPU: medium-high (according to needs)
  -</PRE>
  -<P><A NAME="anchor145"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  * HD:  high-end
  +  * RAM: large amounts   (big joins, sorting of many records)
  +         small amounts (otherwise)
  +  * CPU: medium to high (according to needs)</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="The_Problem">The Problem</A></H2></CENTER>
  -<P><A NAME="anchor146"></A>
  +<P>
   With the database and the httpd on the same machine, you have conflicting
   interests.
   
  -<P><A NAME="anchor147"></A>
  -During the peak load, Apache will spawn more processes and use RAM that the
  +<P>
  +During peak loads, Apache will spawn more processes and use RAM that the
   database server might have been using, or that the kernel was using on its
   behalf in the form of cache. You will starve your database of resources at
   the time when it needs those resources the most.
   
  -<P><A NAME="anchor148"></A>
  +<P>
   Disk I/O contention is the biggest time issue. Adding another disk wouldn't
   cut I/O times because the database is the only one who does I/O - since
  -mod_perl processes has all the code loaded in memory. (I'm talking about
  +mod_perl processes have all their code loaded in memory. (I'm talking about
   code that does pure perl and SQL processing) so it's clear that the DB is
   I/O and CPU bounded (RAM only if there are big joins to make) and mod_perl
   CPU and mostly RAM bounded.
   
  -<P><A NAME="anchor149"></A>
  +<P>
   The problem exists, but it doesn't mean that you cannot run the application
   and the web servers on the same machine. There is a very high degree of
   parallelism in modern PC architecture. The I/O hardware is helpful here.
   The machine can do many things while a SCSI subsystem is processing a
   command, or the network hardware is writing a buffer over the wire.
   
  -<P><A NAME="anchor150"></A>
  +<P>
   If a process is not runnable (that is, it is blocked waiting for I/O or
   similar), it is not using significant CPU time. The only CPU time that will
   be required to maintain a blocked process is the time it takes for the
  @@ -917,147 +1002,175 @@
   0% CPU time, the runnable process is getting 99.9% CPU time, and the kernel
   scheduler is using the remainder.
   
  -<P><A NAME="anchor151"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="The_Solution">The Solution</A></H2></CENTER>
  -<P><A NAME="anchor152"></A>
  +<P>
   Adding another machine, which allows a set-up where both the database and
  -the web servers run on its dedicated machine.
  +the web servers run on their own dedicated machines.
   
  -<P><A NAME="anchor153"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H3><A NAME="Pros">Pros</A></H3></CENTER>
   <UL>
   <P><LI><STRONG><A NAME="item_Hardware">Hardware Requirements</A></STRONG>
  -<P><A NAME="anchor154"></A>
  +<P>
   That allows you to scale two requirements independently.
   
  -<P><A NAME="anchor155"></A>
  +<P>
   If your httpd processes are heavily weighted with respect to RAM
   consumption, you can easily add another machine to accommodate more httpd
   processes, without changing your database machine.
   
  -<P><A NAME="anchor156"></A>
  +<P>
   If your database is CPU intensive, but your httpd doesn't need much CPU
   time, you can get low end machines for the httpd and a high end machine
   with a very fast CPU for the database server.
   
   <P><LI><STRONG><A NAME="item_Scalability">Scalability</A></STRONG>
  -<P><A NAME="anchor157"></A>
  +<P>
   Since your web server is not depending on the database server location any
   more, you can add more web servers hitting the same database server, using
   the existing infrastructure.
   
   <P><LI><STRONG><A NAME="item_Database">Database Security</A></STRONG>
  -<P><A NAME="anchor158"></A>
  +<P>
   Once you have multiple web server boxes the backend database becomes a
   single point of failure so it's a good idea to shield it from direct
  -internet access, something you couldn't do when you had both servers on the
  +Internet access, something you couldn't do when you had both servers on the
   same machine.
   
   </UL>
  -<P><A NAME="anchor159"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H3><A NAME="Cons">Cons</A></H3></CENTER>
   <UL>
   <P><LI><STRONG><A NAME="item_Network">Network latency</A></STRONG>
  -<P><A NAME="anchor160"></A>
  -When the request to the database server like mysql are made at the same
  -machine the database server is running on, it uses the UNIX sockets
  -compared to the TCP/IP socket when the client submits the query from
  -another machine. UNIX sockets are very fast since there is no network
  -delays, since all the communications happens within the same box. TCP/IP
  -sockets communication totally depends on the quality and the speed of the
  -network the two machines are connected with.
  -
  -<P><A NAME="anchor161"></A>
  -Basically you can have almost the same client-server speed if you install a
  -very fast and dedicated network between the two machines. It might impose a
  -cost of additional NICs but it's probably insignificant compared to the
  +<P>
  +A database request from a webserver to a database server running on the
  +same machine uses UNIX sockets, compared to the TCP/IP sockets used when
  +the client submits the query from another machine. UNIX sockets are very
  +fast since all the communications happens within the same box, eliminating
  +network delays. TCP/IP sockets communication totally depends on the quality
  +and the speed of the network the two machines are connected with.
  +
  +<P>
  +Basically, you can have almost the same client-server speed if you install
  +a very fast and dedicated network between the two machines. It might impose
  +a cost of additional NICs but it's probably insignificant compared to the
   speed up you gain.
   
  -<P><A NAME="anchor162"></A>
  +<P>
   But even the normal network that you have would probably fit as well,
   because the networks delays are probably much smaller than the time it
   takes to execute the query. In contrast to the previous paragraph, you
   really want to test the added overhead, since the network can be quite slow
   especially at the peak hours.
   
  -<P><A NAME="anchor163"></A>
  +<P>
   How do you know what overhead is a significant one? All you have to measure
   is the average time spent in the web server and the database server. If any
   of the two numbers is at least 20 times bigger than the added overhead of
   the network you are all set.
   
  -<P><A NAME="anchor164"></A>
  +<P>
   To give you some numbers -- if your query takes about 20 milliseconds to
   process and only 1 millisecond to deliver the results, it's good. If the
   delivery takes about half of the time the processing takes you should start
  -thinking to switch to a faster and/or dedicated network.
  +considering switching to a faster and/or dedicated network.
   
  -<P><A NAME="anchor165"></A>
  -The implications of the slow network can be quite bad. If the network is
  -slow mod_perl processes remain open waiting for data from the database
  -server and eats even more RAM as new child processes pop up to handle new
  -requests. So the overall machine performance can be worse than it was
  -originally when you have had a single machine for both servers.
  +<P>
  +The consequences of a slow network can be quite bad. If the network is slow
  +mod_perl processes remain open waiting for data from the database server
  +and eat even more RAM as new child processes pop up to handle new requests.
  +So the overall machine performance can be worse than it was originally when
  +you had just a single machine for both servers.
   
   </UL>
  -<P><A NAME="anchor166"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="Three_Machines_Model">Three Machines Model</A></H2></CENTER>
  -<P><A NAME="anchor167"></A>
  -Since we are talking about giving a dedicated machine for each server, you
  -might consider adding the third machine to do the proxy work, this will
  -make your setup even more flexible since it will enable you to proxy-pass
  -all request to more than one mod_perl running box, but many of them. It
  -will enable you doing a load balancing if and when you will need that.
  -
  -<P><A NAME="anchor168"></A>
  -Generally the proxy machine can be very light when they serve just a little
  -traffic and mainly proxy-pass to the mod_perl processes. Of course you can
  -put this machine to serve the static content and then the hardware
  -requirement will depend on the number of object you will have to serve and
  -the hit rate.
  +<P>
  +Since we are talking about using a dedicated machine for each server, you
  +might consider adding a third machine to do the proxy work; this will make
  +your setup even more flexible since it will enable you to proxy-pass all
  +request to not just one mod_perl running box, but to many of them. It will
  +enable you to do load balancing if and when you need it.
  +
  +<P>
  +Generally the proxy machine can be very light when it serves just a little
  +traffic and mainly proxy-passes to the mod_perl processes. Of course you
  +can use this machine to serve the static content and then the hardware
  +requirement will depend on the number of objects you will have to serve and
  +the rate at which they are requested.
   
  -<P><A NAME="anchor169"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H1><A NAME="Do_Not_Run_Everything_on_One_mod">Do Not Run Everything on One mod_perl Server</A></H1></CENTER>
  -<P><A NAME="anchor170"></A>
  -Let's assume that you have two different sets of scripts/code which have a
  -little or nothing in common at all (different modules, no code sharing).
  -Typical numbers can be four megabytes of unshared and four megabytes of
  -shared memory for each code set, plus three megabytes of shared basic
  -mod_perl stuff. Which makes each process 17Mb in size when the two code
  -sets are loaded. (3Mb (server) + 4Mb (shared 1st code set ) + 4Mb (unshared
  -1st code set ) + 4Mb (shared 2nd code set ) + 4Mb (unshared 2nd code set ).
  -Where eleven megabytes are shared and eight megabytes not.
  -
  -<P><A NAME="anchor171"></A>
  -We assume that four megabytes is the size of each code set unshared memory.
  -This is pretty typical size of unshared memory, especially when connecting
  -to databases, as the database connections cannot be shared, and especially
  -DB's like Oracle take lots of RAM per connection.
  +<P>
  +Let's assume that you have two different sets of scripts/code which have
  +little or nothing in common; different modules, no code sharing. Typical
  +numbers can be four megabytes of unshared and four megabytes of shared
  +memory for each code set, plus three megabytes of shared basic mod_perl
  +stuff. Which makes each process 17Mb in size when the two code sets are
  +loaded. (3Mb (server) + 4Mb (shared 1st code set ) + 4Mb (unshared 1st code
  +set ) + 4Mb (shared 2nd code set ) + 4Mb (unshared 2nd code set ). Under
  +this scenario, eleven megabytes are shared and eight megabytes not.
  +
  +<P>
  +We assume that four megabytes is the size of each code sets unshared
  +memory. This is a pretty typical size of unshared memory, especially when
  +connecting to databases, as the database connections cannot be shared.
  +Databases like Oracle can take even more RAM per connection on top of this.
   
  -<P><A NAME="anchor172"></A>
  -Let's assume that we have 260 megabytes of RAM dedicated for the webserver.
  +<P>
  +Let's assume that we have 260 megabytes of RAM dedicated to the webserver.
   
  -<P><A NAME="anchor173"></A>
  +<P>
   According to the equation developed in the section: ``<A HREF="././performance.html#Choosing_MaxClients">Choosing MaxClients</A>'':
  +
  +<P>
   
  -<P><A NAME="anchor174"></A>
  -<PRE>                    Total_RAM - Max_Process_Size
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>                    Total_RAM - Max_Process_Size
     MaxClients = ---------------------------------------
  -               Max_Process_Size - Shared_RAM_per_Child
  -</PRE>
  -<P><A NAME="anchor175"></A>
  -<PRE>  MaxClients = (260 - 17)/(17-11) = 40
  -</PRE>
  -<P><A NAME="anchor176"></A>
  +               Max_Process_Size - Shared_RAM_per_Child</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  MaxClients = (260 - 17)/(17-11) = 40</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   We see that we can run 40 processes, using the given memory and the two
   code sets in the same server.
   
  -<P><A NAME="anchor177"></A>
  +<P>
   Now consider this practical decision. Since we have recognized that the
   code sets are very distinct in nature and there is no significant memory
   sharing in place, the wise thing to do is to split the two code sets
  @@ -1067,193 +1180,261 @@
   another mod_perl server. At this point we are talking about a single
   machine.
   
  -<P><A NAME="anchor178"></A>
  +<P>
   Let's look at the figures again. After the split we will have 20 servers of
   eleven megabytes (4Mb unshared + 7mb shared) and another 20 servers of
   eleven megabytes.
   
  -<P><A NAME="anchor179"></A>
  +<P>
   How much memory do we need now? From the above equation we derive:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor180"></A>
  -<PRE>  Total_RAM = MaxClients * (Max_Process_Size - Shared_RAM_per_Child)
  -              + Max_Process_Size
  -</PRE>
  -<P><A NAME="anchor181"></A>
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  Total_RAM = MaxClients * (Max_Process_Size - Shared_RAM_per_Child)
  +              + Max_Process_Size</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   And using the numbers:
   
  -<P><A NAME="anchor182"></A>
  -<PRE>  Total_RAM = 2 * (20 * (11-7) + 11) = 182
  -</PRE>
  -<P><A NAME="anchor183"></A>
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  Total_RAM = 2 * (20 * (11-7) + 11) = 182</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   A total of 182 megabytes of memory required. But, hey, we have 260Mb of
   memory. We've got 78Mb of memory freed up. If we recalculate again the <CODE>MaxClients</CODE> we will see that we can run almost 60 servers:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor184"></A>
  -<PRE>  MaxClients = (260 - 11*2)/(11-8) = 60
  -</PRE>
  -<P><A NAME="anchor185"></A>
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  MaxClients = (260 - 11*2)/(11-8) = 60</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   So we can run about 20 more servers using the same memory size. 30 servers
   for each code set. We have enlarged the servers pool by a half without
  -changing machine's hardware.
  +changing the machine's hardware.
   
  -<P><A NAME="anchor186"></A>
  +<P>
   Moreover this new setup allows us to fine tune the two code sets, since in
   reality the smaller in size code base might have a higher hit rate, so we
   can benefit even more. 
   
  -<P><A NAME="anchor187"></A>
  +<P>
   Let's assume that based on the usage statistics we know that the first code
  -set is deployed in 70% of requests and the other 30% are used by the second
  +set is called in 70% of requests and the other 30% are used by the second
   set. Now we assume that the first code set requires only 5Mbytes of RAM
   (3Mb shared plus 2Mb unshared) over the basic mod_perl server size, and the
   second set needs 11Mbytes (7Mb shared and 4Mb unshared).
   
  -<P><A NAME="anchor188"></A>
  -Lets compare this new requirement with our original 50%/50% setup.
  +<P>
  +Lets compare this new requirement with our original 50:50 setup.
   
  -<P><A NAME="anchor189"></A>
  +<P>
   So now the first mod_perl server running the first code set will have all
  -its processes of 8Mb (3Mb (server shared) + 3Mb (code shared) + 2Mb (code
  -unshared), and the second 14Mb (3+7+4). Given that we have a 70:30 hits
  -relation and that we have 260Mbytes of available memory, we have to solve
  -these two equations:
  -
  -<P><A NAME="anchor190"></A>
  -<PRE>  X/Y = 7/3
  -</PRE>
  -<P><A NAME="anchor191"></A>
  -<PRE>  X*(8-6) + 8 + Y*(14-10) + 14 = 260
  -</PRE>
  -<P><A NAME="anchor192"></A>
  +its processes using 8Mb (3Mb (server shared) + 3Mb (code shared) + 2Mb
  +(code unshared), and the second 14Mb (3+7+4). Given that we have a 70:30
  +hits relation and that we have 260Mbytes of available memory, we have to
  +solve these two equations:
  +
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  X/Y = 7/3</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  X*(8-6) + 8 + Y*(14-10) + 14 = 260</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   where X is the total number of the processes the first code set can use and
   Y the second. The first equation reflect the 70:30 hits relation, and the
   second uses the equation for the total memory requirements for the given
   number of servers and the shared and unshared memory sizes.
   
  -<P><A NAME="anchor193"></A>
  -When we solve these equations, we get that X equals 63 and Y equals 27. So
  -we have a total of 90 servers -- we have twice and a half more servers
  -running compared to the original setup using the same memory size
  +<P>
  +When we solve these equations, we find that X equals 63 and Y equals 27. So
  +we have a total of 90 servers -- two and a half times the number of servers
  +running compared to the original setup using the same memory size.
   
  -<P><A NAME="anchor194"></A>
  +<P>
   The hits rate optimized solution and the fact that the code sets can be
   different in their memory requirements, allowed us to run 30 more servers
   in total and gave us 33 more servers (63 versus 30) for the most wanted
   code base, relative to the simple 50:50 split as in the first example.
   
  -<P><A NAME="anchor195"></A>
  -Of course if you can identify more than two distinct sets of code and your
  -hits rate statistics may require more complicated decisions. You ought to
  -make even more splits and run three and more mod_perl servers.
  -
  -<P><A NAME="anchor196"></A>
  -Remember that having too many running processes doesn't necessarily mean a
  -better performance because of all of them will fight over CPU time slices.
  -The more processes are running the less CPU time each gets the slower the
  -overall performance will be. Therefore after hitting a certain load you
  -might want to start spreading servers over different machine.
  +<P>
  +Of course if you identify more than two distinct sets of code based on your
  +hit rate statistics, more complicated solutions may be required. You could
  +make even more splits and run three or more mod_perl servers.
  +
  +<P>
  +Remember that having too many running processes doesn't necessarily mean
  +better performance because all of them will contend for CPU time slices.
  +The more processes that are running the less CPU time each gets and the
  +slower overall performance will be. Therefore after hitting a certain load
  +you might want to start spreading servers over different machines.
   
  -<P><A NAME="anchor197"></A>
  +<P>
   In addition to the obvious memory saving you gain the power to troubleshoot
  -problems, that occur, much easier, when you have different components
  -running on different servers. It's quite possible that a little change in
  -the server configuration coming to fix or improve something in one code
  -set, might completely break the second code set. For example if you upgrade
  -the first code set and it requires an update of some modules that both code
  -bases rely on. But there is a chance that the second code set won't work
  -with a new module it was relying on.
  -
  -<P><A NAME="anchor198"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<CENTER><H1><A NAME="Do_Not_Put_mod_ssl_into_mod_perl">Do Not Put mod_ssl into mod_perl Server</A></H1></CENTER>
  -<P><A NAME="anchor199"></A>
  -If you need an SSL functionality, you can get it by adding the mod_ssl or
  -equivalent apache_ssl to the light front-end server (httpd_docs) or the
  +problems that occur more easily when you have different components running
  +on different servers. It's quite possible that a small change in the server
  +configuration to fix or improve something for one code set, might
  +completely break the second code set. For example if you upgrade the first
  +code set and it requires an update of some modules that both code bases
  +rely on. But there is a chance that the second code set won't work with a
  +new version of a module it was relying on.
  +
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
  +<CENTER><H1><A NAME="Do_Not_Put_mod_ssl_into_a_mod_pe">Do Not Put mod_ssl into a mod_perl Server</A></H1></CENTER>
  +<P>
  +If you need SSL functionality, you can get it by adding the mod_ssl or
  +equivalent Apache_ssl to the light front-end server (httpd_docs) or the
   heavy back-end mod_perl server (httpd_perl). ( The configuration and
   installation instructions are located
   <A HREF="././install.html#mod_perl_and_mod_ssl_openssl_">here</A>.)
   
  -<P><A NAME="anchor200"></A>
  -The question is whether it's a good idea to add mod_ssl into the back-end
  -mod_perl enabled server. Given that your internal network is secured or if
  +<P>
  +The question is: Is it a good idea to add mod_ssl into the back-end
  +mod_perl enabled server? Given that your internal network is secured, or if
   both the front and back end servers are running on the same machine and you
  -can ensure a safe communication between the processes there is no need for
  +can ensure a safe communication between the processes, there is no need for
   an encrypted traffic between them.
   
  -<P><A NAME="anchor201"></A>
  +<P>
   If this is the situation you don't have to put mod_ssl into the already too
  -much heavy mod_perl server. You will have the external traffic encrypted by
  -the front-end server, which will proxy-pass the unencrypted request and
  +heavy mod_perl server. You will have the external traffic encrypted by the
  +front-end server, which will proxy-pass the unencrypted request and
   response data internally.
   
  -<P><A NAME="anchor202"></A>
  +<P>
   Another important point is if you put the mod_ssl on the back-end, you have
   to tunnel back your images to it (i.e. have the back-end serve the images)
   defeating the whole purpose of having the front-end lightweight server. 
   
  -<P><A NAME="anchor203"></A>
  +<P>
   You cannot serve a secure page which includes non-secured information. If
  -you fetch an html over SSL and have an
  -<CODE>&lt;IMG&gt;</CODE> tag that fetches the image from the non-secure server, the image show
  -broken. This is true for any other non-secured object as well. Of course if
  -the generated response doesn't include any embedded objects, like images --
  -this is not a problem.
  +you fetch an html page over SSL and have an
  +<CODE>&lt;IMG&gt;</CODE> tag that fetches the image from the non-secure server, the image is shown
  +broken. This is true for any other non-secured objects as well. Of course
  +if the generated response doesn't include any embedded objects, like images
  +-- this is not a problem.
   
  -<P><A NAME="anchor204"></A>
  +<P>
   Choosing the front-end machine to have an SSL functionality also simplifies
   configuration of mod_perl by eliminating VirtualHost duplication for SSL.
   mod_perl configuration files can be plenty difficult without the mod_ssl
   overhead.
   
  -<P><A NAME="anchor205"></A>
  +<P>
   Also assuming that you have front-end machines under-worked anyway,
   especially if you run a high-volume web service deploying a cluster of
   machines to serve requests, you save some CPU as it's known that SSL
   connections are about 100 times more CPU intensive than non-SSL
   connections.
   
  -<P><A NAME="anchor206"></A>
  +<P>
   Of course caching session keys so you don't have to set up a new symmetric
   key for every single connection, improves the situation. If you use the
   shared memory session caching mechanism that mod_ssl supports, then the
   overhead is actually rather small except for the initial connection.
   
  -<P><A NAME="anchor207"></A>
  +<P>
   But then on the other hand, why even bother to run a full scale mod_ssl in
   front? You might as well just choose a small tunnel/port forwarding
   application like Stunnel or one of the many other mentioned at <A
   HREF="http://www.openssl.org/related/apps.html">http://www.openssl.org/related/apps.html</A>
   .
   
  -<P><A NAME="anchor208"></A>
  -Of course if you do a heavy SSL processing you should really be offloading
  -it to dedicated cryptography hardware.
  +<P>
  +Of course if you do heavy SSL processing ideally you should really be
  +offloading it to a dedicated cryptography server. But this advice can be
  +misleading based on the current status of the crypto hardware. If you use
  +hardware you get extra speed now, but you're locked into a proprietary
  +solution; in 6 months/one year software will have caught up with whatever
  +hardware you're using and because software is easier to adapt you'll have
  +more freedom to change what software you're using and more control of
  +things. So the choice is in your hand.
   
  -<P><A NAME="anchor209"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H1><A NAME="Pros_and_Cons_of_Building_mod_pe">Pros and Cons of Building mod_perl as DSO</A></H1></CENTER>
  -<P><A NAME="anchor210"></A>
  -On modern Unix derivatives there exists a nifty mechanism usually called
  -dynamic linking/loading of Dynamic Shared Objects (DSO) which provides a
  -way to build a piece of program code in a special format for loading it at
  +<P>
  +On modern Unix derivatives there is a nifty mechanism usually called
  +dynamic linking/loading of Dynamic Shared Objects (DSO), which provides a
  +way to build a piece of program code in a special format for loading in at
   run-time into the address space of an executable program.
   
  -<P><A NAME="anchor211"></A>
  +<P>
   As of Apache 1.3, the configuration system supports two optional features
   for taking advantage of the modular DSO approach: compilation of the Apache
   core program into a DSO library for shared usage and compilation of the
   Apache modules into DSO files for explicit loading at run-time.
   
  -<P><A NAME="anchor212"></A>
  +<P>
   Should you use this method? Read the pros and cons and decide for yourself.
   
  -<P><A NAME="anchor213"></A>
  +<P>
   Pros:
   
   <UL>
   <P><LI>
  -<P><A NAME="anchor214"></A>
  +<P>
   The server package is more flexible at run-time because the actual server
   process can be assembled at run-time via <CODE>LoadModule</CODE>
   
  @@ -1264,44 +1445,44 @@
   with only one Apache installation.
   
   <P><LI>
  -<P><A NAME="anchor215"></A>
  +<P>
   The server package can be easily extended with third-party modules even
   after installation. This is at least a great benefit for vendor package
  -maintainers who can create a Apache core package and additional packages
  +maintainers who can create an Apache core package and additional packages
   containing extensions like PHP3, mod_perl, mod_fastcgi, etc.
   
   <P><LI>
  -<P><A NAME="anchor216"></A>
  +<P>
   Easier Apache module prototyping because with the DSO/apxs pair you can
   both work outside the Apache source tree and only need an apxs
   -i command followed by an apachectl&nbsp;restart to bring a new version of your currently developed module into the running
   Apache server.
   
   </UL>
  -<P><A NAME="anchor217"></A>
  +<P>
   Cons:
   
   <UL>
   <P><LI>
  -<P><A NAME="anchor218"></A>
  +<P>
   The DSO mechanism cannot be used on every platform because not all
   operating systems support dynamic loading of code into the address space of
   a program.
   
   <P><LI>
  -<P><A NAME="anchor219"></A>
  -The server is approximately 20% slower at startup time because of the
  -symbol resolving overhead the Unix loader now has to do.
  +<P>
  +The server starts up approximately 20% slower because of the symbol
  +resolving overhead the Unix loader now has to do.
   
   <P><LI>
  -<P><A NAME="anchor220"></A>
  -The server is approximately 5% slower at execution time under some
  -platforms because position independent code (PIC) sometimes needs
  -complicated assembler tricks for relative addressing which are not
  -necessarily as fast as absolute addressing.
  +<P>
  +The server runs approximately 5% slower on some platforms because position
  +independent code (PIC) sometimes needs complicated assembler tricks for
  +relative addressing which are not necessarily as fast as absolute
  +addressing.
   
   <P><LI>
  -<P><A NAME="anchor221"></A>
  +<P>
   Because DSO modules cannot be linked against other DSO-based libraries (ld
   -lfoo) on all platforms (for instance a.out-based platforms usually don't
   provide this functionality while ELF-based platforms do) you cannot use the
  @@ -1309,77 +1490,103 @@
   as DSO files are restricted to only use symbols from the Apache core, from
   the C library (libc) and all other dynamic or static libraries used by the
   Apache core, or from static library archives (libfoo.a) containing position
  -independent code. The only chances to use other code is to either make sure
  -the Apache core itself already contains a reference to it, loading the code
  -yourself via <CODE>dlopen()</CODE> or enabling the SHARED_CHAIN rule while
  -building Apache when your platform supports linking DSO files against DSO
  -libraries.
  +independent code. The only way you can use other code is to either make
  +sure the Apache core itself already contains a reference to it, loading the
  +code yourself via <CODE>dlopen()</CODE> or enabling the SHARED_CHAIN rule
  +while building Apache when your platform supports linking DSO files against
  +DSO libraries.
   
   <P><LI>
  -<P><A NAME="anchor222"></A>
  +<P>
   Under some platforms (many SVR4 systems) there is no way to force the
   linker to export all global symbols for use in DSO's when linking the
   Apache httpd executable program. But without the visibility of the Apache
   core symbols no standard Apache module could be used as a DSO. The only
  -chance here is to use the SHARED_CORE feature because this way the global
  -symbols are forced to be exported. As a consequence the Apache
  +workaround here is to use the SHARED_CORE feature because this way the
  +global symbols are forced to be exported. As a consequence the Apache
   src/Configure script automatically enforces SHARED_CORE on these platforms
   when DSO features are used in the Configuration file or on the configure
   command line.
   
   </UL>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -	     The <a href="http://www.modperl.com/">
  -	     <B>Writing Apache Modules with Perl and C</B></a>
  -	     book can be purchased online from <a
  -	     href="http://www.ora.com/catalog/wrapmod/">O'Reilly </a>
  -	     and <a
  -	     href="http://www.amazon.com/exec/obidos/ASIN/156592567X/writinapachemodu">
  -	     Amazon.com</a>.
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   
  -	     <HR>
   
  -	     <B>Your corrections of either technical or grammatical
  +    <p>
  +    <div class="navbar">
  +      <a href="control.html">Prev</a>                                 |
  +      <A HREF="index.html"         >Contents</A> |
  +      <A HREF="index.html#search"  >Search</A>   |
  +      <A HREF="index.html#download">Download</A> |
  +      <a href="scenario.html">Next</a>
  +    </div>
  +    <p>
  +
  +    <table width="60%" align="center">
  +
  +      <tr>
  +	<td>
  +	  <div class="notice">
  +	  <B>Your corrections of the technical and grammatical
   	     errors are very welcome. You are encouraged to help me
  -	     to improve this guide.  If you have something to
  -	     contribute please <A
  -	     HREF="help.html#Contacting_me"> send it
  +	     improve this guide.  If you have something to contribute
  +	     please <A HREF="help.html#Contacting_me"> send it
   	     directly to me</A>.</B>
  +	  </div>
  +	</td>
  +      </tr>
  +
  +      <tr>
  +	<td>
  +	  <div class="ad">
  +	    The <a href="http://www.modperl.com/">
  +	      <B>Writing Apache Modules with Perl and C</B></a>
  +	    book can be purchased online from <a
  +	      href="http://www.ora.com/catalog/wrapmod/">O'Reilly </a>
  +	    and <a
  +	    href="http://www.amazon.com/exec/obidos/ASIN/156592567X/writinapachemodu">
  +	      Amazon.com</a>.
  +	  </div>
  +	</td>
  +      </tr>
  +
  +</table>
  +
  +<center>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
  +<table cellspacing=2 cellpadding=2>
  +
  +<tr align=center valign=top>
  +<td align=center valign=center>
  +
  +<b><font size=-1>Written by <a
  +href="help.html#Contacting_me">Stas Bekman</a>.<br> Last Modified at 05/27/2000
  +</font></b>
  +<br>
  +
  +</td>
  +
  +<td>
  +
  +<a href="http://perl.apache.org"><img src="images/mod_perl2.jpg"  border=0 alt="mod_perl icon" border=0 height=59 width=150></a>
  +<br>
  +
  +</td>
  +
  +<td>
  +
  +<font size=-2>Use of the Camel for Perl is <br>
  +a trademark of <a href="http://www.ora.com">O'Reilly &amp; Associates</a>,<br>
  +and is used by permission. </font> 
  +<br>
   
  -	     <HR>
  +</td>
   
  -	     [    <A HREF="control.html">Prev</A> |      <A HREF="index.html">Main Page</A> | <A HREF="scenario.html">Next</A>      ]
  +</tr>
  +</table>
  +</center>
   
  -<CENTER><TABLE CELLSPACING=2 CELLPADDING=2 WIDTH="100%" >
  -<TR ALIGN=CENTER VALIGN=TOP>
  -  <TD ALIGN=CENTER VALIGN=CENTER COLSPAN="3">
  -	     <HR>
  -  </TD>
  -</TR>
  -<TR ALIGN=CENTER VALIGN=TOP>
  -  <TD ALIGN=CENTER VALIGN=CENTER>
  -    <B>
  -      <FONT SIZE=-1>
  -	     Written by <A HREF="help.html#Contacting_me">Stas Bekman</A>.
  -	     <BR>Last Modified at 05/09/2000
  -      </FONT>
  -    </B>
  -  </TD>
  -
  -  <TD>
  -	     <A HREF="http://perl.apache.org"><IMG SRC="images/mod_perl2.jpg" ALT="Mod Perl Icon" BORDER=0 HEIGHT=59 WIDTH=150></A>
  -  </TD>
  -
  -  <TD>
  -    <FONT SIZE=-2>
  -	     Use of the Camel for Perl is <BR>
  -	     a trademark of <A HREF="http://www.ora.com">O'Reilly &amp; Associates</A>,<BR>
  -             and is used by permission. 
  -    </FONT> 
  -  </TD>
  -</TR>
  -</TABLE></CENTER>
  -
  -</BODY>
  -</HTML>
  -	    
  \ No newline at end of file
  +</body>
  +</html>
  
  
  
  1.5       +63 -24    modperl-site/guide/style.css
  
  Index: style.css
  ===================================================================
  RCS file: /home/cvs/modperl-site/guide/style.css,v
  retrieving revision 1.4
  retrieving revision 1.5
  diff -u -r1.4 -r1.5
  --- style.css	2000/05/12 22:42:55	1.4
  +++ style.css	2000/06/07 22:45:37	1.5
  @@ -1,30 +1,69 @@
   
  -BODY {	font-family: helvetica, arial, sans-serif; 
  +body {	font-family: helvetica, arial, sans-serif; 
   	color: #000000; 
  -	background-color: #ffffff;
  +	background-color: #ffffee;
  +	margin: 1em 4em;
  +     }	
  +
  +
  +h1, h2, h3 { color: #005A9C }  
  +h1, h2, h3, h4, h5, h6  { 
  +	font-family: helvetica, arial, sans-serif;
  +	}
  +
  +p, div, th, td {font-family: helvetica, arial, sans-serif;}
  +
  +ul, dl, li, dd {font-family: helvetica, arial, sans-serif;}
  +
  +big, small {	font-family: helvetica, arial, sans-serif;}
  +
  +strong, b {	font-family: helvetica, arial, sans-serif;}
  +
  +em, i {		font-family: helvetica, arial, sans-serif;}
  +
  +a:link {	font-family: helvetica, arial, sans-serif;}
  +a:visited {	font-family: helvetica, arial, sans-serif; }
  +a:active {	font-family: helvetica, arial, sans-serif; }
  +a:hover {	font-family: helvetica, arial, sans-serif;}
  +
  +pre { 
  +     	font-family: courier new, courier, monospace;
  +      	color: #000000;
  +    }
  +
  +code { 
  +     	font-family: courier new, courier, monospace;
  +    }
  +
  +div.notice { 
  +	align: center;
  +	padding: .25em; 
  +	border: dashed green;
  +}
  +
  +div.ad { 
  +	padding: .25em; 
  +	margin: .25em;
  +	border: dashed red;
  +      	color: #000000;
   }
   
  -H1 {font-family: helvetica, arial, sans-serif;}
  -H2 {font-family: helvetica, arial, sans-serif;}
  -H3 {font-family: helvetica, arial, sans-serif;}
  -H4 {font-family: helvetica, arial, sans-serif;}
  -H5 {font-family: helvetica, arial, sans-serif;}
  -H6 {font-family: helvetica, arial, sans-serif;}
  -
  -P, DIV, TH, TD {font-family: helvetica, arial, sans-serif;}
  -UL, UL, DL, LI, DD {font-family: helvetica, arial, sans-serif;}
  -BIG, SMALL {font-family: helvetica, arial, sans-serif;}
  -STRONG, B {font-family: helvetica, arial, sans-serif;}
  -EM, I {font-family: helvetica, arial, sans-serif;}
  -
  -A { text-decoration: none; }
  -A:link {font-family: helvetica, arial, sans-serif;}
  -A:visited {font-family: helvetica, arial, sans-serif; }
  -A:active {font-family: helvetica, arial, sans-serif; }
  -A:hover {font-family: helvetica, arial, sans-serif;}
  -
  -KBD,PRE { 
  -	color: #333333;
  -	background-color: white;
  +div.navbar { 
  +	align: center;
  +	padding: .25em; 
  +	border: thin dashed blue;
  +      	color: blue;
   }
   
  +div.navbar a {text-decoration: none;}
  +
  +div.toc a {text-decoration: none;}
  +
  +div.search { 
  +	align: center;
  +	padding: .25em; 
  +	border: thin dashed #eeeeee;
  +	background-color: #eeeeee;
  +      	color: black;
  +	width: 70%
  +}
  
  
  
  1.6       +844 -366  modperl-site/guide/troubleshooting.html
  
  Index: troubleshooting.html
  ===================================================================
  RCS file: /home/cvs/modperl-site/guide/troubleshooting.html,v
  retrieving revision 1.5
  retrieving revision 1.6
  diff -u -r1.5 -r1.6
  --- troubleshooting.html	2000/05/12 22:42:55	1.5
  +++ troubleshooting.html	2000/06/07 22:45:37	1.6
  @@ -1,29 +1,37 @@
   <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
  -<HTML>
  -<HEAD>
  -   <TITLE>mod_perl guide: Warnings and Errors Troubleshooting Index</TITLE>
  -   <META NAME="GENERATOR" CONTENT="Pod2HTML [Perl/Linux]">
  -   <META NAME="Author" CONTENT="Stas Bekman">
  -   <META NAME="Description" CONTENT="All Apache/Perl related information: Hints, Guidelines, Scenarios and Troubleshottings">
  -   <META NAME="keywords" CONTENT="mod_perl modperl perl apache cgi webserver speed  fast guide mod_perl apache guide help info faq mod_perl installation cgi troubleshooting help no sex speedup free open source OSS mod_perl apache guide">
  -</HEAD>
  -     <LINK REL=STYLESHEET TYPE="text/css"
  -        HREF="style.css" TITLE="refstyle">
  -     <style type="text/css">
  -     <!-- 
  -        @import url(style.css);
  -     -->
  -     
  -     </style>
  -<BODY BGCOLOR="white">
  +<html>
  +  <head>
  +   <title>mod_perl guide: Warnings and Errors Troubleshooting Index</title>
  +   <meta name="Author" content="Stas Bekman">
  +   <meta name="Description" content="All Apache/Perl related information: Hints, Guidelines, Scenarios and Troubleshottings">
  +   <meta name="keywords" content="mod_perl modperl perl cgi apache webserver speed fast guide mod_perl apache guide help info faq mod_perl installation cgi troubleshooting help no sex speedup free open source OSS mod_perl apache guide">
  +   <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
  +   <meta name="Classification" content="information">
  +   <link href="style.css" rel=stylesheet type="text/css" title="refstyle">
  +  </head>
  +  <body>
  +
  +    <h1 align=center>
  +      <a href="http://perl.apache.org"><img src="images/mod_perl.gif" alt="Mod Perl Icon" border=0 height=30 width=90 align=left></a>
  +      <a href="http://perl.apache.org"><img src="images/mod_perl.gif" alt="Mod Perl Icon" border=0 height=30 width=90 align=right></a>
  +      Warnings and Errors Troubleshooting Index
  +    </h1>
  +    <hr>
  +    <p>
  +    <div class="navbar">
  +      <a href="frequent.html">Prev</a>                                 |
  +      <a href="index.html"         >Contents</a> |
  +      <a href="index.html#search"  >Search</a>   |
  +      <a href="index.html#download">Download</a> |
  +      <a href="correct_headers.html">Next</a>
  +    </div>
  +    <p>
  +
  +    <div class="toc">
  +      
   <A NAME="toc"></A>
  -<H1 ALIGN=CENTER>
  -<A HREF="http://perl.apache.org"><IMG SRC="images/mod_perl.gif" ALT="Mod Perl Icon" BORDER=0 HEIGHT=30 WIDTH=90 ALIGN=LEFT></A>
  -<A HREF="http://perl.apache.org"><IMG SRC="images/mod_perl.gif" ALT="Mod Perl Icon" BORDER=0 HEIGHT=30 WIDTH=90 ALIGN=RIGHT></A>
  -Warnings and Errors Troubleshooting Index</H1>
  -<HR WIDTH="100%">
  -	    [    <A HREF="obvious.html">Prev</A> |      <A HREF="index.html">Main Page</A> | <A HREF="correct_headers.html">Next</A>      ]<HR><!-- INDEX BEGIN -->
  -<P><B><FONT SIZE=-1>Table of Contents:</FONT></B></P>
  +<P><B>Table of Contents:</B></P>
  +
   <UL>
   
   	<LI><A HREF="#General_Advice">General Advice </A>
  @@ -86,174 +94,298 @@
   	</UL>
   
   </UL>
  -<!-- INDEX END -->
   
  +    </div>
  +
  +    [ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
   <HR>
  +    <table width="60%" align="center">
   
  -	     The <a href="http://www.modperl.com/">
  -	     <B>Writing Apache Modules with Perl and C</B></a>
  -	     book can be purchased online from <a
  -	     href="http://www.ora.com/catalog/wrapmod/">O'Reilly </a>
  -	     and <a
  -	     href="http://www.amazon.com/exec/obidos/ASIN/156592567X/writinapachemodu">
  -	     Amazon.com</a>.
  -
  -	     <HR>
  -
  -	       <B>Your corrections of either technical or grammatical
  -	       errors are very welcome. You are encouraged to help me
  -	       to improve this guide.  If you have something to
  -	       contribute please <A
  -	       HREF="help.html#Contacting_me"> send it
  -	       directly to me</A>.
  -	       </B>
  -	       <HR>
  +      <tr>
  +	<td>
  +	  <div class="ad">
  +	    The <a href="http://www.modperl.com/">
  +	      <B>Writing Apache Modules with Perl and C</B></a>
  +	    book can be purchased online from <a
  +	      href="http://www.ora.com/catalog/wrapmod/">O'Reilly </a>
  +	    and <a
  +	    href="http://www.amazon.com/exec/obidos/ASIN/156592567X/writinapachemodu">
  +	      Amazon.com</a>.
  +	  </div>
  +	</td>
  +      </tr>
  +
  +      <tr>
  +	<td>
  +	  <div class="notice">
  +	  <B>Your corrections of the technical and grammatical
  +	     errors are very welcome. You are encouraged to help me
  +	     improve this guide.  If you have something to contribute
  +	     please <A HREF="help.html#Contacting_me"> send it
  +	     directly to me</A>.</B>
  +	  </div>
  +	</td>
  +      </tr>
  +
  +</table>
  +
  +    
  +
  +	    [ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   
  -	      <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<P><A NAME="anchor0"></A>
  +<P>
   <CENTER><H1><A NAME="General_Advice">General Advice</A></H1></CENTER>
  -<P><A NAME="anchor1"></A>
  +<P>
   Perl's warnings mode is immensely helpful in detecting possible problems.
   Make sure you always turn on warnings while you are developing code. See <A HREF="././debug.html#The_Importance_of_Warnings">The Importance of Warnings</A>.
   
  -<P><A NAME="anchor2"></A>
  +<P>
   Enabling <CODE>use diagnostics;</CODE> generally helps you to determine the source of the problem and how to solve
   it. See <A HREF="././debug.html#diagnostics_pragma">diagnostics pragma</A> for more information.
   
  -<P><A NAME="anchor3"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H1><A NAME="Building_and_Installation">Building and Installation</A></H1></CENTER>
  -<P><A NAME="anchor4"></A>
  +<P>
   See <A HREF="././install.html#make_Troubleshooting">make Troubleshooting</A> and
   <A HREF="././install.html#make_test_Troubleshooting">make test Troubleshooting</A>
   
   
   
  -<P><A NAME="anchor5"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H1><A NAME="Configuration_and_Startup">Configuration and Startup</A></H1></CENTER>
  -<P><A NAME="anchor6"></A>
  +<P>
   This section talks about errors reported when you attempt to start the
   server.
   
  -<P><A NAME="anchor7"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="libexec_libperl_so_open_failed_">libexec/libperl.so: open failed: No such file or directory</A></H2></CENTER>
  -<P><A NAME="anchor8"></A>
  +<P>
   If when you run the server you get the following error:
  +
  +<P>
   
  -<P><A NAME="anchor9"></A>
  -<PRE>  libexec/libperl.so: open failed: No such file or directory
  -</PRE>
  -<P><A NAME="anchor10"></A>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  libexec/libperl.so: open failed: No such file or directory</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   The above error seems to indicate that Perl was compiled with a shared
   library. mod_perl does detect this and links the Apache executable to the
   Perl shared library (<EM>libperl.so</EM>).
   
  -<P><A NAME="anchor11"></A>
  +<P>
   First of all make sure you have Perl installed on the machine, and that you
   have <EM>libperl.so</EM> in
   <EM>&lt;perlroot&gt;/&lt;version&gt;/&lt;architecture&gt;/CORE</EM>. For example in <EM>/usr/local/lib/perl5/5.00503/sun4-solaris/CORE</EM>.
   
  -<P><A NAME="anchor12"></A>
  +<P>
   Then make sure that that directory is included in the environment variable <CODE>LD_LIBRARY_PRELOAD</CODE>. Under normal circumstances, Apache should have the path configured at
   compile time, but this way you can override the library path.
   
  -<P><A NAME="anchor13"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="Invalid_command_PerlHandler_">Invalid command 'PerlHandler'...</A></H2></CENTER>
  -<P><A NAME="anchor14"></A>
  -<PRE>  Syntax error on line 393 of /etc/httpd/conf/httpd.conf: Invalid
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  Syntax error on line 393 of /etc/httpd/conf/httpd.conf: Invalid
     command 'PerlHandler', perhaps mis-spelled or defined by a module
  -  not included in the server configuration [FAILED]
  -</PRE>
  -<P><A NAME="anchor15"></A>
  +  not included in the server configuration [FAILED]</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   This can happen when you have a mod_perl enabled Apache compiled with DSO
   (Generally it's an installed RPM or other binary package) but the mod_perl
   module isn't loaded. In this case you have to tell Apache to load mod_perl
   by adding:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor16"></A>
  -<PRE>  AddModule mod_perl.c
  -</PRE>
  -<P><A NAME="anchor17"></A>
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  AddModule mod_perl.c</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   in your config file.
   
  -<P><A NAME="anchor18"></A>
  +<P>
   This can also happen when you try to run a non-mod_perl Apache server using
   the configuration from a mod_perl server.
   
  -<P><A NAME="anchor19"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="RegistryLoader_Translation_of_u">RegistryLoader: Translation of uri [...] to filename failed</A></H2></CENTER>
  -<P><A NAME="anchor20"></A>
  -<PRE>  RegistryLoader: Translation of uri [/home/httpd/perl/test.pl] to filename 
  -                  failed [tried: /home/httpd/docs/home/httpd/perl/test.pl]
  -</PRE>
  -<P><A NAME="anchor21"></A>
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  RegistryLoader: Translation of uri [/home/httpd/perl/test.pl] to filename 
  +                  failed [tried: /home/httpd/docs/home/httpd/perl/test.pl]</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   This warning shows up when <CODE>RegistryLoader</CODE> fails to translate the URI into the corresponding filesystem path. Most
   failures happen when one passes a file path instead of URI. (A reminder:
   <EM>/home/httpd/perl/test.pl</EM> is a file path, while <EM>/perl/test.pl</EM> is a URI). In most cases all you have to do is to pass something that
   <CODE>RegistryLoader</CODE> expects to get - the URI, but there are more complex cases. <CODE>RegistryLoader</CODE>'s man page shows how to handle these cases as well (look for the
   <CODE>trans()</CODE> sub).
   
  -<P><A NAME="anchor22"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="_Apache_pm_failed_to_load_">&quot;Apache.pm failed to load!&quot;</A></H2></CENTER>
  -<P><A NAME="anchor23"></A>
  +<P>
   If your server startup fails with:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor24"></A>
  -<PRE>  Apache.pm failed to load!
  -</PRE>
  -<P><A NAME="anchor25"></A>
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  Apache.pm failed to load!</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   try adding this to <EM>httpd.conf</EM>:
   
  -<P><A NAME="anchor26"></A>
  -<PRE>  PerlModule Apache
  -</PRE>
  -<P><A NAME="anchor27"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  PerlModule Apache</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H1><A NAME="Code_Parsing_and_Compilation">Code Parsing and Compilation</A></H1></CENTER>
  -<P><A NAME="anchor28"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="Value_of_x_will_not_stay_shared">Value of $x will not stay shared at - line 5</A></H2></CENTER>
  -<P><A NAME="anchor29"></A>
  +<P>
   <A HREF="././perl.html#my_Scoped_Variable_in_Nested_S">my() Scoped Variable in Nested  Subroutines</A>.
   
  -<P><A NAME="anchor30"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="Value_of_x_may_be_unavailable_a">Value of $x may be unavailable at - line 5.</A></H2></CENTER>
  -<P><A NAME="anchor31"></A>
  +<P>
   <A HREF="././perl.html#my_Scoped_Variable_in_Nested_S">my() Scoped Variable in Nested  Subroutines</A>.
   
  -<P><A NAME="anchor32"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="Can_t_locate_loadable_object_for">Can't locate loadable object for module XXX</A></H2></CENTER>
  -<P><A NAME="anchor33"></A>
  +<P>
   There is no object built for this module. e.g. when you see:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor34"></A>
  -<PRE>  Can't locate loadable object for module Apache::Util in @INC...
  -</PRE>
  -<P><A NAME="anchor35"></A>
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  Can't locate loadable object for module Apache::Util in @INC...</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   make sure to give mod_perl's <CODE>Makefile.PL</CODE>  <CODE>PERL_UTIL_API=1</CODE>,
   <CODE>EVERYTHING=1</CODE> or <CODE>DYNAMIC=1</CODE> parameters to enable and build all the components of <CODE>Apache::Util</CODE>.
   
  -<P><A NAME="anchor36"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="Can_t_locate_object_method_get_">Can't locate object method &quot;get_handlers&quot;...</A></H2></CENTER>
  -<P><A NAME="anchor37"></A>
  -<PRE>  Can't locate object method &quot;get_handlers&quot; via package &quot;Apache&quot;
  -</PRE>
  -<P><A NAME="anchor38"></A>
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  Can't locate object method &quot;get_handlers&quot; via package &quot;Apache&quot;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   You need to rebuild your mod_perl with stacked handlers, i.e.
   <CODE>PERL_STACKED_HANDLERS=1</CODE> or more simply <CODE>EVERYTHING=1</CODE>.
   
  -<P><A NAME="anchor39"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="Missing_right_bracket_at_line_">Missing right bracket at line ...</A></H2></CENTER>
  -<P><A NAME="anchor40"></A>
  +<P>
   Most often you will find that you really do have a syntax error. However
   the other reason might be that a script running under
   <CODE>Apache::Registry</CODE> is using &lt;__DATA__&gt; or &lt;__END__&gt; tokens. See
  @@ -261,163 +393,267 @@
   
   
   
  -<P><A NAME="anchor41"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="Can_t_load_auto_DBI_DBI_so_">Can't load '.../auto/DBI/DBI.so' for module DBI</A></H2></CENTER>
  -<P><A NAME="anchor42"></A>
  +<P>
   Check that all your modules are compiled with the same Perl that is
   compiled into mod_perl. Perl 5.005 and 5.004 are not binary compatible by
   default.
   
  -<P><A NAME="anchor43"></A>
  +<P>
   Other known causes of this problem:
   
  -<P><A NAME="anchor44"></A>
  +<P>
   OS distributions that ship with a broken binary Perl installation.
   
  -<P><A NAME="anchor45"></A>
  +<P>
   The `perl' program and `libperl.a' library are somehow built with different
   binary compatibility flags.
   
  -<P><A NAME="anchor46"></A>
  +<P>
   The solution to these problems is to rebuild Perl and any extension modules
   from a fresh source tree. Tip for running Perl's Configure script: use the
   `-des' flags to accepts defaults and `-D' flag to override certain
   attributes:
   
  -<P><A NAME="anchor47"></A>
  -<PRE>  % ./Configure -des -Dcc=gcc ... &amp;&amp; make test &amp;&amp; make install
  -</PRE>
  -<P><A NAME="anchor48"></A>
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  % ./Configure -des -Dcc=gcc ... &amp;&amp; make test &amp;&amp; make install</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Read Perl's INSTALL document for more details.
   
  -<P><A NAME="anchor49"></A>
  +<P>
   Solaris OS specific:
   
  -<P><A NAME="anchor50"></A>
  +<P>
   ``<CODE>Can't load DBI</CODE>'' or similar Error for the IO module or whatever dynamic module mod_perl
   tries to pull in first. The solution is to re-configure, re-build and
   re-install Perl and dynamic modules with the following flags when Configure
   asks for ``<CODE>additional LD flags</CODE>'':
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor51"></A>
  -<PRE>  -Xlinker --export-dynamic
  -</PRE>
  -<P><A NAME="anchor52"></A>
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  -Xlinker --export-dynamic</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   or
   
  -<P><A NAME="anchor53"></A>
  -<PRE>  -Xlinker -E
  -</PRE>
  -<P><A NAME="anchor54"></A>
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  -Xlinker -E</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   This problem is only known to be caused by installing gnu ld under Solaris.
   
  -<P><A NAME="anchor55"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H1><A NAME="Runtime">Runtime</A></H1></CENTER>
  -<P><A NAME="anchor56"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="Preventing_mod_perl_Processes_Fr">Preventing mod_perl Processes From Going Wild</A></H2></CENTER>
  -<P><A NAME="anchor57"></A>
  -See the sections ``<A HREF="././control.html#All_Disk_Space_Consumed">All Disk Space Consumed</A>'' and ``<A HREF="././control.html#All_RAM_Consumed">All RAM Consumed</A>''
  +<P>
  +See the sections ``<A HREF="././control.html#Non_Scheduled_Emergency_Log_Rota">Non-Scheduled Emergency Log Rotation</A>'' and ``<A HREF="././control.html#All_RAM_Consumed">All RAM Consumed</A>''
   
  -<P><A NAME="anchor58"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="Segfaults_when_using_XML_Parser">Segfaults when using XML::Parser</A></H2></CENTER>
  -<P><A NAME="anchor59"></A>
  +<P>
   If you have some of the processes segfault when using <CODE>XML::Parser</CODE>
   you should use
  +
  +<P>
   
  -<P><A NAME="anchor60"></A>
  -<PRE>  --disable-rule=EXPAT
  -</PRE>
  -<P><A NAME="anchor61"></A>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  --disable-rule=EXPAT</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   during the Apache configuration step.
   
  -<P><A NAME="anchor62"></A>
  +<P>
   Starting from mod_perl version 1.23 this option is disabled by default.
   
  -<P><A NAME="anchor63"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="My_CGI_Perl_Code_Gets_Returned_a">My CGI/Perl Code Gets Returned as Plain Text Instead of Being Executed by the Webserver</A></H2></CENTER>
  -<P><A NAME="anchor64"></A>
  +<P>
   See <A HREF="././config.html#My_CGI_Perl_Code_Gets_Returned_a">My CGI/Perl Code Gets Returned as Plain Text Instead of Being Executed by the Webserver</A>.
   
  -<P><A NAME="anchor65"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="Incorrect_line_number_reporting_">Incorrect line number reporting in error/warn log messages</A></H2></CENTER>
  -<P><A NAME="anchor66"></A>
  +<P>
   See <A HREF="#Use_of_uninitialized_value_at_e">Use of uninitialized value at (eval 80) line 12.</A>
   
   
   
  -<P><A NAME="anchor67"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="rwrite_returned_1">rwrite returned -1</A></H2></CENTER>
  -<P><A NAME="anchor68"></A>
  +<P>
   This message happens when the client breaks the connection while your
   script is trying to write to the client. With Apache 1.3.x, you should only
   see the rwrite messages if <CODE>LogLevel</CODE> is set to <CODE>debug</CODE>.
   
  -<P><A NAME="anchor69"></A>
  +<P>
   There was a bug that reported this debug message regardless of the value of <CODE>LogLevel</CODE> directive. It was fixed in mod_perl 1.19_01 (<A HREF="././download.html#mod_perl">CVS version</A>).
   
  -<P><A NAME="anchor70"></A>
  +<P>
   Generally <CODE>LogLevel</CODE> is either <CODE>debug</CODE> or <CODE>info</CODE>.  <CODE>debug</CODE> logs everything, <CODE>info</CODE> is the next level, which doesn't include debug messages. You shouldn't use
   ``debug'' mode on your production server. At the moment there is no way to
   prevent users from aborting connections.
   
  -<P><A NAME="anchor71"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="Can_t_upgrade_that_kind_of_scala">Can't upgrade that kind of scalar ...</A></H2></CENTER>
  -<P><A NAME="anchor72"></A>
  +<P>
   Fixed in mod_perl 1.23.
   
  -<P><A NAME="anchor73"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="caught_SIGPIPE_in_process">caught SIGPIPE in process</A></H2></CENTER>
  -<P><A NAME="anchor74"></A>
  -<PRE>  [modperl] caught SIGPIPE in process 1234
  -  [modperl] process 1234 going to Apache::exit with status...
  -</PRE>
  -<P><A NAME="anchor75"></A>
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  [modperl] caught SIGPIPE in process 1234
  +  [modperl] process 1234 going to Apache::exit with status...</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   That's the <CODE>$SIG{PIPE}</CODE> handler installed by mod_perl/<CODE>Apache::SIG</CODE>, which is called if a connection times out or Client presses the 'Stop'
   button. It gives you an opportunity to do cleanups if the script was
   aborted in the middle of its execution. See <A HREF="././debug.html#Handling_the_User_pressed_Stop_">Handling the 'User pressed Stop button' case</A> for more info.
   
  -<P><A NAME="anchor76"></A>
  +<P>
   If your mod_perl version is earlier than 1.17 you might also get the
   message in the following section...
   
  -<P><A NAME="anchor77"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="Client_hit_STOP_or_Netscape_bit_">Client hit STOP or Netscape bit it!</A></H2></CENTER>
  -<P><A NAME="anchor78"></A>
  -<PRE>  Client hit STOP or Netscape bit it!
  -  Process 2493 going to Apache::exit with status=-2
  -</PRE>
  -<P><A NAME="anchor79"></A>
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  Client hit STOP or Netscape bit it!
  +  Process 2493 going to Apache::exit with status=-2</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   You may see this message in mod_perl versions less than 1.17. See also
   <A HREF="#caught_SIGPIPE_in_process">caught SIGPIPE in process</A>.
   
  -<P><A NAME="anchor80"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="Global_symbol_foo_requires_ex">Global symbol &quot;$foo&quot; requires explicit package name</A></H2></CENTER>
  -<P><A NAME="anchor81"></A>
  +<P>
   The script below will print a warning like that above, moreover it will
   print the whole script as a part of the warning message:
  +
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
   
  -<P><A NAME="anchor82"></A>
  -<PRE>  #!/usr/bin/perl -w
  +	<td>
  +	  <pre>  #!/usr/bin/perl -w
     use strict;
     print &quot;Content-type: text/html\n\n&quot;;
  -  print &quot;Hello $undefined&quot;;
  -</PRE>
  -<P><A NAME="anchor83"></A>
  +  print &quot;Hello $undefined&quot;;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   The warning:
  +
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
   
  -<P><A NAME="anchor84"></A>
  -<PRE>  Global symbol &quot;$undefined&quot; requires 
  +	<td>
  +	  <pre>  Global symbol &quot;$undefined&quot; requires 
     explicit package name at /usr/apps/foo/cgi/tmp.pl line 4.
             eval 'package Apache::ROOT::perl::tmp_2epl;
     use Apache qw(exit);sub handler {
  @@ -448,230 +684,417 @@
     [Sun Nov 15 15:15:30 1998] [error] Goto undefined subroutine 
     &amp;Apache::Constants::SERVER_ERROR at 
     /usr/apps/lib/perl5/site_perl/5.005/aix/Apache/Constants.pm 
  -  line 23.
  -</PRE>
  -<P><A NAME="anchor85"></A>
  +  line 23.</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   The error is simple to fix. When you use the <CODE>use strict;</CODE> pragma (and you should...), Perl will insist that all variables are defined
   before being used, so the error will not arise.
   
  -<P><A NAME="anchor86"></A>
  +<P>
   The bad thing is that sometimes the whole script (possibly, thousands of
   lines) is printed to the <EM>error_log</EM> file as code that the server has tried to <CODE>eval()</CODE>uate.
   
  -<P><A NAME="anchor87"></A>
  +<P>
   May be you have a <CODE>$SIG{__DIE__}</CODE> handler installed (<CODE>Carp::confess()</CODE>?). If so that's what's expected if so.
   
  -<P><A NAME="anchor88"></A>
  +<P>
   You might wish to try something more terse such as "local
   $SIG{__WARN__}&nbsp;=&nbsp;\&Carp::cluck;" The confess method is <EM>very</EM>
   verbose and will tell you more than you might wish to know including full
   source.
   
  -<P><A NAME="anchor89"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="Use_of_uninitialized_value_at_e">Use of uninitialized value at (eval 80) line 12.</A></H2></CENTER>
  -<P><A NAME="anchor90"></A>
  +<P>
   Your code includes some undefined variable that you have used as if it was
   already defined and initialized. For example:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor91"></A>
  -<PRE>  $param = $q-&gt;param('test');
  -  print $param;
  -</PRE>
  -<P><A NAME="anchor92"></A>
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  $param = $q-&gt;param('test');
  +  print $param;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   vs.
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor93"></A>
  -<PRE>  $param = $q-&gt;param('test') || '';
  -  print $param;
  -</PRE>
  -<P><A NAME="anchor94"></A>
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  $param = $q-&gt;param('test') || '';
  +  print $param;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   In the second case, <CODE>$param</CODE> will always be <CODE>defined</CODE>, either
   <CODE>$q-&gt;param('test')</CODE> returns some value or <CODE>undef</CODE>.
   
  -<P><A NAME="anchor95"></A>
  +<P>
   Also read about <A HREF="././debug.html#Finding_the_Line_Which_Triggered">Finding the Line Which Triggered the Error or Warning</A>.
   
  -<P><A NAME="anchor96"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="Undefined_subroutine_Apache_RO">Undefined subroutine &amp;Apache::ROOT::perl::test_2epl::some_function called at</A></H2></CENTER>
  -<P><A NAME="anchor97"></A>
  +<P>
   See <A HREF="././porting.html#Name_collisions_with_Modules_and">Names collisions with Modules and libs</A>.
   
  -<P><A NAME="anchor98"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="Callback_called_exit">Callback called exit</A></H2></CENTER>
  -<P><A NAME="anchor99"></A>
  +<P>
   <EM>Callback called exit</EM> is just a generic message when some unrecoverable error occurs inside Perl
   during <CODE>perl_call_sv()</CODE> (which mod_perl uses to invoke all handler subroutines. Such problems seem
   far less with 5.005_03 than 5.004.
   
  -<P><A NAME="anchor100"></A>
  +<P>
   Sometimes you discover that your server is not responding and its error_log
   has filled up the remaining space on the file system. When you get to see
   the contents of the error_log -- it includes millions of lines, like:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor101"></A>
  -<PRE>  Callback called exit at -e line 33, &lt;HTML&gt; chunk 1.
  -</PRE>
  -<P><A NAME="anchor102"></A>
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  Callback called exit at -e line 33, &lt;HTML&gt; chunk 1.</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Why the looping?
   
  -<P><A NAME="anchor103"></A>
  +<P>
   Perl can get <EM>very</EM> confused inside an endless loop in your code. It doesn't necessarily mean
   that your code did call <CODE>exit()</CODE>. Perl's malloc went haywire and called <CODE>croak()</CODE>, but no memory is left to properly report the error, so Perl is stuck in a
   loop writing that same message to stderr.
   
  -<P><A NAME="anchor104"></A>
  +<P>
   Perl 5.005+ plus is recommended for its improved malloc.c and other
   features that improve mod_perl and are turned on by default.
   
  -<P><A NAME="anchor105"></A>
  +<P>
   See also <A HREF="#Out_of_memory_">Out_of_memory!</A>
   
   
   
  -<P><A NAME="anchor106"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="Out_of_memory_">Out of memory!</A></H2></CENTER>
  -<P><A NAME="anchor107"></A>
  +<P>
   If something goes really wrong with your code, Perl may die with an ``Out
   of memory!'' message and/or ``Callback called exit''. Common causes of this
   are never-ending loops, deep recursion, or calling an undefined subroutine.
   Here's one way to catch the problem: See Perl's INSTALL document for this
   item:
  +
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  =item -DPERL_EMERGENCY_SBRK</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
   
  -<P><A NAME="anchor108"></A>
  -<PRE>  =item -DPERL_EMERGENCY_SBRK
  -</PRE>
  -<P><A NAME="anchor109"></A>
  -<PRE>  If PERL_EMERGENCY_SBRK is defined, running out of memory need not be a
  +	<td>
  +	  <pre>  If PERL_EMERGENCY_SBRK is defined, running out of memory need not be a
     fatal error: a memory pool can allocated by assigning to the special
  -  variable $^M.  See perlvar(1) for more details.
  -</PRE>
  -<P><A NAME="anchor110"></A>
  +  variable $^M.  See perlvar(1) for more details.</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   If you compile with that option and add '<CODE>use Apache::Debug level
   =&gt; 4;</CODE>' to your PerlScript, it will allocate the <CODE>$^M</CODE> emergency pool and the <CODE>$SIG{__DIE__}</CODE> handler will call <CODE>Carp::confess</CODE>, giving you a stack trace which should reveal where the problem is. See
   the <CODE>Apache::Resource</CODE> module for prevention of spinning httpds.
   
  -<P><A NAME="anchor111"></A>
  +<P>
   Note that Perl 5.005 and later have <CODE>PERL_EMERGENCY_SBRK</CODE> turned on by default.
   
  -<P><A NAME="anchor112"></A>
  +<P>
   The other trick is to have a startup script initialize
   <CODE>Carp::confess</CODE>, like so:
   
  -<P><A NAME="anchor113"></A>
  -<PRE>  use Carp ();
  -  eval { Carp::confess(&quot;init&quot;) };
  -</PRE>
  -<P><A NAME="anchor114"></A>
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  use Carp ();
  +  eval { Carp::confess(&quot;init&quot;) };</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   this way, when the real problem happens, <CODE>Carp::confess</CODE> doesn't eat memory in the emergency pool (<CODE>$^M</CODE>).
   
  -<P><A NAME="anchor115"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="server_reached_MaxClients_settin">server reached MaxClients setting, consider raising the MaxClients setting</A></H2></CENTER>
  -<P><A NAME="anchor116"></A>
  +<P>
   See <A HREF="././performance.html#Choosing_MaxClients">Choosing MaxClients</A>.
   
  -<P><A NAME="anchor117"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="syntax_error_at_dev_null_line_1">syntax error at /dev/null line 1, near &quot;line arguments:&quot;</A></H2></CENTER>
  -<P><A NAME="anchor118"></A>
  -<PRE>  syntax error at /dev/null line 1, near &quot;line arguments:&quot;
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  syntax error at /dev/null line 1, near &quot;line arguments:&quot;
     Execution of /dev/null aborted due to compilation errors.
  -  parse: Undefined error: 0
  -</PRE>
  -<P><A NAME="anchor119"></A>
  +  parse: Undefined error: 0</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   There is a chance that your <CODE>/dev/null</CODE> device is broken. Try:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor120"></A>
  -<PRE>  % sudo echo &gt; /dev/null
  -</PRE>
  -<P><A NAME="anchor121"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  % sudo echo &gt; /dev/null</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="Can_t_call_method_register_clea">Can't call method &quot;register_cleanup&quot; (CGI.pm)</A></H2></CENTER>
  -<P><A NAME="anchor122"></A>
  -<PRE>  Can't call method &quot;register_cleanup&quot; on an
  -  undefined value at /usr/lib/perl5/5.00503/CGI.pm line 263.
  -</PRE>
  -<P><A NAME="anchor123"></A>
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  Can't call method &quot;register_cleanup&quot; on an
  +  undefined value at /usr/lib/perl5/5.00503/CGI.pm line 263.</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   caused by this code snippet in <EM>CGI.pm</EM>:
  +
  +<P>
   
  -<P><A NAME="anchor124"></A>
  -<PRE>  if ($MOD_PERL) {
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  if ($MOD_PERL) {
       Apache-&gt;request-&gt;register_cleanup(\&amp;CGI::_reset_globals);
       undef $NPH;
  -  }
  -</PRE>
  -<P><A NAME="anchor125"></A>
  +  }</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   One solution is to add to <EM>httpd.conf</EM>:
  +
  +<P>
   
  -<P><A NAME="anchor126"></A>
  -<PRE>  PerlPostReadRequestHandler 'sub { Apache-&gt;request(shift) }'
  -</PRE>
  -<P><A NAME="anchor127"></A>
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  PerlPostReadRequestHandler 'sub { Apache-&gt;request(shift) }'</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   But even better, switch to <CODE>Apache::Cookie</CODE>:
  +
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
   
  -<P><A NAME="anchor128"></A>
  -<PRE>  use Apache;
  +	<td>
  +	  <pre>  use Apache;
     use Apache::Cookie;
     
     sub handler {
       my $r = shift;
       my $cookies = Apache::Cookie-&gt;new($r)-&gt;parse;
       my %bar = $cookies-&gt;{foo}-&gt;value;
  -  }
  -</PRE>
  -<P><A NAME="anchor129"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +  }</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H1><A NAME="Shutdown_and_Restart">Shutdown and Restart</A></H1></CENTER>
  -<P><A NAME="anchor130"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="Evil_things_might_happen_when_us">Evil things might happen when using PerlFreshRestart</A></H2></CENTER>
  -<P><A NAME="anchor131"></A>
  +<P>
   Unfortunately, not all perl modules are robust enough to survive reload.
   For them this is an unusual situation.  <CODE>PerlFreshRestart</CODE>
   does not much more than:
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor132"></A>
  -<PRE>  while (my($k,$v) = each %INC) {
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  while (my($k,$v) = each %INC) {
       delete $INC{$k};
       require $k;
  -  }
  -</PRE>
  -<P><A NAME="anchor133"></A>
  +  }</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Besides that, it flushes the <CODE>Apache::Registry</CODE> cache, and empties any dynamic stacked handlers (e.g. <CODE>PerlChildInitHandler</CODE>).
   
  -<P><A NAME="anchor134"></A>
  +<P>
   Lots of SegFaults and other problems were reported by users who had turned <CODE>PerlFreshRestart</CODE>  <STRONG>On</STRONG>. Most of them have gone away when it was turned off. It doesn't mean that
   you shouldn't use it, if it works for you. Just beware of the dragons...
   
  -<P><A NAME="anchor135"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +Note that if you have mod_perl enabled Apache built as DSO and you restart
  +it, the whole Perl interpreter is completely torn down (perl_destruct())and
  +restarted. The value of <CODE>PerlFreshRestart</CODE> is irrelevent at this point.
  +
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="Constant_subroutine_XXX_redefine">Constant subroutine XXX redefined</A></H2></CENTER>
  -<P><A NAME="anchor136"></A>
  +<P>
   That's a mandatory warning inside Perl which happens only if you modify
   your script and Apache::Registry reloads it. Perl is warning you that the
   <CODE>subroutine(s)</CODE> were redefined. It is mostly harmless. If you
   don't like seeing these warnings, just <CODE>kill -USR2</CODE> (graceful restart) Apache when you modify your scripts.
   
  -<P><A NAME="anchor137"></A>
  +<P>
   You aren't supposed to see these warnings when if don't modify the code
   with perl 5.004_05 or 5.005+.and higher. If you still experince a problem
   with code within a CGI script, moving all the code into a module (or a
   library) and <CODE>require()ing</CODE> it should solve the problem.
   
  -<P><A NAME="anchor138"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="Can_t_undef_active_subroutine">Can't undef active subroutine</A></H2></CENTER>
  -<P><A NAME="anchor139"></A>
  -<PRE>  Can't undef active subroutine at
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  Can't undef active subroutine at
     /usr/apps/lib/perl5/site_perl/5.005/aix/Apache/Registry.pm line 102.
     Called from package Apache::Registry, filename
  -  /usr/apps/lib/perl5/site_perl/5.005/aix/Apache/Registry.pm, line 102
  -</PRE>
  -<P><A NAME="anchor140"></A>
  +  /usr/apps/lib/perl5/site_perl/5.005/aix/Apache/Registry.pm, line 102</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   This problem is caused when a client drops the connection while httpd is in
   the middle of a write. httpd times out, sending a SIGPIPE, and Perl (in
   that child) is stuck in the middle of its eval context. This is fixed by
  @@ -679,10 +1102,11 @@
   unless you have code that is messing with <STRONG>$SIG{PIPE}</STRONG>. It's also triggered only when you've changed your script on disk and
   mod_perl is trying to reload it.
   
  -<P><A NAME="anchor141"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="_warn_child_process_30388_did_n">[warn] child process 30388 did not exit, sending another SIGHUP</A></H2></CENTER>
  -<P><A NAME="anchor142"></A>
  +<P>
   From mod_perl.pod: With Apache versions 1.3.0 and higher, mod_perl will
   call the <CODE>perl_destruct()</CODE> Perl API function during the child
   exit phase. This will cause proper execution of <CODE>END</CODE> blocks found during server startup along with invoking the <CODE>DESTROY</CODE> method on global objects who are still alive. It is possible that this
  @@ -690,96 +1114,150 @@
   restart. If your code does not contain and <CODE>END</CODE> blocks or <CODE>DESTROY</CODE> methods which need to be run during child server shutdown, this destruction
   can be avoided by setting the <CODE>PERL_DESTRUCT_LEVEL</CODE> environment variable to <CODE>-1</CODE>.
   
  -<P><A NAME="anchor143"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="Processes_Get_Stuck_on_Graceful_">Processes Get Stuck on Graceful Restart</A></H2></CENTER>
  -<P><A NAME="anchor144"></A>
  +<P>
   If you see a process stuck in ``G'' (Gracefully finishing) after a doing a
   graceful restart (sending kill&nbsp;-SIGUSR1) it means that the process is hanging in <CODE>perl_destruct()</CODE>
   while trying to cleanup. This cleanup normally isn't a requirement, you can
  -disable it by setting the <A HREF="././debug.html#PERL_DESTRUCT_LEVEL_Environment_">PERL_DESTRUCT_LEVEL environment variable</A> to -1.
  +disable it by setting the PERL_DESTRUCT_LEVEL environment variable to -1.
  +See the section ``<A HREF="././control.html#Speeding_up_the_Apache_Terminati">Speeding up the Apache Termination and Restart</A>'' for more information.
   
  -<P><A NAME="anchor145"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H1><A NAME="Windows_OS_specific_notes">Windows OS specific notes</A></H1></CENTER>
  -<P><A NAME="anchor146"></A>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H2><A NAME="Apache_DBI">Apache::DBI</A></H2></CENTER>
  -<P><A NAME="anchor147"></A>
  +<P>
   <CODE>Apache::DBI</CODE> causes the server to exit when it starts up, with:
   
  -<P><A NAME="anchor148"></A>
  -<PRE>  [Mon Oct 25 15:06:11 1999] file .\main\http_main.c, line 5890,
  -  assertion &quot;start_mutex&quot; failed
  -</PRE>
  -<P><A NAME="anchor149"></A>
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  [Mon Oct 25 15:06:11 1999] file .\main\http_main.c, line 5890,
  +  assertion &quot;start_mutex&quot; failed</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   Solution: build mod_perl with <CODE>PERL_STARTUP_DONE_CHECK</CODE> set (e.g. insert
  +
  +<P>
  +
  +    <table>
  +      <tr>
   
  -<P><A NAME="anchor150"></A>
  -<PRE>  #define PERL_STARTUP_DONE_CHECK 1
  -</PRE>
  -<P><A NAME="anchor151"></A>
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  #define PERL_STARTUP_DONE_CHECK 1</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   at the top of mod_perl.h or add it to the defines in MSVC++ Options
   dialog).
   
  -<P><A NAME="anchor152"></A>
  +<P>
   Apache loads all Apache modules twice, to make sure the server will
   successfully restart when asked to. This flag disables all
   <CODE>PerlRequire</CODE> and <CODE>PerlModule</CODE> statements on the first load, so they can succeed on the second load.
   Without that flag, the second load fails.
   
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -	     The <a href="http://www.modperl.com/">
  -	     <B>Writing Apache Modules with Perl and C</B></a>
  -	     book can be purchased online from <a
  -	     href="http://www.ora.com/catalog/wrapmod/">O'Reilly </a>
  -	     and <a
  -	     href="http://www.amazon.com/exec/obidos/ASIN/156592567X/writinapachemodu">
  -	     Amazon.com</a>.
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   
  -	     <HR>
   
  -	     <B>Your corrections of either technical or grammatical
  +    <p>
  +    <div class="navbar">
  +      <a href="frequent.html">Prev</a>                                 |
  +      <A HREF="index.html"         >Contents</A> |
  +      <A HREF="index.html#search"  >Search</A>   |
  +      <A HREF="index.html#download">Download</A> |
  +      <a href="correct_headers.html">Next</a>
  +    </div>
  +    <p>
  +
  +    <table width="60%" align="center">
  +
  +      <tr>
  +	<td>
  +	  <div class="notice">
  +	  <B>Your corrections of the technical and grammatical
   	     errors are very welcome. You are encouraged to help me
  -	     to improve this guide.  If you have something to
  -	     contribute please <A
  -	     HREF="help.html#Contacting_me"> send it
  +	     improve this guide.  If you have something to contribute
  +	     please <A HREF="help.html#Contacting_me"> send it
   	     directly to me</A>.</B>
  +	  </div>
  +	</td>
  +      </tr>
  +
  +      <tr>
  +	<td>
  +	  <div class="ad">
  +	    The <a href="http://www.modperl.com/">
  +	      <B>Writing Apache Modules with Perl and C</B></a>
  +	    book can be purchased online from <a
  +	      href="http://www.ora.com/catalog/wrapmod/">O'Reilly </a>
  +	    and <a
  +	    href="http://www.amazon.com/exec/obidos/ASIN/156592567X/writinapachemodu">
  +	      Amazon.com</a>.
  +	  </div>
  +	</td>
  +      </tr>
  +
  +</table>
  +
  +<center>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
  +<table cellspacing=2 cellpadding=2>
  +
  +<tr align=center valign=top>
  +<td align=center valign=center>
  +
  +<b><font size=-1>Written by <a
  +href="help.html#Contacting_me">Stas Bekman</a>.<br> Last Modified at 05/27/2000
  +</font></b>
  +<br>
  +
  +</td>
  +
  +<td>
  +
  +<a href="http://perl.apache.org"><img src="images/mod_perl2.jpg"  border=0 alt="mod_perl icon" border=0 height=59 width=150></a>
  +<br>
  +
  +</td>
  +
  +<td>
  +
  +<font size=-2>Use of the Camel for Perl is <br>
  +a trademark of <a href="http://www.ora.com">O'Reilly &amp; Associates</a>,<br>
  +and is used by permission. </font> 
  +<br>
   
  -	     <HR>
  +</td>
   
  -	     [    <A HREF="obvious.html">Prev</A> |      <A HREF="index.html">Main Page</A> | <A HREF="correct_headers.html">Next</A>      ]
  +</tr>
  +</table>
  +</center>
   
  -<CENTER><TABLE CELLSPACING=2 CELLPADDING=2 WIDTH="100%" >
  -<TR ALIGN=CENTER VALIGN=TOP>
  -  <TD ALIGN=CENTER VALIGN=CENTER COLSPAN="3">
  -	     <HR>
  -  </TD>
  -</TR>
  -<TR ALIGN=CENTER VALIGN=TOP>
  -  <TD ALIGN=CENTER VALIGN=CENTER>
  -    <B>
  -      <FONT SIZE=-1>
  -	     Written by <A HREF="help.html#Contacting_me">Stas Bekman</A>.
  -	     <BR>Last Modified at 05/09/2000
  -      </FONT>
  -    </B>
  -  </TD>
  -
  -  <TD>
  -	     <A HREF="http://perl.apache.org"><IMG SRC="images/mod_perl2.jpg" ALT="Mod Perl Icon" BORDER=0 HEIGHT=59 WIDTH=150></A>
  -  </TD>
  -
  -  <TD>
  -    <FONT SIZE=-2>
  -	     Use of the Camel for Perl is <BR>
  -	     a trademark of <A HREF="http://www.ora.com">O'Reilly &amp; Associates</A>,<BR>
  -             and is used by permission. 
  -    </FONT> 
  -  </TD>
  -</TR>
  -</TABLE></CENTER>
  -
  -</BODY>
  -</HTML>
  -	    
  \ No newline at end of file
  +</body>
  +</html>