You are viewing a plain text version of this content. The canonical link for it is here.
Posted to modperl-cvs@perl.apache.org by sb...@hyperreal.org on 1998/12/07 14:03:12 UTC

cvs commit: modperl-site/guide CHANGES all.html config.html control.html debug.html help.html index.html intro.html obvious.html performance.html porting.html scenario.html snippets.html start.html status.html warnings.html

sbekman     98/12/07 05:03:12

  Modified:    guide    config.html control.html debug.html help.html
                        index.html intro.html obvious.html performance.html
                        porting.html scenario.html snippets.html start.html
                        status.html warnings.html
  Added:       guide    CHANGES all.html
  Log:
  * Run a spell check. ispell and WWWebster were quite helpful :)
  
  * Added Richard Dice's notes about ways to see whether or not mod_perl
    is actually compiled into the server and working. "check the
    error_log file" (installation)
  
  * Added 'Is it possible to install mod_perl without root access?'
    section into Server Installtion (scenario) page.
  
  * Added Perrin Harkins and Jonathan Peterson's notes about
    apache/mod_perl/embperl/DBI vs IIS/ASP/ADO
  
  * Added a CHANGES file (this one)
  
  * Added an 'all in one page', suitable for printing. Currently it's
    just an ordered cat(). In the future it might change :)
  
  Revision  Changes    Path
  1.3       +6 -6      modperl-site/guide/config.html
  
  Index: config.html
  ===================================================================
  RCS file: /export/home/cvs/modperl-site/guide/config.html,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- config.html	1998/12/03 21:04:21	1.2
  +++ config.html	1998/12/07 13:03:06	1.3
  @@ -53,7 +53,7 @@
   configure server's configuration files. To learn how to configure the
   apache's config files, please the use the apache's documentation or just
   open the files in conf directory and follow the instructions in these files
  -- they are selfexplainable...
  +- they are self explainable...
   
   <P>
   Before you start configuration of mod_perl, configure the apache, and see
  @@ -101,7 +101,7 @@
   and then to put it back!!!
   
   <P>
  -Ofcourse you can choose any other alias (you will use it later in
  +Of course you can choose any other alias (you will use it later in
   http.conf), you can choose to use all 3 modes or only one of these (It's
   unlikely to run plain cgi-bin scripts from mod_perl server - the price is
   too high, you better run these at plain apache server. See
  @@ -135,7 +135,7 @@
   
   <P>
   <CODE>PerlSendHeader On</CODE> tells the server to send an HTTP header to the browser, on every script
  -envocation. You will want to turn it off for you nph (non-parsed-headers)
  +invocation. You will want to turn it off for you nph (non-parsed-headers)
   scripts.
   
   <P>
  @@ -238,8 +238,8 @@
   <CENTER><H2><A NAME="What_modules_should_you_add_to_t">What modules should you add to the startup file and why.</A></H2></CENTER>
   <P>
   Modules that are being loaded at the server startup will be shared among
  -server childs, so only one copy of each module will be loaded, thus saving
  -a lot of RAM for you. 
  +server children, so only one copy of each module will be loaded, thus
  +saving a lot of RAM for you. 
   
   <P>
   See <A HREF="././performance.html#Preload_Perl_modules_at_server_s">Preload Perl modules at server startup</A> 
  @@ -380,7 +380,7 @@
       <B>
         <FONT SIZE=-1>
   	     Written by <A HREF="mailto:sbekman@iil.intel.com">Stas Bekman</A>.
  -	     <BR>Last Modified at 12/03/98 
  +	     <BR>Last Modified at 12/07/98 
         </FONT>
       </B>
     </TD>
  
  
  
  1.3       +23 -23    modperl-site/guide/control.html
  
  Index: control.html
  ===================================================================
  RCS file: /export/home/cvs/modperl-site/guide/control.html,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- control.html	1998/12/03 21:04:21	1.2
  +++ control.html	1998/12/07 13:03:06	1.3
  @@ -151,7 +151,7 @@
   There are other options for apachectl, use 'help' option to see them all
   
   <P>
  -It's important to understand that this scriptmis based on the PID file
  +It's important to understand that this script is based on the PID file
   which is PIDFILE=/usr/apps/var/httpd_perl/run/httpd.pid. If you delete the
   file by hand - the apachectl will fail to run.
   
  @@ -226,8 +226,8 @@
   Another approach, probably even more practical, is to use the Cool LWP perl
   package , to test the server by trying to fetch some document (script)
   served by the server. Why is it more practical? Since the while server can
  -be up as a process, it can be stucked and not working (SYN_RECV state -
  -anyone???), So failing to get the document will trigger restrart, and
  +be up as a process, it can be stuck and not working (SYN_RECV state -
  +anyone???), So 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>
  @@ -269,7 +269,7 @@
     #  print &quot;Status $status\n&quot;;
     
     my $message = ($status == 0) 
  -   ? &quot;Server was down and sucessfully restarted!&quot; 
  +   ? &quot;Server was down and successfully restarted!&quot; 
      : &quot;Server is down. Can't restart.&quot;;
   </PRE>
   <P>
  @@ -285,7 +285,7 @@
   </PRE>
   <P>
   <PRE>  # input:  URL to check 
  -  # output: 1 if sucess, o for fail  
  +  # output: 1 if success, o for fail  
     #######################  
     sub checkurl{
       my ($url) = @_;
  @@ -324,7 +324,7 @@
   <P>
   <PRE>  &lt;META&gt;
     Is it possible to make the server do something when it dies? e.g
  -  restart itself :) NO, really when it dies , (killed in inproper way?)
  +  restart itself :) NO, really when it dies , (killed in improper way?)
     is it possible to trigger some action?
   </PRE>
   <P>
  @@ -370,7 +370,7 @@
   <P>
   If you are the only developer working on the specific server:port - you
   have no problems, since you have a complete control over the server. Now
  -many times you have a group of developers who need to concurently develop
  +many times you have a group of developers who need to concurrently develop
   their mod_perl scripts. It means that each one will want to get the control
   over the server - to kill it, to run it in single server mode, to restart
   it again and soon. As well to have to control over the log files and other
  @@ -413,9 +413,9 @@
     &lt;/IfDefine&gt;
   </PRE>
   <P>
  -So what we have achived with this technique is: A full control over
  -start/stop, number of childs, separate error log file, and different port.
  -Now I wouldn't get the call every few minutes - ``Stas, I'm going to
  +So what we have achieved with this technique is: A full control over
  +start/stop, number of children, separate error log file, and different
  +port. Now I wouldn't get the call every few minutes - ``Stas, I'm going to
   restart the server''.
   
   <P>
  @@ -430,7 +430,7 @@
     HTTPD='/usr/apps/sbin/httpd_perl/httpd_perl -Dsbekman'
   </PRE>
   <P>
  -Ofcourse you think you can use only one control file and to know who is
  +Of course you think you can use only one control file and to know who is
   calling by using uid, but since you have to be root to start the server -
   it's not so simple. 
   
  @@ -484,13 +484,13 @@
     
   
   <P>
  -Ofcourse you have another problem: The cgi generates some html, which
  -should be called again. If it generates a URL with hardcoded PORT the above
  -scheme will not work. There 2 solutions:
  +Of course you have another problem: The cgi generates some html, which
  +should be called again. If it generates a URL with hard coded PORT the
  +above scheme will not work. There 2 solutions:
   
   <P>
   First to generate relative URL so it will reuse the technique above, with
  -redirect (which is trasparent for user) but it will not work if you have
  +redirect (which is transparent for user) but it will not work if you have
   something to POST (redirect looses all the data!)
   
   <P>
  @@ -510,12 +510,12 @@
   <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>
  -Many times you startoff with debugging your script by running it at your
  +Many times you start off with debugging your script by running it at your
   favorite shell. Sometimes you encounter a very weird situation when script
   runs from the shell but dies when called as cgi. The real problem lays in
   the difference of the environment that's being used by your server and your
   shell. An example can be a different perl path or having PERL5LIB env
  -variable which includes pathes that aren't in the <CODE>@INC</CODE> of the
  +variable which includes paths that aren't in the <CODE>@INC</CODE> of the
   perl compiled with mod_perl server and configured during the startup.
   
   <P>
  @@ -524,8 +524,8 @@
   calling the same perl that it's being used by the server. Then setting the
   environment identical to the server's by copying the perl run directives
   from server startup and config files. It'll also allow you to remove
  -competely the first line of the script - since mod_perl skip it and wrapper
  -knows how to call the script
  +completely the first line of the script - since mod_perl skip it and
  +wrapper knows how to call the script
   
   <P>
   Below is the example of such a script. Note that we force the -wT when we
  @@ -537,7 +537,7 @@
      
     # This is a wrapper example 
      
  -  # It simulates the webserver environment by setting the @INC and other
  +  # It simulates the web server environment by setting the @INC and other
     # stuff, so what will run under this wrapper will run under web and
     # vice versa. 
     
  @@ -583,14 +583,14 @@
     }
     
       # run the cgi from the script's directory
  -    # Note that we envoke warnings and Taintness ON!!!
  +    # Note that we invoke warnings and Taintness ON!!!
     system qq{$basedir/bin/perl -I$PERL5LIB -wT $cgi $params};
   </PRE>
   <P>
   <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 little bit offtopic but good to know.
  +A little bit off topic but good to know.
   
   <P>
   To rotate the logs do:
  @@ -619,7 +619,7 @@
       <B>
         <FONT SIZE=-1>
   	     Written by <A HREF="mailto:sbekman@iil.intel.com">Stas Bekman</A>.
  -	     <BR>Last Modified at 12/03/98 
  +	     <BR>Last Modified at 12/07/98 
         </FONT>
       </B>
     </TD>
  
  
  
  1.3       +2 -2      modperl-site/guide/debug.html
  
  Index: debug.html
  ===================================================================
  RCS file: /export/home/cvs/modperl-site/guide/debug.html,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- debug.html	1998/12/03 21:04:21	1.2
  +++ debug.html	1998/12/07 13:03:06	1.3
  @@ -49,7 +49,7 @@
   <PRE>  d - Trace directive handling during configuration read
     s - Trace processing of perl sections
     h - Trace Perl*Handler callbacks
  -  g - Trace global variable handling, intepreter construction, END blocks, etc.
  +  g - Trace global variable handling, interpreter construction, END blocks, etc.
     all - all of the above
   </PRE>
   <P>
  @@ -72,7 +72,7 @@
       <B>
         <FONT SIZE=-1>
   	     Written by <A HREF="mailto:sbekman@iil.intel.com">Stas Bekman</A>.
  -	     <BR>Last Modified at 12/03/98 
  +	     <BR>Last Modified at 12/07/98 
         </FONT>
       </B>
     </TD>
  
  
  
  1.4       +9 -7      modperl-site/guide/help.html
  
  Index: help.html
  ===================================================================
  RCS file: /export/home/cvs/modperl-site/guide/help.html,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- help.html	1998/12/07 04:17:14	1.3
  +++ help.html	1998/12/07 13:03:07	1.4
  @@ -101,15 +101,17 @@
   <LI>mod_perl mailing list</LI>
   
   
  -<P>The Apache/Perl mailing list (modperl@apache.org) <B>is available for
  -mod_perl users and developers to share ideas, solve problems and discuss
  -things related to mod_perl and the Apache::* modules.</B> To subscribe
  -to this list, send mail to <a href="mailto:majordomo@apache.org">majordomo@apache.org</a>
  -with the string &quot;subscribe modperl&quot; in the body. </P>
  +<P>The Apache/Perl mailing list (modperl@apache.org) <B>is available
  +for mod_perl users and developers to share ideas, solve problems and
  +discuss things related to mod_perl and the Apache::* modules.</B> To
  +subscribe to this list, send mail to <a
  +href="mailto:majordomo@apache.org">majordomo@apache.org</a> with the
  +string &quot;subscribe modperl&quot; in the body. </P>
   
   
  -<P><B>Searchable </B>mod_perl mailing list<B> <A HREF="http://forum.swarthmore.edu/epigone/modperl">archive</A>
  -</B>by Ken Williams. </P>
  +<P><B>Searchable </B>mod_perl mailing list<A
  +HREF="http://forum.swarthmore.edu/epigone/modperl"><B>archive</B></A>by
  +Ken Williams. </P>
   </UL>
   
   
  
  
  
  1.3       +10 -2     modperl-site/guide/index.html
  
  Index: index.html
  ===================================================================
  RCS file: /export/home/cvs/modperl-site/guide/index.html,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- index.html	1998/12/03 21:04:22	1.2
  +++ index.html	1998/12/07 13:03:07	1.3
  @@ -15,7 +15,7 @@
   to your perl cgi-bin scripts.</B></P></CENTER>
   
   
  -<CENTER><P><B>Version 1.00  Dec, 3 1998</B></P></CENTER>
  +<CENTER><P><B>Version 1.01  Dec, 7 1998</B></P></CENTER>
   
   
   <P>
  @@ -62,7 +62,15 @@
   <LI><A HREF="snippets.html">Code Snippets</A></LI>
   
   
  -<LI><A HREF="help.html">Help. Futher Learning.</A></LI>
  +<LI><A HREF="help.html">Help. Further Learning.</A></LI>
  +
  +
  +<LI><A HREF="all.html">Guide All in One. Ready for Printing</A></LI>
  +
  +
  +<LI><A HREF="CHANGES">CHANGES</A></LI>
  +
  +
   </UL>
   
   
  
  
  
  1.4       +9 -8      modperl-site/guide/intro.html
  
  Index: intro.html
  ===================================================================
  RCS file: /export/home/cvs/modperl-site/guide/intro.html,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- intro.html	1998/12/07 04:17:14	1.3
  +++ intro.html	1998/12/07 13:03:07	1.4
  @@ -30,7 +30,7 @@
   <LI><A HREF="#2">What is covered in this document</A></LI>
   
   
  -<LI><A HREF="#3">Sources and Acknowlegements</A></LI>
  +<LI><A HREF="#3">Sources and Acknowledgments</LI>
   </UL>
   
   
  @@ -68,7 +68,7 @@
   does mod_perl give?&quot;. Well, it all depends on what you're doing with
   mod_perl and possibly who you ask. People report speed boosts from 200%
   to 2000%.&nbsp;The best way to measure is to try it and see for yourself!
  -(see <A HREF="http://perl.apache.org/tidbits.html">TidBits </A>and <A HREF="http://perl.apache.org/stories/">Stories
  +(see <A HREF="http://perl.apache.org/tidbits.html">Tidbit </A>and <A HREF="http://perl.apache.org/stories/">Stories
   </A>pages for the facts)</P>
   
   
  @@ -79,10 +79,10 @@
   <H3 ALIGN=CENTER><A NAME="2"></A>What is covered in this document</H3>
   
   
  -<P>This document was writtten to help you to start using the mod_perl as
  +<P>This document was written to help you to start using the mod_perl as
   soon as possible and with as less as possible obstacles. It includes an
   information about installation and configuration of perl and apache
  -webserver and goes deeply into an issues of writing and porting the perl
  +web server and goes deeply into an issues of writing and porting the perl
   scripts for mod_perl. Note, that it doesn't enter the big world of using
   the Perl API or C API. You will find the Pointers covering these topics at
   <A HREF="help.html">Help Seek and Learning more</A> section of this document.<B>
  @@ -94,7 +94,7 @@
   (If you don't just read the INSTALL docs coming with distribution of each
   package). However you will find in the document specific perl and
         apache related installation and
  -configuration notes, which will help you to sucessfuly 
  +configuration notes, which will help you to successfully 
   complete the mod_perl installation.</P>
   
   
  @@ -120,7 +120,7 @@
   <HR WIDTH="100%"></P>
   
   
  -<H3 ALIGN=CENTER><A NAME="3"></A>Sources and Acknowledgements</H3>
  +<H3 ALIGN=CENTER><A NAME="3"></A>Sources and Acknowledgments</H3>
   
   
   <P>This document is based on:</P>
  @@ -152,6 +152,7 @@
   href="http://perl.apache.org/src/mod_perl-1.16/SUPPORT">SUPPORT</a>
   file in the distribution)</LI>
   
  +
   <LI>My personal experience with mod_perl</LI>
   </UL>
   
  @@ -159,7 +160,7 @@
   <P>As I said, I've quoted many information snippets from FAQs and emails,
         and I didn't credit people after each quote in the guide. I didn't mean to
         take the credits for myself, it's just that I've tried to keep
  -      track of names, and became lost, so I prefered not to credit at
  +      track of names, and became lost, so I preferred not to credit at
         all in the guide, but to centralize it here. If you think that
         you want your name to show up under your original quote that I
         have used, please tell me and I'll add it for you.<P>
  @@ -199,7 +200,7 @@
   <P>I&nbsp;want to thank all the people who donated their time and efforts
   to made this amazing idea of mod_perl to become reality. It includes Doug
   MacEachern, the author of mod_perl and all the developers who contributed
  -bug patches, modules and help. And ofcourse the numeral unseen users who
  +bug patches, modules and help. And of course the numeral unseen users who
   helped to find the bugs and advocate mod_perl around the world.</P>
   
   
  
  
  
  1.3       +17 -17    modperl-site/guide/obvious.html
  
  Index: obvious.html
  ===================================================================
  RCS file: /export/home/cvs/modperl-site/guide/obvious.html,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- obvious.html	1998/12/03 21:04:22	1.2
  +++ obvious.html	1998/12/07 13:03:07	1.3
  @@ -102,13 +102,13 @@
   <CODE>&amp;y</CODE> is called only from inside &amp;x.
   
   <P>
  -(this was partitially extracted from perl5-porters post)
  +(this was partially extracted from perl5-porters post)
   
   <P>
   Now hold on, you ask what it has to do with your cgi script?
   
   <P>
  -That's exactly the point that is not obvous. Apache::Registry wraps your
  +That's exactly the point that is not obvious. Apache::Registry wraps your
   code into a sub! You heard it right. So all your code's subs are nested.
   And while you don't see it, your code actually is the same as the simple
   snippet above. And all the behavior described above applies to your code!
  @@ -157,16 +157,16 @@
   When you develop your plain cgi scripts you just change the code, and rerun
   the cgi in your browser. Since the script wasn't staying in the memory, the
   next time you call it - server recompile it from scratch so all the changes
  -you apply are immediatley taking the expected effect.
  +you apply are immediately taking the expected effect.
   
   <P>
   The situation is different with Apache::Registry. Since the whole idea was
   to get the maximum performance from the server. By default server wouldn't
   spend the time to go and check whether the code has been changed. It
  -assumes that it wasn't, thus saving a few milisecs to stat the file (And if
  -you have many of them it takes more time). The only check that is being
  +assumes that it wasn't, thus saving a few millisecs to stat the file (And
  +if you have many of them it takes more time). The only check that is being
   done is whether your main script has been changed. So if you have only one
  -script that doesn't requre or use other Perl Modules (packages) there is
  +script that doesn't require or use other Perl Modules (packages) there is
   nothing new about it. The files you <CODE>use()</CODE> or
   <CODE>require()</CODE> aren't being checked at all. So what are the
   workarounds?
  @@ -343,7 +343,7 @@
   text to ensure the match succeeds, you have two possibilities.
   
   <P>
  -If you can guaranteee that the pattern variable contains no meta-characters
  +If you can guarantee that the pattern variable contains no meta-characters
   (things like *, +, ^, $...), you can use the dummy match:
   
   <P>
  @@ -361,8 +361,8 @@
   Phil. Chu contributed this:
   
   <P>
  -It depends on the complexity of the regex you apply this technique to. One
  -common usage where compiled regex is usually more efficient is to ``match
  +It depends on the complexity of the regexp you apply this technique to. One
  +common usage where compiled regexp is usually more efficient is to ``match
   any one of a group of patterns'' over and over again.
   
   <P>
  @@ -428,14 +428,14 @@
   multiply server environment will result in something like 1,9,4,19 (number
   per reload), since ``each'' time your script will be served by a different
   child. (On some OSes parent process assign all the requests to the same
  -child process if all of the childs are idle... AIX...). But if you run in
  +child process if all of the children are idle... AIX...). But if you run in
   httpd -X single server mode you will get 2,3,4,5... (taken that the
   <CODE>random()</CODE> returned 1 at the first call)
   
   <P>
   But don't get too obsessive with this mode, since working only in single
  -server mode sometimes hides problems that show up when you switch to
  -multiserver mode. Assume the following code:
  +server mode sometimes hides problems that show up when you switch to multi
  +server mode. Assume the following code:
   
   <P>
   Application that allows you to change the configuration at the run time.
  @@ -445,12 +445,12 @@
   disk). So you have typed in a new color , and as a respond you print back
   the html with a new color - you think that's it! It was so simple. And if
   you keep running in single server mode you will never notice that you have
  -a problem... If you run the same code in the multiserver environment ,
  +a problem... If you run the same code in the multi server environment ,
   after you submit the color change you will get the result as expected, but
   when you will call the same URL again (not reload!) most of the chances
   that you will get back the old color, since except the child who processed
   the color change request no one knows about their global variable change.
  -Just remember that childs can't share information, but the stuff they
  +Just remember that children can't share information, but the stuff they
   inherited from parent on their load.
   
   <P>
  @@ -465,8 +465,8 @@
   Under mod_perl files that have been created after the server's (child?)
   startup are being reported with negative age with -M (-C -A) test. This is
   obvious if you remember that you will get the negative result if the server
  -was started before the file was created and it's a normal behaviour with
  -any perl.
  +was started before the file was created and it's a normal behavior with any
  +perl.
   
   <P>
   If you want to have -M test to count the time relative to the current
  @@ -487,7 +487,7 @@
       <B>
         <FONT SIZE=-1>
   	     Written by <A HREF="mailto:sbekman@iil.intel.com">Stas Bekman</A>.
  -	     <BR>Last Modified at 12/03/98 
  +	     <BR>Last Modified at 12/07/98 
         </FONT>
       </B>
     </TD>
  
  
  
  1.3       +94 -12    modperl-site/guide/performance.html
  
  Index: performance.html
  ===================================================================
  RCS file: /export/home/cvs/modperl-site/guide/performance.html,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- performance.html	1998/12/03 21:04:23	1.2
  +++ performance.html	1998/12/07 13:03:07	1.3
  @@ -25,10 +25,11 @@
   	<LI><A HREF="#Reducing_the_Memory_Usage">Reducing the Memory Usage</A>
   	<LI><A HREF="#Limiting_the_size_of_the_process">Limiting the size of the processes</A>
   	<LI><A HREF="#Limiting_the_resources_used_by_h">Limiting the resources used by httpd children</A>
  -	<LI><A HREF="#Benchmarks_Impressing_your_Boss">Benchmarks. Impressing your Boss and Collegues.</A>
  +	<LI><A HREF="#Benchmarks_Impressing_your_Boss">Benchmarks. Impressing your Boss and Colleagues.</A>
   	<UL>
   
  -		<LI><A HREF="#Benchmarking_a_Graphic_hits_coun">Benchmarking a Graphic hits counter with Persistant DB Connection</A>
  +		<LI><A HREF="#Developers_Talk">Developers Talk</A>
  +		<LI><A HREF="#Benchmarking_a_Graphic_hits_coun">Benchmarking a Graphic hits counter with Persistent DB Connection</A>
   		<LI><A HREF="#Benchmarking_scripts_with_execut">Benchmarking scripts with execution times below 1 second :)</A>
   		<LI><A HREF="#PerlHandler_s_Benchmarking">PerlHandler's Benchmarking</A>
   	</UL>
  @@ -196,7 +197,7 @@
   
   <P>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<CENTER><H1><A NAME="Benchmarks_Impressing_your_Boss">Benchmarks. Impressing your Boss and Collegues.</A></H1></CENTER>
  +<CENTER><H1><A NAME="Benchmarks_Impressing_your_Boss">Benchmarks. Impressing your Boss and Colleagues.</A></H1></CENTER>
   <P>
   How much faster is mod_perl that CGI? There are many ways to benchmark the
   two. See a few examples and numbers below, also checkout the benchmark/
  @@ -208,7 +209,7 @@
   
   <P>
   There is no need to write a special benchmark, if you want to impress your
  -boss or collegues, just take the heaviest cgi script you have, open 2
  +boss or colleagues, just take the heaviest cgi script you have, open 2
   xterms and call the same script in mod_perl mode in one xterm and in
   mod_cgi mode in the other. You can use lwp-get from LWP package to emulate
   the web agent (browser). (benchmark/ directory of mod_perl dist includes
  @@ -216,8 +217,88 @@
   
   <P>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<CENTER><H2><A NAME="Benchmarking_a_Graphic_hits_coun">Benchmarking a Graphic hits counter with Persistant DB Connection</A></H2></CENTER>
  +<CENTER><H2><A NAME="Developers_Talk">Developers Talk</A></H2></CENTER>
   <P>
  +Perrin Harkins writes on benchmarks or comparisons, official or unofficial:
  +
  +<BLOCKQUOTE>
  +
  +<P>
  +I have used some of the platforms you mentioned and researched others. What
  +I can tell you for sure, is that no commercially available system offers
  +the depth, power, and ease of use that mod_perl has. Either they don't let
  +you access the web server internals, or they make you use less productive
  +languages than Perl, sometimes forcing you into restrictive and confusing
  +APIs and/or GUI development environments. None of them offer the level of
  +support available from simply posting a message to this list, at any price.
  +
  +<P>
  +As for performance, beyond doing several important things (code-caching,
  +pre-forking/threading, and persistent database connections) there isn't
  +much these tools can do, and it's mostly in your hands as the developer to
  +see that the things which really take the time (like database queries) are
  +optimized.
  +
  +<P>
  +The downside of all this is that most manager types seem to be unable to
  +believe that web development software available for free could be better
  +than the stuff that cost $25,000 per CPU. This appears to be the major
  +reason most of the web tools companies are still in business. They send a
  +bunch of suits to give PowerPoint presentations and hand out glossy
  +literature to your boss, and you end up with an expensive disaster and an
  +approaching deadline.
  +
  +<P>
  +But I'm not bitter or anything...
  +
  +</BLOCKQUOTE>
  +
  +<P>
  +Jonathan Peterson adds:
  +
  +<BLOCKQUOTE>
  +
  +<P>
  +Most of the major solutions have something that they do better than the
  +others, and each of them has faults. Microsofts ASP has a very nice objects
  +model, and has IMO the best data access object (better than DBI to use -
  +but less portable) It has the worst scripting language. PHP has many of the
  +advantages of Perl-based solutions, but is less complicated for developers.
  +Netscape's Livewire has a good object model too, and provides good
  +server-side Java integration - if you want to leverage Java skills, it's
  +good. Also, it has a compiled scripting language - which is great if you
  +aren't selling your clients the source code (and a pain otherwise).
  +
  +<P>
  +mod_perl's advantage is that it is the most powerful. It offers the
  +createst degree of control with one of the more powerful languages. It also
  +offers the greatest granularity. You can use an embedding module (eg eperl)
  +from one place, a session module (Session) from another, and your data
  +acces module from yet another.
  +
  +<P>
  +I think the Apache::ASP module looks very promising. It has very easy to
  +use and adequately powerful state maintenance, a good embedding system, and
  +a sensible object model (that emulates the Microsoft ASP one). It doesn't
  +replicate MS's ADO for data access, but DBI is fine for that.
  +
  +<P>
  +I have always found that the developers available make the greatest impact
  +on the decision. If you have a team with no Perl experience, and a small or
  +medium task, using something like PHP, or Microsoft ASP, makes more sense
  +than driving your staff into the vertical learning curve they'll need to
  +use mod_perl.
  +
  +<P>
  +For very large jobs, it may be worth finding the best technical solution,
  +and then recruiting the team with the necessary skills.
  +
  +</BLOCKQUOTE>
  +
  +<P>
  +<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<CENTER><H2><A NAME="Benchmarking_a_Graphic_hits_coun">Benchmarking a Graphic hits counter with Persistent DB Connection</A></H2></CENTER>
  +<P>
   Here are the numbers from Michael Parker's mod_perl presentation at Perl
   Conference (Aug, 98) <A
   HREF="http://www.realtime.net/~parkerm/perl/conf98/index.htm">http://www.realtime.net/~parkerm/perl/conf98/index.htm</A>
  @@ -256,7 +337,7 @@
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
   <CENTER><H2><A NAME="Benchmarking_scripts_with_execut">Benchmarking scripts with execution times below 1 second :)</A></H2></CENTER>
   <P>
  -As noted before for very fast scripts you will ahev to use Time::HiRes
  +As noted before for very fast scripts you will have to use Time::HiRes
   module, it's usage is similar to the Benchmark's.
   
   <P>
  @@ -279,7 +360,7 @@
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
   <CENTER><H1><A NAME="Persistent_DB_Connections">Persistent DB Connections</A></H1></CENTER>
   <P>
  -Another popular use of mod_perl is to take advantage of it's persistance to
  +Another popular use of mod_perl is to take advantage of it's persistence to
   maintain open database connections. The basic idea goes like so:  
   
   <P>
  @@ -296,7 +377,7 @@
   perform <CODE>disconnect().</CODE>
   
   <P>
  -Be carefull to use different names for handlers if you open connection to
  +Be careful to use different names for handlers if you open connection to
   different Databases!
   
   <P>
  @@ -345,7 +426,7 @@
   connections on server startup. This call should be in a startup file
   (PerlModule, &lt;Perl&gt; or PerlRequire). It will establish a connection
   when a child is started in that child process. See the Apache::DBI manpage
  -to see the requrements for this method.
  +to see the requirements for this method.
   
   <P>
   However be warned that some old DBD drivers aren't supporting this feature
  @@ -359,7 +440,7 @@
   
   <P>
   Also some folks at list suggested to change the timeout of the server (they
  -talked specificly about mysql). So starting from 3.22.x you can set a
  +talked specifically about mysql). So starting from 3.22.x you can set a
   wait_timeout option at mysqld server startup to change the default value,
   setting it to 24 hours probably will fix the timeout problem.
   
  @@ -636,7 +717,8 @@
   The Devel::DProf package is a Perl code profiler. This will collect
   information on the execution time of a Perl script and of the subs in that
   script. This information can be used to determine which subroutines are
  -using the most time and which subroutines are being called most often.  <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +using the most time and which subroutines are being called most often.  
  +<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
   <P><A HREF="index.html">[Back to the main page]</A></P>
   
   <CENTER><TABLE CELLSPACING=2 CELLPADDING=2 WIDTH="100%" >
  @@ -650,7 +732,7 @@
       <B>
         <FONT SIZE=-1>
   	     Written by <A HREF="mailto:sbekman@iil.intel.com">Stas Bekman</A>.
  -	     <BR>Last Modified at 12/03/98 
  +	     <BR>Last Modified at 12/07/98 
         </FONT>
       </B>
     </TD>
  
  
  
  1.4       +39 -39    modperl-site/guide/porting.html
  
  Index: porting.html
  ===================================================================
  RCS file: /export/home/cvs/modperl-site/guide/porting.html,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- porting.html	1998/12/07 04:17:14	1.3
  +++ porting.html	1998/12/07 13:03:07	1.4
  @@ -47,7 +47,7 @@
   		<LI><A HREF="#Code_has_been_changed_but_seems">Code has been changed, but seems that script uses the old code</A>
   		<LI><A HREF="#Memory_leakages">Memory leakages</A>
   		<LI><A HREF="#Sometimes_it_works_Sometimes_Not">Sometimes it works Sometimes Not (Very important!)</A>
  -		<LI><A HREF="#The_Script_is_too_dirty_It_does_">The Script is too dirty, It does the job and I can't afford rewriting it.</A>
  +		<LI><A HREF="#The_Script_is_too_dirty_It_does">The Script is too dirty, It does the job and I can't afford rewriting it.</A>
   		<LI><A HREF="#Apache_PerlRun_a_closer_look">Apache::PerlRun - a closer look</A>
   	</UL>
   
  @@ -63,11 +63,11 @@
   
   <P>
   If you are in the porting stage use it as a reference for possible problems
  -you might encounter when running the existant CGI in the new mode.
  +you might encounter when running the existent CGI in the new mode.
   
   <P>
   If you are about to write a new cgi from scratch, it would be a good idea
  -to learn most of the possible pitfalls and to aboid them in first place.
  +to learn most of the possible pitfalls and to avoid them in first place.
   
   <P>
   It covers also the case when the script is too dirty, but does the job and
  @@ -140,7 +140,7 @@
   Just to make things clear before we go into details: each server process
   has its own <CODE>%INC</CODE> array which is used to store the information
   about compiled modules. Where the keys are the names of the modules or
  -parameters passed to <CODE>require().</CODE> And values are the real pathes
  +parameters passed to <CODE>require().</CODE> And values are the real paths
   to these modules. So if you do (assume it's in the <CODE>@INC</CODE> path)
   
   <P>
  @@ -268,7 +268,7 @@
   
   <P><LI>
   <P>
  -Declare a package in the required files! (Ofcourse it should be unique to
  +Declare a package in the required files! (Of course it should be unique to
   the rest of the package names you use!) The <CODE>%INC</CODE> will use the
   package name for the key!
   
  @@ -489,10 +489,10 @@
   it with `#!', you may choose to pass perl switch arguments such as -w or
   -T. Since the command line is only parsed once, when the server starts,
   these switches are unavailable to mod_perl scripts. However, most command
  -line arguments have a perl special variable equivilant. For example, the
  -$^W variable coresponds to the -w switch. Consult perlvar for more details.
  -With mod_perl it is also possible to turn on warnings globaly via the
  -PerlWarn directive:
  +line arguments have a equivalent special variable. For example, the $^W
  +variable corresponds to the -w switch. Consult perlvar for more details.
  +With mod_perl it is also possible to turn on warnings globally via the
  +PerlWarn directive: 
   
   <P>
   <PRE>  PerlWarn On
  @@ -647,11 +647,11 @@
   </PRE>
   <P>
   If you file is of a 5Mb - The child who served that script will grow
  -exectly by that size. Now if you have 20 childs and all of them will serve
  -this cgi, all of them will consume additional 20*5M = 100M of RAM! If
  +exactly by that size. Now if you have 20 children and all of them will
  +serve this cgi, all of them will consume additional 20*5M = 100M of RAM! If
   that's the case try to use other approaches of processing the file, if
  -possible ofcourse. Try to process line at a time and print it back to the
  -file (if you need to modify the file itself, use temperary file for that,
  +possible of course. Try to process line at a time and print it back to the
  +file (if you need to modify the file itself, use temporary file for that,
   when finished overwrite the src file, make sure to provide locking
   mechanism!) 
   
  @@ -661,13 +661,13 @@
   be read before any data processing. Now you have a very nice sub
   <CODE>process()</CODE> that processes the data and returns it back. What
   happens if you pass the <CODE>$content</CODE> by value? You have just
  -copied another 5M and the child growed up by another 5M in size (watch your
  -swap space!) now multiply it again by factor of 10 you have 200M of wasted
  -RAM, which will be apparently reused but it's a waste! Whenever you think
  -the variable can grow bigger than few Kb pass it by reference! Once I wrote
  -the script that passed a content of the little DB to the function and it
  -was OK, but then the DB become huge - I had to make a decision, whether to
  -buy more memory or to rewrite the code. So it's better to plan ahead and
  +copied another 5M and the child has grew up up by another 5M in size (watch
  +your swap space!) now multiply it again by factor of 10 you have 200M of
  +wasted RAM, which will be apparently reused but it's a waste! Whenever you
  +think the variable can grow bigger than few Kb pass it by reference! Once I
  +wrote the script that passed a content of the little DB to the function and
  +it was OK, but then the DB become huge - I had to make a decision, whether
  +to buy more memory or to rewrite the code. So it's better to plan ahead and
   pass the variables by reference. There are few approaches for that:
   
   <P>
  @@ -702,7 +702,7 @@
   From <CODE>perldoc perlsub</CODE>: The array <CODE>@_</CODE> is a local array, but its elements are aliases
   for the actual scalar parameters. In particular, if an element $_[0] is
   updated, the corresponding argument is updated (or an error occurs if it is
  -not updatable).... 
  +not possible to update).... 
   
   <P>
   <STRONG>Third example</STRONG> is work with DataBases. If you do some DB processing, many times you have
  @@ -725,8 +725,8 @@
   </PRE>
   <P>
   In the example above the httpd_process will grow up by the size of the
  -variables that have been alocated for the records that matched the query.
  -(Again remember to multiply it by the number of the childs server runs!)
  +variables that have been allocated for the records that matched the query.
  +(Again remember to multiply it by the number of the children server runs!)
   
   <P>
   What you want to do is to not accumulate the records but print them as they
  @@ -760,7 +760,7 @@
   
   <P>
   Just as a bonus, I wanted to write a single sub that process any query but
  -very flexible, since it accepts: conditions,callback closure sub, select
  +very flexible, since it accepts: conditions, callback closure sub, select
   fields and restrictions. 
   
   <P>
  @@ -809,7 +809,7 @@
   </PRE>
   <P>
   Now a callback closure sub can do lots of things. We need a closure to know
  -what stage are we in: header, body ot tail. For example a callback closure
  +what stage are we in: header, body or tail. For example a callback closure
   for formatting the rows we want to print: 
   
   <P>
  @@ -822,7 +822,7 @@
       my $counter = 0;
       my %cols = (); # columns name=&gt; value hash
    
  -    # Closure with the following behaviour:
  +    # Closure with the following behavior:
       # 1. Header's code will be executed on the first call only and if @_ was set
       # 2. Row's printing code will be executed on every call with @_ set
       # 3. Tail's code will be executed only if Header's code was printed and @_ isn't set
  @@ -880,7 +880,7 @@
   
   <P>
   Generally the problem you have is using global variables. Since global
  -variables don't change from one script envocation to another unless you
  +variables don't change from one script invocation to another unless you
   change it, you can find your scripts do ``fancy'' things.
   
   <P>
  @@ -896,7 +896,7 @@
   simple: Global Variables. You have entered the account of someone who
   happened to be served by the same server child as you, because of the
   sloppiness programming, the global variable was not reset at the beginning
  -of the program and voula you can easily peek into other people emails! You
  +of the program and voila you can easily peek into other people emails! You
   would ask it can't happen, since you have entered the login and passwd. I
   tell you, it happens! See for yourself:
   
  @@ -908,7 +908,7 @@
     authenticate($username,$passwd);
       # failed, break out
     die &quot;Wrong passwd&quot; unless $authenticated == 1;
  -    # user is Ok, fetch user's data
  +    # user is OK, fetch user's data
     show_user($username);
   </PRE>
   <P>
  @@ -921,15 +921,15 @@
   <P>
   Do you see the catch? I can type in any valid username and any dummy passwd
   and enter that's user account, with the code above if someone has
  -sucessfully entered his account before me using the same child process!
  +successfully entered his account before me using the same child process!
   Since <CODE>$authenticated</CODE> is global - if it becomes 1 once it'll be
   1 for the whole child's life!!! The solution is trivial - reset the
   <CODE>$authenticated</CODE> to 0 at the beginning of the program. (Or many
  -other different solution). Ofcourse the example is too trivial - but
  -beleive me it happens!
  +other different solution). Of course the example is too trivial - but
  +believe me it happens!
   
   <P>
  -Just another little one linner that can make your day spoiled, assuming you
  +Just another little one liner that can make your day spoiled, assuming you
   forgot to reset the $allowed. It's perfectly OK in plain mod_cgi :
   
   <P>
  @@ -942,11 +942,11 @@
   <P>
   Another good example is usage of /o in regexp. After you restart the server
   most likely you will not detect the problem, if on every request you will
  -use a different pattern that will be used in regex and it'll happen that
  +use a different pattern that will be used in regexp and it'll happen that
   each time a different child will serve the new request. Only arriving to
  -the child who has already cached the regex will reveal the problem, but
  +the child who has already cached the regexp will reveal the problem, but
   generally you miss that and when you press reload - You see that it works
  -(new fresh child) and then it doesn't (child that already cached the regex
  +(new fresh child) and then it doesn't (child that already cached the regexp
   and wouldn't recompile because of /o). 
   
   <P>
  @@ -957,7 +957,7 @@
   
   <P>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<CENTER><H2><A NAME="The_Script_is_too_dirty_It_does_">The Script is too dirty, It does the job and I can't afford rewriting it.</A></H2></CENTER>
  +<CENTER><H2><A NAME="The_Script_is_too_dirty_It_does">The Script is too dirty, It does the job and I can't afford rewriting it.</A></H2></CENTER>
   <P>
   You still can win from using mod_perl. 
   
  @@ -1006,7 +1006,7 @@
   inside of a subroutine. Scripts will be ``compiled'' on each request. After
   the script has run, it's namespace is flushed of all variables and
   subroutines. Still, you don't have the overhead of loading the perl and
  -compilation time of the standart modules (If your script is very light, but
  +compilation time of the standard modules (If your script is very light, but
   uses lots of standard modules - you will see no difference between
   Apache::PerlRun and Apache::Registry !).
   
  @@ -1074,7 +1074,7 @@
       <B>
         <FONT SIZE=-1>
   	     Written by <A HREF="mailto:sbekman@iil.intel.com">Stas Bekman</A>.
  -	     <BR>Last Modified at 12/03/98 
  +	     <BR>Last Modified at 12/07/98 
         </FONT>
       </B>
     </TD>
  
  
  
  1.3       +53 -5     modperl-site/guide/scenario.html
  
  Index: scenario.html
  ===================================================================
  RCS file: /export/home/cvs/modperl-site/guide/scenario.html,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- scenario.html	1998/12/03 21:04:24	1.2
  +++ scenario.html	1998/12/07 13:03:07	1.3
  @@ -27,6 +27,7 @@
   		<LI><A HREF="#httpd_perl_server_mod_perl_">httpd_perl server (mod_perl):</A>
   	</UL>
   
  +	<LI><A HREF="#Is_it_possible_to_install_mod_pe">Is it possible to install mod_perl without root access?</A>
   </UL>
   <!-- INDEX END -->
   
  @@ -194,8 +195,8 @@
   <PRE>      % mv /usr/apps/sbin/httpd_docs/httpd /usr/apps/sbin/httpd_docs/httpd_docs
   </PRE>
   <P>
  -Now update the apachectl util to point to a new httpd name (by hand or by
  -using perl)
  +Now update the apachectl utility to point to a new httpd name (by hand or
  +by using perl)
   
   <P>
   <PRE>      % perl -p -i -e 's|httpd_docs/httpd|httpd_docs/httpd_docs|' /usr/apps/sbin/httpd_docs/apachectl
  @@ -205,6 +206,18 @@
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
   <CENTER><H2><A NAME="httpd_perl_server_mod_perl_">httpd_perl server (mod_perl):</A></H2></CENTER>
   <P>
  +Before you start to configure the mod_perl, you should be aware that there
  +a few reqired modules that have to be installed before. You will know
  +whether you have all the required installed or not, during the run <CODE>perl Makefile.PL</CODE> below. If you discover that you don't have these, go to your nearest CPAN
  +repository (if you don't know what is it, go to <A
  +HREF="http://www.perl.com/CPAN">http://www.perl.com/CPAN</A> ) or run the
  +interactive shell by
  +<CODE>perl -MCPAN -e shell</CODE> .
  +
  +<P>
  +Now back to installation.
  +
  +<P>
   <PRE>      % cd /usr/apps/usr/src/httpd_perl/apache_1.3.2
         % make clean
         % cd /usr/apps/usr/src/httpd_perl/mod_perl-1.16
  @@ -249,14 +262,49 @@
   <PRE>      % mv /usr/apps/sbin/httpd_perl/httpd /usr/apps/sbin/httpd_perl/httpd_perl
   </PRE>
   <P>
  -now update the apachectl util to point to a new httpd name (by hand or by
  -using perl)
  +now update the apachectl utility to point to a new httpd name (by hand or
  +by using perl)
   
   <P>
   <PRE>      % perl -p -i -e 's|httpd_perl/httpd|httpd_perl/httpd_perl|' /usr/apps/sbin/httpd_perl/apachectl
   </PRE>
   <P>
   Now proceed to <A HREF="././config.html#">Server Configuration</A> section.
  +
  +<P>
  +<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<CENTER><H1><A NAME="Is_it_possible_to_install_mod_pe">Is it possible to install mod_perl without root access?</A></H1></CENTER>
  +<P>
  +Yes, no problem with that. Follow the instructions above and when you
  +encounter APACI_ARGS use your home directory or alike as a prefix (e.g
  +<CODE>/home/stas/www</CODE>) and everything will be installed there. There is a chance that some perl
  +libs will be not installed on your server by root and you will have to
  +install these locally too. See the <A
  +HREF="http://www.esafe.com/stas/TULARC/webmaster/myfaq.html#7">http://www.esafe.com/stas/TULARC/webmaster/myfaq.html#7</A>
  +for more information on local perl installations.
  +
  +<P>
  +You will not be able to set the server to listen to port lower then 1024
  +(if you aren't a root). So pick your port as a number above the 1024. (I
  +use 8080 in most cases). Note that you will have to use the <A
  +HREF="http://www.you.com:8080">http://www.you.com:8080</A> in that case.
  +But it's not a problem since generally users don't access directly the cgi
  +but from the webpage, so they shouldn't know at all that the port is
  +different.
  +
  +<P>
  +You will need to worry to put the start server script into rc.d directory
  +of your machine, so if the last will be rebooted - your webserver will be
  +restarted automatically.
  +
  +<P>
  +One more important thing is Resources, mod_perl is very memory greedy and
  +if you will run lots of mod_perl processes on that machine, most likely
  +your host will ask you to shutdown the mod_perl server, or to find another
  +home. You have a few solutions: <STRONG>a.</STRONG> reduce resource usage - see <A HREF="././performance.html#Limiting_the_size_of_the_process">Limiting the size of the processes</A>  <STRONG>b.</STRONG> ask your ISP if you can put a dedicated machine into their computer room
  +and be root there. <STRONG>c.</STRONG> look for another ISP with lots of resources or one that supports mod_perl
  +(not likely)
  +
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
   <P><A HREF="index.html">[Back to the main page]</A></P>
   
  @@ -271,7 +319,7 @@
       <B>
         <FONT SIZE=-1>
   	     Written by <A HREF="mailto:sbekman@iil.intel.com">Stas Bekman</A>.
  -	     <BR>Last Modified at 12/03/98 
  +	     <BR>Last Modified at 12/07/98 
         </FONT>
       </B>
     </TD>
  
  
  
  1.3       +1 -1      modperl-site/guide/snippets.html
  
  Index: snippets.html
  ===================================================================
  RCS file: /export/home/cvs/modperl-site/guide/snippets.html,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- snippets.html	1998/12/03 21:04:24	1.2
  +++ snippets.html	1998/12/07 13:03:08	1.3
  @@ -63,7 +63,7 @@
       <B>
         <FONT SIZE=-1>
   	     Written by <A HREF="mailto:sbekman@iil.intel.com">Stas Bekman</A>.
  -	     <BR>Last Modified at 12/02/98 
  +	     <BR>Last Modified at 12/07/98 
         </FONT>
       </B>
     </TD>
  
  
  
  1.3       +19 -11    modperl-site/guide/start.html
  
  Index: start.html
  ===================================================================
  RCS file: /export/home/cvs/modperl-site/guide/start.html,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- start.html	1998/12/03 21:04:24	1.2
  +++ start.html	1998/12/07 13:03:08	1.3
  @@ -38,6 +38,7 @@
   	<LI><A HREF="#How_can_I_tell_whether_mod_perl_">How can I tell whether mod_perl is really installed</A>
   	<UL>
   
  +		<LI><A HREF="#Testing_by_checking_the_error_lo">Testing by checking the error_log file</A>
   		<LI><A HREF="#Testing_by_calling_the_perl_sta">Testing by calling the /perl-status </A>
   		<LI><A HREF="#Testing_by_telneting_to_the_port">Testing by telneting to the port server's listening to</A>
   		<LI><A HREF="#Run_a_cgi_that_shows_you_your_se">Run a cgi that shows you your server's environment</A>
  @@ -53,7 +54,7 @@
   <CENTER><H1><A NAME="Coverage">Coverage</A></H1></CENTER>
   <P>
   This sections gets you a quick review of configuration and installation of
  -the required tools. For a kickstart tutorial, whci will allow you make to
  +the required tools. For a kick start tutorial, which will allow you make to
   make copy and paste slick installation, see
   <A HREF="././scenario.html#">Real World Scenario</A>
   
  @@ -122,8 +123,8 @@
   It will be a good idea to try to install the Apache webserver without
   mod_perl first. So later if something going wrong you will know that it's
   not apache's server problem. But you can skip this stage. In any case you
  -have to open the source distribution of apache prefferably at the same
  -level with modperl distribution.
  +have to open the source distribution of apache preferably at the same level
  +with modperl distribution.
   
   <P>
   <PRE>  % ls -l /usr/src
  @@ -185,12 +186,19 @@
   
   <P>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<CENTER><H2><A NAME="Testing_by_checking_the_error_lo">Testing by checking the error_log file</A></H2></CENTER>
  +<P>
  +<PRE>  [Thu Dec  3 17:27:52 1998] [notice] Apache/1.3.1 (Unix) mod_perl/1.15 configured -- resuming normal operations
  +                                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  +</PRE>
  +<P>
  +<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
   <CENTER><H2><A NAME="Testing_by_calling_the_perl_sta">Testing by calling the /perl-status</A></H2></CENTER>
   <P>
   Fetch: <A
   HREF="http://www.yourserver.com/perl-status">http://www.yourserver.com/perl-status</A>
   from your favorite Netscape browser :-) (Assuming you have configured the
  -&lt;Location /perl-status&gt; Section in the server config file (referer to
  +&lt;Location /perl-status&gt; Section in the server config file (refer to
   <A HREF="././config.html#">ModPerlConfiguration</A>)
   
   <P>
  @@ -224,13 +232,13 @@
     Connection closed.
   </PRE>
   <P>
  -So you see <CODE>Server: Apache/1.3.2 (Unix) mod_perl/1.16_01</CODE> - which says that you do have mod_perl installed and it's 1.16_01. Ofcourse
  -in your case it would be the version you have installed.
  +So you see <CODE>Server: Apache/1.3.2 (Unix) mod_perl/1.16_01</CODE> - which says that you do have mod_perl installed and it's 1.16_01. Of
  +course in your case it would be the version you have installed.
   
   <P>
   However, just because you've got it linked in there, that doesn't meant
   that you have your server configured to use mod_perl to handle Perl
  -scripts. You will find the configuaration assistance at
  +scripts. You will find the configuration assistance at
   <A HREF="././config.html#">ModPerlConfiguration</A>
   
   
  @@ -310,8 +318,8 @@
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
   <CENTER><H2><A NAME="with_lwp_request">with lwp-request</A></H2></CENTER>
   <P>
  -Yet another one. Why do I show all these apporoaches? While here they are
  -serving a very simple purpose, they can be helpfull in other situations. 
  +Yet another one. Why do I show all these approaches? While here they are
  +serving a very simple purpose, they can be helpful in other situations. 
   
   <P>
   Assuming you have the libwww-perl package installed (LWP), you will need it
  @@ -336,7 +344,7 @@
   Now you want to writing the cgis. You better start writing it very clean
   and with understanding of the new running environment. You have to learn
   how to write correctly for mod_perl. There is nothing new here, all you
  -have to remember that your script wouldn't die after it finishs to serve
  +have to remember that your script wouldn't die after it finishes to serve
   the request, but will stay in memory and might affect all other scripts
   running under the same server process (child). You will read more about it
   in the following sections: <A HREF="././porting.html#">Writing Mod Perl scripts and Porting plain CGIs</A>
  @@ -355,7 +363,7 @@
       <B>
         <FONT SIZE=-1>
   	     Written by <A HREF="mailto:sbekman@iil.intel.com">Stas Bekman</A>.
  -	     <BR>Last Modified at 12/03/98 
  +	     <BR>Last Modified at 12/07/98 
         </FONT>
       </B>
     </TD>
  
  
  
  1.3       +2 -2      modperl-site/guide/status.html
  
  Index: status.html
  ===================================================================
  RCS file: /export/home/cvs/modperl-site/guide/status.html,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- status.html	1998/12/03 21:04:24	1.2
  +++ status.html	1998/12/07 13:03:08	1.3
  @@ -32,7 +32,7 @@
   <P>
   <CENTER><H1><A NAME="Watching_the_server">Watching the server</A></H1></CENTER>
   <P>
  -Very usefull feature. You can watch what happens to the perl parts of the
  +Very useful feature. You can watch what happens to the perl parts of the
   server. Below you will find the instructions of configuration and usage of
   this feature
   
  @@ -105,7 +105,7 @@
       <B>
         <FONT SIZE=-1>
   	     Written by <A HREF="mailto:sbekman@iil.intel.com">Stas Bekman</A>.
  -	     <BR>Last Modified at 12/03/98 
  +	     <BR>Last Modified at 12/07/98 
         </FONT>
       </B>
     </TD>
  
  
  
  1.3       +7 -7      modperl-site/guide/warnings.html
  
  Index: warnings.html
  ===================================================================
  RCS file: /export/home/cvs/modperl-site/guide/warnings.html,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- warnings.html	1998/12/03 21:04:24	1.2
  +++ warnings.html	1998/12/07 13:03:08	1.3
  @@ -93,9 +93,9 @@
   The warning:
   
   <P>
  -<PRE>  Global symbol &quot;$undefined&quot; requires explicit package name at /usr/apps/pais/cgi/tmp.pl line 4.
  +<PRE>  Global symbol &quot;$undefined&quot; requires explicit package name at /usr/apps/foo/cgi/tmp.pl line 4.
             eval 'package Apache::ROOT::perl::tmp_2epl;use Apache qw(exit);sub handler {
  -  #line 1 /usr/apps/pais/cgi/tmp.pl
  +  #line 1 /usr/apps/foo/cgi/tmp.pl
     BEGIN {$^W = 1;}#!/usr/bin/perl -w
     use strict;
     print &quot;Content-type: text/html\\n\\n&quot;;
  @@ -107,8 +107,8 @@
             Apache::Registry::compile('package
           Apache::ROOT::perl::tmp_2epl;use Apache qw(exit);sub han...') 
           called at /usr/apps/lib/perl5/site_perl/5.005/aix/Apache/Registry.pm line 121
  -          Apache::Registry::handler('Apache=SCALAR(0x205026c0)') called at /usr/apps/pais/cgi/tmp.pl line 4
  -          eval {...} called at /usr/apps/pais/cgi/tmp.pl line 4
  +          Apache::Registry::handler('Apache=SCALAR(0x205026c0)') called at /usr/apps/foo/cgi/tmp.pl line 4
  +          eval {...} called at /usr/apps/foo/cgi/tmp.pl line 4
     [Sun Nov 15 15:15:30 1998] [error] Undefined subroutine &amp;Apache::ROOT::perl::tmp_2epl::handler called at /
     usr/apps/lib/perl5/site_perl/5.005/aix/Apache/Registry.pm line 135.
     
  @@ -148,7 +148,7 @@
   <CENTER><H1><A NAME="Can_t_undef_active_subroutine">Can't undef active subroutine</A></H1></CENTER>
   <P>
   <PRE>  Can't undef active subroutine at /usr/apps/lib/perl5/site_perl/5.005/aix/Apache/Registry.pm line 102. 
  -  Called frompackage Apache::Registry, filename /usr/apps/lib/perl5/site_perl/5.005/aix/Apache/Registry.pm, line 102 
  +  Called from package Apache::Registry, filename /usr/apps/lib/perl5/site_perl/5.005/aix/Apache/Registry.pm, line 102 
   </PRE>
   <P>
   This problem is caused when, a client drops the connection while httpd is
  @@ -177,7 +177,7 @@
   (myscript.pl is optional). It specifies the line number of the _following_
   line, not the line the directive is on. You can use a little script to
   stuff every N lines of your code with this directives, but then you will
  -have to rerun this script everytime you add remove code lines. The script: 
  +have to rerun this script every time you add remove code lines. The script: 
   
   <P>
   <PRE>  #!/usr/bin/perl
  @@ -261,7 +261,7 @@
       <B>
         <FONT SIZE=-1>
   	     Written by <A HREF="mailto:sbekman@iil.intel.com">Stas Bekman</A>.
  -	     <BR>Last Modified at 12/03/98 
  +	     <BR>Last Modified at 12/07/98 
         </FONT>
       </B>
     </TD>
  
  
  
  1.1                  modperl-site/guide/CHANGES
  
  Index: CHANGES
  ===================================================================
  This is a CHANGES file for mod_perl mini_guide
  
  
  12.07.98
  
  
  * Run a spell check. ispell and WWWebster were quite helpful :)
  
  
  * Added Richard Dice's notes about ways to see whether or not mod_perl
    is actually compiled into the server and working. "check the
    error_log file" (installation)
  
  
  * Added 'Is it possible to install mod_perl without root access?'
    section into Server Installtion (scenario) page.
  
  
  * Added Perrin Harkins and Jonathan Peterson's notes about
    apache/mod_perl/embperl/DBI vs IIS/ASP/ADO
  
  
  * Added a CHANGES file (this one)
  
  
  * Added an 'all in one page', suitable for printing. Currently it's
    just an ordered cat(). In the future it might change :)
  
  
  12.03.98
  
  
  * First Release
  
  
  1.1                  modperl-site/guide/all.html
  
  Index: all.html
  ===================================================================
  <HTML><BODY BGCOLOR="white"><CENTER>
  	      <H1>This page includes all the guide and is suitable for printing only!</H1>
  	      </CENTER><HR>
  	      <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
  <HTML>
  <HEAD>
     <TITLE>Mod Perl Developer's Mini Guide</TITLE>
     <META NAME="GENERATOR" CONTENT="Mozilla/3.04Gold (X11; I; AIX 4.1) [Netscape]">
     <META NAME="Author" CONTENT="Bekman Stas">
  </HEAD>
  <BODY TEXT="#000000" BGCOLOR="#E0FFFF" LINK="#0000EE" VLINK="#551A8B" ALINK="#FF0000">
  
  <H1 ALIGN=CENTER>Mod Perl Developer's Mini Guide</H1>
  
  <CENTER><P><B>Deploying apache/mod_perl accelerator to give a rocket speed
  to your perl cgi-bin scripts.</B></P></CENTER>
  
  <CENTER><P><B>Version 1.01  Dec, 7 1998</B></P></CENTER>
  
  <P>
  <HR WIDTH="100%"></P>
  
  <H3><FONT SIZE=-1>Table of Contents:</FONT></H3>
  
  <UL>
  <LI><A HREF="intro.html">Introduction. Incentives. Credits.</A></LI>
  
  <LI><A HREF="start.html">Getting Started with mod_perl. Overview.</A></LI>
  
  <LI><A HREF="scenario.html">Server Installation. Real World scenario</A></LI>
  
  <LI><A HREF="config.html">Server Configuration</A>.</LI>
  
  <LI><A HREF="control.html">Server Controlling and Monitoring</A></LI>
  
  <LI><A HREF="porting.html">CGI => mod_perl Porting. mod_perl Coding guidelines.</A></LI>
  
  <LI><A HREF="obvious.html">What is obvious for others but not for you</A>.</LI>
  
  <LI><A HREF="warnings.html">Warnings and Errors: Where and Why.</A>? </LI>
  
  <LI><A HREF="performance.html">Performance. Benchmarks.</A> </LI>
  
  <LI><A HREF="status.html">mod_perl Status. Peeking into the Server's Perl Inwards</A></LI>
  
  <LI><A HREF="debug.html">Code Debugging techniques</A></LI>
  
  <LI><A HREF="snippets.html">Code Snippets</A></LI>
  
  <LI><A HREF="help.html">Help. Further Learning.</A></LI>
  
  <LI><A HREF="all.html">Guide All in One. Ready for Printing</A></LI>
  
  <LI><A HREF="CHANGES">CHANGES</A></LI>
  
  </UL>
  
  <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="mailto:sbekman@iil.intel.com">Stas
  Bekman</A>.<BR>
  Last Modified at 12/04/1998 </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>
  
  </BODY>
  </HTML>
  
  
  <HR SIZE=6>
  <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
  <HTML>
  <HEAD>
     <TITLE>mod_perl mini-guide: Introduction. Incentives. Credits. </TITLE>
     <META NAME="GENERATOR" CONTENT="Mozilla/3.04Gold (X11; I; AIX 4.1) [Netscape]">
     <META NAME="Author" CONTENT="Bekman Stas">
  </HEAD>
  <BODY TEXT="#000000" BGCOLOR="#E0FFFF" LINK="#0000EE" VLINK="#551A8B" ALINK="#FF0000">
  
  <H1 ALIGN=CENTER><A HREF="http://perl.apache.org">
  <IMG SRC="images/mod_perl.gif" ALT="Mod Perl Icon" BORDER=0 HEIGHT=30
  	  WIDTH=90 ALIGN=LEFT></A>
  <A HREF="http://perl.apache.org">
  <IMG SRC="images/mod_perl.gif" ALT="Mod Perl Icon" BORDER=0 HEIGHT=30
  	  WIDTH=90 ALIGN=RIGHT></A>Introduction. Incentives. Credits.</H1>
  
  <P>
  <HR WIDTH="100%"></P>
  
  <P><A NAME="toc"></A><B><FONT SIZE=-1>Table of Contents:</FONT></B></P>
  
  <UL>
  <LI><A HREF="#1">What is mod_perl</A></LI>
  
  <LI><A HREF="#2">What is covered in this document</A></LI>
  
  <LI><A HREF="#3">Sources and Acknowledgments</LI>
  </UL>
  
  <P>
  <HR WIDTH="100%"></P>
  
  <H3 ALIGN=CENTER><A NAME="1"></A>What is mod_perl</H3>
  
  <P>The Apache/Perl integration project brings together the full power of
  the Perl programming language and the Apache HTTP server. With mod_perl
  it is possible to write Apache modules entirely in Perl. In addition, the
  persistent interpreter embedded in the server avoids the overhead of starting
  an external interpreter, the penalty of Perl start-up time and loading
  and compiling the modules and the scripts. </P>
  
  <P>The primary advantages of mod_perl are power and speed. You have full
  access to the inner-workings of the web server and can intervene at any
  stage of request-processing. This allows for customized processing of (to
  name just a few of the phases) URI-&gt;filename translation, authentication,
  response generation and logging. There is very little run-time overhead.
  In particular, it is not necessary to start a separate process, as is often
  done with web-server extensions. The most wide-spread such extension mechanism,
  the Common Gateway Interface (CGI), can be replaced entirely with perl-code
  that handles the response generation phase of request processing. Mod_perl
  includes 2 general purpose modules for this purpose (Apache::Registry)
  that can transparently run existing perl CGI scripts and Apache::PerlRun,
  which does a similar job but allows you to run dirty (to some extent) written
  scripts.</P>
  
  <P>Many people wonder and ask &quot;How much of a performance improvement
  does mod_perl give?&quot;. Well, it all depends on what you're doing with
  mod_perl and possibly who you ask. People report speed boosts from 200%
  to 2000%.&nbsp;The best way to measure is to try it and see for yourself!
  (see <A HREF="http://perl.apache.org/tidbits.html">Tidbit </A>and <A HREF="http://perl.apache.org/stories/">Stories
  </A>pages for the facts)</P>
  
  <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B> 
  <HR WIDTH="100%"></P>
  
  <H3 ALIGN=CENTER><A NAME="2"></A>What is covered in this document</H3>
  
  <P>This document was written to help you to start using the mod_perl as
  soon as possible and with as less as possible obstacles. It includes an
  information about installation and configuration of perl and apache
  web server and goes deeply into an issues of writing and porting the perl
  scripts for mod_perl. Note, that it doesn't enter the big world of using
  the Perl API or C API. You will find the Pointers covering these topics at
  <A HREF="help.html">Help Seek and Learning more</A> section of this document.<B>
  This guide tries to cover the most of the Apache::Registry and Apache::PerlRun.</B></P>
  
  <P>It's assumed that you know the basics of building and installing of
        perl and apache
  (If you don't just read the INSTALL docs coming with distribution of each
  package). However you will find in the document specific perl and
        apache related installation and
  configuration notes, which will help you to successfully 
  complete the mod_perl installation.</P>
  
  <P>If after reading this guide and other documents listed at <A HREF="help.html">Help
  section</A>, you feel that your question is yet not answered, please ask
  the apache/mod_perl mailing list to help you. But first try to browse the
  mailing list archive. Most of the time you will find the answer for your
  question by searching the mailing archive, since there is a big chance
  someone else already have encountered the problem and found a solution
  for it. If you ignore this advice, don't be surprised if your question
  will be left unanswered - it bores people to answer the same question more
  than once (twice?). It doesn't mean that you should avoid asking questions. Just
  don't abuse the available help and <B>RTFM </B>before you call for <B>HELP</B>.
  (You have certainly heard the infamous fable of the shepherd boy and the
  wolves)</P>
  
  <P>If you find incorrect details, my grammar mistakes or you want to contribute
  to this document please fell free to send me an <A HREF="mailto:sbekman@iil.intel.com">email</A>.</P>
  
  <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B> 
  <HR WIDTH="100%"></P>
  
  <H3 ALIGN=CENTER><A NAME="3"></A>Sources and Acknowledgments</H3>
  
  <P>This document is based on:</P>
  
  <UL>
  <LI>Frank Cringle's <A HREF="http://perl.apache.org/faq/">mod_perl FAQ</A></LI>
  
  <LI>Vivek Khera's <A HREF="http://perl.apache.org/tuning/">mod_perl performance
  tuning guide</A></LI>
  
  <LI>Doug MacEachern's <A HREF="http://perl.apache.org/src/mod_perl.html">mod_perl
  plugin reference guide</A>. </LI>
  
  <LI><A HREF="http://perl.apache.org/dist/cgi_to_mod_perl.html">Quick guide
  </A>for moving from CGI to mod_perl. </LI>
  
  <LI><A HREF="http://perl.apache.org/dist/mod_perl_traps.html">mod_perl_traps,</A>
  common traps and solutions for mod_perl users. </LI>
  
  <LI>Answers to some of the questions posted to <A
  HREF="mailto:modperl@apache.org">Apache/Perl mailing
  list</A>. (Subscription information is in the <a
  href="http://perl.apache.org/src/mod_perl-1.16/SUPPORT">SUPPORT</a>
  file in the distribution)</LI>
  
  <LI>My personal experience with mod_perl</LI>
  </UL>
  
  <P>As I said, I've quoted many information snippets from FAQs and emails,
        and I didn't credit people after each quote in the guide. I didn't mean to
        take the credits for myself, it's just that I've tried to keep
        track of names, and became lost, so I preferred not to credit at
        all in the guide, but to centralize it here. If you think that
        you want your name to show up under your original quote that I
        have used, please tell me and I'll add it for you.<P>
  
  <P> Credits go to ( alphabetically sorted );
      <UL>
        <LI>Andreas J. Koenig
        <LI>Ask Bjoern Hansen
        <LI>Brian Moseley 
        <LI>Chad K. Lewis
        <LI>Doug Bagley
        <LI>Doug MacEachern
        <LI>Edmund Mergl
        <LI>Eric Cholet
        <LI>Frank Cringle
        <LI>G.Richter
        <LI>Gunther Birznieks
        <LI>Howard Jones
        <LI>Jeff Baker
        <LI>Jeff Rowe
        <LI>Jon Orwant
        <LI>Ken Williams
        <LI>Leslie Mikesell
        <LI>Lincoln Stein
        <LI>Mike Fletcher
        <LI>Nathan Torkington
        <LI>Ralf Engelschall
        <LI>Randal Schwartz
        <LI>Vivek Khera
        <LI>
        <LI>Did I miss you? Tell me!
      </UL>
  </P>
  
  <P>I&nbsp;want to thank all the people who donated their time and efforts
  to made this amazing idea of mod_perl to become reality. It includes Doug
  MacEachern, the author of mod_perl and all the developers who contributed
  bug patches, modules and help. And of course the numeral unseen users who
  helped to find the bugs and advocate mod_perl around the world.</P>
  
  <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B> 
  <HR WIDTH="100%"></P>
  
  <P><A HREF="index.html">[Back to the main page]</A></P>
  
  <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="mailto:sbekman@iil.intel.com">Stas
  Bekman</A>.<BR>
  Last Modified at 12/04/1998 </FONT></B></TD>
  
  <TD><A HREF="http://perl.apache.org"><IMG SRC="images/mod_perl2.jpg"  BORDER=0 ALT="Mod Perl Icon" 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>
  
  
  <HR SIZE=6>
  <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
  <HTML>
  <HEAD>
     <TITLE>mod_perl guide: Getting Started with mod_perl. Overview.</TITLE>
     <META NAME="GENERATOR" CONTENT="Mozilla/3.04Gold (X11; I; AIX 4.1) [Netscape]">
     <META NAME="Author" CONTENT="Bekman Stas">
     <META NAME="Description" CONTENT="mod_perl,perl,apache">
     <META NAME="Keywords" CONTENT="mod_perl,perl,apache,webserver,cgi">
  </HEAD>
  <BODY TEXT="#000000" BGCOLOR="#E0FFFF" LINK="#0000EE" VLINK="#551A8B" ALINK="#FF0000">
  
  <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 Started with mod_perl. Overview.</H1>
  <HR WIDTH="100%">
  	    <!-- INDEX BEGIN -->
  <P><A NAME="toc"></A><B><FONT SIZE=-1>Table of Contents:</FONT></B></P>
  <UL>
  
  	<LI><A HREF="#Coverage">Coverage </A>
  	<LI><A HREF="#Downloading_the_needed_component">Downloading the needed components.</A>
  	<UL>
  
  		<LI><A HREF="#Perl">Perl</A>
  		<LI><A HREF="#Apache">Apache</A>
  		<LI><A HREF="#Mod_Perl">Mod_Perl</A>
  	</UL>
  
  	<LI><A HREF="#Configuration_and_Installation">Configuration and Installation</A>
  	<UL>
  
  		<LI><A HREF="#Perl">Perl</A>
  		<LI><A HREF="#Apache">Apache</A>
  		<LI><A HREF="#Mod_Perl">Mod_Perl</A>
  	</UL>
  
  	<LI><A HREF="#How_can_I_tell_whether_mod_perl_">How can I tell whether mod_perl is really installed</A>
  	<UL>
  
  		<LI><A HREF="#Testing_by_checking_the_error_lo">Testing by checking the error_log file</A>
  		<LI><A HREF="#Testing_by_calling_the_perl_sta">Testing by calling the /perl-status </A>
  		<LI><A HREF="#Testing_by_telneting_to_the_port">Testing by telneting to the port server's listening to</A>
  		<LI><A HREF="#Run_a_cgi_that_shows_you_your_se">Run a cgi that shows you your server's environment</A>
  		<LI><A HREF="#with_lwp_request">with lwp-request</A>
  	</UL>
  
  	<LI><A HREF="#Starting_to_use_the_server">Starting to use the server</A>
  </UL>
  <!-- INDEX END -->
  
  <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  <P>
  <CENTER><H1><A NAME="Coverage">Coverage</A></H1></CENTER>
  <P>
  This sections gets you a quick review of configuration and installation of
  the required tools. For a kick start tutorial, which will allow you make to
  make copy and paste slick installation, see
  <A HREF="././scenario.html#">Real World Scenario</A>
  
  <P>
  <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  <CENTER><H1><A NAME="Downloading_the_needed_component">Downloading the needed components.</A></H1></CENTER>
  <P>
  In order to start using the mod_perl - you will need to get first Perl,
  Apache webserver and mod_perl itself. Below you will find the needed
  information.
  
  <P>
  <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  <CENTER><H2><A NAME="Perl">Perl</A></H2></CENTER>
  <P>
  Probably perl is already installed at your machine. But check the version
  you use. You better get the perl5.004 and higher version. You can get the
  latest perl version from <A
  HREF="http://www.perl.com.">http://www.perl.com.</A> Try the direct
  download link <A
  HREF="http://www.perl.com/pace/pub/perldocs/latest.html.">http://www.perl.com/pace/pub/perldocs/latest.html.</A>
  As of this writing the latest maintain (production) release is perl5.00503.
  
  <P>
  <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  <CENTER><H2><A NAME="Apache">Apache</A></H2></CENTER>
  <P>
  Get the latest apache webserver from <A
  HREF="http://www.apache.org.">http://www.apache.org.</A> Try the direct
  download link [http://www.apache.org/dist/]. As of this writing the latest
  production release is apache-1.3.3.
  
  <P>
  <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  <CENTER><H2><A NAME="Mod_Perl">Mod_Perl</A></H2></CENTER>
  <P>
  Get the latest mod_perl from <A
  HREF="http://perl.apache.org.">http://perl.apache.org.</A> Try the direct
  download link [http://perl.apache.org/dist/]. As of this writing the latest
  production release is mod_perl-1.16_02
  
  <P>
  <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  <CENTER><H1><A NAME="Configuration_and_Installation">Configuration and Installation</A></H1></CENTER>
  <P>
  <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  <CENTER><H2><A NAME="Perl">Perl</A></H2></CENTER>
  <P>
  First install perl. Follow the instructions in the distribution's INSTALL
  file. During the configuration stage (while running
  <CODE>./Configure</CODE>), make sure you answer <CODE>YES</CODE> to:
  
  <P>
  <PRE>  Do you wish to use dynamic loading? [y]
  </PRE>
  <P>
  You will want this feature on to dynamically load the Perl
  Modules/extensions.
  
  <P>
  <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  <CENTER><H2><A NAME="Apache">Apache</A></H2></CENTER>
  <P>
  It will be a good idea to try to install the Apache webserver without
  mod_perl first. So later if something going wrong you will know that it's
  not apache's server problem. But you can skip this stage. In any case you
  have to open the source distribution of apache preferably at the same level
  with modperl distribution.
  
  <P>
  <PRE>  % ls -l /usr/src
    drwxr-xr-x   8 stas  bar         2048 Oct  6 09:46 apache_1.3.2/
    drwxr-xr-x  19 stas  bar         4096 Oct  2 14:33 mod_perl-1.16/
  </PRE>
  <P>
  <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  <CENTER><H2><A NAME="Mod_Perl">Mod_Perl</A></H2></CENTER>
  <P>
  Now we come to the main point. 
  
  <P>
  Here I'll give only a short example of mod_perl installation. You should
  read the real world scenario for a more complete description.
  
  <P>
  As with any perl package the installation of mod_perl is very easy and
  standard. perldoc INSTALL will guide you thru the configuration and
  installation process.
  
  <P>
  The fastest way to install would be:
  
  <P>
  <PRE>  % perl Makefile.PL APACHE_SRC=../apache_1.3.2/src \
      DO_HTTPD=1 PERL_MARK_WHERE=1 EVERYTHING=1
    % make &amp;amp;&amp;amp; make test &amp;amp;&amp;amp; make install
  </PRE>
  <P>
  To change the installation target (either if you aren't root or you need to
  install a second copy for testing purposes), assuming you use /foo/server
  as a base directory root, you have to run this:
  
  <P>
  <PRE>  % perl Makefile.PL APACHE_SRC=../apache_1.3.2/src \
      DO_HTTPD=1 PERL_MARK_WHERE=1 EVERYTHING=1 \
      APACHE_PREFIX=/foo/server PREFIX=/foo/server
  </PRE>
  <P>
  Where <CODE>PREFIX</CODE> says where to install the perl modules,
  <CODE>APACHE_PREFIX</CODE> - the same for the apache files.
  
  <P>
  Next step is to configure the mod_perl sections in the apache conf files.
  See <A HREF="././config.html#">ModPerlConfiguration</A>
  
  <P>
  Fire up the server with <CODE>/foo/server/sbin/apachectl start</CODE>, Watch the error log file if server doesn't start up (No error message
  will be printed to the console!)
  
  <P>
  <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  <CENTER><H1><A NAME="How_can_I_tell_whether_mod_perl_">How can I tell whether mod_perl is really installed</A></H1></CENTER>
  <P>
  There a few ways. In older versions of apache you could see that by running <CODE>httpd -v</CODE>, it's no longer work!
  
  <P>
  <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  <CENTER><H2><A NAME="Testing_by_checking_the_error_lo">Testing by checking the error_log file</A></H2></CENTER>
  <P>
  <PRE>  [Thu Dec  3 17:27:52 1998] [notice] Apache/1.3.1 (Unix) mod_perl/1.15 configured -- resuming normal operations
                                        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  </PRE>
  <P>
  <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  <CENTER><H2><A NAME="Testing_by_calling_the_perl_sta">Testing by calling the /perl-status</A></H2></CENTER>
  <P>
  Fetch: <A
  HREF="http://www.yourserver.com/perl-status">http://www.yourserver.com/perl-status</A>
  from your favorite Netscape browser :-) (Assuming you have configured the
  &lt;Location /perl-status&gt; Section in the server config file (refer to
  <A HREF="././config.html#">ModPerlConfiguration</A>)
  
  <P>
  You should see something like this:
  
  <P>
  <PRE>  Embedded Perl version 5.00502 for Apache/1.3.1 (Unix) mod_perl/1.16 
    process 50880, running since Tue Oct 6 14:31:45 1998
  </PRE>
  <P>
  <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  <CENTER><H2><A NAME="Testing_by_telneting_to_the_port">Testing by telneting to the port server's listening to</A></H2></CENTER>
  <P>
  Assume that you set <CODE>Port 8080</CODE> in the httpd.conf for your mod_perl server. You have to telnet to your
  server port 8080, then you should type <CODE>HEAD / HTTP/1.0</CODE> then press the &lt;ENTER&gt; key TWICE!
  
  <P>
  <PRE>  % telnet yourserver.com 8080&lt;ENTER&gt;
    HEAD / HTTP/1.0&lt;ENTER&gt;&lt;ENTER&gt;
  </PRE>
  <P>
  You should see a respond like this:
  
  <P>
  <PRE>  HTTP/1.1 200 OK
    Date: Tue, 01 Dec 1998 12:27:52 GMT
    Server: Apache/1.3.2 (Unix) mod_perl/1.16_01
    Connection: close
    Content-Type: text/html
    
    Connection closed.
  </PRE>
  <P>
  So you see <CODE>Server: Apache/1.3.2 (Unix) mod_perl/1.16_01</CODE> - which says that you do have mod_perl installed and it's 1.16_01. Of
  course in your case it would be the version you have installed.
  
  <P>
  However, just because you've got it linked in there, that doesn't meant
  that you have your server configured to use mod_perl to handle Perl
  scripts. You will find the configuration assistance at
  <A HREF="././config.html#">ModPerlConfiguration</A>
  
  <P>
  <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  <CENTER><H2><A NAME="Run_a_cgi_that_shows_you_your_se">Run a cgi that shows you your server's environment</A></H2></CENTER>
  <P>
  Copy and paste the script below (no need for perl line!). Let's say you
  called it test.pl, you saved it into the root of the cgi scripts, and cgi
  root is mapped directly to /perl of your server.
  
  <P>
  <PRE>  print &quot;Content-type: text/html\n\n&quot;;
    print &quot;Server's environment&lt;P&gt;\n&quot;;
    print &quot;&lt;TABLE&gt;&quot;;
    foreach ( keys %ENV ) {
        print &quot;&lt;TR&gt;&lt;TD&gt;$_ &lt;/TD&gt;&lt;TD&gt;$ENV{$_}&lt;/TR&gt;&lt;/TD&gt;&quot;;
    }
    print &quot;&lt;/TABLE&gt;&quot;;
  </PRE>
  <P>
  Make it executable:
  
  <P>
  <PRE>  % chmod a+x test.pl
  </PRE>
  <P>
  Now fetch the <A
  HREF="http://www.you.com:8080/perl/test.pl">http://www.you.com:8080/perl/test.pl</A>
  . You should see something like this (part of the output was snipped).
  
  <P>
  <PRE>  SERVER_SOFTWARE    Apache/1.3.2 (Unix) mod_perl/1.16_01
    GATEWAY_INTERFACE  CGI-Perl/1.1
    REQUEST_METHOD     GET
    HTTP_ACCEPT        image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, */*
    MOD_PERL           1.16_01
    REQUEST_URI        /perl/test.pl
    SCRIPT_NAME        /perl/test.pl
    [...snipped]
  </PRE>
  <P>
  Now if I run the same script in mod_cgi mode (configured with /cgi-bin)
  (you must add the perl line #!/bin/perl for the above script) and fetch <A
  HREF="http://www.you.com/cgi-bin/test.pl">http://www.you.com/cgi-bin/test.pl</A>
  
  <P>
  <PRE>  SERVER_SOFTWARE   Apache/1.3.2 (Unix)
    GATEWAY_INTERFACE CGI/1.1
    [...snipped]
  </PRE>
  <P>
  You will see that 2 environment variables <CODE>SERVER_SOFTWARE</CODE> and
  <CODE>GATEWAY_INTERFACE</CODE> are different from the case above. So you've got the hint how to tell in
  what mode you are running in your cgi scripts. I start all my cgi scripts
  that are mod_perl aware with:
  
  <P>
  <PRE>  BEGIN {
        # Auto-detect if we are running under mod_perl or CGI.
      $USE_MOD_PERL = ( (exists $ENV{'GATEWAY_INTERFACE'} and $ENV{'GATEWAY_INTERFACE'} =~ /CGI-Perl/)
                        or exists $ENV{'MOD_PERL'} ) ? 1 : 0;
        # perl5.004 is a must under mod_perl
      require 5.004 if $USE_MOD_PERL;
    }
  </PRE>
  <P>
  You might wander why in the world you will need to know in what mode you
  are running. For example you will want to use <CODE>Apache::exit()</CODE>
  and not <CODE>CORE::exit()</CODE> in your scripts, but if you think that your script might be used in both
  environments (mod_cgi vs mod_perl), you will have to override the <CODE>exit()</CODE> subroutine and to make the runtime decision of what method you will use.
  For reasons and implementations see: <A HREF="././porting.html#using_exit_">Using exit()</A> and the whole <A HREF="././porting.html#">Writing Mod Perl scripts and Porting plain CGIs to it</A> page.
  
  <P>
  <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  <CENTER><H2><A NAME="with_lwp_request">with lwp-request</A></H2></CENTER>
  <P>
  Yet another one. Why do I show all these approaches? While here they are
  serving a very simple purpose, they can be helpful in other situations. 
  
  <P>
  Assuming you have the libwww-perl package installed (LWP), you will need it
  installed for passing the mod_perl's <CODE>make test</CODE> anyway.
  
  <P>
  <PRE>  % lwp-request -e -d www.site.com
  </PRE>
  <P>
  Will show you all the headers.
  
  <P>
  <PRE>  % lwp-request -e -d www.site.com | egrep '^Server:'
  </PRE>
  <P>
  To see the server's version only.
  
  <P>
  <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  <CENTER><H1><A NAME="Starting_to_use_the_server">Starting to use the server</A></H1></CENTER>
  <P>
  Now you want to writing the cgis. You better start writing it very clean
  and with understanding of the new running environment. You have to learn
  how to write correctly for mod_perl. There is nothing new here, all you
  have to remember that your script wouldn't die after it finishes to serve
  the request, but will stay in memory and might affect all other scripts
  running under the same server process (child). You will read more about it
  in the following sections: <A HREF="././porting.html#">Writing Mod Perl scripts and Porting plain CGIs</A>
  
  <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  <P><A HREF="index.html">[Back to the main page]</A></P>
  
  <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="mailto:sbekman@iil.intel.com">Stas Bekman</A>.
  	     <BR>Last Modified at 12/07/98 
        </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>
  	    
  
  <HR SIZE=6>
  <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
  <HTML>
  <HEAD>
     <TITLE>mod_perl guide: Server Installation. Real World scenario</TITLE>
     <META NAME="GENERATOR" CONTENT="Mozilla/3.04Gold (X11; I; AIX 4.1) [Netscape]">
     <META NAME="Author" CONTENT="Bekman Stas">
     <META NAME="Description" CONTENT="mod_perl,perl,apache">
     <META NAME="Keywords" CONTENT="mod_perl,perl,apache,webserver,cgi">
  </HEAD>
  <BODY TEXT="#000000" BGCOLOR="#E0FFFF" LINK="#0000EE" VLINK="#551A8B" ALINK="#FF0000">
  
  <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>
  Server Installation. Real World scenario</H1>
  <HR WIDTH="100%">
  	    <!-- INDEX BEGIN -->
  <P><A NAME="toc"></A><B><FONT SIZE=-1>Table of Contents:</FONT></B></P>
  <UL>
  
  	<LI><A HREF="#Making_a_strategic_decision">Making a strategic decision</A>
  	<LI><A HREF="#Deciding_on_directories_layout">Deciding on directories layout</A>
  	<LI><A HREF="#Configuration_and_compilation_of">Configuration and compilation of the sources. </A>
  	<UL>
  
  		<LI><A HREF="#httpd_docs_server">httpd_docs server</A>
  		<LI><A HREF="#httpd_perl_server_mod_perl_">httpd_perl server (mod_perl):</A>
  	</UL>
  
  	<LI><A HREF="#Is_it_possible_to_install_mod_pe">Is it possible to install mod_perl without root access?</A>
  </UL>
  <!-- INDEX END -->
  
  <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  <P>
  <CENTER><H1><A NAME="Making_a_strategic_decision">Making a strategic decision</A></H1></CENTER>
  <P>
  When you will run your scripts under mod_perl - you will notice that the
  httpd processes consumes a huge pieces of memory, from 5M to 25M and more.
  Since there is no free dinner, that's the price we pay for the great speed
  improvements under mod_perl. But it doesn't mean that you should serve the
  static objects like images and html docs with these processes. It's an
  overkill. The best approach is to run 2 servers: a light apache server with
  no mod_perl compiled in to serve the static pages, and a heavy
  apache/mod_perl server to server the cgis in mod_perl mode only. This
  section describes a real world example ready for copy and paste to start
  with. You will probably will want to change the base directories, but
  basically you can pick it as it is. 
  
  <P>
  Since we run 2 apache servers we will need 2 different configuration files,
  log files and etc. We need a special directory layout. While some of the
  directories can be shared between 2 servers (assuming that use the same
  source distribution for both servers, other should be separated. I choose
  to make the difference between 2 servers by calling them httpd_docs
  (apache) and httpd_perl (apache/mod_perl). 
  
  <P>
  <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  <CENTER><H1><A NAME="Deciding_on_directories_layout">Deciding on directories layout</A></H1></CENTER>
  <P>
  We will make /usr/apps our <STRONG>root</STRONG> directory. We will build all the dir tree there. (/usr/apps/bin
  /usr/apps/etc and etc...) 
  
  <P>
  First let's prepare the sources. We assume that all the sources go to
  /usr/apps/usr/src dir. First lets make 2 subdirs: 
  
  <P>
  <PRE>      % mkdir /usr/apps/usr/src/httpd_docs
        % mkdir /usr/apps/usr/src/httpd_perl
  </PRE>
  <P>
  Now we put the apache source into /usr/apps/usr/src/httpd_docs: 
  
  <P>
  <PRE>      % cd /usr/apps/usr/src/httpd_docs
        % cp ~/apache.tar.gz .
        % gzip -d apache.tar.gz
        % tar xvf apache.tar
  </PRE>
  <P>
  let's check: 
  
  <P>
  <PRE>      % ls -l
        drwxr-xr-x  8 stas  stas 2048 Oct 29 17:38 apache_1.3.2/
  </PRE>
  <P>
  Prepare the httpd_perl server sources 
  
  <P>
  <PRE>      % cd /usr/apps/usr/src/httpd_perl
        % cp ~/apache.tar.gz .
        % gzip -d apache.tar.gz
        % tar xvf apache.tar
        % cp ~/modperl.tar.gz .
        % gzip -d modperl.tar.gz
        % tar xvf modperl.tar
  </PRE>
  <P>
  let's check
  
  <P>
  <PRE>      % ls -l
        drwxr-xr-x  8 stas  stas 2048 Oct 29 17:38 apache_1.3.2/
        drwxr-xr-x  8 stas  stas 2048 Oct 29 17:38 modperl-1.16/
  </PRE>
  <P>
  Time to decide the desired directories structure layout (Where apache files
  go): 
  
  <P>
  <PRE>      ROOT = /usr/apps 
  </PRE>
  <P>
  Both Servers Can share the following dirs (so we will not duplicate data): 
  
  <P>
  <PRE>      /usr/apps/bin/
        /usr/apps/lib
        /usr/apps/include/
        /usr/apps/man/
        /usr/apps/share/
  </PRE>
  <P>
  <STRONG>Important:</STRONG> we assume that both servers comes from the same source
  
  <P>
  Servers store their specific files either in httpd_docs or httpd_perl:
  
  <P>
  <PRE>      /usr/apps/etc/httpd_docs/
                      httpd_perl/
  </PRE>
  <P>
  <PRE>      /usr/apps/sbin/httpd_docs/
                       httpd_perl/
  </PRE>
  <P>
  <PRE>      /usr/apps/var/httpd_docs/logs/   
                                 proxy/ 
                                 run/
                      httpd_perl/logs/
                                 proxy/ 
                                 run/
  </PRE>
  <P>
  Next step is to configure and compile the sources: Below are the procedures
  to compile both servers taking into account the above directories layout:
  
  <P>
  <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  <CENTER><H1><A NAME="Configuration_and_compilation_of">Configuration and compilation of the sources.</A></H1></CENTER>
  <P>
  <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  <CENTER><H2><A NAME="httpd_docs_server">httpd_docs server</A></H2></CENTER>
  <DL>
  <P><DT><STRONG><A NAME="item_Configuration">Configuration</A></STRONG><DD>
  <P>
  <PRE>      % cd /usr/apps/usr/src/httpd_docs/apache_1.3.2
  </PRE>
  <P>
  <PRE>      % make clean
  </PRE>
  <P>
  <PRE>      # gcc - compiles httpd by 100K+ smaller on AIX!
  </PRE>
  <P>
  <PRE>      % env CC=gcc \
        ./configure --prefix=/usr/apps \
          --sbindir=/usr/apps/sbin/httpd_docs \
          --sysconfdir=/usr/apps/etc/httpd_docs \
          --localstatedir=/usr/apps/var/httpd_docs \
          --runtimedir=/usr/apps/var/httpd_docs/run \
          --logfiledir=/usr/apps/var/httpd_docs/logs \
          --proxycachedir=/usr/apps/var/httpd_docs/proxy \
          --enable-module=include --enable-module=rewrite 
  </PRE>
  <P>
  Note: add --layout to see the resulting dirs layout without actually making
  the configuration. 
  
  <P><DT><STRONG><A NAME="item_Compilation">Compilation:</A></STRONG><DD>
  <P>
  <PRE>      % make 
  </PRE>
  <P>
  <PRE>      % make install
  </PRE>
  <P>
  Rename the 'httpd' to 'http_docs' 
  
  <P>
  <PRE>      % mv /usr/apps/sbin/httpd_docs/httpd /usr/apps/sbin/httpd_docs/httpd_docs
  </PRE>
  <P>
  Now update the apachectl utility to point to a new httpd name (by hand or
  by using perl)
  
  <P>
  <PRE>      % perl -p -i -e 's|httpd_docs/httpd|httpd_docs/httpd_docs|' /usr/apps/sbin/httpd_docs/apachectl
  </PRE>
  </DL>
  <P>
  <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  <CENTER><H2><A NAME="httpd_perl_server_mod_perl_">httpd_perl server (mod_perl):</A></H2></CENTER>
  <P>
  Before you start to configure the mod_perl, you should be aware that there
  a few reqired modules that have to be installed before. You will know
  whether you have all the required installed or not, during the run <CODE>perl Makefile.PL</CODE> below. If you discover that you don't have these, go to your nearest CPAN
  repository (if you don't know what is it, go to <A
  HREF="http://www.perl.com/CPAN">http://www.perl.com/CPAN</A> ) or run the
  interactive shell by
  <CODE>perl -MCPAN -e shell</CODE> .
  
  <P>
  Now back to installation.
  
  <P>
  <PRE>      % cd /usr/apps/usr/src/httpd_perl/apache_1.3.2
        % make clean
        % cd /usr/apps/usr/src/httpd_perl/mod_perl-1.16
        % make clean
  </PRE>
  <P>
  Here I didn't find a way to compile with gcc (but perl was compiled with cc
  so we have to compile with the same compiler!!!
  
  <P>
  Note the APACI_ARGS (below) must be passed as one long line!!!
  
  <P>
  <PRE>      % /usr/apps/bin/perl Makefile.PL \
        APACHE_PREFIX=/usr/apps/ \
        APACHE_SRC=../apache_1.3.2/src \
        DO_HTTPD=1 \
        USE_APACI=1 \
        PERL_MARK_WHERE=1 \
        PERL_STACKED_HANDLERS=1 \
        ALL_HOOKS=1 \
        APACI_ARGS=--sbindir=/usr/apps/sbin/httpd_perl,--sysconfdir=/usr/apps/etc/httpd_perl,
        --localstatedir=/usr/apps/var/httpd_perl,--runtimedir=/usr/apps/var/httpd_perl/run,
        --logfiledir=/usr/apps/var/httpd_perl/logs,--proxycachedir=/usr/apps/var/httpd_perl/proxy,
        --enable-module=rewrite
  </PRE>
  <P>
  Notes: -DPERL_STACKED_HANDLERS needed for Apache::DBI
  
  <P>
  <PRE>      % make &amp;&amp; make test &amp;&amp; make install
  </PRE>
  <P>
  Note: Apache puts a stripped version of httpd at
  /usr/apps/sbin/httpd_perl/httpd the original version sits at
  /usr/apps/usr/src/httpd_perl/apache_1.3.2/src/httpd
  
  <P>
  rename the 'httpd' to 'http_perl' 
  
  <P>
  <PRE>      % mv /usr/apps/sbin/httpd_perl/httpd /usr/apps/sbin/httpd_perl/httpd_perl
  </PRE>
  <P>
  now update the apachectl utility to point to a new httpd name (by hand or
  by using perl)
  
  <P>
  <PRE>      % perl -p -i -e 's|httpd_perl/httpd|httpd_perl/httpd_perl|' /usr/apps/sbin/httpd_perl/apachectl
  </PRE>
  <P>
  Now proceed to <A HREF="././config.html#">Server Configuration</A> section.
  
  <P>
  <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  <CENTER><H1><A NAME="Is_it_possible_to_install_mod_pe">Is it possible to install mod_perl without root access?</A></H1></CENTER>
  <P>
  Yes, no problem with that. Follow the instructions above and when you
  encounter APACI_ARGS use your home directory or alike as a prefix (e.g
  <CODE>/home/stas/www</CODE>) and everything will be installed there. There is a chance that some perl
  libs will be not installed on your server by root and you will have to
  install these locally too. See the <A
  HREF="http://www.esafe.com/stas/TULARC/webmaster/myfaq.html#7">http://www.esafe.com/stas/TULARC/webmaster/myfaq.html#7</A>
  for more information on local perl installations.
  
  <P>
  You will not be able to set the server to listen to port lower then 1024
  (if you aren't a root). So pick your port as a number above the 1024. (I
  use 8080 in most cases). Note that you will have to use the <A
  HREF="http://www.you.com:8080">http://www.you.com:8080</A> in that case.
  But it's not a problem since generally users don't access directly the cgi
  but from the webpage, so they shouldn't know at all that the port is
  different.
  
  <P>
  You will need to worry to put the start server script into rc.d directory
  of your machine, so if the last will be rebooted - your webserver will be
  restarted automatically.
  
  <P>
  One more important thing is Resources, mod_perl is very memory greedy and
  if you will run lots of mod_perl processes on that machine, most likely
  your host will ask you to shutdown the mod_perl server, or to find another
  home. You have a few solutions: <STRONG>a.</STRONG> reduce resource usage - see <A HREF="././performance.html#Limiting_the_size_of_the_process">Limiting the size of the processes</A>  <STRONG>b.</STRONG> ask your ISP if you can put a dedicated machine into their computer room
  and be root there. <STRONG>c.</STRONG> look for another ISP with lots of resources or one that supports mod_perl
  (not likely)
  
  <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  <P><A HREF="index.html">[Back to the main page]</A></P>
  
  <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="mailto:sbekman@iil.intel.com">Stas Bekman</A>.
  	     <BR>Last Modified at 12/07/98 
        </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>
  	    
  
  <HR SIZE=6>
  <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
  <HTML>
  <HEAD>
     <TITLE>mod_perl guide: Server Configuration</TITLE>
     <META NAME="GENERATOR" CONTENT="Mozilla/3.04Gold (X11; I; AIX 4.1) [Netscape]">
     <META NAME="Author" CONTENT="Bekman Stas">
     <META NAME="Description" CONTENT="mod_perl,perl,apache">
     <META NAME="Keywords" CONTENT="mod_perl,perl,apache,webserver,cgi">
  </HEAD>
  <BODY TEXT="#000000" BGCOLOR="#E0FFFF" LINK="#0000EE" VLINK="#551A8B" ALINK="#FF0000">
  
  <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>
  Server Configuration</H1>
  <HR WIDTH="100%">
  	    <!-- INDEX BEGIN -->
  <P><A NAME="toc"></A><B><FONT SIZE=-1>Table of Contents:</FONT></B></P>
  <UL>
  
  	<LI><A HREF="#configuration">configuration</A>
  	<UL>
  
  		<LI><A HREF="#aliases_configurations">aliases configurations</A>
  	</UL>
  
  	<LI><A HREF="#Configuration_of_Location">Configuration of Location</A>
  	<UL>
  
  		<LI><A HREF="#perl_status_location">perl-status location </A>
  		<LI><A HREF="#perl_startup_file">perl-startup file</A>
  		<LI><A HREF="#PerlFreshRestart">PerlFreshRestart</A>
  		<LI><A HREF="#What_modules_should_you_add_to_t">What modules should you add to the startup file and why.</A>
  		<LI><A HREF="#Is_it_possible_to_preopen_a_DB_c">Is it possible to preopen a DB connection at the server startup?</A>
  		<LI><A HREF="#Perl_behavior_controls">Perl behavior controls</A>
  	</UL>
  
  	<LI><A HREF="#Perl_Sections">Perl Sections</A>
  	<LI><A HREF="#General_pitfalls">General pitfalls</A>
  	<UL>
  
  		<LI><A HREF="#My_cgi_perl_code_is_being_return">My cgi/perl code is being returned as a plain text instead of being executed by the webserver?</A>
  	</UL>
  
  </UL>
  <!-- INDEX END -->
  
  <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  <P>
  <CENTER><H1><A NAME="configuration">configuration</A></H1></CENTER>
  <P>
  You have just installed the new apache/mod_perl server. Now you have to
  configure server's configuration files. To learn how to configure the
  apache's config files, please the use the apache's documentation or just
  open the files in conf directory and follow the instructions in these files
  - they are self explainable...
  
  <P>
  Before you start configuration of mod_perl, configure the apache, and see
  that it works. When done, come back to continue...
  
  <P>
  <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  <CENTER><H2><A NAME="aliases_configurations">aliases configurations</A></H2></CENTER>
  <P>
  OK, first thing you will want to specify the location from where all
  mod_perl scripts will be called.
  
  <P>
  in srm.conf add:
  
  <P>
  <PRE>    # plain cgi-bin:
    ScriptAlias /cgi-bin/ /usr/apps/myproject/cgi-bin
      
      # Apache::Registry mode
    ScriptAlias /perl/ /usr/apps/myproject/cgi/
  </PRE>
  <P>
  <PRE>    # Apache::PerlRun mode
    ScriptAlias /cgi-perl/ /usr/apps/myproject/cgi/
  </PRE>
  <P>
  Alias allows the server to locate the script that was called at the
  filesystem.
  
  <P>
  Alias is the start of the URL path to the script you call, like when you
  fetch <A
  HREF="http://www.you.com/perl/test.pl">http://www.you.com/perl/test.pl</A>
  , server will look for the file test.pl at /usr/apps/myproject/cgi but
  execute it as a Apache::Registry script, after you set this (see the next
  section). <A
  HREF="http://www.you.com/perl/test.pl">http://www.you.com/perl/test.pl</A>
  will be mapped to /usr/apps/myproject/cgi-bin/test.pl . Basically you can
  have all your cgis located at the same place at filesystem, and to call the
  same script in any of 3 modes by just replacing the first directory of the
  URL (cgi-bin|perl|cgi-perl) - Isn't that cool? If something is going wrong
  with your mod_perl you can easily call the scripts in the mod_cgi mode
  without changing the script (in most cases) but only the URL to call it,
  and then to put it back!!!
  
  <P>
  Of course you can choose any other alias (you will use it later in
  http.conf), you can choose to use all 3 modes or only one of these (It's
  unlikely to run plain cgi-bin scripts from mod_perl server - the price is
  too high, you better run these at plain apache server. See
  <A HREF="././scenario.html#Making_a_strategic_decision">Real World scenario</A> for details)
  
  <P>
  <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  <CENTER><H1><A NAME="Configuration_of_Location">Configuration of Location</A></H1></CENTER>
  <P>
  Now we work with httpd.conf, I add all the mod_perl stuff at the end of
  file, after the native apache configurations finish.
  
  <P>
  First we add:
  
  <P>
  <PRE>  &lt;Location /perl&gt;
      #AllowOverride None
      SetHandler perl-script
      PerlHandler Apache::Registry
      Options ExecCGI
      allow from all
      PerlSendHeader On
    &lt;/Location&gt;
  </PRE>
  <P>
  This location's configuration makes all scripts that has been called with
  /perl path at the beginning to be executed under
  <STRONG>Apache::Registry</STRONG> module and as cgi (so the <CODE>ExecCGI</CODE>, if you omit this option the script will be just printed to the caller's
  browser as a plain text or will trigger the 'Save-As' window). 
  
  <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 it off for you nph (non-parsed-headers)
  scripts.
  
  <P>
  Remember the Alias from the section above? We must use the same Alias here,
  if you use Location that doesn't have the same Alias defined in srm.conf,
  the server will fail to locate the script at the filesystem. I'm talking
  about scripts execution (There are cases where Location is something that's
  being executed by the server itself, without having the corresponding file,
  like <A HREF="#perl_status">perl-status</A>)
  
  <P>
  Note that sometimes you will have to to add : PerlModule Apache::Registry
  
  <P>
  before you specify the location that uses Apache::Registry as a
  PerlHandler. Basically you can start running the scripts in the
  Apache::Registry mode...
  
  <P>
  You have to do nothing about /cgi-bin (mod_cgi), since it has nothing to do
  with mod_perl
  
  <P>
  A similar location configuration for Apache::PerlRun. (More about
  <A HREF="././porting.html#Apache_PerlRun_a_closer_look">Apache::PerlRun</A>)
  
  <P>
  <PRE>  &lt;Location /cgi-perl&gt;
      #AllowOverride None
      SetHandler perl-script
      PerlHandler Apache::PerlRun
      Options ExecCGI
      allow from all
      PerlSendHeader On
    &lt;/Location&gt;
  </PRE>
  <P>
  <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  <CENTER><H2><A NAME="perl_status_location">perl-status location</A></H2></CENTER>
  <P>
  /perl-status location allows you to see many things about your server. See
  /<A HREF="././status.html#Configuration">perl-status</A>
  
  <P>
  <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  <CENTER><H2><A NAME="perl_startup_file">perl-startup file</A></H2></CENTER>
  <P>
  Since many times you have to add many perl directives to the config file,
  it can be a good idea to put all of these into one file, so the config file
  will be cleaner, also you can call <CODE>perl -c perl-startup</CODE>
  to test the file's syntax. What is takes? Add this line to httpd.conf:
  
  <P>
  <PRE>    # startup.perl loads all functions that we want to use within mod_perl
    Perlrequire  /path/to/startup.pl
  </PRE>
  <P>
  An example of perl-startup file:
  
  <P>
  <PRE>  use strict;
    
    #modify @INC if needed
    use lib qw(/some/other/dir /some/bar/dir);
    
    # make sure we are in a sane environment.
    $ENV{GATEWAY_INTERFACE} =~ /^CGI-Perl/ or die &quot;GATEWAY_INTERFACE not Perl!&quot;;
     
    # for things in the &quot;/perl&quot; URL
    use Apache::Registry;          
     
    #load perl modules of your choice here
    #this code is interpreted *once* when the server starts
    use LWP::UserAgent ();
    use DBI ();
    
    # tell me more about warnings
    use Carp ();
    $SIG{__WARN__} = \&amp;amp;Carp::cluck;
    
    # Load CGI.pm and call its compile() method to precompile its autoloaded methods. 
    use CGI ();
    CGI-&gt;compile(':all');
    
  </PRE>
  <P>
  <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  <CENTER><H2><A NAME="PerlFreshRestart">PerlFreshRestart</A></H2></CENTER>
  <P>
  To reload <CODE>PerlRequire</CODE>, <CODE>PerlModule</CODE>, other <CODE>use()'d</CODE> modules and flush the Apache::Registry cache
  on server restart, add:
  
  <P>
  <PRE>  PerlFreshRestart On  
  </PRE>
  <P>
  <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  <CENTER><H2><A NAME="What_modules_should_you_add_to_t">What modules should you add to the startup file and why.</A></H2></CENTER>
  <P>
  Modules that are being loaded at the server startup will be shared among
  server children, so only one copy of each module will be loaded, thus
  saving a lot of RAM for you. 
  
  <P>
  See <A HREF="././performance.html#Preload_Perl_modules_at_server_s">Preload Perl modules at server startup</A> 
  
   
  
  <P>
  <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  <CENTER><H2><A NAME="Is_it_possible_to_preopen_a_DB_c">Is it possible to preopen a DB connection at the server startup?</A></H2></CENTER>
  <P>
  Yes! See <A HREF="././performance.html#Persistent_DB_Connections">Persistent DB Connections</A>
  
  <P>
  <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  <CENTER><H2><A NAME="Perl_behavior_controls">Perl behavior controls</A></H2></CENTER>
  <P>
  For <CODE>PerlWarn</CODE> and <CODE>PerlTaintCheck</CODE> see <A HREF="././porting.html#Switches_w_T">Switches -w, -T</A>
  
  <P>
  <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  <CENTER><H1><A NAME="Perl_Sections">Perl Sections</A></H1></CENTER>
  <P>
  With &lt;Perl&gt;&lt;/Perl&gt; sections, it is possible to configure your
  server entirely in Perl.  
  
  <P>
  &lt;Perl&gt; sections can contain *any* and as much Perl code as you wish.
  These sections are compiled into a special package who's symbol table
  mod_perl can then walk and grind the names and values of Perl
  variables/structures through the Apache core config gears. Most of the
  configurations directives can be represented as <CODE>$Scalars</CODE> or
  @Lists. A <CODE>@List</CODE> inside these sections is simply converted into
  a single-space delimited string for you inside. Here's an example:  
  
  <P>
  <PRE>  #httpd.conf
    &lt;Perl&gt;
    @PerlModule = qw(Mail::Send Devel::Peek);
   
    #run the server as whoever starts it
    $User  = getpwuid($&gt;) || $&gt;;
    $Group = getgrgid($)) || $); 
   
    $ServerAdmin = $User;
   
    &lt;/Perl&gt;
  </PRE>
  <P>
  Block sections such as &lt;Location&gt;&lt;/Location&gt; are represented in
  a %Hash, e.g.: 
  
  <P>
  <PRE>  $Location{&quot;/~dougm/&quot;} = {
      AuthUserFile =&gt; '/tmp/htpasswd',
      AuthType =&gt; 'Basic',
      AuthName =&gt; 'test',
      DirectoryIndex =&gt; [qw(index.html index.htm)],  
      Limit =&gt; {
      METHODS =&gt; 'GET POST',
      require =&gt; 'user dougm',
      },
    };
  </PRE>
  <P>
  If a Directive can take say, two *or* three arguments you may push strings
  and the lowest number of arguments will be shifted off the
  <CODE>@List</CODE> or use array reference to handle any number greater than
  the minimum for that directive push @Redirect, ``/foo'',
  ``http://www.foo.com/'';;
  
  <P>
  <PRE>  push @Redirect, &quot;/imdb&quot;, &quot;<A HREF="http://www.imdb.com/&quot">http://www.imdb.com/&quot</A>;;;
  </PRE>
  <P>
  <PRE>  push @Redirect, [qw(temp &quot;/here&quot; &quot;<A HREF="http://www.there.com&quot">http://www.there.com&quot</A>;;)];
  </PRE>
  <P>
  Other section counterparts include %VirtualHost, <CODE>%Directory</CODE>
  and %Files. 
  
  <P>
  These are somewhat boring examples, but they should give you the basic
  idea. You can mix in any Perl code your heart desires. See eg/httpd.conf.pl
  and eg/perl_sections.txt in mod_perl distribution for some examples. 
  
  <P>
  A tip for syntax checking outside of httpd: 
  
  <P>
  <PRE>  &lt;Perl&gt;
    #!perl
    
    #... code here ...
    
    __END__
    &lt;/Perl&gt;
  </PRE>
  <P>
  Now you may run perl -cx httpd.conf. 
  
  <P>
  To configure this feature build with 'perl Makefile.PL PERL_SECTIONS=1'  
  
  <P>
  <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  <CENTER><H1><A NAME="General_pitfalls">General pitfalls</A></H1></CENTER>
  <P>
  <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  <CENTER><H2><A NAME="My_cgi_perl_code_is_being_return">My cgi/perl code is being returned as a plain text instead of being executed by the webserver?</A></H2></CENTER>
  <P>
  Check your config files and make sure that the ``ExecCGI'' is turned on in
  your configurations. 
  
  <P>
  <PRE>  &lt;Location /perl&gt;
      SetHandler perl-script
      PerlHandler Apache::Registry
      Options ExecCGI
      allow from all
      PerlSendHeader On
    &lt;/Location&gt;
  </PRE>
  <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  <P><A HREF="index.html">[Back to the main page]</A></P>
  
  <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="mailto:sbekman@iil.intel.com">Stas Bekman</A>.
  	     <BR>Last Modified at 12/07/98 
        </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>
  	    
  
  <HR SIZE=6>
  <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
  <HTML>
  <HEAD>
     <TITLE>mod_perl guide: Server Controlling and Monitoring</TITLE>
     <META NAME="GENERATOR" CONTENT="Mozilla/3.04Gold (X11; I; AIX 4.1) [Netscape]">
     <META NAME="Author" CONTENT="Bekman Stas">
     <META NAME="Description" CONTENT="mod_perl,perl,apache">
     <META NAME="Keywords" CONTENT="mod_perl,perl,apache,webserver,cgi">
  </HEAD>
  <BODY TEXT="#000000" BGCOLOR="#E0FFFF" LINK="#0000EE" VLINK="#551A8B" ALINK="#FF0000">
  
  <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>
  Server Controlling and Monitoring</H1>
  <HR WIDTH="100%">
  	    <!-- INDEX BEGIN -->
  <P><A NAME="toc"></A><B><FONT SIZE=-1>Table of Contents:</FONT></B></P>
  <UL>
  
  	<LI><A HREF="#Restarting_techniques">Restarting techniques</A>
  	<LI><A HREF="#How_restart_influences_the_mod_p">How restart influences the mod_perl namespace</A>
  	<LI><A HREF="#Using_apachectl_to_control_the_s">Using apachectl to control the server</A>
  	<LI><A HREF="#Monitoring_the_Server_A_watchdo">Monitoring the Server. A watchdog.</A>
  	<LI><A HREF="#Single_Mode_Running">Single Mode Running</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>
  </UL>
  <!-- INDEX END -->
  
  <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  <P>
  <CENTER><H1><A NAME="Restarting_techniques">Restarting techniques</A></H1></CENTER>
  <P>
  In all these techniques you will have to know the server PID (Process ID).
  The easiest 
  
  <P>
  You will notice many httpd_perl executables running on your system, but you
  should not send signals to any of them except the parent, whose pid is in
  the PidFile. That is to say you shouldn't ever need to send signals to any
  process except the parent. There are three signals that you can send the
  parent: TERM, HUP, and USR1.
  
  <P>
  We will concentrate here at the implications of sending these signals to
  mod_perl server. To Read the complete doc at <A
  HREF="http://www.apache.org/docs/stopping.html">http://www.apache.org/docs/stopping.html</A>
  
  <DL>
  <P><DT><STRONG><A NAME="item_TERM">TERM Signal: stop now</A></STRONG><DD>
  <P>
  Sending the TERM signal to the parent causes it to immediately attempt to
  kill off all of its children. It may take it several seconds to complete
  killing off its children. Then the parent itself exits. Any requests in
  progress are terminated, and no further requests are served. 
  
  <P>
  That's the moment that the accumulated END{} blocks will be executed!
  
  <P><DT><STRONG><A NAME="item_HUP">HUP Signal: restart now</A></STRONG><DD>
  <P>
  Sending the HUP signal to the parent causes it to kill off its children
  like in TERM but the parent doesn't exit. It re-reads its configuration
  files, and re-opens any log files. Then it spawns a new set of children and
  continues serving hits. 
  
  <P>
  Server will rerun its config files. Flush all the compiled and preloaded
  modules. Rerun any startup files. It's equal to starting a server after it
  was stopped.
  
  <P>
  Note: If your configuration file has errors in it when you issue a restart
  then your parent will not restart, it will exit with an error. See below
  for a method of avoiding this. 
  
  <P><DT><STRONG><A NAME="item_USR1">USR1 Signal: graceful restart</A></STRONG><DD>
  <P>
  The USR1 signal causes the parent process to advise the children to exit
  after their current request (or to exit immediately if they're not serving
  anything). The parent re-reads its configuration files and re-opens its log
  files. As each child dies off the parent replaces it with a child from the
  new generation of the configuration, which begins serving new requests
  immediately. 
  
  <P>
  META: What's the exact difference between USR1 and HUP?
  
  </DL>
  <P>
  <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  <CENTER><H1><A NAME="How_restart_influences_the_mod_p">How restart influences the mod_perl namespace</A></H1></CENTER>
  <P>
  By default, if a server is restarted (ala kill -USR1 `cat logs/httpd.pid`),
  Perl scripts and modules are not reloaded. To reload PerlRequire's,
  PerlModule's, other <CODE>use()'d</CODE> modules and flush the
  Apache::Registry cache, enable with this command:
  
  <P>
  <PRE> PerlFreshRestart On              (in httpd.conf) 
  </PRE>
  <P>
  <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>
  apache's distribution provides a nice script to control the server. It's
  called apachectl and it's being installed into the same location with
  httpd. In our scenario - it's /usr/apps/sbin/httpd_perl/apachectl
  
  <P>
  Start httpd
  
  <P>
  <PRE>        % /usr/apps/sbin/httpd_perl/apachectl start 
  </PRE>
  <P>
  Stop httpd
  
  <P>
  <PRE>        % /usr/apps/sbin/httpd_perl/apachectl stop
  </PRE>
  <P>
  Restart httpd if running by sending a SIGHUP or start if not running
  
  <P>
  <PRE>        % /usr/apps/sbin/httpd_perl/apachectl restart
  </PRE>
  <P>
  Do a graceful restart by sending a SIGUSR1 or start if not running
  
  <P>
  <PRE>        % /usr/apps/sbin/httpd_perl/apachectl graceful    
  </PRE>
  <P>
  Do a configuration syntax test
  
  <P>
  <PRE>        % /usr/apps/sbin/httpd_perl/apachectl configtest 
  </PRE>
  <P>
  See the next section for the implication of the above calls.
  
  <P>
  Replace the httpd_perl to httpd_docs in the above calls to get the control
  over httpd_docs server.
  
  <P>
  There are other options for apachectl, use 'help' option to see them all
  
  <P>
  It's important to understand that this script is based on the PID file
  which is PIDFILE=/usr/apps/var/httpd_perl/run/httpd.pid. If you delete the
  file by hand - the apachectl will fail to run.
  
  <P>
  <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  <CENTER><H1><A NAME="Monitoring_the_Server_A_watchdo">Monitoring the Server. A watchdog.</A></H1></CENTER>
  <P>
  With mod_perl many things can happen to your server. The worse one is the
  possibility that the server will die when you will be not around. As with
  any other critical service you need to run some kind of watchdog.
  
  <P>
  One simple solution is to use a slightly modified apachectl script which I
  called apache.watchdog and to put it into the crontab to be called every 30
  minutes or even every minute - if it's so critical to make sure the server
  will be up all the time.
  
  <P>
  Crontab entry:
  
  <P>
  0,30 * * * * /path/to/the/apache.watchdog &gt;/dev/null 2&gt;&amp;1
  
  <P>
  The script:
  
  <P>
  <PRE>  #!/bin/sh
    
    # this script is a watchdog to see whether the server is online
    # It tries to restart the server if it's down and sends an email alert to admin
    
    # admin's email
    EMAIL=webmaster@somewhere.far
    #EMAIL=root@localhost
    
    # the path to your PID file
    PIDFILE=/usr/apps/var/httpd_perl/run/httpd.pid
    
    # the path to your httpd binary, including options if necessary
    HTTPD=/usr/apps/sbin/httpd_perl/httpd_perl
      
    # check for pidfile
    if [ -f $PIDFILE ] ; then
      PID=`cat $PIDFILE`
  </PRE>
  <P>
  <PRE>    if kill -0 $PID; then
        STATUS=&quot;httpd (pid $PID) running&quot;
        RUNNING=1
      else
        STATUS=&quot;httpd (pid $PID?) not running&quot;
        RUNNING=0
      fi
    else
      STATUS=&quot;httpd (no pid file) not running&quot;
      RUNNING=0
    fi
    
    if [ $RUNNING -eq 0 ]; then
      echo &quot;$0 $ARG: httpd not running, trying to start&quot;
      if $HTTPD ; then
        echo &quot;$0 $ARG: httpd started&quot;
        mail $EMAIL -s &quot;$0 $ARG: httpd started&quot; &lt;/dev/null &gt;&amp; /dev/null
      else
        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>
  Another approach, probably even more practical, is to use the Cool LWP perl
  package , to test the server by trying to fetch some document (script)
  served by the server. Why is it more practical? Since the while server can
  be up as a process, it can be stuck and not working (SYN_RECV state -
  anyone???), So 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>
  Again we put this script into a crontab to call it every 30 minutes. 
  
  <P>
  <PRE>  #!/usr/local/bin/perl -w
    
    use strict;
    use diagnostics;
    use URI::URL;
    use LWP::MediaTypes qw(media_suffix);
    
    my $VERSION = '0.01';
    use vars qw($ua $proxy);
    
    require LWP::UserAgent;
    use <A HREF="HTTP::Status">HTTP::Status</A>;
    
    ###### Config ########
    my $test_script_url = &quot;<A HREF="http://www.stas.com:81/perl/test.pl&quot">http://www.stas.com:81/perl/test.pl&quot</A>;;
    my $monitor_email = 'root@localhost';
    my $restart_command = '/usr/apps/sbin/httpd_perl/apachectl start';
    my $mail_program = &quot;/usr/lib/sendmail -t -n&quot;;   
    ######################
    
    $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;proxy('http', $proxy) if $proxy;
    
    # If returns '1' it's we are alive
    exit 1 if checkurl($test_script_url);
    
    # We have got the 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; 
     : &quot;Server is down. Can't restart.&quot;;
  </PRE>
  <P>
  <PRE>  my $subject = ($status == 0) 
      ? &quot;Attention! Webserver restarted&quot;
      : &quot;Attention! Webserver is down. can't restart&quot;;
  </PRE>
  <P>
  <PRE>  # email the monitoring person
    my $to = $monitor_email;
    my $from = $monitor_email;
    send_mail($from,$to,$subject,$message);
  </PRE>
  <P>
  <PRE>  # input:  URL to check 
    # output: 1 if success, o for fail  
    #######################  
    sub checkurl{
      my ($url) = @_;
    
      # Fetch document 
      my $res = $ua-&gt;request(<A HREF="HTTP::Request-&gt">HTTP::Request-&gt</A>;new(GET =&gt; $url));
    
      # Check the result status
      return 1 if is_success($res-&gt;code);
    
      # failed
      return 0;
    } #  end of sub checkurl
    
    # sends email about the problem 
    #######################  
    sub send_mail{
      my($from,$to,$subject,$messagebody) = @_;
  </PRE>
  <P>
  <PRE>    open MAIL, &quot;|$mail_program&quot; or die &quot;Can't open a pipe to a $mail_program :$!\n&quot;;
     
      print MAIL &lt;&lt;__END_OF_MAIL__;
    To: $to
    From: $from
    Subject: $subject
    
    $messagebody
    
    __END_OF_MAIL__
    
      close MAIL;
    } 
    
  </PRE>
  <P>
  <PRE>  &lt;META&gt;
    Is it possible to make the server do something when it dies? e.g
    restart itself :) NO, really when it dies , (killed in improper way?)
    is it possible to trigger some action?
  </PRE>
  <P>
  <PRE>  Ideas?
    &lt;/META&gt;
  </PRE>
  <P>
  <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  <CENTER><H1><A NAME="Single_Mode_Running">Single Mode Running</A></H1></CENTER>
  <P>
  Many times while developing a new code, you will want to run the server in
  the single process mode. See <A HREF="././porting.html#Sometimes_it_works_Sometimes_Not">Sometimes it works Sometimes Not</A> and <A HREF="././porting.html#Names_collisions_with_Modules_an">Names collisions with Modules and libs</A> 
  
   
  
  <P>
  <PRE>  % /usr/apps/sbin/httpd_perl/httpd_perl -X
  </PRE>
  <P>
  When you execute the above the server will run in the fg (foreground) of
  the shell you have called it from. So to kill you just kill it with Ctrl-C. 
  
  <P>
  Note that in -X mode the server will run very slowly on fetching the
  images. If you use Netscape while your server is running in single-process
  mode, the ``KeepAlive'' 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 KeepAlive in httpd.conf to avoid this effect while
  developing or you can press <STRONG>STOP</STRONG> after a few secs of run (assuming you use the image size params, so the
  Netscape will be able to render the rest of the page). 
  
  <P>
  In addition you should know that you will not see any control messages
  (when running with -X), you generally see in the error_log that the parent
  server writes: Like ``server started, server stopped and etc''. Since httpd
  -X runs immediately as a child, so there is no controlling parent to write
  all the status messages
  
  <P>
  <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  <CENTER><H1><A NAME="Starting_a_personal_server_for_e">Starting a personal server for each developer</A></H1></CENTER>
  <P>
  If you are the only developer working on the specific server:port - you
  have no problems, since you have a complete control over the server. Now
  many times you have a group of developers who need to concurrently develop
  their mod_perl scripts. It means that each one will want to get the control
  over the server - to kill it, to run it in single server mode, to restart
  it again and soon. As well to have to control over the log files and other
  configuration like MaxClients and etc . You can workaround this problem by
  preparing a few httpd.conf file and to force each developer to use: 
  
  <P>
  <PRE>  httpd_perl -f /path/to/httpd.conf  
  </PRE>
  <P>
  I've approached it in other way. I have used the -Dparameter startup option
  of the server. I call my version of the server 
  
  <P>
  <PRE>  % http_perl -Dsbekman
  </PRE>
  <P>
  At the end of the httpd.conf I wrote: # Personal development Server for
  sbekman # sbekman use the server running on port 8000 &lt;IfDefine
  sbekman&gt; Port 8000 PidFile
  /usr/apps/var/httpd_perl/run/httpd.pid.sbekman ErrorLog
  /usr/apps/var/httpd_perl/logs/error_log.sbekman Timeout 300 KeepAlive On
  MinSpareServers 2 MaxSpareServers 2 StartServers 1 MaxClients 3
  MaxRequestsPerChild 15 &lt;/IfDefine&gt;
  
  <P>
  <PRE>  # Personal development Server for userfoo
    # userfoo use the server running on port 8001
    &lt;IfDefine userfoo&gt;
    Port 8001
    PidFile /usr/apps/var/httpd_perl/run/httpd.pid.userfoo
    ErrorLog /usr/apps/var/httpd_perl/logs/error_log.userfoo
    Timeout 300
    KeepAlive Off
    MinSpareServers 1
    MaxSpareServers 2
    StartServers 1
    MaxClients 5
    MaxRequestsPerChild 0
    &lt;/IfDefine&gt;
  </PRE>
  <P>
  So what we have achieved with this technique is: A full control over
  start/stop, number of children, separate error log file, and different
  port. Now I wouldn't get the call every few minutes - ``Stas, I'm going to
  restart the server''.
  
  <P>
  To make things even more easier. (In the above technique, you have to
  discover the PID of your parent httpd_perl process - written in
  /usr/apps/var/httpd_perl/run/httpd.pid.userfoo) . We change the apachectl
  script to do the work for us. We make a copy for each developer called
  apachectl.username and we change 2 lines in script:
  
  <P>
  <PRE>  PIDFILE=/usr/apps/var/httpd_perl/run/httpd.pid.sbekman
    HTTPD='/usr/apps/sbin/httpd_perl/httpd_perl -Dsbekman'
  </PRE>
  <P>
  Of course you think you can use only one control file and to know who is
  calling by using uid, but since you have to be root to start the server -
  it's not so simple. 
  
  <P>
  The last thing was to let developers an option to run in single process
  node by:
  
  <P>
  <PRE>  /usr/apps/sbin/httpd_perl/httpd_perl -Dsbekman -X
  </PRE>
  <P>
  In addition to make life easier we decided to use relative links everywhere
  in the static docs (including the calls to cgis). You will ask how using
  the relative link you will get to the right server? Very simple - we have
  utilized the mod_rewrite to solve our problems:
  
  <P>
  In access.conf of the httpd_docs server we have the following code: (you
  have to configure your httpd_docs server with --enable-module=rewrite )
  
  <P>
  <PRE>  # sbekman' server
    # port = 8000
    RewriteCond  %{REQUEST_URI} ^/(perl|cgi-perl)  
    RewriteCond  %{REMOTE_ADDR} 123.34.45.56
    RewriteRule ^(.*)           <A HREF="http://ourserver.com:8000/">http://ourserver.com:8000/</A>$1 [R,L]
    
    # userfoo's server
    # port = 8001
    RewriteCond  %{REQUEST_URI} ^/(perl|cgi-perl)  
    RewriteCond  %{REMOTE_ADDR} 123.34.45.57
    RewriteRule ^(.*)           <A HREF="http://ourserver.com:8001/">http://ourserver.com:8001/</A>$1 [R,L]
    
    # all the rest
    RewriteCond  %{REQUEST_URI} ^/(perl|cgi-perl)  
    RewriteRule ^(.*)           <A HREF="http://ourserver.com:81/">http://ourserver.com:81/</A>$1 [R]
    
  </PRE>
  <P>
  where IP numbers are then IPs of the developers they run the browser at. (I
  have tried to use REMOTE_USER since we have all the users authenticated but
  it didn't work for me)
  
  <P>
  So if I have a relative URL like /perl/test.pl written in some html or even
  <A
  HREF="http://ourserver.com/perl/test.pl">http://ourserver.com/perl/test.pl</A>
  in my case (user at machine of sbekman) it will be redirected by httpd_docs
  to <A
  HREF="http://ourserver.com:8000/perl/test.pl">http://ourserver.com:8000/perl/test.pl</A>
    
  
  <P>
  Of course you have another problem: The cgi generates some html, which
  should be called again. If it generates a URL with hard coded PORT the
  above scheme will not work. There 2 solutions:
  
  <P>
  First to generate relative URL so it will reuse the technique above, with
  redirect (which is transparent for user) but it will not work if you have
  something to POST (redirect looses all the data!)
  
  <P>
  Second to use a general config module which generates a correct full URL
  according to REMOTE_USER, so if $ENV{REMOTE_USER} eq 'sbekman', I return <A
  HREF="http://ourserver.com:8000/perl/">http://ourserver.com:8000/perl/</A>
  as cgi_base_url. Again this will work if the user is authenticated.
  
  <P>
  All this good for development. It's better to use the full URLs in
  production, since if you have a static form and the Action is relative but
  the static document sits on another server, pressing form's submit will
  cause a redirect to mod_perl server, but all the form's data will be lost
  during the redirect.
  
  <P>
  <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>
  Many times you start off with debugging your script by running it at your
  favorite shell. Sometimes you encounter a very weird situation when script
  runs from the shell but dies when called as cgi. The real problem lays in
  the difference of the environment that's being used by your server and your
  shell. An example can be a different perl path or having PERL5LIB env
  variable which includes paths that aren't in the <CODE>@INC</CODE> of the
  perl compiled with mod_perl server and configured during the startup.
  
  <P>
  The best thing is to write a wrapper that emulates the exact environment of
  the server, By deleting first the environment variables like PERL5LIB and
  calling the same perl that it's being used by the server. Then setting the
  environment identical to the server's by copying the perl run directives
  from server startup and config files. It'll also allow you to remove
  completely the first line of the script - since mod_perl skip it and
  wrapper knows how to call the script
  
  <P>
  Below is the example of such a script. Note that we force the -wT when we
  call the real script. (I have also added the ability to pass params, which
  is not happen when you call the cgi from the web)
  
  <P>
  <PRE>  #!/usr/apps/bin/perl -w    
     
    # This is a wrapper example 
     
    # It simulates the web server environment by setting the @INC and other
    # stuff, so what will run under this wrapper will run under web and
    # vice versa. 
    
    #
    # Usage: wrap.pl some_cgi.pl
    #
    
    BEGIN{
      use vars qw($basedir);
      $basedir = &quot;/usr/apps&quot;;
    
      # we want to make a complete emulation, so we must remove the
      # user's environment
      @INC = ();
  </PRE>
  <P>
  <PRE>    # local perl libs
      push @INC, (&quot;$basedir/lib/perl5/5.00502/aix&quot;,
                  &quot;$basedir/lib/perl5/5.00502&quot;,
                  &quot;$basedir/lib/perl5/site_perl/5.005/aix&quot;,
                  &quot;$basedir/lib/perl5/site_perl/5.005&quot;,
                 );
    }
    
    use strict;
    use <A HREF="File::Basename">File::Basename</A>;
    
      # process the passed params
    my $cgi = shift || '';
    my $params = (@ARGV) ? join(&quot; &quot;, @ARGV) : '';
    
    die &quot;Usage:\n\t$0 some_cgi.pl\n&quot; unless $cgi;
    
      # Set the environment
    my $PERL5LIB = join &quot;:&quot;, @INC;
    
      # if the path includes the directory we extract it and chdir there
    if ($cgi =~ m|/|) {
      my $dirname = dirname($cgi);
      chdir $dirname or die &quot;Can't chdir to $dirname: $! \n&quot;;
      $cgi =~ m|$dirname/(.*)|;
      $cgi = $1;
    }
    
      # run the cgi from the script's directory
      # Note that we invoke warnings and Taintness ON!!!
    system qq{$basedir/bin/perl -I$PERL5LIB -wT $cgi $params};
  </PRE>
  <P>
  <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 little bit off topic but good to know.
  
  <P>
  To rotate the logs do:
  
  <P>
  <PRE>  mv access_log access_log.renamed
    kill -USR1 `cat httpd.pid`
    sleep 10; # allow some children to complete requests and logging
    # now it's safe to use access_log.renamed
    .....
  </PRE>
  <P>
  The effect of SIGUSR1 is detailed in: <A
  HREF="http://www.apache.org/docs/stopping.html">http://www.apache.org/docs/stopping.html</A>
  <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  <P><A HREF="index.html">[Back to the main page]</A></P>
  
  <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="mailto:sbekman@iil.intel.com">Stas Bekman</A>.
  	     <BR>Last Modified at 12/07/98 
        </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>
  	    
  
  <HR SIZE=6>
  <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
  <HTML>
  <HEAD>
     <TITLE>mod_perl guide: CGI => mod_perl Porting. mod_perl Coding guidelines.</TITLE>
     <META NAME="GENERATOR" CONTENT="Mozilla/3.04Gold (X11; I; AIX 4.1) [Netscape]">
     <META NAME="Author" CONTENT="Bekman Stas">
     <META NAME="Description" CONTENT="mod_perl,perl,apache">
     <META NAME="Keywords" CONTENT="mod_perl,perl,apache,webserver,cgi">
  </HEAD>
  <BODY TEXT="#000000" BGCOLOR="#E0FFFF" LINK="#0000EE" VLINK="#551A8B" ALINK="#FF0000">
  
  <H1 ALIGN=CENTER>
  <A HREF="http://perl.apache.org"><IMG SRC="images/mod_perl.gif" ALT="Mod Perl Icon" BORDER=0 HEIGHT=30 WIDTH=90 ALIGN=LEFT></A>
  <A HREF="http://perl.apache.org"><IMG SRC="images/mod_perl.gif" ALT="Mod Perl Icon" BORDER=0 HEIGHT=30 WIDTH=90 ALIGN=RIGHT></A>
  CGI => mod_perl Porting. mod_perl Coding guidelines.</H1>
  <HR WIDTH="100%">
  	    <!-- INDEX BEGIN -->
  <P><A NAME="toc"></A><B><FONT SIZE=-1>Table of Contents:</FONT></B></P>
  <UL>
  
  	<LI><A HREF="#Document_Coverage">Document Coverage</A>
  	<LI><A HREF="#Before_you_start_to_code">Before you start to code</A>
  	<LI><A HREF="#Coding_with_mod_perl">Coding with mod_perl</A>
  	<UL>
  
  		<LI><A HREF="#What_s_different_about_modperl">What's different about modperl</A>
  		<UL>
  
  			<LI><A HREF="#Script_s_namespace">Script's namespace</A>
  			<LI><A HREF="#Names_collisions_with_Modules_an">Names collisions with Modules and libs</A>
  			<LI><A HREF="#_END_or_DATA_tokens">__END__ or __DATA__ tokens</A>
  			<LI><A HREF="#Output_from_system_calls">Output from system calls</A>
  			<LI><A HREF="#using_exit_">using exit()</A>
  			<LI><A HREF="#Running_from_shell">Running from shell</A>
  			<LI><A HREF="#I_O_is_different">I/O is different</A>
  			<LI><A HREF="#HTTP_MIME_Headers">HTTP (MIME) Headers</A>
  			<LI><A HREF="#NPH_Non_Parsed_Headers_scripts">NPH (Non Parsed Headers) scripts </A>
  			<LI><A HREF="#BEGIN_blocks">BEGIN blocks </A>
  			<LI><A HREF="#END_blocks">END blocks </A>
  			<LI><A HREF="#Switches_w_T">Switches -w, -T </A>
  		</UL>
  
  		<LI><A HREF="#strict_pragma">strict pragma</A>
  		<LI><A HREF="#Turning_warnings_ON">Turning warnings ON</A>
  		<LI><A HREF="#diagnostics_pragma">diagnostics pragma</A>
  		<LI><A HREF="#Global_Variables">Global Variables</A>
  		<LI><A HREF="#Code_has_been_changed_but_seems">Code has been changed, but seems that script uses the old code</A>
  		<LI><A HREF="#Memory_leakages">Memory leakages</A>
  		<LI><A HREF="#Sometimes_it_works_Sometimes_Not">Sometimes it works Sometimes Not (Very important!)</A>
  		<LI><A HREF="#The_Script_is_too_dirty_It_does">The Script is too dirty, It does the job and I can't afford rewriting it.</A>
  		<LI><A HREF="#Apache_PerlRun_a_closer_look">Apache::PerlRun - a closer look</A>
  	</UL>
  
  </UL>
  <!-- INDEX END -->
  
  <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  <P>
  <CENTER><H1><A NAME="Document_Coverage">Document Coverage</A></H1></CENTER>
  <P>
  This document is relevant for both - writing a new cgi from scratch and
  migrating from the plain cgi to mod_perl. 
  
  <P>
  If you are in the porting stage use it as a reference for possible problems
  you might encounter when running the existent CGI in the new mode.
  
  <P>
  If you are about to write a new cgi from scratch, it would be a good idea
  to learn most of the possible pitfalls and to avoid them in first place.
  
  <P>
  It covers also the case when the script is too dirty, but does the job and
  I can't afford rewriting it. (Apache::PerlRun)
  
  <P>
  If your project in hurry, I would think of the following steps: First run
  all the scripts in the Apache::PerlRun mode - then as time allows you, move
  them into Apache::Registry mode.
  
  <P>
  <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  <CENTER><H1><A NAME="Before_you_start_to_code">Before you start to code</A></H1></CENTER>
  <P>
  It can be a good idea to strength some of the programming skills, since
  Apache::Registry doesn't allow sloppiness programming.
  
  <P>
  You might want to read:
  
  <UL>
  <P><LI><STRONG><A NAME="item_Perl">Perl Module Mechanics</A></STRONG>
  <P>
  This page describes the mechanics of creating, compiling, releasing and
  maintaining Perl modules. <A
  HREF="http://world.std.com/~swmcd/steven/perl/module_mechanics.html">http://world.std.com/~swmcd/steven/perl/module_mechanics.html</A>
  
  <P><LI><STRONG><A NAME="item_Mod">Mod Perl Book</A></STRONG>
  <P>
  (when it will be released) - you can find parts of the book online at <A
  HREF="http://www.modperl.com.">http://www.modperl.com.</A> 
  
  </UL>
  <P>
  <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  <CENTER><H1><A NAME="Coding_with_mod_perl">Coding with mod_perl</A></H1></CENTER>
  <P>
  First, before you start coding for Apache::Registry you have to change the
  state of your mind. Scripts running under mod_perl are like subroutines are
  being called from the daemon who runs all the time. Imagine the daemon
  process that when requested to process some of the scripts - reads it in,
  compiles it as a subroutine and finally executes it. On any consequent
  request it'll just recall the already compiled subroutine. Hope that you
  get the idea.
  
  <P>
  The best thing you do when coding from scratch is to make it clean and use
  packages, as you go thru the notes you will understand why.
  
  <P>
  <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  <CENTER><H2><A NAME="What_s_different_about_modperl">What's different about modperl</A></H2></CENTER>
  <P>
  There are a few things that behaves differently under mod_perl. It's good
  to know what they are.
  
  <P>
  <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  <CENTER><H3><A NAME="Script_s_namespace">Script's namespace</A></H3></CENTER>
  <P>
  Scripts under Apache::Registry don't not run in package <STRONG>main</STRONG>, they run in a unique namespace based on the requested uri. e.g if your
  uri is /perl/test.pl the package will be called
  Apache::ROOT::perl::test_2epl;
  
  <P>
  <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  <CENTER><H3><A NAME="Names_collisions_with_Modules_an">Names collisions with Modules and libs</A></H3></CENTER>
  <P>
  Just to make things clear before we go into details: each server process
  has its own <CODE>%INC</CODE> array which is used to store the information
  about compiled modules. Where the keys are the names of the modules or
  parameters passed to <CODE>require().</CODE> And values are the real paths
  to these modules. So if you do (assume it's in the <CODE>@INC</CODE> path)
  
  <P>
  <PRE>  require &quot;./my/lib.pl&quot;; 
  </PRE>
  <P>
  where <CODE>./my/lib.pl</CODE> is actually a <CODE>/home/httpd/perl/my/lib.pl</CODE>. The following entry will show up in the <CODE>%INC</CODE>
  
  <P>
  <PRE>  $INC{&quot;./my/lib.pl&quot;} = &quot;/home/httpd/perl/my/lib.pl&quot;;
  </PRE>
  <P>
  I'm talking about single server child below!
  
  <P>
  You can't have 2 identical module names running under the same server! Only
  the first one <CODE>use()d</CODE> or <CODE>require()d</CODE> will be
  compiled into the package, the request to the other identical module will
  be skipped since server will think that it's already compiled. It'll be
  already in child's %INC. (See <A HREF="././status.html#Watching_the_server">Watching the server</A> 
  section to find out how you can know what is loaded and where)
  
  <P>
  So if you have 
  
  <P>
  <PRE>  cgi/tool1/Foo.pm 
    cgi/tool1/tool1.pl
    cgi/tool2/Foo.pm 
    cgi/tool2/tool2.pl
  </PRE>
  <P>
  And both scripts do: <CODE>use Foo;</CODE> only the first one called will know about Foo, when you will call the
  second script it will not know about Foo at all - it's like you've
  forgotten to write <CODE>use Foo;</CODE>. Run the server in the <A HREF="././control.html#Single_Mode_Running">single server mode</A> to solve that kind of bugs immediately.
  
  <P>
  You will see the following in the error_log file:
  
  <P>
  <PRE>  Undefined subroutine
    &amp;Apache::ROOT::perl::test_2epl::some_function called at
    /home/httpd/perl/test.pl line 10. 
  </PRE>
  <P>
  The above is true for the files you require as well (assuming that the
  required files do not declare a package). If you have:
  
  <P>
  <PRE>  cgi/tool1/config.pl
    cgi/tool1/tool1.pl
    cgi/tool2/config.pl
    cgi/tool2/tool2.pl
  </PRE>
  <P>
  And both scripts do:
  
  <P>
  <PRE>  use lib qw(.);
    require &quot;config.pl&quot;;
  </PRE>
  <P>
  Only the first one will do the require, all for the same reason that
  <CODE>%INC</CODE> already includes the key ``config.pl''!
  
  <P>
  There are 3 workarounds for that: (make sure you read the whole item 3)
  
  <OL>
  <P><LI>
  <P>
  Add some special path so the fs layout will be something like
  
  <P>
  <PRE>  cgi/tool1/Tool1/Foo.pm 
    cgi/tool1/tool1.pl
    cgi/tool2/Tool2/Foo.pm 
    cgi/tool2/tool2.pl
  </PRE>
  <P>
  And you change the scripts:
  
  <P>
  <PRE>  use Tool1::Foo;
    use Tool2::Foo;
  </PRE>
  <P>
  and respectively the package declaration in the modules: 
  
  <P>
  <PRE>  package Tool1::Foo;
    package Tool2::Foo;
  </PRE>
  <P>
  For require:
  
  <P>
  <PRE>  cgi/tool1/tool1-lib/config.pl
    cgi/tool1/tool1.pl
    cgi/tool2/tool2-lib/config.pl
    cgi/tool2/tool2.pl
  </PRE>
  <P>
  And each script does respectively:
  
  <P>
  <PRE>  use lib qw(.);
    require &quot;tool1-lib/config.pl&quot;;
  </PRE>
  <P>
  <PRE>  use lib qw(.);
    require &quot;tool2-lib/config.pl&quot;;
  </PRE>
  <P><LI>
  <P>
  Or use a full path to the script, so it'll be compiled into the name of the
  key in the %INC;
  
  <P>
  <PRE>  require &quot;/full/path/to/the/config.pl&quot;;
  </PRE>
  <P>
  But than you loose portability! (I mean if you move the tool around in the
  filesystem you will have to change the base dir)
  
  <P><LI>
  <P>
  Declare a package in the required files! (Of course it should be unique to
  the rest of the package names you use!) The <CODE>%INC</CODE> will use the
  package name for the key!
  
  <P>
  But then you will have to use Package::function() method unless you will
  export the symbols from the <CODE>use()d</CODE> package like
  
  <P>
  <PRE>  use Package qw(:all_subs);
  </PRE>
  <P>
  This is a bad approach since it'll consume more memory for the current
  process.
  
  <P>
  <STRONG>Important:</STRONG> Only this solution will work, if you have 2 scripts that
  <CODE>require()</CODE> the same file! 
  
  <P>
  <PRE>  cgi/tool1/config.pl
    cgi/tool1/tool_1.pl
    cgi/tool1/tool_2.pl
  </PRE>
  <P>
  and both tool_1.pl and tool_2.pl do:   
  
  <P>
  <PRE>  use lib qw(.);
    require &quot;config.pl&quot;;
  </PRE>
  <P>
  Here playing with dir name or using the full path will not help! You must
  declare a package inside the files that are being <CODE>require()d!</CODE>
  
  </OL>
  <P>
  Read also perlmodlib and perlmod manpages.
  
  <P>
  From the above discussion it should be clear that you can't run a
  development and a production versions of the tools on the same server! You
  have to run a separate server for each.
  
  <P>
  <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  <CENTER><H3><A NAME="_END_or_DATA_tokens">__END__ or __DATA__ tokens</A></H3></CENTER>
  <P>
  Apache::Registry scripts cannot contain __END__ or __DATA__ tokens 
  
  <P>
  <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  <CENTER><H3><A NAME="Output_from_system_calls">Output from system calls</A></H3></CENTER>
  <P>
  Output of system, exec and open PIPE, ``|program'' calls will not be sent
  to the browser unless you Perl was configured with sfio. 
  
  <P>
  <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  <CENTER><H3><A NAME="using_exit_">using exit()</A></H3></CENTER>
  <P>
  Perl's <CODE>exit()</CODE> built-in function cannot be used in mod_perl
  scripts. Unless you want the server child to exit (which makes the whole
  idea of using mod_perl irrelevant). The Apache::exit() function should be
  used instead. Apache::exit() automatically overrides the built-in
  <CODE>exit()</CODE> for Apache::Registry scripts.   
  
  <P>
  You might start you scripts with overriding the exit sub (if you use
  directly the Apache::exit() you will have the problem to test the script
  from the shell, unless you stuff <CODE>use Apache ();</CODE> into your code. I use the following code:
  
  <P>
  <PRE>  BEGIN {
        # Auto-detect if we are running under mod_perl or CGI.
      $USE_MOD_PERL = ( (exists $ENV{'GATEWAY_INTERFACE'} and $ENV{'GATEWAY_INTERFACE'} =~ /CGI-Perl/)
                        or exists $ENV{'MOD_PERL'} ) ? 1 : 0;
    }
    use subs (exit);
  </PRE>
  <P>
  <PRE>  # Select the correct exit way
    ########
    sub exit{
        # Apache::exit(-2) will cause the server to exit gracefully,
        # once logging happens and protocol, etc  (-2 == Apache::Constants::DONE)
      $USE_MOD_PERL ? Apache::exit(0) : CORE::exit(0);
    }
  </PRE>
  <P>
  Now every time the select will be called the correct exit will be picked,
  no matter if you run the script as cgi or from shell.
  
  <P>
  <STRONG>Note</STRONG> that if you run the script under Apache::Registry, <STRONG>The Apache
  function `exit' overrides the Perl core built-in function</STRONG>. While you see the <CODE>exit()</CODE> listed in <CODE>@EXPORT_OK</CODE>
  of Apache package, Apache::Registry makes something you don't see and
  imports this function for you.
  
  <P>
  <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  <CENTER><H3><A NAME="Running_from_shell">Running from shell</A></H3></CENTER>
  <P>
  Your scripts <CODE>*will</CODE> not* run from the command line (yet) unless
  you use CGI::Switch or CGI.pm and 5.004+ and do not make any direct calls
  to Apache-&gt;methods. Since it's different environment and See also above.
  
  <P>
  <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  <CENTER><H3><A NAME="I_O_is_different">I/O is different</A></H3></CENTER>
  <P>
  If you are using Perl 5.004 most CGI scripts can run under mod_perl
  untouched. If you're using 5.003, Perl's built-in <CODE>read()</CODE> and
  <CODE>print()</CODE> functions do not work as they do under CGI. If you're
  using CGI.pm, use $query-&gt;print instead of plain 'ol
  <CODE>print().</CODE>  
  
  <P>
  <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  <CENTER><H3><A NAME="HTTP_MIME_Headers">HTTP (MIME) Headers</A></H3></CENTER>
  <P>
  By default, mod_perl does not send any headers by itself, however, you may
  wish to change this (in httpd.conf):  
  
  <P>
  <PRE>  PerlSendHeader On   
  </PRE>
  <P>
  Now the response line and common headers will be sent as they are by
  mod_cgi. And, just as with mod_cgi, PerlSendHeader will not send a
  terminating newline, your script must send that itself, e.g.:  
  
  <P>
  <PRE>  print &quot;Content-type: text/html\n\n&quot;;
  </PRE>
  <P>
  If you're using CGI.pm or CGI::Switch and 'print $q-&gt;header' you do
  _not_ need PerlSendHeader On. 
  
  <P>
  <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  <CENTER><H3><A NAME="NPH_Non_Parsed_Headers_scripts">NPH (Non Parsed Headers) scripts</A></H3></CENTER>
  <P>
  To run a Non Parsed Header CGI script under mod_perl, simply add to your
  code: 
  
  <P>
  <PRE> local $| = 1;
  </PRE>
  <P>
  And If you normally set PerlSendHeader On, add this to your httpd.conf: 
  
  <P>
  <PRE> &lt;Files */nph-*&gt;
   PerlSendHeader Off
   &lt;/Files&gt;
  </PRE>
  <P>
  <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  <CENTER><H3><A NAME="BEGIN_blocks">BEGIN blocks</A></H3></CENTER>
  <P>
  Perl executes BEGIN blocks during the compile time of code as soon as
  possible. The same is true under mod_perl. However, since mod_perl normally
  only compiles scripts and modules once, in the parent server or once
  per-child, BEGIN blocks in that code will only be run once. As perlmod
  explains, once a BEGIN has run, it is immediately undefined. In the
  mod_perl environment, this means BEGIN blocks will not be run during each
  incoming request unless that request happens to be one that is compiling
  the code.
  
  <P>
  Modules and files pulled in via require/use which contain BEGIN blocks will
  be executed: - only once, if pulled in by the parent process - once
  per-child process if not pulled in by the parent process - an additional
  time, once per-child process if the module is pulled in off of disk again
  via Apache::StatINC - an additional time, in the parent process on each
  restart if PerlFreshRestart is On - unpredictable if you fiddle with
  <CODE>%INC</CODE> yourself
  
  <P>
  Apache::Registry scripts which contain BEGIN blocks will be executed: -
  only once, if pulled in by the parent process via Apache::RegistryLoader -
  once per-child process if not pulled in by the parent process - an
  additional time, once per-child process if the script file has changed on
  disk - an additional time, in the parent process on each restart if pulled
  in by the parent process via Apache::RegistryLoader and PerlFreshRestart is
  On
  
  <P>
  <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  <CENTER><H3><A NAME="END_blocks">END blocks</A></H3></CENTER>
  <P>
  As perlmod explains, an END subroutine is executed as late as possible,
  that is, when the interpreter is being exited. In the mod_perl environment,
  the interpreter does not exit until the server is shutdown. However,
  mod_perl does make a special case for Apache::Registry scripts.
  
  <P>
  Normally, END blocks are executed by Perl during it's
  <CODE>perl_run()</CODE> function, which is called once each time the Perl
  program is executed, e.g. once per (mod_cgi) CGI scripts. However, mod_perl
  only calls <CODE>perl_run()</CODE> once, during server startup. Any END
  blocks encountered during main server startup, i.e. those pulled in by the
  PerlRequire or by any PerlModule are suspended and run at server shutdown,
  aka child_exit (requires apache 1.3b3+). Any END blocks that are
  encountered during compilation of Apache::Registry scripts are called after
  the script done is running, including subsequent invocations when the
  script is cached in memory. All other END blocks encountered during other
  Perl*Handler callbacks, e.g. PerlChildInitHandler, will be suspended while
  the process is running and called during child_exit when the process is
  shutting down. Module authors may be wish to use $r-&gt;register_cleanup as
  an alternative to END blocks if this behavior is not desirable.
  
  <P>
  <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  <CENTER><H3><A NAME="Switches_w_T">Switches -w, -T</A></H3></CENTER>
  <P>
  Normally when you run perl from the command line or have the shell invoke
  it with `#!', you may choose to pass perl switch arguments such as -w or
  -T. Since the command line is only parsed once, when the server starts,
  these switches are unavailable to mod_perl scripts. However, most command
  line arguments have a equivalent special variable. For example, the $^W
  variable corresponds to the -w switch. Consult perlvar for more details.
  With mod_perl it is also possible to turn on warnings globally via the
  PerlWarn directive: 
  
  <P>
  <PRE>  PerlWarn On
  </PRE>
  <P>
  You can turn it off with <CODE>local $^W = 0;</CODE> in your scripts on the local basis (or inside the block).
  
  <P>
  The switch which enables taint checks does not have a special variable, so
  mod_perl provides the PerlTaintCheck directive to turn on taint checks. In
  httpd.conf, enable with:
  
  <P>
  <PRE>  PerlTaintCheck On
  </PRE>
  <P>
  Now, any and all code compiled inside httpd will be checked. 
  
  <P>
  The environment variable PERL5OPT can be used to set additional perl
  startup flags such as -d and -D. See perlrun.
  
  <P>
  <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  <CENTER><H2><A NAME="strict_pragma">strict pragma</A></H2></CENTER>
  <P>
  It's absolutely mandatory to start all your scripts with:
  
  <P>
  <PRE>  use strict;   (at least for development)
  </PRE>
  <P>
  If you need you can always to turn off the 'strict' pragma inside the
  block, e.g:
  
  <P>
  <PRE>  {
      no strict 'refs';
      ... some code
    }
  </PRE>
  <P>
  It's more important to have use strict enabled under mod_perl Perl than
  anywhere else, while it's not required, it strongly recommended, it will
  save you more time in the long run. And, of course, clean scripts will
  still run under mod_cgi (plain CGI)!
  
  <P>
  <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  <CENTER><H2><A NAME="Turning_warnings_ON">Turning warnings ON</A></H2></CENTER>
  <P>
  Have a <CODE>$^W=1</CODE> in the script or PerlWarn ON at the server config file. Turning the warning
  on will save you a lot of troubles with debugging your code. Note that
  first magic line <CODE>#!/perl -swithces</CODE>
  #is ignored by mod_perl so do the switches you used to write there.
  
  <P>
  If you need you can always turn off the warning with <CODE>$^W = 0</CODE> in your code, if you have some section you don't want the perl compiler to
  warn in.
  
  <P>
  In a production code it can be a good idea to have the Warnings Off.
  Otherwise if your code isn't very clean and spits a few lines of warns here
  and there, you will end up with a huge error_log file in a short time on
  the loaded server.
  
  <P>
  <CODE>use diagnostics;</CODE> can put more light on the errors and warns you see, But you better don't
  use <CODE>use diagnostics;</CODE>
  in the production, since you end up in a huge overhead of the diagnostics
  pragma. (run the script with -dDprof to check the overhead. See
  Devel::Dprof for more info) 
  
  <P>
  <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>
  Perl compiler pragma to force verbose warning diagnostics. Put at the start
  of your scripts:
  
  <P>
  <PRE>  use diagnostics;
  </PRE>
  <P>
  This pragma turns on the -w mode, but gives you a much better diagnostics
  of the errors and warnings. Generally it explains the reason for
  warnings/errors you get, shows you an example of code, where the same kind
  of warning is being triggered and tells you the remedy.
  
  <P>
  It's a bad idea to keep it in your production code! Since it'll spit
  zillions of diagnostics lines into your error_log file. And it'll add
  significant overhead to the cgi's runtime. (I discovered this by using
  Devel::DProf!)
  
  <P>
  <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  <CENTER><H2><A NAME="Global_Variables">Global Variables</A></H2></CENTER>
  <P>
  It's always a good idea to stay away from global variables when possible.
  Some variables must be global so Perl can see them, such as a module's
  <CODE>@ISA</CODE> or <CODE>$VERSION</CODE> variables. In common practice, a
  combination of use strict and use vars keeps modules clean and reduces a
  bit of noise. However, use vars also creates aliases as the Exporter does,
  which eat up more space. When possible, try to use fully qualified names
  instead of use vars. Example:
  
  <P>
  <PRE>  package MyPackage;
    use strict;
    @MyPackage::ISA = qw(...);
    $MyPackage::VERSION = &quot;1.00&quot;;
  </PRE>
  <P>
  <PRE>  vs.
  </PRE>
  <P>
  <PRE>  package MyPackage;
    use strict;
    use vars qw(@ISA $VERSION);
    @ISA = qw(...);
    $VERSION = &quot;1.00&quot;;
  </PRE>
  <P>
  <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  <CENTER><H2><A NAME="Code_has_been_changed_but_seems">Code has been changed, but seems that script uses the old code</A></H2></CENTER>
  <P>
  Files pulled in via use or require statements are not automatically
  reloaded when changed on disk. See <A HREF="././obvious.html#Reloading_Modules_and_Required_F">Reloading Modules and Required Files</A> for more info.
  
  <P>
  <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  <CENTER><H2><A NAME="Memory_leakages">Memory leakages</A></H2></CENTER>
  <P>
  Scripts under mod_perl can very easily leak memory! Global variables stay
  around indefinitely, lexical variables (declared with &lt;Cmy()&gt; are
  destroyed when they go out of scope, provided there are no references to
  them from outside of that scope. 
  
  <P>
  Perl doesn't return back the memory it acquired from the kernel. It does
  reuse it so! 
  
  <P>
  <STRONG>First example</STRONG> is file reading:
  
  <P>
  <PRE>  open IN, $file or die $!;
    $/ = undef; # will read the whole file in
    $content = &lt;IN&gt;;
    close IN;
  </PRE>
  <P>
  If you file is of a 5Mb - The child who served that script will grow
  exactly by that size. Now if you have 20 children and all of them will
  serve this cgi, all of them will consume additional 20*5M = 100M of RAM! If
  that's the case try to use other approaches of processing the file, if
  possible of course. Try to process line at a time and print it back to the
  file (if you need to modify the file itself, use temporary file for that,
  when finished overwrite the src file, make sure to provide locking
  mechanism!) 
  
  <P>
  <STRONG>Second example</STRONG> is copying variables between functions (passing variables by value). Let's
  use the example above. Assuming we have no choice and the whole file had to
  be read before any data processing. Now you have a very nice sub
  <CODE>process()</CODE> that processes the data and returns it back. What
  happens if you pass the <CODE>$content</CODE> by value? You have just
  copied another 5M and the child has grew up up by another 5M in size (watch
  your swap space!) now multiply it again by factor of 10 you have 200M of
  wasted RAM, which will be apparently reused but it's a waste! Whenever you
  think the variable can grow bigger than few Kb pass it by reference! Once I
  wrote the script that passed a content of the little DB to the function and
  it was OK, but then the DB become huge - I had to make a decision, whether
  to buy more memory or to rewrite the code. So it's better to plan ahead and
  pass the variables by reference. There are few approaches for that:
  
  <P>
  <PRE>  sub process{
      my $content_r = shift; 
    ... some processing on $$content here ($$var_r - dereference the scalar)
    [nothing returned - the variable $content outside is already changed
    }
    process(\$content);
  </PRE>
  <P>
  @{$var_lr} - dereference an array %{$var_hr} = dereference a hash
  
  <P>
  For more see <CODE>perldoc perlref</CODE>
  
  <P>
  Other approach would be to use directly the <CODE>@_</CODE> variable. Using
  directly the <CODE>@_</CODE> array serves the job of passing by reference!
  
  <P>
  <PRE>  sub process{
      $_[0] =~ s/A/a/gs; 
    ... some processing on $_[0] here 
    [nothing returned - the variable $content outside is already changed
    }
    process($content);
  </PRE>
  <P>
  From <CODE>perldoc perlsub</CODE>: The array <CODE>@_</CODE> is a local array, but its elements are aliases
  for the actual scalar parameters. In particular, if an element $_[0] is
  updated, the corresponding argument is updated (or an error occurs if it is
  not possible to update).... 
  
  <P>
  <STRONG>Third example</STRONG> is work with DataBases. If you do some DB processing, many times you have
  lots of records that you read into you program, and then print them to the
  browser after they were formatted. (I even don't mention the horrible case
  where programmers read in the whole DB and then let the perl to process
  it!!! Use relational DB and let the SQL do the job, so you get only the
  records you need!!!)
  
  <P>
  We will use DBI for that (assume we are already connected to the DB) (read
  perldoc DBI for complete info):
  
  <P>
  <PRE>  $sth-&gt;execute;
    while(@row_ary  = $sth-&gt;fetchrow_array;) {
          &lt;do DB accumulation into some variable&gt;
    } 
    &lt;print the output using the the data returned from the DB&gt;
  </PRE>
  <P>
  In the example above the httpd_process will grow up by the size of the
  variables that have been allocated for the records that matched the query.
  (Again remember to multiply it by the number of the children server runs!)
  
  <P>
  What you want to do is to not accumulate the records but print them as they
  are fetched from the DB. More over we use a bind_col and
  $sth-&gt;fetchrow_arrayref (aliased to $sth-&gt;fetch) methods, to get the
  the fastest way to fetch data. The example below prints the TABLE with
  matched data, the only memory that is being used is a <CODE>@cols</CODE>
  
  <P>
  <PRE>  my @select_fields = qw(a b c);
        # create a list of cols values
    my @cols = ();
    @cols[0..$#select_fields] = ();
    $sth = $dbh-&gt;prepare($do_sql);
    $sth-&gt;execute;
      # Bind perl variables to columns.
    $sth-&gt;bind_columns(undef,\(@cols));
    print &quot;&lt;TABLE&gt;&quot;;
    while($sth-&gt;fetch) {
     print &quot;&lt;TR&gt;&quot;;
     print map { &quot;&lt;TD&gt;$_&lt;/TD&gt;&quot; } @cols;
     print &quot;&lt;/TR&gt;&quot;;
    }
    print &quot;&lt;/TABLE&gt;&quot;;
  </PRE>
  <P>
  Note: the above method doesn't allow you to know how many records has been
  matched. The workaround is to run an identical query before the code above
  where you use 'SELECT <CODE>count(*)</CODE> ...' instead of 'SELECT * ...',
  so you get the number of matched records.
  
  <P>
  Just as a bonus, I wanted to write a single sub that process any query but
  very flexible, since it accepts: conditions, callback closure sub, select
  fields and restrictions. 
  
  <P>
  <PRE>  # $o-&gt;dump(\%conditions,\&amp;callback_closure,\@select_fields,@restrictions)
    sub dump{
      my $self = shift;
      my %param = %{+shift}; # dereference hash
      my $rsub = shift;
      my @select_fields = @{+shift}; # dereference list
      my @restrict = shift || '';
    
        # create a list of cols values
      my @cols = ();
      @cols[0..$#select_fields] = ();
    
      my $do_sql = '';
      my @where = ();
    
        # make a @where list 
      map { push @where, &quot;$_=\'$param{$_}\'&quot; if $param{$_};} keys %param;
    
        # prepare the sql statement
      $do_sql = &quot;SELECT &quot;;
      $do_sql .= join(&quot; &quot;, @restrict) if @restrict;# append the restriction list
      $do_sql .= &quot; &quot; .join(&quot;,&quot;, @select_fields) ;      # append the select list 
      $do_sql .= &quot; FROM $DBConfig{TABLE} &quot;;         # from table
  </PRE>
  <P>
  <PRE>      # we will not add the WHERE clause if @where is empty
      $do_sql .= &quot; WHERE &quot; . join &quot; AND &quot;, @where if @where;
    
      print &quot;SQL: $do_sql \n&quot; if $debug;
        
      $dbh-&gt;{RaiseError} = 1;     # do this, or check every call for errors
      $sth = $dbh-&gt;prepare($do_sql);
      $sth-&gt;execute;
        # Bind perl variables to columns.
      $sth-&gt;bind_columns(undef,\(@cols));
      while($sth-&gt;fetch) {
        &amp;$rsub(@cols);
      }
        # print the tail or &quot;no records found&quot; message according to the previous calls
      &amp;$rsub();
    
    } # end of sub dump
  </PRE>
  <P>
  Now a callback closure sub can do lots of things. We need a closure to know
  what stage are we in: header, body or tail. For example a callback closure
  for formatting the rows we want to print: 
  
  <P>
  <PRE>  my $rsub = eval {
        # make a copy of @fields list, since it might go out of scope when this closure will be called
      my @fields = @fields; 
      my @query_fields = qw(user dir tool act); # no date field!!!
      my $header = 0;
      my $tail   = 0;
      my $counter = 0;
      my %cols = (); # columns name=&gt; value hash
   
      # Closure with the following behavior:
      # 1. Header's code will be executed on the first call only and if @_ was set
      # 2. Row's printing code will be executed on every call with @_ set
      # 3. Tail's code will be executed only if Header's code was printed and @_ isn't set
      # 4. &quot;No record found&quot; code will be executed if Header's code wasn't executed
      
      sub {
            # Header
          if (@_ and !$header){
            print &quot;&lt;TABLE&gt;\n&quot;;
            print $q-&gt;Tr(map{ $q-&gt;td($_) } @fields );
            $header = 1; 
          }
          
            # Body
          if (@_) {
            print $q-&gt;Tr(map{$q-&gt;td($_)} @_ );
            $counter++;
            return; 
          }
          
            # Tail, will be printed only at the end
          if ($header and !($tail or @_)){
            print &quot;&lt;/TABLE&gt;\n $counter records found&quot;;
            $tail = 1;
            return;
          }
          
            # No record found
          unless ($header){
            print $q-&gt;p($q-&gt;center($q-&gt;b(&quot;No record was found!\n&quot;)));
          }
  </PRE>
  <P>
  <PRE>      }  #  end of sub {}
    };  #  end of my $rsub = eval {
  </PRE>
  <P>
  You might want to check also <A HREF="././performance.html#Limiting_the_size_of_the_process">Limiting the size of the processes</A>
   and <A HREF="././performance.html#Limiting_the_resources_used_by_h">Limiting the resources used by httpd children</A>
  
  <P>
  <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  <CENTER><H2><A NAME="Sometimes_it_works_Sometimes_Not">Sometimes it works Sometimes Not (Very important!)</A></H2></CENTER>
  <P>
  When you start running the scripts under mod_perl you might find yourself
  in situation that scripts seems to work, but sometimes it screws up. And
  the more it runs without restart the more it screws up. Many times you can
  resolve this problem very easily. You have to test your script under with
  Server running as a 
  <A HREF="././control.html#Single_Mode_Running">single process</A> 
  
   
  
  <P>
  Generally the problem you have is using global variables. Since global
  variables don't change from one script invocation to another unless you
  change it, you can find your scripts do ``fancy'' things.
  
  <P>
  The first example is amazing. Web Services. Imagine that you enter some
  site you have your account on (Free Email Account?). Now you want to see
  what other users read
  
  <P>
  You type in your name and passwd, and you are expecting to enter to your
  account, but instead to enter the account of someone else. This is cool
  isn't it? Is it a bug or feature. (For some of us it's a feature, while for
  others it's a bug :( You say, why in the world this happens? The answer is
  simple: Global Variables. You have entered the account of someone who
  happened to be served by the same server child as you, because of the
  sloppiness programming, the global variable was not reset at the beginning
  of the program and voila you can easily peek into other people emails! You
  would ask it can't happen, since you have entered the login and passwd. I
  tell you, it happens! See for yourself:
  
  <P>
  <PRE>  use vars ($authenticated);
    my $q = new CGI; 
    my $username = $q-&gt;param('username');
    my $passwd   = $q-&gt;param('passwd');
    authenticate($username,$passwd);
      # failed, break out
    die &quot;Wrong passwd&quot; unless $authenticated == 1;
      # user is OK, fetch user's data
    show_user($username);
  </PRE>
  <P>
  <PRE>  sub authenticate{
      my ($username,$passwd) = @_;
          # some checking
      $authenticated = 1 if (SOMETHING);
    }
  </PRE>
  <P>
  Do you see the catch? I can type in any valid username and any dummy passwd
  and enter that's user account, with the code above if someone has
  successfully entered his account before me using the same child process!
  Since <CODE>$authenticated</CODE> is global - if it becomes 1 once it'll be
  1 for the whole child's life!!! The solution is trivial - reset the
  <CODE>$authenticated</CODE> to 0 at the beginning of the program. (Or many
  other different solution). Of course the example is too trivial - but
  believe me it happens!
  
  <P>
  Just another little one liner that can make your day spoiled, assuming you
  forgot to reset the $allowed. It's perfectly OK in plain mod_cgi :
  
  <P>
  <PRE>  $allowed = 1 if $username eq 'admin'; # 
  </PRE>
  <P>
  But you will let any user to admin your system with the line above (again
  assuming you have used the same child prior to some user request) 
  
  <P>
  Another good example is usage of /o in regexp. After you restart the server
  most likely you will not detect the problem, if on every request you will
  use a different pattern that will be used in regexp and it'll happen that
  each time a different child will serve the new request. Only arriving to
  the child who has already cached the regexp will reveal the problem, but
  generally you miss that and when you press reload - You see that it works
  (new fresh child) and then it doesn't (child that already cached the regexp
  and wouldn't recompile because of /o). 
  
  <P>
  So to make sure you don't miss these bugs always test your CGI in
  <A HREF="././control.html#Single_Mode_Running">single process</A>. To solve this particular <STRONG>/o</STRONG> problem refer to <A HREF="././obvious.html#Regular_Expressions">Regular Expressions</A>   
  
     
  
  <P>
  <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  <CENTER><H2><A NAME="The_Script_is_too_dirty_It_does">The Script is too dirty, It does the job and I can't afford rewriting it.</A></H2></CENTER>
  <P>
  You still can win from using mod_perl. 
  
  <P>
  One approach it to replace the Apache::Registry handler with
  Apache::PerlRun and defined a new location (the script can reside in the
  same directory on the disk. 
  
  <P>
  <PRE>  # srm.conf
    ScriptAlias /cgi-perl/ /home/httpd/cgi/
    
    # httpd.conf
    &lt;Location /cgi-perl&gt;
      #AllowOverride None
      SetHandler perl-script
      PerlHandler Apache::PerlRun
      Options ExecCGI
      allow from all
      PerlSendHeader On
    &lt;/Location&gt;
  </PRE>
  <P>
  See <A HREF="#">Apache::PerlRun - a closer look</A>
  
  <P>
  Another ``bad'', but working method is to set MaxRequestsPerChild to 1,
  which will force each child to exit after serving only one request, so
  you'll get the preloaded modules, etc., the script will be compiled each
  request, then killed off. This isn't good for ``high-traffic'' sites
  though, as the parent server will need to fork a new child each time one is
  killed, but you can fiddle with MaxStartServers, MinSpareServers, to make
  the parent spawn more servers ahead so the killed one will be immediately
  replaced with the fresh one. Again, probably that's not what you want.
  
  <P>
  <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  <CENTER><H2><A NAME="Apache_PerlRun_a_closer_look">Apache::PerlRun - a closer look</A></H2></CENTER>
  <P>
  Apache::PerlRun gives you a benefit of preloaded perl and its modules. This
  module's handler emulates the CGI environment, allowing programmers to
  write scripts that run under CGI or mod_perl without any change. Unlike
  Apache::Registry, the Apache::PerlRun handler does not cache the script
  inside of a subroutine. Scripts will be ``compiled'' on each request. After
  the script has run, it's namespace is flushed of all variables and
  subroutines. Still, you don't have the overhead of loading the perl and
  compilation time of the standard modules (If your script is very light, but
  uses lots of standard modules - you will see no difference between
  Apache::PerlRun and Apache::Registry !).
  
  <P>
  Be aware though, that if you use some packages that use internals variables
  that has circular references, they will be not flushed!!!
  
  <P>
  Apache::PerlRun only flushes your script's namespace, which does not
  include any other required package's namespace. If there's a reference to
  <CODE>my()</CODE> scoped variable that's keeping it from being DESTROYed
  after leaving the eval scope (of Apache::PerlRun), that cleanup might not
  be taken care of until the server is shutdown and
  <CODE>perl_destruct()</CODE> is run, which always happens after running
  command line scripts. Consider this example:
  
  <P>
  <PRE>  package Foo;
    sub new { bless {} }
    sub DESTROY {
      warn &quot;Foo-&gt;DESTROY\n&quot;;
    }
  </PRE>
  <P>
  <PRE>  eval &lt;&lt;'EOF';
    package my_script;
    my $self = Foo-&gt;new;
    #$self-&gt;{circle} = $self;
    EOF
  </PRE>
  <P>
  <PRE>  print $@ if $@;
    print &quot;Done with script\n&quot;;
  </PRE>
  <P>
  First you'll see:
  
  <P>
  <PRE>  Foo-&gt;DESTROY
    Done with script
  </PRE>
  <P>
  Then, uncomment the line where <CODE>$self</CODE> makes a circular
  reference, and you'll see:
  
  <P>
  <PRE>  Done with script
    Foo-&gt;DESTROY
  </PRE>
  <P>
  In this case, under mod_perl you wouldn't see 'Foo-&gt;DESTROY' until the
  server shutdown, or your module properly took care of things.
  
  <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  <P><A HREF="index.html">[Back to the main page]</A></P>
  
  <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="mailto:sbekman@iil.intel.com">Stas Bekman</A>.
  	     <BR>Last Modified at 12/07/98 
        </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>
  	    
  
  <HR SIZE=6>
  <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
  <HTML>
  <HEAD>
     <TITLE>mod_perl guide: What is obvious for others but not for you</TITLE>
     <META NAME="GENERATOR" CONTENT="Mozilla/3.04Gold (X11; I; AIX 4.1) [Netscape]">
     <META NAME="Author" CONTENT="Bekman Stas">
     <META NAME="Description" CONTENT="mod_perl,perl,apache">
     <META NAME="Keywords" CONTENT="mod_perl,perl,apache,webserver,cgi">
  </HEAD>
  <BODY TEXT="#000000" BGCOLOR="#E0FFFF" LINK="#0000EE" VLINK="#551A8B" ALINK="#FF0000">
  
  <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>
  What is obvious for others but not for you</H1>
  <HR WIDTH="100%">
  	    <!-- INDEX BEGIN -->
  <P><A NAME="toc"></A><B><FONT SIZE=-1>Table of Contents:</FONT></B></P>
  <UL>
  
  	<LI><A HREF="#Coverage">Coverage</A>
  	<LI><A HREF="#my_scoped_variable_in_the_nest">my() scoped variable in the nested subroutine</A>
  	<LI><A HREF="#Reloading_Modules_and_Required_F">Reloading Modules and Required Files</A>
  	<UL>
  
  		<LI><A HREF="#Restarting_the_server">Restarting the server</A>
  		<LI><A HREF="#Using_Apache_StatINC">Using Apache::StatINC</A>
  		<LI><A HREF="#Reloading_only_specific_files">Reloading only specific files</A>
  	</UL>
  
  	<LI><A HREF="#Compiled_Regular_Expressions">Compiled Regular Expressions </A>
  	<LI><A HREF="#Debugging_your_code_in_Single_Se">Debugging your code in Single Server Mode</A>
  	<LI><A HREF="#_M_and_other_time_file_tests_u">-M and other time() file tests under mod_perl</A>
  </UL>
  <!-- INDEX END -->
  
  <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  <P>
  <CENTER><H1><A NAME="Coverage">Coverage</A></H1></CENTER>
  <P>
  This document describes a ``special'' traps of running your plain cgis
  under Apache::Registry and Apache::PerlRun
  
  <P>
  <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  <CENTER><H1><A NAME="my_scoped_variable_in_the_nest">my() scoped variable in the nested subroutine</A></H1></CENTER>
  <P>
  When you write a code like:
  
  <P>
  <PRE>    #!perl -w
      my $x;
      sub y {
         $x
      }
  </PRE>
  <P>
  there is no problem. But when you write:
  
  <P>
  <PRE>    #!perl -w
      sub x {
        my $x;
        sub y {
           $x
        }
      }
  </PRE>
  <P>
  it produces this warning:
  
  <P>
  <PRE>  Value of $x will not stay shared at - line 5.
  </PRE>
  <P>
  The tone of this message is definite because the code *will* fail if
  <CODE>&amp;x</CODE> is called more than once. NOTE: Subroutines defined
  inside BEGIN{} and END{} cannot trigger this message, since each BEGIN{}
  and END{} is known to be called exactly once. (To understand why, read
  about the closures at perlref or perlfaq 13.12)
  
  <P>
  Also, this slightly different code:
  
  <P>
  <PRE>   #!perl -w
     sub x {
        my $x;
        sub y {
           sub { $x }
        }
     }
  </PRE>
  <P>
  produces this warning:
  
  <P>
  <PRE>  Value of $x may be unavailable at - line 5.
  </PRE>
  <P>
  This message is less definite because the code can work correctly, if
  <CODE>&amp;y</CODE> is called only from inside &amp;x.
  
  <P>
  (this was partially extracted from perl5-porters post)
  
  <P>
  Now hold on, you ask what it has to do with your cgi script?
  
  <P>
  That's exactly the point that is not obvious. Apache::Registry wraps your
  code into a sub! You heard it right. So all your code's subs are nested.
  And while you don't see it, your code actually is the same as the simple
  snippet above. And all the behavior described above applies to your code!
  
  <P>
  A solution? 
  
  <P>
  <PRE>  use vars qw($x $a); at the top of you code
  </PRE>
  <P>
  Also see the clarification of <CODE>my()</CODE> vs. <CODE>use vars</CODE> - Ken Williams writes:
  
  <P>
  <PRE>  Yes, there's quite a bit of difference!  With use vars(), you're
    making an entry in the symbol table, and you're telling the compiler
    that you're going to be referencing that entry without an explicit
    package name.
  </PRE>
  <P>
  <PRE>  With my(), NO ENTRY IS PUT IN THE SYMBOL TABLE.  The compiler figures
    out _at_ _compile_time_ which my() variables (i.e. lexical variables)
    are the same as each other, and once you hit execute time you can't go
    looking those variables up in the symbol table.
  </PRE>
  <P>
  And <CODE>my()</CODE> vs. <CODE>local()</CODE> - Randal Schwartz writes:
  
  <P>
  <PRE>  local() creates a temporal-limited package-based scalar, array, hash,
    or glob -- when the scope of definition is exited at runtime, the
    previous value (if any) is restored.  References to such a variable
    are *also* global... only the value changes.  (Aside: that's what
    causes variable suicide. :)
  </PRE>
  <P>
  <PRE>  my() creates a lexically-limited non-package-based scalar, array, or
    hash -- when the scope of definition is exited at compile-time, the
    variable ceases to be accessible.  Any references to such a variable
    at runtime turn into unique anonymous variables on each scope exit.
  </PRE>
  <P>
  <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  <CENTER><H1><A NAME="Reloading_Modules_and_Required_F">Reloading Modules and Required Files</A></H1></CENTER>
  <P>
  When you develop your plain cgi scripts you just change the code, and rerun
  the cgi in your browser. Since the script wasn't staying in the memory, the
  next time you call it - server recompile it from scratch so all the changes
  you apply are immediately taking the expected effect.
  
  <P>
  The situation is different with Apache::Registry. Since the whole idea was
  to get the maximum performance from the server. By default server wouldn't
  spend the time to go and check whether the code has been changed. It
  assumes that it wasn't, thus saving a few millisecs to stat the file (And
  if you have many of them it takes more time). The only check that is being
  done is whether your main script has been changed. So if you have only one
  script that doesn't require or use other Perl Modules (packages) there is
  nothing new about it. The files you <CODE>use()</CODE> or
  <CODE>require()</CODE> aren't being checked at all. So what are the
  workarounds?
  
  <P>
  <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  <CENTER><H2><A NAME="Restarting_the_server">Restarting the server</A></H2></CENTER>
  <P>
  See <A HREF="././control.html#Restarting_techniques">Server Restarting techniques</A>.
  
  <P>
  <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  <CENTER><H2><A NAME="Using_Apache_StatINC">Using Apache::StatINC</A></H2></CENTER>
  <P>
  After restarting the server for about 100 times you will be tired and will
  look for another solutions. Here comes for a help the Apache::StatINC
  module. 
  
  <P>
  Read its pod pages, but beware of the following note: Only the modules
  located in <CODE>@INC</CODE> are being reloaded on change, and you can
  change the <CODE>@INC</CODE> only before the server has been started.
  Whatever you do in you scripts/modules which are being
  <CODE>required()</CODE> after the server startup will not take an effect on
  @INC. When you do use lib <CODE>qw(foo/bar);</CODE> the <CODE>@INC</CODE>
  is being changed only for the time the code is being parsed. When it's over
  the <CODE>@INC</CODE> is being reset to its original value. To make sure
  that you have set a correct <CODE>@INC</CODE> fetch <A
  HREF="http://your.perl.server/perl-status?inc">http://your.perl.server/perl-status?inc</A>
  and watch the bottom of the page. (I consider you have configured the
  &lt;Location /perl-status&gt; section in httpd.conf as modperl docs shows.
  
  <P>
  <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  <CENTER><H2><A NAME="Reloading_only_specific_files">Reloading only specific files</A></H2></CENTER>
  <P>
  However checking all the Modules in <CODE>@INC</CODE> can add a big
  overhead to server response times, and you certainly wouldn't want
  Apache::StatINC module to be enabled in your production site's
  configuration. But sometimes you want to have some Configuration file
  (module) to be reloaded without restarting the whole server. For this you
  will have to add something like this in your code:
  
  <P>
  Assume that you started your scripts with:
  
  <P>
  <PRE>  use lib &quot;/some/private/path&quot;;
    use Foo::Bar qw(:subs);
  </PRE>
  <P>
  Now to make a modification test and reload at runtime you have to use
  something like this:
  
  <P>
  <PRE>  # child's global variable to keep the timestamps 
    use vars qw(%MODIFIED);
    
    my $my_lib_root = &quot;/some/private/path&quot;;
    my $conf        = &quot;Foo/Bar.pm&quot;;
    my $conf_path   = &quot;$my_lib_root/$conf&quot;;
    
      # set modification time if it wasn't set before
      # Note: Use (stat $conf_path)[9] instead of -M test, if you reset
      # time with $^M=time
    $MODIFIED{$conf} ||= -M $conf_path;
    
      # now check whether it was changed (assuming the above wasn't
      # performed in this session
    if ($MODIFIED{$conf} != -M $conf_path){
        # only if deleted from %INC the require will be called below
      delete $INC{$conf};
    
          # this should be safe since @INC is being reset after we leave
          # the script, or you can skip this stage and require the script
          # with full path, remember that @INC now is different from the
          # one you have had when the script has been called at first time
      unshift @INC,$my_lib_root;
    
          # reread the file : use() wouldn't work here since it's compile time directive
      require Foo::Bar; 
    
          # now export the symbols (if you need them back :)
      import Foo::Bar qw(:subs);
    
          # Update the MODIFICATION times
      $MODIFIED{$conf} = -M $conf_path;
    }
  </PRE>
  <P>
  You will want to add debug printings to test this code in your application
  
  <P>
  Read also use versus require article for more info.
  (http://www.perl.com/CPAN-local/doc/FMTEYEWTK/use_vs_require)
  
  <P>
  <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  <CENTER><H1><A NAME="Compiled_Regular_Expressions">Compiled Regular Expressions</A></H1></CENTER>
  <P>
  When using a regular expression that contains an interpolated Perl
  variable, if it is known that the variable (or variables) will not vary
  during the execution of the program, a standard optimization technique
  consists of adding the o modifier to the regexp pattern, to direct the
  compiler to build the internal table once, for the entire lifetime of the
  script, rather than every time the pattern is executed. Consider:
  
  <P>
  <PRE>  my $pat = '^foo$'; # likely to be input from an HTML form field
    foreach( @list ) {
      print if /$pat/o;
    }
  </PRE>
  <P>
  This is usually a big win in loops over lists, or when using grep or map. 
  
  <P>
  In long-lived mod_perl scripts, however, this can pose a problem if the
  variable changes according to the invocation. The first invocation of a
  fresh httpd child will compile the table and perform the search correctly,
  however, all subsequent uses by the httpd child will continue to match the
  original pattern, regardless of the current contents of the Perl variables
  the pattern is dependent on. Your script will appear broken.
  
  <P>
  There are two solutions to this problem. 
  
  <P>
  The first is to use eval q//, to force the code to be evaluated each time.
  Just make sure that the eval block covers the entire loop of processing,
  and not just the pattern match itself.
  
  <P>
  The above code fragment would be rewritten as: 
  
  <P>
  <PRE>  my $pat = '^foo$';
    eval q{
      foreach( @list ) {
        print if /$pat/o;
      }
    }
  </PRE>
  <P>
  Just saying 
  
  <P>
  <PRE>  eval q{ print if /$pat/o; };
  </PRE>
  <P>
  is going to be a horribly expensive proposition. 
  
  <P>
  You use this approach if you require more than one pattern match operator
  in a given section of code. If the section contains only one operator (be
  it an m// or s///), you can rely on the property of the null pattern, that
  reuses the last pattern seen. This leads to the second solution, which also
  eliminates the use of eval.
  
  <P>
  The above code fragment becomes: 
  
  <P>
  <PRE>  my $pat = '^foo$';
    &quot;something&quot; =~ /$pat/; # dummy match (MUST NOT FAIL!)
    foreach( @list ) {
      print if //;
    }
  </PRE>
  <P>
  The only gotcha is that the dummy match that boots the regular expression
  engine must absolutely, positively succeed, otherwise the pattern will not
  be cached, and the // will match everything. If you can't count on fixed
  text to ensure the match succeeds, you have two possibilities.
  
  <P>
  If you can guarantee that the pattern variable contains no meta-characters
  (things like *, +, ^, $...), you can use the dummy match:
  
  <P>
  <PRE>  &quot;$pat&quot; =~ /\Q$pat\E/; # guaranteed if no meta-characters present
  </PRE>
  <P>
  If there is a possibility that the pattern can contain meta-characters, you
  should search for the pattern or the unsearchable \377 character as
  follows:
  
  <P>
  <PRE>  &quot;\377&quot; =~ /$pat|^[\377]$/; # guaranteed if meta-characters present
  </PRE>
  <P>
  Phil. Chu contributed this:
  
  <P>
  It depends on the complexity of the regexp you apply this technique to. One
  common usage where compiled regexp is usually more efficient is to ``match
  any one of a group of patterns'' over and over again.
  
  <P>
  Maybe with some helper routine, it's easier to remember. Here is one
  slightly modified from Jeffery Friedl's example in his book ``Mastering
  Regex.''. I find it quite useful:
  
  <P>
  <PRE>  #####################################################
    # Build_MatchMany_Function
    # -- Input:  list of patterns
    # -- Output: A code ref which matches its $_[0]
    #            against ANY of the patterns given in the
    #            &quot;Input&quot;, efficiently.
    #
    sub Build_MatchMany_Function {
      my @R = @_;
      my $expr = join '||', map { &quot;\$_[0] =~ m/\$R[$_]/o&quot; } ( 0..$#R );
      my $matchsub = eval &quot;sub { $expr }&quot;;
      die &quot;Failed in building regex @R: $@&quot; if $@;
      $matchsub;
    }
  </PRE>
  <P>
  Example usage:
  
  <P>
  <PRE>  @some_browsers = qw(Mozilla Lynx MSIE AmigaVoyager lwp libwww);
    $Known_Browser=Build_MatchMany_Function(@some_browsers);
  </PRE>
  <P>
  <PRE>  while (&lt;ACCESS_LOG&gt;) {
      # ...
      $browser = get_browser_field($_);
      if ( ! &amp;$Known_Browser($browser) ) {
        print STDERR &quot;Unknown Browser: $browser\n&quot;;
      }
      # ...
    }
  </PRE>
  <P>
  <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  <CENTER><H1><A NAME="Debugging_your_code_in_Single_Se">Debugging your code in Single Server Mode</A></H1></CENTER>
  <P>
  Running in httpd -X mode. (good only for testing during development phase).
  
  <P>
  You want to test your application that it handles correctly the global
  variables (if you have such - The less you have them the better, but
  sometimes you just can't without them). It's hard to test with multiply
  servers serving your cgi since each child has a different value for its
  global variables. Imagine that you have a <CODE>random()</CODE> sub that
  returns a random number and you have the following script.
  
  <P>
  <PRE>  use vars qw($num);
    $num ||= random();
    print ++$num;
  </PRE>
  <P>
  This script initializes the <CODE>$num</CODE> with random value, then it
  increments on each request and print it out. Running this script in
  multiply server environment will result in something like 1,9,4,19 (number
  per reload), since ``each'' time your script will be served by a different
  child. (On some OSes parent process assign all the requests to the same
  child process if all of the children are idle... AIX...). But if you run in
  httpd -X single server mode you will get 2,3,4,5... (taken that the
  <CODE>random()</CODE> returned 1 at the first call)
  
  <P>
  But don't get too obsessive with this mode, since working only in single
  server mode sometimes hides problems that show up when you switch to multi
  server mode. Assume the following code:
  
  <P>
  Application that allows you to change the configuration at the run time.
  Let's say the script produce a form to change the background color of the
  page. (It's not a good idea but for the sake of potential problem
  presentation we will assume that we don't write down the change on the
  disk). So you have typed in a new color , and as a respond you print back
  the html with a new color - you think that's it! It was so simple. And if
  you keep running in single server mode you will never notice that you have
  a problem... If you run the same code in the multi server environment ,
  after you submit the color change you will get the result as expected, but
  when you will call the same URL again (not reload!) most of the chances
  that you will get back the old color, since except the child who processed
  the color change request no one knows about their global variable change.
  Just remember that children can't share information, but the stuff they
  inherited from parent on their load.
  
  <P>
  Also note that since server run in single mode - If the output returns HTML
  with IMG tags, the load of these will take a lot of time (read apache docs
  of httpd -X to learn why).
  
  <P>
  <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  <CENTER><H1><A NAME="_M_and_other_time_file_tests_u">-M and other time() file tests under mod_perl</A></H1></CENTER>
  <P>
  Under mod_perl files that have been created after the server's (child?)
  startup are being reported with negative age with -M (-C -A) test. This is
  obvious if you remember that you will get the negative result if the server
  was started before the file was created and it's a normal behavior with any
  perl.
  
  <P>
  If you want to have -M test to count the time relative to the current
  request, you should reset the $^T variable as with any other perl script.
  Just add <CODE>$^T = time;</CODE> at the beginning of the scripts.
  
  <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  <P><A HREF="index.html">[Back to the main page]</A></P>
  
  <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="mailto:sbekman@iil.intel.com">Stas Bekman</A>.
  	     <BR>Last Modified at 12/07/98 
        </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>
  	    
  
  <HR SIZE=6>
  <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
  <HTML>
  <HEAD>
     <TITLE>mod_perl guide: Warnings and Errors: Where and Why.</TITLE>
     <META NAME="GENERATOR" CONTENT="Mozilla/3.04Gold (X11; I; AIX 4.1) [Netscape]">
     <META NAME="Author" CONTENT="Bekman Stas">
     <META NAME="Description" CONTENT="mod_perl,perl,apache">
     <META NAME="Keywords" CONTENT="mod_perl,perl,apache,webserver,cgi">
  </HEAD>
  <BODY TEXT="#000000" BGCOLOR="#E0FFFF" LINK="#0000EE" VLINK="#551A8B" ALINK="#FF0000">
  
  <H1 ALIGN=CENTER>
  <A HREF="http://perl.apache.org"><IMG SRC="images/mod_perl.gif" ALT="Mod Perl Icon" BORDER=0 HEIGHT=30 WIDTH=90 ALIGN=LEFT></A>
  <A HREF="http://perl.apache.org"><IMG SRC="images/mod_perl.gif" ALT="Mod Perl Icon" BORDER=0 HEIGHT=30 WIDTH=90 ALIGN=RIGHT></A>
  Warnings and Errors: Where and Why.</H1>
  <HR WIDTH="100%">
  	    <!-- INDEX BEGIN -->
  <P><A NAME="toc"></A><B><FONT SIZE=-1>Table of Contents:</FONT></B></P>
  <UL>
  
  	<LI><A HREF="#A_general_advice">A general advice </A>
  	<LI><A HREF="#Value_of_x_will_not_stay_shared">Value of $x will not stay shared at - line 5</A>
  	<LI><A HREF="#Value_of_x_may_be_unavailable_a">Value of $x may be unavailable at - line 5.</A>
  	<LI><A HREF="#Constant_subroutine_redefine">Constant subroutine ... redefined</A>
  	<LI><A HREF="#Global_symbol_foo_requires_ex">Global symbol &quot;$foo&quot; requires explicit package name</A>
  	<LI><A HREF="#Can_t_undef_active_subroutine">Can't undef active subroutine</A>
  	<LI><A HREF="#Use_of_uninitialized_value_at_e">Use of uninitialized value at (eval 80) line 12.</A>
  	<LI><A HREF="#Undefined_subroutine_Apache_RO">Undefined subroutine &amp;Apache::ROOT::perl::test_2epl::some_function called at</A>
  	<LI><A HREF="#Callback_called_exit">Callback called exit</A>
  	<LI><A HREF="#Out_of_memory_">Out of memory!</A>
  </UL>
  <!-- INDEX END -->
  
  <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  <P>
  <CENTER><H1><A NAME="A_general_advice">A general advice</A></H1></CENTER>
  <P>
  Using the <CODE>use diagnostics;</CODE> generally helps you to determine the source of the problem and how to solve
  it. See <A HREF="././porting.html#diagnostics_pragma">diagnostics pragma</A> for more info.
  
  <P>
  <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  <CENTER><H1><A NAME="Value_of_x_will_not_stay_shared">Value of $x will not stay shared at - line 5</A></H1></CENTER>
  <P>
  See <A HREF="././obvious.html#my_scoped_variable_in_the_nest">my() scoped variable in the nested subroutine</A>
  
  <P>
  <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  <CENTER><H1><A NAME="Value_of_x_may_be_unavailable_a">Value of $x may be unavailable at - line 5.</A></H1></CENTER>
  <P>
  See <A HREF="././obvious.html#my_scoped_variable_in_the_nest">my() scoped variable in the nested subroutine</A>
  
  <P>
  <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  <CENTER><H1><A NAME="Constant_subroutine_redefine">Constant subroutine ... redefined</A></H1></CENTER>
  <P>
  That's a mandatory warning inside Perl. It happens only if you modify your
  script and Apache::Registry reloads it. Perl is warning you that the
  <CODE>subroutine(s)</CODE> were redefined. It is mostly harmless. If you
  don't like seeing those, just kill -USR2 (graceful restart) apache when you
  modify your scripts.
  
  <P>
  <PRE>  &lt;META&gt;
    Someone said: 
    You won't see that warning in this case with 5.004_05 or 5.005+. 
  </PRE>
  <P>
  <PRE>  I'm running perl5.00502 and I still get these warnings???
  </PRE>
  <P>
  <PRE>  Who is right?
    &lt;/META&gt;
  </PRE>
  <P>
  <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  <CENTER><H1><A NAME="Global_symbol_foo_requires_ex">Global symbol &quot;$foo&quot; requires explicit package name</A></H1></CENTER>
  <P>
  A script below will print a warning like above, moreover it will print the
  whole script as a part of the warning message:
  
  <P>
  <PRE>  #!/usr/bin/perl -w
    use strict;
    print &quot;Content-type: text/html\n\n&quot;;
    print &quot;Hello $undefined&quot;;
  </PRE>
  <P>
  The warning:
  
  <P>
  <PRE>  Global symbol &quot;$undefined&quot; requires explicit package name at /usr/apps/foo/cgi/tmp.pl line 4.
            eval 'package Apache::ROOT::perl::tmp_2epl;use Apache qw(exit);sub handler {
    #line 1 /usr/apps/foo/cgi/tmp.pl
    BEGIN {$^W = 1;}#!/usr/bin/perl -w
    use strict;
    print &quot;Content-type: text/html\\n\\n&quot;;
    print &quot;Hello $undefined&quot;;
    
    
    }
    ;' called at /usr/apps/lib/perl5/site_perl/5.005/aix/Apache/Registry.pm line 168
            Apache::Registry::compile('package
          Apache::ROOT::perl::tmp_2epl;use Apache qw(exit);sub han...') 
          called at /usr/apps/lib/perl5/site_perl/5.005/aix/Apache/Registry.pm line 121
            Apache::Registry::handler('Apache=SCALAR(0x205026c0)') called at /usr/apps/foo/cgi/tmp.pl line 4
            eval {...} called at /usr/apps/foo/cgi/tmp.pl line 4
    [Sun Nov 15 15:15:30 1998] [error] Undefined subroutine &amp;Apache::ROOT::perl::tmp_2epl::handler called at /
    usr/apps/lib/perl5/site_perl/5.005/aix/Apache/Registry.pm line 135.
    
    [Sun Nov 15 15:15:30 1998] [error] Goto undefined subroutine &amp;Apache::Constants::SERVER_ERROR at /usr/apps
    /lib/perl5/site_perl/5.005/aix/Apache/Constants.pm line 23.
  </PRE>
  <P>
  The error is simple to fix. When you use <CODE>use strict;</CODE> pragma (and you better do that), all variables should be defined before
  being used.
  
  <P>
  The bad thing is that sometimes the whole script that can be of thousands
  lines is being printed to error_log file as a code that the server has
  tried to <CODE>eval()uate.</CODE>
  
  <P>
  As Doug answered to this question:
  
  <P>
  <PRE> Looks like you have a $SIG{__DIE__} handler installed (Carp::confess?).
   That's what's expected if so
  </PRE>
  <P>
  It wasn't in my case, but may be yours 
  
  <P>
  Bryan Miller said:
  
  <P>
  <PRE> You might wish to try something more terse such as 
   &quot;local $SIG{__WARN__} = \&amp;Carp::cluck;&quot;  The confess method is _very_
   verbose and will tell you more than you might wish to know including
   full source.
  </PRE>
  <P>
  <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  <CENTER><H1><A NAME="Can_t_undef_active_subroutine">Can't undef active subroutine</A></H1></CENTER>
  <P>
  <PRE>  Can't undef active subroutine at /usr/apps/lib/perl5/site_perl/5.005/aix/Apache/Registry.pm line 102. 
    Called from package Apache::Registry, filename /usr/apps/lib/perl5/site_perl/5.005/aix/Apache/Registry.pm, line 102 
  </PRE>
  <P>
  This problem is caused when, a client drops the connection while httpd is
  in the middle of a write, httpd timeout happens, sending a SIGPIPE, and
  Perl in that child is stuck in the middle of it's eval context. This is
  fixed by the Apache::SIG module which is called by default. This should not
  happen unless you have code that is messing with $SIG{PIPE}. It's also
  triggered only when you've changed your script on disk and mod_perl is
  trying to reload it.
  
  <P>
  <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  <CENTER><H1><A NAME="Use_of_uninitialized_value_at_e">Use of uninitialized value at (eval 80) line 12.</A></H1></CENTER>
  <P>
  If you compile with the experimental PERL_MARK_WHERE=1, it shows you
  ``exactly'' where this is happening. many times compiler makes a shift for
  ``unknown'' reasons in it's line counter. You can always stuff you code
  with special compiler directives, to reset it's counter to the value you
  will tell. At the beginning of the line you should write (# sticked to the
  leftmost side):
  
  <P>
  <PRE>  #line 298 myscript.pl
  </PRE>
  <P>
  (myscript.pl is optional). It specifies the line number of the _following_
  line, not the line the directive is on. You can use a little script to
  stuff every N lines of your code with this directives, but then you will
  have to rerun this script every time you add remove code lines. The script: 
  
  <P>
  <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;
    my $filename = $ARGV[0];      
    my $lines = 100;
    open IN, $filename or die &quot;Cannot open file: $filename: $!\n&quot;;
    open OUT, &quot;&gt;$filename.marked&quot; or die &quot;Cannot open file: $filename.marked: $!\n&quot;;
    my $counter = 1;
    while (&lt;IN&gt;) {
      print OUT &quot;# line $counter\n&quot; unless $counter++ % $gap;
      next if $_ =~ /^# line /;
      print OUT $_;
      $counter++;
    }
    close OUT;
    close IN;
    chmod 0755, &quot;$filename.marked&quot;;
  </PRE>
  <P>
  You can also add:
  
  <P>
  <PRE>  use Carp ();
    local $SIG{__WARN__} = \&amp;Carp::cluck;
  </PRE>
  <P>
  <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  <CENTER><H1><A NAME="Undefined_subroutine_Apache_RO">Undefined subroutine &amp;Apache::ROOT::perl::test_2epl::some_function called at</A></H1></CENTER>
  <P>
  See <A HREF="././porting.html#Names_collisions_with_Modules_an">Names collisions with Modules and libs</A>
  
  <P>
  <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  <CENTER><H1><A NAME="Callback_called_exit">Callback called exit</A></H1></CENTER>
  <P>
  See <A HREF="#Out_of_memory_">Out_of_memory!</A>
  
  <P>
  <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  <CENTER><H1><A NAME="Out_of_memory_">Out of memory!</A></H1></CENTER>
  <P>
  If something goes really wrong with your code, Perl may die with an ``Out
  of memory!'' message and or ``Callback called exit''. A common cause of
  this are never-ending loops, deep recursion or calling an undefined
  subroutine. Here's one way to catch the problem: See Perl's INSTALL
  document for this item: 
  
  <P>
  <PRE>  =item -DPERL_EMERGENCY_SBRK
  </PRE>
  <P>
  <PRE>  If PERL_EMERGENCY_SBRK is defined, running out of memory need not be a
    fatal error: a memory pool can allocated by assigning to the special
    variable $^M.  See perlvar(1) for more details.
  </PRE>
  <P>
  If you compile with that option and add 'use Apache::Debug level =&gt; 4;'
  to your PerlScript, it will allocate the $^M emergency pool and the
  $SIG{__DIE__} handler will call Carp::confess, giving you a stack trace
  which should reveal where the problem is. See the Apache::Resource module
  for prevention of spinning httpds. 
  
  <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  <P><A HREF="index.html">[Back to the main page]</A></P>
  
  <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="mailto:sbekman@iil.intel.com">Stas Bekman</A>.
  	     <BR>Last Modified at 12/07/98 
        </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>
  	    
  
  <HR SIZE=6>
  <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
  <HTML>
  <HEAD>
     <TITLE>mod_perl guide: Performance. Benchmarks.</TITLE>
     <META NAME="GENERATOR" CONTENT="Mozilla/3.04Gold (X11; I; AIX 4.1) [Netscape]">
     <META NAME="Author" CONTENT="Bekman Stas">
     <META NAME="Description" CONTENT="mod_perl,perl,apache">
     <META NAME="Keywords" CONTENT="mod_perl,perl,apache,webserver,cgi">
  </HEAD>
  <BODY TEXT="#000000" BGCOLOR="#E0FFFF" LINK="#0000EE" VLINK="#551A8B" ALINK="#FF0000">
  
  <H1 ALIGN=CENTER>
  <A HREF="http://perl.apache.org"><IMG SRC="images/mod_perl.gif" ALT="Mod Perl Icon" BORDER=0 HEIGHT=30 WIDTH=90 ALIGN=LEFT></A>
  <A HREF="http://perl.apache.org"><IMG SRC="images/mod_perl.gif" ALT="Mod Perl Icon" BORDER=0 HEIGHT=30 WIDTH=90 ALIGN=RIGHT></A>
  Performance. Benchmarks.</H1>
  <HR WIDTH="100%">
  	    <!-- INDEX BEGIN -->
  <P><A NAME="toc"></A><B><FONT SIZE=-1>Table of Contents:</FONT></B></P>
  <UL>
  
  	<LI><A HREF="#Preload_Perl_modules_at_server_s">Preload Perl modules at server startup</A>
  	<LI><A HREF="#Preopen_DB_connection_at_server_">Preopen DB connection at server startup</A>
  	<LI><A HREF="#Preload_Registry_Scripts">Preload Registry Scripts</A>
  	<LI><A HREF="#Avoid_Importing_Functions">Avoid Importing Functions</A>
  	<LI><A HREF="#Reducing_the_Memory_Usage">Reducing the Memory Usage</A>
  	<LI><A HREF="#Limiting_the_size_of_the_process">Limiting the size of the processes</A>
  	<LI><A HREF="#Limiting_the_resources_used_by_h">Limiting the resources used by httpd children</A>
  	<LI><A HREF="#Benchmarks_Impressing_your_Boss">Benchmarks. Impressing your Boss and Colleagues.</A>
  	<UL>
  
  		<LI><A HREF="#Developers_Talk">Developers Talk</A>
  		<LI><A HREF="#Benchmarking_a_Graphic_hits_coun">Benchmarking a Graphic hits counter with Persistent DB Connection</A>
  		<LI><A HREF="#Benchmarking_scripts_with_execut">Benchmarking scripts with execution times below 1 second :)</A>
  		<LI><A HREF="#PerlHandler_s_Benchmarking">PerlHandler's Benchmarking</A>
  	</UL>
  
  	<LI><A HREF="#Persistent_DB_Connections">Persistent DB Connections</A>
  	<LI><A HREF="#Real_Numbers">Real Numbers</A>
  	<LI><A HREF="#Profiling">Profiling</A>
  </UL>
  <!-- INDEX END -->
  
  <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  <P>
  <CENTER><H1><A NAME="Preload_Perl_modules_at_server_s">Preload Perl modules at server startup</A></H1></CENTER>
  <P>
  Use the PerlRequire and PerlModule directives to load commonly used modules
  such as CGI.pm, DBI, etc., when the server is started. On most systems,
  server children will be able to share this space. 
  
  <P>
  You can also put the standard <CODE>use Foo;</CODE> into the startup-file. 
  
  <P>
  CGI.pm is a special one, you will want to put into a startup-file:
  
  <P>
  <PRE>  use CGI ();
    CGI-&gt;compile(':all');
  </PRE>
  <P>
  You can also preload the Registry scripts. See <A HREF="#Preload_Registry_Scripts">Preload Registry Scripts</A>.
  
  <P>
  See also: <A HREF="#Real_Numbers">Real Numbers</A>
  
  <P>
  <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  <CENTER><H1><A NAME="Preopen_DB_connection_at_server_">Preopen DB connection at server startup</A></H1></CENTER>
  <P>
  If you use DBI for DB connections, you can preopen a connections to DB for
  each child with Apache::DBI.
  
  <P>
  <PRE>  use Apache::DBI (); 
    Apache::DBI-&gt;connect_on_init(&quot;DBI:mysql:test&quot;, '','', {
                                                           RaiseError =&gt; 1,
                                                           PrintError =&gt; 1,
                                                           AutoCommit =&gt; 1,
                                                          };
  </PRE>
  <P>
  See also <A HREF="#Persistent_DB_Connections">Persistant DB Connections</A>
  
  <P>
  <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  <CENTER><H1><A NAME="Preload_Registry_Scripts">Preload Registry Scripts</A></H1></CENTER>
  <P>
  Apache::RegistryLoader compiles Apache::Registry scripts at server startup.
  It can be a good idea to preload these as well. So the code will be shared
  among the child servers.
  
  <P>
  example of use at modperl.com in a PerlRequire'd file: 
  
  <P>
  <PRE>  use <A HREF="File::Find">File::Find</A> 'finddepth';
    use Apache::RegistryLoader ();
    {
        my $perl_dir = &quot;perl/&quot;;
        my $rl = Apache::RegistryLoader-&gt;new;
        finddepth(sub {
            return unless /\.pl$/;
            my $url = &quot;/$<A HREF="File::Find::dir/">File::Find::dir/</A>$_&quot;;
            print &quot;pre-loading $url\n&quot;;
    
            my $status = $rl-&gt;handler($url);
            unless($status == 200) {
                warn &quot;pre-load of `$url' failed, status=$status\n&quot;;
            }
        }, $perl_dir);
    }         
  </PRE>
  <P>
  See also: perldoc Apache::RegistryLoader
  
  <P>
  You have to check whether it makes any good for you though, I did some
  testing [ <A HREF="#Real_Numbers">Real Numbers</A> ], and it seems that it takes more memory than when the scripts is being
  called from the child - This is only a first impression and needs better
  investigation. If you aren't concerned about few scripts invocations which
  will take some time to respond while they load the code, you might not need
  it all!
  
  <P>
  See also <A HREF="././porting.html#BEGIN_blocks">BEGIN blocks</A>
  
  <P>
  <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  <CENTER><H1><A NAME="Avoid_Importing_Functions">Avoid Importing Functions</A></H1></CENTER>
  <P>
  When possible, avoid importing of a module functions into your namespace.
  The aliases which are created can take up quite a bit of space. Try to use
  method interfaces and fully qualified Package::function names instead.   
  
  <P>
  <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  <CENTER><H1><A NAME="Reducing_the_Memory_Usage">Reducing the Memory Usage</A></H1></CENTER>
  <P>
  One of the important issues in improving the performance is memory usage
  reduce - the less memory server uses - the more server processes you can
  start - the more performance you have (from the user point of view - the
  respond speed )
  
  <P>
  See <A HREF="././porting.html#Global_Variables">Global Variables</A>
  
  <P>
  See <A HREF="././porting.html#Memory_leakages">Memory "leakages"</A>
  
  <P>
  Joel Wagner reports that calling an undefined subroutine in a module can
  cause a tight loop that consumes all memory. Here is a way to catch such
  errors. Define an autoload subroutine  
  
  <P>
  <PRE>  sub UNIVERSAL::AUTOLOAD {
            my $class = shift;
            warn &quot;$class can't \$UNIVERSAL::AUTOLOAD!\n&quot;;
    }
  </PRE>
  <P>
  It will produce a nice error in error_log, giving the line number of the
  call and the name of the undefined subroutine.  
  
  <P>
  <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  <CENTER><H1><A NAME="Limiting_the_size_of_the_process">Limiting the size of the processes</A></H1></CENTER>
  <P>
  Apache::SizeLimit allows you to kill off Apache httpd processes if they
  grow too large. see perldoc Apache::SizeLimit for more details.
  
  <P>
  By using this module, you should be able to discontinue using the Apache
  configuration directive MaxRequestsPerChild, although for some folks, using
  both in combination does the job.
  
  <P>
  <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  <CENTER><H1><A NAME="Limiting_the_resources_used_by_h">Limiting the resources used by httpd children</A></H1></CENTER>
  <P>
  Apache::Resource uses the BSD::Resource module, which uses the C function
  setrlimit to set limits on system resources such as memory and cpu usage.
  
  <P>
  See perldoc Apache::Resource for more info.
  
  <P>
  <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  <CENTER><H1><A NAME="Benchmarks_Impressing_your_Boss">Benchmarks. Impressing your Boss and Colleagues.</A></H1></CENTER>
  <P>
  How much faster is mod_perl that CGI? There are many ways to benchmark the
  two. See a few examples and numbers below, also checkout the benchmark/
  directory of mod_perl dist for more examples.
  
  <P>
  If you write a benchmarks from your own for heavy scripts use
  <CODE>Benchmark</CODE> and for very fast scripts use <CODE>Time::HiRes</CODE> modules.
  
  <P>
  There is no need to write a special benchmark, if you want to impress your
  boss or colleagues, just take the heaviest cgi script you have, open 2
  xterms and call the same script in mod_perl mode in one xterm and in
  mod_cgi mode in the other. You can use lwp-get from LWP package to emulate
  the web agent (browser). (benchmark/ directory of mod_perl dist includes
  such an example)
  
  <P>
  <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  <CENTER><H2><A NAME="Developers_Talk">Developers Talk</A></H2></CENTER>
  <P>
  Perrin Harkins writes on benchmarks or comparisons, official or unofficial:
  
  <BLOCKQUOTE>
  
  <P>
  I have used some of the platforms you mentioned and researched others. What
  I can tell you for sure, is that no commercially available system offers
  the depth, power, and ease of use that mod_perl has. Either they don't let
  you access the web server internals, or they make you use less productive
  languages than Perl, sometimes forcing you into restrictive and confusing
  APIs and/or GUI development environments. None of them offer the level of
  support available from simply posting a message to this list, at any price.
  
  <P>
  As for performance, beyond doing several important things (code-caching,
  pre-forking/threading, and persistent database connections) there isn't
  much these tools can do, and it's mostly in your hands as the developer to
  see that the things which really take the time (like database queries) are
  optimized.
  
  <P>
  The downside of all this is that most manager types seem to be unable to
  believe that web development software available for free could be better
  than the stuff that cost $25,000 per CPU. This appears to be the major
  reason most of the web tools companies are still in business. They send a
  bunch of suits to give PowerPoint presentations and hand out glossy
  literature to your boss, and you end up with an expensive disaster and an
  approaching deadline.
  
  <P>
  But I'm not bitter or anything...
  
  </BLOCKQUOTE>
  
  <P>
  Jonathan Peterson adds:
  
  <BLOCKQUOTE>
  
  <P>
  Most of the major solutions have something that they do better than the
  others, and each of them has faults. Microsofts ASP has a very nice objects
  model, and has IMO the best data access object (better than DBI to use -
  but less portable) It has the worst scripting language. PHP has many of the
  advantages of Perl-based solutions, but is less complicated for developers.
  Netscape's Livewire has a good object model too, and provides good
  server-side Java integration - if you want to leverage Java skills, it's
  good. Also, it has a compiled scripting language - which is great if you
  aren't selling your clients the source code (and a pain otherwise).
  
  <P>
  mod_perl's advantage is that it is the most powerful. It offers the
  createst degree of control with one of the more powerful languages. It also
  offers the greatest granularity. You can use an embedding module (eg eperl)
  from one place, a session module (Session) from another, and your data
  acces module from yet another.
  
  <P>
  I think the Apache::ASP module looks very promising. It has very easy to
  use and adequately powerful state maintenance, a good embedding system, and
  a sensible object model (that emulates the Microsoft ASP one). It doesn't
  replicate MS's ADO for data access, but DBI is fine for that.
  
  <P>
  I have always found that the developers available make the greatest impact
  on the decision. If you have a team with no Perl experience, and a small or
  medium task, using something like PHP, or Microsoft ASP, makes more sense
  than driving your staff into the vertical learning curve they'll need to
  use mod_perl.
  
  <P>
  For very large jobs, it may be worth finding the best technical solution,
  and then recruiting the team with the necessary skills.
  
  </BLOCKQUOTE>
  
  <P>
  <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  <CENTER><H2><A NAME="Benchmarking_a_Graphic_hits_coun">Benchmarking a Graphic hits counter with Persistent DB Connection</A></H2></CENTER>
  <P>
  Here are the numbers from Michael Parker's mod_perl presentation at Perl
  Conference (Aug, 98) <A
  HREF="http://www.realtime.net/~parkerm/perl/conf98/index.htm">http://www.realtime.net/~parkerm/perl/conf98/index.htm</A>
  . The script is a standard hits counter, but it logs the counts into the
  mysql relational DataBase:
  
  <P>
  <PRE>    Benchmark: timing 100 iterations of cgi, perl...  [rate 1:28]
  </PRE>
  <P>
  <PRE>    cgi: 56 secs ( 0.33 usr 0.28 sys = 0.61 cpu) 
      perl: 2 secs ( 0.31 usr 0.27 sys = 0.58 cpu) 
      
      Benchmark: timing 1000 iterations of cgi,perl...  [rate 1:21]
  </PRE>
  <P>
  <PRE>    cgi: 567 secs ( 3.27 usr 2.83 sys = 6.10 cpu) 
      perl: 26 secs ( 3.11 usr 2.53 sys = 5.64 cpu)      
      
      Benchmark: timing 10000 iterations of cgi, perl   [rate 1:21]
  </PRE>
  <P>
  <PRE>    cgi: 6494 secs (34.87 usr 26.68 sys = 61.55 cpu) 
      perl: 299 secs (32.51 usr 23.98 sys = 56.49 cpu) 
  </PRE>
  <P>
  We don't know what server configurations was used for these testing, but I
  guess the numbers talks for themselves.
  
  <P>
  The source code of the script at <A
  HREF="http://www.realtime.net/~parkerm/perl/conf98/sld006.htm">http://www.realtime.net/~parkerm/perl/conf98/sld006.htm</A>
  
  <P>
  <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  <CENTER><H2><A NAME="Benchmarking_scripts_with_execut">Benchmarking scripts with execution times below 1 second :)</A></H2></CENTER>
  <P>
  As noted before for very fast scripts you will have to use Time::HiRes
  module, it's usage is similar to the Benchmark's.
  
  <P>
  <PRE>  use Time::HiRes qw(gettimeofday tv_interval);
    my $start_time = [ gettimeofday ];
    &amp;sub_that_takes_a_teeny_bit_of_time()
    my $end_time = [ gettimeofday ];
    my $elapsed = tv_interval($start_time,$end_time);
    print &quot;the sub took $elapsed secs.&quot;
  </PRE>
  <P>
  <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  <CENTER><H2><A NAME="PerlHandler_s_Benchmarking">PerlHandler's Benchmarking</A></H2></CENTER>
  <P>
  At <A
  HREF="http://perl.apache.org/dist/contrib/">http://perl.apache.org/dist/contrib/</A>
  you will find Apache::Timeit package which does PerlHandler's Benchmarking.
  
  <P>
  <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  <CENTER><H1><A NAME="Persistent_DB_Connections">Persistent DB Connections</A></H1></CENTER>
  <P>
  Another popular use of mod_perl is to take advantage of it's persistence to
  maintain open database connections. The basic idea goes like so:  
  
  <P>
  <PRE>  #Apache::Registry script
    use strict;
    use vars qw($dbh);
  </PRE>
  <P>
  <PRE>  $dbh ||= SomeDbPackage-&gt;connect(...);
  </PRE>
  <P>
  Since <CODE>$dbh</CODE> is a global variable for the child, once the child
  has opened the connection it will use it over and over again, unless you
  perform <CODE>disconnect().</CODE>
  
  <P>
  Be careful to use different names for handlers if you open connection to
  different Databases!
  
  <P>
  Apache::DBI - allows to make a persistent database connection. With this
  module enabled every connect request to plain DBI module will be forwarded
  to the Apache::DBI module. This looks if a database handle from a previous
  connect request is already stored and if this handle is still valid using
  the ping method. If these two conditions are fulfilled it just returns the
  database handle. If there is no appropriate database handle or if the ping
  method fails, a new connection is established and the handle is stored for
  later re-use. <STRONG>There is no need to delete the disconnect statements from your
  code</STRONG>. They won't do anything because the Apache::DBI module overloads the
  disconnect method with a NOP.
  
  <P>
  The usage is simple:
  
  <P>
  <PRE>  httpd.conf
    ----------
    PerlModule Apache::DBI
    
  It is important, to load this module before any other ApacheDBI module !
  </PRE>
  <P>
  <PRE>  a script.perl
    ------------
    use DBI;
    use strict;
    
    my $dbh = DBI-&gt;connect( 'DBI:mysql:database', 'user', 'password',
                            { autocommit =&gt; 0 }
                          ) || die $DBI::errstr;
  </PRE>
  <P>
  <PRE>  ...rest of program
  </PRE>
  <P>
  The module provides the additional method:
  
  <P>
  <PRE>  Apache::DBI-&gt;connect_on_init($data_source, $username, $auth, \%attr)
  </PRE>
  <P>
  This can be used as a simple way to have apache children establish
  connections on server startup. This call should be in a startup file
  (PerlModule, &lt;Perl&gt; or PerlRequire). It will establish a connection
  when a child is started in that child process. See the Apache::DBI manpage
  to see the requirements for this method.
  
  <P>
  However be warned that some old DBD drivers aren't supporting this feature
  (ping method), so check the documentation of the driver you use.
  
  <P>
  Another problem are timeouts: some databases disconnect the client after a
  certain time of inactivity. ping method ensures that this will not happen.
  Some DBD drivers don't have this method, check the Apache::DBI manpage to
  see how to write a ping method.
  
  <P>
  Also some folks at list suggested to change the timeout of the server (they
  talked specifically about mysql). So starting from 3.22.x you can set a
  wait_timeout option at mysqld server startup to change the default value,
  setting it to 24 hours probably will fix the timeout problem.
  
  <P>
  <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  <CENTER><H1><A NAME="Real_Numbers">Real Numbers</A></H1></CENTER>
  <P>
  I have conducted a few tests to benchmark the memory usage when some
  modules are preloaded. First set of tests checks the memory use with
  Library Perl Module preload (only CGI.pm). The second set checks the
  compile method of CGI.pm. The third test checks benefit the the Library
  Perl Module preload but a few of them (too see more memory saved) and also
  the effect of precompiling the Registry modules with
  Apache::RegistryLoader. 
  
  <P>
  Summary: 1. Library Perl Modules Preloading gave a good results everywhere.
  2. compile method of CGI seems to make things worse (may be the speed is
  better?) 3. Apache::RegistryLoader might made the script load faster on the
  first request after the child has just started but the memory usage was
  worse!!! See the numbers by yourself. 
  
  <P>
  HW/SW: The server is apache 1.3.2, mod_perl 1.16 running on AIX 4.1.5
  
  <P>
  --------------------------------------------------------------------------------
  
  <P>
  1. In the first test was used a script:
  
  <P>
  <PRE>  use strict;
    use CGI ();
    my $q = new CGI;
    print $q-&gt;header;
    print $q-&gt;start_html,$q-&gt;p(&quot;Hello&quot;);
  </PRE>
  <P>
  &lt;Server restarted&gt;
  
  <P>
  Before the CGI.pm preload: (No other modules preloaded)
  
  <P>
  <PRE>  USER        PID %CPU %MEM   SZ  RSS    TTY STAT    STIME  TIME COMMAND
    root      87004  0.0  0.0 1060 1524      - A    16:51:14  0:00 httpd
    httpd    240864  0.0  0.0 1304 1784      - A    16:51:13  0:00 httpd
  </PRE>
  <P>
  After running a script which uses CGI's methods (no imports):
  
  <P>
  <PRE>  USER        PID %CPU %MEM   SZ  RSS    TTY STAT    STIME  TIME COMMAND
    root     188068  0.0  0.0 1052 1524      - A    17:04:16  0:00 httpd
    httpd     86952  0.0  1.0 2520 3052      - A    17:04:16  0:00 httpd
  </PRE>
  <P>
  Observation: child httpd has grown up by 1268K
  
  <P>
  &lt;Server restarted&gt;
  
  <P>
  After the CGI.pm preload:
  
  <P>
  <PRE>  USER        PID %CPU %MEM   SZ  RSS    TTY STAT    STIME  TIME COMMAND
    root     240796  0.0  0.0 1456 1552      - A    16:55:30  0:00 httpd
    httpd     86944  0.0  0.0 1688 1800      - A    16:55:30  0:00 httpd
  </PRE>
  <P>
  after running a script which uses CGI's methods (no imports):
  
  <P>
  <PRE>  USER        PID %CPU %MEM   SZ  RSS    TTY STAT    STIME  TIME COMMAND
    root      86872  0.0  0.0 1448 1552      - A    17:02:56  0:00 httpd
    httpd    187996  0.0  1.0 2808 2968      - A    17:02:56  0:00 httpd
  </PRE>
  <P>
  Observation: child httpd has grown up by 1168K, 100K less then without
  preload - good!
  
  <P>
  &lt;Server restarted&gt;
  
  <P>
  After CGI.pm preloaded and compiled with CGI-&gt;compile(':all');
  
  <P>
  <PRE>  USER        PID %CPU %MEM   SZ  RSS    TTY STAT    STIME  TIME COMMAND
    root      86980  0.0  0.0 2836 1524      - A    17:05:27  0:00 httpd
    httpd    188104  0.0  0.0 3064 1768      - A    17:05:27  0:00 httpd
  </PRE>
  <P>
  After running a script which uses CGI's methods (no imports):
  
  <P>
  <PRE>  USER        PID %CPU %MEM   SZ  RSS    TTY STAT    STIME  TIME COMMAND
    root      86980  0.0  0.0 2828 1524      - A    17:05:27  0:00 httpd
    httpd    188104  0.0  1.0 4188 2940      - A    17:05:27  0:00 httpd
  </PRE>
  <P>
  Observation: child httpd has grown up by 1172K No change! So what does
  CGI-&gt;compile(':all') helps? I guess it helps if you import the symbols
  (subs) rather you use the methods
  
  <P>
  --------------------------------------------------------------------------------
  
  <P>
  2. I have tried the second test to find it. I run the script:
  
  <P>
  use strict; use CGI <CODE>qw(:all);</CODE> print
  header,start_html,p(``Hello'');
  
  <P>
  &lt;Server restarted&gt;
  
  <P>
  After CGI.pm preloaded and NOT compiled with CGI-&gt;compile(':all');
  
  <P>
  <PRE>  USER        PID %CPU %MEM   SZ  RSS    TTY STAT    STIME  TIME COMMAND
    root      17268  0.0  0.0 1456 1552      - A    18:02:49  0:00 httpd
    httpd     86904  0.0  0.0 1688 1800      - A    18:02:49  0:00 httpd
  </PRE>
  <P>
  After running a script which imports symbols, all of them
  
  <P>
  <PRE>  USER        PID %CPU %MEM   SZ  RSS    TTY STAT    STIME  TIME COMMAND
    root      17268  0.0  0.0 1448 1552      - A    18:02:49  0:00 httpd
    httpd     86904  0.0  1.0 2952 3112      - A    18:02:49  0:00 httpd
  </PRE>
  <P>
  Observation: child httpd has grown up by 1264K
  
  <P>
  &lt;Server restarted&gt;
  
  <P>
  After CGI.pm preloaded and compiled with CGI-&gt;compile(':all');
  
  <P>
  <PRE>  USER        PID %CPU %MEM   SZ  RSS    TTY STAT    STIME  TIME COMMAND
    root      86812  0.0  0.0 2836 1524      - A    17:59:52  0:00 httpd
    httpd     99104  0.0  0.0 3064 1768      - A    17:59:52  0:00 httpd
  </PRE>
  <P>
  After running a script which imports symbols, all of them
  
  <P>
  <PRE>  USER        PID %CPU %MEM   SZ  RSS    TTY STAT    STIME  TIME COMMAND
    root      86812  0.0  0.0 2832 1436      - A    17:59:52  0:00 httpd
    httpd     99104  0.0  1.0 4884 3636      - A    17:59:52  0:00 httpd
  </PRE>
  <P>
  Observation: child httpd has grown up by 1868K. Why? Isn't
  CGI-&gt;compile(':all') supposed to make children to share the compiled
  code with parent?
  
  <P>
  --------------------------------------------------------------------------------
  
  <P>
  3. The third script
  
  <P>
  <PRE>  use strict;
    use CGI;
    use Data::Dumper;
    use Storable;                   
    [and many lines of code, lots of globals - so the code is huge!]
  </PRE>
  <P>
  &lt;Server restarted&gt;
  
  <P>
  Nothing preloaded at startup
  
  <P>
  <PRE>  USER        PID %CPU %MEM   SZ  RSS    TTY STAT    STIME  TIME COMMAND
    root      90962  0.0  0.0 1060 1524      - A    17:16:45  0:00 httpd
    httpd     86870  0.0  0.0 1304 1784      - A    17:16:45  0:00 httpd
  </PRE>
  <P>
  Script using CGI (methods), Storable, Data::Dumper called
  
  <P>
  <PRE>  USER        PID %CPU %MEM   SZ  RSS    TTY STAT    STIME  TIME COMMAND
    root      90962  0.0  0.0 1064 1436      - A    17:16:45  0:00 httpd
    httpd     86870  0.0  1.0 4024 4548      - A    17:16:45  0:00 httpd
  </PRE>
  <P>
  Observation: child httpd has grown up by 2764K
  
  <P>
  &lt;Server restarted&gt;
  
  <P>
  Preloaded CGI (compiled), Storable, Data::Dumper at startup
  
  <P>
  <PRE>  USER        PID %CPU %MEM   SZ  RSS    TTY STAT    STIME  TIME COMMAND
    root      26792  0.0  0.0 3120 1528      - A    17:19:21  0:00 httpd
    httpd     91052  0.0  0.0 3340 1764      - A    17:19:21  0:00 httpd
  </PRE>
  <P>
  Script using CGI (methods), Storable, Data::Dumper called
  
  <P>
  <PRE>  USER        PID %CPU %MEM   SZ  RSS    TTY STAT    STIME  TIME COMMAND
    root      26792  0.0  0.0 3124 1440      - A    17:19:21  0:00 httpd
    httpd     91052  0.0  1.0 6568 5040      - A    17:19:21  0:00 httpd
  </PRE>
  <P>
  Observation: child httpd has grown up by 3276K. Great different: 512K
  less!!! 
  
  <P>
  &lt;Server restarted&gt;
  
  <P>
  All the above modules + the above script PreCompiled with
  Apache::RegistryLoader at startup 
  
  <P>
  <PRE>  USER        PID %CPU %MEM   SZ  RSS    TTY STAT    STIME  TIME COMMAND
    root      43224  0.0  0.0 3256 1528      - A    17:23:12  0:00 httpd
    httpd     26844  0.0  0.0 3488 1776      - A    17:23:12  0:00 httpd
  </PRE>
  <P>
  Script using CGI (methods), Storable, Data::Dumper called
  
  <P>
  <PRE>  USER        PID %CPU %MEM   SZ  RSS    TTY STAT    STIME  TIME COMMAND
    root      43224  0.0  0.0 3252 1440      - A    17:23:12  0:00 httpd
    httpd     26844  0.0  1.0 6748 5092      - A    17:23:12  0:00 httpd
  </PRE>
  <P>
  Observation: child httpd has grown even more 3316K ! Doesn't seem to be
  good!
  
  <P>
  <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  <CENTER><H1><A NAME="Profiling">Profiling</A></H1></CENTER>
  <P>
  Profiling will help you to determine which subroutines are using the most
  time and which subroutines are being called most often, then you will
  probably will want to optimize those, if your code is a way heavy.
  
  <P>
  It is possible to profile code run under mod_perl with the Devel::DProf
  module available on CPAN. However, you must have apache version 1.3b3 or
  higher and the PerlChildExitHandler enabled. When the server is started,
  Devel::DProf installs an END block to write the tmon.out file, which will
  be run when the server is shutdown. Here's how to start and stop a server
  with the profiler enabled:  
  
  <P>
  <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>
  The Devel::DProf package is a Perl code profiler. This will collect
  information on the execution time of a Perl script and of the subs in that
  script. This information can be used to determine which subroutines are
  using the most time and which subroutines are being called most often.  
  <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  <P><A HREF="index.html">[Back to the main page]</A></P>
  
  <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="mailto:sbekman@iil.intel.com">Stas Bekman</A>.
  	     <BR>Last Modified at 12/07/98 
        </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>
  	    
  
  <HR SIZE=6>
  <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
  <HTML>
  <HEAD>
     <TITLE>mod_perl guide: mod_perl Status. Peeking into the Server's Perl Inwards</TITLE>
     <META NAME="GENERATOR" CONTENT="Mozilla/3.04Gold (X11; I; AIX 4.1) [Netscape]">
     <META NAME="Author" CONTENT="Bekman Stas">
     <META NAME="Description" CONTENT="mod_perl,perl,apache">
     <META NAME="Keywords" CONTENT="mod_perl,perl,apache,webserver,cgi">
  </HEAD>
  <BODY TEXT="#000000" BGCOLOR="#E0FFFF" LINK="#0000EE" VLINK="#551A8B" ALINK="#FF0000">
  
  <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 Status. Peeking into the Server's Perl Inwards</H1>
  <HR WIDTH="100%">
  	    <!-- INDEX BEGIN -->
  <P><A NAME="toc"></A><B><FONT SIZE=-1>Table of Contents:</FONT></B></P>
  <UL>
  
  	<LI><A HREF="#Watching_the_server">Watching the server</A>
  	<UL>
  
  		<LI><A HREF="#Configuration">Configuration</A>
  		<LI><A HREF="#Usage">Usage</A>
  	</UL>
  
  </UL>
  <!-- INDEX END -->
  
  <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  <P>
  <CENTER><H1><A NAME="Watching_the_server">Watching the server</A></H1></CENTER>
  <P>
  Very useful feature. You can watch what happens to the perl parts of the
  server. Below you will find the instructions of configuration and usage of
  this feature
  
  <P>
  <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  <CENTER><H2><A NAME="Configuration">Configuration</A></H2></CENTER>
  <P>
  Add this to http.conf:
  
  <P>
  <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>
  <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  <CENTER><H2><A NAME="Usage">Usage</A></H2></CENTER>
  <P>
  Assuming that your mod_perl server listens to port 81, fetch <A
  HREF="http://www.myserver.com:81/perl-status">http://www.myserver.com:81/perl-status</A>
  
  <P>
  <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>
  Below all sections should be links:
  
  <P>
  <PRE>  Signal Handlers
    Enabled mod_perl Hooks
    PerlRequire'd Files
    Environment
    Perl Section Configuration
    Loaded Modules
    Perl Configuration
    ISA Tree
    Inheritance Tree
    Compiled Registry Scripts
    Symbol Table Dump
  </PRE>
  <P>
  Let's follow for example : PerlRequire'd Files =&gt; we see:
  
  <P>
  <PRE>  PerlRequire                          Location
    /usr/apps/pais/lib/apache-startup.pl /usr/apps/pais/lib/apache-startup.pl
  </PRE>
  <P>
  From some menus you can continue dipper to peek into internals of the
  server, to see the values of the global variables in the packages, to the
  the cached scripts and modules and much more. Just click around...
  
  <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  <P><A HREF="index.html">[Back to the main page]</A></P>
  
  <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="mailto:sbekman@iil.intel.com">Stas Bekman</A>.
  	     <BR>Last Modified at 12/07/98 
        </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>
  	    
  
  <HR SIZE=6>
  <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
  <HTML>
  <HEAD>
     <TITLE>mod_perl guide: Code Debugging techniques </TITLE>
     <META NAME="GENERATOR" CONTENT="Mozilla/3.04Gold (X11; I; AIX 4.1) [Netscape]">
     <META NAME="Author" CONTENT="Bekman Stas">
     <META NAME="Description" CONTENT="mod_perl,perl,apache">
     <META NAME="Keywords" CONTENT="mod_perl,perl,apache,webserver,cgi">
  </HEAD>
  <BODY TEXT="#000000" BGCOLOR="#E0FFFF" LINK="#0000EE" VLINK="#551A8B" ALINK="#FF0000">
  
  <H1 ALIGN=CENTER>
  <A HREF="http://perl.apache.org"><IMG SRC="images/mod_perl.gif" ALT="Mod Perl Icon" BORDER=0 HEIGHT=30 WIDTH=90 ALIGN=LEFT></A>
  <A HREF="http://perl.apache.org"><IMG SRC="images/mod_perl.gif" ALT="Mod Perl Icon" BORDER=0 HEIGHT=30 WIDTH=90 ALIGN=RIGHT></A>
  Code Debugging techniques </H1>
  <HR WIDTH="100%">
  	    <!-- INDEX BEGIN -->
  <P><A NAME="toc"></A><B><FONT SIZE=-1>Table of Contents:</FONT></B></P>
  <UL>
  
  	<LI><A HREF="#Sometimes_script_works_Sometime">Sometimes script works, Sometimes Not</A>
  	<LI><A HREF="#Debug_Tracing">Debug Tracing</A>
  </UL>
  <!-- INDEX END -->
  
  <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  <P>
  <CENTER><H1><A NAME="Sometimes_script_works_Sometime">Sometimes script works, Sometimes Not</A></H1></CENTER>
  <P>
  See <A HREF="././porting.html#Sometimes_it_works_Sometimes_Not">Sometimes it works Sometimes Not</A>
  
  <P>
  <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  <CENTER><H1><A NAME="Debug_Tracing">Debug Tracing</A></H1></CENTER>
  <P>
  To enable mod_perl debug tracing configure mod_perl with the PERL_TRACE
  option:
  
  <P>
  <PRE> perl Makefile.PL PERL_TRACE=1
  </PRE>
  <P>
  The trace levels can then be enabled via the &lt;B&gt;MOD_PERL_TRAC/&B;
  environment variable which can contain any combination of:
  
  <P>
  <PRE>  d - Trace directive handling during configuration read
    s - Trace processing of perl sections
    h - Trace Perl*Handler callbacks
    g - Trace global variable handling, interpreter construction, END blocks, etc.
    all - all of the above
  </PRE>
  <P>
  add to httpd.conf:
  
  <P>
  PerlSetVar MOD_PERL_TRACE all
  
  <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  <P><A HREF="index.html">[Back to the main page]</A></P>
  
  <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="mailto:sbekman@iil.intel.com">Stas Bekman</A>.
  	     <BR>Last Modified at 12/07/98 
        </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>
  	    
  
  <HR SIZE=6>
  <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
  <HTML>
  <HEAD>
     <TITLE>mod_perl guide: Code Snippets</TITLE>
     <META NAME="GENERATOR" CONTENT="Mozilla/3.04Gold (X11; I; AIX 4.1) [Netscape]">
     <META NAME="Author" CONTENT="Bekman Stas">
     <META NAME="Description" CONTENT="mod_perl,perl,apache">
     <META NAME="Keywords" CONTENT="mod_perl,perl,apache,webserver,cgi">
  </HEAD>
  <BODY TEXT="#000000" BGCOLOR="#E0FFFF" LINK="#0000EE" VLINK="#551A8B" ALINK="#FF0000">
  
  <H1 ALIGN=CENTER>
  <A HREF="http://perl.apache.org"><IMG SRC="images/mod_perl.gif" ALT="Mod Perl Icon" BORDER=0 HEIGHT=30 WIDTH=90 ALIGN=LEFT></A>
  <A HREF="http://perl.apache.org"><IMG SRC="images/mod_perl.gif" ALT="Mod Perl Icon" BORDER=0 HEIGHT=30 WIDTH=90 ALIGN=RIGHT></A>
  Code Snippets</H1>
  <HR WIDTH="100%">
  	    <!-- INDEX BEGIN -->
  <P><A NAME="toc"></A><B><FONT SIZE=-1>Table of Contents:</FONT></B></P>
  <UL>
  
  	<LI><A HREF="#Redirecting_Errors_to_Client_ins">Redirecting Errors to Client instead of error_log</A>
  	<LI><A HREF="#Sending_MIME_headers">Sending MIME headers</A>
  </UL>
  <!-- INDEX END -->
  
  <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  <P>
  <CENTER><H1><A NAME="Redirecting_Errors_to_Client_ins">Redirecting Errors to Client instead of error_log</A></H1></CENTER>
  <P>
  To trap all/most Perl run-time errors and send the output to the client
  instead of Apache's error log add this line to your script.
  
  <P>
  <PRE>  use CGI::Carp qw(fatalsToBrowser);
  </PRE>
  <P>
  <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  <CENTER><H1><A NAME="Sending_MIME_headers">Sending MIME headers</A></H1></CENTER>
  <P>
  By default, mod_perl does not send any headers by itself, however, you may
  wish to change this behavior by setting in config file: 
  
  <P>
  <PRE>  PerlSendHeader On   
  </PRE>
  <P>
  The safest bet is to use CGI.pm's <CODE>print header();</CODE> method (If you use this, you don't need the above setting)
  
  <P>
  Also there is $ENV{PERL_SEND_HEADER} to see if PerlSendHeader is On or Off.
  
  <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  <P><A HREF="index.html">[Back to the main page]</A></P>
  
  <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="mailto:sbekman@iil.intel.com">Stas Bekman</A>.
  	     <BR>Last Modified at 12/07/98 
        </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>
  	    
  
  <HR SIZE=6>
  <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
  <HTML>
  <HEAD>
     <TITLE>mod_perl guide: </TITLE>
     <META NAME="GENERATOR" CONTENT="Mozilla/3.04Gold (X11; I; AIX 4.1) [Netscape]">
     <META NAME="Author" CONTENT="Bekman Stas">
     <META NAME="Description" CONTENT="mod_perl,perl,apache">
     <META NAME="Keywords" CONTENT="mod_perl,perl,apache,webserver,cgi">
  </HEAD>
  <BODY TEXT="#000000" BGCOLOR="#E0FFFF" LINK="#0000EE" VLINK="#551A8B" ALINK="#FF0000">
  
  <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>
  Help. Futher Learning</H1>
  
  <P>
  <HR WIDTH="100%"></P>
  
  <P><A NAME="toc"></A><B><FONT SIZE=-1>Table of Contents:</FONT></B></P>
  
  <UL>
  <LI><A HREF="#1">READ ME&nbsp;FIRST</A></LI>
  
  <LI><A HREF="#2">mod_perl</A></LI>
  
  <LI><A HREF="#3">perl </A></LI>
  
  <LI><A HREF="#4">perl/CGI</A></LI>
  
  <LI><A HREF="#5">apache </A></LI>
  </UL>
  
  <P>
  <HR WIDTH="100%"></P>
  
  <H3><A NAME="1"></A>READ ME&nbsp;FIRST</H3>
  
  <P>If after reading this guide and other documents listed n this section,
  you feel that your question is yet not answered, please ask the apache/mod_perl
  mailing list to help you. But first try to browse the mailing list archive.
  Most of the time you will find the answer for your question by searching
  the mailing archive, since there is a big chance someone else already have
  encountered the problem and found a solution for it. If you ignore this
  advice, don't be surprised if your question will be left unanswered - it
  bores people to answer the same question more than once. It doesn't mean
  that you should avoid asking questions. Just don't abuse the available
  help and <B>RTFM </B>before you call for <B>HELP</B>. (You have certainly
  heard the infamous fable of the shepherd boy and the wolves)</P>
  
  <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B> 
  <HR WIDTH="100%"></P>
  
  <H3><A NAME="2"></A>mod_perl</H3>
  
  <UL>
  <LI><A HREF="perl.apache.org">perl.apache.org </A>- mod_perl home </LI>
  
  <LI><A HREF="www.modperl.com">www.modperl.com</A> - This 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.</LI>
  
  <LI><A HREF="http://perl.apache.org/dist/cgi_to_mod_perl.html">Quick guide
  </A>for moving from CGI to mod_perl. </LI>
  
  <LI>Frank Cringle's <A HREF="http://perl.apache.org/faq/">mod_perl FAQ</A></LI>
  
  <LI>Vivek Khera's <A HREF="http://perl.apache.org/tuning/">mod_perl performance
  tuning guide</A></LI>
  
  <LI>Doug MacEachern's <A HREF="http://perl.apache.org/src/mod_perl.html">mod_perl
  plugin reference guide</A>. </LI>
  
  <LI><A HREF="http://perl.apache.org/dist/mod_perl_traps.html">mod_perl_traps,</A>
  common traps and solutions for mod_perl users. </LI>
  
  <LI><A HREF="http://www.refcards.com">mod_perl Quick Reference
  	  Card</A> 
  (Apache and other refcards are available from this link</LI>
  
  <LI>mod_perl mailing list</LI>
  
  <P>The Apache/Perl mailing list (modperl@apache.org) <B>is available
  for mod_perl users and developers to share ideas, solve problems and
  discuss things related to mod_perl and the Apache::* modules.</B> To
  subscribe to this list, send mail to <a
  href="mailto:majordomo@apache.org">majordomo@apache.org</a> with the
  string &quot;subscribe modperl&quot; in the body. </P>
  
  <P><B>Searchable </B>mod_perl mailing list<A
  HREF="http://forum.swarthmore.edu/epigone/modperl"><B>archive</B></A>by
  Ken Williams. </P>
  </UL>
  
  <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B> 
  <HR WIDTH="100%"></P>
  
  <H3><A NAME="3"></A>Perl </H3>
  
  <UL>
  <LI><A HREF="http://www.perl.com/CPAN/doc/FAQs/FAQ/PerlFAQ.html">The Perl
  FAQ </A></LI>
  
  <LI><A HREF="http://www.perl.com/">www.perl.com</A></LI>
  
  <LI><A HREF="http://www.tpj.com/">The Perl Journal </A></LI>
  
  <LI><A HREF="http://world.std.com/~swmcd/steven/perl/module_mechanics.html">Perl
  Module Mechanics </A>- This page describes the mechanics of creating, compiling,
  releasing and maintaining Perl modules. </LI>
  </UL>
  
  <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B> 
  <HR WIDTH="100%"></P>
  
  <H3><A NAME="4"></A>Perl/CGI</H3>
  
  <UL>
  <LI><A HREF="http://www.perl.com/CPAN/doc/FAQs/cgi/perl-cgi-faq.html">Perl/CGI
  FAQ </A></LI>
  
  <LI><A HREF="http://www.eprotect.com/stas/TULARC/webmaster/myfaq.html">Answers
  to some bothering Perl and Perl/CGI&nbsp;questions</A></LI>
  
  <LI><A HREF="http://www.perl.com/CPAN/doc/FAQs/cgi/idiots-guide.html">Idiot's
  Guide to CGI programming </A></LI>
  
  <LI><A HREF="http://www.genome.wi.mit.edu/WWW/faqs/cgi/www-security-faq.html">WWW
  Security FAQ </A></LI>
  
  <LI><A HREF="http://www.gunther.web66.com/FAQS/taintmode.html">CGI/Perl
  Taint Mode FAQ</A> (by Gunther Birznieks)</LI>
  </UL>
  
  <H3><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B> 
  <HR WIDTH="100%"></H3>
  
  <H3><A NAME="5"></A>Apache </H3>
  
  <UL>
  <LI><A HREF="http://www.apache.org">Apache Project's Home</A></LI>
  
  <LI><A HREF="http://www.ford-mason.co.uk/resources/refcards/apache.html">Apache
  Quick Reference Card</A></LI>
  
  <LI><A HREF="http://www.apache.org/docs/misc/FAQ.html">The Apache FAQ</A></LI>
  
  <LI><A HREF="http://www.apache.org/docs/">Apache Server Documentation</A></LI>
  </UL>
  
  <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B> 
  <HR WIDTH="100%"></P>
  
  <P><A HREF="index.html">[Back to the main page]</A></P>
  
  <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="mailto:sbekman@iil.intel.com">Stas
  Bekman</A>.<BR>
  Last Modified at 12/04/1998 </FONT></B></TD>
  
  <TD><A HREF="http://perl.apache.org"><IMG SRC="images/mod_perl2.jpg"  BORDER=0 ALT="Mod Perl Icon" 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>
  
  
  <HR SIZE=6>