perl-modperl-cvs mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From sbek...@locus.apache.org
Subject 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
Date Wed, 07 Jun 2000 22:45:56 GMT
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 th