perl-modperl-cvs mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From sbek...@hyperreal.org
Subject cvs commit: modperl-site/guide CHANGES advocacy.html all.html browserbugs.html config.html control.html databases.html dbm.html debug.html download.html frequent.html guide-src.tar.gz guide.tar.gz hardware.html help.html index.html install.html intro.html mod_perl_guide.ps.gz modules.html multiuser.html obvious.html performance.html perl.html porting.html scenario.html security.html snippets.html start.html status.html strategy.html warnings.html
Date Sat, 25 Sep 1999 23:14:37 GMT
sbekman     99/09/25 16:14:36

  Modified:    guide    CHANGES advocacy.html all.html browserbugs.html
                        config.html control.html databases.html dbm.html
                        debug.html download.html frequent.html
                        guide-src.tar.gz guide.tar.gz hardware.html
                        help.html index.html install.html intro.html
                        mod_perl_guide.ps.gz modules.html multiuser.html
                        obvious.html performance.html perl.html
                        porting.html scenario.html security.html
                        snippets.html start.html status.html strategy.html
                        warnings.html
  Log:
  09.26.99 ver 1.16
  
  * Many little things fixed, rewritten - didn't worth listing them all
    here.
  
  * index.html: added another search box for only mod_perl FAQs and the
    guide provided by perlreference.com
  
  * config: added a note about Apache restarting twice on start
  
  * warnings: added "syntax error at /dev/null" - broken /dev/null
    (Doug)
  
  * porting: added "Special Perl Variables" using local()
  
  * multiuser: Added the considerations not to let users to execute their
    CGI scripts inside mod_perl server because of file permissions
    (non-mod_perl problem) and a possibility to hijack a DBI connection
    from Apache::DBI pool of cached connections (Peter Galbavy)
  
  * install: added "Is it possible to tell whether some option was
    included" nm() hints (Doug)
  
  * performance: new "PerlSetupEnv Off" (Doug)
  
  * porting: new section "Passing and preserving custom data structures
    between handlers" (Ken Williams)
  
  * security: "OK, AUTH_REQUIRED.and FORBIDDEN" in authentication
    phase. (Eric Cholet, Jason Bodnar)
  
  * porting: rewrote the "Generating correct HTTP Headers" section, to
    talk about HEAD requests, PerlSendHeader, Perl API to handle the
    headers generation, Cookie headers, closure methods to send headers
    only once.
  
  * Purifications: I'm very grateful to the people who take their time
    to help me to improve the guide's readablility. This time Richard
    A. Wells and Frank Schoeters submitted a few corrections to the
    text. Keep these corrections coming. Thanks!
  
  * porting: extended the "Forking and Starting Sub-processes with
    mod_perl" section (Les Mikesell, Randal L. Schwartz )
  
  * porting: Wrote a whole new section "Configuration Files: Writing,
    Modifying and Reloading.", which consist of 3 big parts:
  	      Writing Configuration Files
                Reloading Configuration Files
                Dynamically updating configuration files
  
  * scenario: updated the X-Forwarded-For> section with notes of
    non-reliability. (Ask Bjoern Hansen, Vivek Khera)
  
  * porting: started the "Sharing variables between processes" section
    (Eric Cholet)
  
  * config: dumping the configuration by <Perl> sections (Eric Cholet)
  
  * performance: prepare_cached() in persistent connections.
  
  * help.pod: updated a link to Jefferey W. Baker's DBI examples
    (Jefferey W. Baker)
  
  * a list of mailing list archives was updated (Andreas J. Koenig, Jan
    Peter Hecking, Matthew Darwin, Christof Damian, Young, Geoffrey S)
  
  * debug.pod: "Spinning httpds" section from mod_perl.pod
  
  * config.pod: have stolen the sections "PERL METHOD HANDLERS",
   "STACKED HANDLERS" and "Perl*Handlers" from mod_perl.pod
  
  * performance.pod: noted the DTWO_POT_OPTIMIZE and -DPACK_MALLOC Perl
    Options from perl5004delta.pod relevant to mod_perl
  
  * config.pod: wrote sections "PerlModule and PerlRequire directives",
    and Perl*Handlers.
  
  * install.pod: "skipping test on this platform" while 'make test'
    explained. (Doug)
  
  * warnings.pod: syntax error at /dev/null, explained (Doug)
  
  * started to work on intro.pod to make clear out the differences
    between Perl API, Apache::Registry, Apache::PerlRun.
  
  * install.pod: added "mod_auth_dbm nuances" an old notice from
    mod_perl_traps page
  
  * porting.pod: Added the explanation of why you cannot use C<__END__>
    or C<__DATA__> within C<Apache::Registry> scripts.
  
  * Removed the Cyan background from the postscript version of the
    guide. I liked the light grey background when the guide was printed
    on the B&W printer, but yes it uses too much toner - so it's gone :)
  
  Revision  Changes    Path
  1.16      +95 -0     modperl-site/guide/CHANGES
  
  Index: CHANGES
  ===================================================================
  RCS file: /export/home/cvs/modperl-site/guide/CHANGES,v
  retrieving revision 1.15
  retrieving revision 1.16
  diff -u -r1.15 -r1.16
  --- CHANGES	1999/08/17 19:03:28	1.15
  +++ CHANGES	1999/09/25 23:13:47	1.16
  @@ -1,5 +1,100 @@
   This is a CHANGES file for mod_perl guide
   
  +09.20.99 ver 1.16
  +
  +* Many little things fixed, rewritten - didn't worth listing them all
  +  here.
  +
  +* index.html: added another search box for only mod_perl FAQs and the
  +  guide provided by perlreference.com
  +
  +* config: added a note about Apache restarting twice on start
  +
  +* warnings: added "syntax error at /dev/null" - broken /dev/null
  +  (Doug)
  +
  +* porting: added "Special Perl Variables" using local()
  +
  +* multiuser: Added the considerations not to let users to execute their
  +  CGI scripts inside mod_perl server because of file permissions
  +  (non-mod_perl problem) and a possibility to hijack a DBI connection
  +  from Apache::DBI pool of cached connections (Peter Galbavy)
  +
  +* install: added "Is it possible to tell whether some option was
  +  included" nm() hints (Doug)
  +
  +* performance: new "PerlSetupEnv Off" (Doug)
  +
  +* porting: new section "Passing and preserving custom data structures
  +  between handlers" (Ken Williams)
  +
  +* security: "OK, AUTH_REQUIRED.and FORBIDDEN" in authentication
  +  phase. (Eric Cholet, Jason Bodnar)
  +
  +* porting: rewrote the "Generating correct HTTP Headers" section, to
  +  talk about HEAD requests, PerlSendHeader, Perl API to handle the
  +  headers generation, Cookie headers, closure methods to send headers
  +  only once.
  + 
  +* Purifications: I'm very grateful to the people who take their time
  +  to help me to improve the guide's readablility. This time Richard
  +  A. Wells and Frank Schoeters submitted a few corrections to the
  +  text. Keep these corrections coming. Thanks!
  +
  +* porting: extended the "Forking and Starting Sub-processes with
  +  mod_perl" section (Les Mikesell, Randal L. Schwartz )
  +
  +* porting: Wrote a whole new section "Configuration Files: Writing,
  +  Modifying and Reloading.", which consist of 3 big parts:
  +	      Writing Configuration Files 
  +              Reloading Configuration Files 
  +              Dynamically updating configuration files 
  +
  +* scenario: updated the X-Forwarded-For> section with notes of
  +  non-reliability. (Ask Bjoern Hansen, Vivek Khera)
  +
  +* porting: started the "Sharing variables between processes" section
  +  (Eric Cholet)
  +
  +* config: dumping the configuration by <Perl> sections (Eric Cholet)
  +
  +* performance: prepare_cached() in persistent connections.
  +
  +* help.pod: updated a link to Jefferey W. Baker's DBI examples
  +  (Jefferey W. Baker)
  +
  +* a list of mailing list archives was updated (Andreas J. Koenig, Jan
  +  Peter Hecking, Matthew Darwin, Christof Damian, Young, Geoffrey S)
  +
  +* debug.pod: "Spinning httpds" section from mod_perl.pod
  +
  +* config.pod: have stolen the sections "PERL METHOD HANDLERS",
  + "STACKED HANDLERS" and "Perl*Handlers" from mod_perl.pod
  +
  +* performance.pod: noted the DTWO_POT_OPTIMIZE and -DPACK_MALLOC Perl
  +  Options from perl5004delta.pod relevant to mod_perl
  +
  +* config.pod: wrote sections "PerlModule and PerlRequire directives",
  +  and Perl*Handlers.
  +
  +* install.pod: "skipping test on this platform" while 'make test'
  +  explained. (Doug)
  +
  +* warnings.pod: syntax error at /dev/null, explained (Doug)
  +
  +* started to work on intro.pod to make clear out the differences
  +  between Perl API, Apache::Registry, Apache::PerlRun.
  +
  +* install.pod: added "mod_auth_dbm nuances" an old notice from
  +  mod_perl_traps page
  +
  +* porting.pod: Added the explanation of why you cannot use C<__END__>
  +  or C<__DATA__> within C<Apache::Registry> scripts.
  +
  +* Removed the Cyan background from the postscript version of the
  +  guide. I liked the light grey background when the guide was printed
  +  on the B&W printer, but yes it uses too much toner - so it's gone :)
  +
   08.17.99 ver 1.15
   
   * Richard A. Wells has kindly reviewed and corrected the following 
  
  
  
  1.4       +19 -0     modperl-site/guide/advocacy.html
  
  Index: advocacy.html
  ===================================================================
  RCS file: /export/home/cvs/modperl-site/guide/advocacy.html,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- advocacy.html	1999/08/17 19:03:31	1.3
  +++ advocacy.html	1999/09/25 23:13:47	1.4
  @@ -43,6 +43,15 @@
   
   	     <HR>
   
  +	       Your corrections of either technical or grammatical
  +	       errors are very welcome. You are encouraged to help me
  +	       to improve this guide.  If you have something to
  +	       contribute please <A
  +	       HREF="help.html#This_document_s_Author"> send it
  +	       directly to me</A>.
  +
  +	       <HR>
  +
   	      <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
   <P>
   <CENTER><H1><A NAME="Thoughts_about_scalability_and_f">Thoughts about scalability and flexibility</A></H1></CENTER>
  @@ -119,6 +128,16 @@
   	     Amazon.com</a>.
   
   	     <HR>
  +
  +	     Your corrections of either technical or grammatical
  +	     errors are very welcome. You are encouraged to help me
  +	     to improve this guide.  If you have something to
  +	     contribute please <A
  +	     HREF="help.html#This_document_s_Author"> send it
  +	     directly to me</A>.
  +
  +	     <HR>
  +
   	     [    <A HREF="hardware.html">Prev</A> |      <A HREF="index.html">Main Page</A> | <A HREF="help.html">Next</A>      ]
   
   <CENTER><TABLE CELLSPACING=2 CELLPADDING=2 WIDTH="100%" >
  
  
  
  1.17      +3374 -434 modperl-site/guide/all.html
  
  Index: all.html
  ===================================================================
  RCS file: /export/home/cvs/modperl-site/guide/all.html,v
  retrieving revision 1.16
  retrieving revision 1.17
  diff -u -r1.16 -r1.17
  --- all.html	1999/08/17 19:03:32	1.16
  +++ all.html	1999/09/25 23:13:48	1.17
  @@ -30,8 +30,8 @@
   <CENTER><P><B>Deploying mod_perl technology to give a rocket speed
   to your CGI/perl scripts.</B></P></CENTER>
   
  -<CENTER><P><B>Version 1.15
  - Aug, 17 1999</B></P></CENTER>
  +<CENTER><P><B>Version 1.16
  + Sep, 26 1999</B></P></CENTER>
    
   <P>
   <HR WIDTH="100%"></P>
  @@ -49,6 +49,15 @@
   <UL>
   
   	<LI><A HREF="intro.html#What_is_mod_perl">What is mod_perl</A>
  +	<UL>
  +
  +		<LI><A HREF="intro.html#mod_cgi">mod_cgi</A>
  +		<LI><A HREF="intro.html#C_API">C API</A>
  +		<LI><A HREF="intro.html#Perl_API">Perl API</A>
  +		<LI><A HREF="intro.html#Apache_Registry">Apache::Registry</A>
  +		<LI><A HREF="intro.html#Apache_PerlRun">Apache::PerlRun</A>
  +	</UL>
  +
   	<LI><A HREF="intro.html#What_will_you_learn">What will you learn</A>
   	<LI><A HREF="intro.html#References_and_Acknowledgments">References and Acknowledgments</A>
   </UL>
  @@ -65,48 +74,54 @@
   	<LI><A HREF="porting.html#Exposing_Apache_Registry_secret">Exposing Apache::Registry secrets</A>
   	<LI><A HREF="porting.html#Sometimes_it_Works_Sometimes_it_">Sometimes it Works Sometimes it Does Not</A>
   	<LI><A HREF="porting.html#What_s_different_about_modperl">What's different about modperl</A>
  -	<UL>
  -
  -		<LI><A HREF="porting.html#Script_s_name_space">Script's name space</A>
  -		<LI><A HREF="porting.html#Name_collisions_with_Modules_and">Name collisions with Modules and libs</A>
  -		<LI><A HREF="porting.html#More_package_name_related_issues">More package name related issues</A>
  -		<LI><A HREF="porting.html#_END_or_DATA_tokens">__END__ or __DATA__ tokens</A>
  -		<LI><A HREF="porting.html#Output_from_system_calls">Output from system calls</A>
  -		<LI><A HREF="porting.html#Using_format_">Using format()</A>
  -		<LI><A HREF="porting.html#Using_exit_">Using exit()</A>
  -		<LI><A HREF="porting.html#Running_from_shell">Running from shell</A>
  -		<LI><A HREF="porting.html#I_O_is_different">I/O is different</A>
  -		<LI><A HREF="porting.html#HTTP_MIME_Headers_PerlSendHea">HTTP + MIME Headers (PerlSendHeader)</A>
  -		<LI><A HREF="porting.html#NPH_Non_Parsed_Headers_scripts">NPH (Non Parsed Headers) scripts</A>
  -		<LI><A HREF="porting.html#BEGIN_blocks">BEGIN blocks </A>
  -		<LI><A HREF="porting.html#END_blocks">END blocks</A>
  -		<LI><A HREF="porting.html#Switches_w_T">Switches -w, -T</A>
  -		<LI><A HREF="porting.html#strict_pragma">strict pragma</A>
  -		<LI><A HREF="porting.html#Turning_warnings_ON">Turning warnings ON</A>
  -		<LI><A HREF="porting.html#diagnostics_pragma">diagnostics pragma</A>
  -		<LI><A HREF="porting.html#Passing_ENV_variables_to_CGI">Passing ENV variables to CGI</A>
  -		<LI><A HREF="porting.html#Global_Variables">Global Variables</A>
  -		<LI><A HREF="porting.html#Code_has_been_changed_but_it_se">Code has been changed, but it seems the script is running the old code</A>
  -		<LI><A HREF="porting.html#Apache_and_syslog">Apache and syslog</A>
  -		<LI><A HREF="porting.html#Memory_leakage">Memory leakage</A>
  -	</UL>
  -
  +	<LI><A HREF="porting.html#Script_s_name_space">Script's name space</A>
  +	<LI><A HREF="porting.html#Messing_with_INC">Messing with @INC</A>
   	<LI><A HREF="porting.html#Reloading_Modules_and_Required_F">Reloading Modules and Required Files</A>
   	<UL>
   
   		<LI><A HREF="porting.html#Restarting_the_server">Restarting the server</A>
  -		<LI><A HREF="porting.html#Using_Apache_StatINC">Using Apache::StatINC</A>
  -		<LI><A HREF="porting.html#Reloading_only_specific_files">Reloading only specific files</A>
  +		<LI><A HREF="porting.html#Using_Apache_StatINC_for_Develo">Using Apache::StatINC for Development Process</A>
  +		<LI><A HREF="porting.html#Configuration_Files_Writing_Mo">Configuration Files: Writing, Modifying and Reloading.</A>
  +		<UL>
  +
  +			<LI><A HREF="porting.html#Writing_Configuration_Files">Writing Configuration Files</A>
  +			<LI><A HREF="porting.html#Reloading_Configuration_Files">Reloading Configuration Files</A>
  +			<LI><A HREF="porting.html#Dynamically_updating_configurati">Dynamically updating configuration files</A>
  +		</UL>
  +
   		<LI><A HREF="porting.html#Reloading_handlers">Reloading handlers</A>
   	</UL>
   
  +	<LI><A HREF="porting.html#Name_collisions_with_Modules_and">Name collisions with Modules and libs</A>
  +	<LI><A HREF="porting.html#More_package_name_related_issues">More package name related issues</A>
  +	<LI><A HREF="porting.html#_END_or_DATA_tokens">__END__ or __DATA__ tokens</A>
  +	<LI><A HREF="porting.html#Output_from_system_calls">Output from system calls</A>
  +	<LI><A HREF="porting.html#Using_format_and_write_">Using format() and write()</A>
  +	<LI><A HREF="porting.html#Using_exit_">Using exit()</A>
  +	<LI><A HREF="porting.html#Running_from_shell">Running from shell</A>
  +	<LI><A HREF="porting.html#I_O_is_different">I/O is different</A>
  +	<LI><A HREF="porting.html#Special_Perl_Variables">Special Perl Variables</A>
  +	<LI><A HREF="porting.html#Generating_correct_HTTP_Headers">Generating correct HTTP Headers</A>
  +	<LI><A HREF="porting.html#NPH_Non_Parsed_Headers_scripts">NPH (Non Parsed Headers) scripts</A>
  +	<LI><A HREF="porting.html#BEGIN_blocks">BEGIN blocks </A>
  +	<LI><A HREF="porting.html#END_blocks">END blocks</A>
  +	<LI><A HREF="porting.html#Switches_w_T">Switches -w, -T</A>
  +	<LI><A HREF="porting.html#strict_pragma">strict pragma</A>
  +	<LI><A HREF="porting.html#Turning_warnings_ON">Turning warnings ON</A>
  +	<LI><A HREF="porting.html#diagnostics_pragma">diagnostics pragma</A>
  +	<LI><A HREF="porting.html#Passing_ENV_variables_to_CGI">Passing ENV variables to CGI</A>
  +	<LI><A HREF="porting.html#Global_Variables">Global Variables</A>
  +	<LI><A HREF="porting.html#Code_has_been_changed_but_it_se">Code has been changed, but it seems the script is running the old code</A>
  +	<LI><A HREF="porting.html#Apache_and_syslog">Apache and syslog</A>
  +	<LI><A HREF="porting.html#Memory_leakage">Memory leakage</A>
   	<LI><A HREF="porting.html#Filehandlers_and_locks_leakages">Filehandlers and locks leakages</A>
   	<LI><A HREF="porting.html#The_Script_is_too_dirty_but_It_">The Script is too dirty, but It does the job and I can't afford rewriting it.</A>
   	<LI><A HREF="porting.html#Apache_PerlRun_a_closer_look">Apache::PerlRun - a closer look</A>
  +	<LI><A HREF="porting.html#Sharing_variables_between_proces">Sharing variables between processes</A>
   	<LI><A HREF="porting.html#Redirecting_Errors_to_Client_ins">Redirecting Errors to Client instead of error_log</A>
   	<LI><A HREF="porting.html#Finding_the_line_number_the_erro">Finding the line number the error/warning has been triggered at</A>
  -	<LI><A HREF="porting.html#Forking_subprocesses_from_mod_pe">Forking subprocesses from mod_perl</A>
  -	<LI><A HREF="porting.html#Generating_correct_HTTP_MIME_Hea">Generating correct HTTP MIME Headers</A>
  +	<LI><A HREF="porting.html#Forking_or_Executing_subprocesse">Forking or Executing subprocesses from mod_perl</A>
  +	<LI><A HREF="porting.html#Passing_and_preserving_custom_da">Passing and preserving custom data structures between handlers</A>
   </UL>
   <P><LI><A HREF="performance.html"><B><FONT SIZE=+1>Performance. Benchmarks.</FONT></B></A></LI><P>
   <UL>
  @@ -121,6 +136,8 @@
   
   	<LI><A HREF="performance.html#Preload_Registry_Scripts">Preload Registry Scripts</A>
   	<LI><A HREF="performance.html#Avoid_Importing_Functions">Avoid Importing Functions</A>
  +	<LI><A HREF="performance.html#PerlSetupEnv_Off">PerlSetupEnv Off</A>
  +	<LI><A HREF="performance.html#_DTWO_POT_OPTIMIZE_and_DPACK_MA">-DTWO_POT_OPTIMIZE and -DPACK_MALLOC Perl Options</A>
   	<LI><A HREF="performance.html#Shared_Memory">Shared Memory</A>
   	<LI><A HREF="performance.html#Checking_script_modification_tim">Checking script modification times</A>
   	<LI><A HREF="performance.html#How_can_I_find_if_my_mod_perl_sc">How can I find if my mod_perl scripts have memory leaks</A>
  @@ -224,15 +241,18 @@
   	</UL>
   
   	<LI><A HREF="install.html#Is_it_possible_to_install_and_us">Is it possible to install and use apache/mod_perl without having a root access?</A>
  +	<LI><A HREF="install.html#Is_it_possible_to_tell_whether_s">Is it possible to tell whether some option was included</A>
   	<LI><A HREF="install.html#Is_it_possible_to_determine_whic">Is it possible to determine which options were given to modperl's Makefile.PL</A>
   	<LI><A HREF="install.html#Server_Installation_problems">Server Installation problems</A>
   	<UL>
   
  +		<LI><A HREF="install.html#_skipping_test_on_this_plat">......skipping test on this platform</A>
   		<LI><A HREF="install.html#make_test_fails">make test fails</A>
   		<LI><A HREF="install.html#mod_perl_c_is_incompatible_with_">mod_perl.c is incompatible with this version of apache</A>
   		<LI><A HREF="install.html#Should_I_rebuild_mod_perl_if_I_h">Should I rebuild mod_perl if I have upgraded my perl?</A>
   	</UL>
   
  +	<LI><A HREF="install.html#mod_auth_dbm_nuances">mod_auth_dbm nuances</A>
   	<LI><A HREF="install.html#Stripping_apache_to_make_it_almo">Stripping apache to make it almost perl-server</A>
   </UL>
   <P><LI><A HREF="config.html"><B><FONT SIZE=+1>Server Configuration</FONT></B></A></LI><P>
  @@ -243,6 +263,14 @@
   
   		<LI><A HREF="config.html#Alias_Configurations">Alias Configurations</A>
   		<LI><A HREF="config.html#Location_Configuration">Location Configuration</A>
  +		<LI><A HREF="config.html#PerlModule_and_PerlRequire_direc">PerlModule and PerlRequire directives</A>
  +		<LI><A HREF="config.html#Perl_Handlers">Perl*Handlers</A>
  +	</UL>
  +
  +	<LI><A HREF="config.html#STACKED_HANDLERS">STACKED HANDLERS</A>
  +	<LI><A HREF="config.html#PERL_METHOD_HANDLERS">PERL METHOD HANDLERS</A>
  +	<UL>
  +
   		<LI><A HREF="config.html#PerlFreshRestart">PerlFreshRestart</A>
   		<LI><A HREF="config.html#_perl_status_location">/perl-status location</A>
   		<UL>
  @@ -277,12 +305,13 @@
   		<LI><A HREF="config.html#My_script_works_under_cgi_bin_b">My script works under cgi-bin, but when called via mod_perl I see A 'Save-As' prompt</A>
   		<LI><A HREF="config.html#Is_there_a_way_to_provide_a_diff">Is there a way to provide a different startup.pl file for each individual virtual host</A>
   		<LI><A HREF="config.html#Is_there_a_way_to_modify_INC_on">Is there a way to modify @INC on a per-virtual-host or per-location basis.</A>
  -		<LI><A HREF="config.html#Sometimes_the_script_from_one_vi">Sometimes the script from one virtual host calls a script with</A>
  +		<LI><A HREF="config.html#A_Script_from_one_virtual_host_c">A Script from one virtual host calls a script with the same path from the other virtual host</A>
   		<LI><A HREF="config.html#the_server_no_longer_retrieves_t">the server no longer retrieves the DirectoryIndex files for a directory</A>
   	</UL>
   
   	<LI><A HREF="config.html#Configuration_Security_Concerns">Configuration Security Concerns</A>
   	<LI><A HREF="config.html#Logical_grouping_of_Location_Di">Logical grouping of Location, Directory and FilesMatch directives</A>
  +	<LI><A HREF="config.html#Apache_restarts_twice_on_start">Apache restarts twice on start</A>
   </UL>
   <P><LI><A HREF="frequent.html"><B><FONT SIZE=+1>Frequent mod_perl problems</FONT></B></A></LI><P>
   <UL>
  @@ -348,6 +377,7 @@
   	<LI><A HREF="warnings.html#RegistryLoader_Cannot_translate">RegistryLoader: Cannot translate the URI /home/httpd/perl/test.pl</A>
   	<LI><A HREF="warnings.html#Evil_things_might_happen_when_us">Evil things might happen when using PerlFreshRestart</A>
   	<LI><A HREF="warnings.html#server_reached_MaxClients_settin">server reached MaxClients setting, consider raising the MaxClients setting</A>
  +	<LI><A HREF="warnings.html#syntax_error_at_dev_null_line_1">syntax error at /dev/null line 1, near &quot;line arguments:&quot;</A>
   </UL>
   <P><LI><A HREF="security.html"><B><FONT SIZE=+1>Protecting Your Site</FONT></B></A></LI><P>
   <UL>
  @@ -362,7 +392,8 @@
   	<LI><A HREF="security.html#Authentication_code_snippets">Authentication code snippets</A>
   	<UL>
   
  -		<LI><A HREF="security.html#Forcing_reauthenticating">Forcing reauthenticating</A>
  +		<LI><A HREF="security.html#Forcing_re_authentication">Forcing re-authentication</A>
  +		<LI><A HREF="security.html#OK_AUTH_REQUIRED_and_FORBIDDEN_">OK, AUTH_REQUIRED.and FORBIDDEN in Authentication handlers</A>
   	</UL>
   
   </UL>
  @@ -437,6 +468,8 @@
   	<LI><A HREF="debug.html#gdb_says_there_are_no_debugging_">gdb says there are no debugging symbols</A>
   	<LI><A HREF="debug.html#Monitoring_error_log_file">Monitoring error_log file</A>
   	<LI><A HREF="debug.html#Debugging_Signal_Handlers_SIG_">Debugging Signal Handlers ($SIG{FOO})</A>
  +	<LI><A HREF="debug.html#Spinning_httpds">Spinning httpds</A>
  +	<LI><A HREF="debug.html#PROFILING">PROFILING</A>
   	<LI><A HREF="debug.html#examples_of_strace_or_truss_us">examples of strace (or truss) usage</A>
   	<LI><A HREF="debug.html#Devel_Peek">Devel::Peek</A>
   </UL>
  @@ -476,8 +509,6 @@
   <P><LI><A HREF="snippets.html"><B><FONT SIZE=+1>Code Snippets</FONT></B></A></LI><P>
   <UL>
   
  -	<LI><A HREF="snippets.html#Sending_MIME_headers">Sending MIME headers</A>
  -	<LI><A HREF="snippets.html#How_to_avoid_printing_the_header">How to avoid printing the header more than once</A>
   	<LI><A HREF="snippets.html#More_on_relative_paths">More on relative paths</A>
   	<LI><A HREF="snippets.html#Watching_the_error_log_file_with">Watching the error_log file without telneting to the server</A>
   	<LI><A HREF="snippets.html#Accessing_variables_from_the_cal">Accessing variables from the caller's package</A>
  @@ -585,16 +616,31 @@
   <HR>
   <P>
   
  -Now you can search the indexed version of the guide at <A
  -HREF="http://www.perlreference.com/mod_perl/guide">perlreference.com</A>.
  -
   <HR>
  +
  +<A NAME="SEARCH"></A>
  +<CENTER>
  +<TABLE BORDER=10 CELLSPACING=2 CELLPADDING=8 >
  +<TR BGCOLOR="gray" ALIGN=CENTER VALIGN=TOP>
  +<TD ALIGN=CENTER VALIGN=TOP>
  +<FONT COLOR=WHITE>
  +Search mod_perl FAQs along with this guide 
  +<BR> at www.perlreference.com
  +<FORM action="http://perlreference.com/cgi-bin/mod_perl/search.pl" method="GET">
  +<INPUT type="text" name="q" value="" SIZE=15>
  +<INPUT TYPE="submit" VALUE="Search">
  +</FORM>
  +</FONT>
  +</TD></TR>
  +</TABLE>
  +</CENTER>
  +
   <CENTER>
   <TABLE BORDER=10 CELLSPACING=2 CELLPADDING=8 >
   <TR BGCOLOR="gray" ALIGN=CENTER VALIGN=TOP>
   <TD ALIGN=CENTER VALIGN=TOP>
   <FONT COLOR=WHITE>
  -<A NAME="SEARCH">Search perl.apache.org along with this guide.</A>
  +Search perl.apache.org along with this guide.
   <FORM ACTION="http://search.apache.org/" METHOD="POST">
   <INPUT TYPE="text" NAME="keyword" value="" SIZE=15>
   <input type="hidden" name="what" value="perl">
  @@ -624,7 +670,7 @@
   
   <TR ALIGN=CENTER VALIGN=TOP>
   <TD ALIGN=CENTER VALIGN=CENTER><B><FONT SIZE=-1>Written by <A
  -HREF="help.html#This_document_s_Author">Stas Bekman</A>.<BR> Last Modified at 08/17/1999
  +HREF="help.html#This_document_s_Author">Stas Bekman</A>.<BR> Last Modified at 09/26/1999
   </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>
  @@ -671,6 +717,15 @@
   <UL>
   
   	<LI><A HREF="#What_is_mod_perl">What is mod_perl</A>
  +	<UL>
  +
  +		<LI><A HREF="#mod_cgi">mod_cgi</A>
  +		<LI><A HREF="#C_API">C API</A>
  +		<LI><A HREF="#Perl_API">Perl API</A>
  +		<LI><A HREF="#Apache_Registry">Apache::Registry</A>
  +		<LI><A HREF="#Apache_PerlRun">Apache::PerlRun</A>
  +	</UL>
  +
   	<LI><A HREF="#What_will_you_learn">What will you learn</A>
   	<LI><A HREF="#References_and_Acknowledgments">References and Acknowledgments</A>
   </UL>
  @@ -688,6 +743,15 @@
   
   	     <HR>
   
  +	       Your corrections of either technical or grammatical
  +	       errors are very welcome. You are encouraged to help me
  +	       to improve this guide.  If you have something to
  +	       contribute please <A
  +	       HREF="help.html#This_document_s_Author"> send it
  +	       directly to me</A>.
  +
  +	       <HR>
  +
   	      <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
   <P>
   <CENTER><H1><A NAME="What_is_mod_perl">What is mod_perl</A></H1></CENTER>
  @@ -735,6 +799,123 @@
   
   <P>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<CENTER><H2><A NAME="mod_cgi">mod_cgi</A></H2></CENTER>
  +<P>
  +When you run your CGI scripts by using a configuration of:
  +
  +<P>
  +<PRE>  ScriptAlias /cgi-bin/ /home/httpd/cgi-bin/
  +</PRE>
  +<P>
  +you run it under a mod_cgi handler, you never define it explicitly. Apache
  +does all the configuration work behind the scenes, when you use a
  +ScriptAlias.
  +
  +<P>
  +BTW, don't confuse it with a <CODE>ExecCGI</CODE> configuration option, it's being enabled so the script will be executed and
  +not returned as a plain file. For example for mod_perl and <CODE>Apache::Registry</CODE> you would use a configuration like:
  +
  +<P>
  +<PRE>  &lt;Location /perl&gt;
  +    SetHandler perl-script
  +    PerlHandler Apache::Registry
  +    Options ExecCGI
  +    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="C_API">C API</A></H2></CENTER>
  +<P>
  +META: complete
  +
  +<P>
  +<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<CENTER><H2><A NAME="Perl_API">Perl API</A></H2></CENTER>
  +<P>
  +META: complete
  +
  +<P>
  +<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<CENTER><H2><A NAME="Apache_Registry">Apache::Registry</A></H2></CENTER>
  +<P>
  +From the point of Perl API, <CODE>Apache::Registry</CODE> is just yet another handler that's not conceptually different from any
  +other handler. It reads in the file, compiles, executes it and stores into
  +the cache. Since the perl interpreter keeps running from child process'
  +creation to its death, any code compiled by the interpreter is not removed
  +from memory until the child dies.
  +
  +<P>
  +To keep the script names from collisions, it prepends
  +<CODE>Apache::ROOT::</CODE> and the mangled path of the URI to the key of the cached script. This key
  +is actually a package name, the script resides in. So if you have requested
  +a script <CODE>/perl/project/test.pl</CODE>, the scripts would be wrapped in code which starts with package
  +declaration of:
  +
  +<P>
  +<PRE>  package Apache::ROOT::perl::project::test_e2pl;
  +</PRE>
  +<P>
  +<CODE>Apache::Registry</CODE> also stores the script's last modification time. Everytime the script
  +changes, the cached code would be discarded and recompiled using the
  +modified source. However, it doesn't check any of the perl libraries the
  +script might use.
  +
  +<P>
  +<CODE>Apache::Registry</CODE> overrides the <CODE>CORE::exit()</CODE> with &lt;Apache::exit()&gt;, so the CGI scripts that used the
  +&lt;exit()&gt; will run correctly. We will talk about all these details
  +indepth later.
  +
  +<P>
  +The last thing <CODE>Apache::Registry</CODE> does, is emulating of the mod_cgi's environment variables. Like <CODE>$ENV{SERVER_NAME}</CODE>, <CODE>$ENV{REMOTE_USER}</CODE>
  +and so on. <STRONG>PerlSetupEnv Off</STRONG> disables this feature and saves some memory bits and CPU clocks.
  +
  +<P>
  +From the point of mod_cgi (when you take the script that was running as a
  +plain CGI under mod_cgi to run under mod_perl), there is almost no
  +difference, but great speed improve, though much heavier memory usage
  +(there is no free lunch :).
  +
  +<P>
  +Just rememeber that the code is being cached, so it wouldn't cleanup the
  +memory, like you used to with mod_cgi when the script was existing (it
  +doesn't exit in mod_perl).
  +
  +<P>
  +Also rememeber that any libraries that your script might
  +<CODE>require()</CODE> or <CODE>use()</CODE> wouldn't be recompiled when
  +changed.
  +
  +<P>
  +Of course the book will answer all this issues in depth.
  +
  +<P>
  +Just to show you what happens with your script, when it's being executed
  +under <CODE>Apache::Registry</CODE>. If we take the simplest code of (URI <CODE>/perl/project/test.pl</CODE>)
  +
  +<P>
  +<PRE>  print &quot;Content-type: text/html\n\n&quot;;
  +  print &quot;It works\n&quot;;
  +</PRE>
  +<P>
  +<CODE>Apache::Registry</CODE> will convert it into the following:
  +
  +<P>
  +<PRE>  package Apache::ROOT::perl::project::test_e2pl;
  +  use Apache qw(exit);
  +  sub handler {
  +    print &quot;Content-type: text/html\n\n&quot;;
  +    print &quot;It works\n&quot;;
  +  }
  +</PRE>
  +<P>
  +<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<CENTER><H2><A NAME="Apache_PerlRun">Apache::PerlRun</A></H2></CENTER>
  +<P>
  +META: Complete
  +
  +<P>
  +<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
   <CENTER><H1><A NAME="What_will_you_learn">What will you learn</A></H1></CENTER>
   <P>
   This document was written in an effort to help you start using Apache's
  @@ -852,8 +1033,8 @@
   
   <P><LI>
   <P>
  -<STRONG>Eric Cholet</STRONG>, who wrote complete sections for the guide, and pointed out the errors in
  -the guide.
  +<STRONG>Eric Cholet</STRONG>, who wrote complete sections for the guide, and pointed out the errors the
  +guide carried away.
   
   <P><LI>
   <P>
  @@ -921,6 +1102,16 @@
   	     Amazon.com</a>.
   
   	     <HR>
  +
  +	     Your corrections of either technical or grammatical
  +	     errors are very welcome. You are encouraged to help me
  +	     to improve this guide.  If you have something to
  +	     contribute please <A
  +	     HREF="help.html#This_document_s_Author"> send it
  +	     directly to me</A>.
  +
  +	     <HR>
  +
   	     [    <A HREF="index.html">Main Page</A> | <A HREF="start.html">Next</A>      ]
   
   <CENTER><TABLE CELLSPACING=2 CELLPADDING=2 WIDTH="100%" >
  @@ -934,7 +1125,7 @@
       <B>
         <FONT SIZE=-1>
   	     Written by <A HREF="help.html#This_document_s_Author">Stas Bekman</A>.
  -	     <BR>Last Modified at 07/29/1999
  +	     <BR>Last Modified at 09/25/1999
         </FONT>
       </B>
     </TD>
  @@ -1002,18 +1193,26 @@
   
   	     <HR>
   
  +	       Your corrections of either technical or grammatical
  +	       errors are very welcome. You are encouraged to help me
  +	       to improve this guide.  If you have something to
  +	       contribute please <A
  +	       HREF="help.html#This_document_s_Author"> send it
  +	       directly to me</A>.
  +
  +	       <HR>
  +
   	      <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
   <P>
   <CENTER><H1><A NAME="What_s_inside_">What's inside?</A></H1></CENTER>
   <P>
  -Before you start installing mod_perl, you should have an overall picture of
  -this wonderful technology. There is more then one way to use a
  +Before you start with mod_perl installation, you should have an overall
  +picture of this wonderful technology. There is more then one way to use a
   mod_perl-enabled webserver. You have to decide what mod_perl scheme you
  -want to use. <A HREF="././strategy.html#">Picking the Right Strategy</A>
  -chapter presents various approaches and discusses their pros and cons.
  +want to use. <A HREF="././strategy.html#">Picking the Right Strategy</A> chapter presents various approaches and discusses their pros and cons.
   
   <P>
  -Once you know what fits your requirements the best, you should proceed to <A HREF="././scenario.html#">Real World Scenarios Implementaion</A>. This chapter provides very detailed scenarios of the schemes discussed in
  +Once you know what fits your requirements the best, you should proceed to <A HREF="././scenario.html#">Real World Scenarios Implementation</A>. This chapter provides very detailed scenarios of the schemes discussed in
   the
   <A HREF="././strategy.html#">Picking the Right Strategy</A> chapter.
   
  @@ -1058,6 +1257,9 @@
   the chapter <A HREF="././warnings.html#">Warnings and Errors: Where and Why</A>.
   
   <P>
  +<A HREF="././security.html#">Protecting Your Site</A> - Everything regarding security.
  +
  +<P>
   If you are into driving relational databases with your cgi scripts, the <A HREF="././databases.html#">mod_perl and Relational Databases</A> chapter will tell you all about the database-related goodies mod_perl has
   prepared for you.
   
  @@ -1070,7 +1272,7 @@
   possible? Is it secure? Will it work? What resources does it take? The <A HREF="././multiuser.html#">mod_perl for ISPs. mod_perl and Virtual Hosts</A>
   chapter answers all these questions. If you want to run a mod_perl- enabled
   server, but do not have root access, read this chapter as well, either to
  -learn how do it yourself, or maybe to persuade your ISP to provide this
  +learn how to do it yourself, or maybe to persuade your ISP to provide this
   service.
   
   <P>
  @@ -1115,6 +1317,13 @@
   writing the scripts.
   
   <P>
  +The <A HREF="././hardware.html#">Choosing an Operating System and Hardware</A> chapter gives you an idea on how to choose the SW and HW for the webserver.
  +
  +<P>
  +The &lt;mod_perl Advocacy|advocacy/&gt; tries to help to make it easier to
  +advocate mod_perl around the world.
  +
  +<P>
   The <A HREF="././help.html#">Getting Helped and Further Learning</A> chapter refers you to other related information resources, like learning
   Perl programming and SQL, understanding security, building databases, and
   more.
  @@ -1134,6 +1343,16 @@
   	     Amazon.com</a>.
   
   	     <HR>
  +
  +	     Your corrections of either technical or grammatical
  +	     errors are very welcome. You are encouraged to help me
  +	     to improve this guide.  If you have something to
  +	     contribute please <A
  +	     HREF="help.html#This_document_s_Author"> send it
  +	     directly to me</A>.
  +
  +	     <HR>
  +
   	     [    <A HREF="intro.html">Prev</A> |      <A HREF="index.html">Main Page</A> | <A HREF="porting.html">Next</A>      ]
   
   <CENTER><TABLE CELLSPACING=2 CELLPADDING=2 WIDTH="100%" >
  @@ -1147,7 +1366,7 @@
       <B>
         <FONT SIZE=-1>
   	     Written by <A HREF="help.html#This_document_s_Author">Stas Bekman</A>.
  -	     <BR>Last Modified at 07/29/1999
  +	     <BR>Last Modified at 09/26/1999
         </FONT>
       </B>
     </TD>
  @@ -1204,48 +1423,54 @@
   	<LI><A HREF="#Exposing_Apache_Registry_secret">Exposing Apache::Registry secrets</A>
   	<LI><A HREF="#Sometimes_it_Works_Sometimes_it_">Sometimes it Works Sometimes it Does Not</A>
   	<LI><A HREF="#What_s_different_about_modperl">What's different about modperl</A>
  -	<UL>
  -
  -		<LI><A HREF="#Script_s_name_space">Script's name space</A>
  -		<LI><A HREF="#Name_collisions_with_Modules_and">Name collisions with Modules and libs</A>
  -		<LI><A HREF="#More_package_name_related_issues">More package name related issues</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_format_">Using format()</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_PerlSendHea">HTTP + MIME Headers (PerlSendHeader)</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>
  -		<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="#Passing_ENV_variables_to_CGI">Passing ENV variables to CGI</A>
  -		<LI><A HREF="#Global_Variables">Global Variables</A>
  -		<LI><A HREF="#Code_has_been_changed_but_it_se">Code has been changed, but it seems the script is running the old code</A>
  -		<LI><A HREF="#Apache_and_syslog">Apache and syslog</A>
  -		<LI><A HREF="#Memory_leakage">Memory leakage</A>
  -	</UL>
  -
  +	<LI><A HREF="#Script_s_name_space">Script's name space</A>
  +	<LI><A HREF="#Messing_with_INC">Messing with @INC</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>
  +		<LI><A HREF="#Using_Apache_StatINC_for_Develo">Using Apache::StatINC for Development Process</A>
  +		<LI><A HREF="#Configuration_Files_Writing_Mo">Configuration Files: Writing, Modifying and Reloading.</A>
  +		<UL>
  +
  +			<LI><A HREF="#Writing_Configuration_Files">Writing Configuration Files</A>
  +			<LI><A HREF="#Reloading_Configuration_Files">Reloading Configuration Files</A>
  +			<LI><A HREF="#Dynamically_updating_configurati">Dynamically updating configuration files</A>
  +		</UL>
  +
   		<LI><A HREF="#Reloading_handlers">Reloading handlers</A>
   	</UL>
   
  +	<LI><A HREF="#Name_collisions_with_Modules_and">Name collisions with Modules and libs</A>
  +	<LI><A HREF="#More_package_name_related_issues">More package name related issues</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_format_and_write_">Using format() and write()</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="#Special_Perl_Variables">Special Perl Variables</A>
  +	<LI><A HREF="#Generating_correct_HTTP_Headers">Generating correct HTTP Headers</A>
  +	<LI><A HREF="#NPH_Non_Parsed_Headers_scripts">NPH (Non Parsed Headers) scripts</A>
  +	<LI><A HREF="#BEGIN_blocks">BEGIN blocks </A>
  +	<LI><A HREF="#END_blocks">END blocks</A>
  +	<LI><A HREF="#Switches_w_T">Switches -w, -T</A>
  +	<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="#Passing_ENV_variables_to_CGI">Passing ENV variables to CGI</A>
  +	<LI><A HREF="#Global_Variables">Global Variables</A>
  +	<LI><A HREF="#Code_has_been_changed_but_it_se">Code has been changed, but it seems the script is running the old code</A>
  +	<LI><A HREF="#Apache_and_syslog">Apache and syslog</A>
  +	<LI><A HREF="#Memory_leakage">Memory leakage</A>
   	<LI><A HREF="#Filehandlers_and_locks_leakages">Filehandlers and locks leakages</A>
   	<LI><A HREF="#The_Script_is_too_dirty_but_It_">The Script is too dirty, but 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>
  +	<LI><A HREF="#Sharing_variables_between_proces">Sharing variables between processes</A>
   	<LI><A HREF="#Redirecting_Errors_to_Client_ins">Redirecting Errors to Client instead of error_log</A>
   	<LI><A HREF="#Finding_the_line_number_the_erro">Finding the line number the error/warning has been triggered at</A>
  -	<LI><A HREF="#Forking_subprocesses_from_mod_pe">Forking subprocesses from mod_perl</A>
  -	<LI><A HREF="#Generating_correct_HTTP_MIME_Hea">Generating correct HTTP MIME Headers</A>
  +	<LI><A HREF="#Forking_or_Executing_subprocesse">Forking or Executing subprocesses from mod_perl</A>
  +	<LI><A HREF="#Passing_and_preserving_custom_da">Passing and preserving custom data structures between handlers</A>
   </UL>
   <!-- INDEX END -->
   
  @@ -1261,6 +1486,15 @@
   
   	     <HR>
   
  +	       Your corrections of either technical or grammatical
  +	       errors are very welcome. You are encouraged to help me
  +	       to improve this guide.  If you have something to
  +	       contribute please <A
  +	       HREF="help.html#This_document_s_Author"> send it
  +	       directly to me</A>.
  +
  +	       <HR>
  +
   	      <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>
  @@ -1304,9 +1538,15 @@
   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>
  -A must have book! See the details at <A
  +The information is very relevant to a mod_perl developer.
  +
  +<P><LI><STRONG><A NAME="item_The">The Eagle Book</A></STRONG>
  +<P>
  +``Writing Apache Modules with Perl and C'' is a ``must have'' book!
  +
  +<P>
  +See the details at <A
   HREF="http://www.modperl.com">http://www.modperl.com</A> .
   
   </UL>
  @@ -1482,8 +1722,8 @@
   the <CODE>handler</CODE> subroutine.
   
   <P>
  -The workaround is to use global declared variables, with <CODE>vars</CODE>
  -pragma.
  +One of the workarounds is to use global declared variables, with
  +<CODE>vars</CODE> pragma.
   
   <P>
   <PRE>  # !/usr/bin/perl -w
  @@ -1528,16 +1768,133 @@
       print &quot;Counter is equal to $main::counter !&lt;BR&gt;\n&quot;;
     }
   </PRE>
  +<P>
  +Another working but not quite good solution, is always to pass the variable
  +as an argument. It's not good when the variable can be quite big, so it
  +adds an overhead of time and memory. 
  +
  +<P>
  +<PRE>  #!/usr/bin/perl -w
  +  use strict;
  +  
  +  print &quot;Content-type: text/html\r\n\r\n&quot;;
  +  
  +  my $counter = 0;
  +  
  +  for (1..5) {
  +    increment_counter($counter);
  +  }
  +  
  +  sub increment_counter{
  +    my $counter = shift || 0 ;
  +    $counter++; 
  +    print &quot;Counter is equal to $counter !&lt;BR&gt;\n&quot;;
  +  }
  +</PRE>
  +<P>
  +It's important to understand that the closure effect happens only with code
  +that <CODE>Apache::Registry</CODE> wraps with a declaration of the
  +<CODE>handler</CODE> subroutine. If you put your code into a library or module, which the main
  +script <CODE>require()'s</CODE> or <CODE>use()'s,</CODE> there is no such a
  +problem. For example if we put the subroutine <CODE>increment_counter()</CODE>
  +into a <CODE>mylib.pl</CODE> (e.g. save it in the same directory as the main script) and
  +<CODE>require()</CODE> it, there will be no problem at all. (Don't forget
  +the <CODE>1;</CODE> at the end of the library or the <CODE>require()</CODE> might fail.)
  +
  +<P>
  +<PRE>  mylib.pl:
  +  ----------
  +  sub increment_counter{
  +    $counter++;
  +    print &quot;Counter is equal to $counter !&lt;BR&gt;\n&quot;;
  +  }
  +  1;
  +  ----------
  +</PRE>
  +<P>
  +<PRE>  counter.pl:
  +  ----------
  +  #!/usr/bin/perl -w
  +  use strict;
  +  require &quot;./mylib.pl&quot;;
  +  
  +  print &quot;Content-type: text/html\r\n\r\n&quot;;
  +  
  +  my $counter = 0;
  +  
  +  for (1..5) {
  +    increment_counter();
  +  }
  +  
  +  ----------
  +</PRE>
  +<P>
  +Personally, unless the script is too short, I've got used to write all the
  +code in the external libraries, and to have only a few lines in the main
  +script, generally to call the main function of my library. Usually i call
  +it <CODE>init()</CODE>. I don't worry about closure effect anymore (unless I create it myself :).
  +
  +<P>
  +You shouldn't be intimidated by this issue at all, since Perl is your
  +friend. Just keep the warnings mode On and whenever you will have this
  +effect in place, Perl will gladly tell you that by saying:
  +
  +<P>
  +<PRE>  Variable &quot;$counter&quot; will not stay shared at ...[snipped]
  +</PRE>
  +<P>
  +Just don't forget to check your error_log file, before going in production!
  +
  +<P>
  +BTW, the above example was pretty boring. In my first days of using
  +mod_perl, I wrote some cool user registration program. I'll show a very
  +simple represenataion of this program.
  +
  +<P>
  +<PRE>  use CGI;
  +  $q = new CGI;
  +  my $name = $q-&gt;param('name')
  +  print_respond();
  +  
  +  sub print_respond{
  +    print &quot;Content-type: text/html\n\n&quot;;
  +    print &quot;Thank you, $name!&quot;;
  +  }
  +</PRE>
   <P>
  -Now let's proceed to the second mystery. Why did we see inconsistent
  -results over numerous reloads. That's very simple. Every time a server gets
  -a request to process, it handles it over one of the children, generally in
  -a round robin fashion. So if you have 10 httpd children alive, first 10
  -reloads might seem to be correct. Since the closure starts to effect from
  -the second re-invocation, consequent reloads return unexpected results.
  -Moreover children don't serve the same request always consequently, at any
  -given moment one of the children could serve more times the same script
  -than any other. That's why we saw that strange behavior.
  +My boss and I have checked the program at the development server at it
  +worked OK. So we decided to put it in production, everything was OK, but my
  +boss decided to keep on checking by submitting a variations of his profile.
  +Imagine what was the surprise when after submitting his name (let's say
  +``Me Boss'' :), he saw a response ``Thank you, Stas Bekman!''. What
  +happened is that I tried the production system as well. I was new to
  +mod_perl stuff and was so excited with the speed improve, I didn't notice
  +the clusure problem and it hit me. At the beginning I thought that may be
  +Apache started to confuse connection, by returning responses from other
  +people's requests. I was wrong of course. Why didn't we notice this when we
  +were trying the system at our development server? Keep reading and you will
  +understand what was the problem.
  +
  +<P>
  +Now let's return to our original example and proceed with the second
  +mystery we have noticed. Why did we see inconsistent results over numerous
  +reloads. That's very simple. Every time a server gets a request to process,
  +it handles it over one of the children, generally in a round robin fashion.
  +So if you have 10 httpd children alive, first 10 reloads might seem to be
  +correct. Since the closure starts to effect from the second re-invocation,
  +consequent reloads return unexpected results. Moreover children don't serve
  +the same request always consequently, at any given moment one of the
  +children could serve more times the same script than any other. That's why
  +we saw that strange behavior.
  +
  +<P>
  +And now you understand why we didn't notice the problem with the user
  +registration system in the last example I've presented. First we didn't
  +look at the error_log files. (As a matter of fact we did, but there were so
  +many warnings in there, we couldn't tell what are the important ones and
  +what aren't). Then we didn't test the system under
  +<CODE>-X</CODE> flag (single mode) and we have had too many server children running to
  +notice the problem.
   
   <P>
   A workaround is to run the server in a single server mode. You achieve this
  @@ -1576,6 +1933,138 @@
   sometimes it helps.
   
   <P>
  +Sometimes it's very hard to understand what the warning complains about,
  +you see the source code, but you cannot understand why some specific
  +snippet produces warning. The mystery is in fact that the code can be
  +called from different places, e.g when it's a subrotine.
  +
  +<P>
  +I'll show you an example of such code.
  +
  +<P>
  +<PRE>  local $^W=1;
  +  good();
  +  bad();
  +  
  +  sub good{
  +    print_value(&quot;Perl&quot;);
  +  }
  +  
  +  sub bad{
  +    print_value();
  +  }
  +  
  +  sub print_value{
  +    my $var = shift;
  +    print &quot;My value is $var\n&quot;;
  +  }
  +</PRE>
  +<P>
  +In the code above, there is a sub that prints the passed value, sub
  +<CODE>good</CODE> that passes correctly the value and sub <CODE>bad</CODE> where we forgot to pass it. When we run the script, we get the warning:
  +
  +<P>
  +<PRE>  Use of uninitialized value at ./warning.pl line 15.
  +</PRE>
  +<P>
  +We can clearly see that there is an undefined value at the line, that
  +attempts to print it:
  +
  +<P>
  +<PRE>  print &quot;My value is $var\n&quot;;
  +</PRE>
  +<P>
  +But how do we know, why it was undefined? The solution is quite simple.
  +What we need is a full stack trace which triggered the warning.
  +
  +<P>
  +The <CODE>Carp</CODE> module comes to help with its <CODE>cluck()</CODE> function. Let's modify the script:
  +
  +<P>
  +<PRE>  use Carp ();
  +  local $SIG{__WARN__} = \&amp;Carp::cluck;
  +  
  +  local $^W=1;
  +  good();
  +  bad();
  +  
  +  sub good{
  +    print_value(&quot;Perl&quot;);
  +  }
  +  
  +  sub bad{
  +    print_value();
  +  }
  +  
  +  sub print_value{
  +    my $var = shift;
  +    print &quot;My value is $var\n&quot;;
  +  }
  +</PRE>
  +<P>
  +Now when we execute it, we would see:
  +
  +<P>
  +<PRE>  Use of uninitialized value at /home/httpd/perl/book/warning.pl line 17.
  +  Apache::ROOT::perl::book::warning_2epl::print_value() 
  +    called at /home/httpd/perl/book/warning.pl line 12
  +  Apache::ROOT::perl::book::warning_2epl::bad() 
  +    called at /home/httpd/perl/book/warning.pl line 5
  +  Apache::ROOT::perl::book::warning_2epl::handler('Apache=SCALAR(0x84b1154)') 
  +    called at /usr/lib/perl5/site_perl/5.005/i386-linux/Apache/Registry.pm line 139
  +  eval {...} called at 
  +    /usr/lib/perl5/site_perl/5.005/i386-linux/Apache/Registry.pm line 139
  +  Apache::Registry::handler('Apache=SCALAR(0x84b1154)') 
  +    called at PerlHandler subroutine `Apache::Registry::handler' line 0
  +  eval {...} called at PerlHandler subroutine `Apache::Registry::handler' line 0
  +</PRE>
  +<P>
  +Take a moment to understand the trace, the only part that we are intersted
  +in is the one that starts when actuall script is being called, so we can
  +skip the <CODE>Apache::Registry</CODE> trace part. So we get:
  +
  +<P>
  +<PRE>  Use of uninitialized value at /home/httpd/perl/book/warning.pl line 17.
  +  Apache::ROOT::perl::book::warning_2epl::print_value() 
  +    called at /home/httpd/perl/book/warning.pl line 12
  +  Apache::ROOT::perl::book::warning_2epl::bad() 
  +    called at /home/httpd/perl/book/warning.pl line 5
  +</PRE>
  +<P>
  +which tells us that the code that triggered the warning was:
  +
  +<P>
  +<PRE>  Apache::Registry code =&gt; bad() =&gt; print_value()
  +</PRE>
  +<P>
  +We go into a <CODE>bad()</CODE> and indeed see that we forgot to pass the variable. Of course when you
  +write a subroutine like <CODE>print_value</CODE> it could be a good idea to check the passed arguments before starting the
  +execution. But it was ``good'' enough to show you how to ease the code
  +debugging process.
  +
  +<P>
  +Sure, you would say. I could find the problem by a simple inspectation of
  +the code. You are right, but I promise you that your task would be quite
  +complicated and time consuming for the code of thousands lines.
  +
  +<P>
  +Notice the <CODE>local()</CODE> keyword, before the settings of the
  +<CODE>$SIG{__WARN__}</CODE>. Since it's a global variable, forgetting to use
  +<CODE>local()</CODE> will enforce this setting for all the scripts running under the same
  +process. And if it's wanted behaviour, for example in the development
  +server, you better do it in the startup file, where you can easily switch
  +this feature on and off when the server restarts.
  +
  +<P>
  +As you have noticed warnings report the line number the event happened at,
  +so it's supposed to help to find the problematic code. The problem is that
  +many times the line numbers are incorrect, because certain use of the <EM>eval</EM> operator and ``here'' documents are known to throw off Perl's line
  +numbering.
  +
  +<P>
  +META: move here the code that explains the settings of #line
  +
  +<P>
   While having a warning mode turned <STRONG>On</STRONG> is a must in a development server, you better turn it globally <STRONG>Off</STRONG> in a production server, since if every CGI script generates only one
   warning per request, and your server serves millions of requests per day -
   your log file will eat up all of your disk space and machine will die. My
  @@ -1691,7 +2180,7 @@
   
   <P>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<CENTER><H2><A NAME="Script_s_name_space">Script's name space</A></H2></CENTER>
  +<CENTER><H1><A NAME="Script_s_name_space">Script's name space</A></H1></CENTER>
   <P>
   Scripts under <CODE>Apache::Registry</CODE> do not run in package <STRONG>main</STRONG>, they run in a unique name space based on the requested URI. For example,
   if your URI is <STRONG>/perl/test.pl</STRONG> the package will be called
  @@ -1699,18 +2188,1072 @@
   
   <P>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<CENTER><H2><A NAME="Name_collisions_with_Modules_and">Name collisions with Modules and libs</A></H2></CENTER>
  +<CENTER><H1><A NAME="Messing_with_INC">Messing with @INC</A></H1></CENTER>
   <P>
  -To make things clear before we go into details: each child process has its
  -own <CODE>%INC</CODE> hash which is used to store information about its compiled modules. The
  -keys of the hash are the names of the modules or parameters passed to <CODE>require()</CODE> (<CODE>use()</CODE>). The values are the full or relative paths to these modules/files. Let's
  -say we have
  -<CODE>my-lib.pl</CODE> and <CODE>MyModule.pm</CODE> both located at <CODE>/home/httpd/perl/my/</CODE>.
  +When you <CODE>use(),</CODE> <CODE>require()</CODE> or <CODE>do()</CODE> a
  +file, Perl uses a <CODE>@INC</CODE>
  +variable, for a list of directories to search for the file. If the file
  +that you want to load is not located in one of the listed directories. You
  +have to tell Perl where to find the file.
   
   <P>
  -* <CODE>/home/httpd/perl/my/</CODE> is in the <CODE>@INC</CODE> path at the server startup.
  +In order to <CODE>require()</CODE> a file located at
  +<CODE>/home/httpd/perl/examples/test.pl</CODE> you would:
   
  -<P>
  +<UL>
  +<P><LI>
  +<P>
  +Use a relative path to one of the directories in the <CODE>@INC</CODE>. Let's say that one of the directories is <CODE>/home/httpd/perl</CODE>.
  +
  +<P>
  +<PRE>  require(&quot;examples/test.pl&quot;);
  +</PRE>
  +<P>
  +or modify the <CODE>@INC</CODE> on the fly:
  +
  +<P>
  +<PRE>  use lib qw(&quot;examples&quot;);
  +  require(&quot;test.pl&quot;);
  +</PRE>
  +<P>
  +That's when the script might be called from any place. If you always
  +execute the script from the directory it resides in (<CODE>examples</CODE>
  +here), you can do:
  +
  +<P>
  +<PRE>  use lib qw(&quot;.&quot;);
  +  require(&quot;test.pl&quot;);
  +</PRE>
  +<P>
  +But the latest two snippets would fail the reload by
  +<CODE>Apache::StatINC</CODE> module (which helps to automatically reload scripts while developing code)
  +since when running under mod_perl, <CODE>@INC</CODE> is being freezed, once the server is up and cannot be updated. The only
  +chance to temperarely modify the <CODE>@INC</CODE> is while the script is being loaded and compiled for the first time, and
  +when it's done, its value will be reset to the original one. Your only
  +chance to change the
  +<CODE>@INC</CODE> is to modify it in the startup or Apache configuration files.
  +
  +<P><LI>
  +<P>
  +You can write a full path to the script:
  +
  +<P>
  +<PRE>  require(&quot;/home/httpd/perl/examples/test.pl&quot;)
  +</PRE>
  +<P>
  +or
  +
  +<P>
  +<PRE>  use lib qw(&quot;/home/httpd/perl/examples/&quot;);
  +  require(&quot;test.pl&quot;);
  +</PRE>
  +<P>
  +the latter will fail the reload of <CODE>Apache::StatINC</CODE> as above. The former will set a correct entry into a <CODE>%INC</CODE> variable.
  +
  +<P>
  +This approach is quite discouraging, since if you want to move this script
  +around -- it's quite difficult since you have to modify the path all the
  +time. And it can be pretty painful when you move scripts from development
  +to production server.
  +
  +<P>
  +But wait, Graham Barr &amp; Nick Ing-Simmons made a present for you by
  +writing the <CODE>FindBin</CODE> module, if you know about this module, you don't need to write a hardcoded
  +path. The following snippet does all the work for you:
  +
  +<P>
  +<PRE>  use FindBin ();
  +  use lib &quot;$FindBin::Bin&quot;;
  +  use MyModule;
  +</PRE>
  +<P>
  +It works exactly like with hardcoded path, and it sets a correct
  +<CODE>%INC</CODE> entry as if you have used the hardcoded path while using
  +<CODE>require().</CODE>
  +
  +</UL>
  +<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 plain CGI scripts, you can just change the code, and rerun
  +the CGI from your browser. Since the script isn't cached in memory, the
  +next time you call it the server starts up a new perl process, which
  +recompiles it from scratch. The effects of any modifications you've applied
  +are immediately present.
  +
  +<P>
  +The situation is different with <CODE>Apache::Registry</CODE>, since the whole idea is to get maximum performance from the server. By
  +default, the server won't spend the time to check whether any included
  +library modules have been changed. It assumes that they weren't, thus
  +saving a few milliseconds to <CODE>stat()</CODE> the source file (multiplied by however many modules/libraries you are <CODE>use()</CODE>-ing and/or <CODE>require()</CODE>-ing in your script.) 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
  +<CODE>use()</CODE> (or <CODE>require()</CODE>) other perl modules (or packages), there is nothing new about it. If
  +however, you are developing a script that includes other modules, the files
  +you <CODE>use()</CODE> or <CODE>require()</CODE> aren't being checked whether they have been modified.
  +
  +<P>
  +Acknowledging this, how do we get our modperl-enabled server to recognize
  +changes in any library modules? Well, there are a couple of techniques:
  +
  +<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>
  +The simplest approach is to restart the server each time you apply some
  +change to your code. See <A HREF="././control.html#Restarting_techniques">Server Restarting techniques</A>.
  +
  +<P>
  +<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<CENTER><H2><A NAME="Using_Apache_StatINC_for_Develo">Using Apache::StatINC for Development Process</A></H2></CENTER>
  +<P>
  +After restarting the server about 100 times, you will be tired and will
  +look for another solutions. Help comes from the
  +<CODE>Apache::StatINC</CODE> module.
  +
  +<P>
  +<CODE>Apache::StatINC</CODE> reloads <CODE>%INC</CODE> files when updated on disk. When Perl pulls a file via require, it stores
  +the filename in the global hash <CODE>%INC</CODE>. The next time Perl tries to require the same file, it sees the file in <CODE>%INC</CODE> and does not reload from disk. This module's handler iterates over <CODE>%INC</CODE> and reloads the file if it has changed on disk.
  +
  +<P>
  +To enable this module just add two lines to <CODE>httpd.conf</CODE> file.
  +
  +<P>
  +<PRE>  PerlModule Apache::StatINC
  +  PerlInitHandler Apache::StatINC
  +</PRE>
  +<P>
  +To be sure it really works, turn on the debug mode on your development box
  +with <CODE>PerlSetVar StatINCDebug On</CODE>. You end up with something like:
  +
  +<P>
  +<PRE>  PerlModule Apache::StatINC
  +  &lt;Location /perl&gt;
  +    SetHandler perl-script
  +    PerlHandler Apache::Registry::handler
  +    Options ExecCGI
  +    PerlSendHeader On
  +    PerlInitHandler Apache::StatINC
  +    PerlSetVar StatINCDebug On
  +  &lt;/Location&gt;
  +</PRE>
  +<P>
  +Beware that 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 (in startup file).
  +
  +<P>
  +Whatever you do in your scripts and modules which are being <CODE>required()</CODE> after the server startup will not have any effect on <CODE>@INC</CODE>. When you do:
  +
  +<P>
  +<PRE>  use lib qw(foo/bar);
  +</PRE>
  +<P>
  +the <CODE>@INC</CODE> is being changed only for the time the code is being parsed and compiled.
  +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://www.nowhere.com/perl-status?inc">http://www.nowhere.com/perl-status?inc</A>
  +and look at the bottom of the page. (I assume you have configured the <A HREF="././config.html#_perl_status_location">/perl-status location</A>.)
  +
  +<P>
  +Also, notice the following caveat: While ``<CODE>.</CODE>'' is in the <CODE>@INC</CODE> -- perl knows to <CODE>require()</CODE> files relative to the script directory. Once the script was parsed - the
  +server doesn't remember the path any more! So you end up with broken entry
  +in <CODE>%INC</CODE> like:
  +
  +<P>
  +<PRE>  $INC{bar.pl} eq &quot;bar.pl&quot;
  +</PRE>
  +<P>
  +If you want Apache::StatINC to reload your script - modify the <CODE>@INC</CODE>
  +at the server startup file! or use a full path in <CODE>require()</CODE> call.
  +
  +<P>
  +<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<CENTER><H2><A NAME="Configuration_Files_Writing_Mo">Configuration Files: Writing, Modifying and Reloading.</A></H2></CENTER>
  +<P>
  +Checking all the modules in <STRONG>%INC</STRONG> every time can add a large overhead to server response times, and you
  +certainly would not want
  +<CODE>Apache::StatINC</CODE> module to be enabled in your production site's configuration. But sometimes
  +you want to have a configuration file to be reloaded when this updated,
  +without restarting the server.
  +
  +<P>
  +This is especially important feature if you have a person that is allowed
  +to modify some of the tool configuration, but it's very undesirable for
  +this person to telnet to the server to restart it, for either this admin
  +person's lack of profeccional skills or because of security reasons -- you
  +don't want to give a root password, unless you have to.
  +
  +<P>
  +<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<CENTER><H3><A NAME="Writing_Configuration_Files">Writing Configuration Files</A></H3></CENTER>
  +<P>
  +Since we are talking about configuration files, I would like to jump on
  +this and show you some good and bad approaches of configuration file
  +writing.
  +
  +<P>
  +If you have a configuration file of just a few variables, it doesn't really
  +matter how you do it. But generally this is not a case. Configuration files
  +tend to grow as a project grows. It's very relevant to the projects that
  +generate HTML files, since the they tend to demand many easily configurable
  +parameters, like headers, tails, colors and so on.
  +
  +<P>
  +So let's start from the basic approach that is being mostly deployed by
  +many CGI scripts writers. This approach is based on having many variables
  +defined in a separate configuration file. For example:
  +
  +<P>
  +<PRE>  $cgi_dir = &quot;/home/httpd/perl&quot;;
  +  $cgi_url = &quot;/perl&quot;;
  +  $docs_dir = &quot;/home/httpd/docs&quot;;
  +  $docs_url = &quot;/&quot;;
  +  $img_dir = &quot;/home/httpd/docs/images&quot;;
  +  $img_url = &quot;/images&quot;;
  +  ... many more config params here ...
  +  $color_hint   = &quot;#777777&quot;;
  +  $color_warn   = &quot;#990066&quot;;
  +  $color_normal = &quot;#000000&quot;;
  +</PRE>
  +<P>
  +Now when we want to use these variables in the mod_perl script we must
  +declare them all with help of <CODE>use vars</CODE> in the script, because of the <CODE>use strict;</CODE> pragma, which demands all the variables to be declared if used in the
  +script. 
  +
  +<P>
  +So we start the script with:
  +
  +<P>
  +<PRE>  use strict;
  +  use vars qw($cgi_dir $cgi_url $docs_dir $docs_url 
  +              ... many more config params here ....
  +              $color_hint  $color_warn $color_normal
  +             );
  +</PRE>
  +<P>
  +This is a nightmare to maintain such a script, especially if not all the
  +features were written yet, so you keep adding and reming the names to the
  +list. But that's not a big deal.
  +
  +<P>
  +Since we want our code clean, we start the configuration file with
  +<CODE>use strict;</CODE> as well, so we have to list the variables here as well. Second list to
  +maintain.
  +
  +<P>
  +The moment you will have many scripts, you will get into a problem of
  +collisions between configuration files, where one of the best solutions is
  +a package declaration, which makes the scripts unique (if you declare
  +unique package names of course).
  +
  +<P>
  +The moment you add a package declaration and think that you are done, you
  +just realize that the nightmare has just begun. The moment you have
  +declared the package, you cannot just <CODE>require()</CODE> the file and
  +use the variables, since they now belong to a different package. So you
  +have ether to modify all you script to use a fully qualified notation like <CODE>$My::Config::cgi_url</CODE> instead of just <CODE>$cgi_url</CODE> or to import the need variables into a script that is going to use them.
  +
  +<P>
  +Since you don't want extra typing to make the variables fully qualified,
  +you would go for importing approach. But your configuration package has to
  +export them first. It means that you have to list all the variables again
  +and now to keep at least three variable lists updated, when you do some
  +changes in the naming of the configuration variables. And that's when you
  +have only one script that uses the configuration file, in a general case
  +you have many of them. So now our example of config file looks like that.
  +
  +<P>
  +<PRE>  package My::Config;
  +  use strict;
  +  
  +  BEGIN {
  +    use Exporter ();
  +  
  +    @My::HTML::ISA       = qw(Exporter);
  +    @My::HTML::EXPORT    = qw();
  +    @My::HTML::EXPORT_OK = qw($cgi_dir $cgi_url $docs_dir $docs_url
  +                              ... many more config params here ....
  +                              $color_hint $color_warn $color_normal);
  +  }
  +  
  +  use vars qw($cgi_dir $cgi_url $docs_dir $docs_url 
  +              ... many more config params here ....
  +              $color_hint  $color_warn $color_normal
  +             );
  +  
  +  $cgi_dir = &quot;/home/httpd/perl&quot;;
  +  $cgi_url = &quot;/perl&quot;;
  +  $docs_dir = &quot;/home/httpd/docs&quot;;
  +  $docs_url = &quot;/&quot;;
  +  $img_dir = &quot;/home/httpd/docs/images&quot;;
  +  $img_url = &quot;/images&quot;;
  +  ... many more config params here ...
  +  $color_hint   = &quot;#777777&quot;;
  +  $color_warn   = &quot;#990066&quot;;
  +  $color_normal = &quot;#000000&quot;;
  +</PRE>
  +<P>
  +And in the code:
  +
  +<P>
  +<PRE>  use strict;
  +  use My::Config qw($cgi_dir $cgi_url $docs_dir $docs_url 
  +                    ... many more config params here ....
  +                    $color_hint  $color_warn $color_normal
  +                   );
  +  use vars       qw($cgi_dir $cgi_url $docs_dir $docs_url 
  +                    ... many more config params here ....
  +                    $color_hint  $color_warn $color_normal
  +                   );
  +</PRE>
  +<P>
  +But as we know this approach is especially bad in a context of mod_perl
  +usage, since exported variables add a memory overhead. The more variables
  +are being exported the more memory you use. Now as usual we rememeber to
  +multiply this overhead by number of the servers we are going to run and we
  +receive a pretty big number, which could be used to run a few more servers
  +instead.
  +
  +<P>
  +As a matter of fact things aren't so horrible, since you can group your
  +variables, and call the groups by special names called tags, which can
  +later be used as arguments to the <CODE>import()</CODE> or
  +<CODE>use().</CODE> You probably familiar with:
  +
  +<P>
  +<PRE>  use CGI qw(:standard :html);
  +</PRE>
  +<P>
  +We can implement it quite easily, with help of <CODE>exporter_tags()</CODE>
  +and <CODE>export_ok_tags()</CODE> from <CODE>Exporter</CODE>. For example:
  +
  +<P>
  +<PRE>  BEGIN {
  +    use Exporter ();
  +    use vars qw( @ISA @EXPORT @EXPORT_OK %EXPORT_TAGS);
  +    @ISA         = qw(Exporter);
  +    @EXPORT      = qw();
  +    @EXPORT_OK   = qw();
  +    
  +    %EXPORT_TAGS = (
  +      vars =&gt; [qw($fname $lname)],
  +      subs =&gt; [qw(reread_conf untaint_path)],
  +    );
  +    Exporter::export_ok_tags('vars');
  +    Exporter::export_ok_tags('subs');
  +  }
  +</PRE>
  +<P>
  +Yes, you export subroutines exactly like variables, since what's actually
  +being exported is a symbol. The definition of these subroutines is not
  +shown here.
  +
  +<P>
  +In your code now you can write:
  +
  +<P>
  +<PRE>  use My::Config qw(:subs :vars);
  +</PRE>
  +<P>
  +Regarding groups of groups. Like the <CODE>:all</CODE> tag from <CODE>CGI.pm</CODE>, which is a group tag of all other groups. It will require a little more
  +magic from your side, but you can always save your time and look up the
  +solution inside the code of <CODE>CGI.pm</CODE>. It's just a matter of a little code to expand all the groups recursively.
  +
  +<P>
  +After going through a pain of maintaining a list of variables in a big
  +project with a huge configuration file (more than 100 variables) and many
  +files actually using them, I have come up with a much simpler solution,
  +using a single hash, and having all the variables kept inside. Now my
  +configuration file looks like:
  +
  +<P>
  +<PRE>  package My::Config;
  +  use strict;
  +  
  +  BEGIN {
  +    use Exporter ();
  +  
  +    @My::Config::ISA       = qw(Exporter);
  +    @My::Config::EXPORT    = qw();
  +    @My::Config::EXPORT_OK = qw(%c);
  +  }
  +  
  +  use vars qw(%c);
  +  
  +  %c = 
  +    (
  +     dir =&gt; {
  +             cgi  =&gt; &quot;/home/httpd/perl&quot;,
  +             docs =&gt; &quot;/home/httpd/docs&quot;,
  +             img  =&gt; &quot;/home/httpd/docs/images&quot;,
  +            },
  +     url =&gt; {
  +             cgi  =&gt; &quot;/perl&quot;,
  +             docs =&gt; &quot;/&quot;,
  +             img  =&gt; &quot;/images&quot;,
  +            },
  +     color =&gt; {
  +               hint   =&gt; &quot;#777777&quot;,
  +               warn   =&gt; &quot;#990066&quot;,
  +               normal =&gt; &quot;#000000&quot;,
  +              },
  +    );
  +</PRE>
  +<P>
  +A good perl style suggests keeping a comma at the end of lists. That's
  +because additional items are tend to be added to the end of the list, and
  +when you keep a last comma in place, you never have to remember to add one
  +when you add a new item.
  +
  +<P>
  +So now the script looks like:
  +
  +<P>
  +<PRE>  use strict;
  +  use My::Config qw(%c);
  +  use vars       qw(%c)
  +  print &quot;Content-type: text/plain\n\n&quot;;
  +  print &quot;My url docs root: $c{url}{docs}\n&quot;;
  +</PRE>
  +<P>
  +Do you see the difference? The whole mess has gone, there is only one
  +variable to worry about.
  +
  +<P>
  +So far so good, but let's make it even better. I would like to get rid of <CODE>Exporter</CODE> stuff at all. I remove all the exporting code so my config file now looks
  +like:
  +
  +<P>
  +<PRE>  package My::Config;
  +  use strict;
  +  use vars qw(%c);
  +  
  +  %c = 
  +    (
  +     dir =&gt; {
  +             cgi  =&gt; &quot;/home/httpd/perl&quot;,
  +             docs =&gt; &quot;/home/httpd/docs&quot;,
  +             img  =&gt; &quot;/home/httpd/docs/images&quot;,
  +            },
  +     url =&gt; {
  +             cgi  =&gt; &quot;/perl&quot;,
  +             docs =&gt; &quot;/&quot;,
  +             img  =&gt; &quot;/images&quot;,
  +            },
  +     color =&gt; {
  +               hint   =&gt; &quot;#777777&quot;,
  +               warn   =&gt; &quot;#990066&quot;,
  +               normal =&gt; &quot;#000000&quot;,
  +              },
  +    );
  +</PRE>
  +<P>
  +And the code
  +
  +<P>
  +<PRE>  use strict;
  +  use My::Config ();
  +  print &quot;Content-type: text/plain\n\n&quot;;
  +  print &quot;My url docs root: $My::Config::c{url}{docs}\n&quot;;
  +</PRE>
  +<P>
  +Since we still want to save us lots of typing, since now we need to use a
  +fully qualified notation like in <CODE>$My::Config::c{url}{docs}</CODE>, let's use a magical perl's aliasing feature. I'll modify the code to be:
  +
  +<P>
  +<PRE>  use strict;
  +  use My::Config ();
  +  use vars qw(%c);
  +  *c = \%My::Config::c;
  +  print &quot;Content-type: text/plain\n\n&quot;;
  +  print &quot;My url docs root: $c{url}{docs}\n&quot;;
  +</PRE>
  +<P>
  +I have alised <CODE>*c</CODE> glob with <CODE>\%My::Config::c</CODE> hash reference. From now on <CODE>%My::Config::c</CODE> and <CODE>%c</CODE> are the same hash. You can read from or modify any of them, both variables
  +are the same one.
  +
  +<P>
  +Just one last little notice. Sometimes you see a lot of redundance in the
  +configuration variables, like:
  +
  +<P>
  +<PRE>  $cgi_dir  = &quot;/home/httpd/perl&quot;;
  +  $docs_dir = &quot;/home/httpd/docs&quot;;
  +  $img_dir  = &quot;/home/httpd/docs/images&quot;;
  +</PRE>
  +<P>
  +Now if you want to move the base path <CODE>&quot;/home/httpd&quot;</CODE> into a new place, it demands lots of typing. Of course the solution is:
  +
  +<P>
  +<PRE>  $base     = &quot;/home/httpd&quot;;
  +  $cgi_dir  = &quot;$base/perl&quot;;
  +  $docs_dir = &quot;$base/docs&quot;;
  +  $img_dir  = &quot;$base/docs/images&quot;;
  +</PRE>
  +<P>
  +But you cannot do the same trick with hash. This wouldn't work:
  +
  +<P>
  +<PRE>  %c =
  +    (
  +     base =&gt; &quot;/home/httpd&quot;,
  +     dir =&gt; {
  +             cgi  =&gt; &quot;$base/perl&quot;,
  +             docs =&gt; &quot;$base/docs&quot;,
  +             img  =&gt; &quot;$base/docs/images&quot;,
  +            },
  +    );
  +</PRE>
  +<P>
  +But nothing stops us from adding additional variables, which are lexically
  +scoped with <CODE>my().</CODE> The following code is correct.
  +
  +<P>
  +<PRE>  my $base = &quot;/home/httpd&quot;;
  +  %c =
  +    (
  +     dir =&gt; {
  +             cgi  =&gt; &quot;$base/perl&quot;,
  +             docs =&gt; &quot;$base/docs&quot;,
  +             img  =&gt; &quot;$base/docs/images&quot;,
  +            },
  +    );
  +</PRE>
  +<P>
  +We have just learned how to make configuration files easily maintainable,
  +and how to save memory by avoiding variables exporting into a script's
  +namespace.
  +
  +<P>
  +<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<CENTER><H3><A NAME="Reloading_Configuration_Files">Reloading Configuration Files</A></H3></CENTER>
  +<P>
  +Now back to the task of dynamically reloading of configuration files.
  +
  +<P>
  +First, lets see a simple case, when we just have to watch after a simple
  +configuration file, like this one. Imagine a script that tells who is patch
  +pumkin of the current perl release.
  +
  +<P>
  +Sidenote: &lt;jargon&gt; A humourous term for the token - the object
  +(notional or real) that gives its possessor (the ``pumpking'' or the
  +``pumpkineer'') exclusive access to something, e.g. applying patches to a
  +master copy of source (for which the pumpkin is called a ``patch
  +pumpkin'').
  +
  +<P>
  +<PRE>  use CGI ();
  +  use strict;
  +  
  +  my $fname = &quot;Larry&quot;;
  +  my $lname = &quot;Wall&quot;;
  +  my $q = new CGI;
  +  
  +  print $q-&gt;header(-type=&gt;'text/html');
  +  print $q-&gt;p(&quot;$fname $lname holds the patch pumpkin
  +               for this perl release.&quot;);
  +</PRE>
  +<P>
  +The script has a hardcoded value for the name. It's very simple: initialize
  +the CGI object, print the proper HTTP header and tell the world who is the
  +current patch pumpkin.
  +
  +<P>
  +When the patch pumkin changes we don't want to modify the script.
  +Therefore, we put the <CODE>$fname</CODE> and <CODE>lname</CODE> variables into a configuration file.
  +
  +<P>
  +<PRE>  $fname = &quot;Gurusamy&quot;;
  +  $lname = &quot;Sarathy&quot;;
  +  1;
  +</PRE>
  +<P>
  +Please notice that there is no package declaration in the above file, so
  +the code will be evaluated in the caller's package or in the
  +<CODE>main::</CODE> package if none was declared. It means that variables
  +<CODE>$fname</CODE> and <CODE>$lname</CODE> will override (or initialize if they weren't yet) the variables with the
  +same names in the caller's namespace. This works for global variables only
  +-- you cannot update lexically defined (with <CODE>my())</CODE> variables
  +by this technique.
  +
  +<P>
  +You have started the server and everything is working properly. After a
  +while you decide to modify the configuration. How do you let your running
  +know, that the configuration was modified, without restarting the server,
  +remember we are in production and server restarting can be quite expensive
  +for us. ? One of the simplest solutions is to poll the file's modification
  +time by calling <CODE>stat()</CODE> before the script starts to do a real
  +work, and if we see that the file was updated, we force a reconfiguration
  +of the variables located in this file. We will call the function that
  +reloads the configuration <CODE>reread_conf()</CODE> and it accepts a
  +single argument, which is a relative path to the configuration file.
  +
  +<P>
  +If your CGI script is being invoked under <CODE>Apache::Registry</CODE> handler, you can put the configuration file in the same directory as a
  +script or below it and path a relative path to the file, since
  +<CODE>Apache::Registry</CODE> calls a <CODE>chdir()</CODE> to the script's directory before it starts the
  +script's execution. Otherwise you would have to make sure that the file
  +will be found. <CODE>do()</CODE> does search the <CODE>@INC</CODE>
  +libraries.
  +
  +<P>
  +<PRE>  use vars qw(%MODIFIED);
  +  sub reread_conf{
  +    my $file = shift;
  +    return unless $file;
  +    return unless -e $file and -r _;
  +    unless ($MODIFIED{$file} and $MODIFIED{$file} == -M _){
  +      my $return;
  +      unless ($return = do $file) {
  +        warn &quot;couldn't parse $file: $@&quot; if $@;
  +        warn &quot;couldn't do $file: $!&quot;    unless defined $return;
  +        warn &quot;couldn't run $file&quot;       unless $return;
  +      }
  +      $MODIFIED{$file} =  -M _; # Update the MODIFICATION times
  +    }
  +  } # end of reread_conf
  +</PRE>
  +<P>
  +We use <CODE>do()</CODE> to reload the code in this file and not
  +<CODE>require()</CODE> because, <CODE>do()</CODE> reloads the file
  +unconditionally, while <CODE>require()</CODE> will not load the file if it
  +was already loaded in one of the previous requests, since there will be an
  +entry in the <CODE>%INC</CODE> where the key is the name of the file and the value the path to it. That's
  +how Perl keeps track of loaded files and saves overhead of reloading when
  +it has to load the same file again. You generally doesn't notice that with
  +plain perl scripts, but in mod_perl it's being used all the time (since the
  +same script is being reloaded all the time, and all the
  +<CODE>require()'s</CODE> files are already loaded after a first request for
  +each process.
  +
  +<P>
  +Nevertheless, <CODE>do()</CODE> keeps track of the current filename for
  +error messages, searches the <CODE>@INC</CODE> libraries, updates the <CODE>%INC</CODE> if the file is found.
  +
  +<P>
  +To explain all the possible warnings the script emits if something went
  +wrong with operation, it's just for a matter of completeness. Generally you
  +would do all these checks. If <CODE>do()</CODE> cannot read the file, it returns <CODE>undef</CODE> and sets <CODE>$!</CODE> to the error. If <CODE>do()</CODE> can read the file but cannot compile it, it returns <CODE>undef</CODE> and sets an error message in <CODE>$@</CODE>. If the file is successfully compiled, <CODE>do()</CODE>
  +returns the value of the last expression evaluated.
  +
  +<P>
  +Also the configuration file can be broken if someone has incorrectly
  +modified it. We don't want the service to go broken, because of that. We
  +just trap the possible failure to <CODE>do()</CODE> the file and ignore the
  +changes, by the resetting the modification time. It might be a good idea to
  +send an email to system administrator about the problem.
  +
  +<P>
  +Notice however, that since <CODE>do()</CODE> updates the <CODE>%INC</CODE> like <CODE>require()</CODE> does, if you are using <CODE>Apache::StatINC</CODE>, it will attempt to reload this file before the <CODE>reread_conf()</CODE>
  +call, so if it the file wouldn't compile the request would be aborted. This
  +shouldn't be a problem since <CODE>Apache::StatINC</CODE> shouldn't be used in production (because it slows things down by
  +<CODE>stat()'ing</CODE> all the files listed in <CODE>%INC</CODE>).
  +
  +<P>
  +Note that we assume that the entire purpose of this function is to reload
  +the configuration if that was changed, that's why there is no possible
  +failure for this function. If something goes wrong we just return. This
  +approach would be incorrect if you are going to initialize the variables
  +thru this method on the first invocation of the script. If you do, you will
  +want to replace each occurence of <CODE>return()</CODE> and
  +<CODE>warn()</CODE> with <CODE>die().</CODE>
  +
  +<P>
  +I used the above approach when I've had a huge configuration file that was
  +loaded only once at the server startup, and another little configuration
  +file that included only a few variables that could be updated by hand or
  +through the web interface, and those variables were duplicates in the main
  +config file.
  +
  +<P>
  +So if webmaster breaks the syntax in this dynamic file while updating it by
  +hand, it wouldn't affect the main configuration file (which was
  +write-protected) and so the proper executing of the programs. Soon we will
  +see a simple web interface which allows to modify the configuration file
  +without actually breaking it.
  +
  +<P>
  +A sample script using the presented subroutine would be:
  +
  +<P>
  +<PRE>  use vars qw(%MODIFIED $fname $lname);
  +  use CGI ();
  +  use strict;
  +  
  +  my $q = new CGI;
  +  print $q-&gt;header(-type=&gt;'text/plain');
  +  my $config_file = &quot;./config.pl&quot;;
  +  reread_conf($config_file);
  +  print $q-&gt;p(&quot;$fname $lname holds the patch pumpkin
  +               for this perl release.&quot;);
  +  
  +  sub reread_conf{
  +    my $file = shift;
  +    return unless $file;
  +    return unless -e $file and -r _;
  +    unless ($MODIFIED{$file} and $MODIFIED{$file} == -M _){
  +      my $return;
  +      unless ($return = do $file) {
  +        warn &quot;couldn't parse $file: $@&quot; if $@;
  +        warn &quot;couldn't do $file: $!&quot;    unless defined $return;
  +        warn &quot;couldn't run $file&quot;       unless $return;
  +      }
  +      $MODIFIED{$file} =  -M _; # Update the MODIFICATION times
  +    }
  +  } # end of reread_conf
  +</PRE>
  +<P>
  +Remember that you should be using <CODE>(stat $file)[9]</CODE> instead of <CODE>-M
  +$file</CODE> if you are modifying the <CODE>$^M</CODE> variable. In some of my scripts, I reset <CODE>$^M</CODE> to the time of the script invocation with
  +<CODE>&quot;$^M = time()&quot;</CODE>, so I can perform <CODE>-M</CODE> and alike (<CODE>-A</CODE>, <CODE>-C</CODE>) file status testings relative to the script invocation time and not the
  +time the process was started.
  +
  +<P>
  +If your configuration file is more sophisticated and it declares a package
  +and exports variables, the above code will work just as well. Even if you
  +think that you will have to re-import() variables, they are just there and
  +when do recompiles the code, the originally imported variables get updates
  +with the values from the reloaded code.
  +
  +<P>
  +<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<CENTER><H3><A NAME="Dynamically_updating_configurati">Dynamically updating configuration files</A></H3></CENTER>
  +<P>
  +The CGI script below allows a system administrator, to dynamically update
  +configuration file through the web interface. Combining this with the code
  +we have just showed to reload the modified files, you get a complete suite
  +of dynamically reconfigurable system which doesn't require server restart
  +and can be performed from any machine having just a web interface (a simple
  +browser connected to the Internet).
  +
  +<P>
  +Let's say you have a configuration file like:
  +
  +<P>
  +<PRE>  package MainConfig;
  +  
  +  use strict;
  +  use vars qw(%c);
  +  
  +  %c = (
  +        name     =&gt; &quot;Larry Wall&quot;,
  +        release  =&gt; &quot;5.000&quot;,
  +        comments =&gt; &quot;Adding more ways to do the same thing :)&quot;,
  +  
  +        other    =&gt; &quot;More config values&quot;,
  +  
  +        hash     =&gt; { foo  =&gt; &quot;bar&quot;,
  +                    fooo =&gt; &quot;barr&quot;,
  +                  },
  +  
  +        array    =&gt; [qw( a b c)],
  +  
  +       );
  +</PRE>
  +<P>
  +You want to make the variables <CODE>name</CODE>, <CODE>release</CODE> and <CODE>comments</CODE>
  +dynamically configurable. Which means that you want to have a web interface
  +with input form that allows to modify these variables. Once modified you
  +want to update the configuration file and propogate the changes to all the
  +currently running processes. Quite a simple task.
  +
  +<P>
  +Let's see the main stages of this algorithm. Create a form with preset
  +current values of the variables. Let the administrator to modify and submit
  +the changes. Validate that the submitted information is correctly formatted
  +(numeric fields should carry numbers, literal - words and etc). Update the
  +configuration file. Update the modified value in the memory of the current
  +process. Present the form as before but with updated fields if any.
  +
  +<P>
  +The only part that seems to be complicated to implement is a configuration
  +file update. For a few reasons. If updating the file breaks it - the whole
  +service wouldn't work. If the file is very big and includes comments and
  +complex data structures, parsing the file can be quite a challenge.
  +
  +<P>
  +So let's simplify the task. We wouldn't touch the original configuration
  +file, if all we want is to updated a few variables, why don't we create a
  +little configuration file with just a variables that can be modified
  +throught the web interface and overwrite it each time there is something to
  +be changed. This way we don't have to parse the file, before updating it.
  +And if the main configuration file is going to be changed, we don't care
  +about it -- since we aren't dependent on it any more.
  +
  +<P>
  +Moreover, we will have these dynamically updated variables duplicated, they
  +will show up in both places - in the main file and in the dynamic file. We
  +do it, to simplify the maintainance. When a new release is being installed
  +the dynamic configuration file shouldn't exist at all. It'll be created
  +only after a first update. The only change it requires to the main code is
  +to add a snippet of code to load this file if it exists and was changed as
  +we just saw.
  +
  +<P>
  +This additional code must be executed after the main configuration file is
  +being loaded. That way the updated variables would override the default
  +values in the main file.
  +
  +<P>
  +META: extend on the comments:
  +
  +<P>
  +<PRE>  # remember to run this code under taint mode
  +  
  +  use strict;
  +  use vars qw($q %c $dynamic_config_file %vars_to_change %validation_rules);
  +  
  +  use CGI ();
  +  
  +  use lib qw(.);
  +  use MainConfig ();
  +  *c = \%MainConfig::c;
  +  
  +  $dynamic_config_file = &quot;./config.pl&quot;;
  +  
  +  # load the dynamic conf file if exists, and override the default
  +  # values from the main config file
  +  do $dynamic_config_file if -e $dynamic_config_file and -r _;
  +  
  +  # fields that can be changed and their titles
  +  %vars_to_change =
  +    (
  +     'name'     =&gt; &quot;Patch Pumkin's Name&quot;,
  +     'release'  =&gt; &quot;Current Perl Release&quot;,
  +     'comments' =&gt; &quot;Release Comments&quot;,
  +    );
  +  
  +  %validation_rules =
  +    (
  +     'name'     =&gt; sub { $_[0] =~ /^[\w\s\.]+$/;   },
  +     'release'  =&gt; sub { $_[0] =~ /^\d+\.[\d_]+$/; },
  +     'comments' =&gt; sub { 1;                        },
  +    );
  +  
  +  $q = new CGI;
  +  print $q-&gt;header(-type=&gt;'text/html'),
  +    $q-&gt;start_html();
  +  
  +  my %updates = ();
  +  
  +  # We always rewrite the dynamic config file, so we want all the
  +  # vars to be passed but to save the time we will only do checking
  +  # of vars that that was changed the rest will be retrieved from
  +  # the 'prev_foo' values
  +  foreach (keys %vars_to_change) {
  +    # copy var so we can modify it
  +    my $new_val = $q-&gt;param($_) || '';
  +  
  +    # strip a possible ^M char (DOS/WIN)
  +    $new_val =~ s/\cM//g;
  +  
  +    # push to hash if was changed
  +    $updates{$_} = $new_val
  +      if defined $q-&gt;param(&quot;prev_&quot;.$_) and $new_val ne $q-&gt;param(&quot;prev_&quot;.$_);
  +  }
  +  
  +  # Notice that we cannot trust the previous values of the variables
  +  # since they were presented to user as hidden form variables, and
  +  # of course user can mangle those. In our case we don't care since
  +  # it cannot make any damage, since as you will see in a minute we
  +  # verify each variable by the rules we define.
  +  
  +  # Process if there is something to process. Will be not called if
  +  # it's invoked a first time to diplay the form or when the form
  +  # was submitted but the values weren't modified (we know that by
  +  # comparing with the previous values of the variables, which are
  +  # the hidden fields in the form)
  +  
  +  # process and update the values if valid
  +  process_change_config(%updates) if %updates;
  +  
  +  # print the update form
  +  conf_modification_form();
  +  
  +  # update the config file but first validate that the values are correct ones
  +  #########################
  +  sub process_change_config{
  +    my %updates = @_; # dereference
  +  
  +      # we will list here all the malformatted vars
  +    my %malformatted = ();
  +  
  +    print $q-&gt;b(&quot;Trying to validate these values&lt;BR&gt;&quot;);
  +    foreach (keys %updates) {
  +      print &quot;&lt;DT&gt;&lt;B&gt;$_&lt;/B&gt; =&gt; &lt;PRE&gt;$updates{$_}&lt;/PRE&gt;&quot;;
  +  
  +      # now we have to handle each var to be changed very very carefully
  +      # since this file goes immediately into production!
  +      $malformatted{$_} = delete $updates{$_}
  +        unless $validation_rules{$_}-&gt;($updates{$_});
  +  
  +    } # end of foreach my $var (keys %updates)
  +  
  +    # print warnings if there are any invalid changes
  +    print $q-&gt;hr,
  +      $q-&gt;p($q-&gt;b(qq{Warning! These variables were attempted to be
  +                   changed, but found malformed, thus the original
  +                   value will be preserved.})
  +         ),
  +      join(&quot;,&lt;BR&gt;&quot;,
  +         map { $q-&gt;b($vars_to_change{$_}) . &quot; : $malformatted{$_}\n&quot;
  +             } keys %malformatted)
  +        if %malformatted;
  +  
  +    # Now complete the vars that weren't changed from the
  +    # $q-&gt;param('prev_var') values
  +    map { $updates{$_} = $q-&gt;param('prev_'.$_) unless exists $updates{$_}
  +        } keys %vars_to_change;
  +  
  +    # Now we have all the data that should be written into dynamic
  +    # config file
  +  
  +      # escape single quotes &quot;'&quot; while creating a file
  +    my $content = join &quot;\n&quot;,
  +      map { $updates{$_} =~ s/(['\\])/\\$1/g;
  +          '$c{' . $_ . &quot;}  =  '&quot; . $updates{$_} . &quot;';\n&quot;
  +        } keys %updates;
  +  
  +      # now add '1;' to make require() happy
  +    $content .= &quot;\n1;&quot;;
  +  
  +      # keep the dummy result in $r so it'll not complain
  +    eval {my $res = $content};
  +    if ($@) {
  +      print qq{Warning! Something went wrong with config file
  +             generation!&lt;P&gt; The error was : &lt;BR&gt;&lt;PRE&gt;$@&lt;/PRE&gt;};
  +      return;
  +    }
  +  
  +    print $q-&gt;hr;
  +  
  +      # overwrite the dynamic config file
  +    use Symbol ();
  +    my $fh = Symbol::gensym();
  +    open $fh, &quot;&gt;$dynamic_config_file.bak&quot;
  +      or die &quot;Can't open the $dynamic_config_file.bak for writing :$! \n&quot;;
  +    flock $fh,2; # exclusive lock
  +    seek $fh,0,2;       # rewind to the start
  +    truncate $fh, 0; # the file might shrink!
  +       print $fh $content;
  +    close $fh;
  +  
  +      # OK, now we make a real file
  +    rename &quot;$dynamic_config_file.bak&quot;,$dynamic_config_file;
  +  
  +      # rerun it to update variables in the current process! Note that
  +      # it wouldn't update the variables in other processes. A special
  +      # code that watches the timestamps on the config file will do this
  +      # work for each process. Since the next invocation will update the
  +      # configuration anyway, why do we need to load it here? The reason
  +      # is simple, since we are going to fill form's input fields, with
  +      # the updated data.
  +    do $dynamic_config_file;
  +  
  +  } # end sub process_change_config
  +  
  +  ##########################
  +  sub conf_modification_form{
  +  
  +    print $q-&gt;center($q-&gt;h3(&quot;Update Form&quot;));
  +  
  +    print $q-&gt;hr,
  +      $q-&gt;p(qq{This form allows you to dynamically update the current
  +             configuration. You don\'t need to restart the server in
  +             order for changes to take an effect}
  +           );
  +  
  +      # set the previous settings into the form's hidden fields, so we
  +      # know whether we have to do some changes or not
  +    map {$q-&gt;param(&quot;prev_$_&quot;,$c{$_}) } keys %vars_to_change;
  +  
  +      # raws for the table, go into the form
  +    my @configs = ();
  +  
  +      # prepare one textfield entries
  +    push @configs,
  +      map {
  +        $q-&gt;td(
  +             $q-&gt;b(&quot;$vars_to_change{$_}:&quot;),
  +            ),
  +        $q-&gt;td(
  +             $q-&gt;textfield(-name      =&gt; $_,
  +                           -default   =&gt; $c{$_},
  +                           -override  =&gt; 1,
  +                           -size      =&gt; 20,
  +                           -maxlength =&gt; 50,
  +                          )
  +            ),
  +          } qw(name release);
  +  
  +      # prepare multiline textarea entries
  +    push @configs,
  +      map {
  +        $q-&gt;td(
  +             $q-&gt;b(&quot;$vars_to_change{$_}:&quot;),
  +            ),
  +        $q-&gt;td(
  +             $q-&gt;textarea(-name    =&gt; $_,
  +                          -default =&gt; $c{$_},
  +                          -override  =&gt; 1,
  +                          -rows    =&gt; 10,
  +                          -columns =&gt; 50,
  +                          -wrap    =&gt; &quot;HARD&quot;,
  +                          )
  +            ),
  +          } qw(comments);
  +  
  +    print $q-&gt;startform('POST',$q-&gt;url),&quot;\n&quot;,
  +        $q-&gt;center($q-&gt;table(map {$q-&gt;Tr($_),&quot;\n&quot;,} @configs),
  +                   $q-&gt;submit('','Update!'),&quot;\n&quot;,
  +                  ),
  +        map ({$q-&gt;hidden(&quot;prev_&quot;.$_, $q-&gt;param(&quot;prev_&quot;.$_)).&quot;\n&quot; }
  +             keys %vars_to_change), # hidden previous values
  +        $q-&gt;br,&quot;\n&quot;,
  +        $q-&gt;endform,&quot;\n&quot;,
  +        $q-&gt;hr,&quot;\n&quot;,
  +        $q-&gt;end_html;
  +  
  +  } # end sub conf_modification_form
  +</PRE>
  +<P>
  +Once updated the script generates a file like:
  +
  +<P>
  +<PRE>  $c{release}  =  '5.6';
  +  
  +  $c{name}  =  'Gurusamy Sarathy';
  +  
  +  $c{comments}  =  'Perl rules the world!';
  +  
  +  1;
  +</PRE>
  +<P>
  +<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<CENTER><H2><A NAME="Reloading_handlers">Reloading handlers</A></H2></CENTER>
  +<P>
  +If you want to reload perlhandler on each invocation, the following trick
  +will do it:
  +
  +<P>
  +<PRE>  PerlHandler &quot;sub { do 'MyTest.pm'; MyTest::handler(shift) }&quot;
  +</PRE>
  +<P>
  +<CODE>do()</CODE> will reload <CODE>MyTest.pm</CODE> every request.
  +
  +<P>
  +<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<CENTER><H1><A NAME="Name_collisions_with_Modules_and">Name collisions with Modules and libs</A></H1></CENTER>
  +<P>
  +To make things clear before we go into details: each child process has its
  +own <CODE>%INC</CODE> hash which is used to store information about its compiled modules. The
  +keys of the hash are the names of the modules or parameters passed to <CODE>require()</CODE> (<CODE>use()</CODE>). The values are the full or relative paths to these modules/files. Let's
  +say we have
  +<CODE>my-lib.pl</CODE> and <CODE>MyModule.pm</CODE> both located at <CODE>/home/httpd/perl/my/</CODE>.
  +
  +<UL>
  +<P><LI><STRONG><A NAME="item__home_httpd_perl_my_is_in_the_">/home/httpd/perl/my/ is in the @INC at the server startup.</A></STRONG>
  +<P>
   <PRE>  require &quot;my-lib.pl&quot;;
     use MyModule.pm;
     print $INC{&quot;my-lib.pl&quot;},&quot;\n&quot;;
  @@ -1740,9 +3283,7 @@
   <PRE>  my-lib.pl
     MyModule.pm
   </PRE>
  -<P>
  -* <CODE>/home/httpd/perl/my/</CODE> isn't in the <CODE>@INC</CODE> path at the server startup.
  -
  +<P><DT><STRONG><A NAME="item__home_httpd_perl_my_">/home/httpd/perl/my/ isn't in the @INC path at the server startup.</A></STRONG><DD>
   <P>
   <PRE>  require &quot;my-lib.pl&quot;;
     use MyModule.pm;
  @@ -1750,7 +3291,7 @@
     print $INC{&quot;MyModule.pm&quot;},&quot;\n&quot;;
   </PRE>
   <P>
  -Wouldn't work, since perl cannot find the modules.
  +wouldn't work, since perl cannot find the modules.
   
   <P>
   Adding <CODE>use lib</CODE>:
  @@ -1769,8 +3310,9 @@
   <PRE>  my-lib.pl
     MyModule.pm
   </PRE>
  +</UL>
   <P>
  -I'm talking about single server child below!
  +I'm talking about single child below!
   
   <P>
   Let's look at 3 faulty script's name space related scenarios:
  @@ -2002,7 +3544,7 @@
   
   <P>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<CENTER><H2><A NAME="More_package_name_related_issues">More package name related issues</A></H2></CENTER>
  +<CENTER><H1><A NAME="More_package_name_related_issues">More package name related issues</A></H1></CENTER>
   <P>
   If you have the following:
   
  @@ -2017,26 +3559,82 @@
   
   <P>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<CENTER><H2><A NAME="_END_or_DATA_tokens">__END__ or __DATA__ tokens</A></H2></CENTER>
  +<CENTER><H1><A NAME="_END_or_DATA_tokens">__END__ or __DATA__ tokens</A></H1></CENTER>
  +<P>
  +<CODE>Apache::Registry</CODE> scripts cannot contain <CODE>__END__</CODE> or <CODE>__DATA__</CODE>
  +tokens.
  +
  +<P>
  +Why? Because <CODE>Apache::Registry</CODE> scripts are being wrapped into a subroutine called <CODE>handler</CODE>, like the script at URI <CODE>/perl/test.pl</CODE>:
  +
  +<P>
  +<PRE>  print &quot;Content-type: text/plain\n\n&quot;;
  +  print &quot;Hi&quot;;
  +</PRE>
  +<P>
  +When the script is being executed under <CODE>Apache::Registry</CODE> handler, it actually becomes:
  +
   <P>
  -<CODE>Apache::Registry</CODE> scripts cannot contain __END__ or __DATA__ tokens.
  +<PRE>  package Apache::ROOT::perl::test_2epl;
  +  use Apache qw(exit);
  +  sub handler {
  +    print &quot;Content-type: text/plain\n\n&quot;;
  +    print &quot;Hi&quot;;
  +  }
  +</PRE>
  +<P>
  +So if you happen to put an <CODE>__END__</CODE> tag, like:
  +
  +<P>
  +<PRE>  print &quot;Content-type: text/plain\n\n&quot;;
  +  print &quot;Hi&quot;;
  +  __END__
  +  Some text that wouldn't be normally executed
  +</PRE>
  +<P>
  +it will be turned into:
  +
  +<P>
  +<PRE>  package Apache::ROOT::perl::test_2epl;
  +  use Apache qw(exit);
  +  sub handler {
  +    print &quot;Content-type: text/plain\n\n&quot;;
  +    print &quot;Hi&quot;;
  +    __END__
  +    Some text that wouldn't be normally executed
  +  }
  +</PRE>
  +<P>
  +and you try to execute this script, you will receive the following warning:
  +
  +<P>
  +<PRE>  Missing right bracket at q line 4, at end of line
  +</PRE>
  +<P>
  +And that's clear, Perl cuts everything after <CODE>__END__</CODE> tag. The same thing applies to <CODE>__DATA__</CODE> tag.
  +
  +<P>
  +Also, rememeber that whatever applies to <CODE>Apache::Registry</CODE> scripts, in most cases applies to <CODE>Apache::PerlRun</CODE> scripts.
   
   <P>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<CENTER><H2><A NAME="Output_from_system_calls">Output from system calls</A></H2></CENTER>
  +<CENTER><H1><A NAME="Output_from_system_calls">Output from system calls</A></H1></CENTER>
   <P>
   Output of <CODE>system()</CODE>, <CODE>exec()</CODE>, and <CODE>open(PIPE,&quot;|program&quot;)</CODE> calls will not be sent to the browser unless your Perl was configured with
   <CODE>sfio</CODE>.
   
   <P>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<CENTER><H2><A NAME="Using_format_">Using format()</A></H2></CENTER>
  +<CENTER><H1><A NAME="Using_format_and_write_">Using format() and write()</A></H1></CENTER>
   <P>
  -Currently possible only if you have perl compiled with <CODE>sfio</CODE>.
  +The Perl <CODE>tie()'d</CODE> filehandle interface is not complete,
  +<CODE>format()</CODE> / <CODE>write()</CODE> are ones of the missing
  +pieces. If you configure Perl with
  +<CODE>sfio</CODE>, <CODE>write()</CODE> and <CODE>format()</CODE> should work just fine.
   
   <P>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<CENTER><H2><A NAME="Using_exit_">Using exit()</A></H2></CENTER>
  +<CENTER><H1><A NAME="Using_exit_">Using exit()</A></H1></CENTER>
   <P>
   Perl's <STRONG>exit()</STRONG> built-in function cannot be used in mod_perl scripts. Calling it causes the
   server child to exit (which makes the whole idea of using mod_perl
  @@ -2095,13 +3693,13 @@
   </PRE>
   <P>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<CENTER><H2><A NAME="Running_from_shell">Running from shell</A></H2></CENTER>
  +<CENTER><H1><A NAME="Running_from_shell">Running from shell</A></H1></CENTER>
   <P>
   Your scripts <STRONG>will not</STRONG> run from the command line (yet) unless you use <CODE>CGI::Switch</CODE> or <CODE>CGI.pm</CODE> and perl 5.004+ and do not make any direct calls to <CODE>Apache-&amp;gt;methods</CODE>.
   
   <P>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<CENTER><H2><A NAME="I_O_is_different">I/O is different</A></H2></CENTER>
  +<CENTER><H1><A NAME="I_O_is_different">I/O is different</A></H1></CENTER>
   <P>
   If you are using Perl 5.004 or better, most CGI scripts can run under
   mod_perl untouched. If you're using 5.003, Perl's built-in <CODE>read()</CODE>
  @@ -2109,30 +3707,257 @@
   <CODE>print()</CODE>.
   
   <P>
  +<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<CENTER><H1><A NAME="Special_Perl_Variables">Special Perl Variables</A></H1></CENTER>
  +<P>
  +A special Perl variables like <CODE>$|</CODE> (buffering), <CODE>$^T</CODE> (time), <CODE>$^W</CODE>
  +(warnings), <CODE>$/</CODE> (input record separator), <CODE>$\</CODE> (output record separator) and many more are all global variables. It means
  +that you cannot localize them with <CODE>my().</CODE> Only
  +<CODE>local()</CODE> is permitted to do that. Since the child server
  +doesn't quit - if in one of your scripts you modify the global varible
  +it'll be changed for the rest of the process' life and would affect all the
  +scripts that will be executed under the same process.
  +
  +<P>
  +Remembering this you should never write a code like this. We will exercise
  +the input record separator variable. If you undefine this variable, a
  +diamond operator will suck the whole file at once.
  +
  +<P>
  +<PRE>  $/ = undef; 
  +  open IN, &quot;file&quot; ....
  +    # slurp it all inside a variable
  +  $all_the_file = &lt;IN&gt;;
  +</PRE>
  +<P>
  +The proper way is to have a <CODE>local()</CODE> keyword before the special
  +variable is being changed, like:
  +
  +<P>
  +<PRE>  local $/ = undef; 
  +  open IN, &quot;file&quot; ....
  +    # slurp it all inside a variable
  +  $all_the_file = &lt;IN&gt;;
  +</PRE>
  +<P>
  +But there is a little catch. <CODE>local()</CODE> will propogate the
  +changed value to any of the code below it and would be in effect untill the
  +script will be finished, if not modified in some other place.
  +
  +<P>
  +A cleaner approach is to embrace the whole code that is being effected by
  +the modificated variable in to a block, like:
  +
  +<P>
  +<PRE>  {
  +    $/ = undef; 
  +    open IN, &quot;file&quot; ....
  +      # slurp it all inside a variable
  +    $all_the_file = &lt;IN&gt;;
  +  }
  +</PRE>
  +<P>
  +That way when Perl leaves the block, it restores the original value of the <CODE>$/</CODE> variable. So you should worry about this variable anywhere else in scope of
  +your program.
  +
  +<P>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<CENTER><H2><A NAME="HTTP_MIME_Headers_PerlSendHea">HTTP + MIME Headers (PerlSendHeader)</A></H2></CENTER>
  +<CENTER><H1><A NAME="Generating_correct_HTTP_Headers">Generating correct HTTP Headers</A></H1></CENTER>
  +<P>
  +When writing your own handlers with Perl API the proper way to send the
  +HTTP Header is to set the header first and then to send it. Like:
  +
  +<P>
  +<PRE>  $r-&gt;content_type('text/html');
  +  $r-&gt;send_http_header;
  +  return OK if $r-&gt;header_only;
  +</PRE>
  +<P>
  +If the client issues a HTTP <CODE>HEAD</CODE> request rather than the usual
  +<CODE>GET</CODE>, to be compilent with the HTTP protocol we better will not send the
  +document body, but the the HTTP header only. When Apache receives a HEAD
  +request, it sets <EM>header_only()</EM> to true. If we see that this has happened, we return from the handler
  +immediately with an OK status code.
  +
  +<P>
  +Generally, you don't need the explicit content type setting, since Apache
  +does it for you, by looking up the MIME type of the request by matching the
  +extension of the URI in the MIME tables (from the
  +<CODE>mime.types</CODE> file). So if the request URI is <CODE>/welcome.html</CODE>, the
  +<CODE>text/html</CODE> content-type will be picked. However for CGI scripts or URIs that cannot be
  +mapped by a known extension, you should set the appropriate type by using <CODE>content_type()</CODE> method.
  +
  +<P>
  +The situation is a little bit different with <CODE>Apache::Registry</CODE> and alike handlers. It means that if you take a basic CGI script like:
  +
  +<P>
  +<PRE>  print &quot;Content-type: text/plain\n\n&quot;;
  +  print &quot;Hello world&quot;;
  +</PRE>
   <P>
  -By default, mod_perl does not send any headers by itself, however, you may
  -wish to change this (in <CODE>httpd.conf</CODE>):
  +it wouldn't work, because the HTTP header will be not sent. By default,
  +mod_perl does not send any headers by itself, however, you may wish to
  +change this by adding:
   
   <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, <CODE>PerlSendHeader</CODE> will not send the MIME type and a terminating newline. Your script must
  -send that itself, e.g.:
  +in <CODE>&lt;Location</CODE>&gt; part of your configuration. Now the response line and common headers
  +will be sent as they are by mod_cgi. And, just as with mod_cgi, <CODE>PerlSendHeader</CODE> will not send the MIME type and a terminating double newline. Your script
  +must send that itself, e.g.:
   
   <P>
   <PRE>  print &quot;Content-type: text/html\r\n\r\n&quot;;
   </PRE>
  +<P>
  +Note, that the book always uses ``\n\n'' and not ``\r\n\r\n''. The latter
  +is a way to send new lines as defined in HTTP standards, but as of this
  +moment all the browsers accept the former format as well. To follow
  +strictly the HTTP protocol you must you the ``\r\n'' format.
  +
  +<P>
  +The <STRONG>PerlSendHeader On</STRONG> directive tells mod_perl to intercept anything that looks like a header
  +line (such as <CODE>Content-Type:
  +text/plain</CODE>) and automatically turn it into a correctly formatted HTTP/1.0 header, the
  +same way it happens with CGI scripts running under mod_cgi. This allows you
  +to keep your CGI scripts unmodified.
  +
  +<P>
  +There is <CODE>$ENV{PERL_SEND_HEADER}</CODE> which tells whether
  +<CODE>PerlSendHeader</CODE> is <CODE>On</CODE> or <CODE>Off</CODE>. You can use it in your module like:
  +
  +<P>
  +<PRE> if($ENV{PERL_SEND_HEADER}) {
  +     print &quot;Content-type: text/html\n\n&quot;;
  + }
  + else {
  +     my $r = Apache-&gt;request;
  +     $r-&gt;content_type('text/html');
  +     $r-&gt;send_http_header;
  + }
  +</PRE>
  +<P>
  +If you use <EM>CGI.pm</EM>'s <EM>header()</EM> function to generate HTTP headers, you do not need to activate this
  +directive because <EM>CGI.pm</EM> detects
  +<EM>mod_perl</EM> and calls <EM>send_http_header()</EM> for you. However, it does not hurt to use this directive anyway.
  +
  +<P>
  +There is no free lunch -- you get the mod_cgi behavior on cost of little
  +but still overhead of parsing the text that is being sent, and mod_perl
  +makes the assumption that individual headers are not split across print
  +statements.
  +
  +<P>
  +The <CODE>Apache::print()</CODE> routine has to gather up the headers that your script outputs, in order to
  +pass them to <CODE>$r-&amp;gt;send_http_header</CODE>. This happens in <CODE>src/modules/perl/Apache.xs</CODE> (<CODE>print</CODE>) and
  +<CODE>Apache/Apache.pm</CODE> (<CODE>send_cgi_header</CODE>). There is a shortcut in there, namely the assumption that each print
  +statement contains one or more complete headers. If for example you used to
  +generate a
  +<CODE>Set-Cookie</CODE> header by multiply <CODE>print()</CODE> statements, like:
  +
  +<P>
  +<PRE>   print &quot;Content-type: text/html\n&quot;;
  +   print &quot;Set-Cookie: iscookietext\; &quot;;
  +   print &quot;expires=Wednesday, 09-Nov-1999 00:00:00 GMT\; &quot;;
  +   print &quot;path=\/\; &quot;;
  +   print &quot;domain=\.mmyserver.com\; &quot;;
  +   print &quot;\n\n&quot;;
  +   print &quot;hello&quot;;
  +</PRE>
  +<P>
  +your generated <CODE>Set-Cookie</CODE> header is split over a number of print statements and gets lost. The above
  +example wouldn't work! Try this instead:
  +
  +<P>
  +<PRE>   print &quot;Content-type: text/html\n&quot;;
  +   my $cookie = &quot;Set-Cookie: iscookietext\; &quot;;
  +   $cookie .= &quot;expires=Wednesday, 09-Nov-1999 00:00:00 GMT\; &quot;;
  +   $cookie .= &quot;path=\/\; &quot;;
  +   $cookie .= &quot;domain=\.mmyserver.com\; &quot;;
  +   print $cookie;
  +   print &quot;\n\n&quot;;
  +   print &quot;hello&quot;;
  +</PRE>
  +<P>
  +Sometimes when you call a script you see an ugly <CODE>&quot;Content-Type:
  +text/html&quot;</CODE> displayed at the top of the page, and of course the HTML code becomes
  +broken. As you understand from the above discussion this generally happens
  +when your code already send the header, that's why you see it rendered into
  +a browser's page. This might happen when you call the <CODE>CGI.pm</CODE>  <CODE>$q-&amp;gt;header</CODE> method or mod_perl's
  +<CODE>$r-&amp;gt;send_http_header</CODE>. 
  +
  +<P>
  +If you have a complicated application where the header might be generated
  +from many different places, depending on the calling logic, you might want
  +to write a special subroutine that sends a header, and keeps a track
  +whether the header has been already sent. Of course you can use a global
  +variable to flag that the header has been already sent, but there is
  +another elegant solution, where the closure effect is a desired feature.
  +
  +<P>
  +Just copy the code below, including the block's curly braces. And
  +everywhere in your code you print the header use the <CODE>print_header()</CODE>
  +subroutine. <CODE>$need_header</CODE> is the same kind of beast as a static variable in C, so it remembers its
  +value from call to call. The first time you will call the <CODE>print_header</CODE>, the value of <CODE>$need_header</CODE>
  +will become zero and on the subsequent calls if any happens, the header
  +will be not sent any more.
  +
  +<P>
  +<PRE>  {
  +    my $need_header = 1;
  +    sub print_header {
  +      my type = shift || &quot;text/html&quot;;
  +      print(&quot;Content-type: $type\n\n),$need_header = 0 if $need_header;
  +    }
  +  }
  +</PRE>
  +<P>
  +In your code you call the above subroutine as:
  +
  +<P>
  +<PRE>  print_header();
  +</PRE>
  +<P>
  +or
  +
  +<P>
  +<PRE>  print_header(&quot;text/plain);
  +</PRE>
  +<P>
  +if you want to override the default (text/html) MIME type.
  +
  +<P>
  +Let's make our smart method to elaborate with PerlSendHeader directive
  +settings, to always do the right thing. It's especially important if you
  +write an application that you are going to distribute, hopefully as an Open
  +Source.
  +
  +<P>
  +<PRE>  {
  +    my $need_header = 1;
  +    sub print_header {
  +      my type = shift || &quot;text/html&quot;;
  +      return unless $need_header;
  +      $need_header = 0;
  +      if($ENV{PERL_SEND_HEADER}) {
  +        print &quot;Content-type: $type\n\n&quot;;
  +      }
  +      else {
  +        my $r = Apache-&gt;request;
  +        $r-&gt;content_type($type);
  +        $r-&gt;send_http_header;
  +      }
  +    }
  +  }
  +</PRE>
   <P>
  -If you are using <CODE>CGI.pm</CODE> or <CODE>CGI::Switch</CODE> and <STRONG>print
  -$q-&gt;header</STRONG> you do _not_ need <CODE>PerlSendHeader</CODE> On.
  +You can continue to improve this subroutine even further to handle
  +additional headers, like cookies and alike.
   
   <P>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<CENTER><H2><A NAME="NPH_Non_Parsed_Headers_scripts">NPH (Non Parsed Headers) scripts</A></H2></CENTER>
  +<CENTER><H1><A NAME="NPH_Non_Parsed_Headers_scripts">NPH (Non Parsed Headers) scripts</A></H1></CENTER>
   <P>
   To run a Non Parsed Header CGI script under mod_perl, simply add to your
   code:
  @@ -2141,8 +3966,7 @@
   <PRE>  local $| = 1;
   </PRE>
   <P>
  -And if you normally set <CODE>PerlSendHeader On</CODE>, add this to your
  -<CODE>httpd.conf</CODE>:
  +And if you normally set <CODE>PerlSendHeader On</CODE>, add this to your server's configuration file:
   
   <P>
   <PRE>  &lt;Files */nph-*&gt;
  @@ -2151,7 +3975,7 @@
   </PRE>
   <P>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<CENTER><H2><A NAME="BEGIN_blocks">BEGIN blocks</A></H2></CENTER>
  +<CENTER><H1><A NAME="BEGIN_blocks">BEGIN blocks</A></H1></CENTER>
   <P>
   Perl executes <CODE>BEGIN</CODE> 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
  @@ -2213,7 +4037,7 @@
   
   <P>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<CENTER><H2><A NAME="END_blocks">END blocks</A></H2></CENTER>
  +<CENTER><H1><A NAME="END_blocks">END blocks</A></H1></CENTER>
   <P>
   As perlmod explains, an <CODE>END</CODE> subroutine is executed as late as possible, that is, when the interpreter
   exits. In the mod_perl environment, the interpreter does not exit until the
  @@ -2236,14 +4060,15 @@
   <P>
   All other <CODE>END</CODE> blocks encountered during other <CODE>Perl*Handler</CODE>
   call-backs, e.g.  <CODE>PerlChildInitHandler</CODE>, will be suspended while the process is running and called during <CODE>child_exit()</CODE> when the process is shutting down. Module authors might wish to use
  -<CODE>$r-&amp;gt;register_cleanup</CODE> as an alternative to <CODE>END</CODE> blocks if this behavior is not desirable.
  +<CODE>$r-&amp;gt;register_cleanup()</CODE> as an alternative to <CODE>END</CODE> blocks if this behavior is not desirable. <CODE>$r-&amp;gt;register_cleanup()</CODE> is being called at the CleanUp processing phase of each request and thus
  +can be used to emulate plain perl's <CODE>END{}</CODE> block behavior.
   
   <P>
   The last paragraph is very important for the <A HREF="././obvious.html#Handling_the_User_pressed_Stop_">Handling the 'User pressed Stop button' case</A>.
   
   <P>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<CENTER><H2><A NAME="Switches_w_T">Switches -w, -T</A></H2></CENTER>
  +<CENTER><H1><A NAME="Switches_w_T">Switches -w, -T</A></H1></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 <STRONG>-w</STRONG> or <STRONG>-T</STRONG>. Most command line arguments have a equivalent special variable. For
  @@ -2281,7 +4106,7 @@
   
   <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>
  +<CENTER><H1><A NAME="strict_pragma">strict pragma</A></H1></CENTER>
   <P>
   It's _absolutely_ mandatory (at least for development) to start all your
   scripts with:
  @@ -2306,7 +4131,7 @@
   
   <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>
  +<CENTER><H1><A NAME="Turning_warnings_ON">Turning warnings ON</A></H1></CENTER>
   <P>
   Have a <CODE>local $^W=1</CODE> in the script or <CODE>PerlWarn ON</CODE> at the server configuration file. Turning the warning on will save you a
   lot of troubles with debugging your code. Note that all perl switches, but
  @@ -2347,7 +4172,7 @@
   
   <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>
  +<CENTER><H1><A NAME="diagnostics_pragma">diagnostics pragma</A></H1></CENTER>
   <P>
   This is a Perl compiler pragma which forces verbose warning diagnostics.
   Put at the start of your scripts:
  @@ -2370,7 +4195,7 @@
   
   <P>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<CENTER><H2><A NAME="Passing_ENV_variables_to_CGI">Passing ENV variables to CGI</A></H2></CENTER>
  +<CENTER><H1><A NAME="Passing_ENV_variables_to_CGI">Passing ENV variables to CGI</A></H1></CENTER>
   <P>
   To pass an environment variable from a configuration file, add to it:
   
  @@ -2398,7 +4223,7 @@
   
   <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>
  +<CENTER><H1><A NAME="Global_Variables">Global Variables</A></H1></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 (or fully qualified
  @@ -2430,13 +4255,13 @@
   
   <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_it_se">Code has been changed, but it seems the script is running the old code</A></H2></CENTER>
  +<CENTER><H1><A NAME="Code_has_been_changed_but_it_se">Code has been changed, but it seems the script is running the old code</A></H1></CENTER>
   <P>
   Files pulled in via <STRONG>use</STRONG> or <STRONG>require</STRONG> statements are not automatically reloaded when changed on disk. See <A HREF="#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="Apache_and_syslog">Apache and syslog</A></H2></CENTER>
  +<CENTER><H1><A NAME="Apache_and_syslog">Apache and syslog</A></H1></CENTER>
   <P>
   When native syslog support is enabled, the stderr stream will be redirected
   to <CODE>/dev/null</CODE>!
  @@ -2447,7 +4272,7 @@
   
   <P>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<CENTER><H2><A NAME="Memory_leakage">Memory leakage</A></H2></CENTER>
  +<CENTER><H1><A NAME="Memory_leakage">Memory leakage</A></H1></CENTER>
   <P>
   Scripts under mod_perl can very easily leak memory! Global variables stay
   around indefinitely, lexical variables (declared with <CODE>my()</CODE> are destroyed when they go out of scope, provided there are no references
  @@ -2733,176 +4558,6 @@
   
   <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 plain CGI scripts, you can just change the code, and rerun
  -the CGI from your browser. Since the script isn't cached in memory, the
  -next time you call it the server starts up a new perl process, which
  -recompiles it from scratch. The effects of any modifications you've applied
  -are immediately present.
  -
  -<P>
  -The situation is different with <CODE>Apache::Registry</CODE>, since the whole idea is to get maximum performance from the server. By
  -default, the server won't spend the time to check whether any included
  -library modules have been changed. It assumes that they weren't, thus
  -saving a few milliseconds to <CODE>stat()</CODE> the source file (multiplied by however many modules/libraries you are <CODE>use()</CODE>-ing and/or <CODE>require()</CODE>-ing in your script.) 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
  -<CODE>use()</CODE> (or <CODE>require()</CODE>) other perl modules (or packages), there is nothing new about it. If
  -however, you are developing a script that includes other modules, the files
  -you <CODE>use()</CODE> or <CODE>require()</CODE> aren't being checked whether they have been modified.
  -
  -<P>
  -Acknowledging this, how do we get our modperl-enabled server to recognize
  -changes in any library modules? Well, there are a couple of techniques:
  -
  -<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>
  -The simplest approach is to restart the server each time you apply some
  -change to your code. See <A HREF="././control.html#Restarting_techniques">Server Restarting techniques</A>.
  -
  -<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 about 100 times, you will be tired and will
  -look for another solutions. Help comes from the
  -<CODE>Apache::StatINC</CODE> module.
  -
  -<P>
  -<CODE>Apache::StatINC</CODE> reloads <CODE>%INC</CODE> files when updated on disk. When Perl pulls a file via require, it stores
  -the filename in the global hash <CODE>%INC</CODE>. The next time Perl tries to require the same file, it sees the file in <CODE>%INC</CODE> and does not reload from disk. This module's handler iterates over <CODE>%INC</CODE> and reloads the file if it has changed on disk.
  -
  -<P>
  -To enable this module just add two lines to <CODE>httpd.conf</CODE> file.
  -
  -<P>
  -<PRE>  PerlModule Apache::StatINC
  -  PerlInitHandler Apache::StatINC
  -</PRE>
  -<P>
  -To be sure it really works, turn on the debug mode on your development box
  -with <CODE>PerlSetVar StatINCDebug On</CODE>. You end up with something like:
  -
  -<P>
  -<PRE>  PerlModule Apache::StatINC
  -  &lt;Location /perl&gt;
  -    SetHandler perl-script
  -    PerlHandler Apache::Registry::handler
  -    Options ExecCGI
  -    PerlSendHeader On
  -    PerlInitHandler Apache::StatINC
  -    PerlSetVar StatINCDebug On
  -  &lt;/Location&gt;
  -</PRE>
  -<P>
  -Beware that 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 (in startup file).
  -
  -<P>
  -Whatever you do in your scripts and modules which are being <CODE>required()</CODE> after the server startup will not have any effect on <CODE>@INC</CODE>. When you do:
  -
  -<P>
  -<PRE>  use lib qw(foo/bar);
  -</PRE>
  -<P>
  -the <CODE>@INC</CODE> is being changed only for the time the code is being parsed and compiled.
  -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://www.nowhere.com/perl-status?inc">http://www.nowhere.com/perl-status?inc</A>
  -and look at the bottom of the page. (I assume you have configured the <A HREF="././config.html#_perl_status_location">/perl-status location</A>.)
  -
  -<P>
  -Also, notice the following caveat: While ``<CODE>.</CODE>'' is in the <CODE>@INC</CODE> -- perl knows to <CODE>require()</CODE> files relative to the script directory. Once the script was parsed - the
  -server doesn't remember the path any more! So you end up with broken entry
  -in <CODE>%INC</CODE> like:
  -
  -<P>
  -<PRE>  $INC{bar.pl} eq &quot;bar.pl&quot;
  -</PRE>
  -<P>
  -If you want Apache::StatINC to reload your script - modify the <CODE>@INC</CODE>
  -at the server startup file! or use a full path in <CODE>require()</CODE> call.
  -
  -<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>
  -Checking all the modules in <STRONG>%INC</STRONG> every time can add a large overhead to server response times, and you
  -certainly would not want
  -<CODE>Apache::StatINC</CODE> module to be enabled in your production site's configuration. But sometimes
  -you want to have some Configuration module to be reloaded without
  -restarting the whole server. To accomplish this, one of the solutions is to
  -use a code that I describe below.
  -
  -<P>
  -Assuming that you start your script with loading <CODE>Foo::Bar</CODE> and importing some tags:
  -
  -<P>
  -<PRE>  use lib &quot;/some/private/path&quot;;
  -  use Foo::Bar qw(:tags_group tag1 tag2);
  -</PRE>
  -<P>
  -Now to make a modification testing and reload at runtime you have to use
  -something like this:
  -
  -<P>
  -<PRE>  # child's private global variable to keep the timestamps
  -  use vars qw(%MODIFIED);
  -    
  -  my $module = &quot;Foo::Bar&quot;;
  -  
  -  (my $inc_key = $module) =~ s|::|/|g;
  -  $inc_key .= &quot;.pm&quot;;
  -  # the $module's path should be registered in %INC if it was already loaded
  -  my $path = $INC{$inc_key} or warn &quot;Can't find $inc_key in %INC\n&quot;;
  -  
  -  # Note: consider to not continue if $path wasn't set!
  -  
  -  # set modification time if it wasn't set before (first time)
  -  # Note: Use (stat $path)[9] instead of -M test, if you reset
  -  # time with $^M=time
  -  $MODIFIED{$module} ||= -M $path;
  -    
  -  # now check whether it was changed (assuming the above wasn't
  -  # performed in this session
  -  if ($MODIFIED{$module} != -M $path){
  -    # only if deleted from %INC the require will be called below
  -    delete $INC{$inc_key};
  -    
  -    require $path;
  -    
  -    # now reimport the symbols (if you need them back :)
  -    import $module qw(:tags_group tag1 tag2);
  -    
  -    # Update the MODIFICATION times
  -    $MODIFIED{$module} = -M $path;
  -  }
  -</PRE>
  -<P>
  -You may want to add debug print statements to debug this code in your
  -application.
  -
  -<P>
  -Read the ``use versus require'' article for more info. ( <A
  -HREF="http://www.perl.com/CPAN-local/doc/FMTEYEWTK/use_vs_require">http://www.perl.com/CPAN-local/doc/FMTEYEWTK/use_vs_require</A>
  -)
  -
  -<P>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<CENTER><H2><A NAME="Reloading_handlers">Reloading handlers</A></H2></CENTER>
  -<P>
  -If you want to reload perlhandler on each invocation, the following trick
  -will do it:
  -
  -<P>
  -<PRE>  PerlHandler &quot;sub { do 'MyTest.pm'; MyTest::handler(shift) }&quot;
  -</PRE>
  -<P>
  -<CODE>do()</CODE> will reload <CODE>MyTest.pm</CODE> every request.
  -
  -<P>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
   <CENTER><H1><A NAME="Filehandlers_and_locks_leakages">Filehandlers and locks leakages</A></H1></CENTER>
   <P>
   When you write a script running under mod_cgi, you can get away with sloppy
  @@ -3067,6 +4722,40 @@
   
   <P>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<CENTER><H1><A NAME="Sharing_variables_between_proces">Sharing variables between processes</A></H1></CENTER>
  +<P>
  +META: to be completed
  +
  +<UL>
  +<P><LI>
  +<P>
  +Global variables initialized at the server startup, through the Perl
  +startup file, can be shared between processes, untill modified by some of
  +the processes. e.g. when you write:
  +
  +<P>
  +<PRE>  $My::debug = 1;
  +</PRE>
  +<P>
  +all processes will read the same value. If one of the processes changes
  +that value to <CODE>0</CODE>, it'll be still equal to <CODE>1</CODE> for any process, but the one who actually did the change. When the process
  +modifies the variable, it becomes process' private copy.
  +
  +<P><LI>
  +<P>
  +<CODE>IPC::Shareable</CODE> can be used to share variables between children.
  +
  +<P><LI>
  +<P>
  +libmm
  +
  +<P><LI>
  +<P>
  +other methods?
  +
  +</UL>
  +<P>
  +<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></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
  @@ -3272,23 +4961,27 @@
   </PRE>
   <P>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<CENTER><H1><A NAME="Forking_subprocesses_from_mod_pe">Forking subprocesses from mod_perl</A></H1></CENTER>
  +<CENTER><H1><A NAME="Forking_or_Executing_subprocesse">Forking or Executing subprocesses from mod_perl</A></H1></CENTER>
   <P>
   Generally you should not fork from your mod_perl scripts, since when you do
   -- you are forking the entire apache web server, lock, stock and barrel.
   Not only is your perl code being duplicated, but so is mod_ssl,
   mod_rewrite, mod_log, mod_proxy, mod_spelling or whatever modules you have
  -used in your server, all the core routines and so on. A much wiser approach
  -would be to spawn a sub-process, hand it the information it needs to do the
  -task, and have it detach (close x3 +
  +used in your server, all the core routines and so on.
  +
  +<P>
  +A much wiser approach would be to spawn a sub-process, hand it the
  +information it needs to do the task, and have it detach (close x3 +
   <CODE>setsid()</CODE>). This is wise only if the parent who spawns this process, immediately
  -continue, you do not wait for the sub process to complete. This approach is
  +continue, you do not wait for the sub-process to complete. This approach is
   suitable for a situation when you want to trigger a long time taking
   process through the web interface, like processing some data, sending email
   to thousands of subscribed users and etc. Otherwise, you should convert the
   code into a module, and use its functions or methods to call from CGI
  -script. Just making a
  -<CODE>system()</CODE> call defeats the whole idea behind mod_perl, perl interpreter and modules
  +script.
  +
  +<P>
  +Just making a <CODE>system()</CODE> call defeats the whole idea behind mod_perl, perl interpreter and modules
   should be loaded again for this external program to run.
   
   <P>
  @@ -3329,54 +5022,96 @@
   post-processing, look into <CODE>PerlCleanupHandler</CODE>.
   
   <P>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<CENTER><H1><A NAME="Generating_correct_HTTP_MIME_Hea">Generating correct HTTP MIME Headers</A></H1></CENTER>
  +If you are interested in more deep level details, this is what actually
  +happens when you fork and make a system call, like
  +
   <P>
  -The <CODE>Apache::print()</CODE> routine has to gather up the headers that your script outputs, in order to
  -pass them to <CODE>$r-&amp;gt;send_http_header</CODE>. This happens in <CODE>src/modules/perl/Apache.xs</CODE> (<CODE>print</CODE>) and
  -<CODE>Apache/Apache.pm</CODE> (<CODE>send_cgi_header</CODE>). There is a shortcut in there, namely the assumption that each print
  -statement contains one or more complete headers. If for example you used to
  -generate a
  -<CODE>Set-Cookie</CODE> header by multiply <CODE>print()</CODE> statements, like:
  +<PRE>  system(&quot;echo Hi&quot;),exit unless fork();
  +</PRE>
  +<P>
  +What happens is that <CODE>fork()</CODE> gives you 2 execution paths and
  +the child gets virtual memory sharing a copy of the program text (read
  +only) and sharing a copy of the data space copy-on-write (remember why you
  +pre-load modules in mod_perl?). In the above code a parent will immediately
  +continue with the code that comes up after the fork, while the forked
  +process will execute <CODE>system(&quot;echo Hi&quot;)</CODE> and then terminate itself. Note that you might need to set:
   
   <P>
  -<PRE>   print &quot;Content-type: text/html\n&quot;;
  -   print &quot;Set-Cookie: iscookietext\; &quot;;
  -   print &quot;expires=Wednesday, 09-Nov-1999 00:00:00 GMT\; &quot;;
  -   print &quot;path=\/\; &quot;;
  -   print &quot;domain=\.mmyserver.com\; &quot;;
  -   print &quot;\n\n&quot;;
  -   print &quot;hello&quot;;
  +<PRE>  $SIG{CHLD} = sub {wait};
   </PRE>
   <P>
  -your generated <CODE>Set-Cookie</CODE> header is split over a number of print statements and gets lost. Try this:
  +or
   
   <P>
  -<PRE>   print &quot;Content-type: text/html\n&quot;;
  -   my $cookie = &quot;Set-Cookie: iscookietext\; &quot;;
  -   $cookie .= &quot;expires=Wednesday, 09-Nov-1999 00:00:00 GMT\; &quot;;
  -   $cookie .= &quot;path=\/\; &quot;;
  -   $cookie .= &quot;domain=\.mmyserver.com\; &quot;;
  -   print $cookie;
  -   print &quot;\n\n&quot;;
  -   print &quot;hello&quot;;
  +<PRE>  $SIG{CHLD} = IGNORE;
  +</PRE>
  +<P>
  +or the terminated process might become a zombie. Normally, every process
  +has its parent, many processes a children of PID 1, the init process.
  +Zombie, is a process that doesn't have a father. When the child quits, it
  +reports the termination to his parent. If he doesn't know who the father is
  +it becomes zombie. (META: Did I formulate it correctly?)
  +
  +<P>
  +The only work is setting up the page tables for the virtual memory and the
  +second process goes on its separate way.
  +
  +<P>
  +Next, Perl will find <CODE>/bin/echo</CODE> along the search path, and invoke it directly. Perl <CODE>system()</CODE>
  +is *not* <CODE>system(3)</CODE> [C-library]. Only when the command has shell meta-chars does Perl invoke a
  +real shell. That's a *very* nice optimization.
  +
  +<P>
  +Only if you do:
  +
  +<P>
  +<PRE>  system &quot;sh -c 'echo foo'&quot;
   </PRE>
  +<P>
  +OS actually parses your command with a shell so you <CODE>exec()</CODE> a
  +copy of
  +<CODE>/bin/sh</CODE>, but since one is almost certainly already running somewhere, the system
  +will notice that (via the disk inode reference) and replace your virtual
  +memory page table with one pointed at the already-loaded program code plus
  +your own data space. Then the shell parses the passed command.
  +
   <P>
  -&lt;META&gt; some leftovers... # =head1 Coding with mod_perl
  +Since it is <CODE>echo</CODE>, it will execute it as a built-in in the latter example or a <CODE>/bin/echo</CODE> in the former and be done, but this is only an example. You aren't calling <CODE>system(&quot;echo Hi&quot;)</CODE> in your mod_perl scripts, right? Since most other real things (heavy
  +programs executed as a subprocess) would involve repeating the process to
  +load the specified command or script (it might involve some actual demand
  +paging from the program file if you execute new code).
   
  +<P>
  +The only place you see real overhead from this scheme is when the parent
  +process is huge (unfortunately like mod_perl...) and the page table becomes
  +large as a side effect. The whole point of mod_perl is to avoid having to
  +<CODE>fork()</CODE> / <CODE>exec()</CODE> something on every hit, though.
  +Perl can do just about anything by itself. However, you probably won't get
  +in trouble until you hit about 30 forks/sec on a so-so pentium.
  +
  +<P>
  +<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<CENTER><H1><A NAME="Passing_and_preserving_custom_da">Passing and preserving custom data structures between handlers</A></H1></CENTER>
  +<P>
  +Let's say that you wrote a few handlers to process a request, and they all
  +need to share some custom Perl data structure. The <CODE>pnotes()</CODE>
  +method comes to rescue. Taken that one of the handlers stored some data in
  +hash <CODE>%my_data</CODE>, before it finished its activity:
  +
  +<P>
  +<PRE>   # First handler:
  +   $r-&gt;pnotes('my_info' =&gt; \%hash);
  +</PRE>
   <P>
  -Before you start coding for <CODE>Apache::Registry</CODE>, you have to change your programming state of mind. Scripts running under
  -mod_perl are like subroutines are being called from a continually running
  -daemon. Imagine a daemon process that when requested to process some
  -script, reads it in, compiles it as a subroutine, and finally executes it.
  -On any subsequent request, it'll just recall the already compiled
  -subroutine. Hope that you get the idea.
  +All the following handler will be able to retrive the stored data with.
   
   <P>
  -The best thing you do when coding from scratch is to make it clean and use
  -packages. By ``make it clean'' we mean make certain that you <STRONG>use
  -strict;</STRONG> and that your script produces no warnings when tested via
  -<STRONG>perl -cw myscript.pl</STRONG>. As you go thru the notes you will understand why. &lt;/META&gt;
  +<PRE>   # Later handler:
  +   my $info = $r-&gt;pnotes('my_info');
  +   print $info-&gt;{foo};
  +</PRE>
  +<P>
  +The stored information will be destroyed at the end of the request.
   
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
   	     The <a href="http://www.modperl.com/">
  @@ -3388,6 +5123,16 @@
   	     Amazon.com</a>.
   
   	     <HR>
  +
  +	     Your corrections of either technical or grammatical
  +	     errors are very welcome. You are encouraged to help me
  +	     to improve this guide.  If you have something to
  +	     contribute please <A
  +	     HREF="help.html#This_document_s_Author"> send it
  +	     directly to me</A>.
  +
  +	     <HR>
  +
   	     [    <A HREF="start.html">Prev</A> |      <A HREF="index.html">Main Page</A> | <A HREF="performance.html">Next</A>      ]
   
   <CENTER><TABLE CELLSPACING=2 CELLPADDING=2 WIDTH="100%" >
  @@ -3401,7 +5146,7 @@
       <B>
         <FONT SIZE=-1>
   	     Written by <A HREF="help.html#This_document_s_Author">Stas Bekman</A>.
  -	     <BR>Last Modified at 08/17/1999
  +	     <BR>Last Modified at 09/26/1999
         </FONT>
       </B>
     </TD>
  @@ -3463,6 +5208,8 @@
   
   	<LI><A HREF="#Preload_Registry_Scripts">Preload Registry Scripts</A>
   	<LI><A HREF="#Avoid_Importing_Functions">Avoid Importing Functions</A>
  +	<LI><A HREF="#PerlSetupEnv_Off">PerlSetupEnv Off</A>
  +	<LI><A HREF="#_DTWO_POT_OPTIMIZE_and_DPACK_MA">-DTWO_POT_OPTIMIZE and -DPACK_MALLOC Perl Options</A>
   	<LI><A HREF="#Shared_Memory">Shared Memory</A>
   	<LI><A HREF="#Checking_script_modification_tim">Checking script modification times</A>
   	<LI><A HREF="#How_can_I_find_if_my_mod_perl_sc">How can I find if my mod_perl scripts have memory leaks</A>
  @@ -3510,6 +5257,15 @@
   
   	     <HR>
   
  +	       Your corrections of either technical or grammatical
  +	       errors are very welcome. You are encouraged to help me
  +	       to improve this guide.  If you have something to
  +	       contribute please <A
  +	       HREF="help.html#This_document_s_Author"> send it
  +	       directly to me</A>.
  +
  +	       <HR>
  +
   	      <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
   <P>
   <CENTER><H1><A NAME="Performance_The_Overall_picture">Performance: The Overall picture</A></H1></CENTER>
  @@ -3641,6 +5397,21 @@
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
   <CENTER><H2><A NAME="Preload_Perl_modules_Real_Numb">Preload Perl modules - Real Numbers</A></H2></CENTER>
   <P>
  +(META: while the numbers and conclusions are mostly correct, need to
  +rewrite the whole benchmark section using the GTop library to report the
  +shared memory which is very important and will improve the benchmarks)
  +
  +<P>
  +(META: Add the memory size tests when the server was compiled with
  +EVERYTHING=1 and without it, does loading everything imposes a big change
  +in the memory footprint? Probably the suggestion would be as follows: For a
  +development server use EVERYTHING=1, while for a production if your server
  +is pretty busy and/or low on memory and every bit is on account, only the
  +required parts should be built in. BTW, remember that apache comes with
  +many modules that are being built by default, and you might not need
  +those!)
  +
  +<P>
   I have conducted a few tests to benchmark the memory usage when some
   modules are preloaded. The first set of tests checks the memory use with
   Library Perl Module preload (only <CODE>CGI.pm</CODE>). The second set checks the compile method of <CODE>CGI.pm</CODE>. The third test checks the benefit of Library Perl Module preload but a
  @@ -3850,8 +5621,24 @@
     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 by 3276K. Ouch: 512K more!!!
  +
  +<P>
  +The reason is that when you preload at the startup all of the methods, they
  +all are being precompiled, there are many of them and they take a big chunk
  +of memory. If you don't use the <CODE>compile()</CODE> method, only the
  +functions that are being used will be compiled. Yes, it will slightly slow
  +down the first reposnse of each process, but the actuall memory usage will
  +be lower. BTW, if you write in the script:
  +
  +<P>
  +<PRE>  use CGI qw(all);
  +</PRE>
   <P>
  -Observation: child httpd has grown by 3276K. Great difference: 512K less!!!
  +Only the symbols of all functions are being imported. While they are taking
  +some space, it's smaller than the space that a compiled code of these
  +functions might occupy.
   
   <P>
   <STRONG>Server restarted</STRONG>
  @@ -3961,6 +5748,52 @@
   
   <P>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<CENTER><H1><A NAME="PerlSetupEnv_Off">PerlSetupEnv Off</A></H1></CENTER>
  +<P>
  +<CODE>PerlSetupEnv Off</CODE> is another optimization you might consider.
  +
  +<P>
  +<EM>mod_perl</EM> fiddles with the environment to make it appear as if the script were being
  +called under the CGI protocol. For example, the
  +<CODE>$ENV{QUERY_STRING}</CODE> environment variable is initialized with the contents of <EM>Apache::args()</EM>, and <CODE>$ENV{SERVER_NAME}</CODE> is filled in from the value returned by <EM>Apache::server_hostname()</EM>.
  +
  +<P>
  +But <CODE>%ENV</CODE> population is expensive. Those who have moved to the Perl Apache API no
  +longer need this extra <CODE>%ENV</CODE> population, can gain by turning it <STRONG>Off</STRONG>.
  +
  +<P>
  +<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<CENTER><H1><A NAME="_DTWO_POT_OPTIMIZE_and_DPACK_MA">-DTWO_POT_OPTIMIZE and -DPACK_MALLOC Perl Options</A></H1></CENTER>
  +<P>
  +Newer Perl versions also have build time options to reduce runtime memory
  +consumption. These options might shrink down the size of your httpd by
  +about ~150k (quite big number if you remember to multiply it by the number
  +of chidren you use.)
  +
  +<P>
  +<CODE>-DTWO_POT_OPTIMIZE</CODE> macro improves allocations of data with size close to a power of two; but
  +this works for big allocations (starting with 16K by default). Such
  +allocations are typical for big hashes and special-purpose scripts,
  +especially image processing.
  +
  +<P>
  +Perl memory allocation is by bucket with sizes close to powers of two.
  +Because of these malloc overhead may be big, especially for data of size
  +exactly a power of two. If <CODE>PACK_MALLOC</CODE> is defined, perl uses a slightly different algorithm for small allocations
  +(up to 64 bytes long), which makes it possible to have overhead down to 1
  +byte for allocations which are powers of two (and appear quite often). 
  +
  +<P>
  +Expected memory savings (with 8-byte alignment in <CODE>alignbytes</CODE>) is about 20% for typical Perl usage. Expected slowdown due to additional
  +malloc overhead is in fractions of a percent (hard to measure, because of
  +the effect of saved memory on speed).
  +
  +<P>
  +You will find these and other memory improvement details in
  +<CODE>perl5004delta.pod</CODE>.
  +
  +<P>
  +<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
   <CENTER><H1><A NAME="Shared_Memory">Shared Memory</A></H1></CENTER>
   <P>
   You've probably noticed that the word shared is being repeated many times
  @@ -4061,6 +5894,10 @@
   <CODE>Apache::Status</CODE> now includes a new StatusLexInfo option.
   
   <P>
  +Apache::Leak works better if you've built a libperld.a (see SUPPORT) and
  +given PERL_DEBUG=1 to mod_perl's Makefile.PL
  +
  +<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>
  @@ -5183,7 +7020,8 @@
   <PRE>  PerlModule Apache::DBI
   </PRE>
   <P>
  -It is important, to load this module before any other <CODE>ApacheDBI*</CODE> module!
  +It is important, to load this module before any other <CODE>DBI</CODE>,
  +<CODE>DBD::*</CODE> and <CODE>ApacheDBI*</CODE> modules!
   
   <P>
   <PRE>  db.pl
  @@ -5221,6 +7059,11 @@
   that child process. See the <CODE>Apache::DBI</CODE> manpage to see the requirements for this method.
   
   <P>
  +You can also benefit from persistent connections by replacing
  +<CODE>prepare()</CODE> with <CODE>prepare_cached().</CODE> But it can
  +produce a little overhead (META, why?).
  +
  +<P>
   Another problem is with timeouts: some databases disconnect the client
   after a certain time of inactivity. This problem is known as <STRONG>morning
   bug</STRONG>. The <CODE>ping()</CODE> method ensures that this will not happen. Some
  @@ -5421,6 +7264,16 @@
   	     Amazon.com</a>.
   
   	     <HR>
  +
  +	     Your corrections of either technical or grammatical
  +	     errors are very welcome. You are encouraged to help me
  +	     to improve this guide.  If you have something to
  +	     contribute please <A
  +	     HREF="help.html#This_document_s_Author"> send it
  +	     directly to me</A>.
  +
  +	     <HR>
  +
   	     [    <A HREF="porting.html">Prev</A> |      <A HREF="index.html">Main Page</A> | <A HREF="strategy.html">Next</A>      ]
   
   <CENTER><TABLE CELLSPACING=2 CELLPADDING=2 WIDTH="100%" >
  @@ -5434,7 +7287,7 @@
       <B>
         <FONT SIZE=-1>
   	     Written by <A HREF="help.html#This_document_s_Author">Stas Bekman</A>.
  -	     <BR>Last Modified at 08/16/1999
  +	     <BR>Last Modified at 09/26/1999
         </FONT>
       </B>
     </TD>
  @@ -5509,6 +7362,15 @@
   
   	     <HR>
   
  +	       Your corrections of either technical or grammatical
  +	       errors are very welcome. You are encouraged to help me
  +	       to improve this guide.  If you have something to
  +	       contribute please <A
  +	       HREF="help.html#This_document_s_Author"> send it
  +	       directly to me</A>.
  +
  +	       <HR>
  +
   	      <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
   <P>
   <CENTER><H1><A NAME="Do_it_like_me_">Do it like me?!</A></H1></CENTER>
  @@ -6143,6 +8005,16 @@
   	     Amazon.com</a>.
   
   	     <HR>
  +
  +	     Your corrections of either technical or grammatical
  +	     errors are very welcome. You are encouraged to help me
  +	     to improve this guide.  If you have something to
  +	     contribute please <A
  +	     HREF="help.html#This_document_s_Author"> send it
  +	     directly to me</A>.
  +
  +	     <HR>
  +
   	     [    <A HREF="performance.html">Prev</A> |      <A HREF="index.html">Main Page</A> | <A HREF="scenario.html">Next</A>      ]
   
   <CENTER><TABLE CELLSPACING=2 CELLPADDING=2 WIDTH="100%" >
  @@ -6255,6 +8127,15 @@
   
   	     <HR>
   
  +	       Your corrections of either technical or grammatical
  +	       errors are very welcome. You are encouraged to help me
  +	       to improve this guide.  If you have something to
  +	       contribute please <A
  +	       HREF="help.html#This_document_s_Author"> send it
  +	       directly to me</A>.
  +
  +	       <HR>
  +
   	      <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
   <P>
   <CENTER><H1><A NAME="Standalone_mod_perl_Enabled_Apac">Standalone mod_perl Enabled Apache Server</A></H1></CENTER>
  @@ -6274,7 +8155,7 @@
     % perl Makefile.PL APACHE_SRC=../apache_x.x.x/src \
       DO_HTTPD=1 USE_APACI=1 PERL_MARK_WHERE=1 EVERYTHING=1
     % make &amp;&amp; make test &amp;&amp; make install
  -  % cd ../apache_x.x.x/src
  +  % cd ../apache_x.x.x
     % make install
   </PRE>
   <P>
  @@ -6345,7 +8226,7 @@
   directory tree and to put the <CODE>httpd</CODE> there.
   
   <P>
  -<PRE>  % cd ../apache_x.x.x/src
  +<PRE>  % cd ../apache_x.x.x
     % make install
   </PRE>
   <P>
  @@ -7412,6 +9293,14 @@
   coming from, before changing the <CODE>remote_ip</CODE>.
   
   <P>
  +Generally you shouldn't trust the <CODE>X-Forwarded-For</CODE> header. You only want to rely on <CODE>X-Forwarded-For</CODE> headers from proxies you control yourself. If you know how to spoof a
  +cookie you've probably got the general idea on making HTTP headers and can
  +spoof the
  +<CODE>X-Forwarded-For</CODE> header as well. The only address *you* can count on as being a reliable
  +value is the one from
  +<CODE>r-&amp;gt;connection-&amp;gt;remote_ip</CODE>.
  +
  +<P>
   From that point on, the remote IP address is correct. You should be able to
   access <CODE>REMOTE_ADDR</CODE> as usual.
   
  @@ -7463,6 +9352,10 @@
   The only possible caveat in the config file is that your <CODE>Auth</CODE> stuff needs to be in <CODE>&lt;Directory ...</CODE>&gt; ... <CODE>&lt;/Directory</CODE>&gt; tags because if you use a <CODE>&lt;Location /...</CODE>&gt; ... <CODE>&lt;/Location</CODE>&gt; the proxypass server takes the auth info for its own authentication
   and would not pass it on.
   
  +<P>
  +The same with mod_ssl, if plugged into a front-end server, all the SSL
  +requests be encoded/decoded properly by it.
  +
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
   	     The <a href="http://www.modperl.com/">
   	     <B>Writing Apache Modules with Perl and C</B></a>
  @@ -7473,6 +9366,16 @@
   	     Amazon.com</a>.
   
   	     <HR>
  +
  +	     Your corrections of either technical or grammatical
  +	     errors are very welcome. You are encouraged to help me
  +	     to improve this guide.  If you have something to
  +	     contribute please <A
  +	     HREF="help.html#This_document_s_Author"> send it
  +	     directly to me</A>.
  +
  +	     <HR>
  +
   	     [    <A HREF="strategy.html">Prev</A> |      <A HREF="index.html">Main Page</A> | <A HREF="install.html">Next</A>      ]
   
   <CENTER><TABLE CELLSPACING=2 CELLPADDING=2 WIDTH="100%" >
  @@ -7486,7 +9389,7 @@
       <B>
         <FONT SIZE=-1>
   	     Written by <A HREF="help.html#This_document_s_Author">Stas Bekman</A>.
  -	     <BR>Last Modified at 08/17/1999
  +	     <BR>Last Modified at 09/25/1999
         </FONT>
       </B>
     </TD>
  @@ -7557,15 +9460,18 @@
   	</UL>
   
   	<LI><A HREF="#Is_it_possible_to_install_and_us">Is it possible to install and use apache/mod_perl without having a root access?</A>
  +	<LI><A HREF="#Is_it_possible_to_tell_whether_s">Is it possible to tell whether some option was included</A>
   	<LI><A HREF="#Is_it_possible_to_determine_whic">Is it possible to determine which options were given to modperl's Makefile.PL</A>
   	<LI><A HREF="#Server_Installation_problems">Server Installation problems</A>
   	<UL>
   
  +		<LI><A HREF="#_skipping_test_on_this_plat">......skipping test on this platform</A>
   		<LI><A HREF="#make_test_fails">make test fails</A>
   		<LI><A HREF="#mod_perl_c_is_incompatible_with_">mod_perl.c is incompatible with this version of apache</A>
   		<LI><A HREF="#Should_I_rebuild_mod_perl_if_I_h">Should I rebuild mod_perl if I have upgraded my perl?</A>
   	</UL>
   
  +	<LI><A HREF="#mod_auth_dbm_nuances">mod_auth_dbm nuances</A>
   	<LI><A HREF="#Stripping_apache_to_make_it_almo">Stripping apache to make it almost perl-server</A>
   </UL>
   <!-- INDEX END -->
  @@ -7582,6 +9488,15 @@
   
   	     <HR>
   
  +	       Your corrections of either technical or grammatical
  +	       errors are very welcome. You are encouraged to help me
  +	       to improve this guide.  If you have something to
  +	       contribute please <A
  +	       HREF="help.html#This_document_s_Author"> send it
  +	       directly to me</A>.
  +
  +	       <HR>
  +
   	      <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
   <P>
   <CENTER><H1><A NAME="Configuration_and_Installation">Configuration and Installation</A></H1></CENTER>
  @@ -7852,6 +9767,25 @@
   for more information on local perl installations.
   
   <P>
  +So you end up with something like:
  +
  +<P>
  +<PRE>  $ gunzip &lt;apache_x.x.xx.tar.gz | tar xvf -
  +  $ gunzip &lt;mod_perl-x.xx.tar.gz | tar xvf -
  +  $ cd mod_perl-x.xx
  +  $ perl Makefile.PL \
  +      APACHE_SRC=../apache-1.3.X/src \
  +      DO_HTTPD=1 \
  +      USE_APACI=1 \
  +      EVERYTHING=1 \
  +      APACI_ARGS=--sbindir=/home/stas/sbin/httpd_perl, \
  +           --sysconfdir=/home/stas/etc/httpd_perl, \
  +           --localstatedir=/home/stas/var/httpd_perl, \
  +           --runtimedir=/home/stas/var/httpd_perl/run, \
  +           --logfiledir=/home/stas/var/httpd_perl/logs, \
  +           --proxycachedir=/home/stas/var/httpd_perl/proxy
  +</PRE>
  +<P>
   You will not be able to have the server listen to a port lower then 1024 if
   you are not starting it as <CODE>root</CODE>, so choose a port number above 1024. (I use 8080 in most cases). Note that
   you will have to use a URL like <CODE>http://www.nowhere.com:8080</CODE> in that case, but that is not a problem since usually users do not directly
  @@ -7890,6 +9824,17 @@
   </UL>
   <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_tell_whether_s">Is it possible to tell whether some option was included</A></H1></CENTER>
  +<P>
  +Sure, you can take a look at the symbols inside the httpd executable. e.g.
  +if you want to see whether you have enabled PERL_AUTH=1 while building the
  +mod_perl, you do:
  +
  +<P>
  +<PRE>  nm httpd | grep perl_authenticate
  +</PRE>
  +<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_determine_whic">Is it possible to determine which options were given to modperl's Makefile.PL</A></H1></CENTER>
   <P>
   It is possible to determine which options were given to modperl's
  @@ -7924,6 +9869,56 @@
   <CENTER><H1><A NAME="Server_Installation_problems">Server Installation problems</A></H1></CENTER>
   <P>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<CENTER><H2><A NAME="_skipping_test_on_this_plat">......skipping test on this platform</A></H2></CENTER>
  +<P>
  +While doing <CODE>make test</CODE> you would notice that some of the tests are being reported as skipped. The
  +real reason is that you are missing some optional modules for these test to
  +be passed. For a hint you might want to peek at the content of each test
  +(you will find them all in the <CODE>./t</CODE> directory (mnemonic - t, tests). I'll list a few examples, but of course
  +the requirements might be changed in the future.
  +
  +<P>
  +&gt; modules/cookie......skipping test on this platform
  +
  +<P>
  +install libapreq
  +
  +<P>
  +&gt; modules/psections...skipping test on this platform
  +
  +<P>
  +install Devel::Symdump / Data::Dumper
  +
  +<P>
  +&gt; modules/request.....skipping test on this platform
  +
  +<P>
  +libapreq
  +
  +<P>
  +&gt; modules/sandwich....skipping test on this platform
  +
  +<P>
  +Apache::Sandwich
  +
  +<P>
  +&gt; modules/stage.......skipping test on this platform
  +
  +<P>
  +Apache::Stage
  +
  +<P>
  +&gt; modules/symbol......skipping test on this platform
  +
  +<P>
  +Devel::Symdump
  +
  +<P>
  +Chances are that all of these are installed if you use <CODE>CPAN.pm</CODE> to
  +<CODE>install Bundle::Apache</CODE>.
  +
  +<P>
  +<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
   <CENTER><H2><A NAME="make_test_fails">make test fails</A></H2></CENTER>
   <P>
   There are two configuration parameters: <CODE>PREP_HTTPD</CODE> and <CODE>DO_HTTPD</CODE>, that you can use in:
  @@ -7984,6 +9979,54 @@
   
   <P>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<CENTER><H1><A NAME="mod_auth_dbm_nuances">mod_auth_dbm nuances</A></H1></CENTER>
  +<P>
  +If you are a user of <STRONG>mod_auth_dbm</STRONG> or <STRONG>mod_auth_db</STRONG>, you may need to edit Perl's <CODE>Config</CODE> module. When Perl is configured it attempts to find libraries for ndbm,
  +gdbm, db, etc., for the *DBM*_File modules. By default, these libraries are
  +linked with Perl and remembered by the <STRONG>Config</STRONG> module. When mod_perl is configured with apache, the <STRONG>ExtUtils::Embed</STRONG> module returns these libraries to be linked with httpd so Perl extensions
  +will work under mod_perl. However, the order in which these libraries are
  +stored in
  +<STRONG>Config.pm</STRONG>, may confuse <CODE>mod_auth_db*</CODE>. If <CODE>mod_auth_db*</CODE> does not work with mod_perl, take a look at this order with the following
  +command:
  +
  +<P>
  +<PRE> % perl -V:libs
  +</PRE>
  +<P>
  +If <CODE>-lgdbm</CODE> or <CODE>-ldb</CODE> is before <CODE>-lndbm</CODE>, example:
  +
  +<P>
  +<PRE> libs='-lnet -lnsl_s -lgdbm -lndbm -ldb -ldld -lm -lc -lndir -lcrypt';
  +</PRE>
  +<P>
  +Edit <STRONG>Config.pm</STRONG> and move <CODE>-lgdbm</CODE> and <CODE>-ldb</CODE> to the end of the list. Here's how to find <STRONG>Config.pm</STRONG>:
  +
  +<P>
  +<PRE> % perl -MConfig -e 'print &quot;$Config{archlibexp}/Config.pm\n&quot;'
  +</PRE>
  +<P>
  +Another solution for building Apache/mod_perl+mod_auth_dbm under Solaris is
  +to remove the DBM and NDBM ``emulation'' from libgdbm.a. Seems Solaris
  +already provides its own DBM and NDBM, and there's no reason to build GDBM
  +with them (for us anyway).
  +
  +<P>
  +In our Makefile for GDBM, we changed
  +
  +<P>
  +<PRE>  OBJS = $(DBM_OF) $(NDBM_OF) $(GDBM_OF)
  +</PRE>
  +<P>
  +to
  +
  +<P>
  +<PRE>  OBJS = $(GDBM_OF)
  +</PRE>
  +<P>
  +Rebuild libgdbm, then Apache/mod_perl.  
  +
  +<P>
  +<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
   <CENTER><H1><A NAME="Stripping_apache_to_make_it_almo">Stripping apache to make it almost perl-server</A></H1></CENTER>
   <P>
   Since most of the functionality that various apache mod_* modules provide
  @@ -8003,6 +10046,16 @@
   	     Amazon.com</a>.
   
   	     <HR>
  +
  +	     Your corrections of either technical or grammatical
  +	     errors are very welcome. You are encouraged to help me
  +	     to improve this guide.  If you have something to
  +	     contribute please <A
  +	     HREF="help.html#This_document_s_Author"> send it
  +	     directly to me</A>.
  +
  +	     <HR>
  +
   	     [    <A HREF="scenario.html">Prev</A> |      <A HREF="index.html">Main Page</A> | <A HREF="config.html">Next</A>      ]
   
   <CENTER><TABLE CELLSPACING=2 CELLPADDING=2 WIDTH="100%" >
  @@ -8016,7 +10069,7 @@
       <B>
         <FONT SIZE=-1>
   	     Written by <A HREF="help.html#This_document_s_Author">Stas Bekman</A>.
  -	     <BR>Last Modified at 07/09/1999
  +	     <BR>Last Modified at 09/25/1999
         </FONT>
       </B>
     </TD>
  @@ -8073,6 +10126,14 @@
   
   		<LI><A HREF="#Alias_Configurations">Alias Configurations</A>
   		<LI><A HREF="#Location_Configuration">Location Configuration</A>
  +		<LI><A HREF="#PerlModule_and_PerlRequire_direc">PerlModule and PerlRequire directives</A>
  +		<LI><A HREF="#Perl_Handlers">Perl*Handlers</A>
  +	</UL>
  +
  +	<LI><A HREF="#STACKED_HANDLERS">STACKED HANDLERS</A>
  +	<LI><A HREF="#PERL_METHOD_HANDLERS">PERL METHOD HANDLERS</A>
  +	<UL>
  +
   		<LI><A HREF="#PerlFreshRestart">PerlFreshRestart</A>
   		<LI><A HREF="#_perl_status_location">/perl-status location</A>
   		<UL>
  @@ -8107,12 +10168,13 @@
   		<LI><A HREF="#My_script_works_under_cgi_bin_b">My script works under cgi-bin, but when called via mod_perl I see A 'Save-As' prompt</A>
   		<LI><A HREF="#Is_there_a_way_to_provide_a_diff">Is there a way to provide a different startup.pl file for each individual virtual host</A>
   		<LI><A HREF="#Is_there_a_way_to_modify_INC_on">Is there a way to modify @INC on a per-virtual-host or per-location basis.</A>
  -		<LI><A HREF="#Sometimes_the_script_from_one_vi">Sometimes the script from one virtual host calls a script with</A>
  +		<LI><A HREF="#A_Script_from_one_virtual_host_c">A Script from one virtual host calls a script with the same path from the other virtual host</A>
   		<LI><A HREF="#the_server_no_longer_retrieves_t">the server no longer retrieves the DirectoryIndex files for a directory</A>
   	</UL>
   
   	<LI><A HREF="#Configuration_Security_Concerns">Configuration Security Concerns</A>
   	<LI><A HREF="#Logical_grouping_of_Location_Di">Logical grouping of Location, Directory and FilesMatch directives</A>
  +	<LI><A HREF="#Apache_restarts_twice_on_start">Apache restarts twice on start</A>
   </UL>
   <!-- INDEX END -->
   
  @@ -8128,6 +10190,15 @@
   
   	     <HR>
   
  +	       Your corrections of either technical or grammatical
  +	       errors are very welcome. You are encouraged to help me
  +	       to improve this guide.  If you have something to
  +	       contribute please <A
  +	       HREF="help.html#This_document_s_Author"> send it
  +	       directly to me</A>.
  +
  +	       <HR>
  +
   	      <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
   <P>
   <CENTER><H1><A NAME="mod_perl_Specific_Configuration">mod_perl Specific Configuration</A></H1></CENTER>
  @@ -8238,8 +10309,8 @@
   invocation. You will want to turn this off for nph (non-parsed-headers)
   scripts. <CODE>PerlSendHeader On</CODE> means to call
   <CODE>ap_send_http_header()</CODE> after parsing your script headers. It is only meant for CGI emulation, its
  -always better to use <CODE>CGI-</CODE>header&gt; from
  -<CODE>CGI.pm</CODE> module or <CODE>$r-&amp;gt;send_http_header</CODE> directly.
  +always better to use <CODE>CGI-&amp;gt;header</CODE>
  +from <CODE>CGI.pm</CODE> module or <CODE>$r-&amp;gt;send_http_header</CODE> directly.
   
   <P>
   Remember the <STRONG>Alias</STRONG> from the section above? We must use the same
  @@ -8277,6 +10348,350 @@
   </PRE>
   <P>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<CENTER><H2><A NAME="PerlModule_and_PerlRequire_direc">PerlModule and PerlRequire directives</A></H2></CENTER>
  +<P>
  +You may load modules from the config file at server startup via:
  +
  +<P>
  +<PRE>    PerlModule Apache::DBI CGI DBD::Mysql
  +</PRE>
  +<P>
  +There is a limit of 10 <CODE>PerlModule</CODE>'s, if you need more to be loaded when the server starts, use one <CODE>PerlModule</CODE> to pull in many or write them all in a regular perl syntax and put them
  +into a startup file which can be loaded with use of the <CODE>PerlRequire</CODE> directive. 
  +
  +<P>
  +<PRE>    PerlRequire  /home/httpd/perl/lib/startup.pl
  +</PRE>
  +<P>
  +Both <CODE>PerlModule</CODE> and <CODE>PerlRequire</CODE> are implemented by <CODE>require(),</CODE> but there is a subtle change. <CODE>PerlModule</CODE> works like <CODE>use(),</CODE> expecting a module name without <CODE>.pm</CODE> extension and slashes.
  +<CODE>Apache::DBI</CODE> is OK, while <CODE>Apache/DBI.pm</CODE> is not. <CODE>PerlRequire</CODE> is the opposite to <CODE>PerlModule</CODE> -- it expects a relative or full path to the module or a filename, like in
  +the example above.
  +
  +<P>
  +As with any file that's being <CODE>required()</CODE> -- it must return a <STRONG>true</STRONG>
  +value, to ensure that this happens don't forget to add <CODE>1;</CODE> at the end of such files.
  +
  +<P>
  +We must stress that all the code that is run at the server initialization
  +time is run with root priveleges if you are executing it as a root user
  +(you have to unless you choose an unpriveledged port, above 1024.
  +somethings that you might have to if you don't have a root access. Just
  +remember that you better pick a well known port like 8000 or 8080 since
  +other non-standard ports might be blocked by firewalls that protect many
  +organizations and individuals). This means that anyone who has write access
  +to a script or module that is loaded by <CODE>PerlModule</CODE> or <CODE>PerlRequire</CODE>, effectively has root access to the system. You might want to take a look
  +at the new and experimental <CODE>PerlOpmask</CODE> directive and <CODE>PERL_OPMASK_DEFAULT</CODE>
  +compile time option to try to disable some dangerous operators.
  +
  +<P>
  +<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<CENTER><H2><A NAME="Perl_Handlers">Perl*Handlers</A></H2></CENTER>
  +<P>
  +As you know Apache specifies about 11 phases of the request loop, namely in
  +that order: Post-Read-Request, URI Translation, Header Parsing, Access
  +Control, Authentication, Authorization, MIME type checking, FixUp, Response
  +(Content phase). Logging and finally Cleanup. These are the stages of a
  +request where the Apache API allows a module to step in and do something.
  +There is a dedicated PerlHandler for each of these stages. Namely:
  +
  +<P>
  +<PRE>    PerlChildInitHandler
  +    PerlPostReadRequestHandler
  +    PerlInitHandler
  +    PerlTransHandler
  +    PerlHeaderParserHandler
  +    PerlAccessHandler
  +    PerlAuthenHandler
  +    PerlAuthzHandler
  +    PerlTypeHandler
  +    PerlFixupHandler
  +    PerlHandler
  +    PerlLogHandler
  +    PerlCleanupHandler
  +    PerlChildExitHandler
  +</PRE>
  +<P>
  +The first 4 handlers cannot be used in the <CODE>&lt;Location</CODE>&gt;,
  +<CODE>&lt;Directory</CODE>&gt;, <CODE>&lt;Files</CODE>&gt; and <CODE>.htaccess</CODE> file, the main reason is all the above require a known path to the file in
  +order to bind a requested path with one or more of the identifiers above.
  +Starting from <CODE>PerlHeaderParserHandler</CODE> (5th) URI is allready being mapped to a physical pathname, thus can be used
  +to match the <CODE>&lt;Location</CODE>&gt;,
  +<CODE>&lt;Directory</CODE>&gt; or <CODE>&lt;Files</CODE>&gt; configuration section, or to look at
  +<CODE>.htaccess</CODE> file if exists at the specified directory in the translated path.
  +
  +<P>
  +The Apache documentation (or even better -- the ``Writing Apache Modules
  +with Perl and C'' book by Doug MacEachern and Lincoln Stein) will tell you
  +all about those stages and what your modules can do. By default, these
  +hooks are disabled at compile time, see the INSTALL document for
  +information on enabling these hooks.
  +
  +<P>
  +Note that by default Perl API expects a subrotine called <CODE>handler</CODE> to handle the request in the registered PerlHandler module. Thus if your
  +module implements this subrotine, you can register the handler as simple as
  +writing:
  +
  +<P>
  +<PRE>  Perl*Handler Apache::SomeModule
  +</PRE>
  +<P>
  +replace <EM>Perl*Handler</EM> with a wanted name of the handler. mod_perl will preload the specified
  +module for you. But if you decide to give the handler code a different
  +name, like <CODE>my_handler</CODE>, you must preload the module and to write explicitly the chosen name.
  +
  +<P>
  +<PRE>  PerlModule Apache::SomeModule
  +  Perl*Handler Apache::SomeModule::my_handler
  +</PRE>
  +<P>
  +Please note that the former approach will not preload the module at the
  +startup, so either explicitly preload it with <CODE>PerlModule</CODE>
  +directive, add it to the startup file or use a nice shortcut the
  +<CODE>Perl*Handler</CODE> syntax suggests:
  +
  +<P>
  +<PRE>  Perl*Handler +Apache::SomeModule
  +</PRE>
  +<P>
  +Notice the leading <CODE>+</CODE> character. It's equal to:
  +
  +<P>
  +<PRE>  PerlModule Apache::SomeModule
  +  Perl*Handler Apache::SomeModule
  +</PRE>
  +<P>
  +If a module wishes to know what handler is currently being run, it can find
  +out with the <EM>current_callback</EM> method. This method is most useful to <EM>PerlDispatchHandlers</EM> who wish to only take action for certain phases.
  +
  +<P>
  +<PRE> if($r-&gt;current_callback eq &quot;PerlLogHandler&quot;) {
  +     $r-&gt;warn(&quot;Logging request&quot;);
  + }
  +</PRE>
  +<P>
  +<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<CENTER><H1><A NAME="STACKED_HANDLERS">STACKED HANDLERS</A></H1></CENTER>
  +<P>
  +With the mod_perl stacked handlers mechanism, it is possible for more than
  +one <CODE>Perl*Handler</CODE> to be defined and run during each stage of a request.
  +
  +<P>
  +Perl*Handler directives can define any number of subroutines, e.g. (in
  +config files)
  +
  +<P>
  +<PRE> PerlTransHandler OneTrans TwoTrans RedTrans BlueTrans
  +</PRE>
  +<P>
  +With the method, <CODE>Apache-&amp;gt;push_handlers()</CODE>, callbacks can be added to the stack by scripts at runtime by mod_perl
  +scripts.
  +
  +<P>
  +<CODE>Apache-&amp;gt;push_handlers()</CODE> takes the callback hook name as its first argument and a subroutine name or
  +reference as its second. e.g.:
  +
  +<P>
  +<PRE> Apache-&gt;push_handlers(&quot;PerlLogHandler&quot;, \&amp;first_one);
  + 
  + $r-&gt;push_handlers(&quot;PerlLogHandler&quot;, sub {
  +     print STDERR &quot;__ANON__ called\n&quot;;
  +     return 0;
  + });
  +</PRE>
  +<P>
  +After each request, this stack is cleared out.
  +
  +<P>
  +All handlers will be called unless a handler returns a status other than <CODE>OK</CODE> or <CODE>DECLINED</CODE>.
  +
  +<P>
  +example uses:
  +
  +<P>
  +<CODE>CGI.pm</CODE> maintains a global object for its plain function interface. Since the
  +object is global, it does not go out of scope, DESTROY is never called.  <CODE>CGI-&amp;gt;new</CODE> can call:
  +
  +<P>
  +<PRE> Apache-&gt;push_handlers(&quot;PerlCleanupHandler&quot;, \&amp;CGI::_reset_globals);
  +</PRE>
  +<P>
  +This function will be called during the final stage of a request,
  +refreshing <CODE>CGI.pm</CODE>'s globals before the next request comes in.
  +
  +<P>
  +<CODE>Apache::DCELogin</CODE> establishes a DCE login context which must exist for the lifetime of a
  +request, so the <CODE>DCE::Login</CODE> object is stored in a global variable. Without stacked handlers, users must
  +set
  +
  +<P>
  +<PRE> PerlCleanupHandler Apache::DCELogin::purge
  +</PRE>
  +<P>
  +in the configuration files to destroy the context. This is not
  +``user-friendly''. Now, <CODE>Apache::DCELogin::handler</CODE> can call:
  +
  +<P>
  +<PRE> Apache-&gt;push_handlers(&quot;PerlCleanupHandler&quot;, \&amp;purge);
  +</PRE>
  +<P>
  +Persistent database connection modules such as <CODE>Apache::DBI</CODE> could push a <CODE>PerlCleanupHandler</CODE> handler that iterates over <CODE>%Connected</CODE>, refreshing connections or just checking that ones have not gone stale.
  +Remember, by the time we get to <CODE>PerlCleanupHandler</CODE>, the client has what it wants and has gone away, we can spend as much time
  +as we want here without slowing down response time to the client (but the
  +process is unavailable for serving new request befor the operation is
  +completed).
  +
  +<P>
  +<CODE>PerlTransHandlers</CODE> may decide, based on URI or other condition, whether or not to handle a
  +request, e.g. <CODE>Apache::MsqlProxy</CODE>. Without stacked handlers, users must configure:
  +
  +<P>
  +<PRE> PerlTransHandler Apache::MsqlProxy::translate
  + PerlHandler      Apache::MsqlProxy
  +</PRE>
  +<P>
  +<CODE>PerlHandler</CODE> is never actually invoked unless <CODE>translate()</CODE> sees the request is a proxy request (<CODE>$r-&amp;gt;proxyreq</CODE>), if it is a proxy request, <CODE>translate()</CODE> sets <CODE>$r-&amp;gt;handler(&quot;perl-script&quot;)</CODE>, only then will <CODE>PerlHandler</CODE> handle the request. Now, users do not have to specify <CODE>PerlHandler Apache::MsqlProxy</CODE>, the <CODE>translate()</CODE>
  +function can set it with <CODE>push_handlers()</CODE>.
  +
  +<P>
  +Includes, footers, headers, etc., piecing together a document, imagine (no
  +need for SSI parsing!):
  +
  +<P>
  +<PRE> PerlHandler My::Header Some::Body A::Footer
  +</PRE>
  +<P>
  +A little test:
  +
  +<P>
  +<PRE> #My.pm
  + package My;
  +</PRE>
  +<P>
  +<PRE> sub header {
  +     my $r = shift;
  +     $r-&gt;content_type(&quot;text/plain&quot;);
  +     $r-&gt;send_http_header;
  +     $r-&gt;print(&quot;header text\n&quot;);
  + }
  + sub body   { shift-&gt;print(&quot;body text\n&quot;)   }
  + sub footer { shift-&gt;print(&quot;footer text\n&quot;) }
  + 1;
  + __END__
  +</PRE>
  +<P>
  +<PRE> #in config
  + &lt;Location /foo&gt;
  + SetHandler &quot;perl-script&quot;
  + PerlHandler My::header My::body My::footer   
  + &lt;/Location&gt;
  +</PRE>
  +<P>
  +Parsing the output of another PerlHandler? this is a little more tricky,
  +but consider:
  +
  +<P>
  +<PRE> &lt;Location /foo&gt;
  +   SetHandler &quot;perl-script&quot;
  +   PerlHandler OutputParser SomeApp
  + &lt;/Location&gt;
  + 
  + &lt;Location /bar&gt;
  +   SetHandler &quot;perl-script&quot;
  +   PerlHandler OutputParser AnotherApp
  + &lt;/Location&gt;
  +</PRE>
  +<P>
  +Now, OutputParser goes first, but it <CODE>untie()'s</CODE> <CODE>*STDOUT</CODE> and re-tie()'s to its own package like so:
  +
  +<P>
  +<PRE> package OutputParser;
  +</PRE>
  +<P>
  +<PRE> sub handler {
  +     my $r = shift;
  +     untie *STDOUT;
  +     tie *STDOUT =&gt; 'OutputParser', $r;
  + }
  +  
  + sub TIEHANDLE {
  +     my($class, $r) = @_;
  +     bless { r =&gt; $r}, $class;
  + }
  + 
  + sub PRINT {
  +     my $self = shift;   
  +     for (@_) {
  +         #do whatever you want to $_
  +         $self-&gt;{r}-&gt;print($_ . &quot;[insert stuff]&quot;);
  +     }
  + }
  +</PRE>
  +<P>
  +<PRE> 1;
  + __END__
  +</PRE>
  +<P>
  +To build in this feature, configure with:
  +
  +<P>
  +<PRE> % perl Makefile.PL PERL_STACKED_HANDLERS=1 [PERL_FOO_HOOK=1,etc]
  +</PRE>
  +<P>
  +Another method <CODE>Apache-&amp;gt;can_stack_handlers</CODE> will return TRUE if mod_perl was configured with <CODE>PERL_STACKED_HANDLERS=1</CODE>, FALSE otherwise.
  +
  +<P>
  +<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<CENTER><H1><A NAME="PERL_METHOD_HANDLERS">PERL METHOD HANDLERS</A></H1></CENTER>
  +<P>
  +If a Perl*Handler is prototyped with <CODE>$$</CODE>, this handler will be invoked as method. e.g.
  +
  +<P>
  +<PRE> package My;
  + @ISA = qw(BaseClass);
  +  
  + sub handler ($$) {
  +     my($class, $r) = @_;
  +     ...;
  + }
  +  
  + package BaseClass;
  +  
  + sub method ($$) {
  +     my($class, $r) = @_;
  +     ...;
  + }
  + __END__
  +</PRE>
  +<P>
  +Configuration:
  +
  +<P>
  +<PRE> PerlHandler My
  +</PRE>
  +<P>
  +or
  +
  +<P>
  +<PRE> PerlHandler My-&gt;handler
  +</PRE>
  +<P>
  +Since the handler is invoked as a method, it may inherit from other
  +classes:
  +
  +<P>
  +<PRE> PerlHandler My-&gt;method
  +</PRE>
  +<P>
  +In this case, the <CODE>My</CODE> class inherits this method from <CODE>BaseClass</CODE>.
  +
  +<P>
  +To build in this feature, configure with:
  +
  +<P>
  +<PRE> % perl Makefile.PL PERL_METHOD_HANDLERS=1 [PERL_FOO_HOOK=1,etc]
  +</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()</CODE>'d modules and flush the <CODE>Apache::Registry</CODE> cache on server restart, add:
  @@ -8385,6 +10800,9 @@
   <EM>ENVironment</EM> variables to your scripts. you can access them in your scripts through <CODE>%ENV</CODE> (e.g. <CODE>$ENV{&quot;key&quot;}</CODE>).
   
   <P>
  +Regarding the setting of <CODE>PerlPassEnv PERL5LIB</CODE> in httpd.conf If you turn on taint checks (<CODE>PerlTaintMode On</CODE>), <CODE>$ENV{PERL5LIB}</CODE> will be ignored (unset).
  +
  +<P>
   <CODE>PerlSetVar</CODE> is very similar to <CODE>PerlSetEnv</CODE>, but you extract it with another method. In &lt;Perl&gt; sections:
   
   <P>
  @@ -8733,11 +11151,25 @@
   You can watch how have you configured the <CODE>&lt;Perl</CODE>&gt; sections through the <A HREF="././config.html#_perl_status_location">/perl-status</A> location, by choosing the <STRONG>Perl Sections</STRONG> from the menu.
   
   <P>
  -<A
  -HREF="http://www.modperl.com/book/chapters/ch8.html#Debugging_B_E_lt_PerlE_gt_Sect">http://www.modperl.com/book/chapters/ch8.html#Debugging_B_E_lt_PerlE_gt_Sect</A>
  -shows how can you dump the contents of your <CODE>&lt;Perl</CODE>&gt; sections to the error_log.
  +You can dump the configuration by <CODE>&lt;Perl</CODE>&gt; sections configuration this way:
  +
  +<P>
  +<PRE>  &lt;Perl&gt;
  +  use Apache::PerlSections();
  +  ...
  +  print STDERR Apache-&gt;PerlSections-&gt;dump();
  +  &lt;/Perl&gt;
  +</PRE>
  +<P>
  +Alternatively you can store it in a file:
   
   <P>
  +<PRE>  Apache::PerlSections-&gt;store(&quot;httpd_config.pl&quot;);
  +</PRE>
  +<P>
  +You can then <CODE>require()</CODE> that file in some other <CODE>&lt;Perl</CODE>&gt; section.
  +
  +<P>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
   <CENTER><H1><A NAME="Configuring_Apache_mod_perl_wi">Configuring Apache + mod_perl with mod_macro</A></H1></CENTER>
   <P>
  @@ -8930,8 +11362,7 @@
   
   <P>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<CENTER><H2><A NAME="Sometimes_the_script_from_one_vi">Sometimes the script from one virtual host calls a script with
  -the same path from the second virtual host</A></H2></CENTER>
  +<CENTER><H2><A NAME="A_Script_from_one_virtual_host_c">A Script from one virtual host calls a script with the same path from the other virtual host</A></H2></CENTER>
   <P>
   This has been a bug before, last fixed in 1.15_01, i.e. if you are running
   1.15, that could be the problem. You should set this variable in a startup
  @@ -8945,7 +11376,8 @@
   script running for more than one Virtual host on the same machine, this can
   be a waste, right? Set it to 0 in a startup script if you want to turn it
   off and have this bug as a feature. (Only makes sense if you are sure that
  -there will be no <STRONG>other</STRONG>scripts named by the same path/name)
  +there will be no <STRONG>other</STRONG>scripts named by the same path/name). It also saves you some memory on the
  +way.
   
   <P>
   <PRE>  $Apache::Registry::NameWithVirtualHost = 0;
  @@ -9014,6 +11446,19 @@
   <P>
   Note that you cannot have <CODE>Files</CODE> derective inside <CODE>Location</CODE>, but you can have <CODE>Files</CODE> inside <CODE>Directory</CODE>.
   
  +<P>
  +<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<CENTER><H1><A NAME="Apache_restarts_twice_on_start">Apache restarts twice on start</A></H1></CENTER>
  +<P>
  +When the server is restarted. the configuration and module initialization
  +phases are called again (twice in total). To ensure that the future restart
  +will workout correctly, Apache actually runs these two phases twice during
  +server startup, to check that all modules can survive a restart.
  +
  +<P>
  +(META: And add an example that writes to the log file - I was restarted 1,
  +2 times)
  +
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
   	     The <a href="http://www.modperl.com/">
   	     <B>Writing Apache Modules with Perl and C</B></a>
  @@ -9024,6 +11469,16 @@
   	     Amazon.com</a>.
   
   	     <HR>
  +
  +	     Your corrections of either technical or grammatical
  +	     errors are very welcome. You are encouraged to help me
  +	     to improve this guide.  If you have something to
  +	     contribute please <A
  +	     HREF="help.html#This_document_s_Author"> send it
  +	     directly to me</A>.
  +
  +	     <HR>
  +
   	     [    <A HREF="install.html">Prev</A> |      <A HREF="index.html">Main Page</A> | <A HREF="frequent.html">Next</A>      ]
   
   <CENTER><TABLE CELLSPACING=2 CELLPADDING=2 WIDTH="100%" >
  @@ -9037,7 +11492,7 @@
       <B>
         <FONT SIZE=-1>
   	     Written by <A HREF="help.html#This_document_s_Author">Stas Bekman</A>.
  -	     <BR>Last Modified at 08/15/1999
  +	     <BR>Last Modified at 09/26/1999
         </FONT>
       </B>
     </TD>
  @@ -9107,6 +11562,15 @@
   
   	     <HR>
   
  +	       Your corrections of either technical or grammatical
  +	       errors are very welcome. You are encouraged to help me
  +	       to improve this guide.  If you have something to
  +	       contribute please <A
  +	       HREF="help.html#This_document_s_Author"> send it
  +	       directly to me</A>.
  +
  +	       <HR>
  +
   	      <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>
  @@ -9142,6 +11606,16 @@
   	     Amazon.com</a>.
   
   	     <HR>
  +
  +	     Your corrections of either technical or grammatical
  +	     errors are very welcome. You are encouraged to help me
  +	     to improve this guide.  If you have something to
  +	     contribute please <A
  +	     HREF="help.html#This_document_s_Author"> send it
  +	     directly to me</A>.
  +
  +	     <HR>
  +
   	     [    <A HREF="config.html">Prev</A> |      <A HREF="index.html">Main Page</A> | <A HREF="control.html">Next</A>      ]
   
   <CENTER><TABLE CELLSPACING=2 CELLPADDING=2 WIDTH="100%" >
  @@ -9232,6 +11706,15 @@
   
   	     <HR>
   
  +	       Your corrections of either technical or grammatical
  +	       errors are very welcome. You are encouraged to help me
  +	       to improve this guide.  If you have something to
  +	       contribute please <A
  +	       HREF="help.html#This_document_s_Author"> send it
  +	       directly to me</A>.
  +
  +	       <HR>
  +
   	      <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>
  @@ -10131,6 +12614,16 @@
   	     Amazon.com</a>.
   
   	     <HR>
  +
  +	     Your corrections of either technical or grammatical
  +	     errors are very welcome. You are encouraged to help me
  +	     to improve this guide.  If you have something to
  +	     contribute please <A
  +	     HREF="help.html#This_document_s_Author"> send it
  +	     directly to me</A>.
  +
  +	     <HR>
  +
   	     [    <A HREF="frequent.html">Prev</A> |      <A HREF="index.html">Main Page</A> | <A HREF="obvious.html">Next</A>      ]
   
   <CENTER><TABLE CELLSPACING=2 CELLPADDING=2 WIDTH="100%" >
  @@ -10228,6 +12721,15 @@
   
   	     <HR>
   
  +	       Your corrections of either technical or grammatical
  +	       errors are very welcome. You are encouraged to help me
  +	       to improve this guide.  If you have something to
  +	       contribute please <A
  +	       HREF="help.html#This_document_s_Author"> send it
  +	       directly to me</A>.
  +
  +	       <HR>
  +
   	      <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>
  @@ -10584,6 +13086,17 @@
   
   <P>
   Also note that since the server is running in single mode, if the output
  +returns HTML with <CODE>&lt;IMG</CODE>&gt; tags, then the load of these will take a lot of time. 
  +
  +<P>
  +When you use Netscape client while your server is running in single-process
  +mode, if the output returns a HTML with <CODE>&lt;IMG</CODE>&gt; tags, then the load of these will take a lot of time, since the <CODE>KeepAlive</CODE>
  +feature gets in the way. Netscape tries to open multiple connections and
  +keep them open. Because there is only one server process listening, each
  +connection has to time-out before the next succeeds. Turn off <CODE>KeepAlive</CODE> in <CODE>httpd.conf</CODE> to avoid this effect.
  +
  +<P>
  +Also note that since the server is running in single mode, if the output
   returns HTML with <CODE>&lt;IMG</CODE>&gt; tags, then the load of these will take a lot of time. If you use
   Netscape while your server is running in single-process mode, HTTP's <CODE>KeepAlive</CODE> feature gets in the way. Netscape tries to open multiple connections and
   keep them open. Because there is only one server process listening, each
  @@ -10862,6 +13375,16 @@
   	     Amazon.com</a>.
   
   	     <HR>
  +
  +	     Your corrections of either technical or grammatical
  +	     errors are very welcome. You are encouraged to help me
  +	     to improve this guide.  If you have something to
  +	     contribute please <A
  +	     HREF="help.html#This_document_s_Author"> send it
  +	     directly to me</A>.
  +
  +	     <HR>
  +
   	     [    <A HREF="control.html">Prev</A> |      <A HREF="index.html">Main Page</A> | <A HREF="warnings.html">Next</A>      ]
   
   <CENTER><TABLE CELLSPACING=2 CELLPADDING=2 WIDTH="100%" >
  @@ -10875,7 +13398,7 @@
       <B>
         <FONT SIZE=-1>
   	     Written by <A HREF="help.html#This_document_s_Author">Stas Bekman</A>.
  -	     <BR>Last Modified at 08/07/1999
  +	     <BR>Last Modified at 09/26/1999
         </FONT>
       </B>
     </TD>
  @@ -10946,6 +13469,7 @@
   	<LI><A HREF="#RegistryLoader_Cannot_translate">RegistryLoader: Cannot translate the URI /home/httpd/perl/test.pl</A>
   	<LI><A HREF="#Evil_things_might_happen_when_us">Evil things might happen when using PerlFreshRestart</A>
   	<LI><A HREF="#server_reached_MaxClients_settin">server reached MaxClients setting, consider raising the MaxClients setting</A>
  +	<LI><A HREF="#syntax_error_at_dev_null_line_1">syntax error at /dev/null line 1, near &quot;line arguments:&quot;</A>
   </UL>
   <!-- INDEX END -->
   
  @@ -10961,6 +13485,15 @@
   
   	     <HR>
   
  +	       Your corrections of either technical or grammatical
  +	       errors are very welcome. You are encouraged to help me
  +	       to improve this guide.  If you have something to
  +	       contribute please <A
  +	       HREF="help.html#This_document_s_Author"> send it
  +	       directly to me</A>.
  +
  +	       <HR>
  +
   	      <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
   <P>
   <CENTER><H1><A NAME="General_Advice">General Advice</A></H1></CENTER>
  @@ -11286,8 +13819,8 @@
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
   <CENTER><H1><A NAME="Evil_things_might_happen_when_us">Evil things might happen when using PerlFreshRestart</A></H1></CENTER>
   <P>
  -Not all Perl modules can survive a reload. PerlFreshRestart does not much
  -more than:
  +Unfortunately, not all perl modules are robust enough to survive reload,
  +for them, unusual situation. PerlFreshRestart does not much more than:
   
   <P>
   <PRE>  while (my($k,$v) = each %INC) {
  @@ -11309,6 +13842,20 @@
   <P>
   See <A HREF="././performance.html#Choosing_MaxClients">Choosing MaxClients</A>.
   
  +<P>
  +<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<CENTER><H1><A NAME="syntax_error_at_dev_null_line_1">syntax error at /dev/null line 1, near &quot;line arguments:&quot;</A></H1></CENTER>
  +<P>
  +<PRE>  syntax error at /dev/null line 1, near &quot;line arguments:&quot;
  +  Execution of /dev/null aborted due to compilation errors.
  +  parse: Undefined error: 0
  +</PRE>
  +<P>
  +There is a chance that your <CODE>/dev/null</CODE> device is broken. Try:
  +
  +<P>
  +<PRE>  % sudo echo &gt; /dev/null
  +</PRE>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
   	     The <a href="http://www.modperl.com/">
   	     <B>Writing Apache Modules with Perl and C</B></a>
  @@ -11319,6 +13866,16 @@
   	     Amazon.com</a>.
   
   	     <HR>
  +
  +	     Your corrections of either technical or grammatical
  +	     errors are very welcome. You are encouraged to help me
  +	     to improve this guide.  If you have something to
  +	     contribute please <A
  +	     HREF="help.html#This_document_s_Author"> send it
  +	     directly to me</A>.
  +
  +	     <HR>
  +
   	     [    <A HREF="obvious.html">Prev</A> |      <A HREF="index.html">Main Page</A> | <A HREF="security.html">Next</A>      ]
   
   <CENTER><TABLE CELLSPACING=2 CELLPADDING=2 WIDTH="100%" >
  @@ -11332,7 +13889,7 @@
       <B>
         <FONT SIZE=-1>
   	     Written by <A HREF="help.html#This_document_s_Author">Stas Bekman</A>.
  -	     <BR>Last Modified at 07/09/1999
  +	     <BR>Last Modified at 09/26/1999
         </FONT>
       </B>
     </TD>
  @@ -11394,7 +13951,8 @@
   	<LI><A HREF="#Authentication_code_snippets">Authentication code snippets</A>
   	<UL>
   
  -		<LI><A HREF="#Forcing_reauthenticating">Forcing reauthenticating</A>
  +		<LI><A HREF="#Forcing_re_authentication">Forcing re-authentication</A>
  +		<LI><A HREF="#OK_AUTH_REQUIRED_and_FORBIDDEN_">OK, AUTH_REQUIRED.and FORBIDDEN in Authentication handlers</A>
   	</UL>
   
   </UL>
  @@ -11412,6 +13970,15 @@
   
   	     <HR>
   
  +	       Your corrections of either technical or grammatical
  +	       errors are very welcome. You are encouraged to help me
  +	       to improve this guide.  If you have something to
  +	       contribute please <A
  +	       HREF="help.html#This_document_s_Author"> send it
  +	       directly to me</A>.
  +
  +	       <HR>
  +
   	      <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
   <P>
   <CENTER><H1><A NAME="An_Importance_of_Your_site_s_Sec">An Importance of Your site's Security</A></H1></CENTER>
  @@ -11586,22 +14153,77 @@
   <CENTER><H1><A NAME="Authentication_code_snippets">Authentication code snippets</A></H1></CENTER>
   <P>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<CENTER><H2><A NAME="Forcing_reauthenticating">Forcing reauthenticating</A></H2></CENTER>
  +<CENTER><H2><A NAME="Forcing_re_authentication">Forcing re-authentication</A></H2></CENTER>
   <P>
   To force authenticated user to reauthenticate just send the following
   header to the browser:
   
   <P>
  -<PRE>  HTTP/1.0 401 Unauthorized
  +<PRE>  WWW-Authenticate: Basic realm=&quot;My Realm&quot;
  +  HTTP/1.0 401 Unauthorized
   </PRE>
   <P>
  -This will pop-up (on Netscape at least) a window saying that the
  +This will pop-up (in Netscape at least) a window saying that the
   <STRONG>Authorization Failed.  Retry?</STRONG> And an <STRONG>OK</STRONG> and a <STRONG>Cancel</STRONG> buttons. When that window pops up you know that the password has been
   cleared. If the user hits the <STRONG>Cancel</STRONG> button the username will also be cleared, and you can have a page that will
   be output written after the header if this is a CGI (or PHP, or anything
   else like that). If the user hits the <STRONG>OK</STRONG> button, the authentication window will be brought up again with their
   previous username already in the username field.
   
  +<P>
  +In Perl API you would use <CODE>note_basic_auth_failure()</CODE> method to
  +force reauthentication.
  +
  +<P>
  +Since the browser's behaviour is in no way guaranteed, it also may not
  +work, and that should be noted.
  +
  +<P>
  +<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<CENTER><H2><A NAME="OK_AUTH_REQUIRED_and_FORBIDDEN_">OK, AUTH_REQUIRED.and FORBIDDEN in Authentication handlers</A></H2></CENTER>
  +<P>
  +When your authentication handler returns OK, it means that user has
  +correctly authenticated and now <CODE>$r-&amp;gt;connection-&amp;gt;user</CODE> will have the username set for all the subsequent requests. For
  +<CODE>Apache::Registry</CODE> and friends, where the environment variables setting weren't turned off, an
  +equivalent <CODE>$ENV{REMOTE_USER}</CODE>
  +variable will be available. Password is available only through Perl API
  +with help of <CODE>get_basic_auth_pw()</CODE> method.
  +
  +<P>
  +If there is a failure, returned <CODE>AUTH_REQUIRED</CODE> flag will tell the browser to pop up an authentication window, to try
  +again, unless it's a first time. For example:
  +
  +<P>
  +<PRE>   my($status, $sent_pw) = $r-&gt;get_basic_auth_pw;
  +   unless($r-&gt;connection-&gt;user and $sent_pw) {
  +       $r-&gt;note_basic_auth_failure;
  +       $r-&gt;log_reason(&quot;Both a username and password must be provided&quot;);
  +       return AUTH_REQUIRED;
  +   }
  +</PRE>
  +<P>
  +Let's say that you have a mod_perl authen handler, where user credentials
  +are checked against a database, and it either returns
  +<CODE>OK</CODE> or <CODE>AUTH_REQUIRED</CODE>. One of the possible authentication failure case might happen when the
  +username/password are correct, but the user's account has been suspended
  +temporarily.
  +
  +<P>
  +If this is the case you would like to make the user aware of this, through
  +a page display instead of having the browser pop up the auth dialog again.
  +At the same time you need to refuse the authentication, of course.
  +
  +<P>
  +The solution is to return <CODE>FORBIDDEN</CODE>, but before that you should set a custom error page for this specific
  +handler, with help of
  +<CODE>$r-&amp;gt;custom_response</CODE>. Something like:
  +
  +<P>
  +<PRE>  use Apache::Constants qw(:common);
  +  $r-&gt;custom_response(SERVER_ERROR, &quot;/errors/suspended_account.html&quot;);
  +   
  +  return FORBIDDEN if $suspended;
  +</PRE>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
   	     The <a href="http://www.modperl.com/">
   	     <B>Writing Apache Modules with Perl and C</B></a>
  @@ -11612,6 +14234,16 @@
   	     Amazon.com</a>.
   
   	     <HR>
  +
  +	     Your corrections of either technical or grammatical
  +	     errors are very welcome. You are encouraged to help me
  +	     to improve this guide.  If you have something to
  +	     contribute please <A
  +	     HREF="help.html#This_document_s_Author"> send it
  +	     directly to me</A>.
  +
  +	     <HR>
  +
   	     [    <A HREF="warnings.html">Prev</A> |      <A HREF="index.html">Main Page</A> | <A HREF="databases.html">Next</A>      ]
   
   <CENTER><TABLE CELLSPACING=2 CELLPADDING=2 WIDTH="100%" >
  @@ -11625,7 +14257,7 @@
       <B>
         <FONT SIZE=-1>
   	     Written by <A HREF="help.html#This_document_s_Author">Stas Bekman</A>.
  -	     <BR>Last Modified at 07/29/1999
  +	     <BR>Last Modified at 09/25/1999
         </FONT>
       </B>
     </TD>
  @@ -11721,6 +14353,15 @@
   
   	     <HR>
   
  +	       Your corrections of either technical or grammatical
  +	       errors are very welcome. You are encouraged to help me
  +	       to improve this guide.  If you have something to
  +	       contribute please <A
  +	       HREF="help.html#This_document_s_Author"> send it
  +	       directly to me</A>.
  +
  +	       <HR>
  +
   	      <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
   <P>
   <CENTER><H1><A NAME="Why_Relational_SQL_Databases">Why Relational (SQL) Databases</A></H1></CENTER>
  @@ -12832,6 +15473,16 @@
   	     Amazon.com</a>.
   
   	     <HR>
  +
  +	     Your corrections of either technical or grammatical
  +	     errors are very welcome. You are encouraged to help me
  +	     to improve this guide.  If you have something to
  +	     contribute please <A
  +	     HREF="help.html#This_document_s_Author"> send it
  +	     directly to me</A>.
  +
  +	     <HR>
  +
   	     [    <A HREF="security.html">Prev</A> |      <A HREF="index.html">Main Page</A> | <A HREF="dbm.html">Next</A>      ]
   
   <CENTER><TABLE CELLSPACING=2 CELLPADDING=2 WIDTH="100%" >
  @@ -12917,6 +15568,15 @@
   
   	     <HR>
   
  +	       Your corrections of either technical or grammatical
  +	       errors are very welcome. You are encouraged to help me
  +	       to improve this guide.  If you have something to
  +	       contribute please <A
  +	       HREF="help.html#This_document_s_Author"> send it
  +	       directly to me</A>.
  +
  +	       <HR>
  +
   	      <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
   <P>
   <CENTER><H1><A NAME="Where_and_Why_to_use_dbm_files">Where and Why to use dbm files</A></H1></CENTER>
  @@ -13115,7 +15775,7 @@
     
     BEGIN {
         # RCS/CVS complient:  must be all one line, for MakeMaker
  -    $DB_File::Wrap::VERSION = do { my @r = (q$Revision: 1.16 $ =~ /\d+/g); sprintf &quot;%d.&quot;.&quot;%02d&quot; x $#r, @r };
  +    $DB_File::Wrap::VERSION = do { my @r = (q$Revision: 1.17 $ =~ /\d+/g); sprintf &quot;%d.&quot;.&quot;%02d&quot; x $#r, @r };
     
     }
     
  @@ -13265,7 +15925,8 @@
   A simple tie, READ lock and untie
   
   <P>
  -<PRE>  my %mydb = ();
  +<PRE>  my $dbfile = &quot;/tmp/test&quot;;
  +  my %mydb = ();
     my $db = new DB_File::Wrap \%mydb, $dbfile, 'read';
     print $mydb{'stas'} if exists $mydb{'stas'};
       # sync and untie
  @@ -13292,7 +15953,8 @@
   Perform both, read and write operations:
   
   <P>
  -<PRE>  my %mydb = ();
  +<PRE>  my $dbfile = &quot;/tmp/test&quot;;
  +  my %mydb = ();
     my $db = new DB_File::Wrap \%mydb, $dbfile;
     print $mydb{'stas'} if exists $mydb{'stas'};
     
  @@ -13322,6 +15984,16 @@
   	     Amazon.com</a>.
   
   	     <HR>
  +
  +	     Your corrections of either technical or grammatical
  +	     errors are very welcome. You are encouraged to help me
  +	     to improve this guide.  If you have something to
  +	     contribute please <A
  +	     HREF="help.html#This_document_s_Author"> send it
  +	     directly to me</A>.
  +
  +	     <HR>
  +
   	     [    <A HREF="databases.html">Prev</A> |      <A HREF="index.html">Main Page</A> | <A HREF="multiuser.html">Next</A>      ]
   
   <CENTER><TABLE CELLSPACING=2 CELLPADDING=2 WIDTH="100%" >
  @@ -13335,7 +16007,7 @@
       <B>
         <FONT SIZE=-1>
   	     Written by <A HREF="help.html#This_document_s_Author">Stas Bekman</A>.
  -	     <BR>Last Modified at 07/09/1999
  +	     <BR>Last Modified at 09/25/1999
         </FONT>
       </B>
     </TD>
  @@ -13404,6 +16076,15 @@
   
   	     <HR>
   
  +	       Your corrections of either technical or grammatical
  +	       errors are very welcome. You are encouraged to help me
  +	       to improve this guide.  If you have something to
  +	       contribute please <A
  +	       HREF="help.html#This_document_s_Author"> send it
  +	       directly to me</A>.
  +
  +	       <HR>
  +
   	      <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
   <P>
   <CENTER><H1><A NAME="ISPs_providing_mod_perl_services">ISPs providing mod_perl services - a fantasy or reality.</A></H1></CENTER>
  @@ -13440,6 +16121,14 @@
   user (guest books, counters and etc - the same standard scripts ISPs
   providing since they were born). So you have to say <STRONG>NO</STRONG> for this choice.
   
  +<P>
  +More things to think about are file permissions (any user who is allowed to
  +write and run CGI script, can at least read if not write any other files
  +that has a permissions of the web server. This has nothing to do with
  +mod_perl, and there are solutions for that
  +<CODE>suEXEC</CODE> and <CODE>cgiwrap</CODE> for example) and <CODE>Apache::DBI</CODE> connections (You can pick a connection from the pool of cached
  +connenctions, opened by someone else by hacking the <CODE>Apache::DBI</CODE> code).
  +
   <P><LI>
   <P>
   But, hey why I cannot let my user to run his own server, so I clean my
  @@ -13568,7 +16257,7 @@
   
   
   <P>
  -<A HREF="././config.html#Sometimes_the_script_from_one_vi">Sometimes the script from one virtual host calls a script with the same path from the second virtual host</A>
  +<A HREF="././config.html#A_Script_from_one_virtual_host_c">Sometimes the script from one virtual host calls a script with the same path from the second virtual host</A>
   
   
   
  @@ -13582,6 +16271,16 @@
   	     Amazon.com</a>.
   
   	     <HR>
  +
  +	     Your corrections of either technical or grammatical
  +	     errors are very welcome. You are encouraged to help me
  +	     to improve this guide.  If you have something to
  +	     contribute please <A
  +	     HREF="help.html#This_document_s_Author"> send it
  +	     directly to me</A>.
  +
  +	     <HR>
  +
   	     [    <A HREF="dbm.html">Prev</A> |      <A HREF="index.html">Main Page</A> | <A HREF="status.html">Next</A>      ]
   
   <CENTER><TABLE CELLSPACING=2 CELLPADDING=2 WIDTH="100%" >
  @@ -13595,7 +16294,7 @@
       <B>
         <FONT SIZE=-1>
   	     Written by <A HREF="help.html#This_document_s_Author">Stas Bekman</A>.
  -	     <BR>Last Modified at 07/09/1999
  +	     <BR>Last Modified at 09/26/1999
         </FONT>
       </B>
     </TD>
  @@ -13670,6 +16369,15 @@
   
   	     <HR>
   
  +	       Your corrections of either technical or grammatical
  +	       errors are very welcome. You are encouraged to help me
  +	       to improve this guide.  If you have something to
  +	       contribute please <A
  +	       HREF="help.html#This_document_s_Author"> send it
  +	       directly to me</A>.
  +
  +	       <HR>
  +
   	      <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>
  @@ -13768,6 +16476,16 @@
   	     Amazon.com</a>.
   
   	     <HR>
  +
  +	     Your corrections of either technical or grammatical
  +	     errors are very welcome. You are encouraged to help me
  +	     to improve this guide.  If you have something to
  +	     contribute please <A
  +	     HREF="help.html#This_document_s_Author"> send it
  +	     directly to me</A>.
  +
  +	     <HR>
  +
   	     [    <A HREF="multiuser.html">Prev</A> |      <A HREF="index.html">Main Page</A> | <A HREF="debug.html">Next</A>      ]
   
   <CENTER><TABLE CELLSPACING=2 CELLPADDING=2 WIDTH="100%" >
  @@ -13841,6 +16559,8 @@
   	<LI><A HREF="#gdb_says_there_are_no_debugging_">gdb says there are no debugging symbols</A>
   	<LI><A HREF="#Monitoring_error_log_file">Monitoring error_log file</A>
   	<LI><A HREF="#Debugging_Signal_Handlers_SIG_">Debugging Signal Handlers ($SIG{FOO})</A>
  +	<LI><A HREF="#Spinning_httpds">Spinning httpds</A>
  +	<LI><A HREF="#PROFILING">PROFILING</A>
   	<LI><A HREF="#examples_of_strace_or_truss_us">examples of strace (or truss) usage</A>
   	<LI><A HREF="#Devel_Peek">Devel::Peek</A>
   </UL>
  @@ -13858,6 +16578,15 @@
   
   	     <HR>
   
  +	       Your corrections of either technical or grammatical
  +	       errors are very welcome. You are encouraged to help me
  +	       to improve this guide.  If you have something to
  +	       contribute please <A
  +	       HREF="help.html#This_document_s_Author"> send it
  +	       directly to me</A>.
  +
  +	       <HR>
  +
   	      <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 does not</A></H1></CENTER>
  @@ -14023,7 +16752,7 @@
   <P>
   Current perl implementation does not restore the original apache's C
   handler when you use <CODE>local $SIG{FOO}</CODE> clause. While save/restore of
  -<CODE>$SIG{ALRM}</CODE> was fixed in the mod_perl 1.19_01 (CVS version) other signals are not yet
  +<CODE>$SIG{ALRM}</CODE> was fixed in the mod_perl 1.19_01 (CVS version), other signals are not yet
   fixed. The real fix should probably be in Perl itself.
   
   <P>
  @@ -14059,6 +16788,9 @@
     die $@ if $@;
   </PRE>
   <P>
  +If a timeout happens and <CODE>SIGALRM</CODE> is thrown, the <CODE>alarm()</CODE> will be reset, otherwise <CODE>alarm 0</CODE> is reached and timer is being reset as well.
  +
  +<P>
   Now you would write:
   
   <P>
  @@ -14073,6 +16805,49 @@
   </PRE>
   <P>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<CENTER><H1><A NAME="Spinning_httpds">Spinning httpds</A></H1></CENTER>
  +<P>
  +To see where an httpd is ``spinning'', try adding this to your script or a
  +startup file:
  +
  +<P>
  +<PRE>  use Carp ();
  +  $SIG{'USR1'} = sub { 
  +     Carp::confess(&quot;caught SIGUSR1!&quot;);
  +  };
  +</PRE>
  +<P>
  +Then issue the command line:
  +
  +<P>
  +<PRE>  kill -USR1 &lt;spinning_httpd_pid&gt;
  +</PRE>
  +<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>
  +It is possible to profile code run under mod_perl with the
  +<CODE>Devel::DProf</CODE> module available on CPAN. However, you must have apache version 1.3b3 or
  +higher and the <CODE>PerlChildExitHandler</CODE>
  +enabled. When the server is started, <CODE>Devel::DProf</CODE> installs an
  +<CODE>END</CODE> block to write the <CODE>tmon.out</CODE> file, which will be run when the server is shutdown. Here's how to start
  +and stop a server with the profiler enabled:
  +
  +<P>
  +<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>
  +See also: <CODE>Apache::DProf</CODE>
  +
  +
  +
  +<P>
  +<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
   <CENTER><H1><A NAME="examples_of_strace_or_truss_us">examples of strace (or truss) usage</A></H1></CENTER>
   <P>
   (META: below are some snippets of strace outputs from list's emails)
  @@ -14174,6 +16949,16 @@
   	     Amazon.com</a>.
   
   	     <HR>
  +
  +	     Your corrections of either technical or grammatical
  +	     errors are very welcome. You are encouraged to help me
  +	     to improve this guide.  If you have something to
  +	     contribute please <A
  +	     HREF="help.html#This_document_s_Author"> send it
  +	     directly to me</A>.
  +
  +	     <HR>
  +
   	     [    <A HREF="status.html">Prev</A> |      <A HREF="index.html">Main Page</A> | <A HREF="browserbugs.html">Next</A>      ]
   
   <CENTER><TABLE CELLSPACING=2 CELLPADDING=2 WIDTH="100%" >
  @@ -14187,7 +16972,7 @@
       <B>
         <FONT SIZE=-1>
   	     Written by <A HREF="help.html#This_document_s_Author">Stas Bekman</A>.
  -	     <BR>Last Modified at 08/17/1999
  +	     <BR>Last Modified at 09/22/1999
         </FONT>
       </B>
     </TD>
  @@ -14256,6 +17041,15 @@
   
   	     <HR>
   
  +	       Your corrections of either technical or grammatical
  +	       errors are very welcome. You are encouraged to help me
  +	       to improve this guide.  If you have something to
  +	       contribute please <A
  +	       HREF="help.html#This_document_s_Author"> send it
  +	       directly to me</A>.
  +
  +	       <HR>
  +
   	      <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
   <P>
   <CENTER><H1><A NAME="Preventing_QUERY_STRING_from_get">Preventing QUERY_STRING from getting corrupted because of &amp;entity key names.</A></H1></CENTER>
  @@ -14295,6 +17089,16 @@
   	     Amazon.com</a>.
   
   	     <HR>
  +
  +	     Your corrections of either technical or grammatical
  +	     errors are very welcome. You are encouraged to help me
  +	     to improve this guide.  If you have something to
  +	     contribute please <A
  +	     HREF="help.html#This_document_s_Author"> send it
  +	     directly to me</A>.
  +
  +	     <HR>
  +
   	     [    <A HREF="debug.html">Prev</A> |      <A HREF="index.html">Main Page</A> | <A HREF="modules.html">Next</A>      ]
   
   <CENTER><TABLE CELLSPACING=2 CELLPADDING=2 WIDTH="100%" >
  @@ -14383,6 +17187,15 @@
   
   	     <HR>
   
  +	       Your corrections of either technical or grammatical
  +	       errors are very welcome. You are encouraged to help me
  +	       to improve this guide.  If you have something to
  +	       contribute please <A
  +	       HREF="help.html#This_document_s_Author"> send it
  +	       directly to me</A>.
  +
  +	       <HR>
  +
   	      <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
   <P>
   <CENTER><H1><A NAME="Apache_Session_Maintain_sessi">Apache::Session - Maintain session state across HTTP requests</A></H1></CENTER>
  @@ -14646,6 +17459,16 @@
   	     Amazon.com</a>.
   
   	     <HR>
  +
  +	     Your corrections of either technical or grammatical
  +	     errors are very welcome. You are encouraged to help me
  +	     to improve this guide.  If you have something to
  +	     contribute please <A
  +	     HREF="help.html#This_document_s_Author"> send it
  +	     directly to me</A>.
  +
  +	     <HR>
  +
   	     [    <A HREF="browserbugs.html">Prev</A> |      <A HREF="index.html">Main Page</A> | <A HREF="perl.html">Next</A>      ]
   
   <CENTER><TABLE CELLSPACING=2 CELLPADDING=2 WIDTH="100%" >
  @@ -14737,6 +17560,15 @@
   
   	     <HR>
   
  +	       Your corrections of either technical or grammatical
  +	       errors are very welcome. You are encouraged to help me
  +	       to improve this guide.  If you have something to
  +	       contribute please <A
  +	       HREF="help.html#This_document_s_Author"> send it
  +	       directly to me</A>.
  +
  +	       <HR>
  +
   	      <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>
  @@ -15025,6 +17857,16 @@
   	     Amazon.com</a>.
   
   	     <HR>
  +
  +	     Your corrections of either technical or grammatical
  +	     errors are very welcome. You are encouraged to help me
  +	     to improve this guide.  If you have something to
  +	     contribute please <A
  +	     HREF="help.html#This_document_s_Author"> send it
  +	     directly to me</A>.
  +
  +	     <HR>
  +
   	     [    <A HREF="modules.html">Prev</A> |      <A HREF="index.html">Main Page</A> | <A HREF="snippets.html">Next</A>      ]
   
   <CENTER><TABLE CELLSPACING=2 CELLPADDING=2 WIDTH="100%" >
  @@ -15090,8 +17932,6 @@
   <P><B><FONT SIZE=-1>Table of Contents:</FONT></B></P>
   <UL>
   
  -	<LI><A HREF="#Sending_MIME_headers">Sending MIME headers</A>
  -	<LI><A HREF="#How_to_avoid_printing_the_header">How to avoid printing the header more than once</A>
   	<LI><A HREF="#More_on_relative_paths">More on relative paths</A>
   	<LI><A HREF="#Watching_the_error_log_file_with">Watching the error_log file without telneting to the server</A>
   	<LI><A HREF="#Accessing_variables_from_the_cal">Accessing variables from the caller's package</A>
  @@ -15110,49 +17950,18 @@
   	     Amazon.com</a>.
   
   	     <HR>
  -
  -	      <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<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 the config file: 
  -
  -<P>
  -<PRE>  PerlSendHeader On
  -</PRE>
  -<P>
  -The safest bet is to use CGI.pm's <CODE>header()</CODE> method. (If you do <CODE>print header();</CODE>, you don't need the above setting.)
   
  -<P>
  -Also there is <CODE>$ENV{PERL_SEND_HEADER}</CODE> to see if <CODE>PerlSendHeader</CODE> is <CODE>On</CODE> or
  -<CODE>Off</CODE>.
  -
  -<P>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<CENTER><H1><A NAME="How_to_avoid_printing_the_header">How to avoid printing the header more than once</A></H1></CENTER>
  -<P>
  -I'm sure you have been in situations where you wish you knew whether the
  -MIME header has already been printed. Since if it is printed again it will
  -cause an ugly ``Content-type: ...'' string to show up in the browser. So
  -how do we solve it? With the help of a closure.
  +	       Your corrections of either technical or grammatical
  +	       errors are very welcome. You are encouraged to help me
  +	       to improve this guide.  If you have something to
  +	       contribute please <A
  +	       HREF="help.html#This_document_s_Author"> send it
  +	       directly to me</A>.
   
  -<P>
  -Just copy the code below, including the block's curly parentheses. And
  -everywhere in your code you print the header use the <CODE>print_header()</CODE> sub.
  -<CODE>$need_header</CODE> is the same kind of beast as a static variable in C, so it remembers its
  -value from call to call.
  +	       <HR>
   
  +	      <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
   <P>
  -<PRE>  {
  -    my $need_header = 1;
  -    sub print_header {
  -      print header(@_),$need_header = 0 if $need_header;
  -    }
  -  }
  -</PRE>
  -<P>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
   <CENTER><H1><A NAME="More_on_relative_paths">More on relative paths</A></H1></CENTER>
   <P>
   Many people use relative paths for <CODE>require</CODE>, <CODE>use</CODE>, etc., or open files in the current directory or relative to the current
  @@ -15348,6 +18157,16 @@
   	     Amazon.com</a>.
   
   	     <HR>
  +
  +	     Your corrections of either technical or grammatical
  +	     errors are very welcome. You are encouraged to help me
  +	     to improve this guide.  If you have something to
  +	     contribute please <A
  +	     HREF="help.html#This_document_s_Author"> send it
  +	     directly to me</A>.
  +
  +	     <HR>
  +
   	     [    <A HREF="perl.html">Prev</A> |      <A HREF="index.html">Main Page</A> | <A HREF="hardware.html">Next</A>      ]
   
   <CENTER><TABLE CELLSPACING=2 CELLPADDING=2 WIDTH="100%" >
  @@ -15361,7 +18180,7 @@
       <B>
         <FONT SIZE=-1>
   	     Written by <A HREF="help.html#This_document_s_Author">Stas Bekman</A>.
  -	     <BR>Last Modified at 08/17/1999
  +	     <BR>Last Modified at 09/25/1999
         </FONT>
       </B>
     </TD>
  @@ -15453,6 +18272,15 @@
   
   	     <HR>
   
  +	       Your corrections of either technical or grammatical
  +	       errors are very welcome. You are encouraged to help me
  +	       to improve this guide.  If you have something to
  +	       contribute please <A
  +	       HREF="help.html#This_document_s_Author"> send it
  +	       directly to me</A>.
  +
  +	       <HR>
  +
   	      <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
   <P>
   <CENTER><H1><A NAME="Is_it_important_">Is it important?</A></H1></CENTER>
  @@ -15847,6 +18675,16 @@
   	     Amazon.com</a>.
   
   	     <HR>
  +
  +	     Your corrections of either technical or grammatical
  +	     errors are very welcome. You are encouraged to help me
  +	     to improve this guide.  If you have something to
  +	     contribute please <A
  +	     HREF="help.html#This_document_s_Author"> send it
  +	     directly to me</A>.
  +
  +	     <HR>
  +
   	     [    <A HREF="snippets.html">Prev</A> |      <A HREF="index.html">Main Page</A> | <A HREF="advocacy.html">Next</A>      ]
   
   <CENTER><TABLE CELLSPACING=2 CELLPADDING=2 WIDTH="100%" >
  @@ -15929,6 +18767,15 @@
   
   	     <HR>
   
  +	       Your corrections of either technical or grammatical
  +	       errors are very welcome. You are encouraged to help me
  +	       to improve this guide.  If you have something to
  +	       contribute please <A
  +	       HREF="help.html#This_document_s_Author"> send it
  +	       directly to me</A>.
  +
  +	       <HR>
  +
   	      <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
   <P>
   <CENTER><H1><A NAME="Thoughts_about_scalability_and_f">Thoughts about scalability and flexibility</A></H1></CENTER>
  @@ -16005,6 +18852,16 @@
   	     Amazon.com</a>.
   
   	     <HR>
  +
  +	     Your corrections of either technical or grammatical
  +	     errors are very welcome. You are encouraged to help me
  +	     to improve this guide.  If you have something to
  +	     contribute please <A
  +	     HREF="help.html#This_document_s_Author"> send it
  +	     directly to me</A>.
  +
  +	     <HR>
  +
   	     [    <A HREF="hardware.html">Prev</A> |      <A HREF="index.html">Main Page</A> | <A HREF="help.html">Next</A>      ]
   
   <CENTER><TABLE CELLSPACING=2 CELLPADDING=2 WIDTH="100%" >
  @@ -16093,6 +18950,15 @@
   
   	     <HR>
   
  +	       Your corrections of either technical or grammatical
  +	       errors are very welcome. You are encouraged to help me
  +	       to improve this guide.  If you have something to
  +	       contribute please <A
  +	       HREF="help.html#This_document_s_Author"> send it
  +	       directly to me</A>.
  +
  +	       <HR>
  +
   	      <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
   <P>
   <CENTER><H1><A NAME="READ_ME_FIRST">READ ME FIRST</A></H1></CENTER>
  @@ -16125,8 +18991,11 @@
   However, you are welcome to submit corrections and suggestions directly to
   me at <A
   HREF="mailto:sbekman@iname.com?subject=mod_perl%20guide%20corrections.">sbekman@iname.com?subject=mod_perl%20guide%20corrections.</A>
  - <STRONG>But PLEASE
  -NO QUESTIONS, they will be immediately deleted.</STRONG>
  +If you are going to <STRONG>submit heavy corrections of the text</STRONG> (I love those!), please help me by downloading the source pages in POD
  +(from the main age under the index) and directly editing them. I will use
  +Emacs Ediff to perform an easy merge of your changes. Thank you!  <STRONG>But PLEASE NO
  +PERSONAL QUESTIONS, I didn't invite those by writing a guide. They all
  +will be immediately deleted.</STRONG>
   
   
   
  @@ -16215,11 +19084,47 @@
   HREF="http://forum.swarthmore.edu/epigone/modperl">http://forum.swarthmore.edu/epigone/modperl</A>
   . We owe it to Ken Williams.
   
  +<P>
  +More archives available:
  +
  +<UL>
  +<P><LI>
   <P>
  -Another arhive: <A
  +<A
   HREF="http://www.geocrawler.com/lists/3/web/182/0/">http://www.geocrawler.com/lists/3/web/182/0/</A>
   
   
  +<P><LI>
  +<P>
  +<A
  +HREF="http://www.bitmechanic.com/mail-archives/modperl/">http://www.bitmechanic.com/mail-archives/modperl/</A>
  +
  +
  +<P><LI>
  +<P>
  +<A
  +HREF="http://www.mail-archive.com/modperl%40apache.org/">http://www.mail-archive.com/modperl%40apache.org/</A>
  +
  +
  +<P><LI>
  +<P>
  +<A
  +HREF="http://www.davin.ottawa.on.ca/archive/modperl/">http://www.davin.ottawa.on.ca/archive/modperl/</A>
  +
  +
  +<P><LI>
  +<P>
  +<A
  +HREF="http://www.progressive-comp.com/Lists/?l=apache-modperl&r=1&w=2#apache-modperl">http://www.progressive-comp.com/Lists/?l=apache-modperl&r=1&w=2#apache-modperl</A>
  +
  +
  +<P><LI>
  +<P>
  +<A
  +HREF="http://www.egroups.com/group/modperl/">http://www.egroups.com/group/modperl/</A>
  +
  +
  +</UL>
   </DL>
   <P>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  @@ -16311,6 +19216,12 @@
   HREF="http://www.apache.org/docs/handler.html">http://www.apache.org/docs/handler.html</A>
   
   
  +<P><LI><STRONG><A NAME="item_mod_rewrite">mod_rewrite Guide</A></STRONG>
  +<P>
  +<A
  +HREF="http://www.engelschall.com/pw/apache/rewriteguide/">http://www.engelschall.com/pw/apache/rewriteguide/</A>
  +
  +
   </UL>
   <P>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  @@ -16319,7 +19230,7 @@
   <P><LI><STRONG><A NAME="item_Perl">Perl DBI examples</A></STRONG>
   <P>
   <A
  -HREF="http://eskimo.tamu.edu/~jbaker/dbi-examples.html">http://eskimo.tamu.edu/~jbaker/dbi-examples.html</A>
  +HREF="http://www.saturn5.com/~jwb/dbi-examples.html">http://www.saturn5.com/~jwb/dbi-examples.html</A>
   (by Jeffrey William Baker).
   
   <P><LI><STRONG><A NAME="item_DBI">DBI at Hermetica</A></STRONG>
  @@ -16382,6 +19293,16 @@
   	     Amazon.com</a>.
   
   	     <HR>
  +
  +	     Your corrections of either technical or grammatical
  +	     errors are very welcome. You are encouraged to help me
  +	     to improve this guide.  If you have something to
  +	     contribute please <A
  +	     HREF="help.html#This_document_s_Author"> send it
  +	     directly to me</A>.
  +
  +	     <HR>
  +
   	     [    <A HREF="advocacy.html">Prev</A> |      <A HREF="index.html">Main Page</A> | <A HREF="download.html">Next</A>      ]
   
   <CENTER><TABLE CELLSPACING=2 CELLPADDING=2 WIDTH="100%" >
  @@ -16395,7 +19316,7 @@
       <B>
         <FONT SIZE=-1>
   	     Written by <A HREF="help.html#This_document_s_Author">Stas Bekman</A>.
  -	     <BR>Last Modified at 07/29/1999
  +	     <BR>Last Modified at 09/25/1999
         </FONT>
       </B>
     </TD>
  @@ -16473,6 +19394,15 @@
   
   	     <HR>
   
  +	       Your corrections of either technical or grammatical
  +	       errors are very welcome. You are encouraged to help me
  +	       to improve this guide.  If you have something to
  +	       contribute please <A
  +	       HREF="help.html#This_document_s_Author"> send it
  +	       directly to me</A>.
  +
  +	       <HR>
  +
   	      <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>
  @@ -16580,6 +19510,16 @@
   	     Amazon.com</a>.
   
   	     <HR>
  +
  +	     Your corrections of either technical or grammatical
  +	     errors are very welcome. You are encouraged to help me
  +	     to improve this guide.  If you have something to
  +	     contribute please <A
  +	     HREF="help.html#This_document_s_Author"> send it
  +	     directly to me</A>.
  +
  +	     <HR>
  +
   	     [    <A HREF="help.html">Prev</A> |      <A HREF="index.html">Main Page</A> ]
   
   <CENTER><TABLE CELLSPACING=2 CELLPADDING=2 WIDTH="100%" >
  
  
  
  1.5       +19 -0     modperl-site/guide/browserbugs.html
  
  Index: browserbugs.html
  ===================================================================
  RCS file: /export/home/cvs/modperl-site/guide/browserbugs.html,v
  retrieving revision 1.4
  retrieving revision 1.5
  diff -u -r1.4 -r1.5
  --- browserbugs.html	1999/08/17 19:03:34	1.4
  +++ browserbugs.html	1999/09/25 23:13:52	1.5
  @@ -43,6 +43,15 @@
   
   	     <HR>
   
  +	       Your corrections of either technical or grammatical
  +	       errors are very welcome. You are encouraged to help me
  +	       to improve this guide.  If you have something to
  +	       contribute please <A
  +	       HREF="help.html#This_document_s_Author"> send it
  +	       directly to me</A>.
  +
  +	       <HR>
  +
   	      <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
   <P>
   <CENTER><H1><A NAME="Preventing_QUERY_STRING_from_get">Preventing QUERY_STRING from getting corrupted because of &amp;entity key names.</A></H1></CENTER>
  @@ -82,6 +91,16 @@
   	     Amazon.com</a>.
   
   	     <HR>
  +
  +	     Your corrections of either technical or grammatical
  +	     errors are very welcome. You are encouraged to help me
  +	     to improve this guide.  If you have something to
  +	     contribute please <A
  +	     HREF="help.html#This_document_s_Author"> send it
  +	     directly to me</A>.
  +
  +	     <HR>
  +
   	     [    <A HREF="debug.html">Prev</A> |      <A HREF="index.html">Main Page</A> | <A HREF="modules.html">Next</A>      ]
   
   <CENTER><TABLE CELLSPACING=2 CELLPADDING=2 WIDTH="100%" >
  
  
  
  1.18      +412 -10   modperl-site/guide/config.html
  
  Index: config.html
  ===================================================================
  RCS file: /export/home/cvs/modperl-site/guide/config.html,v
  retrieving revision 1.17
  retrieving revision 1.18
  diff -u -r1.17 -r1.18
  --- config.html	1999/08/17 19:03:34	1.17
  +++ config.html	1999/09/25 23:13:52	1.18
  @@ -31,6 +31,14 @@
   
   		<LI><A HREF="#Alias_Configurations">Alias Configurations</A>
   		<LI><A HREF="#Location_Configuration">Location Configuration</A>
  +		<LI><A HREF="#PerlModule_and_PerlRequire_direc">PerlModule and PerlRequire directives</A>
  +		<LI><A HREF="#Perl_Handlers">Perl*Handlers</A>
  +	</UL>
  +
  +	<LI><A HREF="#STACKED_HANDLERS">STACKED HANDLERS</A>
  +	<LI><A HREF="#PERL_METHOD_HANDLERS">PERL METHOD HANDLERS</A>
  +	<UL>
  +
   		<LI><A HREF="#PerlFreshRestart">PerlFreshRestart</A>
   		<LI><A HREF="#_perl_status_location">/perl-status location</A>
   		<UL>
  @@ -65,12 +73,13 @@
   		<LI><A HREF="#My_script_works_under_cgi_bin_b">My script works under cgi-bin, but when called via mod_perl I see A 'Save-As' prompt</A>
   		<LI><A HREF="#Is_there_a_way_to_provide_a_diff">Is there a way to provide a different startup.pl file for each individual virtual host</A>
   		<LI><A HREF="#Is_there_a_way_to_modify_INC_on">Is there a way to modify @INC on a per-virtual-host or per-location basis.</A>
  -		<LI><A HREF="#Sometimes_the_script_from_one_vi">Sometimes the script from one virtual host calls a script with</A>
  +		<LI><A HREF="#A_Script_from_one_virtual_host_c">A Script from one virtual host calls a script with the same path from the other virtual host</A>
   		<LI><A HREF="#the_server_no_longer_retrieves_t">the server no longer retrieves the DirectoryIndex files for a directory</A>
   	</UL>
   
   	<LI><A HREF="#Configuration_Security_Concerns">Configuration Security Concerns</A>
   	<LI><A HREF="#Logical_grouping_of_Location_Di">Logical grouping of Location, Directory and FilesMatch directives</A>
  +	<LI><A HREF="#Apache_restarts_twice_on_start">Apache restarts twice on start</A>
   </UL>
   <!-- INDEX END -->
   
  @@ -86,6 +95,15 @@
   
   	     <HR>
   
  +	       Your corrections of either technical or grammatical
  +	       errors are very welcome. You are encouraged to help me
  +	       to improve this guide.  If you have something to
  +	       contribute please <A
  +	       HREF="help.html#This_document_s_Author"> send it
  +	       directly to me</A>.
  +
  +	       <HR>
  +
   	      <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
   <P>
   <CENTER><H1><A NAME="mod_perl_Specific_Configuration">mod_perl Specific Configuration</A></H1></CENTER>
  @@ -196,8 +214,8 @@
   invocation. You will want to turn this off for nph (non-parsed-headers)
   scripts. <CODE>PerlSendHeader On</CODE> means to call
   <CODE>ap_send_http_header()</CODE> after parsing your script headers. It is only meant for CGI emulation, its
  -always better to use <CODE>CGI-</CODE>header&gt; from
  -<CODE>CGI.pm</CODE> module or <CODE>$r-&amp;gt;send_http_header</CODE> directly.
  +always better to use <CODE>CGI-&amp;gt;header</CODE>
  +from <CODE>CGI.pm</CODE> module or <CODE>$r-&amp;gt;send_http_header</CODE> directly.
   
   <P>
   Remember the <STRONG>Alias</STRONG> from the section above? We must use the same
  @@ -235,6 +253,350 @@
   </PRE>
   <P>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<CENTER><H2><A NAME="PerlModule_and_PerlRequire_direc">PerlModule and PerlRequire directives</A></H2></CENTER>
  +<P>
  +You may load modules from the config file at server startup via:
  +
  +<P>
  +<PRE>    PerlModule Apache::DBI CGI DBD::Mysql
  +</PRE>
  +<P>
  +There is a limit of 10 <CODE>PerlModule</CODE>'s, if you need more to be loaded when the server starts, use one <CODE>PerlModule</CODE> to pull in many or write them all in a regular perl syntax and put them
  +into a startup file which can be loaded with use of the <CODE>PerlRequire</CODE> directive. 
  +
  +<P>
  +<PRE>    PerlRequire  /home/httpd/perl/lib/startup.pl
  +</PRE>
  +<P>
  +Both <CODE>PerlModule</CODE> and <CODE>PerlRequire</CODE> are implemented by <CODE>require(),</CODE> but there is a subtle change. <CODE>PerlModule</CODE> works like <CODE>use(),</CODE> expecting a module name without <CODE>.pm</CODE> extension and slashes.
  +<CODE>Apache::DBI</CODE> is OK, while <CODE>Apache/DBI.pm</CODE> is not. <CODE>PerlRequire</CODE> is the opposite to <CODE>PerlModule</CODE> -- it expects a relative or full path to the module or a filename, like in
  +the example above.
  +
  +<P>
  +As with any file that's being <CODE>required()</CODE> -- it must return a <STRONG>true</STRONG>
  +value, to ensure that this happens don't forget to add <CODE>1;</CODE> at the end of such files.
  +
  +<P>
  +We must stress that all the code that is run at the server initialization
  +time is run with root priveleges if you are executing it as a root user
  +(you have to unless you choose an unpriveledged port, above 1024.
  +somethings that you might have to if you don't have a root access. Just
  +remember that you better pick a well known port like 8000 or 8080 since
  +other non-standard ports might be blocked by firewalls that protect many
  +organizations and individuals). This means that anyone who has write access
  +to a script or module that is loaded by <CODE>PerlModule</CODE> or <CODE>PerlRequire</CODE>, effectively has root access to the system. You might want to take a look
  +at the new and experimental <CODE>PerlOpmask</CODE> directive and <CODE>PERL_OPMASK_DEFAULT</CODE>
  +compile time option to try to disable some dangerous operators.
  +
  +<P>
  +<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<CENTER><H2><A NAME="Perl_Handlers">Perl*Handlers</A></H2></CENTER>
  +<P>
  +As you know Apache specifies about 11 phases of the request loop, namely in
  +that order: Post-Read-Request, URI Translation, Header Parsing, Access
  +Control, Authentication, Authorization, MIME type checking, FixUp, Response
  +(Content phase). Logging and finally Cleanup. These are the stages of a
  +request where the Apache API allows a module to step in and do something.
  +There is a dedicated PerlHandler for each of these stages. Namely:
  +
  +<P>
  +<PRE>    PerlChildInitHandler
  +    PerlPostReadRequestHandler
  +    PerlInitHandler
  +    PerlTransHandler
  +    PerlHeaderParserHandler
  +    PerlAccessHandler
  +    PerlAuthenHandler
  +    PerlAuthzHandler
  +    PerlTypeHandler
  +    PerlFixupHandler
  +    PerlHandler
  +    PerlLogHandler
  +    PerlCleanupHandler
  +    PerlChildExitHandler
  +</PRE>
  +<P>
  +The first 4 handlers cannot be used in the <CODE>&lt;Location</CODE>&gt;,
  +<CODE>&lt;Directory</CODE>&gt;, <CODE>&lt;Files</CODE>&gt; and <CODE>.htaccess</CODE> file, the main reason is all the above require a known path to the file in
  +order to bind a requested path with one or more of the identifiers above.
  +Starting from <CODE>PerlHeaderParserHandler</CODE> (5th) URI is allready being mapped to a physical pathname, thus can be used
  +to match the <CODE>&lt;Location</CODE>&gt;,
  +<CODE>&lt;Directory</CODE>&gt; or <CODE>&lt;Files</CODE>&gt; configuration section, or to look at
  +<CODE>.htaccess</CODE> file if exists at the specified directory in the translated path.
  +
  +<P>
  +The Apache documentation (or even better -- the ``Writing Apache Modules
  +with Perl and C'' book by Doug MacEachern and Lincoln Stein) will tell you
  +all about those stages and what your modules can do. By default, these
  +hooks are disabled at compile time, see the INSTALL document for
  +information on enabling these hooks.
  +
  +<P>
  +Note that by default Perl API expects a subrotine called <CODE>handler</CODE> to handle the request in the registered PerlHandler module. Thus if your
  +module implements this subrotine, you can register the handler as simple as
  +writing:
  +
  +<P>
  +<PRE>  Perl*Handler Apache::SomeModule
  +</PRE>
  +<P>
  +replace <EM>Perl*Handler</EM> with a wanted name of the handler. mod_perl will preload the specified
  +module for you. But if you decide to give the handler code a different
  +name, like <CODE>my_handler</CODE>, you must preload the module and to write explicitly the chosen name.
  +
  +<P>
  +<PRE>  PerlModule Apache::SomeModule
  +  Perl*Handler Apache::SomeModule::my_handler
  +</PRE>
  +<P>
  +Please note that the former approach will not preload the module at the
  +startup, so either explicitly preload it with <CODE>PerlModule</CODE>
  +directive, add it to the startup file or use a nice shortcut the
  +<CODE>Perl*Handler</CODE> syntax suggests:
  +
  +<P>
  +<PRE>  Perl*Handler +Apache::SomeModule
  +</PRE>
  +<P>
  +Notice the leading <CODE>+</CODE> character. It's equal to:
  +
  +<P>
  +<PRE>  PerlModule Apache::SomeModule
  +  Perl*Handler Apache::SomeModule
  +</PRE>
  +<P>
  +If a module wishes to know what handler is currently being run, it can find
  +out with the <EM>current_callback</EM> method. This method is most useful to <EM>PerlDispatchHandlers</EM> who wish to only take action for certain phases.
  +
  +<P>
  +<PRE> if($r-&gt;current_callback eq &quot;PerlLogHandler&quot;) {
  +     $r-&gt;warn(&quot;Logging request&quot;);
  + }
  +</PRE>
  +<P>
  +<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<CENTER><H1><A NAME="STACKED_HANDLERS">STACKED HANDLERS</A></H1></CENTER>
  +<P>
  +With the mod_perl stacked handlers mechanism, it is possible for more than
  +one <CODE>Perl*Handler</CODE> to be defined and run during each stage of a request.
  +
  +<P>
  +Perl*Handler directives can define any number of subroutines, e.g. (in
  +config files)
  +
  +<P>
  +<PRE> PerlTransHandler OneTrans TwoTrans RedTrans BlueTrans
  +</PRE>
  +<P>
  +With the method, <CODE>Apache-&amp;gt;push_handlers()</CODE>, callbacks can be added to the stack by scripts at runtime by mod_perl
  +scripts.
  +
  +<P>
  +<CODE>Apache-&amp;gt;push_handlers()</CODE> takes the callback hook name as its first argument and a subroutine name or
  +reference as its second. e.g.:
  +
  +<P>
  +<PRE> Apache-&gt;push_handlers(&quot;PerlLogHandler&quot;, \&amp;first_one);
  + 
  + $r-&gt;push_handlers(&quot;PerlLogHandler&quot;, sub {
  +     print STDERR &quot;__ANON__ called\n&quot;;
  +     return 0;
  + });
  +</PRE>
  +<P>
  +After each request, this stack is cleared out.
  +
  +<P>
  +All handlers will be called unless a handler returns a status other than <CODE>OK</CODE> or <CODE>DECLINED</CODE>.
  +
  +<P>
  +example uses:
  +
  +<P>
  +<CODE>CGI.pm</CODE> maintains a global object for its plain function interface. Since the
  +object is global, it does not go out of scope, DESTROY is never called.  <CODE>CGI-&amp;gt;new</CODE> can call:
  +
  +<P>
  +<PRE> Apache-&gt;push_handlers(&quot;PerlCleanupHandler&quot;, \&amp;CGI::_reset_globals);
  +</PRE>
  +<P>
  +This function will be called during the final stage of a request,
  +refreshing <CODE>CGI.pm</CODE>'s globals before the next request comes in.
  +
  +<P>
  +<CODE>Apache::DCELogin</CODE> establishes a DCE login context which must exist for the lifetime of a
  +request, so the <CODE>DCE::Login</CODE> object is stored in a global variable. Without stacked handlers, users must
  +set
  +
  +<P>
  +<PRE> PerlCleanupHandler Apache::DCELogin::purge
  +</PRE>
  +<P>
  +in the configuration files to destroy the context. This is not
  +``user-friendly''. Now, <CODE>Apache::DCELogin::handler</CODE> can call:
  +
  +<P>
  +<PRE> Apache-&gt;push_handlers(&quot;PerlCleanupHandler&quot;, \&amp;purge);
  +</PRE>
  +<P>
  +Persistent database connection modules such as <CODE>Apache::DBI</CODE> could push a <CODE>PerlCleanupHandler</CODE> handler that iterates over <CODE>%Connected</CODE>, refreshing connections or just checking that ones have not gone stale.
  +Remember, by the time we get to <CODE>PerlCleanupHandler</CODE>, the client has what it wants and has gone away, we can spend as much time
  +as we want here without slowing down response time to the client (but the
  +process is unavailable for serving new request befor the operation is
  +completed).
  +
  +<P>
  +<CODE>PerlTransHandlers</CODE> may decide, based on URI or other condition, whether or not to handle a
  +request, e.g. <CODE>Apache::MsqlProxy</CODE>. Without stacked handlers, users must configure:
  +
  +<P>
  +<PRE> PerlTransHandler Apache::MsqlProxy::translate
  + PerlHandler      Apache::MsqlProxy
  +</PRE>
  +<P>
  +<CODE>PerlHandler</CODE> is never actually invoked unless <CODE>translate()</CODE> sees the request is a proxy request (<CODE>$r-&amp;gt;proxyreq</CODE>), if it is a proxy request, <CODE>translate()</CODE> sets <CODE>$r-&amp;gt;handler(&quot;perl-script&quot;)</CODE>, only then will <CODE>PerlHandler</CODE> handle the request. Now, users do not have to specify <CODE>PerlHandler Apache::MsqlProxy</CODE>, the <CODE>translate()</CODE>
  +function can set it with <CODE>push_handlers()</CODE>.
  +
  +<P>
  +Includes, footers, headers, etc., piecing together a document, imagine (no
  +need for SSI parsing!):
  +
  +<P>
  +<PRE> PerlHandler My::Header Some::Body A::Footer
  +</PRE>
  +<P>
  +A little test:
  +
  +<P>
  +<PRE> #My.pm
  + package My;
  +</PRE>
  +<P>
  +<PRE> sub header {
  +     my $r = shift;
  +     $r-&gt;content_type(&quot;text/plain&quot;);
  +     $r-&gt;send_http_header;
  +     $r-&gt;print(&quot;header text\n&quot;);
  + }
  + sub body   { shift-&gt;print(&quot;body text\n&quot;)   }
  + sub footer { shift-&gt;print(&quot;footer text\n&quot;) }
  + 1;
  + __END__
  +</PRE>
  +<P>
  +<PRE> #in config
  + &lt;Location /foo&gt;
  + SetHandler &quot;perl-script&quot;
  + PerlHandler My::header My::body My::footer   
  + &lt;/Location&gt;
  +</PRE>
  +<P>
  +Parsing the output of another PerlHandler? this is a little more tricky,
  +but consider:
  +
  +<P>
  +<PRE> &lt;Location /foo&gt;
  +   SetHandler &quot;perl-script&quot;
  +   PerlHandler OutputParser SomeApp
  + &lt;/Location&gt;
  + 
  + &lt;Location /bar&gt;
  +   SetHandler &quot;perl-script&quot;
  +   PerlHandler OutputParser AnotherApp
  + &lt;/Location&gt;
  +</PRE>
  +<P>
  +Now, OutputParser goes first, but it <CODE>untie()'s</CODE> <CODE>*STDOUT</CODE> and re-tie()'s to its own package like so:
  +
  +<P>
  +<PRE> package OutputParser;
  +</PRE>
  +<P>
  +<PRE> sub handler {
  +     my $r = shift;
  +     untie *STDOUT;
  +     tie *STDOUT =&gt; 'OutputParser', $r;
  + }
  +  
  + sub TIEHANDLE {
  +     my($class, $r) = @_;
  +     bless { r =&gt; $r}, $class;
  + }
  + 
  + sub PRINT {
  +     my $self = shift;   
  +     for (@_) {
  +         #do whatever you want to $_
  +         $self-&gt;{r}-&gt;print($_ . &quot;[insert stuff]&quot;);
  +     }
  + }
  +</PRE>
  +<P>
  +<PRE> 1;
  + __END__
  +</PRE>
  +<P>
  +To build in this feature, configure with:
  +
  +<P>
  +<PRE> % perl Makefile.PL PERL_STACKED_HANDLERS=1 [PERL_FOO_HOOK=1,etc]
  +</PRE>
  +<P>
  +Another method <CODE>Apache-&amp;gt;can_stack_handlers</CODE> will return TRUE if mod_perl was configured with <CODE>PERL_STACKED_HANDLERS=1</CODE>, FALSE otherwise.
  +
  +<P>
  +<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<CENTER><H1><A NAME="PERL_METHOD_HANDLERS">PERL METHOD HANDLERS</A></H1></CENTER>
  +<P>
  +If a Perl*Handler is prototyped with <CODE>$$</CODE>, this handler will be invoked as method. e.g.
  +
  +<P>
  +<PRE> package My;
  + @ISA = qw(BaseClass);
  +  
  + sub handler ($$) {
  +     my($class, $r) = @_;
  +     ...;
  + }
  +  
  + package BaseClass;
  +  
  + sub method ($$) {
  +     my($class, $r) = @_;
  +     ...;
  + }
  + __END__
  +</PRE>
  +<P>
  +Configuration:
  +
  +<P>
  +<PRE> PerlHandler My
  +</PRE>
  +<P>
  +or
  +
  +<P>
  +<PRE> PerlHandler My-&gt;handler
  +</PRE>
  +<P>
  +Since the handler is invoked as a method, it may inherit from other
  +classes:
  +
  +<P>
  +<PRE> PerlHandler My-&gt;method
  +</PRE>
  +<P>
  +In this case, the <CODE>My</CODE> class inherits this method from <CODE>BaseClass</CODE>.
  +
  +<P>
  +To build in this feature, configure with:
  +
  +<P>
  +<PRE> % perl Makefile.PL PERL_METHOD_HANDLERS=1 [PERL_FOO_HOOK=1,etc]
  +</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()</CODE>'d modules and flush the <CODE>Apache::Registry</CODE> cache on server restart, add:
  @@ -343,6 +705,9 @@
   <EM>ENVironment</EM> variables to your scripts. you can access them in your scripts through <CODE>%ENV</CODE> (e.g. <CODE>$ENV{&quot;key&quot;}</CODE>).
   
   <P>
  +Regarding the setting of <CODE>PerlPassEnv PERL5LIB</CODE> in httpd.conf If you turn on taint checks (<CODE>PerlTaintMode On</CODE>), <CODE>$ENV{PERL5LIB}</CODE> will be ignored (unset).
  +
  +<P>
   <CODE>PerlSetVar</CODE> is very similar to <CODE>PerlSetEnv</CODE>, but you extract it with another method. In &lt;Perl&gt; sections:
   
   <P>
  @@ -690,10 +1055,24 @@
   <P>
   You can watch how have you configured the <CODE>&lt;Perl</CODE>&gt; sections through the <A HREF="././config.html#_perl_status_location">/perl-status</A> location, by choosing the <STRONG>Perl Sections</STRONG> from the menu.
   
  +<P>
  +You can dump the configuration by <CODE>&lt;Perl</CODE>&gt; sections configuration this way:
  +
  +<P>
  +<PRE>  &lt;Perl&gt;
  +  use Apache::PerlSections();
  +  ...
  +  print STDERR Apache-&gt;PerlSections-&gt;dump();
  +  &lt;/Perl&gt;
  +</PRE>
  +<P>
  +Alternatively you can store it in a file:
  +
  +<P>
  +<PRE>  Apache::PerlSections-&gt;store(&quot;httpd_config.pl&quot;);
  +</PRE>
   <P>
  -<A
  -HREF="http://www.modperl.com/book/chapters/ch8.html#Debugging_B_E_lt_PerlE_gt_Sect">http://www.modperl.com/book/chapters/ch8.html#Debugging_B_E_lt_PerlE_gt_Sect</A>
  -shows how can you dump the contents of your <CODE>&lt;Perl</CODE>&gt; sections to the error_log.
  +You can then <CODE>require()</CODE> that file in some other <CODE>&lt;Perl</CODE>&gt; section.
   
   <P>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  @@ -888,8 +1267,7 @@
   
   <P>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<CENTER><H2><A NAME="Sometimes_the_script_from_one_vi">Sometimes the script from one virtual host calls a script with
  -the same path from the second virtual host</A></H2></CENTER>
  +<CENTER><H2><A NAME="A_Script_from_one_virtual_host_c">A Script from one virtual host calls a script with the same path from the other virtual host</A></H2></CENTER>
   <P>
   This has been a bug before, last fixed in 1.15_01, i.e. if you are running
   1.15, that could be the problem. You should set this variable in a startup
  @@ -903,7 +1281,8 @@
   script running for more than one Virtual host on the same machine, this can
   be a waste, right? Set it to 0 in a startup script if you want to turn it
   off and have this bug as a feature. (Only makes sense if you are sure that
  -there will be no <STRONG>other</STRONG>scripts named by the same path/name)
  +there will be no <STRONG>other</STRONG>scripts named by the same path/name). It also saves you some memory on the
  +way.
   
   <P>
   <PRE>  $Apache::Registry::NameWithVirtualHost = 0;
  @@ -972,7 +1351,20 @@
   <P>
   Note that you cannot have <CODE>Files</CODE> derective inside <CODE>Location</CODE>, but you can have <CODE>Files</CODE> inside <CODE>Directory</CODE>.
   
  +<P>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<CENTER><H1><A NAME="Apache_restarts_twice_on_start">Apache restarts twice on start</A></H1></CENTER>
  +<P>
  +When the server is restarted. the configuration and module initialization
  +phases are called again (twice in total). To ensure that the future restart
  +will workout correctly, Apache actually runs these two phases twice during
  +server startup, to check that all modules can survive a restart.
  +
  +<P>
  +(META: And add an example that writes to the log file - I was restarted 1,
  +2 times)
  +
  +<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
   	     The <a href="http://www.modperl.com/">
   	     <B>Writing Apache Modules with Perl and C</B></a>
   	     book can be purchased online from <a
  @@ -982,6 +1374,16 @@
   	     Amazon.com</a>.
   
   	     <HR>
  +
  +	     Your corrections of either technical or grammatical
  +	     errors are very welcome. You are encouraged to help me
  +	     to improve this guide.  If you have something to
  +	     contribute please <A
  +	     HREF="help.html#This_document_s_Author"> send it
  +	     directly to me</A>.
  +
  +	     <HR>
  +
   	     [    <A HREF="install.html">Prev</A> |      <A HREF="index.html">Main Page</A> | <A HREF="frequent.html">Next</A>      ]
   
   <CENTER><TABLE CELLSPACING=2 CELLPADDING=2 WIDTH="100%" >
  @@ -995,7 +1397,7 @@
       <B>
         <FONT SIZE=-1>
   	     Written by <A HREF="help.html#This_document_s_Author">Stas Bekman</A>.
  -	     <BR>Last Modified at 08/15/1999
  +	     <BR>Last Modified at 09/26/1999
         </FONT>
       </B>
     </TD>
  
  
  
  1.18      +19 -0     modperl-site/guide/control.html
  
  Index: control.html
  ===================================================================
  RCS file: /export/home/cvs/modperl-site/guide/control.html,v
  retrieving revision 1.17
  retrieving revision 1.18
  diff -u -r1.17 -r1.18
  --- control.html	1999/08/17 19:03:34	1.17
  +++ control.html	1999/09/25 23:13:53	1.18
  @@ -51,6 +51,15 @@
   
   	     <HR>
   
  +	       Your corrections of either technical or grammatical
  +	       errors are very welcome. You are encouraged to help me
  +	       to improve this guide.  If you have something to
  +	       contribute please <A
  +	       HREF="help.html#This_document_s_Author"> send it
  +	       directly to me</A>.
  +
  +	       <HR>
  +
   	      <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>
  @@ -950,6 +959,16 @@
   	     Amazon.com</a>.
   
   	     <HR>
  +
  +	     Your corrections of either technical or grammatical
  +	     errors are very welcome. You are encouraged to help me
  +	     to improve this guide.  If you have something to
  +	     contribute please <A
  +	     HREF="help.html#This_document_s_Author"> send it
  +	     directly to me</A>.
  +
  +	     <HR>
  +
   	     [    <A HREF="frequent.html">Prev</A> |      <A HREF="index.html">Main Page</A> | <A HREF="obvious.html">Next</A>      ]
   
   <CENTER><TABLE CELLSPACING=2 CELLPADDING=2 WIDTH="100%" >
  
  
  
  1.7       +19 -0     modperl-site/guide/databases.html
  
  Index: databases.html
  ===================================================================
  RCS file: /export/home/cvs/modperl-site/guide/databases.html,v
  retrieving revision 1.6
  retrieving revision 1.7
  diff -u -r1.6 -r1.7
  --- databases.html	1999/08/17 19:03:35	1.6
  +++ databases.html	1999/09/25 23:13:53	1.7
  @@ -70,6 +70,15 @@
   
   	     <HR>
   
  +	       Your corrections of either technical or grammatical
  +	       errors are very welcome. You are encouraged to help me
  +	       to improve this guide.  If you have something to
  +	       contribute please <A
  +	       HREF="help.html#This_document_s_Author"> send it
  +	       directly to me</A>.
  +
  +	       <HR>
  +
   	      <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
   <P>
   <CENTER><H1><A NAME="Why_Relational_SQL_Databases">Why Relational (SQL) Databases</A></H1></CENTER>
  @@ -1181,6 +1190,16 @@
   	     Amazon.com</a>.
   
   	     <HR>
  +
  +	     Your corrections of either technical or grammatical
  +	     errors are very welcome. You are encouraged to help me
  +	     to improve this guide.  If you have something to
  +	     contribute please <A
  +	     HREF="help.html#This_document_s_Author"> send it
  +	     directly to me</A>.
  +
  +	     <HR>
  +
   	     [    <A HREF="security.html">Prev</A> |      <A HREF="index.html">Main Page</A> | <A HREF="dbm.html">Next</A>      ]
   
   <CENTER><TABLE CELLSPACING=2 CELLPADDING=2 WIDTH="100%" >
  
  
  
  1.7       +24 -3     modperl-site/guide/dbm.html
  
  Index: dbm.html
  ===================================================================
  RCS file: /export/home/cvs/modperl-site/guide/dbm.html,v
  retrieving revision 1.6
  retrieving revision 1.7
  diff -u -r1.6 -r1.7
  --- dbm.html	1999/08/17 19:03:35	1.6
  +++ dbm.html	1999/09/25 23:13:54	1.7
  @@ -46,6 +46,15 @@
   
   	     <HR>
   
  +	       Your corrections of either technical or grammatical
  +	       errors are very welcome. You are encouraged to help me
  +	       to improve this guide.  If you have something to
  +	       contribute please <A
  +	       HREF="help.html#This_document_s_Author"> send it
  +	       directly to me</A>.
  +
  +	       <HR>
  +
   	      <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
   <P>
   <CENTER><H1><A NAME="Where_and_Why_to_use_dbm_files">Where and Why to use dbm files</A></H1></CENTER>
  @@ -244,7 +253,7 @@
     
     BEGIN {
         # RCS/CVS complient:  must be all one line, for MakeMaker
  -    $DB_File::Wrap::VERSION = do { my @r = (q$Revision: 1.6 $ =~ /\d+/g); sprintf &quot;%d.&quot;.&quot;%02d&quot; x $#r, @r };
  +    $DB_File::Wrap::VERSION = do { my @r = (q$Revision: 1.7 $ =~ /\d+/g); sprintf &quot;%d.&quot;.&quot;%02d&quot; x $#r, @r };
     
     }
     
  @@ -394,7 +403,8 @@
   A simple tie, READ lock and untie
   
   <P>
  -<PRE>  my %mydb = ();
  +<PRE>  my $dbfile = &quot;/tmp/test&quot;;
  +  my %mydb = ();
     my $db = new DB_File::Wrap \%mydb, $dbfile, 'read';
     print $mydb{'stas'} if exists $mydb{'stas'};
       # sync and untie
  @@ -421,7 +431,8 @@
   Perform both, read and write operations:
   
   <P>
  -<PRE>  my %mydb = ();
  +<PRE>  my $dbfile = &quot;/tmp/test&quot;;
  +  my %mydb = ();
     my $db = new DB_File::Wrap \%mydb, $dbfile;
     print $mydb{'stas'} if exists $mydb{'stas'};
     
  @@ -451,6 +462,16 @@
   	     Amazon.com</a>.
   
   	     <HR>
  +
  +	     Your corrections of either technical or grammatical
  +	     errors are very welcome. You are encouraged to help me
  +	     to improve this guide.  If you have something to
  +	     contribute please <A
  +	     HREF="help.html#This_document_s_Author"> send it
  +	     directly to me</A>.
  +
  +	     <HR>
  +
   	     [    <A HREF="databases.html">Prev</A> |      <A HREF="index.html">Main Page</A> | <A HREF="multiuser.html">Next</A>      ]
   
   <CENTER><TABLE CELLSPACING=2 CELLPADDING=2 WIDTH="100%" >
  @@ -464,7 +485,7 @@
       <B>
         <FONT SIZE=-1>
   	     Written by <A HREF="help.html#This_document_s_Author">Stas Bekman</A>.
  -	     <BR>Last Modified at 07/09/1999
  +	     <BR>Last Modified at 09/25/1999
         </FONT>
       </B>
     </TD>
  
  
  
  1.16      +69 -2     modperl-site/guide/debug.html
  
  Index: debug.html
  ===================================================================
  RCS file: /export/home/cvs/modperl-site/guide/debug.html,v
  retrieving revision 1.15
  retrieving revision 1.16
  diff -u -r1.15 -r1.16
  --- debug.html	1999/08/17 19:03:35	1.15
  +++ debug.html	1999/09/25 23:13:54	1.16
  @@ -34,6 +34,8 @@
   	<LI><A HREF="#gdb_says_there_are_no_debugging_">gdb says there are no debugging symbols</A>
   	<LI><A HREF="#Monitoring_error_log_file">Monitoring error_log file</A>
   	<LI><A HREF="#Debugging_Signal_Handlers_SIG_">Debugging Signal Handlers ($SIG{FOO})</A>
  +	<LI><A HREF="#Spinning_httpds">Spinning httpds</A>
  +	<LI><A HREF="#PROFILING">PROFILING</A>
   	<LI><A HREF="#examples_of_strace_or_truss_us">examples of strace (or truss) usage</A>
   	<LI><A HREF="#Devel_Peek">Devel::Peek</A>
   </UL>
  @@ -51,6 +53,15 @@
   
   	     <HR>
   
  +	       Your corrections of either technical or grammatical
  +	       errors are very welcome. You are encouraged to help me
  +	       to improve this guide.  If you have something to
  +	       contribute please <A
  +	       HREF="help.html#This_document_s_Author"> send it
  +	       directly to me</A>.
  +
  +	       <HR>
  +
   	      <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 does not</A></H1></CENTER>
  @@ -216,7 +227,7 @@
   <P>
   Current perl implementation does not restore the original apache's C
   handler when you use <CODE>local $SIG{FOO}</CODE> clause. While save/restore of
  -<CODE>$SIG{ALRM}</CODE> was fixed in the mod_perl 1.19_01 (CVS version) other signals are not yet
  +<CODE>$SIG{ALRM}</CODE> was fixed in the mod_perl 1.19_01 (CVS version), other signals are not yet
   fixed. The real fix should probably be in Perl itself.
   
   <P>
  @@ -252,6 +263,9 @@
     die $@ if $@;
   </PRE>
   <P>
  +If a timeout happens and <CODE>SIGALRM</CODE> is thrown, the <CODE>alarm()</CODE> will be reset, otherwise <CODE>alarm 0</CODE> is reached and timer is being reset as well.
  +
  +<P>
   Now you would write:
   
   <P>
  @@ -266,6 +280,49 @@
   </PRE>
   <P>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<CENTER><H1><A NAME="Spinning_httpds">Spinning httpds</A></H1></CENTER>
  +<P>
  +To see where an httpd is ``spinning'', try adding this to your script or a
  +startup file:
  +
  +<P>
  +<PRE>  use Carp ();
  +  $SIG{'USR1'} = sub { 
  +     Carp::confess(&quot;caught SIGUSR1!&quot;);
  +  };
  +</PRE>
  +<P>
  +Then issue the command line:
  +
  +<P>
  +<PRE>  kill -USR1 &lt;spinning_httpd_pid&gt;
  +</PRE>
  +<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>
  +It is possible to profile code run under mod_perl with the
  +<CODE>Devel::DProf</CODE> module available on CPAN. However, you must have apache version 1.3b3 or
  +higher and the <CODE>PerlChildExitHandler</CODE>
  +enabled. When the server is started, <CODE>Devel::DProf</CODE> installs an
  +<CODE>END</CODE> block to write the <CODE>tmon.out</CODE> file, which will be run when the server is shutdown. Here's how to start
  +and stop a server with the profiler enabled:
  +
  +<P>
  +<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>
  +See also: <CODE>Apache::DProf</CODE>
  +
  +
  +
  +<P>
  +<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
   <CENTER><H1><A NAME="examples_of_strace_or_truss_us">examples of strace (or truss) usage</A></H1></CENTER>
   <P>
   (META: below are some snippets of strace outputs from list's emails)
  @@ -367,6 +424,16 @@
   	     Amazon.com</a>.
   
   	     <HR>
  +
  +	     Your corrections of either technical or grammatical
  +	     errors are very welcome. You are encouraged to help me
  +	     to improve this guide.  If you have something to
  +	     contribute please <A
  +	     HREF="help.html#This_document_s_Author"> send it
  +	     directly to me</A>.
  +
  +	     <HR>
  +
   	     [    <A HREF="status.html">Prev</A> |      <A HREF="index.html">Main Page</A> | <A HREF="browserbugs.html">Next</A>      ]
   
   <CENTER><TABLE CELLSPACING=2 CELLPADDING=2 WIDTH="100%" >
  @@ -380,7 +447,7 @@
       <B>
         <FONT SIZE=-1>
   	     Written by <A HREF="help.html#This_document_s_Author">Stas Bekman</A>.
  -	     <BR>Last Modified at 08/17/1999
  +	     <BR>Last Modified at 09/22/1999
         </FONT>
       </B>
     </TD>
  
  
  
  1.5       +19 -0     modperl-site/guide/download.html
  
  Index: download.html
  ===================================================================
  RCS file: /export/home/cvs/modperl-site/guide/download.html,v
  retrieving revision 1.4
  retrieving revision 1.5
  diff -u -r1.4 -r1.5
  --- download.html	1999/08/17 19:03:36	1.4
  +++ download.html	1999/09/25 23:13:55	1.5
  @@ -52,6 +52,15 @@
   
   	     <HR>
   
  +	       Your corrections of either technical or grammatical
  +	       errors are very welcome. You are encouraged to help me
  +	       to improve this guide.  If you have something to
  +	       contribute please <A
  +	       HREF="help.html#This_document_s_Author"> send it
  +	       directly to me</A>.
  +
  +	       <HR>
  +
   	      <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>
  @@ -159,6 +168,16 @@
   	     Amazon.com</a>.
   
   	     <HR>
  +
  +	     Your corrections of either technical or grammatical
  +	     errors are very welcome. You are encouraged to help me
  +	     to improve this guide.  If you have something to
  +	     contribute please <A
  +	     HREF="help.html#This_document_s_Author"> send it
  +	     directly to me</A>.
  +
  +	     <HR>
  +
   	     [    <A HREF="help.html">Prev</A> |      <A HREF="index.html">Main Page</A> ]
   
   <CENTER><TABLE CELLSPACING=2 CELLPADDING=2 WIDTH="100%" >
  
  
  
  1.8       +19 -0     modperl-site/guide/frequent.html
  
  Index: frequent.html
  ===================================================================
  RCS file: /export/home/cvs/modperl-site/guide/frequent.html,v
  retrieving revision 1.7
  retrieving revision 1.8
  diff -u -r1.7 -r1.8
  --- frequent.html	1999/08/17 19:03:36	1.7
  +++ frequent.html	1999/09/25 23:13:55	1.8
  @@ -44,6 +44,15 @@
   
   	     <HR>
   
  +	       Your corrections of either technical or grammatical
  +	       errors are very welcome. You are encouraged to help me
  +	       to improve this guide.  If you have something to
  +	       contribute please <A
  +	       HREF="help.html#This_document_s_Author"> send it
  +	       directly to me</A>.
  +
  +	       <HR>
  +
   	      <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>
  @@ -79,6 +88,16 @@
   	     Amazon.com</a>.
   
   	     <HR>
  +
  +	     Your corrections of either technical or grammatical
  +	     errors are very welcome. You are encouraged to help me
  +	     to improve this guide.  If you have something to
  +	     contribute please <A
  +	     HREF="help.html#This_document_s_Author"> send it
  +	     directly to me</A>.
  +
  +	     <HR>
  +
   	     [    <A HREF="config.html">Prev</A> |      <A HREF="index.html">Main Page</A> | <A HREF="control.html">Next</A>      ]
   
   <CENTER><TABLE CELLSPACING=2 CELLPADDING=2 WIDTH="100%" >
  
  
  
  1.10      +1067 -793 modperl-site/guide/guide-src.tar.gz
  
  	<<Binary file>>
  
  
  1.11      +1616 -1420modperl-site/guide/guide.tar.gz
  
  	<<Binary file>>
  
  
  1.6       +19 -0     modperl-site/guide/hardware.html
  
  Index: hardware.html
  ===================================================================
  RCS file: /export/home/cvs/modperl-site/guide/hardware.html,v
  retrieving revision 1.5
  retrieving revision 1.6
  diff -u -r1.5 -r1.6
  --- hardware.html	1999/08/17 19:03:41	1.5
  +++ hardware.html	1999/09/25 23:14:01	1.6
  @@ -66,6 +66,15 @@
   
   	     <HR>
   
  +	       Your corrections of either technical or grammatical
  +	       errors are very welcome. You are encouraged to help me
  +	       to improve this guide.  If you have something to
  +	       contribute please <A
  +	       HREF="help.html#This_document_s_Author"> send it
  +	       directly to me</A>.
  +
  +	       <HR>
  +
   	      <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
   <P>
   <CENTER><H1><A NAME="Is_it_important_">Is it important?</A></H1></CENTER>
  @@ -460,6 +469,16 @@
   	     Amazon.com</a>.
   
   	     <HR>
  +
  +	     Your corrections of either technical or grammatical
  +	     errors are very welcome. You are encouraged to help me
  +	     to improve this guide.  If you have something to
  +	     contribute please <A
  +	     HREF="help.html#This_document_s_Author"> send it
  +	     directly to me</A>.
  +
  +	     <HR>
  +
   	     [    <A HREF="snippets.html">Prev</A> |      <A HREF="index.html">Main Page</A> | <A HREF="advocacy.html">Next</A>      ]
   
   <CENTER><TABLE CELLSPACING=2 CELLPADDING=2 WIDTH="100%" >
  
  
  
  1.17      +69 -5     modperl-site/guide/help.html
  
  Index: help.html
  ===================================================================
  RCS file: /export/home/cvs/modperl-site/guide/help.html,v
  retrieving revision 1.16
  retrieving revision 1.17
  diff -u -r1.16 -r1.17
  --- help.html	1999/08/17 19:03:41	1.16
  +++ help.html	1999/09/25 23:14:01	1.17
  @@ -49,6 +49,15 @@
   
   	     <HR>
   
  +	       Your corrections of either technical or grammatical
  +	       errors are very welcome. You are encouraged to help me
  +	       to improve this guide.  If you have something to
  +	       contribute please <A
  +	       HREF="help.html#This_document_s_Author"> send it
  +	       directly to me</A>.
  +
  +	       <HR>
  +
   	      <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
   <P>
   <CENTER><H1><A NAME="READ_ME_FIRST">READ ME FIRST</A></H1></CENTER>
  @@ -81,8 +90,11 @@
   However, you are welcome to submit corrections and suggestions directly to
   me at <A
   HREF="mailto:sbekman@iname.com?subject=mod_perl%20guide%20corrections.">sbekman@iname.com?subject=mod_perl%20guide%20corrections.</A>
  - <STRONG>But PLEASE
  -NO QUESTIONS, they will be immediately deleted.</STRONG>
  +If you are going to <STRONG>submit heavy corrections of the text</STRONG> (I love those!), please help me by downloading the source pages in POD
  +(from the main age under the index) and directly editing them. I will use
  +Emacs Ediff to perform an easy merge of your changes. Thank you!  <STRONG>But PLEASE NO
  +PERSONAL QUESTIONS, I didn't invite those by writing a guide. They all
  +will be immediately deleted.</STRONG>
   
   
   
  @@ -171,11 +183,47 @@
   HREF="http://forum.swarthmore.edu/epigone/modperl">http://forum.swarthmore.edu/epigone/modperl</A>
   . We owe it to Ken Williams.
   
  +<P>
  +More archives available:
  +
  +<UL>
  +<P><LI>
   <P>
  -Another arhive: <A
  +<A
   HREF="http://www.geocrawler.com/lists/3/web/182/0/">http://www.geocrawler.com/lists/3/web/182/0/</A>
   
   
  +<P><LI>
  +<P>
  +<A
  +HREF="http://www.bitmechanic.com/mail-archives/modperl/">http://www.bitmechanic.com/mail-archives/modperl/</A>
  +
  +
  +<P><LI>
  +<P>
  +<A
  +HREF="http://www.mail-archive.com/modperl%40apache.org/">http://www.mail-archive.com/modperl%40apache.org/</A>
  +
  +
  +<P><LI>
  +<P>
  +<A
  +HREF="http://www.davin.ottawa.on.ca/archive/modperl/">http://www.davin.ottawa.on.ca/archive/modperl/</A>
  +
  +
  +<P><LI>
  +<P>
  +<A
  +HREF="http://www.progressive-comp.com/Lists/?l=apache-modperl&r=1&w=2#apache-modperl">http://www.progressive-comp.com/Lists/?l=apache-modperl&r=1&w=2#apache-modperl</A>
  +
  +
  +<P><LI>
  +<P>
  +<A
  +HREF="http://www.egroups.com/group/modperl/">http://www.egroups.com/group/modperl/</A>
  +
  +
  +</UL>
   </DL>
   <P>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  @@ -267,6 +315,12 @@
   HREF="http://www.apache.org/docs/handler.html">http://www.apache.org/docs/handler.html</A>
   
   
  +<P><LI><STRONG><A NAME="item_mod_rewrite">mod_rewrite Guide</A></STRONG>
  +<P>
  +<A
  +HREF="http://www.engelschall.com/pw/apache/rewriteguide/">http://www.engelschall.com/pw/apache/rewriteguide/</A>
  +
  +
   </UL>
   <P>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  @@ -275,7 +329,7 @@
   <P><LI><STRONG><A NAME="item_Perl">Perl DBI examples</A></STRONG>
   <P>
   <A
  -HREF="http://eskimo.tamu.edu/~jbaker/dbi-examples.html">http://eskimo.tamu.edu/~jbaker/dbi-examples.html</A>
  +HREF="http://www.saturn5.com/~jwb/dbi-examples.html">http://www.saturn5.com/~jwb/dbi-examples.html</A>
   (by Jeffrey William Baker).
   
   <P><LI><STRONG><A NAME="item_DBI">DBI at Hermetica</A></STRONG>
  @@ -338,6 +392,16 @@
   	     Amazon.com</a>.
   
   	     <HR>
  +
  +	     Your corrections of either technical or grammatical
  +	     errors are very welcome. You are encouraged to help me
  +	     to improve this guide.  If you have something to
  +	     contribute please <A
  +	     HREF="help.html#This_document_s_Author"> send it
  +	     directly to me</A>.
  +
  +	     <HR>
  +
   	     [    <A HREF="advocacy.html">Prev</A> |      <A HREF="index.html">Main Page</A> | <A HREF="download.html">Next</A>      ]
   
   <CENTER><TABLE CELLSPACING=2 CELLPADDING=2 WIDTH="100%" >
  @@ -351,7 +415,7 @@
       <B>
         <FONT SIZE=-1>
   	     Written by <A HREF="help.html#This_document_s_Author">Stas Bekman</A>.
  -	     <BR>Last Modified at 07/29/1999
  +	     <BR>Last Modified at 09/25/1999
         </FONT>
       </B>
     </TD>
  
  
  
  1.20      +87 -41    modperl-site/guide/index.html
  
  Index: index.html
  ===================================================================
  RCS file: /export/home/cvs/modperl-site/guide/index.html,v
  retrieving revision 1.19
  retrieving revision 1.20
  diff -u -r1.19 -r1.20
  --- index.html	1999/08/17 19:03:41	1.19
  +++ index.html	1999/09/25 23:14:02	1.20
  @@ -27,8 +27,8 @@
   <CENTER><P><B>Deploying mod_perl technology to give a rocket speed
   to your CGI/perl scripts.</B></P></CENTER>
   
  -<CENTER><P><B>Version 1.15
  - Aug, 17 1999</B></P></CENTER>
  +<CENTER><P><B>Version 1.16
  + Sep, 26 1999</B></P></CENTER>
    
   <P>
   <HR WIDTH="100%"></P>
  @@ -46,6 +46,15 @@
   <UL>
   
   	<LI><A HREF="intro.html#What_is_mod_perl">What is mod_perl</A>
  +	<UL>
  +
  +		<LI><A HREF="intro.html#mod_cgi">mod_cgi</A>
  +		<LI><A HREF="intro.html#C_API">C API</A>
  +		<LI><A HREF="intro.html#Perl_API">Perl API</A>
  +		<LI><A HREF="intro.html#Apache_Registry">Apache::Registry</A>
  +		<LI><A HREF="intro.html#Apache_PerlRun">Apache::PerlRun</A>
  +	</UL>
  +
   	<LI><A HREF="intro.html#What_will_you_learn">What will you learn</A>
   	<LI><A HREF="intro.html#References_and_Acknowledgments">References and Acknowledgments</A>
   </UL>
  @@ -62,48 +71,54 @@
   	<LI><A HREF="porting.html#Exposing_Apache_Registry_secret">Exposing Apache::Registry secrets</A>
   	<LI><A HREF="porting.html#Sometimes_it_Works_Sometimes_it_">Sometimes it Works Sometimes it Does Not</A>
   	<LI><A HREF="porting.html#What_s_different_about_modperl">What's different about modperl</A>
  -	<UL>
  -
  -		<LI><A HREF="porting.html#Script_s_name_space">Script's name space</A>
  -		<LI><A HREF="porting.html#Name_collisions_with_Modules_and">Name collisions with Modules and libs</A>
  -		<LI><A HREF="porting.html#More_package_name_related_issues">More package name related issues</A>
  -		<LI><A HREF="porting.html#_END_or_DATA_tokens">__END__ or __DATA__ tokens</A>
  -		<LI><A HREF="porting.html#Output_from_system_calls">Output from system calls</A>
  -		<LI><A HREF="porting.html#Using_format_">Using format()</A>
  -		<LI><A HREF="porting.html#Using_exit_">Using exit()</A>
  -		<LI><A HREF="porting.html#Running_from_shell">Running from shell</A>
  -		<LI><A HREF="porting.html#I_O_is_different">I/O is different</A>
  -		<LI><A HREF="porting.html#HTTP_MIME_Headers_PerlSendHea">HTTP + MIME Headers (PerlSendHeader)</A>
  -		<LI><A HREF="porting.html#NPH_Non_Parsed_Headers_scripts">NPH (Non Parsed Headers) scripts</A>
  -		<LI><A HREF="porting.html#BEGIN_blocks">BEGIN blocks </A>
  -		<LI><A HREF="porting.html#END_blocks">END blocks</A>
  -		<LI><A HREF="porting.html#Switches_w_T">Switches -w, -T</A>
  -		<LI><A HREF="porting.html#strict_pragma">strict pragma</A>
  -		<LI><A HREF="porting.html#Turning_warnings_ON">Turning warnings ON</A>
  -		<LI><A HREF="porting.html#diagnostics_pragma">diagnostics pragma</A>
  -		<LI><A HREF="porting.html#Passing_ENV_variables_to_CGI">Passing ENV variables to CGI</A>
  -		<LI><A HREF="porting.html#Global_Variables">Global Variables</A>
  -		<LI><A HREF="porting.html#Code_has_been_changed_but_it_se">Code has been changed, but it seems the script is running the old code</A>
  -		<LI><A HREF="porting.html#Apache_and_syslog">Apache and syslog</A>
  -		<LI><A HREF="porting.html#Memory_leakage">Memory leakage</A>
  -	</UL>
  -
  +	<LI><A HREF="porting.html#Script_s_name_space">Script's name space</A>
  +	<LI><A HREF="porting.html#Messing_with_INC">Messing with @INC</A>
   	<LI><A HREF="porting.html#Reloading_Modules_and_Required_F">Reloading Modules and Required Files</A>
   	<UL>
   
   		<LI><A HREF="porting.html#Restarting_the_server">Restarting the server</A>
  -		<LI><A HREF="porting.html#Using_Apache_StatINC">Using Apache::StatINC</A>
  -		<LI><A HREF="porting.html#Reloading_only_specific_files">Reloading only specific files</A>
  +		<LI><A HREF="porting.html#Using_Apache_StatINC_for_Develo">Using Apache::StatINC for Development Process</A>
  +		<LI><A HREF="porting.html#Configuration_Files_Writing_Mo">Configuration Files: Writing, Modifying and Reloading.</A>
  +		<UL>
  +
  +			<LI><A HREF="porting.html#Writing_Configuration_Files">Writing Configuration Files</A>
  +			<LI><A HREF="porting.html#Reloading_Configuration_Files">Reloading Configuration Files</A>
  +			<LI><A HREF="porting.html#Dynamically_updating_configurati">Dynamically updating configuration files</A>
  +		</UL>
  +
   		<LI><A HREF="porting.html#Reloading_handlers">Reloading handlers</A>
   	</UL>
   
  +	<LI><A HREF="porting.html#Name_collisions_with_Modules_and">Name collisions with Modules and libs</A>
  +	<LI><A HREF="porting.html#More_package_name_related_issues">More package name related issues</A>
  +	<LI><A HREF="porting.html#_END_or_DATA_tokens">__END__ or __DATA__ tokens</A>
  +	<LI><A HREF="porting.html#Output_from_system_calls">Output from system calls</A>
  +	<LI><A HREF="porting.html#Using_format_and_write_">Using format() and write()</A>
  +	<LI><A HREF="porting.html#Using_exit_">Using exit()</A>
  +	<LI><A HREF="porting.html#Running_from_shell">Running from shell</A>
  +	<LI><A HREF="porting.html#I_O_is_different">I/O is different</A>
  +	<LI><A HREF="porting.html#Special_Perl_Variables">Special Perl Variables</A>
  +	<LI><A HREF="porting.html#Generating_correct_HTTP_Headers">Generating correct HTTP Headers</A>
  +	<LI><A HREF="porting.html#NPH_Non_Parsed_Headers_scripts">NPH (Non Parsed Headers) scripts</A>
  +	<LI><A HREF="porting.html#BEGIN_blocks">BEGIN blocks </A>
  +	<LI><A HREF="porting.html#END_blocks">END blocks</A>
  +	<LI><A HREF="porting.html#Switches_w_T">Switches -w, -T</A>
  +	<LI><A HREF="porting.html#strict_pragma">strict pragma</A>
  +	<LI><A HREF="porting.html#Turning_warnings_ON">Turning warnings ON</A>
  +	<LI><A HREF="porting.html#diagnostics_pragma">diagnostics pragma</A>
  +	<LI><A HREF="porting.html#Passing_ENV_variables_to_CGI">Passing ENV variables to CGI</A>
  +	<LI><A HREF="porting.html#Global_Variables">Global Variables</A>
  +	<LI><A HREF="porting.html#Code_has_been_changed_but_it_se">Code has been changed, but it seems the script is running the old code</A>
  +	<LI><A HREF="porting.html#Apache_and_syslog">Apache and syslog</A>
  +	<LI><A HREF="porting.html#Memory_leakage">Memory leakage</A>
   	<LI><A HREF="porting.html#Filehandlers_and_locks_leakages">Filehandlers and locks leakages</A>
   	<LI><A HREF="porting.html#The_Script_is_too_dirty_but_It_">The Script is too dirty, but It does the job and I can't afford rewriting it.</A>
   	<LI><A HREF="porting.html#Apache_PerlRun_a_closer_look">Apache::PerlRun - a closer look</A>
  +	<LI><A HREF="porting.html#Sharing_variables_between_proces">Sharing variables between processes</A>
   	<LI><A HREF="porting.html#Redirecting_Errors_to_Client_ins">Redirecting Errors to Client instead of error_log</A>
   	<LI><A HREF="porting.html#Finding_the_line_number_the_erro">Finding the line number the error/warning has been triggered at</A>
  -	<LI><A HREF="porting.html#Forking_subprocesses_from_mod_pe">Forking subprocesses from mod_perl</A>
  -	<LI><A HREF="porting.html#Generating_correct_HTTP_MIME_Hea">Generating correct HTTP MIME Headers</A>
  +	<LI><A HREF="porting.html#Forking_or_Executing_subprocesse">Forking or Executing subprocesses from mod_perl</A>
  +	<LI><A HREF="porting.html#Passing_and_preserving_custom_da">Passing and preserving custom data structures between handlers</A>
   </UL>
   <P><LI><A HREF="performance.html"><B><FONT SIZE=+1>Performance. Benchmarks.</FONT></B></A></LI><P>
   <UL>
  @@ -118,6 +133,8 @@
   
   	<LI><A HREF="performance.html#Preload_Registry_Scripts">Preload Registry Scripts</A>
   	<LI><A HREF="performance.html#Avoid_Importing_Functions">Avoid Importing Functions</A>
  +	<LI><A HREF="performance.html#PerlSetupEnv_Off">PerlSetupEnv Off</A>
  +	<LI><A HREF="performance.html#_DTWO_POT_OPTIMIZE_and_DPACK_MA">-DTWO_POT_OPTIMIZE and -DPACK_MALLOC Perl Options</A>
   	<LI><A HREF="performance.html#Shared_Memory">Shared Memory</A>
   	<LI><A HREF="performance.html#Checking_script_modification_tim">Checking script modification times</A>
   	<LI><A HREF="performance.html#How_can_I_find_if_my_mod_perl_sc">How can I find if my mod_perl scripts have memory leaks</A>
  @@ -221,15 +238,18 @@
   	</UL>
   
   	<LI><A HREF="install.html#Is_it_possible_to_install_and_us">Is it possible to install and use apache/mod_perl without having a root access?</A>
  +	<LI><A HREF="install.html#Is_it_possible_to_tell_whether_s">Is it possible to tell whether some option was included</A>
   	<LI><A HREF="install.html#Is_it_possible_to_determine_whic">Is it possible to determine which options were given to modperl's Makefile.PL</A>
   	<LI><A HREF="install.html#Server_Installation_problems">Server Installation problems</A>
   	<UL>
   
  +		<LI><A HREF="install.html#_skipping_test_on_this_plat">......skipping test on this platform</A>
   		<LI><A HREF="install.html#make_test_fails">make test fails</A>
   		<LI><A HREF="install.html#mod_perl_c_is_incompatible_with_">mod_perl.c is incompatible with this version of apache</A>
   		<LI><A HREF="install.html#Should_I_rebuild_mod_perl_if_I_h">Should I rebuild mod_perl if I have upgraded my perl?</A>
   	</UL>
   
  +	<LI><A HREF="install.html#mod_auth_dbm_nuances">mod_auth_dbm nuances</A>
   	<LI><A HREF="install.html#Stripping_apache_to_make_it_almo">Stripping apache to make it almost perl-server</A>
   </UL>
   <P><LI><A HREF="config.html"><B><FONT SIZE=+1>Server Configuration</FONT></B></A></LI><P>
  @@ -240,6 +260,14 @@
   
   		<LI><A HREF="config.html#Alias_Configurations">Alias Configurations</A>
   		<LI><A HREF="config.html#Location_Configuration">Location Configuration</A>
  +		<LI><A HREF="config.html#PerlModule_and_PerlRequire_direc">PerlModule and PerlRequire directives</A>
  +		<LI><A HREF="config.html#Perl_Handlers">Perl*Handlers</A>
  +	</UL>
  +
  +	<LI><A HREF="config.html#STACKED_HANDLERS">STACKED HANDLERS</A>
  +	<LI><A HREF="config.html#PERL_METHOD_HANDLERS">PERL METHOD HANDLERS</A>
  +	<UL>
  +
   		<LI><A HREF="config.html#PerlFreshRestart">PerlFreshRestart</A>
   		<LI><A HREF="config.html#_perl_status_location">/perl-status location</A>
   		<UL>
  @@ -274,12 +302,13 @@
   		<LI><A HREF="config.html#My_script_works_under_cgi_bin_b">My script works under cgi-bin, but when called via mod_perl I see A 'Save-As' prompt</A>
   		<LI><A HREF="config.html#Is_there_a_way_to_provide_a_diff">Is there a way to provide a different startup.pl file for each individual virtual host</A>
   		<LI><A HREF="config.html#Is_there_a_way_to_modify_INC_on">Is there a way to modify @INC on a per-virtual-host or per-location basis.</A>
  -		<LI><A HREF="config.html#Sometimes_the_script_from_one_vi">Sometimes the script from one virtual host calls a script with</A>
  +		<LI><A HREF="config.html#A_Script_from_one_virtual_host_c">A Script from one virtual host calls a script with the same path from the other virtual host</A>
   		<LI><A HREF="config.html#the_server_no_longer_retrieves_t">the server no longer retrieves the DirectoryIndex files for a directory</A>
   	</UL>
   
   	<LI><A HREF="config.html#Configuration_Security_Concerns">Configuration Security Concerns</A>
   	<LI><A HREF="config.html#Logical_grouping_of_Location_Di">Logical grouping of Location, Directory and FilesMatch directives</A>
  +	<LI><A HREF="config.html#Apache_restarts_twice_on_start">Apache restarts twice on start</A>
   </UL>
   <P><LI><A HREF="frequent.html"><B><FONT SIZE=+1>Frequent mod_perl problems</FONT></B></A></LI><P>
   <UL>
  @@ -345,6 +374,7 @@
   	<LI><A HREF="warnings.html#RegistryLoader_Cannot_translate">RegistryLoader: Cannot translate the URI /home/httpd/perl/test.pl</A>
   	<LI><A HREF="warnings.html#Evil_things_might_happen_when_us">Evil things might happen when using PerlFreshRestart</A>
   	<LI><A HREF="warnings.html#server_reached_MaxClients_settin">server reached MaxClients setting, consider raising the MaxClients setting</A>
  +	<LI><A HREF="warnings.html#syntax_error_at_dev_null_line_1">syntax error at /dev/null line 1, near &quot;line arguments:&quot;</A>
   </UL>
   <P><LI><A HREF="security.html"><B><FONT SIZE=+1>Protecting Your Site</FONT></B></A></LI><P>
   <UL>
  @@ -359,7 +389,8 @@
   	<LI><A HREF="security.html#Authentication_code_snippets">Authentication code snippets</A>
   	<UL>
   
  -		<LI><A HREF="security.html#Forcing_reauthenticating">Forcing reauthenticating</A>
  +		<LI><A HREF="security.html#Forcing_re_authentication">Forcing re-authentication</A>
  +		<LI><A HREF="security.html#OK_AUTH_REQUIRED_and_FORBIDDEN_">OK, AUTH_REQUIRED.and FORBIDDEN in Authentication handlers</A>
   	</UL>
   
   </UL>
  @@ -434,6 +465,8 @@
   	<LI><A HREF="debug.html#gdb_says_there_are_no_debugging_">gdb says there are no debugging symbols</A>
   	<LI><A HREF="debug.html#Monitoring_error_log_file">Monitoring error_log file</A>
   	<LI><A HREF="debug.html#Debugging_Signal_Handlers_SIG_">Debugging Signal Handlers ($SIG{FOO})</A>
  +	<LI><A HREF="debug.html#Spinning_httpds">Spinning httpds</A>
  +	<LI><A HREF="debug.html#PROFILING">PROFILING</A>
   	<LI><A HREF="debug.html#examples_of_strace_or_truss_us">examples of strace (or truss) usage</A>
   	<LI><A HREF="debug.html#Devel_Peek">Devel::Peek</A>
   </UL>
  @@ -473,8 +506,6 @@
   <P><LI><A HREF="snippets.html"><B><FONT SIZE=+1>Code Snippets</FONT></B></A></LI><P>
   <UL>
   
  -	<LI><A HREF="snippets.html#Sending_MIME_headers">Sending MIME headers</A>
  -	<LI><A HREF="snippets.html#How_to_avoid_printing_the_header">How to avoid printing the header more than once</A>
   	<LI><A HREF="snippets.html#More_on_relative_paths">More on relative paths</A>
   	<LI><A HREF="snippets.html#Watching_the_error_log_file_with">Watching the error_log file without telneting to the server</A>
   	<LI><A HREF="snippets.html#Accessing_variables_from_the_cal">Accessing variables from the caller's package</A>
  @@ -582,16 +613,31 @@
   <HR>
   <P>
   
  -Now you can search the indexed version of the guide at <A
  -HREF="http://www.perlreference.com/mod_perl/guide">perlreference.com</A>.
  -
   <HR>
  +
  +<A NAME="SEARCH"></A>
  +<CENTER>
  +<TABLE BORDER=10 CELLSPACING=2 CELLPADDING=8 >
  +<TR BGCOLOR="gray" ALIGN=CENTER VALIGN=TOP>
  +<TD ALIGN=CENTER VALIGN=TOP>
  +<FONT COLOR=WHITE>
  +Search mod_perl FAQs along with this guide 
  +<BR> at www.perlreference.com
  +<FORM action="http://perlreference.com/cgi-bin/mod_perl/search.pl" method="GET">
  +<INPUT type="text" name="q" value="" SIZE=15>
  +<INPUT TYPE="submit" VALUE="Search">
  +</FORM>
  +</FONT>
  +</TD></TR>
  +</TABLE>
  +</CENTER>
  +
   <CENTER>
   <TABLE BORDER=10 CELLSPACING=2 CELLPADDING=8 >
   <TR BGCOLOR="gray" ALIGN=CENTER VALIGN=TOP>
   <TD ALIGN=CENTER VALIGN=TOP>
   <FONT COLOR=WHITE>
  -<A NAME="SEARCH">Search perl.apache.org along with this guide.</A>
  +Search perl.apache.org along with this guide.
   <FORM ACTION="http://search.apache.org/" METHOD="POST">
   <INPUT TYPE="text" NAME="keyword" value="" SIZE=15>
   <input type="hidden" name="what" value="perl">
  @@ -621,7 +667,7 @@
   
   <TR ALIGN=CENTER VALIGN=TOP>
   <TD ALIGN=CENTER VALIGN=CENTER><B><FONT SIZE=-1>Written by <A
  -HREF="help.html#This_document_s_Author">Stas Bekman</A>.<BR> Last Modified at 08/17/1999
  +HREF="help.html#This_document_s_Author">Stas Bekman</A>.<BR> Last Modified at 09/26/1999
   </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>
  
  
  
  1.7       +151 -1    modperl-site/guide/install.html
  
  Index: install.html
  ===================================================================
  RCS file: /export/home/cvs/modperl-site/guide/install.html,v
  retrieving revision 1.6
  retrieving revision 1.7
  diff -u -r1.6 -r1.7
  --- install.html	1999/08/17 19:03:42	1.6
  +++ install.html	1999/09/25 23:14:03	1.7
  @@ -45,15 +45,18 @@
   	</UL>
   
   	<LI><A HREF="#Is_it_possible_to_install_and_us">Is it possible to install and use apache/mod_perl without having a root access?</A>
  +	<LI><A HREF="#Is_it_possible_to_tell_whether_s">Is it possible to tell whether some option was included</A>
   	<LI><A HREF="#Is_it_possible_to_determine_whic">Is it possible to determine which options were given to modperl's Makefile.PL</A>
   	<LI><A HREF="#Server_Installation_problems">Server Installation problems</A>
   	<UL>
   
  +		<LI><A HREF="#_skipping_test_on_this_plat">......skipping test on this platform</A>
   		<LI><A HREF="#make_test_fails">make test fails</A>
   		<LI><A HREF="#mod_perl_c_is_incompatible_with_">mod_perl.c is incompatible with this version of apache</A>
   		<LI><A HREF="#Should_I_rebuild_mod_perl_if_I_h">Should I rebuild mod_perl if I have upgraded my perl?</A>
   	</UL>
   
  +	<LI><A HREF="#mod_auth_dbm_nuances">mod_auth_dbm nuances</A>
   	<LI><A HREF="#Stripping_apache_to_make_it_almo">Stripping apache to make it almost perl-server</A>
   </UL>
   <!-- INDEX END -->
  @@ -70,6 +73,15 @@
   
   	     <HR>
   
  +	       Your corrections of either technical or grammatical
  +	       errors are very welcome. You are encouraged to help me
  +	       to improve this guide.  If you have something to
  +	       contribute please <A
  +	       HREF="help.html#This_document_s_Author"> send it
  +	       directly to me</A>.
  +
  +	       <HR>
  +
   	      <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
   <P>
   <CENTER><H1><A NAME="Configuration_and_Installation">Configuration and Installation</A></H1></CENTER>
  @@ -340,6 +352,25 @@
   for more information on local perl installations.
   
   <P>
  +So you end up with something like:
  +
  +<P>
  +<PRE>  $ gunzip &lt;apache_x.x.xx.tar.gz | tar xvf -
  +  $ gunzip &lt;mod_perl-x.xx.tar.gz | tar xvf -
  +  $ cd mod_perl-x.xx
  +  $ perl Makefile.PL \
  +      APACHE_SRC=../apache-1.3.X/src \
  +      DO_HTTPD=1 \
  +      USE_APACI=1 \
  +      EVERYTHING=1 \
  +      APACI_ARGS=--sbindir=/home/stas/sbin/httpd_perl, \
  +           --sysconfdir=/home/stas/etc/httpd_perl, \
  +           --localstatedir=/home/stas/var/httpd_perl, \
  +           --runtimedir=/home/stas/var/httpd_perl/run, \
  +           --logfiledir=/home/stas/var/httpd_perl/logs, \
  +           --proxycachedir=/home/stas/var/httpd_perl/proxy
  +</PRE>
  +<P>
   You will not be able to have the server listen to a port lower then 1024 if
   you are not starting it as <CODE>root</CODE>, so choose a port number above 1024. (I use 8080 in most cases). Note that
   you will have to use a URL like <CODE>http://www.nowhere.com:8080</CODE> in that case, but that is not a problem since usually users do not directly
  @@ -378,6 +409,17 @@
   </UL>
   <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_tell_whether_s">Is it possible to tell whether some option was included</A></H1></CENTER>
  +<P>
  +Sure, you can take a look at the symbols inside the httpd executable. e.g.
  +if you want to see whether you have enabled PERL_AUTH=1 while building the
  +mod_perl, you do:
  +
  +<P>
  +<PRE>  nm httpd | grep perl_authenticate
  +</PRE>
  +<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_determine_whic">Is it possible to determine which options were given to modperl's Makefile.PL</A></H1></CENTER>
   <P>
   It is possible to determine which options were given to modperl's
  @@ -412,6 +454,56 @@
   <CENTER><H1><A NAME="Server_Installation_problems">Server Installation problems</A></H1></CENTER>
   <P>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<CENTER><H2><A NAME="_skipping_test_on_this_plat">......skipping test on this platform</A></H2></CENTER>
  +<P>
  +While doing <CODE>make test</CODE> you would notice that some of the tests are being reported as skipped. The
  +real reason is that you are missing some optional modules for these test to
  +be passed. For a hint you might want to peek at the content of each test
  +(you will find them all in the <CODE>./t</CODE> directory (mnemonic - t, tests). I'll list a few examples, but of course
  +the requirements might be changed in the future.
  +
  +<P>
  +&gt; modules/cookie......skipping test on this platform
  +
  +<P>
  +install libapreq
  +
  +<P>
  +&gt; modules/psections...skipping test on this platform
  +
  +<P>
  +install Devel::Symdump / Data::Dumper
  +
  +<P>
  +&gt; modules/request.....skipping test on this platform
  +
  +<P>
  +libapreq
  +
  +<P>
  +&gt; modules/sandwich....skipping test on this platform
  +
  +<P>
  +Apache::Sandwich
  +
  +<P>
  +&gt; modules/stage.......skipping test on this platform
  +
  +<P>
  +Apache::Stage
  +
  +<P>
  +&gt; modules/symbol......skipping test on this platform
  +
  +<P>
  +Devel::Symdump
  +
  +<P>
  +Chances are that all of these are installed if you use <CODE>CPAN.pm</CODE> to
  +<CODE>install Bundle::Apache</CODE>.
  +
  +<P>
  +<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
   <CENTER><H2><A NAME="make_test_fails">make test fails</A></H2></CENTER>
   <P>
   There are two configuration parameters: <CODE>PREP_HTTPD</CODE> and <CODE>DO_HTTPD</CODE>, that you can use in:
  @@ -472,6 +564,54 @@
   
   <P>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<CENTER><H1><A NAME="mod_auth_dbm_nuances">mod_auth_dbm nuances</A></H1></CENTER>
  +<P>
  +If you are a user of <STRONG>mod_auth_dbm</STRONG> or <STRONG>mod_auth_db</STRONG>, you may need to edit Perl's <CODE>Config</CODE> module. When Perl is configured it attempts to find libraries for ndbm,
  +gdbm, db, etc., for the *DBM*_File modules. By default, these libraries are
  +linked with Perl and remembered by the <STRONG>Config</STRONG> module. When mod_perl is configured with apache, the <STRONG>ExtUtils::Embed</STRONG> module returns these libraries to be linked with httpd so Perl extensions
  +will work under mod_perl. However, the order in which these libraries are
  +stored in
  +<STRONG>Config.pm</STRONG>, may confuse <CODE>mod_auth_db*</CODE>. If <CODE>mod_auth_db*</CODE> does not work with mod_perl, take a look at this order with the following
  +command:
  +
  +<P>
  +<PRE> % perl -V:libs
  +</PRE>
  +<P>
  +If <CODE>-lgdbm</CODE> or <CODE>-ldb</CODE> is before <CODE>-lndbm</CODE>, example:
  +
  +<P>
  +<PRE> libs='-lnet -lnsl_s -lgdbm -lndbm -ldb -ldld -lm -lc -lndir -lcrypt';
  +</PRE>
  +<P>
  +Edit <STRONG>Config.pm</STRONG> and move <CODE>-lgdbm</CODE> and <CODE>-ldb</CODE> to the end of the list. Here's how to find <STRONG>Config.pm</STRONG>:
  +
  +<P>
  +<PRE> % perl -MConfig -e 'print &quot;$Config{archlibexp}/Config.pm\n&quot;'
  +</PRE>
  +<P>
  +Another solution for building Apache/mod_perl+mod_auth_dbm under Solaris is
  +to remove the DBM and NDBM ``emulation'' from libgdbm.a. Seems Solaris
  +already provides its own DBM and NDBM, and there's no reason to build GDBM
  +with them (for us anyway).
  +
  +<P>
  +In our Makefile for GDBM, we changed
  +
  +<P>
  +<PRE>  OBJS = $(DBM_OF) $(NDBM_OF) $(GDBM_OF)
  +</PRE>
  +<P>
  +to
  +
  +<P>
  +<PRE>  OBJS = $(GDBM_OF)
  +</PRE>
  +<P>
  +Rebuild libgdbm, then Apache/mod_perl.  
  +
  +<P>
  +<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
   <CENTER><H1><A NAME="Stripping_apache_to_make_it_almo">Stripping apache to make it almost perl-server</A></H1></CENTER>
   <P>
   Since most of the functionality that various apache mod_* modules provide
  @@ -491,6 +631,16 @@
   	     Amazon.com</a>.
   
   	     <HR>
  +
  +	     Your corrections of either technical or grammatical
  +	     errors are very welcome. You are encouraged to help me
  +	     to improve this guide.  If you have something to
  +	     contribute please <A
  +	     HREF="help.html#This_document_s_Author"> send it
  +	     directly to me</A>.
  +
  +	     <HR>
  +
   	     [    <A HREF="scenario.html">Prev</A> |      <A HREF="index.html">Main Page</A> | <A HREF="config.html">Next</A>      ]
   
   <CENTER><TABLE CELLSPACING=2 CELLPADDING=2 WIDTH="100%" >
  @@ -504,7 +654,7 @@
       <B>
         <FONT SIZE=-1>
   	     Written by <A HREF="help.html#This_document_s_Author">Stas Bekman</A>.
  -	     <BR>Last Modified at 07/09/1999
  +	     <BR>Last Modified at 09/25/1999
         </FONT>
       </B>
     </TD>
  
  
  
  1.14      +148 -3    modperl-site/guide/intro.html
  
  Index: intro.html
  ===================================================================
  RCS file: /export/home/cvs/modperl-site/guide/intro.html,v
  retrieving revision 1.13
  retrieving revision 1.14
  diff -u -r1.13 -r1.14
  --- intro.html	1999/08/17 19:03:42	1.13
  +++ intro.html	1999/09/25 23:14:04	1.14
  @@ -27,6 +27,15 @@
   <UL>
   
   	<LI><A HREF="#What_is_mod_perl">What is mod_perl</A>
  +	<UL>
  +
  +		<LI><A HREF="#mod_cgi">mod_cgi</A>
  +		<LI><A HREF="#C_API">C API</A>
  +		<LI><A HREF="#Perl_API">Perl API</A>
  +		<LI><A HREF="#Apache_Registry">Apache::Registry</A>
  +		<LI><A HREF="#Apache_PerlRun">Apache::PerlRun</A>
  +	</UL>
  +
   	<LI><A HREF="#What_will_you_learn">What will you learn</A>
   	<LI><A HREF="#References_and_Acknowledgments">References and Acknowledgments</A>
   </UL>
  @@ -44,6 +53,15 @@
   
   	     <HR>
   
  +	       Your corrections of either technical or grammatical
  +	       errors are very welcome. You are encouraged to help me
  +	       to improve this guide.  If you have something to
  +	       contribute please <A
  +	       HREF="help.html#This_document_s_Author"> send it
  +	       directly to me</A>.
  +
  +	       <HR>
  +
   	      <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
   <P>
   <CENTER><H1><A NAME="What_is_mod_perl">What is mod_perl</A></H1></CENTER>
  @@ -91,6 +109,123 @@
   
   <P>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<CENTER><H2><A NAME="mod_cgi">mod_cgi</A></H2></CENTER>
  +<P>
  +When you run your CGI scripts by using a configuration of:
  +
  +<P>
  +<PRE>  ScriptAlias /cgi-bin/ /home/httpd/cgi-bin/
  +</PRE>
  +<P>
  +you run it under a mod_cgi handler, you never define it explicitly. Apache
  +does all the configuration work behind the scenes, when you use a
  +ScriptAlias.
  +
  +<P>
  +BTW, don't confuse it with a <CODE>ExecCGI</CODE> configuration option, it's being enabled so the script will be executed and
  +not returned as a plain file. For example for mod_perl and <CODE>Apache::Registry</CODE> you would use a configuration like:
  +
  +<P>
  +<PRE>  &lt;Location /perl&gt;
  +    SetHandler perl-script
  +    PerlHandler Apache::Registry
  +    Options ExecCGI
  +    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="C_API">C API</A></H2></CENTER>
  +<P>
  +META: complete
  +
  +<P>
  +<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<CENTER><H2><A NAME="Perl_API">Perl API</A></H2></CENTER>
  +<P>
  +META: complete
  +
  +<P>
  +<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<CENTER><H2><A NAME="Apache_Registry">Apache::Registry</A></H2></CENTER>
  +<P>
  +From the point of Perl API, <CODE>Apache::Registry</CODE> is just yet another handler that's not conceptually different from any
  +other handler. It reads in the file, compiles, executes it and stores into
  +the cache. Since the perl interpreter keeps running from child process'
  +creation to its death, any code compiled by the interpreter is not removed
  +from memory until the child dies.
  +
  +<P>
  +To keep the script names from collisions, it prepends
  +<CODE>Apache::ROOT::</CODE> and the mangled path of the URI to the key of the cached script. This key
  +is actually a package name, the script resides in. So if you have requested
  +a script <CODE>/perl/project/test.pl</CODE>, the scripts would be wrapped in code which starts with package
  +declaration of:
  +
  +<P>
  +<PRE>  package Apache::ROOT::perl::project::test_e2pl;
  +</PRE>
  +<P>
  +<CODE>Apache::Registry</CODE> also stores the script's last modification time. Everytime the script
  +changes, the cached code would be discarded and recompiled using the
  +modified source. However, it doesn't check any of the perl libraries the
  +script might use.
  +
  +<P>
  +<CODE>Apache::Registry</CODE> overrides the <CODE>CORE::exit()</CODE> with &lt;Apache::exit()&gt;, so the CGI scripts that used the
  +&lt;exit()&gt; will run correctly. We will talk about all these details
  +indepth later.
  +
  +<P>
  +The last thing <CODE>Apache::Registry</CODE> does, is emulating of the mod_cgi's environment variables. Like <CODE>$ENV{SERVER_NAME}</CODE>, <CODE>$ENV{REMOTE_USER}</CODE>
  +and so on. <STRONG>PerlSetupEnv Off</STRONG> disables this feature and saves some memory bits and CPU clocks.
  +
  +<P>
  +From the point of mod_cgi (when you take the script that was running as a
  +plain CGI under mod_cgi to run under mod_perl), there is almost no
  +difference, but great speed improve, though much heavier memory usage
  +(there is no free lunch :).
  +
  +<P>
  +Just rememeber that the code is being cached, so it wouldn't cleanup the
  +memory, like you used to with mod_cgi when the script was existing (it
  +doesn't exit in mod_perl).
  +
  +<P>
  +Also rememeber that any libraries that your script might
  +<CODE>require()</CODE> or <CODE>use()</CODE> wouldn't be recompiled when
  +changed.
  +
  +<P>
  +Of course the book will answer all this issues in depth.
  +
  +<P>
  +Just to show you what happens with your script, when it's being executed
  +under <CODE>Apache::Registry</CODE>. If we take the simplest code of (URI <CODE>/perl/project/test.pl</CODE>)
  +
  +<P>
  +<PRE>  print &quot;Content-type: text/html\n\n&quot;;
  +  print &quot;It works\n&quot;;
  +</PRE>
  +<P>
  +<CODE>Apache::Registry</CODE> will convert it into the following:
  +
  +<P>
  +<PRE>  package Apache::ROOT::perl::project::test_e2pl;
  +  use Apache qw(exit);
  +  sub handler {
  +    print &quot;Content-type: text/html\n\n&quot;;
  +    print &quot;It works\n&quot;;
  +  }
  +</PRE>
  +<P>
  +<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<CENTER><H2><A NAME="Apache_PerlRun">Apache::PerlRun</A></H2></CENTER>
  +<P>
  +META: Complete
  +
  +<P>
  +<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
   <CENTER><H1><A NAME="What_will_you_learn">What will you learn</A></H1></CENTER>
   <P>
   This document was written in an effort to help you start using Apache's
  @@ -208,8 +343,8 @@
   
   <P><LI>
   <P>
  -<STRONG>Eric Cholet</STRONG>, who wrote complete sections for the guide, and pointed out the errors in
  -the guide.
  +<STRONG>Eric Cholet</STRONG>, who wrote complete sections for the guide, and pointed out the errors the
  +guide carried away.
   
   <P><LI>
   <P>
  @@ -277,6 +412,16 @@
   	     Amazon.com</a>.
   
   	     <HR>
  +
  +	     Your corrections of either technical or grammatical
  +	     errors are very welcome. You are encouraged to help me
  +	     to improve this guide.  If you have something to
  +	     contribute please <A
  +	     HREF="help.html#This_document_s_Author"> send it
  +	     directly to me</A>.
  +
  +	     <HR>
  +
   	     [    <A HREF="index.html">Main Page</A> | <A HREF="start.html">Next</A>      ]
   
   <CENTER><TABLE CELLSPACING=2 CELLPADDING=2 WIDTH="100%" >
  @@ -290,7 +435,7 @@
       <B>
         <FONT SIZE=-1>
   	     Written by <A HREF="help.html#This_document_s_Author">Stas Bekman</A>.
  -	     <BR>Last Modified at 07/29/1999
  +	     <BR>Last Modified at 09/25/1999
         </FONT>
       </B>
     </TD>
  
  
  
  1.4       +858 -712  modperl-site/guide/mod_perl_guide.ps.gz
  
  	<<Binary file>>
  
  
  1.8       +19 -0     modperl-site/guide/modules.html
  
  Index: modules.html
  ===================================================================
  RCS file: /export/home/cvs/modperl-site/guide/modules.html,v
  retrieving revision 1.7
  retrieving revision 1.8
  diff -u -r1.7 -r1.8
  --- modules.html	1999/08/17 19:03:43	1.7
  +++ modules.html	1999/09/25 23:14:07	1.8
  @@ -49,6 +49,15 @@
   
   	     <HR>
   
  +	       Your corrections of either technical or grammatical
  +	       errors are very welcome. You are encouraged to help me
  +	       to improve this guide.  If you have something to
  +	       contribute please <A
  +	       HREF="help.html#This_document_s_Author"> send it
  +	       directly to me</A>.
  +
  +	       <HR>
  +
   	      <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
   <P>
   <CENTER><H1><A NAME="Apache_Session_Maintain_sessi">Apache::Session - Maintain session state across HTTP requests</A></H1></CENTER>
  @@ -312,6 +321,16 @@
   	     Amazon.com</a>.
   
   	     <HR>
  +
  +	     Your corrections of either technical or grammatical
  +	     errors are very welcome. You are encouraged to help me
  +	     to improve this guide.  If you have something to
  +	     contribute please <A
  +	     HREF="help.html#This_document_s_Author"> send it
  +	     directly to me</A>.
  +
  +	     <HR>
  +
   	     [    <A HREF="browserbugs.html">Prev</A> |      <A HREF="index.html">Main Page</A> | <A HREF="perl.html">Next</A>      ]
   
   <CENTER><TABLE CELLSPACING=2 CELLPADDING=2 WIDTH="100%" >
  
  
  
  1.8       +29 -2     modperl-site/guide/multiuser.html
  
  Index: multiuser.html
  ===================================================================
  RCS file: /export/home/cvs/modperl-site/guide/multiuser.html,v
  retrieving revision 1.7
  retrieving revision 1.8
  diff -u -r1.7 -r1.8
  --- multiuser.html	1999/08/17 19:03:43	1.7
  +++ multiuser.html	1999/09/25 23:14:07	1.8
  @@ -43,6 +43,15 @@
   
   	     <HR>
   
  +	       Your corrections of either technical or grammatical
  +	       errors are very welcome. You are encouraged to help me
  +	       to improve this guide.  If you have something to
  +	       contribute please <A
  +	       HREF="help.html#This_document_s_Author"> send it
  +	       directly to me</A>.
  +
  +	       <HR>
  +
   	      <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
   <P>
   <CENTER><H1><A NAME="ISPs_providing_mod_perl_services">ISPs providing mod_perl services - a fantasy or reality.</A></H1></CENTER>
  @@ -79,6 +88,14 @@
   user (guest books, counters and etc - the same standard scripts ISPs
   providing since they were born). So you have to say <STRONG>NO</STRONG> for this choice.
   
  +<P>
  +More things to think about are file permissions (any user who is allowed to
  +write and run CGI script, can at least read if not write any other files
  +that has a permissions of the web server. This has nothing to do with
  +mod_perl, and there are solutions for that
  +<CODE>suEXEC</CODE> and <CODE>cgiwrap</CODE> for example) and <CODE>Apache::DBI</CODE> connections (You can pick a connection from the pool of cached
  +connenctions, opened by someone else by hacking the <CODE>Apache::DBI</CODE> code).
  +
   <P><LI>
   <P>
   But, hey why I cannot let my user to run his own server, so I clean my
  @@ -207,7 +224,7 @@
   
   
   <P>
  -<A HREF="././config.html#Sometimes_the_script_from_one_vi">Sometimes the script from one virtual host calls a script with the same path from the second virtual host</A>
  +<A HREF="././config.html#A_Script_from_one_virtual_host_c">Sometimes the script from one virtual host calls a script with the same path from the second virtual host</A>
   
   
   
  @@ -221,6 +238,16 @@
   	     Amazon.com</a>.
   
   	     <HR>
  +
  +	     Your corrections of either technical or grammatical
  +	     errors are very welcome. You are encouraged to help me
  +	     to improve this guide.  If you have something to
  +	     contribute please <A
  +	     HREF="help.html#This_document_s_Author"> send it
  +	     directly to me</A>.
  +
  +	     <HR>
  +
   	     [    <A HREF="dbm.html">Prev</A> |      <A HREF="index.html">Main Page</A> | <A HREF="status.html">Next</A>      ]
   
   <CENTER><TABLE CELLSPACING=2 CELLPADDING=2 WIDTH="100%" >
  @@ -234,7 +261,7 @@
       <B>
         <FONT SIZE=-1>
   	     Written by <A HREF="help.html#This_document_s_Author">Stas Bekman</A>.
  -	     <BR>Last Modified at 07/09/1999
  +	     <BR>Last Modified at 09/26/1999
         </FONT>
       </B>
     </TD>
  
  
  
  1.17      +31 -1     modperl-site/guide/obvious.html
  
  Index: obvious.html
  ===================================================================
  RCS file: /export/home/cvs/modperl-site/guide/obvious.html,v
  retrieving revision 1.16
  retrieving revision 1.17
  diff -u -r1.16 -r1.17
  --- obvious.html	1999/08/17 19:03:44	1.16
  +++ obvious.html	1999/09/25 23:14:08	1.17
  @@ -58,6 +58,15 @@
   
   	     <HR>
   
  +	       Your corrections of either technical or grammatical
  +	       errors are very welcome. You are encouraged to help me
  +	       to improve this guide.  If you have something to
  +	       contribute please <A
  +	       HREF="help.html#This_document_s_Author"> send it
  +	       directly to me</A>.
  +
  +	       <HR>
  +
   	      <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>
  @@ -414,6 +423,17 @@
   
   <P>
   Also note that since the server is running in single mode, if the output
  +returns HTML with <CODE>&lt;IMG</CODE>&gt; tags, then the load of these will take a lot of time. 
  +
  +<P>
  +When you use Netscape client while your server is running in single-process
  +mode, if the output returns a HTML with <CODE>&lt;IMG</CODE>&gt; tags, then the load of these will take a lot of time, since the <CODE>KeepAlive</CODE>
  +feature gets in the way. Netscape tries to open multiple connections and
  +keep them open. Because there is only one server process listening, each
  +connection has to time-out before the next succeeds. Turn off <CODE>KeepAlive</CODE> in <CODE>httpd.conf</CODE> to avoid this effect.
  +
  +<P>
  +Also note that since the server is running in single mode, if the output
   returns HTML with <CODE>&lt;IMG</CODE>&gt; tags, then the load of these will take a lot of time. If you use
   Netscape while your server is running in single-process mode, HTTP's <CODE>KeepAlive</CODE> feature gets in the way. Netscape tries to open multiple connections and
   keep them open. Because there is only one server process listening, each
  @@ -692,6 +712,16 @@
   	     Amazon.com</a>.
   
   	     <HR>
  +
  +	     Your corrections of either technical or grammatical
  +	     errors are very welcome. You are encouraged to help me
  +	     to improve this guide.  If you have something to
  +	     contribute please <A
  +	     HREF="help.html#This_document_s_Author"> send it
  +	     directly to me</A>.
  +
  +	     <HR>
  +
   	     [    <A HREF="control.html">Prev</A> |      <A HREF="index.html">Main Page</A> | <A HREF="warnings.html">Next</A>      ]
   
   <CENTER><TABLE CELLSPACING=2 CELLPADDING=2 WIDTH="100%" >
  @@ -705,7 +735,7 @@
       <B>
         <FONT SIZE=-1>
   	     Written by <A HREF="help.html#This_document_s_Author">Stas Bekman</A>.
  -	     <BR>Last Modified at 08/07/1999
  +	     <BR>Last Modified at 09/26/1999
         </FONT>
       </B>
     </TD>
  
  
  
  1.19      +111 -3    modperl-site/guide/performance.html
  
  Index: performance.html
  ===================================================================
  RCS file: /export/home/cvs/modperl-site/guide/performance.html,v
  retrieving revision 1.18
  retrieving revision 1.19
  diff -u -r1.18 -r1.19
  --- performance.html	1999/08/17 19:03:44	1.18
  +++ performance.html	1999/09/25 23:14:09	1.19
  @@ -36,6 +36,8 @@
   
   	<LI><A HREF="#Preload_Registry_Scripts">Preload Registry Scripts</A>
   	<LI><A HREF="#Avoid_Importing_Functions">Avoid Importing Functions</A>
  +	<LI><A HREF="#PerlSetupEnv_Off">PerlSetupEnv Off</A>
  +	<LI><A HREF="#_DTWO_POT_OPTIMIZE_and_DPACK_MA">-DTWO_POT_OPTIMIZE and -DPACK_MALLOC Perl Options</A>
   	<LI><A HREF="#Shared_Memory">Shared Memory</A>
   	<LI><A HREF="#Checking_script_modification_tim">Checking script modification times</A>
   	<LI><A HREF="#How_can_I_find_if_my_mod_perl_sc">How can I find if my mod_perl scripts have memory leaks</A>
  @@ -83,6 +85,15 @@
   
   	     <HR>
   
  +	       Your corrections of either technical or grammatical
  +	       errors are very welcome. You are encouraged to help me
  +	       to improve this guide.  If you have something to
  +	       contribute please <A
  +	       HREF="help.html#This_document_s_Author"> send it
  +	       directly to me</A>.
  +
  +	       <HR>
  +
   	      <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
   <P>
   <CENTER><H1><A NAME="Performance_The_Overall_picture">Performance: The Overall picture</A></H1></CENTER>
  @@ -214,6 +225,21 @@
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
   <CENTER><H2><A NAME="Preload_Perl_modules_Real_Numb">Preload Perl modules - Real Numbers</A></H2></CENTER>
   <P>
  +(META: while the numbers and conclusions are mostly correct, need to
  +rewrite the whole benchmark section using the GTop library to report the
  +shared memory which is very important and will improve the benchmarks)
  +
  +<P>
  +(META: Add the memory size tests when the server was compiled with
  +EVERYTHING=1 and without it, does loading everything imposes a big change
  +in the memory footprint? Probably the suggestion would be as follows: For a
  +development server use EVERYTHING=1, while for a production if your server
  +is pretty busy and/or low on memory and every bit is on account, only the
  +required parts should be built in. BTW, remember that apache comes with
  +many modules that are being built by default, and you might not need
  +those!)
  +
  +<P>
   I have conducted a few tests to benchmark the memory usage when some
   modules are preloaded. The first set of tests checks the memory use with
   Library Perl Module preload (only <CODE>CGI.pm</CODE>). The second set checks the compile method of <CODE>CGI.pm</CODE>. The third test checks the benefit of Library Perl Module preload but a
  @@ -423,8 +449,24 @@
     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 by 3276K. Ouch: 512K more!!!
  +
  +<P>
  +The reason is that when you preload at the startup all of the methods, they
  +all are being precompiled, there are many of them and they take a big chunk
  +of memory. If you don't use the <CODE>compile()</CODE> method, only the
  +functions that are being used will be compiled. Yes, it will slightly slow
  +down the first reposnse of each process, but the actuall memory usage will
  +be lower. BTW, if you write in the script:
  +
  +<P>
  +<PRE>  use CGI qw(all);
  +</PRE>
   <P>
  -Observation: child httpd has grown by 3276K. Great difference: 512K less!!!
  +Only the symbols of all functions are being imported. While they are taking
  +some space, it's smaller than the space that a compiled code of these
  +functions might occupy.
   
   <P>
   <STRONG>Server restarted</STRONG>
  @@ -534,6 +576,52 @@
   
   <P>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<CENTER><H1><A NAME="PerlSetupEnv_Off">PerlSetupEnv Off</A></H1></CENTER>
  +<P>
  +<CODE>PerlSetupEnv Off</CODE> is another optimization you might consider.
  +
  +<P>
  +<EM>mod_perl</EM> fiddles with the environment to make it appear as if the script were being
  +called under the CGI protocol. For example, the
  +<CODE>$ENV{QUERY_STRING}</CODE> environment variable is initialized with the contents of <EM>Apache::args()</EM>, and <CODE>$ENV{SERVER_NAME}</CODE> is filled in from the value returned by <EM>Apache::server_hostname()</EM>.
  +
  +<P>
  +But <CODE>%ENV</CODE> population is expensive. Those who have moved to the Perl Apache API no
  +longer need this extra <CODE>%ENV</CODE> population, can gain by turning it <STRONG>Off</STRONG>.
  +
  +<P>
  +<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<CENTER><H1><A NAME="_DTWO_POT_OPTIMIZE_and_DPACK_MA">-DTWO_POT_OPTIMIZE and -DPACK_MALLOC Perl Options</A></H1></CENTER>
  +<P>
  +Newer Perl versions also have build time options to reduce runtime memory
  +consumption. These options might shrink down the size of your httpd by
  +about ~150k (quite big number if you remember to multiply it by the number
  +of chidren you use.)
  +
  +<P>
  +<CODE>-DTWO_POT_OPTIMIZE</CODE> macro improves allocations of data with size close to a power of two; but
  +this works for big allocations (starting with 16K by default). Such
  +allocations are typical for big hashes and special-purpose scripts,
  +especially image processing.
  +
  +<P>
  +Perl memory allocation is by bucket with sizes close to powers of two.
  +Because of these malloc overhead may be big, especially for data of size
  +exactly a power of two. If <CODE>PACK_MALLOC</CODE> is defined, perl uses a slightly different algorithm for small allocations
  +(up to 64 bytes long), which makes it possible to have overhead down to 1
  +byte for allocations which are powers of two (and appear quite often). 
  +
  +<P>
  +Expected memory savings (with 8-byte alignment in <CODE>alignbytes</CODE>) is about 20% for typical Perl usage. Expected slowdown due to additional
  +malloc overhead is in fractions of a percent (hard to measure, because of
  +the effect of saved memory on speed).
  +
  +<P>
  +You will find these and other memory improvement details in
  +<CODE>perl5004delta.pod</CODE>.
  +
  +<P>
  +<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
   <CENTER><H1><A NAME="Shared_Memory">Shared Memory</A></H1></CENTER>
   <P>
   You've probably noticed that the word shared is being repeated many times
  @@ -634,6 +722,10 @@
   <CODE>Apache::Status</CODE> now includes a new StatusLexInfo option.
   
   <P>
  +Apache::Leak works better if you've built a libperld.a (see SUPPORT) and
  +given PERL_DEBUG=1 to mod_perl's Makefile.PL
  +
  +<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>
  @@ -1756,7 +1848,8 @@
   <PRE>  PerlModule Apache::DBI
   </PRE>
   <P>
  -It is important, to load this module before any other <CODE>ApacheDBI*</CODE> module!
  +It is important, to load this module before any other <CODE>DBI</CODE>,
  +<CODE>DBD::*</CODE> and <CODE>ApacheDBI*</CODE> modules!
   
   <P>
   <PRE>  db.pl
  @@ -1794,6 +1887,11 @@
   that child process. See the <CODE>Apache::DBI</CODE> manpage to see the requirements for this method.
   
   <P>
  +You can also benefit from persistent connections by replacing
  +<CODE>prepare()</CODE> with <CODE>prepare_cached().</CODE> But it can
  +produce a little overhead (META, why?).
  +
  +<P>
   Another problem is with timeouts: some databases disconnect the client
   after a certain time of inactivity. This problem is known as <STRONG>morning
   bug</STRONG>. The <CODE>ping()</CODE> method ensures that this will not happen. Some
  @@ -1994,6 +2092,16 @@
   	     Amazon.com</a>.
   
   	     <HR>
  +
  +	     Your corrections of either technical or grammatical
  +	     errors are very welcome. You are encouraged to help me
  +	     to improve this guide.  If you have something to
  +	     contribute please <A
  +	     HREF="help.html#This_document_s_Author"> send it
  +	     directly to me</A>.
  +
  +	     <HR>
  +
   	     [    <A HREF="porting.html">Prev</A> |      <A HREF="index.html">Main Page</A> | <A HREF="strategy.html">Next</A>      ]
   
   <CENTER><TABLE CELLSPACING=2 CELLPADDING=2 WIDTH="100%" >
  @@ -2007,7 +2115,7 @@
       <B>
         <FONT SIZE=-1>
   	     Written by <A HREF="help.html#This_document_s_Author">Stas Bekman</A>.
  -	     <BR>Last Modified at 08/16/1999
  +	     <BR>Last Modified at 09/26/1999
         </FONT>
       </B>
     </TD>
  
  
  
  1.8       +19 -0     modperl-site/guide/perl.html
  
  Index: perl.html
  ===================================================================
  RCS file: /export/home/cvs/modperl-site/guide/perl.html,v
  retrieving revision 1.7
  retrieving revision 1.8
  diff -u -r1.7 -r1.8
  --- perl.html	1999/08/17 19:03:44	1.7
  +++ perl.html	1999/09/25 23:14:12	1.8
  @@ -52,6 +52,15 @@
   
   	     <HR>
   
  +	       Your corrections of either technical or grammatical
  +	       errors are very welcome. You are encouraged to help me
  +	       to improve this guide.  If you have something to
  +	       contribute please <A
  +	       HREF="help.html#This_document_s_Author"> send it
  +	       directly to me</A>.
  +
  +	       <HR>
  +
   	      <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>
  @@ -340,6 +349,16 @@
   	     Amazon.com</a>.
   
   	     <HR>
  +
  +	     Your corrections of either technical or grammatical
  +	     errors are very welcome. You are encouraged to help me
  +	     to improve this guide.  If you have something to
  +	     contribute please <A
  +	     HREF="help.html#This_document_s_Author"> send it
  +	     directly to me</A>.
  +
  +	     <HR>
  +
   	     [    <A HREF="modules.html">Prev</A> |      <A HREF="index.html">Main Page</A> | <A HREF="snippets.html">Next</A>      ]
   
   <CENTER><TABLE CELLSPACING=2 CELLPADDING=2 WIDTH="100%" >
  
  
  
  1.20      +1915 -389 modperl-site/guide/porting.html
  
  Index: porting.html
  ===================================================================
  RCS file: /export/home/cvs/modperl-site/guide/porting.html,v
  retrieving revision 1.19
  retrieving revision 1.20
  diff -u -r1.19 -r1.20
  --- porting.html	1999/08/17 19:03:44	1.19
  +++ porting.html	1999/09/25 23:14:13	1.20
  @@ -31,48 +31,54 @@
   	<LI><A HREF="#Exposing_Apache_Registry_secret">Exposing Apache::Registry secrets</A>
   	<LI><A HREF="#Sometimes_it_Works_Sometimes_it_">Sometimes it Works Sometimes it Does Not</A>
   	<LI><A HREF="#What_s_different_about_modperl">What's different about modperl</A>
  -	<UL>
  -
  -		<LI><A HREF="#Script_s_name_space">Script's name space</A>
  -		<LI><A HREF="#Name_collisions_with_Modules_and">Name collisions with Modules and libs</A>
  -		<LI><A HREF="#More_package_name_related_issues">More package name related issues</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_format_">Using format()</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_PerlSendHea">HTTP + MIME Headers (PerlSendHeader)</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>
  -		<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="#Passing_ENV_variables_to_CGI">Passing ENV variables to CGI</A>
  -		<LI><A HREF="#Global_Variables">Global Variables</A>
  -		<LI><A HREF="#Code_has_been_changed_but_it_se">Code has been changed, but it seems the script is running the old code</A>
  -		<LI><A HREF="#Apache_and_syslog">Apache and syslog</A>
  -		<LI><A HREF="#Memory_leakage">Memory leakage</A>
  -	</UL>
  -
  +	<LI><A HREF="#Script_s_name_space">Script's name space</A>
  +	<LI><A HREF="#Messing_with_INC">Messing with @INC</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>
  +		<LI><A HREF="#Using_Apache_StatINC_for_Develo">Using Apache::StatINC for Development Process</A>
  +		<LI><A HREF="#Configuration_Files_Writing_Mo">Configuration Files: Writing, Modifying and Reloading.</A>
  +		<UL>
  +
  +			<LI><A HREF="#Writing_Configuration_Files">Writing Configuration Files</A>
  +			<LI><A HREF="#Reloading_Configuration_Files">Reloading Configuration Files</A>
  +			<LI><A HREF="#Dynamically_updating_configurati">Dynamically updating configuration files</A>
  +		</UL>
  +
   		<LI><A HREF="#Reloading_handlers">Reloading handlers</A>
   	</UL>
   
  +	<LI><A HREF="#Name_collisions_with_Modules_and">Name collisions with Modules and libs</A>
  +	<LI><A HREF="#More_package_name_related_issues">More package name related issues</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_format_and_write_">Using format() and write()</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="#Special_Perl_Variables">Special Perl Variables</A>
  +	<LI><A HREF="#Generating_correct_HTTP_Headers">Generating correct HTTP Headers</A>
  +	<LI><A HREF="#NPH_Non_Parsed_Headers_scripts">NPH (Non Parsed Headers) scripts</A>
  +	<LI><A HREF="#BEGIN_blocks">BEGIN blocks </A>
  +	<LI><A HREF="#END_blocks">END blocks</A>
  +	<LI><A HREF="#Switches_w_T">Switches -w, -T</A>
  +	<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="#Passing_ENV_variables_to_CGI">Passing ENV variables to CGI</A>
  +	<LI><A HREF="#Global_Variables">Global Variables</A>
  +	<LI><A HREF="#Code_has_been_changed_but_it_se">Code has been changed, but it seems the script is running the old code</A>
  +	<LI><A HREF="#Apache_and_syslog">Apache and syslog</A>
  +	<LI><A HREF="#Memory_leakage">Memory leakage</A>
   	<LI><A HREF="#Filehandlers_and_locks_leakages">Filehandlers and locks leakages</A>
   	<LI><A HREF="#The_Script_is_too_dirty_but_It_">The Script is too dirty, but 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>
  +	<LI><A HREF="#Sharing_variables_between_proces">Sharing variables between processes</A>
   	<LI><A HREF="#Redirecting_Errors_to_Client_ins">Redirecting Errors to Client instead of error_log</A>
   	<LI><A HREF="#Finding_the_line_number_the_erro">Finding the line number the error/warning has been triggered at</A>
  -	<LI><A HREF="#Forking_subprocesses_from_mod_pe">Forking subprocesses from mod_perl</A>
  -	<LI><A HREF="#Generating_correct_HTTP_MIME_Hea">Generating correct HTTP MIME Headers</A>
  +	<LI><A HREF="#Forking_or_Executing_subprocesse">Forking or Executing subprocesses from mod_perl</A>
  +	<LI><A HREF="#Passing_and_preserving_custom_da">Passing and preserving custom data structures between handlers</A>
   </UL>
   <!-- INDEX END -->
   
  @@ -88,6 +94,15 @@
   
   	     <HR>
   
  +	       Your corrections of either technical or grammatical
  +	       errors are very welcome. You are encouraged to help me
  +	       to improve this guide.  If you have something to
  +	       contribute please <A
  +	       HREF="help.html#This_document_s_Author"> send it
  +	       directly to me</A>.
  +
  +	       <HR>
  +
   	      <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>
  @@ -130,10 +145,16 @@
   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>
  +The information is very relevant to a mod_perl developer.
  +
  +<P><LI><STRONG><A NAME="item_The">The Eagle Book</A></STRONG>
  +<P>
  +``Writing Apache Modules with Perl and C'' is a ``must have'' book!
   
  -<P><LI><STRONG><A NAME="item_Mod">Mod Perl Book</A></STRONG>
   <P>
  -A must have book! See the details at <A
  +See the details at <A
   HREF="http://www.modperl.com">http://www.modperl.com</A> .
   
   </UL>
  @@ -309,8 +330,8 @@
   the <CODE>handler</CODE> subroutine.
   
   <P>
  -The workaround is to use global declared variables, with <CODE>vars</CODE>
  -pragma.
  +One of the workarounds is to use global declared variables, with
  +<CODE>vars</CODE> pragma.
   
   <P>
   <PRE>  # !/usr/bin/perl -w
  @@ -355,16 +376,133 @@
       print &quot;Counter is equal to $main::counter !&lt;BR&gt;\n&quot;;
     }
   </PRE>
  +<P>
  +Another working but not quite good solution, is always to pass the variable
  +as an argument. It's not good when the variable can be quite big, so it
  +adds an overhead of time and memory. 
  +
  +<P>
  +<PRE>  #!/usr/bin/perl -w
  +  use strict;
  +  
  +  print &quot;Content-type: text/html\r\n\r\n&quot;;
  +  
  +  my $counter = 0;
  +  
  +  for (1..5) {
  +    increment_counter($counter);
  +  }
  +  
  +  sub increment_counter{
  +    my $counter = shift || 0 ;
  +    $counter++; 
  +    print &quot;Counter is equal to $counter !&lt;BR&gt;\n&quot;;
  +  }
  +</PRE>
  +<P>
  +It's important to understand that the closure effect happens only with code
  +that <CODE>Apache::Registry</CODE> wraps with a declaration of the
  +<CODE>handler</CODE> subroutine. If you put your code into a library or module, which the main
  +script <CODE>require()'s</CODE> or <CODE>use()'s,</CODE> there is no such a
  +problem. For example if we put the subroutine <CODE>increment_counter()</CODE>
  +into a <CODE>mylib.pl</CODE> (e.g. save it in the same directory as the main script) and
  +<CODE>require()</CODE> it, there will be no problem at all. (Don't forget
  +the <CODE>1;</CODE> at the end of the library or the <CODE>require()</CODE> might fail.)
  +
  +<P>
  +<PRE>  mylib.pl:
  +  ----------
  +  sub increment_counter{
  +    $counter++;
  +    print &quot;Counter is equal to $counter !&lt;BR&gt;\n&quot;;
  +  }
  +  1;
  +  ----------
  +</PRE>
  +<P>
  +<PRE>  counter.pl:
  +  ----------
  +  #!/usr/bin/perl -w
  +  use strict;
  +  require &quot;./mylib.pl&quot;;
  +  
  +  print &quot;Content-type: text/html\r\n\r\n&quot;;
  +  
  +  my $counter = 0;
  +  
  +  for (1..5) {
  +    increment_counter();
  +  }
  +  
  +  ----------
  +</PRE>
  +<P>
  +Personally, unless the script is too short, I've got used to write all the
  +code in the external libraries, and to have only a few lines in the main
  +script, generally to call the main function of my library. Usually i call
  +it <CODE>init()</CODE>. I don't worry about closure effect anymore (unless I create it myself :).
  +
  +<P>
  +You shouldn't be intimidated by this issue at all, since Perl is your
  +friend. Just keep the warnings mode On and whenever you will have this
  +effect in place, Perl will gladly tell you that by saying:
  +
  +<P>
  +<PRE>  Variable &quot;$counter&quot; will not stay shared at ...[snipped]
  +</PRE>
  +<P>
  +Just don't forget to check your error_log file, before going in production!
  +
  +<P>
  +BTW, the above example was pretty boring. In my first days of using
  +mod_perl, I wrote some cool user registration program. I'll show a very
  +simple represenataion of this program.
  +
  +<P>
  +<PRE>  use CGI;
  +  $q = new CGI;
  +  my $name = $q-&gt;param('name')
  +  print_respond();
  +  
  +  sub print_respond{
  +    print &quot;Content-type: text/html\n\n&quot;;
  +    print &quot;Thank you, $name!&quot;;
  +  }
  +</PRE>
  +<P>
  +My boss and I have checked the program at the development server at it
  +worked OK. So we decided to put it in production, everything was OK, but my
  +boss decided to keep on checking by submitting a variations of his profile.
  +Imagine what was the surprise when after submitting his name (let's say
  +``Me Boss'' :), he saw a response ``Thank you, Stas Bekman!''. What
  +happened is that I tried the production system as well. I was new to
  +mod_perl stuff and was so excited with the speed improve, I didn't notice
  +the clusure problem and it hit me. At the beginning I thought that may be
  +Apache started to confuse connection, by returning responses from other
  +people's requests. I was wrong of course. Why didn't we notice this when we
  +were trying the system at our development server? Keep reading and you will
  +understand what was the problem.
  +
  +<P>
  +Now let's return to our original example and proceed with the second
  +mystery we have noticed. Why did we see inconsistent results over numerous
  +reloads. That's very simple. Every time a server gets a request to process,
  +it handles it over one of the children, generally in a round robin fashion.
  +So if you have 10 httpd children alive, first 10 reloads might seem to be
  +correct. Since the closure starts to effect from the second re-invocation,
  +consequent reloads return unexpected results. Moreover children don't serve
  +the same request always consequently, at any given moment one of the
  +children could serve more times the same script than any other. That's why
  +we saw that strange behavior.
  +
   <P>
  -Now let's proceed to the second mystery. Why did we see inconsistent
  -results over numerous reloads. That's very simple. Every time a server gets
  -a request to process, it handles it over one of the children, generally in
  -a round robin fashion. So if you have 10 httpd children alive, first 10
  -reloads might seem to be correct. Since the closure starts to effect from
  -the second re-invocation, consequent reloads return unexpected results.
  -Moreover children don't serve the same request always consequently, at any
  -given moment one of the children could serve more times the same script
  -than any other. That's why we saw that strange behavior.
  +And now you understand why we didn't notice the problem with the user
  +registration system in the last example I've presented. First we didn't
  +look at the error_log files. (As a matter of fact we did, but there were so
  +many warnings in there, we couldn't tell what are the important ones and
  +what aren't). Then we didn't test the system under
  +<CODE>-X</CODE> flag (single mode) and we have had too many server children running to
  +notice the problem.
   
   <P>
   A workaround is to run the server in a single server mode. You achieve this
  @@ -403,6 +541,138 @@
   sometimes it helps.
   
   <P>
  +Sometimes it's very hard to understand what the warning complains about,
  +you see the source code, but you cannot understand why some specific
  +snippet produces warning. The mystery is in fact that the code can be
  +called from different places, e.g when it's a subrotine.
  +
  +<P>
  +I'll show you an example of such code.
  +
  +<P>
  +<PRE>  local $^W=1;
  +  good();
  +  bad();
  +  
  +  sub good{
  +    print_value(&quot;Perl&quot;);
  +  }
  +  
  +  sub bad{
  +    print_value();
  +  }
  +  
  +  sub print_value{
  +    my $var = shift;
  +    print &quot;My value is $var\n&quot;;
  +  }
  +</PRE>
  +<P>
  +In the code above, there is a sub that prints the passed value, sub
  +<CODE>good</CODE> that passes correctly the value and sub <CODE>bad</CODE> where we forgot to pass it. When we run the script, we get the warning:
  +
  +<P>
  +<PRE>  Use of uninitialized value at ./warning.pl line 15.
  +</PRE>
  +<P>
  +We can clearly see that there is an undefined value at the line, that
  +attempts to print it:
  +
  +<P>
  +<PRE>  print &quot;My value is $var\n&quot;;
  +</PRE>
  +<P>
  +But how do we know, why it was undefined? The solution is quite simple.
  +What we need is a full stack trace which triggered the warning.
  +
  +<P>
  +The <CODE>Carp</CODE> module comes to help with its <CODE>cluck()</CODE> function. Let's modify the script:
  +
  +<P>
  +<PRE>  use Carp ();
  +  local $SIG{__WARN__} = \&amp;Carp::cluck;
  +  
  +  local $^W=1;
  +  good();
  +  bad();
  +  
  +  sub good{
  +    print_value(&quot;Perl&quot;);
  +  }
  +  
  +  sub bad{
  +    print_value();
  +  }
  +  
  +  sub print_value{
  +    my $var = shift;
  +    print &quot;My value is $var\n&quot;;
  +  }
  +</PRE>
  +<P>
  +Now when we execute it, we would see:
  +
  +<P>
  +<PRE>  Use of uninitialized value at /home/httpd/perl/book/warning.pl line 17.
  +  Apache::ROOT::perl::book::warning_2epl::print_value() 
  +    called at /home/httpd/perl/book/warning.pl line 12
  +  Apache::ROOT::perl::book::warning_2epl::bad() 
  +    called at /home/httpd/perl/book/warning.pl line 5
  +  Apache::ROOT::perl::book::warning_2epl::handler('Apache=SCALAR(0x84b1154)') 
  +    called at /usr/lib/perl5/site_perl/5.005/i386-linux/Apache/Registry.pm line 139
  +  eval {...} called at 
  +    /usr/lib/perl5/site_perl/5.005/i386-linux/Apache/Registry.pm line 139
  +  Apache::Registry::handler('Apache=SCALAR(0x84b1154)') 
  +    called at PerlHandler subroutine `Apache::Registry::handler' line 0
  +  eval {...} called at PerlHandler subroutine `Apache::Registry::handler' line 0
  +</PRE>
  +<P>
  +Take a moment to understand the trace, the only part that we are intersted
  +in is the one that starts when actuall script is being called, so we can
  +skip the <CODE>Apache::Registry</CODE> trace part. So we get:
  +
  +<P>
  +<PRE>  Use of uninitialized value at /home/httpd/perl/book/warning.pl line 17.
  +  Apache::ROOT::perl::book::warning_2epl::print_value() 
  +    called at /home/httpd/perl/book/warning.pl line 12
  +  Apache::ROOT::perl::book::warning_2epl::bad() 
  +    called at /home/httpd/perl/book/warning.pl line 5
  +</PRE>
  +<P>
  +which tells us that the code that triggered the warning was:
  +
  +<P>
  +<PRE>  Apache::Registry code =&gt; bad() =&gt; print_value()
  +</PRE>
  +<P>
  +We go into a <CODE>bad()</CODE> and indeed see that we forgot to pass the variable. Of course when you
  +write a subroutine like <CODE>print_value</CODE> it could be a good idea to check the passed arguments before starting the
  +execution. But it was ``good'' enough to show you how to ease the code
  +debugging process.
  +
  +<P>
  +Sure, you would say. I could find the problem by a simple inspectation of
  +the code. You are right, but I promise you that your task would be quite
  +complicated and time consuming for the code of thousands lines.
  +
  +<P>
  +Notice the <CODE>local()</CODE> keyword, before the settings of the
  +<CODE>$SIG{__WARN__}</CODE>. Since it's a global variable, forgetting to use
  +<CODE>local()</CODE> will enforce this setting for all the scripts running under the same
  +process. And if it's wanted behaviour, for example in the development
  +server, you better do it in the startup file, where you can easily switch
  +this feature on and off when the server restarts.
  +
  +<P>
  +As you have noticed warnings report the line number the event happened at,
  +so it's supposed to help to find the problematic code. The problem is that
  +many times the line numbers are incorrect, because certain use of the <EM>eval</EM> operator and ``here'' documents are known to throw off Perl's line
  +numbering.
  +
  +<P>
  +META: move here the code that explains the settings of #line
  +
  +<P>
   While having a warning mode turned <STRONG>On</STRONG> is a must in a development server, you better turn it globally <STRONG>Off</STRONG> in a production server, since if every CGI script generates only one
   warning per request, and your server serves millions of requests per day -
   your log file will eat up all of your disk space and machine will die. My
  @@ -518,7 +788,7 @@
   
   <P>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<CENTER><H2><A NAME="Script_s_name_space">Script's name space</A></H2></CENTER>
  +<CENTER><H1><A NAME="Script_s_name_space">Script's name space</A></H1></CENTER>
   <P>
   Scripts under <CODE>Apache::Registry</CODE> do not run in package <STRONG>main</STRONG>, they run in a unique name space based on the requested URI. For example,
   if your URI is <STRONG>/perl/test.pl</STRONG> the package will be called
  @@ -526,147 +796,1200 @@
   
   <P>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<CENTER><H2><A NAME="Name_collisions_with_Modules_and">Name collisions with Modules and libs</A></H2></CENTER>
  +<CENTER><H1><A NAME="Messing_with_INC">Messing with @INC</A></H1></CENTER>
   <P>
  -To make things clear before we go into details: each child process has its
  -own <CODE>%INC</CODE> hash which is used to store information about its compiled modules. The
  -keys of the hash are the names of the modules or parameters passed to <CODE>require()</CODE> (<CODE>use()</CODE>). The values are the full or relative paths to these modules/files. Let's
  -say we have
  -<CODE>my-lib.pl</CODE> and <CODE>MyModule.pm</CODE> both located at <CODE>/home/httpd/perl/my/</CODE>.
  +When you <CODE>use(),</CODE> <CODE>require()</CODE> or <CODE>do()</CODE> a
  +file, Perl uses a <CODE>@INC</CODE>
  +variable, for a list of directories to search for the file. If the file
  +that you want to load is not located in one of the listed directories. You
  +have to tell Perl where to find the file.
  +
  +<P>
  +In order to <CODE>require()</CODE> a file located at
  +<CODE>/home/httpd/perl/examples/test.pl</CODE> you would:
   
  +<UL>
  +<P><LI>
   <P>
  -* <CODE>/home/httpd/perl/my/</CODE> is in the <CODE>@INC</CODE> path at the server startup.
  +Use a relative path to one of the directories in the <CODE>@INC</CODE>. Let's say that one of the directories is <CODE>/home/httpd/perl</CODE>.
   
   <P>
  -<PRE>  require &quot;my-lib.pl&quot;;
  -  use MyModule.pm;
  -  print $INC{&quot;my-lib.pl&quot;},&quot;\n&quot;;
  -  print $INC{&quot;MyModule.pm&quot;},&quot;\n&quot;;
  +<PRE>  require(&quot;examples/test.pl&quot;);
   </PRE>
   <P>
  -prints:
  +or modify the <CODE>@INC</CODE> on the fly:
   
   <P>
  -<PRE>  /home/httpd/perl/my/my-lib.pl
  -  /home/httpd/perl/my/MyModule.pm
  +<PRE>  use lib qw(&quot;examples&quot;);
  +  require(&quot;test.pl&quot;);
   </PRE>
   <P>
  -Adding <CODE>use lib</CODE>:
  +That's when the script might be called from any place. If you always
  +execute the script from the directory it resides in (<CODE>examples</CODE>
  +here), you can do:
   
   <P>
  -<PRE>  use lib qw(.);
  -  require &quot;my-lib.pl&quot;;
  -  use MyModule.pm;
  -  print $INC{&quot;my-lib.pl&quot;},&quot;\n&quot;;
  -  print $INC{&quot;MyModule.pm&quot;},&quot;\n&quot;;
  +<PRE>  use lib qw(&quot;.&quot;);
  +  require(&quot;test.pl&quot;);
   </PRE>
   <P>
  -prints:
  +But the latest two snippets would fail the reload by
  +<CODE>Apache::StatINC</CODE> module (which helps to automatically reload scripts while developing code)
  +since when running under mod_perl, <CODE>@INC</CODE> is being freezed, once the server is up and cannot be updated. The only
  +chance to temperarely modify the <CODE>@INC</CODE> is while the script is being loaded and compiled for the first time, and
  +when it's done, its value will be reset to the original one. Your only
  +chance to change the
  +<CODE>@INC</CODE> is to modify it in the startup or Apache configuration files.
   
  +<P><LI>
   <P>
  -<PRE>  my-lib.pl
  -  MyModule.pm
  +You can write a full path to the script:
  +
  +<P>
  +<PRE>  require(&quot;/home/httpd/perl/examples/test.pl&quot;)
   </PRE>
   <P>
  -* <CODE>/home/httpd/perl/my/</CODE> isn't in the <CODE>@INC</CODE> path at the server startup.
  +or
   
   <P>
  -<PRE>  require &quot;my-lib.pl&quot;;
  -  use MyModule.pm;
  -  print $INC{&quot;my-lib.pl&quot;},&quot;\n&quot;;
  -  print $INC{&quot;MyModule.pm&quot;},&quot;\n&quot;;
  +<PRE>  use lib qw(&quot;/home/httpd/perl/examples/&quot;);
  +  require(&quot;test.pl&quot;);
   </PRE>
   <P>
  -Wouldn't work, since perl cannot find the modules.
  +the latter will fail the reload of <CODE>Apache::StatINC</CODE> as above. The former will set a correct entry into a <CODE>%INC</CODE> variable.
   
   <P>
  -Adding <CODE>use lib</CODE>:
  +This approach is quite discouraging, since if you want to move this script
  +around -- it's quite difficult since you have to modify the path all the
  +time. And it can be pretty painful when you move scripts from development
  +to production server.
   
  -<P>
  -<PRE>  use lib qw(.);
  -  require &quot;my-lib.pl&quot;;
  -  use MyModule.pm;
  -  print $INC{&quot;my-lib.pl&quot;},&quot;\n&quot;;
  -  print $INC{&quot;MyModule.pm&quot;},&quot;\n&quot;;
  -</PRE>
   <P>
  -prints:
  +But wait, Graham Barr &amp; Nick Ing-Simmons made a present for you by
  +writing the <CODE>FindBin</CODE> module, if you know about this module, you don't need to write a hardcoded
  +path. The following snippet does all the work for you:
   
   <P>
  -<PRE>  my-lib.pl
  -  MyModule.pm
  +<PRE>  use FindBin ();
  +  use lib &quot;$FindBin::Bin&quot;;
  +  use MyModule;
   </PRE>
   <P>
  -I'm talking about single server child below!
  +It works exactly like with hardcoded path, and it sets a correct
  +<CODE>%INC</CODE> entry as if you have used the hardcoded path while using
  +<CODE>require().</CODE>
   
  +</UL>
   <P>
  -Let's look at 3 faulty script's name space related scenarios:
  -
  -<DL>
  -<P><DT><STRONG><A NAME="item_Scenario">Scenario 1</A></STRONG><DD>
  +<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>
  -First, You can't have 2 identical module names running under the same
  -server! Only the first one <CODE>use()</CODE>'d or <CODE>require()</CODE>'d 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's already in the child's <CODE>%INC</CODE>. (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)
  +When you develop plain CGI scripts, you can just change the code, and rerun
  +the CGI from your browser. Since the script isn't cached in memory, the
  +next time you call it the server starts up a new perl process, which
  +recompiles it from scratch. The effects of any modifications you've applied
  +are immediately present.
   
   <P>
  -So if you have two different <CODE>Foo</CODE> modules in two different directories and two scripts <CODE>script1.pl</CODE> and <CODE>script2.pl</CODE>, placed like:
  +The situation is different with <CODE>Apache::Registry</CODE>, since the whole idea is to get maximum performance from the server. By
  +default, the server won't spend the time to check whether any included
  +library modules have been changed. It assumes that they weren't, thus
  +saving a few milliseconds to <CODE>stat()</CODE> the source file (multiplied by however many modules/libraries you are <CODE>use()</CODE>-ing and/or <CODE>require()</CODE>-ing in your script.) 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
  +<CODE>use()</CODE> (or <CODE>require()</CODE>) other perl modules (or packages), there is nothing new about it. If
  +however, you are developing a script that includes other modules, the files
  +you <CODE>use()</CODE> or <CODE>require()</CODE> aren't being checked whether they have been modified.
   
  -<P>
  -<PRE>  ./perl/tool1/Foo.pm
  -  ./perl/tool1/tool1.pl
  -  ./perl/tool2/Foo.pm
  -  ./perl/tool2/tool2.pl
  -</PRE>
   <P>
  -Where a sample code could be:
  +Acknowledging this, how do we get our modperl-enabled server to recognize
  +changes in any library modules? Well, there are a couple of techniques:
   
   <P>
  -<PRE>  ./perl/tool1/tool1.pl
  -  --------------------
  -  use Foo;
  -  print &quot;Content-type: text/html\n\n&quot;;
  -  print &quot;I'm Script number One&lt;BR&gt;\n&quot;;
  -  foo();
  -  --------------------
  -</PRE>
  +<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>
  -<PRE>  ./perl/tool1/Foo.pm
  -  --------------------
  -  sub foo{
  -    print &quot;&lt;B&gt;I'm Tool Number One!&lt;/B&gt;&lt;BR&gt;\n&quot;;
  -  }
  -  1;
  -  --------------------
  -</PRE>
  +The simplest approach is to restart the server each time you apply some
  +change to your code. See <A HREF="././control.html#Restarting_techniques">Server Restarting techniques</A>.
  +
   <P>
  -<PRE>  ./perl/tool2/tool2.pl
  -  --------------------
  -  use Foo;
  -  print &quot;Content-type: text/html\n\n&quot;;
  -  print &quot;I'm Script number Two&lt;BR&gt;\n&quot;;
  -  foo();
  -  --------------------
  -</PRE>
  +<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<CENTER><H2><A NAME="Using_Apache_StatINC_for_Develo">Using Apache::StatINC for Development Process</A></H2></CENTER>
   <P>
  -<PRE>  ./perl/tool2/Foo.pm
  -  --------------------
  -  sub foo{
  -    print &quot;&lt;B&gt;I'm Tool Number Two!&lt;/B&gt;&lt;BR&gt;\n&quot;;
  -  }
  -  1;
  -  --------------------
  -</PRE>
  +After restarting the server about 100 times, you will be tired and will
  +look for another solutions. Help comes from the
  +<CODE>Apache::StatINC</CODE> module.
  +
   <P>
  -And both scripts call: <CODE>use Foo;</CODE> -- only the first one called will know about <CODE>Foo</CODE>, when you will call the second script it will not know about <CODE>Foo</CODE> at all - it's like you've forgotten to write <CODE>use
  -Foo;</CODE>. Run the server in <A HREF="././control.html#Running_server_in_a_single_mode">single server mode</A> to detect this kind of bug immediately.
  +<CODE>Apache::StatINC</CODE> reloads <CODE>%INC</CODE> files when updated on disk. When Perl pulls a file via require, it stores
  +the filename in the global hash <CODE>%INC</CODE>. The next time Perl tries to require the same file, it sees the file in <CODE>%INC</CODE> and does not reload from disk. This module's handler iterates over <CODE>%INC</CODE> and reloads the file if it has changed on disk.
   
   <P>
  -You will see the following in the error_log file:
  +To enable this module just add two lines to <CODE>httpd.conf</CODE> file.
   
   <P>
  -<PRE>  Undefined subroutine
  +<PRE>  PerlModule Apache::StatINC
  +  PerlInitHandler Apache::StatINC
  +</PRE>
  +<P>
  +To be sure it really works, turn on the debug mode on your development box
  +with <CODE>PerlSetVar StatINCDebug On</CODE>. You end up with something like:
  +
  +<P>
  +<PRE>  PerlModule Apache::StatINC
  +  &lt;Location /perl&gt;
  +    SetHandler perl-script
  +    PerlHandler Apache::Registry::handler
  +    Options ExecCGI
  +    PerlSendHeader On
  +    PerlInitHandler Apache::StatINC
  +    PerlSetVar StatINCDebug On
  +  &lt;/Location&gt;
  +</PRE>
  +<P>
  +Beware that 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 (in startup file).
  +
  +<P>
  +Whatever you do in your scripts and modules which are being <CODE>required()</CODE> after the server startup will not have any effect on <CODE>@INC</CODE>. When you do:
  +
  +<P>
  +<PRE>  use lib qw(foo/bar);
  +</PRE>
  +<P>
  +the <CODE>@INC</CODE> is being changed only for the time the code is being parsed and compiled.
  +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://www.nowhere.com/perl-status?inc">http://www.nowhere.com/perl-status?inc</A>
  +and look at the bottom of the page. (I assume you have configured the <A HREF="././config.html#_perl_status_location">/perl-status location</A>.)
  +
  +<P>
  +Also, notice the following caveat: While ``<CODE>.</CODE>'' is in the <CODE>@INC</CODE> -- perl knows to <CODE>require()</CODE> files relative to the script directory. Once the script was parsed - the
  +server doesn't remember the path any more! So you end up with broken entry
  +in <CODE>%INC</CODE> like:
  +
  +<P>
  +<PRE>  $INC{bar.pl} eq &quot;bar.pl&quot;
  +</PRE>
  +<P>
  +If you want Apache::StatINC to reload your script - modify the <CODE>@INC</CODE>
  +at the server startup file! or use a full path in <CODE>require()</CODE> call.
  +
  +<P>
  +<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<CENTER><H2><A NAME="Configuration_Files_Writing_Mo">Configuration Files: Writing, Modifying and Reloading.</A></H2></CENTER>
  +<P>
  +Checking all the modules in <STRONG>%INC</STRONG> every time can add a large overhead to server response times, and you
  +certainly would not want
  +<CODE>Apache::StatINC</CODE> module to be enabled in your production site's configuration. But sometimes
  +you want to have a configuration file to be reloaded when this updated,
  +without restarting the server.
  +
  +<P>
  +This is especially important feature if you have a person that is allowed
  +to modify some of the tool configuration, but it's very undesirable for
  +this person to telnet to the server to restart it, for either this admin
  +person's lack of profeccional skills or because of security reasons -- you
  +don't want to give a root password, unless you have to.
  +
  +<P>
  +<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<CENTER><H3><A NAME="Writing_Configuration_Files">Writing Configuration Files</A></H3></CENTER>
  +<P>
  +Since we are talking about configuration files, I would like to jump on
  +this and show you some good and bad approaches of configuration file
  +writing.
  +
  +<P>
  +If you have a configuration file of just a few variables, it doesn't really
  +matter how you do it. But generally this is not a case. Configuration files
  +tend to grow as a project grows. It's very relevant to the projects that
  +generate HTML files, since the they tend to demand many easily configurable
  +parameters, like headers, tails, colors and so on.
  +
  +<P>
  +So let's start from the basic approach that is being mostly deployed by
  +many CGI scripts writers. This approach is based on having many variables
  +defined in a separate configuration file. For example:
  +
  +<P>
  +<PRE>  $cgi_dir = &quot;/home/httpd/perl&quot;;
  +  $cgi_url = &quot;/perl&quot;;
  +  $docs_dir = &quot;/home/httpd/docs&quot;;
  +  $docs_url = &quot;/&quot;;
  +  $img_dir = &quot;/home/httpd/docs/images&quot;;
  +  $img_url = &quot;/images&quot;;
  +  ... many more config params here ...
  +  $color_hint   = &quot;#777777&quot;;
  +  $color_warn   = &quot;#990066&quot;;
  +  $color_normal = &quot;#000000&quot;;
  +</PRE>
  +<P>
  +Now when we want to use these variables in the mod_perl script we must
  +declare them all with help of <CODE>use vars</CODE> in the script, because of the <CODE>use strict;</CODE> pragma, which demands all the variables to be declared if used in the
  +script. 
  +
  +<P>
  +So we start the script with:
  +
  +<P>
  +<PRE>  use strict;
  +  use vars qw($cgi_dir $cgi_url $docs_dir $docs_url 
  +              ... many more config params here ....
  +              $color_hint  $color_warn $color_normal
  +             );
  +</PRE>
  +<P>
  +This is a nightmare to maintain such a script, especially if not all the
  +features were written yet, so you keep adding and reming the names to the
  +list. But that's not a big deal.
  +
  +<P>
  +Since we want our code clean, we start the configuration file with
  +<CODE>use strict;</CODE> as well, so we have to list the variables here as well. Second list to
  +maintain.
  +
  +<P>
  +The moment you will have many scripts, you will get into a problem of
  +collisions between configuration files, where one of the best solutions is
  +a package declaration, which makes the scripts unique (if you declare
  +unique package names of course).
  +
  +<P>
  +The moment you add a package declaration and think that you are done, you
  +just realize that the nightmare has just begun. The moment you have
  +declared the package, you cannot just <CODE>require()</CODE> the file and
  +use the variables, since they now belong to a different package. So you
  +have ether to modify all you script to use a fully qualified notation like <CODE>$My::Config::cgi_url</CODE> instead of just <CODE>$cgi_url</CODE> or to import the need variables into a script that is going to use them.
  +
  +<P>
  +Since you don't want extra typing to make the variables fully qualified,
  +you would go for importing approach. But your configuration package has to
  +export them first. It means that you have to list all the variables again
  +and now to keep at least three variable lists updated, when you do some
  +changes in the naming of the configuration variables. And that's when you
  +have only one script that uses the configuration file, in a general case
  +you have many of them. So now our example of config file looks like that.
  +
  +<P>
  +<PRE>  package My::Config;
  +  use strict;
  +  
  +  BEGIN {
  +    use Exporter ();
  +  
  +    @My::HTML::ISA       = qw(Exporter);
  +    @My::HTML::EXPORT    = qw();
  +    @My::HTML::EXPORT_OK = qw($cgi_dir $cgi_url $docs_dir $docs_url
  +                              ... many more config params here ....
  +                              $color_hint $color_warn $color_normal);
  +  }
  +  
  +  use vars qw($cgi_dir $cgi_url $docs_dir $docs_url 
  +              ... many more config params here ....
  +              $color_hint  $color_warn $color_normal
  +             );
  +  
  +  $cgi_dir = &quot;/home/httpd/perl&quot;;
  +  $cgi_url = &quot;/perl&quot;;
  +  $docs_dir = &quot;/home/httpd/docs&quot;;
  +  $docs_url = &quot;/&quot;;
  +  $img_dir = &quot;/home/httpd/docs/images&quot;;
  +  $img_url = &quot;/images&quot;;
  +  ... many more config params here ...
  +  $color_hint   = &quot;#777777&quot;;
  +  $color_warn   = &quot;#990066&quot;;
  +  $color_normal = &quot;#000000&quot;;
  +</PRE>
  +<P>
  +And in the code:
  +
  +<P>
  +<PRE>  use strict;
  +  use My::Config qw($cgi_dir $cgi_url $docs_dir $docs_url 
  +                    ... many more config params here ....
  +                    $color_hint  $color_warn $color_normal
  +                   );
  +  use vars       qw($cgi_dir $cgi_url $docs_dir $docs_url 
  +                    ... many more config params here ....
  +                    $color_hint  $color_warn $color_normal
  +                   );
  +</PRE>
  +<P>
  +But as we know this approach is especially bad in a context of mod_perl
  +usage, since exported variables add a memory overhead. The more variables
  +are being exported the more memory you use. Now as usual we rememeber to
  +multiply this overhead by number of the servers we are going to run and we
  +receive a pretty big number, which could be used to run a few more servers
  +instead.
  +
  +<P>
  +As a matter of fact things aren't so horrible, since you can group your
  +variables, and call the groups by special names called tags, which can
  +later be used as arguments to the <CODE>import()</CODE> or
  +<CODE>use().</CODE> You probably familiar with:
  +
  +<P>
  +<PRE>  use CGI qw(:standard :html);
  +</PRE>
  +<P>
  +We can implement it quite easily, with help of <CODE>exporter_tags()</CODE>
  +and <CODE>export_ok_tags()</CODE> from <CODE>Exporter</CODE>. For example:
  +
  +<P>
  +<PRE>  BEGIN {
  +    use Exporter ();
  +    use vars qw( @ISA @EXPORT @EXPORT_OK %EXPORT_TAGS);
  +    @ISA         = qw(Exporter);
  +    @EXPORT      = qw();
  +    @EXPORT_OK   = qw();
  +    
  +    %EXPORT_TAGS = (
  +      vars =&gt; [qw($fname $lname)],
  +      subs =&gt; [qw(reread_conf untaint_path)],
  +    );
  +    Exporter::export_ok_tags('vars');
  +    Exporter::export_ok_tags('subs');
  +  }
  +</PRE>
  +<P>
  +Yes, you export subroutines exactly like variables, since what's actually
  +being exported is a symbol. The definition of these subroutines is not
  +shown here.
  +
  +<P>
  +In your code now you can write:
  +
  +<P>
  +<PRE>  use My::Config qw(:subs :vars);
  +</PRE>
  +<P>
  +Regarding groups of groups. Like the <CODE>:all</CODE> tag from <CODE>CGI.pm</CODE>, which is a group tag of all other groups. It will require a little more
  +magic from your side, but you can always save your time and look up the
  +solution inside the code of <CODE>CGI.pm</CODE>. It's just a matter of a little code to expand all the groups recursively.
  +
  +<P>
  +After going through a pain of maintaining a list of variables in a big
  +project with a huge configuration file (more than 100 variables) and many
  +files actually using them, I have come up with a much simpler solution,
  +using a single hash, and having all the variables kept inside. Now my
  +configuration file looks like:
  +
  +<P>
  +<PRE>  package My::Config;
  +  use strict;
  +  
  +  BEGIN {
  +    use Exporter ();
  +  
  +    @My::Config::ISA       = qw(Exporter);
  +    @My::Config::EXPORT    = qw();
  +    @My::Config::EXPORT_OK = qw(%c);
  +  }
  +  
  +  use vars qw(%c);
  +  
  +  %c = 
  +    (
  +     dir =&gt; {
  +             cgi  =&gt; &quot;/home/httpd/perl&quot;,
  +             docs =&gt; &quot;/home/httpd/docs&quot;,
  +             img  =&gt; &quot;/home/httpd/docs/images&quot;,
  +            },
  +     url =&gt; {
  +             cgi  =&gt; &quot;/perl&quot;,
  +             docs =&gt; &quot;/&quot;,
  +             img  =&gt; &quot;/images&quot;,
  +            },
  +     color =&gt; {
  +               hint   =&gt; &quot;#777777&quot;,
  +               warn   =&gt; &quot;#990066&quot;,
  +               normal =&gt; &quot;#000000&quot;,
  +              },
  +    );
  +</PRE>
  +<P>
  +A good perl style suggests keeping a comma at the end of lists. That's
  +because additional items are tend to be added to the end of the list, and
  +when you keep a last comma in place, you never have to remember to add one
  +when you add a new item.
  +
  +<P>
  +So now the script looks like:
  +
  +<P>
  +<PRE>  use strict;
  +  use My::Config qw(%c);
  +  use vars       qw(%c)
  +  print &quot;Content-type: text/plain\n\n&quot;;
  +  print &quot;My url docs root: $c{url}{docs}\n&quot;;
  +</PRE>
  +<P>
  +Do you see the difference? The whole mess has gone, there is only one
  +variable to worry about.
  +
  +<P>
  +So far so good, but let's make it even better. I would like to get rid of <CODE>Exporter</CODE> stuff at all. I remove all the exporting code so my config file now looks
  +like:
  +
  +<P>
  +<PRE>  package My::Config;
  +  use strict;
  +  use vars qw(%c);
  +  
  +  %c = 
  +    (
  +     dir =&gt; {
  +             cgi  =&gt; &quot;/home/httpd/perl&quot;,
  +             docs =&gt; &quot;/home/httpd/docs&quot;,
  +             img  =&gt; &quot;/home/httpd/docs/images&quot;,
  +            },
  +     url =&gt; {
  +             cgi  =&gt; &quot;/perl&quot;,
  +             docs =&gt; &quot;/&quot;,
  +             img  =&gt; &quot;/images&quot;,
  +            },
  +     color =&gt; {
  +               hint   =&gt; &quot;#777777&quot;,
  +               warn   =&gt; &quot;#990066&quot;,
  +               normal =&gt; &quot;#000000&quot;,
  +              },
  +    );
  +</PRE>
  +<P>
  +And the code
  +
  +<P>
  +<PRE>  use strict;
  +  use My::Config ();
  +  print &quot;Content-type: text/plain\n\n&quot;;
  +  print &quot;My url docs root: $My::Config::c{url}{docs}\n&quot;;
  +</PRE>
  +<P>
  +Since we still want to save us lots of typing, since now we need to use a
  +fully qualified notation like in <CODE>$My::Config::c{url}{docs}</CODE>, let's use a magical perl's aliasing feature. I'll modify the code to be:
  +
  +<P>
  +<PRE>  use strict;
  +  use My::Config ();
  +  use vars qw(%c);
  +  *c = \%My::Config::c;
  +  print &quot;Content-type: text/plain\n\n&quot;;
  +  print &quot;My url docs root: $c{url}{docs}\n&quot;;
  +</PRE>
  +<P>
  +I have alised <CODE>*c</CODE> glob with <CODE>\%My::Config::c</CODE> hash reference. From now on <CODE>%My::Config::c</CODE> and <CODE>%c</CODE> are the same hash. You can read from or modify any of them, both variables
  +are the same one.
  +
  +<P>
  +Just one last little notice. Sometimes you see a lot of redundance in the
  +configuration variables, like:
  +
  +<P>
  +<PRE>  $cgi_dir  = &quot;/home/httpd/perl&quot;;
  +  $docs_dir = &quot;/home/httpd/docs&quot;;
  +  $img_dir  = &quot;/home/httpd/docs/images&quot;;
  +</PRE>
  +<P>
  +Now if you want to move the base path <CODE>&quot;/home/httpd&quot;</CODE> into a new place, it demands lots of typing. Of course the solution is:
  +
  +<P>
  +<PRE>  $base     = &quot;/home/httpd&quot;;
  +  $cgi_dir  = &quot;$base/perl&quot;;
  +  $docs_dir = &quot;$base/docs&quot;;
  +  $img_dir  = &quot;$base/docs/images&quot;;
  +</PRE>
  +<P>
  +But you cannot do the same trick with hash. This wouldn't work:
  +
  +<P>
  +<PRE>  %c =
  +    (
  +     base =&gt; &quot;/home/httpd&quot;,
  +     dir =&gt; {
  +             cgi  =&gt; &quot;$base/perl&quot;,
  +             docs =&gt; &quot;$base/docs&quot;,
  +             img  =&gt; &quot;$base/docs/images&quot;,
  +            },
  +    );
  +</PRE>
  +<P>
  +But nothing stops us from adding additional variables, which are lexically
  +scoped with <CODE>my().</CODE> The following code is correct.
  +
  +<P>
  +<PRE>  my $base = &quot;/home/httpd&quot;;
  +  %c =
  +    (
  +     dir =&gt; {
  +             cgi  =&gt; &quot;$base/perl&quot;,
  +             docs =&gt; &quot;$base/docs&quot;,
  +             img  =&gt; &quot;$base/docs/images&quot;,
  +            },
  +    );
  +</PRE>
  +<P>
  +We have just learned how to make configuration files easily maintainable,
  +and how to save memory by avoiding variables exporting into a script's
  +namespace.
  +
  +<P>
  +<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<CENTER><H3><A NAME="Reloading_Configuration_Files">Reloading Configuration Files</A></H3></CENTER>
  +<P>
  +Now back to the task of dynamically reloading of configuration files.
  +
  +<P>
  +First, lets see a simple case, when we just have to watch after a simple
  +configuration file, like this one. Imagine a script that tells who is patch
  +pumkin of the current perl release.
  +
  +<P>
  +Sidenote: &lt;jargon&gt; A humourous term for the token - the object
  +(notional or real) that gives its possessor (the ``pumpking'' or the
  +``pumpkineer'') exclusive access to something, e.g. applying patches to a
  +master copy of source (for which the pumpkin is called a ``patch
  +pumpkin'').
  +
  +<P>
  +<PRE>  use CGI ();
  +  use strict;
  +  
  +  my $fname = &quot;Larry&quot;;
  +  my $lname = &quot;Wall&quot;;
  +  my $q = new CGI;
  +  
  +  print $q-&gt;header(-type=&gt;'text/html');
  +  print $q-&gt;p(&quot;$fname $lname holds the patch pumpkin
  +               for this perl release.&quot;);
  +</PRE>
  +<P>
  +The script has a hardcoded value for the name. It's very simple: initialize
  +the CGI object, print the proper HTTP header and tell the world who is the
  +current patch pumpkin.
  +
  +<P>
  +When the patch pumkin changes we don't want to modify the script.
  +Therefore, we put the <CODE>$fname</CODE> and <CODE>lname</CODE> variables into a configuration file.
  +
  +<P>
  +<PRE>  $fname = &quot;Gurusamy&quot;;
  +  $lname = &quot;Sarathy&quot;;
  +  1;
  +</PRE>
  +<P>
  +Please notice that there is no package declaration in the above file, so
  +the code will be evaluated in the caller's package or in the
  +<CODE>main::</CODE> package if none was declared. It means that variables
  +<CODE>$fname</CODE> and <CODE>$lname</CODE> will override (or initialize if they weren't yet) the variables with the
  +same names in the caller's namespace. This works for global variables only
  +-- you cannot update lexically defined (with <CODE>my())</CODE> variables
  +by this technique.
  +
  +<P>
  +You have started the server and everything is working properly. After a
  +while you decide to modify the configuration. How do you let your running
  +know, that the configuration was modified, without restarting the server,
  +remember we are in production and server restarting can be quite expensive
  +for us. ? One of the simplest solutions is to poll the file's modification
  +time by calling <CODE>stat()</CODE> before the script starts to do a real
  +work, and if we see that the file was updated, we force a reconfiguration
  +of the variables located in this file. We will call the function that
  +reloads the configuration <CODE>reread_conf()</CODE> and it accepts a
  +single argument, which is a relative path to the configuration file.
  +
  +<P>
  +If your CGI script is being invoked under <CODE>Apache::Registry</CODE> handler, you can put the configuration file in the same directory as a
  +script or below it and path a relative path to the file, since
  +<CODE>Apache::Registry</CODE> calls a <CODE>chdir()</CODE> to the script's directory before it starts the
  +script's execution. Otherwise you would have to make sure that the file
  +will be found. <CODE>do()</CODE> does search the <CODE>@INC</CODE>
  +libraries.
  +
  +<P>
  +<PRE>  use vars qw(%MODIFIED);
  +  sub reread_conf{
  +    my $file = shift;
  +    return unless $file;
  +    return unless -e $file and -r _;
  +    unless ($MODIFIED{$file} and $MODIFIED{$file} == -M _){
  +      my $return;
  +      unless ($return = do $file) {
  +        warn &quot;couldn't parse $file: $@&quot; if $@;
  +        warn &quot;couldn't do $file: $!&quot;    unless defined $return;
  +        warn &quot;couldn't run $file&quot;       unless $return;
  +      }
  +      $MODIFIED{$file} =  -M _; # Update the MODIFICATION times
  +    }
  +  } # end of reread_conf
  +</PRE>
  +<P>
  +We use <CODE>do()</CODE> to reload the code in this file and not
  +<CODE>require()</CODE> because, <CODE>do()</CODE> reloads the file
  +unconditionally, while <CODE>require()</CODE> will not load the file if it
  +was already loaded in one of the previous requests, since there will be an
  +entry in the <CODE>%INC</CODE> where the key is the name of the file and the value the path to it. That's
  +how Perl keeps track of loaded files and saves overhead of reloading when
  +it has to load the same file again. You generally doesn't notice that with
  +plain perl scripts, but in mod_perl it's being used all the time (since the
  +same script is being reloaded all the time, and all the
  +<CODE>require()'s</CODE> files are already loaded after a first request for
  +each process.
  +
  +<P>
  +Nevertheless, <CODE>do()</CODE> keeps track of the current filename for
  +error messages, searches the <CODE>@INC</CODE> libraries, updates the <CODE>%INC</CODE> if the file is found.
  +
  +<P>
  +To explain all the possible warnings the script emits if something went
  +wrong with operation, it's just for a matter of completeness. Generally you
  +would do all these checks. If <CODE>do()</CODE> cannot read the file, it returns <CODE>undef</CODE> and sets <CODE>$!</CODE> to the error. If <CODE>do()</CODE> can read the file but cannot compile it, it returns <CODE>undef</CODE> and sets an error message in <CODE>$@</CODE>. If the file is successfully compiled, <CODE>do()</CODE>
  +returns the value of the last expression evaluated.
  +
  +<P>
  +Also the configuration file can be broken if someone has incorrectly
  +modified it. We don't want the service to go broken, because of that. We
  +just trap the possible failure to <CODE>do()</CODE> the file and ignore the
  +changes, by the resetting the modification time. It might be a good idea to
  +send an email to system administrator about the problem.
  +
  +<P>
  +Notice however, that since <CODE>do()</CODE> updates the <CODE>%INC</CODE> like <CODE>require()</CODE> does, if you are using <CODE>Apache::StatINC</CODE>, it will attempt to reload this file before the <CODE>reread_conf()</CODE>
  +call, so if it the file wouldn't compile the request would be aborted. This
  +shouldn't be a problem since <CODE>Apache::StatINC</CODE> shouldn't be used in production (because it slows things down by
  +<CODE>stat()'ing</CODE> all the files listed in <CODE>%INC</CODE>).
  +
  +<P>
  +Note that we assume that the entire purpose of this function is to reload
  +the configuration if that was changed, that's why there is no possible
  +failure for this function. If something goes wrong we just return. This
  +approach would be incorrect if you are going to initialize the variables
  +thru this method on the first invocation of the script. If you do, you will
  +want to replace each occurence of <CODE>return()</CODE> and
  +<CODE>warn()</CODE> with <CODE>die().</CODE>
  +
  +<P>
  +I used the above approach when I've had a huge configuration file that was
  +loaded only once at the server startup, and another little configuration
  +file that included only a few variables that could be updated by hand or
  +through the web interface, and those variables were duplicates in the main
  +config file.
  +
  +<P>
  +So if webmaster breaks the syntax in this dynamic file while updating it by
  +hand, it wouldn't affect the main configuration file (which was
  +write-protected) and so the proper executing of the programs. Soon we will
  +see a simple web interface which allows to modify the configuration file
  +without actually breaking it.
  +
  +<P>
  +A sample script using the presented subroutine would be:
  +
  +<P>
  +<PRE>  use vars qw(%MODIFIED $fname $lname);
  +  use CGI ();
  +  use strict;
  +  
  +  my $q = new CGI;
  +  print $q-&gt;header(-type=&gt;'text/plain');
  +  my $config_file = &quot;./config.pl&quot;;
  +  reread_conf($config_file);
  +  print $q-&gt;p(&quot;$fname $lname holds the patch pumpkin
  +               for this perl release.&quot;);
  +  
  +  sub reread_conf{
  +    my $file = shift;
  +    return unless $file;
  +    return unless -e $file and -r _;
  +    unless ($MODIFIED{$file} and $MODIFIED{$file} == -M _){
  +      my $return;
  +      unless ($return = do $file) {
  +        warn &quot;couldn't parse $file: $@&quot; if $@;
  +        warn &quot;couldn't do $file: $!&quot;    unless defined $return;
  +        warn &quot;couldn't run $file&quot;       unless $return;
  +      }
  +      $MODIFIED{$file} =  -M _; # Update the MODIFICATION times
  +    }
  +  } # end of reread_conf
  +</PRE>
  +<P>
  +Remember that you should be using <CODE>(stat $file)[9]</CODE> instead of <CODE>-M
  +$file</CODE> if you are modifying the <CODE>$^M</CODE> variable. In some of my scripts, I reset <CODE>$^M</CODE> to the time of the script invocation with
  +<CODE>&quot;$^M = time()&quot;</CODE>, so I can perform <CODE>-M</CODE> and alike (<CODE>-A</CODE>, <CODE>-C</CODE>) file status testings relative to the script invocation time and not the
  +time the process was started.
  +
  +<P>
  +If your configuration file is more sophisticated and it declares a package
  +and exports variables, the above code will work just as well. Even if you
  +think that you will have to re-import() variables, they are just there and
  +when do recompiles the code, the originally imported variables get updates
  +with the values from the reloaded code.
  +
  +<P>
  +<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<CENTER><H3><A NAME="Dynamically_updating_configurati">Dynamically updating configuration files</A></H3></CENTER>
  +<P>
  +The CGI script below allows a system administrator, to dynamically update
  +configuration file through the web interface. Combining this with the code
  +we have just showed to reload the modified files, you get a complete suite
  +of dynamically reconfigurable system which doesn't require server restart
  +and can be performed from any machine having just a web interface (a simple
  +browser connected to the Internet).
  +
  +<P>
  +Let's say you have a configuration file like:
  +
  +<P>
  +<PRE>  package MainConfig;
  +  
  +  use strict;
  +  use vars qw(%c);
  +  
  +  %c = (
  +        name     =&gt; &quot;Larry Wall&quot;,
  +        release  =&gt; &quot;5.000&quot;,
  +        comments =&gt; &quot;Adding more ways to do the same thing :)&quot;,
  +  
  +        other    =&gt; &quot;More config values&quot;,
  +  
  +        hash     =&gt; { foo  =&gt; &quot;bar&quot;,
  +                    fooo =&gt; &quot;barr&quot;,
  +                  },
  +  
  +        array    =&gt; [qw( a b c)],
  +  
  +       );
  +</PRE>
  +<P>
  +You want to make the variables <CODE>name</CODE>, <CODE>release</CODE> and <CODE>comments</CODE>
  +dynamically configurable. Which means that you want to have a web interface
  +with input form that allows to modify these variables. Once modified you
  +want to update the configuration file and propogate the changes to all the
  +currently running processes. Quite a simple task.
  +
  +<P>
  +Let's see the main stages of this algorithm. Create a form with preset
  +current values of the variables. Let the administrator to modify and submit
  +the changes. Validate that the submitted information is correctly formatted
  +(numeric fields should carry numbers, literal - words and etc). Update the
  +configuration file. Update the modified value in the memory of the current
  +process. Present the form as before but with updated fields if any.
  +
  +<P>
  +The only part that seems to be complicated to implement is a configuration
  +file update. For a few reasons. If updating the file breaks it - the whole
  +service wouldn't work. If the file is very big and includes comments and
  +complex data structures, parsing the file can be quite a challenge.
  +
  +<P>
  +So let's simplify the task. We wouldn't touch the original configuration
  +file, if all we want is to updated a few variables, why don't we create a
  +little configuration file with just a variables that can be modified
  +throught the web interface and overwrite it each time there is something to
  +be changed. This way we don't have to parse the file, before updating it.
  +And if the main configuration file is going to be changed, we don't care
  +about it -- since we aren't dependent on it any more.
  +
  +<P>
  +Moreover, we will have these dynamically updated variables duplicated, they
  +will show up in both places - in the main file and in the dynamic file. We
  +do it, to simplify the maintainance. When a new release is being installed
  +the dynamic configuration file shouldn't exist at all. It'll be created
  +only after a first update. The only change it requires to the main code is
  +to add a snippet of code to load this file if it exists and was changed as
  +we just saw.
  +
  +<P>
  +This additional code must be executed after the main configuration file is
  +being loaded. That way the updated variables would override the default
  +values in the main file.
  +
  +<P>
  +META: extend on the comments:
  +
  +<P>
  +<PRE>  # remember to run this code under taint mode
  +  
  +  use strict;
  +  use vars qw($q %c $dynamic_config_file %vars_to_change %validation_rules);
  +  
  +  use CGI ();
  +  
  +  use lib qw(.);
  +  use MainConfig ();
  +  *c = \%MainConfig::c;
  +  
  +  $dynamic_config_file = &quot;./config.pl&quot;;
  +  
  +  # load the dynamic conf file if exists, and override the default
  +  # values from the main config file
  +  do $dynamic_config_file if -e $dynamic_config_file and -r _;
  +  
  +  # fields that can be changed and their titles
  +  %vars_to_change =
  +    (
  +     'name'     =&gt; &quot;Patch Pumkin's Name&quot;,
  +     'release'  =&gt; &quot;Current Perl Release&quot;,
  +     'comments' =&gt; &quot;Release Comments&quot;,
  +    );
  +  
  +  %validation_rules =
  +    (
  +     'name'     =&gt; sub { $_[0] =~ /^[\w\s\.]+$/;   },
  +     'release'  =&gt; sub { $_[0] =~ /^\d+\.[\d_]+$/; },
  +     'comments' =&gt; sub { 1;                        },
  +    );
  +  
  +  $q = new CGI;
  +  print $q-&gt;header(-type=&gt;'text/html'),
  +    $q-&gt;start_html();
  +  
  +  my %updates = ();
  +  
  +  # We always rewrite the dynamic config file, so we want all the
  +  # vars to be passed but to save the time we will only do checking
  +  # of vars that that was changed the rest will be retrieved from
  +  # the 'prev_foo' values
  +  foreach (keys %vars_to_change) {
  +    # copy var so we can modify it
  +    my $new_val = $q-&gt;param($_) || '';
  +  
  +    # strip a possible ^M char (DOS/WIN)
  +    $new_val =~ s/\cM//g;
  +  
  +    # push to hash if was changed
  +    $updates{$_} = $new_val
  +      if defined $q-&gt;param(&quot;prev_&quot;.$_) and $new_val ne $q-&gt;param(&quot;prev_&quot;.$_);
  +  }
  +  
  +  # Notice that we cannot trust the previous values of the variables
  +  # since they were presented to user as hidden form variables, and
  +  # of course user can mangle those. In our case we don't care since
  +  # it cannot make any damage, since as you will see in a minute we
  +  # verify each variable by the rules we define.
  +  
  +  # Process if there is something to process. Will be not called if
  +  # it's invoked a first time to diplay the form or when the form
  +  # was submitted but the values weren't modified (we know that by
  +  # comparing with the previous values of the variables, which are
  +  # the hidden fields in the form)
  +  
  +  # process and update the values if valid
  +  process_change_config(%updates) if %updates;
  +  
  +  # print the update form
  +  conf_modification_form();
  +  
  +  # update the config file but first validate that the values are correct ones
  +  #########################
  +  sub process_change_config{
  +    my %updates = @_; # dereference
  +  
  +      # we will list here all the malformatted vars
  +    my %malformatted = ();
  +  
  +    print $q-&gt;b(&quot;Trying to validate these values&lt;BR&gt;&quot;);
  +    foreach (keys %updates) {
  +      print &quot;&lt;DT&gt;&lt;B&gt;$_&lt;/B&gt; =&gt; &lt;PRE&gt;$updates{$_}&lt;/PRE&gt;&quot;;
  +  
  +      # now we have to handle each var to be changed very very carefully
  +      # since this file goes immediately into production!
  +      $malformatted{$_} = delete $updates{$_}
  +        unless $validation_rules{$_}-&gt;($updates{$_});
  +  
  +    } # end of foreach my $var (keys %updates)
  +  
  +    # print warnings if there are any invalid changes
  +    print $q-&gt;hr,
  +      $q-&gt;p($q-&gt;b(qq{Warning! These variables were attempted to be
  +                   changed, but found malformed, thus the original
  +                   value will be preserved.})
  +         ),
  +      join(&quot;,&lt;BR&gt;&quot;,
  +         map { $q-&gt;b($vars_to_change{$_}) . &quot; : $malformatted{$_}\n&quot;
  +             } keys %malformatted)
  +        if %malformatted;
  +  
  +    # Now complete the vars that weren't changed from the
  +    # $q-&gt;param('prev_var') values
  +    map { $updates{$_} = $q-&gt;param('prev_'.$_) unless exists $updates{$_}
  +        } keys %vars_to_change;
  +  
  +    # Now we have all the data that should be written into dynamic
  +    # config file
  +  
  +      # escape single quotes &quot;'&quot; while creating a file
  +    my $content = join &quot;\n&quot;,
  +      map { $updates{$_} =~ s/(['\\])/\\$1/g;
  +          '$c{' . $_ . &quot;}  =  '&quot; . $updates{$_} . &quot;';\n&quot;
  +        } keys %updates;
  +  
  +      # now add '1;' to make require() happy
  +    $content .= &quot;\n1;&quot;;
  +  
  +      # keep the dummy result in $r so it'll not complain
  +    eval {my $res = $content};
  +    if ($@) {
  +      print qq{Warning! Something went wrong with config file
  +             generation!&lt;P&gt; The error was : &lt;BR&gt;&lt;PRE&gt;$@&lt;/PRE&gt;};
  +      return;
  +    }
  +  
  +    print $q-&gt;hr;
  +  
  +      # overwrite the dynamic config file
  +    use Symbol ();
  +    my $fh = Symbol::gensym();
  +    open $fh, &quot;&gt;$dynamic_config_file.bak&quot;
  +      or die &quot;Can't open the $dynamic_config_file.bak for writing :$! \n&quot;;
  +    flock $fh,2; # exclusive lock
  +    seek $fh,0,2;       # rewind to the start
  +    truncate $fh, 0; # the file might shrink!
  +       print $fh $content;
  +    close $fh;
  +  
  +      # OK, now we make a real file
  +    rename &quot;$dynamic_config_file.bak&quot;,$dynamic_config_file;
  +  
  +      # rerun it to update variables in the current process! Note that
  +      # it wouldn't update the variables in other processes. A special
  +      # code that watches the timestamps on the config file will do this
  +      # work for each process. Since the next invocation will update the
  +      # configuration anyway, why do we need to load it here? The reason
  +      # is simple, since we are going to fill form's input fields, with
  +      # the updated data.
  +    do $dynamic_config_file;
  +  
  +  } # end sub process_change_config
  +  
  +  ##########################
  +  sub conf_modification_form{
  +  
  +    print $q-&gt;center($q-&gt;h3(&quot;Update Form&quot;));
  +  
  +    print $q-&gt;hr,
  +      $q-&gt;p(qq{This form allows you to dynamically update the current
  +             configuration. You don\'t need to restart the server in
  +             order for changes to take an effect}
  +           );
  +  
  +      # set the previous settings into the form's hidden fields, so we
  +      # know whether we have to do some changes or not
  +    map {$q-&gt;param(&quot;prev_$_&quot;,$c{$_}) } keys %vars_to_change;
  +  
  +      # raws for the table, go into the form
  +    my @configs = ();
  +  
  +      # prepare one textfield entries
  +    push @configs,
  +      map {
  +        $q-&gt;td(
  +             $q-&gt;b(&quot;$vars_to_change{$_}:&quot;),
  +            ),
  +        $q-&gt;td(
  +             $q-&gt;textfield(-name      =&gt; $_,
  +                           -default   =&gt; $c{$_},
  +                           -override  =&gt; 1,
  +                           -size      =&gt; 20,
  +                           -maxlength =&gt; 50,
  +                          )
  +            ),
  +          } qw(name release);
  +  
  +      # prepare multiline textarea entries
  +    push @configs,
  +      map {
  +        $q-&gt;td(
  +             $q-&gt;b(&quot;$vars_to_change{$_}:&quot;),
  +            ),
  +        $q-&gt;td(
  +             $q-&gt;textarea(-name    =&gt; $_,
  +                          -default =&gt; $c{$_},
  +                          -override  =&gt; 1,
  +                          -rows    =&gt; 10,
  +                          -columns =&gt; 50,
  +                          -wrap    =&gt; &quot;HARD&quot;,
  +                          )
  +            ),
  +          } qw(comments);
  +  
  +    print $q-&gt;startform('POST',$q-&gt;url),&quot;\n&quot;,
  +        $q-&gt;center($q-&gt;table(map {$q-&gt;Tr($_),&quot;\n&quot;,} @configs),
  +                   $q-&gt;submit('','Update!'),&quot;\n&quot;,
  +                  ),
  +        map ({$q-&gt;hidden(&quot;prev_&quot;.$_, $q-&gt;param(&quot;prev_&quot;.$_)).&quot;\n&quot; }
  +             keys %vars_to_change), # hidden previous values
  +        $q-&gt;br,&quot;\n&quot;,
  +        $q-&gt;endform,&quot;\n&quot;,
  +        $q-&gt;hr,&quot;\n&quot;,
  +        $q-&gt;end_html;
  +  
  +  } # end sub conf_modification_form
  +</PRE>
  +<P>
  +Once updated the script generates a file like:
  +
  +<P>
  +<PRE>  $c{release}  =  '5.6';
  +  
  +  $c{name}  =  'Gurusamy Sarathy';
  +  
  +  $c{comments}  =  'Perl rules the world!';
  +  
  +  1;
  +</PRE>
  +<P>
  +<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<CENTER><H2><A NAME="Reloading_handlers">Reloading handlers</A></H2></CENTER>
  +<P>
  +If you want to reload perlhandler on each invocation, the following trick
  +will do it:
  +
  +<P>
  +<PRE>  PerlHandler &quot;sub { do 'MyTest.pm'; MyTest::handler(shift) }&quot;
  +</PRE>
  +<P>
  +<CODE>do()</CODE> will reload <CODE>MyTest.pm</CODE> every request.
  +
  +<P>
  +<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<CENTER><H1><A NAME="Name_collisions_with_Modules_and">Name collisions with Modules and libs</A></H1></CENTER>
  +<P>
  +To make things clear before we go into details: each child process has its
  +own <CODE>%INC</CODE> hash which is used to store information about its compiled modules. The
  +keys of the hash are the names of the modules or parameters passed to <CODE>require()</CODE> (<CODE>use()</CODE>). The values are the full or relative paths to these modules/files. Let's
  +say we have
  +<CODE>my-lib.pl</CODE> and <CODE>MyModule.pm</CODE> both located at <CODE>/home/httpd/perl/my/</CODE>.
  +
  +<UL>
  +<P><LI><STRONG><A NAME="item__home_httpd_perl_my_is_in_the_">/home/httpd/perl/my/ is in the @INC at the server startup.</A></STRONG>
  +<P>
  +<PRE>  require &quot;my-lib.pl&quot;;
  +  use MyModule.pm;
  +  print $INC{&quot;my-lib.pl&quot;},&quot;\n&quot;;
  +  print $INC{&quot;MyModule.pm&quot;},&quot;\n&quot;;
  +</PRE>
  +<P>
  +prints:
  +
  +<P>
  +<PRE>  /home/httpd/perl/my/my-lib.pl
  +  /home/httpd/perl/my/MyModule.pm
  +</PRE>
  +<P>
  +Adding <CODE>use lib</CODE>:
  +
  +<P>
  +<PRE>  use lib qw(.);
  +  require &quot;my-lib.pl&quot;;
  +  use MyModule.pm;
  +  print $INC{&quot;my-lib.pl&quot;},&quot;\n&quot;;
  +  print $INC{&quot;MyModule.pm&quot;},&quot;\n&quot;;
  +</PRE>
  +<P>
  +prints:
  +
  +<P>
  +<PRE>  my-lib.pl
  +  MyModule.pm
  +</PRE>
  +<P><DT><STRONG><A NAME="item__home_httpd_perl_my_">/home/httpd/perl/my/ isn't in the @INC path at the server startup.</A></STRONG><DD>
  +<P>
  +<PRE>  require &quot;my-lib.pl&quot;;
  +  use MyModule.pm;
  +  print $INC{&quot;my-lib.pl&quot;},&quot;\n&quot;;
  +  print $INC{&quot;MyModule.pm&quot;},&quot;\n&quot;;
  +</PRE>
  +<P>
  +wouldn't work, since perl cannot find the modules.
  +
  +<P>
  +Adding <CODE>use lib</CODE>:
  +
  +<P>
  +<PRE>  use lib qw(.);
  +  require &quot;my-lib.pl&quot;;
  +  use MyModule.pm;
  +  print $INC{&quot;my-lib.pl&quot;},&quot;\n&quot;;
  +  print $INC{&quot;MyModule.pm&quot;},&quot;\n&quot;;
  +</PRE>
  +<P>
  +prints:
  +
  +<P>
  +<PRE>  my-lib.pl
  +  MyModule.pm
  +</PRE>
  +</UL>
  +<P>
  +I'm talking about single child below!
  +
  +<P>
  +Let's look at 3 faulty script's name space related scenarios:
  +
  +<DL>
  +<P><DT><STRONG><A NAME="item_Scenario">Scenario 1</A></STRONG><DD>
  +<P>
  +First, You can't have 2 identical module names running under the same
  +server! Only the first one <CODE>use()</CODE>'d or <CODE>require()</CODE>'d 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's already in the child's <CODE>%INC</CODE>. (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 two different <CODE>Foo</CODE> modules in two different directories and two scripts <CODE>script1.pl</CODE> and <CODE>script2.pl</CODE>, placed like:
  +
  +<P>
  +<PRE>  ./perl/tool1/Foo.pm
  +  ./perl/tool1/tool1.pl
  +  ./perl/tool2/Foo.pm
  +  ./perl/tool2/tool2.pl
  +</PRE>
  +<P>
  +Where a sample code could be:
  +
  +<P>
  +<PRE>  ./perl/tool1/tool1.pl
  +  --------------------
  +  use Foo;
  +  print &quot;Content-type: text/html\n\n&quot;;
  +  print &quot;I'm Script number One&lt;BR&gt;\n&quot;;
  +  foo();
  +  --------------------
  +</PRE>
  +<P>
  +<PRE>  ./perl/tool1/Foo.pm
  +  --------------------
  +  sub foo{
  +    print &quot;&lt;B&gt;I'm Tool Number One!&lt;/B&gt;&lt;BR&gt;\n&quot;;
  +  }
  +  1;
  +  --------------------
  +</PRE>
  +<P>
  +<PRE>  ./perl/tool2/tool2.pl
  +  --------------------
  +  use Foo;
  +  print &quot;Content-type: text/html\n\n&quot;;
  +  print &quot;I'm Script number Two&lt;BR&gt;\n&quot;;
  +  foo();
  +  --------------------
  +</PRE>
  +<P>
  +<PRE>  ./perl/tool2/Foo.pm
  +  --------------------
  +  sub foo{
  +    print &quot;&lt;B&gt;I'm Tool Number Two!&lt;/B&gt;&lt;BR&gt;\n&quot;;
  +  }
  +  1;
  +  --------------------
  +</PRE>
  +<P>
  +And both scripts call: <CODE>use Foo;</CODE> -- only the first one called will know about <CODE>Foo</CODE>, when you will call the second script it will not know about <CODE>Foo</CODE> at all - it's like you've forgotten to write <CODE>use
  +Foo;</CODE>. Run the server in <A HREF="././control.html#Running_server_in_a_single_mode">single server mode</A> to detect this kind of bug immediately.
  +
  +<P>
  +You will see the following in the error_log file:
  +
  +<P>
  +<PRE>  Undefined subroutine
     &amp;Apache::ROOT::perl::tool2::tool2_2epl::foo called at
     /home/httpd/perl/tool2/tool2.pl line 4.
   </PRE>
  @@ -829,7 +2152,7 @@
   
   <P>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<CENTER><H2><A NAME="More_package_name_related_issues">More package name related issues</A></H2></CENTER>
  +<CENTER><H1><A NAME="More_package_name_related_issues">More package name related issues</A></H1></CENTER>
   <P>
   If you have the following:
   
  @@ -844,26 +2167,82 @@
   
   <P>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<CENTER><H2><A NAME="_END_or_DATA_tokens">__END__ or __DATA__ tokens</A></H2></CENTER>
  +<CENTER><H1><A NAME="_END_or_DATA_tokens">__END__ or __DATA__ tokens</A></H1></CENTER>
  +<P>
  +<CODE>Apache::Registry</CODE> scripts cannot contain <CODE>__END__</CODE> or <CODE>__DATA__</CODE>
  +tokens.
  +
  +<P>
  +Why? Because <CODE>Apache::Registry</CODE> scripts are being wrapped into a subroutine called <CODE>handler</CODE>, like the script at URI <CODE>/perl/test.pl</CODE>:
  +
  +<P>
  +<PRE>  print &quot;Content-type: text/plain\n\n&quot;;
  +  print &quot;Hi&quot;;
  +</PRE>
  +<P>
  +When the script is being executed under <CODE>Apache::Registry</CODE> handler, it actually becomes:
  +
  +<P>
  +<PRE>  package Apache::ROOT::perl::test_2epl;
  +  use Apache qw(exit);
  +  sub handler {
  +    print &quot;Content-type: text/plain\n\n&quot;;
  +    print &quot;Hi&quot;;
  +  }
  +</PRE>
  +<P>
  +So if you happen to put an <CODE>__END__</CODE> tag, like:
  +
  +<P>
  +<PRE>  print &quot;Content-type: text/plain\n\n&quot;;
  +  print &quot;Hi&quot;;
  +  __END__
  +  Some text that wouldn't be normally executed
  +</PRE>
   <P>
  -<CODE>Apache::Registry</CODE> scripts cannot contain __END__ or __DATA__ tokens.
  +it will be turned into:
   
   <P>
  +<PRE>  package Apache::ROOT::perl::test_2epl;
  +  use Apache qw(exit);
  +  sub handler {
  +    print &quot;Content-type: text/plain\n\n&quot;;
  +    print &quot;Hi&quot;;
  +    __END__
  +    Some text that wouldn't be normally executed
  +  }
  +</PRE>
  +<P>
  +and you try to execute this script, you will receive the following warning:
  +
  +<P>
  +<PRE>  Missing right bracket at q line 4, at end of line
  +</PRE>
  +<P>
  +And that's clear, Perl cuts everything after <CODE>__END__</CODE> tag. The same thing applies to <CODE>__DATA__</CODE> tag.
  +
  +<P>
  +Also, rememeber that whatever applies to <CODE>Apache::Registry</CODE> scripts, in most cases applies to <CODE>Apache::PerlRun</CODE> scripts.
  +
  +<P>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<CENTER><H2><A NAME="Output_from_system_calls">Output from system calls</A></H2></CENTER>
  +<CENTER><H1><A NAME="Output_from_system_calls">Output from system calls</A></H1></CENTER>
   <P>
   Output of <CODE>system()</CODE>, <CODE>exec()</CODE>, and <CODE>open(PIPE,&quot;|program&quot;)</CODE> calls will not be sent to the browser unless your Perl was configured with
   <CODE>sfio</CODE>.
   
   <P>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<CENTER><H2><A NAME="Using_format_">Using format()</A></H2></CENTER>
  +<CENTER><H1><A NAME="Using_format_and_write_">Using format() and write()</A></H1></CENTER>
   <P>
  -Currently possible only if you have perl compiled with <CODE>sfio</CODE>.
  +The Perl <CODE>tie()'d</CODE> filehandle interface is not complete,
  +<CODE>format()</CODE> / <CODE>write()</CODE> are ones of the missing
  +pieces. If you configure Perl with
  +<CODE>sfio</CODE>, <CODE>write()</CODE> and <CODE>format()</CODE> should work just fine.
   
   <P>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<CENTER><H2><A NAME="Using_exit_">Using exit()</A></H2></CENTER>
  +<CENTER><H1><A NAME="Using_exit_">Using exit()</A></H1></CENTER>
   <P>
   Perl's <STRONG>exit()</STRONG> built-in function cannot be used in mod_perl scripts. Calling it causes the
   server child to exit (which makes the whole idea of using mod_perl
  @@ -908,58 +2287,285 @@
   <CODE>$r-&amp;gt;child_terminate</CODE> (which sets the internal
   <CODE>MaxRequestsPerChild</CODE> so the child will exit).
   
  +<P>
  +You can accomplish this in two ways - in the <CODE>Apache::Registry</CODE> script:
  +
  +<P>
  +<PRE>  Apache-&gt;request-&gt;child_terminate;
  +</PRE>
  +<P>
  +in httpd.conf:
  +
  +<P>
  +<PRE>  PerlFixupHandler &quot;sub { shift-&gt;child_terminate }&quot;
  +</PRE>
  +<P>
  +<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<CENTER><H1><A NAME="Running_from_shell">Running from shell</A></H1></CENTER>
  +<P>
  +Your scripts <STRONG>will not</STRONG> run from the command line (yet) unless you use <CODE>CGI::Switch</CODE> or <CODE>CGI.pm</CODE> and perl 5.004+ and do not make any direct calls to <CODE>Apache-&amp;gt;methods</CODE>.
  +
  +<P>
  +<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<CENTER><H1><A NAME="I_O_is_different">I/O is different</A></H1></CENTER>
  +<P>
  +If you are using Perl 5.004 or better, 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 <CODE>CGI.pm</CODE>, use <CODE>$query-&amp;gt;print</CODE> 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><H1><A NAME="Special_Perl_Variables">Special Perl Variables</A></H1></CENTER>
  +<P>
  +A special Perl variables like <CODE>$|</CODE> (buffering), <CODE>$^T</CODE> (time), <CODE>$^W</CODE>
  +(warnings), <CODE>$/</CODE> (input record separator), <CODE>$\</CODE> (output record separator) and many more are all global variables. It means
  +that you cannot localize them with <CODE>my().</CODE> Only
  +<CODE>local()</CODE> is permitted to do that. Since the child server
  +doesn't quit - if in one of your scripts you modify the global varible
  +it'll be changed for the rest of the process' life and would affect all the
  +scripts that will be executed under the same process.
  +
  +<P>
  +Remembering this you should never write a code like this. We will exercise
  +the input record separator variable. If you undefine this variable, a
  +diamond operator will suck the whole file at once.
  +
  +<P>
  +<PRE>  $/ = undef; 
  +  open IN, &quot;file&quot; ....
  +    # slurp it all inside a variable
  +  $all_the_file = &lt;IN&gt;;
  +</PRE>
  +<P>
  +The proper way is to have a <CODE>local()</CODE> keyword before the special
  +variable is being changed, like:
  +
  +<P>
  +<PRE>  local $/ = undef; 
  +  open IN, &quot;file&quot; ....
  +    # slurp it all inside a variable
  +  $all_the_file = &lt;IN&gt;;
  +</PRE>
  +<P>
  +But there is a little catch. <CODE>local()</CODE> will propogate the
  +changed value to any of the code below it and would be in effect untill the
  +script will be finished, if not modified in some other place.
  +
  +<P>
  +A cleaner approach is to embrace the whole code that is being effected by
  +the modificated variable in to a block, like:
  +
  +<P>
  +<PRE>  {
  +    $/ = undef; 
  +    open IN, &quot;file&quot; ....
  +      # slurp it all inside a variable
  +    $all_the_file = &lt;IN&gt;;
  +  }
  +</PRE>
  +<P>
  +That way when Perl leaves the block, it restores the original value of the <CODE>$/</CODE> variable. So you should worry about this variable anywhere else in scope of
  +your program.
  +
  +<P>
  +<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<CENTER><H1><A NAME="Generating_correct_HTTP_Headers">Generating correct HTTP Headers</A></H1></CENTER>
  +<P>
  +When writing your own handlers with Perl API the proper way to send the
  +HTTP Header is to set the header first and then to send it. Like:
  +
  +<P>
  +<PRE>  $r-&gt;content_type('text/html');
  +  $r-&gt;send_http_header;
  +  return OK if $r-&gt;header_only;
  +</PRE>
  +<P>
  +If the client issues a HTTP <CODE>HEAD</CODE> request rather than the usual
  +<CODE>GET</CODE>, to be compilent with the HTTP protocol we better will not send the
  +document body, but the the HTTP header only. When Apache receives a HEAD
  +request, it sets <EM>header_only()</EM> to true. If we see that this has happened, we return from the handler
  +immediately with an OK status code.
  +
  +<P>
  +Generally, you don't need the explicit content type setting, since Apache
  +does it for you, by looking up the MIME type of the request by matching the
  +extension of the URI in the MIME tables (from the
  +<CODE>mime.types</CODE> file). So if the request URI is <CODE>/welcome.html</CODE>, the
  +<CODE>text/html</CODE> content-type will be picked. However for CGI scripts or URIs that cannot be
  +mapped by a known extension, you should set the appropriate type by using <CODE>content_type()</CODE> method.
  +
  +<P>
  +The situation is a little bit different with <CODE>Apache::Registry</CODE> and alike handlers. It means that if you take a basic CGI script like:
  +
  +<P>
  +<PRE>  print &quot;Content-type: text/plain\n\n&quot;;
  +  print &quot;Hello world&quot;;
  +</PRE>
  +<P>
  +it wouldn't work, because the HTTP header will be not sent. By default,
  +mod_perl does not send any headers by itself, however, you may wish to
  +change this by adding:
  +
  +<P>
  +<PRE>  PerlSendHeader On
  +</PRE>
  +<P>
  +in <CODE>&lt;Location</CODE>&gt; part of your configuration. Now the response line and common headers
  +will be sent as they are by mod_cgi. And, just as with mod_cgi, <CODE>PerlSendHeader</CODE> will not send the MIME type and a terminating double newline. Your script
  +must send that itself, e.g.:
  +
  +<P>
  +<PRE>  print &quot;Content-type: text/html\r\n\r\n&quot;;
  +</PRE>
  +<P>
  +Note, that the book always uses ``\n\n'' and not ``\r\n\r\n''. The latter
  +is a way to send new lines as defined in HTTP standards, but as of this
  +moment all the browsers accept the former format as well. To follow
  +strictly the HTTP protocol you must you the ``\r\n'' format.
  +
  +<P>
  +The <STRONG>PerlSendHeader On</STRONG> directive tells mod_perl to intercept anything that looks like a header
  +line (such as <CODE>Content-Type:
  +text/plain</CODE>) and automatically turn it into a correctly formatted HTTP/1.0 header, the
  +same way it happens with CGI scripts running under mod_cgi. This allows you
  +to keep your CGI scripts unmodified.
  +
  +<P>
  +There is <CODE>$ENV{PERL_SEND_HEADER}</CODE> which tells whether
  +<CODE>PerlSendHeader</CODE> is <CODE>On</CODE> or <CODE>Off</CODE>. You can use it in your module like:
  +
  +<P>
  +<PRE> if($ENV{PERL_SEND_HEADER}) {
  +     print &quot;Content-type: text/html\n\n&quot;;
  + }
  + else {
  +     my $r = Apache-&gt;request;
  +     $r-&gt;content_type('text/html');
  +     $r-&gt;send_http_header;
  + }
  +</PRE>
  +<P>
  +If you use <EM>CGI.pm</EM>'s <EM>header()</EM> function to generate HTTP headers, you do not need to activate this
  +directive because <EM>CGI.pm</EM> detects
  +<EM>mod_perl</EM> and calls <EM>send_http_header()</EM> for you. However, it does not hurt to use this directive anyway.
  +
  +<P>
  +There is no free lunch -- you get the mod_cgi behavior on cost of little
  +but still overhead of parsing the text that is being sent, and mod_perl
  +makes the assumption that individual headers are not split across print
  +statements.
  +
   <P>
  -You can accomplish this in two ways - in the <CODE>Apache::Registry</CODE> script:
  +The <CODE>Apache::print()</CODE> routine has to gather up the headers that your script outputs, in order to
  +pass them to <CODE>$r-&amp;gt;send_http_header</CODE>. This happens in <CODE>src/modules/perl/Apache.xs</CODE> (<CODE>print</CODE>) and
  +<CODE>Apache/Apache.pm</CODE> (<CODE>send_cgi_header</CODE>). There is a shortcut in there, namely the assumption that each print
  +statement contains one or more complete headers. If for example you used to
  +generate a
  +<CODE>Set-Cookie</CODE> header by multiply <CODE>print()</CODE> statements, like:
   
   <P>
  -<PRE>  Apache-&gt;request-&gt;child_terminate;
  +<PRE>   print &quot;Content-type: text/html\n&quot;;
  +   print &quot;Set-Cookie: iscookietext\; &quot;;
  +   print &quot;expires=Wednesday, 09-Nov-1999 00:00:00 GMT\; &quot;;
  +   print &quot;path=\/\; &quot;;
  +   print &quot;domain=\.mmyserver.com\; &quot;;
  +   print &quot;\n\n&quot;;
  +   print &quot;hello&quot;;
   </PRE>
   <P>
  -in httpd.conf:
  +your generated <CODE>Set-Cookie</CODE> header is split over a number of print statements and gets lost. The above
  +example wouldn't work! Try this instead:
   
   <P>
  -<PRE>  PerlFixupHandler &quot;sub { shift-&gt;child_terminate }&quot;
  +<PRE>   print &quot;Content-type: text/html\n&quot;;
  +   my $cookie = &quot;Set-Cookie: iscookietext\; &quot;;
  +   $cookie .= &quot;expires=Wednesday, 09-Nov-1999 00:00:00 GMT\; &quot;;
  +   $cookie .= &quot;path=\/\; &quot;;
  +   $cookie .= &quot;domain=\.mmyserver.com\; &quot;;
  +   print $cookie;
  +   print &quot;\n\n&quot;;
  +   print &quot;hello&quot;;
   </PRE>
  -<P>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<CENTER><H2><A NAME="Running_from_shell">Running from shell</A></H2></CENTER>
   <P>
  -Your scripts <STRONG>will not</STRONG> run from the command line (yet) unless you use <CODE>CGI::Switch</CODE> or <CODE>CGI.pm</CODE> and perl 5.004+ and do not make any direct calls to <CODE>Apache-&amp;gt;methods</CODE>.
  +Sometimes when you call a script you see an ugly <CODE>&quot;Content-Type:
  +text/html&quot;</CODE> displayed at the top of the page, and of course the HTML code becomes
  +broken. As you understand from the above discussion this generally happens
  +when your code already send the header, that's why you see it rendered into
  +a browser's page. This might happen when you call the <CODE>CGI.pm</CODE>  <CODE>$q-&amp;gt;header</CODE> method or mod_perl's
  +<CODE>$r-&amp;gt;send_http_header</CODE>. 
  +
  +<P>
  +If you have a complicated application where the header might be generated
  +from many different places, depending on the calling logic, you might want
  +to write a special subroutine that sends a header, and keeps a track
  +whether the header has been already sent. Of course you can use a global
  +variable to flag that the header has been already sent, but there is
  +another elegant solution, where the closure effect is a desired feature.
  +
  +<P>
  +Just copy the code below, including the block's curly braces. And
  +everywhere in your code you print the header use the <CODE>print_header()</CODE>
  +subroutine. <CODE>$need_header</CODE> is the same kind of beast as a static variable in C, so it remembers its
  +value from call to call. The first time you will call the <CODE>print_header</CODE>, the value of <CODE>$need_header</CODE>
  +will become zero and on the subsequent calls if any happens, the header
  +will be not sent any more.
   
   <P>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<CENTER><H2><A NAME="I_O_is_different">I/O is different</A></H2></CENTER>
  +<PRE>  {
  +    my $need_header = 1;
  +    sub print_header {
  +      my type = shift || &quot;text/html&quot;;
  +      print(&quot;Content-type: $type\n\n),$need_header = 0 if $need_header;
  +    }
  +  }
  +</PRE>
   <P>
  -If you are using Perl 5.004 or better, 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 <CODE>CGI.pm</CODE>, use <CODE>$query-&amp;gt;print</CODE> instead of plain 'ol
  -<CODE>print()</CODE>.
  +In your code you call the above subroutine as:
   
   <P>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<CENTER><H2><A NAME="HTTP_MIME_Headers_PerlSendHea">HTTP + MIME Headers (PerlSendHeader)</A></H2></CENTER>
  +<PRE>  print_header();
  +</PRE>
   <P>
  -By default, mod_perl does not send any headers by itself, however, you may
  -wish to change this (in <CODE>httpd.conf</CODE>):
  +or
   
   <P>
  -<PRE>  PerlSendHeader On
  +<PRE>  print_header(&quot;text/plain);
   </PRE>
   <P>
  -Now the response line and common headers will be sent as they are by
  -mod_cgi. And, just as with mod_cgi, <CODE>PerlSendHeader</CODE> will not send the MIME type and a terminating newline. Your script must
  -send that itself, e.g.:
  +if you want to override the default (text/html) MIME type.
   
   <P>
  -<PRE>  print &quot;Content-type: text/html\r\n\r\n&quot;;
  +Let's make our smart method to elaborate with PerlSendHeader directive
  +settings, to always do the right thing. It's especially important if you
  +write an application that you are going to distribute, hopefully as an Open
  +Source.
  +
  +<P>
  +<PRE>  {
  +    my $need_header = 1;
  +    sub print_header {
  +      my type = shift || &quot;text/html&quot;;
  +      return unless $need_header;
  +      $need_header = 0;
  +      if($ENV{PERL_SEND_HEADER}) {
  +        print &quot;Content-type: $type\n\n&quot;;
  +      }
  +      else {
  +        my $r = Apache-&gt;request;
  +        $r-&gt;content_type($type);
  +        $r-&gt;send_http_header;
  +      }
  +    }
  +  }
   </PRE>
   <P>
  -If you are using <CODE>CGI.pm</CODE> or <CODE>CGI::Switch</CODE> and <STRONG>print
  -$q-&gt;header</STRONG> you do _not_ need <CODE>PerlSendHeader</CODE> On.
  +You can continue to improve this subroutine even further to handle
  +additional headers, like cookies and alike.
   
   <P>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<CENTER><H2><A NAME="NPH_Non_Parsed_Headers_scripts">NPH (Non Parsed Headers) scripts</A></H2></CENTER>
  +<CENTER><H1><A NAME="NPH_Non_Parsed_Headers_scripts">NPH (Non Parsed Headers) scripts</A></H1></CENTER>
   <P>
   To run a Non Parsed Header CGI script under mod_perl, simply add to your
   code:
  @@ -968,8 +2574,7 @@
   <PRE>  local $| = 1;
   </PRE>
   <P>
  -And if you normally set <CODE>PerlSendHeader On</CODE>, add this to your
  -<CODE>httpd.conf</CODE>:
  +And if you normally set <CODE>PerlSendHeader On</CODE>, add this to your server's configuration file:
   
   <P>
   <PRE>  &lt;Files */nph-*&gt;
  @@ -978,7 +2583,7 @@
   </PRE>
   <P>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<CENTER><H2><A NAME="BEGIN_blocks">BEGIN blocks</A></H2></CENTER>
  +<CENTER><H1><A NAME="BEGIN_blocks">BEGIN blocks</A></H1></CENTER>
   <P>
   Perl executes <CODE>BEGIN</CODE> 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
  @@ -1040,7 +2645,7 @@
   
   <P>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<CENTER><H2><A NAME="END_blocks">END blocks</A></H2></CENTER>
  +<CENTER><H1><A NAME="END_blocks">END blocks</A></H1></CENTER>
   <P>
   As perlmod explains, an <CODE>END</CODE> subroutine is executed as late as possible, that is, when the interpreter
   exits. In the mod_perl environment, the interpreter does not exit until the
  @@ -1063,14 +2668,15 @@
   <P>
   All other <CODE>END</CODE> blocks encountered during other <CODE>Perl*Handler</CODE>
   call-backs, e.g.  <CODE>PerlChildInitHandler</CODE>, will be suspended while the process is running and called during <CODE>child_exit()</CODE> when the process is shutting down. Module authors might wish to use
  -<CODE>$r-&amp;gt;register_cleanup</CODE> as an alternative to <CODE>END</CODE> blocks if this behavior is not desirable.
  +<CODE>$r-&amp;gt;register_cleanup()</CODE> as an alternative to <CODE>END</CODE> blocks if this behavior is not desirable. <CODE>$r-&amp;gt;register_cleanup()</CODE> is being called at the CleanUp processing phase of each request and thus
  +can be used to emulate plain perl's <CODE>END{}</CODE> block behavior.
   
   <P>
   The last paragraph is very important for the <A HREF="././obvious.html#Handling_the_User_pressed_Stop_">Handling the 'User pressed Stop button' case</A>.
   
   <P>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<CENTER><H2><A NAME="Switches_w_T">Switches -w, -T</A></H2></CENTER>
  +<CENTER><H1><A NAME="Switches_w_T">Switches -w, -T</A></H1></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 <STRONG>-w</STRONG> or <STRONG>-T</STRONG>. Most command line arguments have a equivalent special variable. For
  @@ -1108,7 +2714,7 @@
   
   <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>
  +<CENTER><H1><A NAME="strict_pragma">strict pragma</A></H1></CENTER>
   <P>
   It's _absolutely_ mandatory (at least for development) to start all your
   scripts with:
  @@ -1133,7 +2739,7 @@
   
   <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>
  +<CENTER><H1><A NAME="Turning_warnings_ON">Turning warnings ON</A></H1></CENTER>
   <P>
   Have a <CODE>local $^W=1</CODE> in the script or <CODE>PerlWarn ON</CODE> at the server configuration file. Turning the warning on will save you a
   lot of troubles with debugging your code. Note that all perl switches, but
  @@ -1174,7 +2780,7 @@
   
   <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>
  +<CENTER><H1><A NAME="diagnostics_pragma">diagnostics pragma</A></H1></CENTER>
   <P>
   This is a Perl compiler pragma which forces verbose warning diagnostics.
   Put at the start of your scripts:
  @@ -1197,7 +2803,7 @@
   
   <P>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<CENTER><H2><A NAME="Passing_ENV_variables_to_CGI">Passing ENV variables to CGI</A></H2></CENTER>
  +<CENTER><H1><A NAME="Passing_ENV_variables_to_CGI">Passing ENV variables to CGI</A></H1></CENTER>
   <P>
   To pass an environment variable from a configuration file, add to it:
   
  @@ -1225,7 +2831,7 @@
   
   <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>
  +<CENTER><H1><A NAME="Global_Variables">Global Variables</A></H1></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 (or fully qualified
  @@ -1257,13 +2863,13 @@
   
   <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_it_se">Code has been changed, but it seems the script is running the old code</A></H2></CENTER>
  +<CENTER><H1><A NAME="Code_has_been_changed_but_it_se">Code has been changed, but it seems the script is running the old code</A></H1></CENTER>
   <P>
   Files pulled in via <STRONG>use</STRONG> or <STRONG>require</STRONG> statements are not automatically reloaded when changed on disk. See <A HREF="#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="Apache_and_syslog">Apache and syslog</A></H2></CENTER>
  +<CENTER><H1><A NAME="Apache_and_syslog">Apache and syslog</A></H1></CENTER>
   <P>
   When native syslog support is enabled, the stderr stream will be redirected
   to <CODE>/dev/null</CODE>!
  @@ -1274,7 +2880,7 @@
   
   <P>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<CENTER><H2><A NAME="Memory_leakage">Memory leakage</A></H2></CENTER>
  +<CENTER><H1><A NAME="Memory_leakage">Memory leakage</A></H1></CENTER>
   <P>
   Scripts under mod_perl can very easily leak memory! Global variables stay
   around indefinitely, lexical variables (declared with <CODE>my()</CODE> are destroyed when they go out of scope, provided there are no references
  @@ -1560,176 +3166,6 @@
   
   <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 plain CGI scripts, you can just change the code, and rerun
  -the CGI from your browser. Since the script isn't cached in memory, the
  -next time you call it the server starts up a new perl process, which
  -recompiles it from scratch. The effects of any modifications you've applied
  -are immediately present.
  -
  -<P>
  -The situation is different with <CODE>Apache::Registry</CODE>, since the whole idea is to get maximum performance from the server. By
  -default, the server won't spend the time to check whether any included
  -library modules have been changed. It assumes that they weren't, thus
  -saving a few milliseconds to <CODE>stat()</CODE> the source file (multiplied by however many modules/libraries you are <CODE>use()</CODE>-ing and/or <CODE>require()</CODE>-ing in your script.) 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
  -<CODE>use()</CODE> (or <CODE>require()</CODE>) other perl modules (or packages), there is nothing new about it. If
  -however, you are developing a script that includes other modules, the files
  -you <CODE>use()</CODE> or <CODE>require()</CODE> aren't being checked whether they have been modified.
  -
  -<P>
  -Acknowledging this, how do we get our modperl-enabled server to recognize
  -changes in any library modules? Well, there are a couple of techniques:
  -
  -<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>
  -The simplest approach is to restart the server each time you apply some
  -change to your code. See <A HREF="././control.html#Restarting_techniques">Server Restarting techniques</A>.
  -
  -<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 about 100 times, you will be tired and will
  -look for another solutions. Help comes from the
  -<CODE>Apache::StatINC</CODE> module.
  -
  -<P>
  -<CODE>Apache::StatINC</CODE> reloads <CODE>%INC</CODE> files when updated on disk. When Perl pulls a file via require, it stores
  -the filename in the global hash <CODE>%INC</CODE>. The next time Perl tries to require the same file, it sees the file in <CODE>%INC</CODE> and does not reload from disk. This module's handler iterates over <CODE>%INC</CODE> and reloads the file if it has changed on disk.
  -
  -<P>
  -To enable this module just add two lines to <CODE>httpd.conf</CODE> file.
  -
  -<P>
  -<PRE>  PerlModule Apache::StatINC
  -  PerlInitHandler Apache::StatINC
  -</PRE>
  -<P>
  -To be sure it really works, turn on the debug mode on your development box
  -with <CODE>PerlSetVar StatINCDebug On</CODE>. You end up with something like:
  -
  -<P>
  -<PRE>  PerlModule Apache::StatINC
  -  &lt;Location /perl&gt;
  -    SetHandler perl-script
  -    PerlHandler Apache::Registry::handler
  -    Options ExecCGI
  -    PerlSendHeader On
  -    PerlInitHandler Apache::StatINC
  -    PerlSetVar StatINCDebug On
  -  &lt;/Location&gt;
  -</PRE>
  -<P>
  -Beware that 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 (in startup file).
  -
  -<P>
  -Whatever you do in your scripts and modules which are being <CODE>required()</CODE> after the server startup will not have any effect on <CODE>@INC</CODE>. When you do:
  -
  -<P>
  -<PRE>  use lib qw(foo/bar);
  -</PRE>
  -<P>
  -the <CODE>@INC</CODE> is being changed only for the time the code is being parsed and compiled.
  -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://www.nowhere.com/perl-status?inc">http://www.nowhere.com/perl-status?inc</A>
  -and look at the bottom of the page. (I assume you have configured the <A HREF="././config.html#_perl_status_location">/perl-status location</A>.)
  -
  -<P>
  -Also, notice the following caveat: While ``<CODE>.</CODE>'' is in the <CODE>@INC</CODE> -- perl knows to <CODE>require()</CODE> files relative to the script directory. Once the script was parsed - the
  -server doesn't remember the path any more! So you end up with broken entry
  -in <CODE>%INC</CODE> like:
  -
  -<P>
  -<PRE>  $INC{bar.pl} eq &quot;bar.pl&quot;
  -</PRE>
  -<P>
  -If you want Apache::StatINC to reload your script - modify the <CODE>@INC</CODE>
  -at the server startup file! or use a full path in <CODE>require()</CODE> call.
  -
  -<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>
  -Checking all the modules in <STRONG>%INC</STRONG> every time can add a large overhead to server response times, and you
  -certainly would not want
  -<CODE>Apache::StatINC</CODE> module to be enabled in your production site's configuration. But sometimes
  -you want to have some Configuration module to be reloaded without
  -restarting the whole server. To accomplish this, one of the solutions is to
  -use a code that I describe below.
  -
  -<P>
  -Assuming that you start your script with loading <CODE>Foo::Bar</CODE> and importing some tags:
  -
  -<P>
  -<PRE>  use lib &quot;/some/private/path&quot;;
  -  use Foo::Bar qw(:tags_group tag1 tag2);
  -</PRE>
  -<P>
  -Now to make a modification testing and reload at runtime you have to use
  -something like this:
  -
  -<P>
  -<PRE>  # child's private global variable to keep the timestamps
  -  use vars qw(%MODIFIED);
  -    
  -  my $module = &quot;Foo::Bar&quot;;
  -  
  -  (my $inc_key = $module) =~ s|::|/|g;
  -  $inc_key .= &quot;.pm&quot;;
  -  # the $module's path should be registered in %INC if it was already loaded
  -  my $path = $INC{$inc_key} or warn &quot;Can't find $inc_key in %INC\n&quot;;
  -  
  -  # Note: consider to not continue if $path wasn't set!
  -  
  -  # set modification time if it wasn't set before (first time)
  -  # Note: Use (stat $path)[9] instead of -M test, if you reset
  -  # time with $^M=time
  -  $MODIFIED{$module} ||= -M $path;
  -    
  -  # now check whether it was changed (assuming the above wasn't
  -  # performed in this session
  -  if ($MODIFIED{$module} != -M $path){
  -    # only if deleted from %INC the require will be called below
  -    delete $INC{$inc_key};
  -    
  -    require $path;
  -    
  -    # now reimport the symbols (if you need them back :)
  -    import $module qw(:tags_group tag1 tag2);
  -    
  -    # Update the MODIFICATION times
  -    $MODIFIED{$module} = -M $path;
  -  }
  -</PRE>
  -<P>
  -You may want to add debug print statements to debug this code in your
  -application.
  -
  -<P>
  -Read the ``use versus require'' article for more info. ( <A
  -HREF="http://www.perl.com/CPAN-local/doc/FMTEYEWTK/use_vs_require">http://www.perl.com/CPAN-local/doc/FMTEYEWTK/use_vs_require</A>
  -)
  -
  -<P>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<CENTER><H2><A NAME="Reloading_handlers">Reloading handlers</A></H2></CENTER>
  -<P>
  -If you want to reload perlhandler on each invocation, the following trick
  -will do it:
  -
  -<P>
  -<PRE>  PerlHandler &quot;sub { do 'MyTest.pm'; MyTest::handler(shift) }&quot;
  -</PRE>
  -<P>
  -<CODE>do()</CODE> will reload <CODE>MyTest.pm</CODE> every request.
  -
  -<P>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
   <CENTER><H1><A NAME="Filehandlers_and_locks_leakages">Filehandlers and locks leakages</A></H1></CENTER>
   <P>
   When you write a script running under mod_cgi, you can get away with sloppy
  @@ -1894,6 +3330,40 @@
   
   <P>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<CENTER><H1><A NAME="Sharing_variables_between_proces">Sharing variables between processes</A></H1></CENTER>
  +<P>
  +META: to be completed
  +
  +<UL>
  +<P><LI>
  +<P>
  +Global variables initialized at the server startup, through the Perl
  +startup file, can be shared between processes, untill modified by some of
  +the processes. e.g. when you write:
  +
  +<P>
  +<PRE>  $My::debug = 1;
  +</PRE>
  +<P>
  +all processes will read the same value. If one of the processes changes
  +that value to <CODE>0</CODE>, it'll be still equal to <CODE>1</CODE> for any process, but the one who actually did the change. When the process
  +modifies the variable, it becomes process' private copy.
  +
  +<P><LI>
  +<P>
  +<CODE>IPC::Shareable</CODE> can be used to share variables between children.
  +
  +<P><LI>
  +<P>
  +libmm
  +
  +<P><LI>
  +<P>
  +other methods?
  +
  +</UL>
  +<P>
  +<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></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
  @@ -2099,23 +3569,27 @@
   </PRE>
   <P>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<CENTER><H1><A NAME="Forking_subprocesses_from_mod_pe">Forking subprocesses from mod_perl</A></H1></CENTER>
  +<CENTER><H1><A NAME="Forking_or_Executing_subprocesse">Forking or Executing subprocesses from mod_perl</A></H1></CENTER>
   <P>
   Generally you should not fork from your mod_perl scripts, since when you do
   -- you are forking the entire apache web server, lock, stock and barrel.
   Not only is your perl code being duplicated, but so is mod_ssl,
   mod_rewrite, mod_log, mod_proxy, mod_spelling or whatever modules you have
  -used in your server, all the core routines and so on. A much wiser approach
  -would be to spawn a sub-process, hand it the information it needs to do the
  -task, and have it detach (close x3 +
  +used in your server, all the core routines and so on.
  +
  +<P>
  +A much wiser approach would be to spawn a sub-process, hand it the
  +information it needs to do the task, and have it detach (close x3 +
   <CODE>setsid()</CODE>). This is wise only if the parent who spawns this process, immediately
  -continue, you do not wait for the sub process to complete. This approach is
  +continue, you do not wait for the sub-process to complete. This approach is
   suitable for a situation when you want to trigger a long time taking
   process through the web interface, like processing some data, sending email
   to thousands of subscribed users and etc. Otherwise, you should convert the
   code into a module, and use its functions or methods to call from CGI
  -script. Just making a
  -<CODE>system()</CODE> call defeats the whole idea behind mod_perl, perl interpreter and modules
  +script.
  +
  +<P>
  +Just making a <CODE>system()</CODE> call defeats the whole idea behind mod_perl, perl interpreter and modules
   should be loaded again for this external program to run.
   
   <P>
  @@ -2156,55 +3630,97 @@
   post-processing, look into <CODE>PerlCleanupHandler</CODE>.
   
   <P>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<CENTER><H1><A NAME="Generating_correct_HTTP_MIME_Hea">Generating correct HTTP MIME Headers</A></H1></CENTER>
  +If you are interested in more deep level details, this is what actually
  +happens when you fork and make a system call, like
  +
   <P>
  -The <CODE>Apache::print()</CODE> routine has to gather up the headers that your script outputs, in order to
  -pass them to <CODE>$r-&amp;gt;send_http_header</CODE>. This happens in <CODE>src/modules/perl/Apache.xs</CODE> (<CODE>print</CODE>) and
  -<CODE>Apache/Apache.pm</CODE> (<CODE>send_cgi_header</CODE>). There is a shortcut in there, namely the assumption that each print
  -statement contains one or more complete headers. If for example you used to
  -generate a
  -<CODE>Set-Cookie</CODE> header by multiply <CODE>print()</CODE> statements, like:
  +<PRE>  system(&quot;echo Hi&quot;),exit unless fork();
  +</PRE>
  +<P>
  +What happens is that <CODE>fork()</CODE> gives you 2 execution paths and
  +the child gets virtual memory sharing a copy of the program text (read
  +only) and sharing a copy of the data space copy-on-write (remember why you
  +pre-load modules in mod_perl?). In the above code a parent will immediately
  +continue with the code that comes up after the fork, while the forked
  +process will execute <CODE>system(&quot;echo Hi&quot;)</CODE> and then terminate itself. Note that you might need to set:
   
   <P>
  -<PRE>   print &quot;Content-type: text/html\n&quot;;
  -   print &quot;Set-Cookie: iscookietext\; &quot;;
  -   print &quot;expires=Wednesday, 09-Nov-1999 00:00:00 GMT\; &quot;;
  -   print &quot;path=\/\; &quot;;
  -   print &quot;domain=\.mmyserver.com\; &quot;;
  -   print &quot;\n\n&quot;;
  -   print &quot;hello&quot;;
  +<PRE>  $SIG{CHLD} = sub {wait};
   </PRE>
   <P>
  -your generated <CODE>Set-Cookie</CODE> header is split over a number of print statements and gets lost. Try this:
  +or
   
   <P>
  -<PRE>   print &quot;Content-type: text/html\n&quot;;
  -   my $cookie = &quot;Set-Cookie: iscookietext\; &quot;;
  -   $cookie .= &quot;expires=Wednesday, 09-Nov-1999 00:00:00 GMT\; &quot;;
  -   $cookie .= &quot;path=\/\; &quot;;
  -   $cookie .= &quot;domain=\.mmyserver.com\; &quot;;
  -   print $cookie;
  -   print &quot;\n\n&quot;;
  -   print &quot;hello&quot;;
  +<PRE>  $SIG{CHLD} = IGNORE;
  +</PRE>
  +<P>
  +or the terminated process might become a zombie. Normally, every process
  +has its parent, many processes a children of PID 1, the init process.
  +Zombie, is a process that doesn't have a father. When the child quits, it
  +reports the termination to his parent. If he doesn't know who the father is
  +it becomes zombie. (META: Did I formulate it correctly?)
  +
  +<P>
  +The only work is setting up the page tables for the virtual memory and the
  +second process goes on its separate way.
  +
  +<P>
  +Next, Perl will find <CODE>/bin/echo</CODE> along the search path, and invoke it directly. Perl <CODE>system()</CODE>
  +is *not* <CODE>system(3)</CODE> [C-library]. Only when the command has shell meta-chars does Perl invoke a
  +real shell. That's a *very* nice optimization.
  +
  +<P>
  +Only if you do:
  +
  +<P>
  +<PRE>  system &quot;sh -c 'echo foo'&quot;
   </PRE>
   <P>
  -&lt;META&gt; some leftovers... # =head1 Coding with mod_perl
  +OS actually parses your command with a shell so you <CODE>exec()</CODE> a
  +copy of
  +<CODE>/bin/sh</CODE>, but since one is almost certainly already running somewhere, the system
  +will notice that (via the disk inode reference) and replace your virtual
  +memory page table with one pointed at the already-loaded program code plus
  +your own data space. Then the shell parses the passed command.
   
   <P>
  -Before you start coding for <CODE>Apache::Registry</CODE>, you have to change your programming state of mind. Scripts running under
  -mod_perl are like subroutines are being called from a continually running
  -daemon. Imagine a daemon process that when requested to process some
  -script, reads it in, compiles it as a subroutine, and finally executes it.
  -On any subsequent request, it'll just recall the already compiled
  -subroutine. Hope that you get the idea.
  +Since it is <CODE>echo</CODE>, it will execute it as a built-in in the latter example or a <CODE>/bin/echo</CODE> in the former and be done, but this is only an example. You aren't calling <CODE>system(&quot;echo Hi&quot;)</CODE> in your mod_perl scripts, right? Since most other real things (heavy
  +programs executed as a subprocess) would involve repeating the process to
  +load the specified command or script (it might involve some actual demand
  +paging from the program file if you execute new code).
   
   <P>
  -The best thing you do when coding from scratch is to make it clean and use
  -packages. By ``make it clean'' we mean make certain that you <STRONG>use
  -strict;</STRONG> and that your script produces no warnings when tested via
  -<STRONG>perl -cw myscript.pl</STRONG>. As you go thru the notes you will understand why. &lt;/META&gt;
  +The only place you see real overhead from this scheme is when the parent
  +process is huge (unfortunately like mod_perl...) and the page table becomes
  +large as a side effect. The whole point of mod_perl is to avoid having to
  +<CODE>fork()</CODE> / <CODE>exec()</CODE> something on every hit, though.
  +Perl can do just about anything by itself. However, you probably won't get
  +in trouble until you hit about 30 forks/sec on a so-so pentium.
   
  +<P>
  +<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<CENTER><H1><A NAME="Passing_and_preserving_custom_da">Passing and preserving custom data structures between handlers</A></H1></CENTER>
  +<P>
  +Let's say that you wrote a few handlers to process a request, and they all
  +need to share some custom Perl data structure. The <CODE>pnotes()</CODE>
  +method comes to rescue. Taken that one of the handlers stored some data in
  +hash <CODE>%my_data</CODE>, before it finished its activity:
  +
  +<P>
  +<PRE>   # First handler:
  +   $r-&gt;pnotes('my_info' =&gt; \%hash);
  +</PRE>
  +<P>
  +All the following handler will be able to retrive the stored data with.
  +
  +<P>
  +<PRE>   # Later handler:
  +   my $info = $r-&gt;pnotes('my_info');
  +   print $info-&gt;{foo};
  +</PRE>
  +<P>
  +The stored information will be destroyed at the end of the request.
  +
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
   	     The <a href="http://www.modperl.com/">
   	     <B>Writing Apache Modules with Perl and C</B></a>
  @@ -2215,6 +3731,16 @@
   	     Amazon.com</a>.
   
   	     <HR>
  +
  +	     Your corrections of either technical or grammatical
  +	     errors are very welcome. You are encouraged to help me
  +	     to improve this guide.  If you have something to
  +	     contribute please <A
  +	     HREF="help.html#This_document_s_Author"> send it
  +	     directly to me</A>.
  +
  +	     <HR>
  +
   	     [    <A HREF="start.html">Prev</A> |      <A HREF="index.html">Main Page</A> | <A HREF="performance.html">Next</A>      ]
   
   <CENTER><TABLE CELLSPACING=2 CELLPADDING=2 WIDTH="100%" >
  @@ -2228,7 +3754,7 @@
       <B>
         <FONT SIZE=-1>
   	     Written by <A HREF="help.html#This_document_s_Author">Stas Bekman</A>.
  -	     <BR>Last Modified at 08/17/1999
  +	     <BR>Last Modified at 09/26/1999
         </FONT>
       </B>
     </TD>
  
  
  
  1.18      +34 -3     modperl-site/guide/scenario.html
  
  Index: scenario.html
  ===================================================================
  RCS file: /export/home/cvs/modperl-site/guide/scenario.html,v
  retrieving revision 1.17
  retrieving revision 1.18
  diff -u -r1.17 -r1.18
  --- scenario.html	1999/08/17 19:03:45	1.17
  +++ scenario.html	1999/09/25 23:14:16	1.18
  @@ -73,6 +73,15 @@
   
   	     <HR>
   
  +	       Your corrections of either technical or grammatical
  +	       errors are very welcome. You are encouraged to help me
  +	       to improve this guide.  If you have something to
  +	       contribute please <A
  +	       HREF="help.html#This_document_s_Author"> send it
  +	       directly to me</A>.
  +
  +	       <HR>
  +
   	      <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
   <P>
   <CENTER><H1><A NAME="Standalone_mod_perl_Enabled_Apac">Standalone mod_perl Enabled Apache Server</A></H1></CENTER>
  @@ -92,7 +101,7 @@
     % perl Makefile.PL APACHE_SRC=../apache_x.x.x/src \
       DO_HTTPD=1 USE_APACI=1 PERL_MARK_WHERE=1 EVERYTHING=1
     % make &amp;&amp; make test &amp;&amp; make install
  -  % cd ../apache_x.x.x/src
  +  % cd ../apache_x.x.x
     % make install
   </PRE>
   <P>
  @@ -163,7 +172,7 @@
   directory tree and to put the <CODE>httpd</CODE> there.
   
   <P>
  -<PRE>  % cd ../apache_x.x.x/src
  +<PRE>  % cd ../apache_x.x.x
     % make install
   </PRE>
   <P>
  @@ -1230,6 +1239,14 @@
   coming from, before changing the <CODE>remote_ip</CODE>.
   
   <P>
  +Generally you shouldn't trust the <CODE>X-Forwarded-For</CODE> header. You only want to rely on <CODE>X-Forwarded-For</CODE> headers from proxies you control yourself. If you know how to spoof a
  +cookie you've probably got the general idea on making HTTP headers and can
  +spoof the
  +<CODE>X-Forwarded-For</CODE> header as well. The only address *you* can count on as being a reliable
  +value is the one from
  +<CODE>r-&amp;gt;connection-&amp;gt;remote_ip</CODE>.
  +
  +<P>
   From that point on, the remote IP address is correct. You should be able to
   access <CODE>REMOTE_ADDR</CODE> as usual.
   
  @@ -1281,6 +1298,10 @@
   The only possible caveat in the config file is that your <CODE>Auth</CODE> stuff needs to be in <CODE>&lt;Directory ...</CODE>&gt; ... <CODE>&lt;/Directory</CODE>&gt; tags because if you use a <CODE>&lt;Location /...</CODE>&gt; ... <CODE>&lt;/Location</CODE>&gt; the proxypass server takes the auth info for its own authentication
   and would not pass it on.
   
  +<P>
  +The same with mod_ssl, if plugged into a front-end server, all the SSL
  +requests be encoded/decoded properly by it.
  +
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
   	     The <a href="http://www.modperl.com/">
   	     <B>Writing Apache Modules with Perl and C</B></a>
  @@ -1291,6 +1312,16 @@
   	     Amazon.com</a>.
   
   	     <HR>
  +
  +	     Your corrections of either technical or grammatical
  +	     errors are very welcome. You are encouraged to help me
  +	     to improve this guide.  If you have something to
  +	     contribute please <A
  +	     HREF="help.html#This_document_s_Author"> send it
  +	     directly to me</A>.
  +
  +	     <HR>
  +
   	     [    <A HREF="strategy.html">Prev</A> |      <A HREF="index.html">Main Page</A> | <A HREF="install.html">Next</A>      ]
   
   <CENTER><TABLE CELLSPACING=2 CELLPADDING=2 WIDTH="100%" >
  @@ -1304,7 +1335,7 @@
       <B>
         <FONT SIZE=-1>
   	     Written by <A HREF="help.html#This_document_s_Author">Stas Bekman</A>.
  -	     <BR>Last Modified at 08/17/1999
  +	     <BR>Last Modified at 09/25/1999
         </FONT>
       </B>
     </TD>
  
  
  
  1.6       +80 -5     modperl-site/guide/security.html
  
  Index: security.html
  ===================================================================
  RCS file: /export/home/cvs/modperl-site/guide/security.html,v
  retrieving revision 1.5
  retrieving revision 1.6
  diff -u -r1.5 -r1.6
  --- security.html	1999/08/17 19:03:45	1.5
  +++ security.html	1999/09/25 23:14:17	1.6
  @@ -36,7 +36,8 @@
   	<LI><A HREF="#Authentication_code_snippets">Authentication code snippets</A>
   	<UL>
   
  -		<LI><A HREF="#Forcing_reauthenticating">Forcing reauthenticating</A>
  +		<LI><A HREF="#Forcing_re_authentication">Forcing re-authentication</A>
  +		<LI><A HREF="#OK_AUTH_REQUIRED_and_FORBIDDEN_">OK, AUTH_REQUIRED.and FORBIDDEN in Authentication handlers</A>
   	</UL>
   
   </UL>
  @@ -54,6 +55,15 @@
   
   	     <HR>
   
  +	       Your corrections of either technical or grammatical
  +	       errors are very welcome. You are encouraged to help me
  +	       to improve this guide.  If you have something to
  +	       contribute please <A
  +	       HREF="help.html#This_document_s_Author"> send it
  +	       directly to me</A>.
  +
  +	       <HR>
  +
   	      <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
   <P>
   <CENTER><H1><A NAME="An_Importance_of_Your_site_s_Sec">An Importance of Your site's Security</A></H1></CENTER>
  @@ -228,22 +238,77 @@
   <CENTER><H1><A NAME="Authentication_code_snippets">Authentication code snippets</A></H1></CENTER>
   <P>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<CENTER><H2><A NAME="Forcing_reauthenticating">Forcing reauthenticating</A></H2></CENTER>
  +<CENTER><H2><A NAME="Forcing_re_authentication">Forcing re-authentication</A></H2></CENTER>
   <P>
   To force authenticated user to reauthenticate just send the following
   header to the browser:
   
   <P>
  -<PRE>  HTTP/1.0 401 Unauthorized
  +<PRE>  WWW-Authenticate: Basic realm=&quot;My Realm&quot;
  +  HTTP/1.0 401 Unauthorized
   </PRE>
   <P>
  -This will pop-up (on Netscape at least) a window saying that the
  +This will pop-up (in Netscape at least) a window saying that the
   <STRONG>Authorization Failed.  Retry?</STRONG> And an <STRONG>OK</STRONG> and a <STRONG>Cancel</STRONG> buttons. When that window pops up you know that the password has been
   cleared. If the user hits the <STRONG>Cancel</STRONG> button the username will also be cleared, and you can have a page that will
   be output written after the header if this is a CGI (or PHP, or anything
   else like that). If the user hits the <STRONG>OK</STRONG> button, the authentication window will be brought up again with their
   previous username already in the username field.
   
  +<P>
  +In Perl API you would use <CODE>note_basic_auth_failure()</CODE> method to
  +force reauthentication.
  +
  +<P>
  +Since the browser's behaviour is in no way guaranteed, it also may not
  +work, and that should be noted.
  +
  +<P>
  +<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<CENTER><H2><A NAME="OK_AUTH_REQUIRED_and_FORBIDDEN_">OK, AUTH_REQUIRED.and FORBIDDEN in Authentication handlers</A></H2></CENTER>
  +<P>
  +When your authentication handler returns OK, it means that user has
  +correctly authenticated and now <CODE>$r-&amp;gt;connection-&amp;gt;user</CODE> will have the username set for all the subsequent requests. For
  +<CODE>Apache::Registry</CODE> and friends, where the environment variables setting weren't turned off, an
  +equivalent <CODE>$ENV{REMOTE_USER}</CODE>
  +variable will be available. Password is available only through Perl API
  +with help of <CODE>get_basic_auth_pw()</CODE> method.
  +
  +<P>
  +If there is a failure, returned <CODE>AUTH_REQUIRED</CODE> flag will tell the browser to pop up an authentication window, to try
  +again, unless it's a first time. For example:
  +
  +<P>
  +<PRE>   my($status, $sent_pw) = $r-&gt;get_basic_auth_pw;
  +   unless($r-&gt;connection-&gt;user and $sent_pw) {
  +       $r-&gt;note_basic_auth_failure;
  +       $r-&gt;log_reason(&quot;Both a username and password must be provided&quot;);
  +       return AUTH_REQUIRED;
  +   }
  +</PRE>
  +<P>
  +Let's say that you have a mod_perl authen handler, where user credentials
  +are checked against a database, and it either returns
  +<CODE>OK</CODE> or <CODE>AUTH_REQUIRED</CODE>. One of the possible authentication failure case might happen when the
  +username/password are correct, but the user's account has been suspended
  +temporarily.
  +
  +<P>
  +If this is the case you would like to make the user aware of this, through
  +a page display instead of having the browser pop up the auth dialog again.
  +At the same time you need to refuse the authentication, of course.
  +
  +<P>
  +The solution is to return <CODE>FORBIDDEN</CODE>, but before that you should set a custom error page for this specific
  +handler, with help of
  +<CODE>$r-&amp;gt;custom_response</CODE>. Something like:
  +
  +<P>
  +<PRE>  use Apache::Constants qw(:common);
  +  $r-&gt;custom_response(SERVER_ERROR, &quot;/errors/suspended_account.html&quot;);
  +   
  +  return FORBIDDEN if $suspended;
  +</PRE>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
   	     The <a href="http://www.modperl.com/">
   	     <B>Writing Apache Modules with Perl and C</B></a>
  @@ -254,6 +319,16 @@
   	     Amazon.com</a>.
   
   	     <HR>
  +
  +	     Your corrections of either technical or grammatical
  +	     errors are very welcome. You are encouraged to help me
  +	     to improve this guide.  If you have something to
  +	     contribute please <A
  +	     HREF="help.html#This_document_s_Author"> send it
  +	     directly to me</A>.
  +
  +	     <HR>
  +
   	     [    <A HREF="warnings.html">Prev</A> |      <A HREF="index.html">Main Page</A> | <A HREF="databases.html">Next</A>      ]
   
   <CENTER><TABLE CELLSPACING=2 CELLPADDING=2 WIDTH="100%" >
  @@ -267,7 +342,7 @@
       <B>
         <FONT SIZE=-1>
   	     Written by <A HREF="help.html#This_document_s_Author">Stas Bekman</A>.
  -	     <BR>Last Modified at 07/29/1999
  +	     <BR>Last Modified at 09/25/1999
         </FONT>
       </B>
     </TD>
  
  
  
  1.16      +19 -42    modperl-site/guide/snippets.html
  
  Index: snippets.html
  ===================================================================
  RCS file: /export/home/cvs/modperl-site/guide/snippets.html,v
  retrieving revision 1.15
  retrieving revision 1.16
  diff -u -r1.15 -r1.16
  --- snippets.html	1999/08/17 19:03:45	1.15
  +++ snippets.html	1999/09/25 23:14:18	1.16
  @@ -26,8 +26,6 @@
   <P><B><FONT SIZE=-1>Table of Contents:</FONT></B></P>
   <UL>
   
  -	<LI><A HREF="#Sending_MIME_headers">Sending MIME headers</A>
  -	<LI><A HREF="#How_to_avoid_printing_the_header">How to avoid printing the header more than once</A>
   	<LI><A HREF="#More_on_relative_paths">More on relative paths</A>
   	<LI><A HREF="#Watching_the_error_log_file_with">Watching the error_log file without telneting to the server</A>
   	<LI><A HREF="#Accessing_variables_from_the_cal">Accessing variables from the caller's package</A>
  @@ -47,48 +45,17 @@
   
   	     <HR>
   
  -	      <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<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 the config file: 
  -
  -<P>
  -<PRE>  PerlSendHeader On
  -</PRE>
  -<P>
  -The safest bet is to use CGI.pm's <CODE>header()</CODE> method. (If you do <CODE>print header();</CODE>, you don't need the above setting.)
  -
  -<P>
  -Also there is <CODE>$ENV{PERL_SEND_HEADER}</CODE> to see if <CODE>PerlSendHeader</CODE> is <CODE>On</CODE> or
  -<CODE>Off</CODE>.
  -
  -<P>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<CENTER><H1><A NAME="How_to_avoid_printing_the_header">How to avoid printing the header more than once</A></H1></CENTER>
  -<P>
  -I'm sure you have been in situations where you wish you knew whether the
  -MIME header has already been printed. Since if it is printed again it will
  -cause an ugly ``Content-type: ...'' string to show up in the browser. So
  -how do we solve it? With the help of a closure.
  +	       Your corrections of either technical or grammatical
  +	       errors are very welcome. You are encouraged to help me
  +	       to improve this guide.  If you have something to
  +	       contribute please <A
  +	       HREF="help.html#This_document_s_Author"> send it
  +	       directly to me</A>.
   
  -<P>
  -Just copy the code below, including the block's curly parentheses. And
  -everywhere in your code you print the header use the <CODE>print_header()</CODE> sub.
  -<CODE>$need_header</CODE> is the same kind of beast as a static variable in C, so it remembers its
  -value from call to call.
  +	       <HR>
   
  +	      <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
   <P>
  -<PRE>  {
  -    my $need_header = 1;
  -    sub print_header {
  -      print header(@_),$need_header = 0 if $need_header;
  -    }
  -  }
  -</PRE>
  -<P>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
   <CENTER><H1><A NAME="More_on_relative_paths">More on relative paths</A></H1></CENTER>
   <P>
   Many people use relative paths for <CODE>require</CODE>, <CODE>use</CODE>, etc., or open files in the current directory or relative to the current
  @@ -284,6 +251,16 @@
   	     Amazon.com</a>.
   
   	     <HR>
  +
  +	     Your corrections of either technical or grammatical
  +	     errors are very welcome. You are encouraged to help me
  +	     to improve this guide.  If you have something to
  +	     contribute please <A
  +	     HREF="help.html#This_document_s_Author"> send it
  +	     directly to me</A>.
  +
  +	     <HR>
  +
   	     [    <A HREF="perl.html">Prev</A> |      <A HREF="index.html">Main Page</A> | <A HREF="hardware.html">Next</A>      ]
   
   <CENTER><TABLE CELLSPACING=2 CELLPADDING=2 WIDTH="100%" >
  @@ -297,7 +274,7 @@
       <B>
         <FONT SIZE=-1>
   	     Written by <A HREF="help.html#This_document_s_Author">Stas Bekman</A>.
  -	     <BR>Last Modified at 08/17/1999
  +	     <BR>Last Modified at 09/25/1999
         </FONT>
       </B>
     </TD>
  
  
  
  1.17      +35 -7     modperl-site/guide/start.html
  
  Index: start.html
  ===================================================================
  RCS file: /export/home/cvs/modperl-site/guide/start.html,v
  retrieving revision 1.16
  retrieving revision 1.17
  diff -u -r1.16 -r1.17
  --- start.html	1999/08/17 19:03:46	1.16
  +++ start.html	1999/09/25 23:14:18	1.17
  @@ -42,18 +42,26 @@
   
   	     <HR>
   
  +	       Your corrections of either technical or grammatical
  +	       errors are very welcome. You are encouraged to help me
  +	       to improve this guide.  If you have something to
  +	       contribute please <A
  +	       HREF="help.html#This_document_s_Author"> send it
  +	       directly to me</A>.
  +
  +	       <HR>
  +
   	      <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
   <P>
   <CENTER><H1><A NAME="What_s_inside_">What's inside?</A></H1></CENTER>
   <P>
  -Before you start installing mod_perl, you should have an overall picture of
  -this wonderful technology. There is more then one way to use a
  +Before you start with mod_perl installation, you should have an overall
  +picture of this wonderful technology. There is more then one way to use a
   mod_perl-enabled webserver. You have to decide what mod_perl scheme you
  -want to use. <A HREF="././strategy.html#">Picking the Right Strategy</A>
  -chapter presents various approaches and discusses their pros and cons.
  +want to use. <A HREF="././strategy.html#">Picking the Right Strategy</A> chapter presents various approaches and discusses their pros and cons.
   
   <P>
  -Once you know what fits your requirements the best, you should proceed to <A HREF="././scenario.html#">Real World Scenarios Implementaion</A>. This chapter provides very detailed scenarios of the schemes discussed in
  +Once you know what fits your requirements the best, you should proceed to <A HREF="././scenario.html#">Real World Scenarios Implementation</A>. This chapter provides very detailed scenarios of the schemes discussed in
   the
   <A HREF="././strategy.html#">Picking the Right Strategy</A> chapter.
   
  @@ -98,6 +106,9 @@
   the chapter <A HREF="././warnings.html#">Warnings and Errors: Where and Why</A>.
   
   <P>
  +<A HREF="././security.html#">Protecting Your Site</A> - Everything regarding security.
  +
  +<P>
   If you are into driving relational databases with your cgi scripts, the <A HREF="././databases.html#">mod_perl and Relational Databases</A> chapter will tell you all about the database-related goodies mod_perl has
   prepared for you.
   
  @@ -110,7 +121,7 @@
   possible? Is it secure? Will it work? What resources does it take? The <A HREF="././multiuser.html#">mod_perl for ISPs. mod_perl and Virtual Hosts</A>
   chapter answers all these questions. If you want to run a mod_perl- enabled
   server, but do not have root access, read this chapter as well, either to
  -learn how do it yourself, or maybe to persuade your ISP to provide this
  +learn how to do it yourself, or maybe to persuade your ISP to provide this
   service.
   
   <P>
  @@ -155,6 +166,13 @@
   writing the scripts.
   
   <P>
  +The <A HREF="././hardware.html#">Choosing an Operating System and Hardware</A> chapter gives you an idea on how to choose the SW and HW for the webserver.
  +
  +<P>
  +The &lt;mod_perl Advocacy|advocacy/&gt; tries to help to make it easier to
  +advocate mod_perl around the world.
  +
  +<P>
   The <A HREF="././help.html#">Getting Helped and Further Learning</A> chapter refers you to other related information resources, like learning
   Perl programming and SQL, understanding security, building databases, and
   more.
  @@ -174,6 +192,16 @@
   	     Amazon.com</a>.
   
   	     <HR>
  +
  +	     Your corrections of either technical or grammatical
  +	     errors are very welcome. You are encouraged to help me
  +	     to improve this guide.  If you have something to
  +	     contribute please <A
  +	     HREF="help.html#This_document_s_Author"> send it
  +	     directly to me</A>.
  +
  +	     <HR>
  +
   	     [    <A HREF="intro.html">Prev</A> |      <A HREF="index.html">Main Page</A> | <A HREF="porting.html">Next</A>      ]
   
   <CENTER><TABLE CELLSPACING=2 CELLPADDING=2 WIDTH="100%" >
  @@ -187,7 +215,7 @@
       <B>
         <FONT SIZE=-1>
   	     Written by <A HREF="help.html#This_document_s_Author">Stas Bekman</A>.
  -	     <BR>Last Modified at 07/29/1999
  +	     <BR>Last Modified at 09/26/1999
         </FONT>
       </B>
     </TD>
  
  
  
  1.17      +19 -0     modperl-site/guide/status.html
  
  Index: status.html
  ===================================================================
  RCS file: /export/home/cvs/modperl-site/guide/status.html,v
  retrieving revision 1.16
  retrieving revision 1.17
  diff -u -r1.16 -r1.17
  --- status.html	1999/08/17 19:03:46	1.16
  +++ status.html	1999/09/25 23:14:19	1.17
  @@ -49,6 +49,15 @@
   
   	     <HR>
   
  +	       Your corrections of either technical or grammatical
  +	       errors are very welcome. You are encouraged to help me
  +	       to improve this guide.  If you have something to
  +	       contribute please <A
  +	       HREF="help.html#This_document_s_Author"> send it
  +	       directly to me</A>.
  +
  +	       <HR>
  +
   	      <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>
  @@ -147,6 +156,16 @@
   	     Amazon.com</a>.
   
   	     <HR>
  +
  +	     Your corrections of either technical or grammatical
  +	     errors are very welcome. You are encouraged to help me
  +	     to improve this guide.  If you have something to
  +	     contribute please <A
  +	     HREF="help.html#This_document_s_Author"> send it
  +	     directly to me</A>.
  +
  +	     <HR>
  +
   	     [    <A HREF="multiuser.html">Prev</A> |      <A HREF="index.html">Main Page</A> | <A HREF="debug.html">Next</A>      ]
   
   <CENTER><TABLE CELLSPACING=2 CELLPADDING=2 WIDTH="100%" >
  
  
  
  1.7       +19 -0     modperl-site/guide/strategy.html
  
  Index: strategy.html
  ===================================================================
  RCS file: /export/home/cvs/modperl-site/guide/strategy.html,v
  retrieving revision 1.6
  retrieving revision 1.7
  diff -u -r1.6 -r1.7
  --- strategy.html	1999/08/17 19:03:46	1.6
  +++ strategy.html	1999/09/25 23:14:20	1.7
  @@ -49,6 +49,15 @@
   
   	     <HR>
   
  +	       Your corrections of either technical or grammatical
  +	       errors are very welcome. You are encouraged to help me
  +	       to improve this guide.  If you have something to
  +	       contribute please <A
  +	       HREF="help.html#This_document_s_Author"> send it
  +	       directly to me</A>.
  +
  +	       <HR>
  +
   	      <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
   <P>
   <CENTER><H1><A NAME="Do_it_like_me_">Do it like me?!</A></H1></CENTER>
  @@ -683,6 +692,16 @@
   	     Amazon.com</a>.
   
   	     <HR>
  +
  +	     Your corrections of either technical or grammatical
  +	     errors are very welcome. You are encouraged to help me
  +	     to improve this guide.  If you have something to
  +	     contribute please <A
  +	     HREF="help.html#This_document_s_Author"> send it
  +	     directly to me</A>.
  +
  +	     <HR>
  +
   	     [    <A HREF="performance.html">Prev</A> |      <A HREF="index.html">Main Page</A> | <A HREF="scenario.html">Next</A>      ]
   
   <CENTER><TABLE CELLSPACING=2 CELLPADDING=2 WIDTH="100%" >
  
  
  
  1.18      +37 -3     modperl-site/guide/warnings.html
  
  Index: warnings.html
  ===================================================================
  RCS file: /export/home/cvs/modperl-site/guide/warnings.html,v
  retrieving revision 1.17
  retrieving revision 1.18
  diff -u -r1.17 -r1.18
  --- warnings.html	1999/08/17 19:03:46	1.17
  +++ warnings.html	1999/09/25 23:14:20	1.18
  @@ -45,6 +45,7 @@
   	<LI><A HREF="#RegistryLoader_Cannot_translate">RegistryLoader: Cannot translate the URI /home/httpd/perl/test.pl</A>
   	<LI><A HREF="#Evil_things_might_happen_when_us">Evil things might happen when using PerlFreshRestart</A>
   	<LI><A HREF="#server_reached_MaxClients_settin">server reached MaxClients setting, consider raising the MaxClients setting</A>
  +	<LI><A HREF="#syntax_error_at_dev_null_line_1">syntax error at /dev/null line 1, near &quot;line arguments:&quot;</A>
   </UL>
   <!-- INDEX END -->
   
  @@ -60,6 +61,15 @@
   
   	     <HR>
   
  +	       Your corrections of either technical or grammatical
  +	       errors are very welcome. You are encouraged to help me
  +	       to improve this guide.  If you have something to
  +	       contribute please <A
  +	       HREF="help.html#This_document_s_Author"> send it
  +	       directly to me</A>.
  +
  +	       <HR>
  +
   	      <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
   <P>
   <CENTER><H1><A NAME="General_Advice">General Advice</A></H1></CENTER>
  @@ -385,8 +395,8 @@
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
   <CENTER><H1><A NAME="Evil_things_might_happen_when_us">Evil things might happen when using PerlFreshRestart</A></H1></CENTER>
   <P>
  -Not all Perl modules can survive a reload. PerlFreshRestart does not much
  -more than:
  +Unfortunately, not all perl modules are robust enough to survive reload,
  +for them, unusual situation. PerlFreshRestart does not much more than:
   
   <P>
   <PRE>  while (my($k,$v) = each %INC) {
  @@ -408,6 +418,20 @@
   <P>
   See <A HREF="././performance.html#Choosing_MaxClients">Choosing MaxClients</A>.
   
  +<P>
  +<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<CENTER><H1><A NAME="syntax_error_at_dev_null_line_1">syntax error at /dev/null line 1, near &quot;line arguments:&quot;</A></H1></CENTER>
  +<P>
  +<PRE>  syntax error at /dev/null line 1, near &quot;line arguments:&quot;
  +  Execution of /dev/null aborted due to compilation errors.
  +  parse: Undefined error: 0
  +</PRE>
  +<P>
  +There is a chance that your <CODE>/dev/null</CODE> device is broken. Try:
  +
  +<P>
  +<PRE>  % sudo echo &gt; /dev/null
  +</PRE>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
   	     The <a href="http://www.modperl.com/">
   	     <B>Writing Apache Modules with Perl and C</B></a>
  @@ -418,6 +442,16 @@
   	     Amazon.com</a>.
   
   	     <HR>
  +
  +	     Your corrections of either technical or grammatical
  +	     errors are very welcome. You are encouraged to help me
  +	     to improve this guide.  If you have something to
  +	     contribute please <A
  +	     HREF="help.html#This_document_s_Author"> send it
  +	     directly to me</A>.
  +
  +	     <HR>
  +
   	     [    <A HREF="obvious.html">Prev</A> |      <A HREF="index.html">Main Page</A> | <A HREF="security.html">Next</A>      ]
   
   <CENTER><TABLE CELLSPACING=2 CELLPADDING=2 WIDTH="100%" >
  @@ -431,7 +465,7 @@
       <B>
         <FONT SIZE=-1>
   	     Written by <A HREF="help.html#This_document_s_Author">Stas Bekman</A>.
  -	     <BR>Last Modified at 07/09/1999
  +	     <BR>Last Modified at 09/26/1999
         </FONT>
       </B>
     </TD>
  
  
  

Mime
View raw message