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 all.html config.html control.html databases.html dbm.html debug.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 porting.html scenario.html security.html start.html status.html strategy.html warnings.html
Date Fri, 02 Jul 1999 13:42:50 GMT
sbekman     99/07/02 06:42:48

  Modified:    guide    CHANGES all.html config.html control.html
                        databases.html dbm.html debug.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 porting.html
                        scenario.html security.html start.html status.html
                        strategy.html warnings.html
  Log:
  * porting.pod: added "Exposing Apache::Registry secrets, closures,
    multiserver mode".
  
  * A complete review, which included corrections, verifications,
    extensions and clarifications was done to the following pods during
    the preparation of the tutorial for the 3rd apache conference:
  	start.pod
  	intro.pod
  	porting.pod
  	performance.pod
  	strategy.pod
  	scenario.pod
  	config.pod
  	install.pod
  	control.pod
  	databases.pod
  	multiuser.pod
  	help.pod
  
  Revision  Changes    Path
  1.14      +43 -0     modperl-site/guide/CHANGES
  
  Index: CHANGES
  ===================================================================
  RCS file: /export/home/cvs/modperl-site/guide/CHANGES,v
  retrieving revision 1.13
  retrieving revision 1.14
  diff -u -r1.13 -r1.14
  --- CHANGES	1999/06/19 21:14:58	1.13
  +++ CHANGES	1999/07/02 13:42:09	1.14
  @@ -1,5 +1,48 @@
   This is a CHANGES file for mod_perl guide
   
  +07.3.99 ver 1.14
  +
  +* porting.pod: added "Exposing Apache::Registry secrets, closures,
  +  multiserver mode".
  +
  +* A complete review, which included corrections, verifications,
  +  extensions and clarifications was done to the following pods during
  +  the preparation of the tutorial for the 3rd apache conference:
  +	start.pod     
  +	intro.pod     
  +	porting.pod   
  +	performance.pod
  +	strategy.pod  
  +	scenario.pod  
  +	config.pod    
  +	install.pod   
  +	control.pod   
  +	databases.pod 
  +	multiuser.pod  
  +	help.pod      
  +
  +* 
  +
  +* 
  +
  +* 
  +
  +* 
  +
  +* 
  +
  +* 
  +
  +* 
  +
  +* 
  +
  +* 
  +
  +* 
  +
  +* 
  +
   06.19.99 ver 1.13
   
   * While working on presentation discovered a wonderfull 'html2ps'
  
  
  
  1.15      +7185 -6613modperl-site/guide/all.html
  
  Index: all.html
  ===================================================================
  RCS file: /export/home/cvs/modperl-site/guide/all.html,v
  retrieving revision 1.14
  retrieving revision 1.15
  diff -u -r1.14 -r1.15
  --- all.html	1999/06/19 21:14:59	1.14
  +++ all.html	1999/07/02 13:42:11	1.15
  @@ -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.13
  - Jun, 19 1999</B></P></CENTER>
  +<CENTER><P><B>Version 1.14
  + Jul, 2 1999</B></P></CENTER>
    
   <P>
   <HR WIDTH="100%"></P>
  @@ -57,6 +57,98 @@
   
   	<LI><A HREF="start.html#What_s_inside_">What's inside?</A>
   </UL>
  +<P><LI><A HREF="porting.html"><B><FONT SIZE=+1>CGI to mod_perl Porting. mod_perl Coding guidelines.</FONT></B></A></LI><P>
  +<UL>
  +
  +	<LI><A HREF="porting.html#Document_Coverage">Document Coverage</A>
  +	<LI><A HREF="porting.html#Before_you_start_to_code">Before you start to code</A>
  +	<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#_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#Memory_leakage">Memory leakage</A>
  +	</UL>
  +
  +	<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>
  +	</UL>
  +
  +	<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#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>
  +</UL>
  +<P><LI><A HREF="performance.html"><B><FONT SIZE=+1>Performance. Benchmarks.</FONT></B></A></LI><P>
  +<UL>
  +
  +	<LI><A HREF="performance.html#Performance_The_Overall_picture">Performance: The Overall picture</A>
  +	<LI><A HREF="performance.html#Sharing_Memory">Sharing Memory</A>
  +	<LI><A HREF="performance.html#Preload_Perl_modules_at_server_s">Preload Perl modules at server startup</A>
  +	<UL>
  +
  +		<LI><A HREF="performance.html#Preload_Perl_modules_Real_Numb">Preload Perl modules - Real Numbers</A>
  +	</UL>
  +
  +	<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#How_can_I_find_if_my_mod_perl_sc">How can I find if my mod_perl scripts have memory leaks (and where)</A>
  +	<LI><A HREF="performance.html#Limiting_the_size_of_the_process">Limiting the size of the processes</A>
  +	<LI><A HREF="performance.html#Limiting_the_resources_used_by_h">Limiting the resources used by httpd children</A>
  +	<LI><A HREF="performance.html#Limiting_the_request_rate_speed_">Limiting the request rate speed (robots blocking)</A>
  +	<LI><A HREF="performance.html#Benchmarks_Impressing_your_Boss">Benchmarks. Impressing your Boss and Colleagues.</A>
  +	<UL>
  +
  +		<LI><A HREF="performance.html#Developers_Talk">Developers Talk</A>
  +		<LI><A HREF="performance.html#Benchmarking_a_Graphic_hits_coun">Benchmarking a Graphic hits counter with Persistent DB Connection</A>
  +		<LI><A HREF="performance.html#Benchmarking_scripts_with_execut">Benchmarking scripts with execution times below 1 second :)</A>
  +		<LI><A HREF="performance.html#PerlHandler_s_Benchmarking">PerlHandler's Benchmarking</A>
  +	</UL>
  +
  +	<LI><A HREF="performance.html#Tuning_the_Apache_s_configuratio">Tuning the Apache's configuration variables for the best performance</A>
  +	<UL>
  +
  +		<LI><A HREF="performance.html#Tuning_with_ab_ApacheBench">Tuning with ab - ApacheBench </A>
  +		<LI><A HREF="performance.html#Tuning_with_crashme_script">Tuning with crashme script</A>
  +		<LI><A HREF="performance.html#Choosing_MaxClients">Choosing MaxClients</A>
  +		<LI><A HREF="performance.html#Choosing_MaxRequestsPerChild">Choosing MaxRequestsPerChild</A>
  +		<LI><A HREF="performance.html#Choosing_MinSpareServers_MaxSpa">Choosing MinSpareServers, MaxSpareServers and StartServers</A>
  +		<LI><A HREF="performance.html#Summary_of_Benchmarking_to_tune_">Summary of Benchmarking to tune all 5 parameters</A>
  +	</UL>
  +
  +	<LI><A HREF="performance.html#Persistent_DB_Connections">Persistent DB Connections</A>
  +	<LI><A HREF="performance.html#Using_1_under_mod_perl_and_be">Using $|=1 under mod_perl and better print() techniques.</A>
  +	<LI><A HREF="performance.html#More_Reducing_Memory_Usage_Tips">More Reducing Memory Usage Tips</A>
  +	<LI><A HREF="performance.html#Profiling">Profiling</A>
  +	<LI><A HREF="performance.html#CGI_pm_s_object_methods_calls_vs">CGI.pm's object methods calls vs. function calls</A>
  +	<LI><A HREF="performance.html#Sending_plain_HTML_as_a_compress">Sending plain HTML as a compressed output</A>
  +</UL>
   <P><LI><A HREF="strategy.html"><B><FONT SIZE=+1>Choosing the Right Strategy</FONT></B></A></LI><P>
   <UL>
   
  @@ -66,13 +158,12 @@
   	<LI><A HREF="strategy.html#One_Plain_and_One_mod_perl_enabl">One Plain and One mod_perl-enabled Apache Servers</A>
   	<LI><A HREF="strategy.html#One_light_non_Apache_and_One_mod">One light non-Apache and One mod_perl enabled Apache Servers</A>
   	<LI><A HREF="strategy.html#Adding_a_Proxy_Server_in_http_Ac">Adding a Proxy Server in http Accelerator Mode</A>
  -	<LI><A HREF="strategy.html#squid_server">squid server</A>
  -	<LI><A HREF="strategy.html#apache_s_mod_proxy">apache's mod_proxy</A>
  +	<LI><A HREF="strategy.html#The_Squid_Server">The Squid Server</A>
  +	<LI><A HREF="strategy.html#An_Apache_s_mod_proxy">An Apache's mod_proxy</A>
   </UL>
  -<P><LI><A HREF="scenario.html"><B><FONT SIZE=+1>Real World Scenarios Implementaion</FONT></B></A></LI><P>
  +<P><LI><A HREF="scenario.html"><B><FONT SIZE=+1>Real World Scenarios Implementation</FONT></B></A></LI><P>
   <UL>
   
  -	<LI><A HREF="scenario.html#Before_you_dive_into_the_gory_de">Before you dive into the gory details</A>
   	<LI><A HREF="scenario.html#Standalone_mod_perl_Enabled_Apac">Standalone mod_perl Enabled Apache Server</A>
   	<UL>
   
  @@ -88,7 +179,7 @@
   		<UL>
   
   			<LI><A HREF="scenario.html#Building_the_httpd_docs_Server">Building the httpd_docs Server</A>
  -			<LI><A HREF="scenario.html#Building_the_httpd_perl_Server_">Building the httpd_perl Server (mod_perl):</A>
  +			<LI><A HREF="scenario.html#Building_the_httpd_perl_mod_per">Building the httpd_perl (mod_perl enabled) Server</A>
   		</UL>
   
   		<LI><A HREF="scenario.html#Configuration_of_the_servers">Configuration of the servers</A>
  @@ -112,12 +203,12 @@
   	<LI><A HREF="install.html#Configuration_and_Installation">Configuration and Installation</A>
   	<UL>
   
  -		<LI><A HREF="install.html#Perl">Perl</A>
  -		<LI><A HREF="install.html#Apache">Apache</A>
  -		<LI><A HREF="install.html#Mod_Perl">Mod_Perl</A>
  +		<LI><A HREF="install.html#perl">perl</A>
  +		<LI><A HREF="install.html#apache">apache</A>
  +		<LI><A HREF="install.html#mod_perl">mod_perl</A>
   	</UL>
   
  -	<LI><A HREF="install.html#How_can_I_tell_whether_mod_perl_">How can I tell whether mod_perl is really installed</A>
  +	<LI><A HREF="install.html#How_can_I_tell_whether_mod_perl_">How can I tell whether mod_perl is running</A>
   	<UL>
   
   		<LI><A HREF="install.html#Testing_by_checking_the_error_lo">Testing by checking the error_log file</A>
  @@ -149,13 +240,19 @@
   		<LI><A HREF="config.html#Location_Configuration">Location Configuration</A>
   		<LI><A HREF="config.html#PerlFreshRestart">PerlFreshRestart</A>
   		<LI><A HREF="config.html#_perl_status_location">/perl-status location</A>
  +		<UL>
  +
  +			<LI><A HREF="config.html#Configuration">Configuration</A>
  +			<LI><A HREF="config.html#Usage">Usage</A>
  +			<LI><A HREF="config.html#Compiled_Registry_Scripts_sectio">Compiled Registry Scripts section seems to be empty.</A>
  +		</UL>
  +
   		<LI><A HREF="config.html#PerlSetVar_PerlSetEnv_and_PerlP">PerlSetVar, PerlSetEnv and PerlPassEnv</A>
   		<LI><A HREF="config.html#perl_startup_file">perl-startup file</A>
   		<UL>
   
   			<LI><A HREF="config.html#Sample_perl_startup_file">Sample perl-startup file</A>
   			<LI><A HREF="config.html#What_modules_should_you_add_to_t">What modules should you add to the startup file and why.</A>
  -			<LI><A HREF="config.html#Is_it_possible_to_preopen_a_DB_c">Is it possible to preopen a DB connection at the server startup?</A>
   			<LI><A HREF="config.html#The_confusion_with_use_clause_">The confusion with use() clause at the server startup?</A>
   			<LI><A HREF="config.html#The_confusion_with_defining_glob">The confusion with defining globals in startup</A>
   		</UL>
  @@ -188,94 +285,20 @@
   	<LI><A HREF="frequent.html#Coverage">Coverage</A>
   	<LI><A HREF="frequent.html#my_scoped_variable_in_nested_s">my() scoped variable in nested subroutines</A>
   	<LI><A HREF="frequent.html#Segfaults_caused_by_PerlFreshRes">Segfaults caused by PerlFreshRestart</A>
  -</UL>
  -<P><LI><A HREF="porting.html"><B><FONT SIZE=+1>CGI to mod_perl Porting. mod_perl Coding guidelines.</FONT></B></A></LI><P>
  -<UL>
  -
  -	<LI><A HREF="porting.html#Document_Coverage">Document Coverage</A>
  -	<LI><A HREF="porting.html#Before_you_start_to_code">Before you start to code</A>
  -	<LI><A HREF="porting.html#Coding_with_mod_perl">Coding with mod_perl</A>
  -	<UL>
  -
  -		<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#_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>
  -		</UL>
  -
  -		<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#Global_Variables">Global Variables</A>
  -		<LI><A HREF="porting.html#Passing_ENV_variables_to_CGI">Passing ENV variables to CGI</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#Memory_leakage">Memory leakage</A>
  -	</UL>
  -
  -	<LI><A HREF="porting.html#Filehandlers_and_locks_leakages">Filehandlers and locks leakages</A>
  -	<LI><A HREF="porting.html#Sometimes_it_Works_Sometimes_it_">Sometimes it Works Sometimes it does Not (Very important!)</A>
  -	<LI><A HREF="porting.html#The_Script_is_too_dirty_It_does">The Script is too dirty, It does the job and I can't afford rewriting it.</A>
  -	<LI><A HREF="porting.html#Apache_PerlRun_a_closer_look">Apache::PerlRun - a closer look</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>
   </UL>
  -<P><LI><A HREF="performance.html"><B><FONT SIZE=+1>Performance. Benchmarks.</FONT></B></A></LI><P>
  +<P><LI><A HREF="control.html"><B><FONT SIZE=+1>Controlling and Monitoring the Server</FONT></B></A></LI><P>
   <UL>
  -
  -	<LI><A HREF="performance.html#Preload_Perl_modules_at_server_s">Preload Perl modules at server startup</A>
  -	<UL>
  -
  -		<LI><A HREF="performance.html#Preload_Perl_modules_Real_Numb">Preload Perl modules - Real Numbers</A>
  -	</UL>
  -
  -	<LI><A HREF="performance.html#Preload_Registry_Scripts">Preload Registry Scripts</A>
  -	<LI><A HREF="performance.html#Sharing_Memory">Sharing Memory</A>
  -	<LI><A HREF="performance.html#Avoid_Importing_Functions">Avoid Importing Functions</A>
  -	<LI><A HREF="performance.html#How_can_I_find_if_my_modperl_scr">How can I find if my modperl scripts have memory leaks (and where)</A>
  -	<LI><A HREF="performance.html#Limiting_the_size_of_the_process">Limiting the size of the processes</A>
  -	<LI><A HREF="performance.html#Limiting_the_resources_used_by_h">Limiting the resources used by httpd children</A>
  -	<LI><A HREF="performance.html#Limiting_the_request_rate_speed_">Limiting the request rate speed (robots blocking)</A>
  -	<LI><A HREF="performance.html#Benchmarks_Impressing_your_Boss">Benchmarks. Impressing your Boss and Colleagues.</A>
  -	<UL>
  -
  -		<LI><A HREF="performance.html#Developers_Talk">Developers Talk</A>
  -		<LI><A HREF="performance.html#Benchmarking_a_Graphic_hits_coun">Benchmarking a Graphic hits counter with Persistent DB Connection</A>
  -		<LI><A HREF="performance.html#Benchmarking_scripts_with_execut">Benchmarking scripts with execution times below 1 second :)</A>
  -		<LI><A HREF="performance.html#PerlHandler_s_Benchmarking">PerlHandler's Benchmarking</A>
  -	</UL>
  -
  -	<LI><A HREF="performance.html#Tuning_the_Apache_s_configuratio">Tuning the Apache's configuration variables for the best performance</A>
  -	<UL>
  -
  -		<LI><A HREF="performance.html#Tuning_with_ab_ApacheBench">Tuning with ab - ApacheBench </A>
  -		<LI><A HREF="performance.html#Tuning_with_crashme_script">Tuning with crashme script</A>
  -		<LI><A HREF="performance.html#Choosing_MaxClients">Choosing MaxClients</A>
  -		<LI><A HREF="performance.html#Choosing_MaxRequestsPerChild">Choosing MaxRequestsPerChild</A>
  -		<LI><A HREF="performance.html#Choosing_MinSpareServers_MaxSpa">Choosing MinSpareServers, MaxSpareServers and StartServers</A>
  -		<LI><A HREF="performance.html#Summary_of_Benchmarking_to_tune_">Summary of Benchmarking to tune all 5 parameters</A>
  -	</UL>
   
  -	<LI><A HREF="performance.html#Preopen_DB_connection_at_server_">Preopen DB connection at server startup:</A>
  -	<LI><A HREF="performance.html#Persistent_DB_Connections">Persistent DB Connections</A>
  -	<LI><A HREF="performance.html#Using_1_under_mod_perl_and_be">Using $|=1 under mod_perl and better print() techniques.</A>
  -	<LI><A HREF="performance.html#More_Reducing_Memory_Usage_Tips">More Reducing Memory Usage Tips</A>
  -	<LI><A HREF="performance.html#Profiling">Profiling</A>
  -	<LI><A HREF="performance.html#CGI_pm_s_object_methods_calls_vs">CGI.pm's object methods calls vs. function calls</A>
  -	<LI><A HREF="performance.html#Sending_plain_HTML_as_a_compress">Sending plain HTML as a compressed output</A>
  +	<LI><A HREF="control.html#Restarting_techniques">Restarting techniques</A>
  +	<LI><A HREF="control.html#Implications_of_sending_TERM_HU">Implications of sending TERM, HUP, and USR1 to the server</A>
  +	<LI><A HREF="control.html#Using_apachectl_to_control_the_s">Using apachectl to control the server</A>
  +	<LI><A HREF="control.html#SUID_start_up_scripts">SUID start-up scripts</A>
  +	<LI><A HREF="control.html#Monitoring_the_Server_A_watchdo">Monitoring the Server. A watchdog.</A>
  +	<LI><A HREF="control.html#Running_server_in_a_single_mode">Running server in a single mode</A>
  +	<LI><A HREF="control.html#Starting_a_personal_server_for_e">Starting a personal server for each developer</A>
  +	<LI><A HREF="control.html#Wrapper_to_emulate_the_server_en">Wrapper to emulate the server environment</A>
  +	<LI><A HREF="control.html#Log_Rotation">Log Rotation</A>
  +	<LI><A HREF="control.html#Preventing_from_modperl_process_">Preventing from modperl process from going wild</A>
   </UL>
   <P><LI><A HREF="obvious.html"><B><FONT SIZE=+1>Things obvious to others, but not to you</FONT></B></A></LI><P>
   <UL>
  @@ -290,14 +313,6 @@
   		<LI><A HREF="obvious.html#Additional_reading_references">Additional reading references</A>
   	</UL>
   
  -	<LI><A HREF="obvious.html#Reloading_Modules_and_Required_F">Reloading Modules and Required Files</A>
  -	<UL>
  -
  -		<LI><A HREF="obvious.html#Restarting_the_server">Restarting the server</A>
  -		<LI><A HREF="obvious.html#Using_Apache_StatINC">Using Apache::StatINC</A>
  -		<LI><A HREF="obvious.html#Reloading_only_specific_files">Reloading only specific files</A>
  -	</UL>
  -
   	<LI><A HREF="obvious.html#Compiled_Regular_Expressions">Compiled Regular Expressions </A>
   	<LI><A HREF="obvious.html#Debugging_your_code_in_Single_Se">Debugging your code in Single Server Mode</A>
   	<LI><A HREF="obvious.html#_M_and_other_time_file_tests_u">-M and other time() file tests under mod_perl</A>
  @@ -329,20 +344,6 @@
   	<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>
   </UL>
  -<P><LI><A HREF="control.html"><B><FONT SIZE=+1>Controlling and Monitoring the Server</FONT></B></A></LI><P>
  -<UL>
  -
  -	<LI><A HREF="control.html#Restarting_techniques">Restarting techniques</A>
  -	<LI><A HREF="control.html#Implications_of_sending_TERM_HU">Implications of sending TERM, HUP, and USR1 to the server</A>
  -	<LI><A HREF="control.html#Using_apachectl_to_control_the_s">Using apachectl to control the server</A>
  -	<LI><A HREF="control.html#SUID_start_up_scripts">SUID start-up scripts</A>
  -	<LI><A HREF="control.html#Monitoring_the_Server_A_watchdo">Monitoring the Server. A watchdog.</A>
  -	<LI><A HREF="control.html#Running_server_in_a_single_mode">Running server in a single mode</A>
  -	<LI><A HREF="control.html#Starting_a_personal_server_for_e">Starting a personal server for each developer</A>
  -	<LI><A HREF="control.html#Wrapper_to_emulate_the_server_en">Wrapper to emulate the server environment</A>
  -	<LI><A HREF="control.html#Log_Rotation">Log Rotation</A>
  -	<LI><A HREF="control.html#Preventing_from_modperl_process_">Preventing from modperl process from going wild</A>
  -</UL>
   <P><LI><A HREF="security.html"><B><FONT SIZE=+1>Protecting Your Site</FONT></B></A></LI><P>
   <UL>
   
  @@ -534,7 +535,10 @@
   
   <UL>
   
  -<LI><A HREF="all.html"><B>Guide All in One. Ready for Printing</B></A></LI>
  +<LI><A HREF="all.html"><B>Guide All in One. Ready for Printing</B></A>
  +(You better use the Postscript Book -- <A
  +HREF="mod_perl_guide.ps.gz">mod_perl_guide.ps.gz</A>)
  + </LI>
   
   <LI><A HREF="CHANGES"><B>CHANGES</B></A></LI>
   
  @@ -583,11 +587,20 @@
   <TD ALIGN=CENTER VALIGN=CENTER COLSPAN="3">
   <HR></TD>
   </TR>
  -
   <TR ALIGN=CENTER VALIGN=TOP>
  +<TD ALIGN=CENTER VALIGN=CENTER COLSPAN="3">
  +URL: <B>http://perl.apache.org/guide</B><BR>
  +Copyright &copy; 1998, 1999 Stas Bekman. All rights reserved.
  +</TD>
  +</TR>
  +<TR ALIGN=CENTER VALIGN=TOP>
  +<TD ALIGN=CENTER VALIGN=CENTER COLSPAN="3">
  +<HR></TD>
  +</TR>
   
  +<TR ALIGN=CENTER VALIGN=TOP>
   <TD ALIGN=CENTER VALIGN=CENTER><B><FONT SIZE=-1>Written by <A
  -HREF="help.html#This_document_s_Author">Stas Bekman</A>.<BR> Last Modified at 06/19/1999
  +HREF="help.html#This_document_s_Author">Stas Bekman</A>.<BR> Last Modified at 07/02/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>
  @@ -898,7 +911,7 @@
       <B>
         <FONT SIZE=-1>
   	     Written by <A HREF="help.html#This_document_s_Author">Stas Bekman</A>.
  -	     <BR>Last Modified at 06/19/1999
  +	     <BR>Last Modified at 06/26/1999
         </FONT>
       </B>
     </TD>
  @@ -946,7 +959,7 @@
   <A HREF="http://perl.apache.org"><IMG SRC="images/mod_perl.gif" ALT="Mod Perl Icon" BORDER=0 HEIGHT=30 WIDTH=90 ALIGN=RIGHT></A>
   Guide's Overview</H1>
   <HR WIDTH="100%">
  -	    [    <A HREF="intro.html">Prev</A> |      <A HREF="index.html">Main Page</A> | <A HREF="strategy.html">Next</A>      ]<HR><!-- INDEX BEGIN -->
  +	    [    <A HREF="intro.html">Prev</A> |      <A HREF="index.html">Main Page</A> | <A HREF="porting.html">Next</A>      ]<HR><!-- INDEX BEGIN -->
   <P><B><FONT SIZE=-1>Table of Contents:</FONT></B></P>
   <UL>
   
  @@ -1100,7 +1113,7 @@
   	     Amazon.com</a>.
   
   	     <HR>
  -	     [    <A HREF="intro.html">Prev</A> |      <A HREF="index.html">Main Page</A> | <A HREF="strategy.html">Next</A>      ]
  +	     [    <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%" >
   <TR ALIGN=CENTER VALIGN=TOP>
  @@ -1113,7 +1126,7 @@
       <B>
         <FONT SIZE=-1>
   	     Written by <A HREF="help.html#This_document_s_Author">Stas Bekman</A>.
  -	     <BR>Last Modified at 05/14/1999
  +	     <BR>Last Modified at 06/26/1999
         </FONT>
       </B>
     </TD>
  @@ -1140,7 +1153,7 @@
   <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
   <HTML>
   <HEAD>
  -   <TITLE>mod_perl guide: Choosing the Right Strategy</TITLE>
  +   <TITLE>mod_perl guide: CGI to mod_perl Porting. mod_perl Coding guidelines.</TITLE>
      <META NAME="GENERATOR" CONTENT="Pod2HTML [Perl/Linux]">
      <META NAME="Author" CONTENT="Stas Bekman">
      <META NAME="Description" CONTENT="All Apache/Perl related information: Hints, Guidelines, Scenarios and Troubleshottings">
  @@ -1159,20 +1172,56 @@
   <H1 ALIGN=CENTER>
   <A HREF="http://perl.apache.org"><IMG SRC="images/mod_perl.gif" ALT="Mod Perl Icon" BORDER=0 HEIGHT=30 WIDTH=90 ALIGN=LEFT></A>
   <A HREF="http://perl.apache.org"><IMG SRC="images/mod_perl.gif" ALT="Mod Perl Icon" BORDER=0 HEIGHT=30 WIDTH=90 ALIGN=RIGHT></A>
  -Choosing the Right Strategy</H1>
  +CGI to mod_perl Porting. mod_perl Coding guidelines.</H1>
   <HR WIDTH="100%">
  -	    [    <A HREF="start.html">Prev</A> |      <A HREF="index.html">Main Page</A> | <A HREF="scenario.html">Next</A>      ]<HR><!-- INDEX BEGIN -->
  +	    [    <A HREF="start.html">Prev</A> |      <A HREF="index.html">Main Page</A> | <A HREF="performance.html">Next</A>      ]<HR><!-- INDEX BEGIN -->
   <P><B><FONT SIZE=-1>Table of Contents:</FONT></B></P>
   <UL>
   
  -	<LI><A HREF="#Do_it_like_me_">Do it like me?!</A>
  -	<LI><A HREF="#mod_perl_Deployment_Overview">mod_perl Deployment Overview</A>
  -	<LI><A HREF="#Standalone_mod_perl_Enabled_Apac">Standalone mod_perl Enabled Apache Server</A>
  -	<LI><A HREF="#One_Plain_and_One_mod_perl_enabl">One Plain and One mod_perl-enabled Apache Servers</A>
  -	<LI><A HREF="#One_light_non_Apache_and_One_mod">One light non-Apache and One mod_perl enabled Apache Servers</A>
  -	<LI><A HREF="#Adding_a_Proxy_Server_in_http_Ac">Adding a Proxy Server in http Accelerator Mode</A>
  -	<LI><A HREF="#squid_server">squid server</A>
  -	<LI><A HREF="#apache_s_mod_proxy">apache's mod_proxy</A>
  +	<LI><A HREF="#Document_Coverage">Document Coverage</A>
  +	<LI><A HREF="#Before_you_start_to_code">Before you start to code</A>
  +	<LI><A HREF="#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="#_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="#Memory_leakage">Memory leakage</A>
  +	</UL>
  +
  +	<LI><A HREF="#Reloading_Modules_and_Required_F">Reloading Modules and Required Files</A>
  +	<UL>
  +
  +		<LI><A HREF="#Restarting_the_server">Restarting the server</A>
  +		<LI><A HREF="#Using_Apache_StatINC">Using Apache::StatINC</A>
  +		<LI><A HREF="#Reloading_only_specific_files">Reloading only specific files</A>
  +	</UL>
  +
  +	<LI><A HREF="#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="#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>
   </UL>
   <!-- INDEX END -->
   
  @@ -1190,1973 +1239,1988 @@
   
   	      <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>
  +<CENTER><H1><A NAME="Document_Coverage">Document Coverage</A></H1></CENTER>
   <P>
  -There is no such a thing as a single <STRONG>RIGHT</STRONG> strategy in web server business, though there are many wrong ones. Never
  -believe a person who says: <EM>"Do it this way, this is the best!"</EM>. As the old saying goes:
  -<EM>"Trust but verify"</EM>. There are too many technologies out there to choose from, and it would
  -take an enormous investment of time and money to try to validate each one
  -before deciding which is the best choice for your situation. Keeping this
  -idea in mind, I will present some different combinations of mod_perl and
  -other technologies or just standalone mod_perl. I'll describe how these
  -things work together, and offer my opinions on the pros and cons of each,
  -the relative degree of difficulty in installing and maintaining them, and
  -some hints on approaches that should be used and things to avoid.
  +This document is relevant to both writing a new CGI from scratch and
  +migrating an application from plain CGI to mod_perl.
   
   <P>
  -To be clear, I will not address all technologies and tools, but limit this
  -discussion to those complementing mod_perl.
  +If you are in the porting stage, use it as a reference for possible
  +problems you might encounter when running the existent CGI in the new mode.
   
   <P>
  -Please let me stress it again: <STRONG>DO NOT</STRONG> blindly copy someone's setup and hope for a good result. Choose what is
  -best for your situation -- it might take <STRONG>some</STRONG> effort to find out what this is.
  +If you are about to write a new CGI from scratch, it would be a good idea
  +to learn most of the possible pitfalls and to avoid them in first place.
   
   <P>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<CENTER><H1><A NAME="mod_perl_Deployment_Overview">mod_perl Deployment Overview</A></H1></CENTER>
  +It covers also the case where the CGI script being ported does the job, but
  +is too dirty to be easily altered to run as a mod_perl program. (<CODE>Apache::PerlRun</CODE>)
  +
   <P>
  -There are several different ways to build, configure and deploy your
  -mod_perl enabled server. Some of them are:
  +If your project schedule is tight, I would suggest converting to mod_perl
  +in the following steps: Initially, run all the scripts in the
  +<CODE>Apache::PerlRun</CODE> mode. Then as time allows, move them into
  +<CODE>Apache::Registry</CODE> mode.
   
  -<OL>
  -<P><LI>
   <P>
  -Having one binary and one config file (one big binary for mod_perl).
  +<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<CENTER><H1><A NAME="Before_you_start_to_code">Before you start to code</A></H1></CENTER>
  +<P>
  +It can be a good idea to tighten up some of your Perl programming
  +practices, since <CODE>Apache::Registry</CODE> doesn't allow sloppy programming.
   
  -<P><LI>
   <P>
  -Having two binaries and two config files (one big binary for mod_perl and
  -one small for static objects like images.)
  +You might want to read:
   
  -<P><LI>
  +<UL>
  +<P><LI><STRONG><A NAME="item_Perl">Perl Module Mechanics</A></STRONG>
   <P>
  -Having one DSO-style binary, mod_perl loadable object and two config files
  -(Dynamic linking lets you compile once and have a big and a small binary in
  -memory BUT you have to deal with a freshly made solution that has weak
  -documentation and is still subject to change and is rather more complex.)
  +This page describes the mechanics of creating, compiling, releasing, and
  +maintaining Perl modules. <A
  +HREF="http://world.std.com/~swmcd/steven/perl/module_mechanics.html">http://world.std.com/~swmcd/steven/perl/module_mechanics.html</A>
   
  -<P><LI>
  -<P>
  -Any of the above plus a reverse proxy server in http accelerator mode.
   
  -</OL>
  +<P><LI><STRONG><A NAME="item_Mod">Mod Perl Book</A></STRONG>
   <P>
  -If you are a newbie, I would recommend that you start with the first option
  -and work on getting your feet wet with apache and mod_perl. Later, you can
  -decide whether to move to the second one which allows better tuning at the
  -expense of more complicated administration, or to the third option -- the
  -more state-of-the-art-yet-suspiciously-new DSO system, or to the forth
  -option which gives you even more power.
  +A must have book! See the details at <A
  +HREF="http://www.modperl.com">http://www.modperl.com</A> .
   
  -<OL>
  -<P><LI>
  +</UL>
   <P>
  -The first option will kill your production site if you serve a lot of
  -static data with ~2-12 MB webserver processes. On the other hand, while
  -testing you will have no other server interaction to mask or add to your
  -errors.
  -
  -<P><LI>
  +<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<CENTER><H1><A NAME="Exposing_Apache_Registry_secret">Exposing Apache::Registry secrets</A></H1></CENTER>
   <P>
  -The second option allows you to seriously tune the two servers for maximum
  -performance. On the other hand you have to deal with proxying or fancy site
  -design to keep the two servers in sync. In this configuration, you also
  -need to choose between running the two servers on multiple ports, multiple
  -IPs, etc... This adds the burden of administrating more than one server.
  +Let's start with some simple code and see what can go wrong with it ,detect
  +bugs and debug them, discuss possible caveats and how to avoid them.
   
  -<P><LI>
   <P>
  -The third option (DSO) -- as mentioned above -- means playing with the
  -bleeding edge. In addition <CODE>mod_so</CODE> (the DSO module) adds size and complexity to your binaries. With DSO,
  -modules can be added and removed without recompiling the server, and
  -modules are even shared among multiple servers. Again, it is bleeding edge
  -and still somewhat platform specific, but your milegue may vary. See <A HREF="././scenario.html#mod_perl_server_as_DSO">mod_perl server as DSO</A>.
  +I will use a simple CGI script, that initializes a <CODE>$counter</CODE> to 0, and prints its value to the screen while incrementing it.
   
  -<P><LI>
   <P>
  -The fourth option (proxy in http accelerator mode), once correctly
  -configured and tuned, improves performance by caching and buffering page
  -results.
  -
  -</OL>
  +<PRE>  counter.pl:
  +  ----------
  +  #!/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();
  +  }
  +  
  +  sub increment_counter{
  +    $counter++;
  +    print &quot;Counter is equal to $counter !&lt;BR&gt;\n&quot;;
  +  }
  +  ----------
  +</PRE>
   <P>
  -The rest of this chapter discusses the pros and the cons of each of these
  -presented configurations.  <A HREF="././scenario.html#">Real World Scenarios Implementaion</A> describes the implementation techniques of these schemas.
  +You would expect to see an output:
   
  -<P>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<CENTER><H1><A NAME="Standalone_mod_perl_Enabled_Apac">Standalone mod_perl Enabled Apache Server</A></H1></CENTER>
   <P>
  -The first approach is to implement a straightforward mod_perl server. Just
  -take your plain apache server and add mod_perl, like you add any other
  -apache module. You continue to run it at the port it was running before.
  -You probably want to try this before you proceed to more sophisticated and
  -complex techniques.
  -
  +<PRE>  Counter is equal to 1 !
  +  Counter is equal to 2 !
  +  Counter is equal to 3 !
  +  Counter is equal to 4 !
  +  Counter is equal to 5 !
  +</PRE>
   <P>
  -The Advantages:
  +And that's what you see when you execute this script at first time. But
  +let's reload it a few times... See, suddenly after a few reloads the
  +counter doesn't start its count from 5 anymore. We continue to reload and
  +see that it keeps on growing, but not steadily 10, 10, 10, 15, 20...
  +Weird...
   
  -<UL>
  -<P><LI>
   <P>
  -Simplicity. You just follow the installation instructions, configure it,
  -restart the server and you are done.
  -
  -<P><LI>
  +<PRE>  Counter is equal to 6 !
  +  Counter is equal to 7 !
  +  Counter is equal to 8 !
  +  Counter is equal to 9 !
  +  Counter is equal to 10 !
  +</PRE>
   <P>
  -No network changes. You do not have to worry about using additional ports
  -as we will see later.
  +We saw two anomalies in this very simple script: Unexpected growth of
  +counter over 5 and inconsistent growth over reloads. Let's investigate this
  +script.
   
  -<P><LI>
   <P>
  -Speed. You get a very fast server, you see an enormous speedup from the
  -first moment you start to use it.
  +First let's peek into an <CODE>error_log</CODE> file... what we see is:
   
  -</UL>
   <P>
  -The Disadvantages:
  -
  -<UL>
  -<P><LI>
  +<PRE>  Variable &quot;$counter&quot; will not stay shared 
  +  at /home/httpd/perl/conference/counter.pl line 13.
  +</PRE>
   <P>
  -The process size of a mod_perl-enabled Apache server is huge (starting from
  -4Mb at startup and growing to 10Mb and more, depending on how you use it)
  -compared to the typical plain Apache
  +What kind of error is this? We should ask perl to help us. I'm going to
  +enable a special diagnostics mode, by adding at the top of the script:
   
   <P>
  -You probably have a few tens of children processes. The additional memory
  -requirements add up in direct relation to the number of children processes.
  -Your memory demands are growing by an order of magnitude, but this is the
  -price you pay for the additional performance boost of mod_perl. With memory
  -prices so cheap nowadays, the additional cost is low -- especially when you
  -consider the dramatic performance boost mod_perl gives to your services
  -with every 100Mb of RAM you add.
  -
  +<PRE>  use diagnostics;
  +</PRE>
   <P>
  -While you will be happy to have these monster processes serving your
  -scripts with monster speed, you should be very worried about having them
  -serve static objects such as images and html files. Each static request
  -served by a mod_perl-enabled server means another large process running,
  -competing for system resources such as memory and CPU cycles. The real
  -overhead depends on static objects request rate. Remember that if your
  -mod_perl code produces HTML code which includes images, each one will turn
  -into another static object request. Having another plain webserver to serve
  -the static objects solves this not pleasant obstacle. Having a proxy server
  -as a front end, caching the static objects and freeing the mod_perl
  -processes from this burden is another solution. We will discuss both below.
  +Reloading again, <CODE>error_log</CODE> shows:
   
  -<P><LI>
   <P>
  -Another drawback of this approach is that when serving output to a client
  -with a slow connection, the huge mod_perl-enabled server process (with all
  -of its system resources) will be tied up until the response is completely
  -written to the client. While it might take a few milliseconds for your
  -script to complete the request, there is a chance it will be still busy for
  -some number of seconds or even minutes if the request is from a slow
  -connection client. As in the previous drawback, a proxy solution can solve
  -this problem. More on proxies later.
  +<PRE>    Variable &quot;$counter&quot; will not stay shared at
  +        /home/httpd/perl/conference/counter.pl line 15 (#1)
  +    
  +    (W) An inner (nested) named subroutine is referencing a lexical
  +    variable defined in an outer subroutine.
  +    
  +    When the inner subroutine is called, it will probably see the value of
  +    the outer subroutine's variable as it was before and during the
  +    *first* call to the outer subroutine; in this case, after the first
  +    call to the outer subroutine is complete, the inner and outer
  +    subroutines will no longer share a common value for the variable.  In
  +    other words, the variable will no longer be shared.
  +    
  +    Furthermore, if the outer subroutine is anonymous and references a
  +    lexical variable outside itself, then the outer and inner subroutines
  +    will never share the given variable.
  +    
  +    This problem can usually be solved by making the inner subroutine
  +    anonymous, using the sub {} syntax.  When inner anonymous subs that
  +    reference variables in outer subroutines are called or referenced,
  +    they are automatically rebound to the current values of such
  +    variables.
  +</PRE>
  +<P>
  +Actually perl detected a <STRONG>closure</STRONG>, which is sometimes a wanted effect, but not in our case (see <CODE>perldoc perlsub</CODE> for more information about closures). While <CODE>diagnostics.pm</CODE> sometimes is handy for debugging purpose - it drastically slows down your
  +CGI script. Make sure you remove it in your production server.
  +
  +<P>
  +Do you see a <STRONG>nested named subroutine</STRONG> in my script? I do not!!! What is going on? I suggest to report a bug. But
  +wait, may be a perl interpreter sees the script in a different way, may be
  +the code goes through some changes before it actually gets executed? The
  +easiest way to check what's actually happening is to run the script with
  +debugger, but since we must debug it when it's being executed by the
  +server, normal debugging process wouldn't help, for we have to invoke the
  +debugger from within the webserver. Luckily Doug wrote an
  +<CODE>Apache::DB</CODE> module and we will use it to debug my script. I'll do it non-interactively
  +(while you can debug interactively with
  +<CODE>Apache::DB</CODE>). I change my <CODE>http.conf</CODE> with:
   
   <P>
  -Proxying dynamic content is not going to help much if all the clients are
  -on a fast local net (for example, if you are administering an Intranet.) On
  -the contrary, it can decrease performance. Still, remember that some of
  -your Intranet users might work from home through the slow modem links.
  -
  -</UL>
  +<PRE>  PerlSetEnv PERLDB_OPTS &quot;NonStop=1 LineInfo=/tmp/db.out AutoTrace=1 frame=2&quot;
  +  PerlModule Apache::DB
  +  &lt;Location /perl&gt;
  +    PerlFixupHandler Apache::DB
  +    SetHandler perl-script
  +    PerlHandler Apache::Registry::handler
  +    Options ExecCGI
  +    PerlSendHeader On
  +  &lt;/Location&gt;
  +</PRE>
   <P>
  -If you are new to mod_perl, this is probably the best way to get yourself
  -started.
  +Comment out '<CODE>use diagnostics;</CODE>', restart the server and call the
  +<CODE>counter.pl</CODE> from your browser. On the surface nothing changed - we still see the
  +correct output as before, but two things happened at the background: first
  +-- the <CODE>/tmp/db.out</CODE> was written, with a complete trace of the code that was executed, second -- <CODE>error_log</CODE> file showed us the whole code that was executed as a side effect of
  +reporting the warning we saw before: <CODE>Variable &quot;$counter&quot; will not
  +stay shared at (eval 52) line 15...</CODE>. In any case that's the code that actually is being executed:
   
   <P>
  -And of course, if your site is serving only mod_perl scripts (close to zero
  -static objects, like images), this might be the perfect choice for you!
  -
  +<PRE>  package Apache::ROOT::perl::conference::counter_2epl;
  +  use Apache qw(exit);
  +  sub handler {
  +    BEGIN {
  +      $^W = 1;
  +    };
  +    $^W = 1;
  +    
  +    use strict;
  +    
  +    print &quot;Content-type: text/html\\r\\n\\r\\n&quot;;
  +    
  +    my $counter = 0;
  +    
  +    for (1..5) {
  +      increment_counter();
  +    }
  +    
  +    sub increment_counter{
  +      $counter++;
  +      print &quot;Counter is equal to $counter !&lt;BR&gt;\\n&quot;;
  +    }
  +    
  +  }
  +</PRE>
   <P>
  -For implementation notes see : <A HREF="././scenario.html#One_Plain_and_One_mod_perl_enabl">One Plain and One mod_perl enabled Apache Servers</A>
  -
  +What do we learn from this discovering? First that every cgi script is
  +being cached under a package whose name is compounded from
  +<CODE>Apache::ROOT::</CODE> prefix and the relative part of the script's URL (<CODE>perl::conference::counter_2epl</CODE>) by replacing all occurrences of
  +<CODE>/</CODE> with <CODE>::</CODE>. That's how mod_perl knows what script should be fetched from cache - each
  +script is just a package with a single subroutine named <CODE>handler</CODE>. Now you understand why <CODE>diagnostics</CODE>
  +pragma talked about inner (nested) subroutine - <CODE>increment_counter</CODE>
  +is actually a nested sub. In every script each subroutine is nested inside
  +the <CODE>handler</CODE> subroutine.
   
  -
  -<P>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<CENTER><H1><A NAME="One_Plain_and_One_mod_perl_enabl">One Plain and One mod_perl-enabled Apache Servers</A></H1></CENTER>
   <P>
  -As I have mentioned before, when running scripts under mod_perl, you will
  -notice that the httpd processes consume a huge amount of memory, from 5M to
  -25M, or even more. That is the price you pay for the enormous speed
  -improvements under mod_perl.
  +The workaround is to use global declared variables, with <CODE>vars</CODE>
  +pragma.
   
   <P>
  -Using these large processes to serve static objects like images and html
  -documents is overkill. A better approach is to run two servers: a very
  -light, plain apache server to serve static objects and a heavier
  -mod_perl-enabled apache server to serve requests for dynamic (generated)
  -objects (aka CGI).
  -
  +<PRE>  # !/usr/bin/perl -w
  +  use strict;
  +  use vars qw($counter);
  +  
  +  print &quot;Content-type: text/html\r\n\r\n&quot;;
  +  
  +  $counter = 0;
  +  
  +  for (1..5) {
  +    increment_counter();
  +  }
  +  
  +  sub increment_counter{
  +    $counter++;
  +    print &quot;Counter is equal to $counter !&lt;BR&gt;\n&quot;;
  +  }
  +</PRE>
   <P>
  -From here on, I will refer to these two servers as <STRONG>httpd_docs</STRONG>
  -(vanilla apache) and <STRONG>httpd_perl</STRONG> (mod_perl enabled apache).
  +There is no more <CODE>closure</CODE> effect, since there is no <CODE>my()</CODE>
  +(lexically) defined variable being used in the nested subroutine.
   
   <P>
  -The Advantages:
  +Another approach is to use fully qualified variables, which is even better,
  +since less memory will be used, but it adds an overhead of extra typing:
   
  -<UL>
  -<P><LI>
   <P>
  -The heavy mod_perl processes serve only dynamic requests, which allows the
  -deployment of fewer of these large servers. When user browses static pages,
  -all relative URLs (e.g. <CODE>/main/download.html</CODE>) are being served by the light plain apache server. But this is not the
  -case with dynamically generated pages, all relative URLs in the dynamically
  -generated HTML will be served by the mod_perl process. You must use a fully
  -qualified URLs and not the relative ones!
  -<CODE>http://www.nowhere.com/icons/arrow.gif</CODE> is a full URL while
  -<CODE>/icons/arrow.gif</CODE> is a relative one). When you generate a HTML page which has relative
  -references to images or other static objects - the user's browser sets its
  -base url to point to that of the
  -<CODE>httpd_perl</CODE> server. Because of this, all static requests will be sent to the heavy <CODE>httpd_perl</CODE>. Beware! You can solve this by either generating full URLs to the <CODE>httpd_docs</CODE> server (the fastest) or by rewriting the requests back to <CODE>httpd_docs</CODE> inside the <CODE>httpd_perl</CODE>
  -<CODE>server(much</CODE> slower). This is not a problem if you hide the
  -internal implementations, so client sees only one server running on port
  -<CODE>80</CODE>. (<A HREF="././config.html#Publishing_port_numbers_differen">Publishing port numbers different from 80</A>)
  -
  -<P><LI>
  +<PRE>  #!/usr/bin/perl -w
  +  use strict;
  +  
  +  print &quot;Content-type: text/html\r\n\r\n&quot;;
  +  
  +  $main::counter = 0;
  +  
  +  for (1..5) {
  +    increment_counter();
  +  }
  +  
  +  sub increment_counter{
  +    $main::counter++;
  +    print &quot;Counter is equal to $main::counter !&lt;BR&gt;\n&quot;;
  +  }
  +</PRE>
   <P>
  -<CODE>MaxClients</CODE>, <CODE>MaxRequestsPerChild</CODE> and related parameters can now be optimally tuned for both <CODE>httpd_docs</CODE> and <CODE>httpd_perl</CODE> servers, something we could not do before. This allows us to fine tune the
  -memory usage and get better server performance.
  +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.
   
   <P>
  -Now we can run many lightweight <CODE>httpd_docs</CODE> servers and just a few heavy <CODE>httpd_perl</CODE> servers.
  +A workaround is to run the server in a single server mode. You achieve this
  +by invoking the server with <CODE>-X</CODE> parameter (<CODE>httpd -X</CODE>). Since there is no other servers (children) running - you will detect the
  +problem on the second reload. But before that let the <CODE>error_log</CODE> to help you detect most of the possible errors - most of the warnings can
  +become errors, so you better make sure to check every warning that is being
  +detected by perl, and probably to write the code in a way, that none of the
  +warnings will show up in the <CODE>error_log</CODE>. If your
  +<CODE>error_log</CODE> file is being filled up with hundreds of lines on every script invocation -
  +you will have a problem to locate and notice real problems.
   
  -</UL>
   <P>
  -The Disadvantages:
  +Of course none of the warnings will be reported if the warning mechanism
  +will not be turned ON. With mod_perl it is also possible to turn on
  +warnings globally via the PerlWarn directive, just add into a
  +<CODE>httpd.conf</CODE>:
   
  -<UL>
  -<P><LI>
   <P>
  -An administration overhead.
  -
  -<UL>
  -<P><LI>
  +<PRE>    PerlWarn On
  +</PRE>
   <P>
  -A need for two different configuration files, two log files sets, etc. We
  -need a special directory layout to manage these. While some directories can
  -be shared between the two servers (like the <CODE>include</CODE>
  -directory, storing the apache include files), most of them should be
  -separated and the configuration files updated to reflect the changes. (Of
  -course, this assumes that both are built from the same source
  -distribution.)
  +You can turn it off within your code with <CODE>local $^W=0</CODE>. on the local basis (or inside the block). If you write <CODE>$^W=0</CODE> you disable the warning mode everywhere inside the child, <CODE>$^W=1</CODE> enables it back. So if perl warns you somewhere you sure it's not a
  +problem, you can locally disable the warning, e.g.:
   
  -<P><LI>
   <P>
  -A need for two sets of controlling scripts (startup/shutdown)
  -
  -<P><LI>
  +<PRE>  [snip]
  +    # we want perl to be quiet here - 
  +    # we don't care whether $a was initialized
  +  local $^W = 0;
  +    print $a;
  +  local $^W = 1;
  +  [snip]
  +</PRE>
   <P>
  -If you are processing log files, now you probably will have to merge the
  -two separate log files into one before processing them.
  +Of course this is not a way to fix initialization and other problems, but
  +sometimes it helps.
   
  -</UL>
  -<P><LI>
   <P>
  -We still have the problem of a mod_perl process spending its precious time
  -serving slow clients, when the processing portion of the request was
  -completed long time ago, exactly as in the one server approach. Deploying a
  -proxy solves this, and will be covered in the next sections.
  +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
  +production serves has the following directive in the <CODE>httpd.conf</CODE>:
   
   <P>
  -As with only one server approach, this is not a major disadvantage if you
  -are on a fast local Intranet. It is likely that you do not want a buffering
  -server in this case.
  -
  -</UL>
  +<PRE>    PerlWarn Off
  +</PRE>
   <P>
  -Before you go on with this solution you really want to look at the
  -<A HREF="././strategy.html#Adding_a_Proxy_Server_in_http_Ac">Adding a Proxy Server in http Accelerator Mode</A> section.
  +While we are talking about control flags, another even more important flag
  +is <CODE>-T</CODE> which turns <STRONG>On</STRONG> the <STRONG>Taint</STRONG> mode <STRONG>On</STRONG>. Since this is very broad topic I'll not discuss it here, but if you
  +aren't forcing all of your scripts to run under <STRONG>Taint</STRONG> mode you are looking for a trouble (always remember about malicious users).
  +To turn it on, add to
  +<CODE>httpd.conf</CODE>:
   
   <P>
  -For implementation notes see : <A HREF="././scenario.html#One_Plain_and_One_mod_perl_enabl">One Plain and One mod_perl enabled Apache Servers</A>
  -
  -
  -
  +<PRE>  PerlTaintCheck On
  +</PRE>
   <P>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<CENTER><H1><A NAME="One_light_non_Apache_and_One_mod">One light non-Apache and One mod_perl enabled Apache Servers</A></H1></CENTER>
  -<P>
  -If the only requirement from the light server is for it to serve static
  -objects, then you can get away with non-apache servers having an even
  -smaller memory footprint. <CODE>thttpd</CODE> has been reported to be about 5 times faster then apache (especially under
  -a heavy load), since it is very simple and uses almost no memory (260k) and
  -does not spawn child processes.
  -
  -<P>
  -Meta: Hey No personal experience. Please let me know if I have missed some
  -pros/cons here. Thanks!
  -
  +<CENTER><H1><A NAME="Sometimes_it_Works_Sometimes_it_">Sometimes it Works Sometimes it Does Not</A></H1></CENTER>
   <P>
  -The Advantages:
  +When you start running your scripts under mod_perl, you might find yourself
  +in situation where a script seems to work, but sometimes it screws up. And
  +the more it runs without a restart, the more it screws up. Many times you
  +can resolve this problem very easily. You have to test your script under a
  +server running in a single process mode (<CODE>httpd -X</CODE>).
   
  -<UL>
  -<P><LI>
   <P>
  -All the advantages of the 2 servers scenario.
  +Generally the problem you have is of using global variables. Since global
  +variables don't change from one script invocation to another unless you
  +change them, you can find your scripts do ``fancy'' things.
   
  -<P><LI>
   <P>
  -More memory saving. Apache is about 4 times bigger then <STRONG>thttpd</STRONG>, if you spawn 30 children you use about 30M of memory, while <STRONG>thttpd</STRONG>
  -uses only 260k - 100 times less! You could use the saved 30M to run more
  -mod_perl servers.
  +The first example is amazing -- Web Services. Imagine that you enter some
  +site you have your account on (Free Email Account?). Now you want to see
  +what other users read.
   
   <P>
  -Note that this is not true if your OS supports memory sharing and you
  -configured apache to use it (it is a DSO approach. There is no memory
  -sharing if apache modules are being statically compiled into httpd). If you
  -do allow memory sharing -- 30 light apache servers ought to use about 3-4Mb
  -only, because most of it will be shared. Than the save-ups with <STRONG>thttpd</STRONG> are much smaller.
  +You type in your name and passwd, and you expect to enter to your account,
  +but instead you enter the account of someone else. This is cool isn't it?
  +Is it a bug or feature. (For some of us it's a feature, while for others
  +it's a bug.) You say, why in the world does this happen? The answer is
  +simple: Global Variables. You have entered the account of someone who
  +happened to be served by the same server child as you. Because of sloppy
  +programming, a global variable was not reset at the beginning of the
  +program and voila, you can easily peek into other people's emails! You
  +would think that it can't happen, since you have entered the login and
  +passwd. I tell you, it happens! See for yourself:
   
  -<P><LI>
   <P>
  -Reported to be about 5 times faster then plain apache serving static
  -objects.
  -
  -</UL>
  +<PRE>  use vars ($authenticated);
  +  my $q = new CGI;
  +  my $username = $q-&gt;param('username');
  +  my $passwd   = $q-&gt;param('passwd');
  +  authenticate($username,$passwd);
  +    # failed, break out
  +  die &quot;Wrong passwd&quot; unless $authenticated == 1;
  +    # user is OK, fetch user's data
  +  show_user($username);
  +  
  +  sub authenticate{
  +    my ($username,$passwd) = @_;
  +        # some checking
  +    $authenticated = 1 if (SOMETHING);
  +  }
  +</PRE>
   <P>
  -The Disadvantages:
  +Do you see the catch? With the code above, I can type in any valid username
  +and any dummy passwd and enter that user's account, if someone has
  +successfully entered his account before me using the same child process!
  +Since <STRONG>$authenticated</STRONG> is global - if it becomes 1 once it'll be 1 for the remainder of the
  +child's life!!! The solution is trivial -- reset <STRONG>$authenticated</STRONG> to 0 at the beginning of the program. (Or many other different solutions).
  +Of course this example is trivial -- but believe me it happens!
   
  -<UL>
  -<P><LI>
   <P>
  -Lacks some of apache's features, like access control, error redirection,
  -customizable logfile formats, and so on.
  +Just another little one liner that can spoil your day, assuming you forgot
  +to reset the <STRONG>$allowed</STRONG> variable. It works perfectly OK in plain mod_cgi:
   
  -</UL>
   <P>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<CENTER><H1><A NAME="Adding_a_Proxy_Server_in_http_Ac">Adding a Proxy Server in http Accelerator Mode</A></H1></CENTER>
  +<PRE>  $allowed = 1 if $username eq 'admin';
  +</PRE>
   <P>
  -At the beginning there were 2 servers: one - plain apache server, which was
  -_very_ light, and configured to serve static objects, the other - mod_perl
  -enabled, which was _very_ heavy and aimed to serve mod_perl scripts. We
  -named them: <CODE>httpd_docs</CODE> and <CODE>httpd_perl</CODE>
  -appropriately. The two servers coexisted at the same <CODE>IP(DNS)</CODE>
  -by listening to different ports: 80 - for httpd_docs (e.g. <A
  -HREF="http://www.nowhere.com/images/test.gif">http://www.nowhere.com/images/test.gif</A>
  -) and 8080 for httpd_perl (e.g. <A
  -HREF="http://www.nowhere.com:8080/perl/test.pl">http://www.nowhere.com:8080/perl/test.pl</A>
  -). Note that I did not write <A
  -HREF="http://www.nowhere.com:80">http://www.nowhere.com:80</A> for the
  -first example, since port 80 is a default http port. (Note that later on, I
  -will be moving the httpd_docs server to port 81.)
  +But you will let any user to admin your system with the line above (again
  +assuming you have used the same child prior to some user request).
   
   <P>
  -Now I am going to convince you that you _want_ to use a proxy server (in
  -the http accelerator mode). The advantages are:
  +Another good example is usage of the <STRONG>/o</STRONG> regular expression qualifier, which compiles a regular expression once, on
  +its first execution and never recompile it again. This problem can be
  +difficult to detect, as after restarting the server each request you make
  +will be served by a different child process, and thus the regex pattern for
  +that child will be compiled fresh. Only when you make a request that
  +happens to be served by a child which has already cached the regexp will
  +you see the problem. Generally you miss that and when you press reload, you
  +see that it works (with a new, fresh child) and then it doesn't (with a
  +child that already cached the regexp and wouldn't recompile because of <STRONG>/o</STRONG>.) The example of such a case would be:
   
  -<UL>
  -<P><LI>
   <P>
  -Allow serving of static objects from the proxy's cache (objects that
  -previously were entirely served by the httpd_docs server).
  +<PRE>  my $pat = '^foo$'; # likely to be input from an HTML form field
  +  foreach( @list ) {
  +    print if /$pat/o;
  +  }
  +</PRE>
  +<P>
  +To make sure you don't miss these bugs always test your CGI in
  +<A HREF="././control.html#Running_server_in_a_single_mode">single process</A>. To solve this particular <STRONG>/o</STRONG> problem refer to <A HREF="././obvious.html#Compiled_Regular_Expressions">Compiled Regular Expressions</A>.
   
  -<P><LI>
  +<P>
  +<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<CENTER><H1><A NAME="What_s_different_about_modperl">What's different about modperl</A></H1></CENTER>
   <P>
  -You get less I/O activity reading objects from the disk (proxy serves the
  -most ``popular'' objects from the RAM memory - of course you benefit more
  -if you allow the proxy server to consume more RAM). Since you do not wait
  -for the I/O to be completed you serve the static objects faster.
  +There are a few things that behave differently under mod_perl. It's good to
  +know what they are.
   
  -<P><LI>
   <P>
  -The proxy server acts as a sort of output buffer for the dynamic content.
  -The mod_perl server sends the entire response to the proxy and is then free
  -to deal with other requests. The proxy server is responsible for sending
  -the response to the browser. So if the transfer is over a slow link, the
  -mod_perl server is not waiting around for the data to move.
  +<P><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>
  +<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
  +<STRONG>Apache::ROOT::perl::test_2epl</STRONG>.
   
   <P>
  -Using numbers is always more convincing :) Let's take a user connected to
  -your site with 28.8 kbps (bps == bits/sec) modem. It means that the speed
  -of the user's link is 28.8/8 = 3.6 kbytes/sec. I assume an average
  -generated HTML page to be of 10kb (kb == kilobytes) and an average script
  -that generates this output in 0.5 secs. How much time will the server wait
  -before the user gets the whole output response? A simple calculation
  -reveals pretty scary numbers - it will have to wait for another 6 secs
  -(20kb/3.6kb), when it could serve another 12 (6/0.5) dynamic requests in
  -this time. This very simple example shows us that we need a twelve the
  -number of children running, which means you will need only one twelve of
  -the memory (which is not quite true because some parts of the code are
  -being shared). But you know that nowadays scripts return pages which
  -sometimes are being blown up with javascript code and similar, which makes
  -them of 100kb size and download time to be of... (This calculation was left
  -to the reader as an exercise :)
  +<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>
  +<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>. The values are the real paths to these modules. So if you do:
   
   <P>
  -To make your download time numbers even worse, let me remind you that many
  -users like to open many browser windows and do many things at once
  -(download files and visit _heavy_ sites). So the speed of 3.6kb/sec we were
  -assuming before, may many times be 5-10 times slower.
  +<PRE>  use lib qw(.);
  +  require &quot;./my/lib.pl&quot;;
  +</PRE>
  +<P>
  +where <CODE>./my/lib.pl</CODE> is actually a <CODE>/home/httpd/perl/my/lib.pl</CODE>. The following entry will show up in the <CODE>%INC</CODE>:
   
  -<P><LI>
   <P>
  -Also we are going to hide the details of the server's implementation. Users
  -will never see ports in the URLs (more on that topic later). And you can
  -have a few boxes serving the requests, and only one serving as a front end,
  -which spreads the jobs between the servers in a way you configured it too.
  -So you can actually put down one server down for upgrade, but end user will
  -never notice that because the front end server will dispatch the jobs to
  -other servers. (Of course this is pretty big topic, and it would not be
  -included in the scope of this document)
  +<PRE>  print $INC{&quot;./my/lib.pl&quot;};
  +   
  +  printed result:
  +  ---------------
  +  /home/httpd/perl/my/lib.pl
  +</PRE>
  +<P>
  +I'm talking about single server child below!
   
  -<P><LI>
   <P>
  -For security reasons, using any httpd accelerator (or a proxy in httpd
  -accelerator mode) is essential because you do not let your internal server
  -get directly attacked by arbitrary packets from whomever. The httpd
  -accelerator and internal server communicate in expected HTTP requests. This
  -allows for only your public ``bastion'' accelerating www server to get
  -hosed in a successful attack, while leaving your internal data safe.
  +Let's look at 3 faulty scenarios:
   
  -<P><LI>
  +<DL>
  +<P><DT><STRONG><A NAME="item_Scenario">Scenario 1</A></STRONG><DD>
   <P>
  -You can have the <CODE>mod_proxy</CODE> process serve your static documents from disk to ``kill two birds with one
  -stone''.
  +First, You can't have 2 identical module names running under the same
  +server! Only the first one <CODE>use()'d</CODE> or <CODE>require()'d</CODE>
  +will be compiled into the package, the request to the other identical
  +module will be skipped since server will think that it's already compiled.
  +It'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)
   
  -</UL>
   <P>
  -The disadvantages are:
  +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>, locate like:
   
  -<UL>
  -<P><LI>
   <P>
  -Of course there are drawbacks. Luckily, these are not functionality
  -drawbacks, but more of administration hassle. You add another program to
  -worry about, and while proxies are generally stable, you have to make sure
  -to prepare proper startup and shutdown scripts, which are being run at the
  -boot and reboot appropriately. Also, maybe a watchdog script running at the
  -crontab.
  +<PRE>  ./cgi/tool1/Foo.pm
  +  ./cgi/tool1/tool1.pl
  +  ./cgi/tool2/Foo.pm
  +  ./cgi/tool2/tool2.pl
  +</PRE>
  +<P>
  +Where a sample code could be:
   
  -<P><LI>
   <P>
  -Proxy servers can be configured to be light or heavy, the admin must decide
  -what gives the highest performance for his application. A proxy server like
  -squid is light in the concept of having only one process serving all
  -requests. But it can appear pretty heavy when it loads objects into memory
  -for faster service.
  +<PRE>  ./cgi/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>  ./cgi/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>  ./cgi/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>  ./cgi/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 Foo, when you will call the
  +second script it will not know about Foo at all - it's like you've
  +forgotten to write <CODE>use Foo;</CODE>. Run the server in <A HREF="././control.html#Running_server_in_a_single_mode">single server mode</A> to detect that kind of bug immediately.
   
  -</UL>
   <P>
  -Have I succeeded in convincing you that you want the proxy server?
  +You will see the following in the error_log file:
   
   <P>
  -If you are on a local area network, then the big benefit of the proxy
  -buffering the output and feeding a slow client is gone. You are probably
  -better off sticking with a straight mod_perl server in this case.
  +<PRE>  Undefined subroutine
  +  &amp;Apache::ROOT::perl::tool2_2epl::some_function called at
  +  /home/httpd/perl/tool2.pl line 4.
  +</PRE>
  +<P><DT><STRONG>Scenario 2</STRONG><DD>
  +<P>
  +The above is true for the files you <CODE>require()</CODE> as well (assuming that the required files do not declare a package). If you
  +have:
   
   <P>
  -As of this writing the two proxy implementations are known to be used in
  -bundle with mod_perl - <STRONG>squid</STRONG> proxy server and <STRONG>mod_proxy</STRONG> which is a part of the apache server. Let's compare the two of them.
  +<PRE>  ./cgi/tool1/config.pl
  +  ./cgi/tool1/tool1.pl
  +  ./cgi/tool2/config.pl
  +  ./cgi/tool2/tool2.pl
  +</PRE>
  +<P>
  +And both scripts do:
   
   <P>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<CENTER><H1><A NAME="squid_server">squid server</A></H1></CENTER>
  +<PRE>  use lib qw(.);
  +  require &quot;config.pl&quot;;
  +</PRE>
   <P>
  -The Advantages:
  +While the content of the scripts and <CODE>config.pl</CODE> files is exactly like in the example above. Only the first one will
  +actually do the
  +<CODE>require()</CODE>, all for the same reason that <CODE>%INC</CODE> already includes the key <STRONG>"config.pl"</STRONG>! The second scenario is not different from the first one, since there is
  +no difference between <CODE>use()</CODE> and
  +<CODE>require()</CODE> if you don't have to import some symbols into a calling script.
   
  -<UL>
  -<P><LI>
  +<P><DT><STRONG>Scenario 3</STRONG><DD>
   <P>
  -Caching of static objects. So these are being served much faster assuming
  -that your cache size is big enough to keep the most requested objects in
  -the cache.
  +What's interesting that the following scenario wouldn't work too!
   
  -<P><LI>
   <P>
  -Buffering of dynamic content, by taking the burden of returning the content
  -generated by mod_perl servers to slow clients, thus freeing mod_perl
  -servers from waiting for the slow clients to download the data. Freed
  -servers immediately switch to serve other requests, thus your number of
  -required servers goes dramatically down.
  +<PRE>  ./cgi/tool/config.pl
  +  ./cgi/tool/tool1.pl
  +  ./cgi/tool/tool2.pl
  +</PRE>
  +<P>
  +where <CODE>tool1.pl</CODE> and <CODE>tool2.pl</CODE> both <CODE>require()</CODE> the <STRONG>same</STRONG>
   
  -<P><LI>
  +<CODE>config.pl</CODE>.
  +
  +</DL>
   <P>
  -Non-linear URL space / server setup. You can use Squid to play some tricks
  -with the URL space and/or domain based virtual server support.
  +There are 3 solutions for that: (make sure you read the whole item 3)
   
  -</UL>
  +<DL>
  +<P><DT><STRONG><A NAME="item_Solution">Solution 1</A></STRONG><DD>
   <P>
  -The Disadvantages:
  +The first two faulty scenarios can be solved by placing your library
  +modules in a subdirectory structure so that they have different path
  +prefixes. The file system layout will be something like:
   
  -<UL>
  -<P><LI>
   <P>
  -Proxying dynamic content is not going to help much if all the clients are
  -on a fast local net. Also, a message on the squid mailing list implied that
  -squid only buffers in 16k chunks so it would not allow a mod_perl to
  -complete immediately if the output is larger.
  +<PRE>  ./cgi/tool1/Tool1/Foo.pm
  +  ./cgi/tool1/tool1.pl
  +  ./cgi/tool2/Tool2/Foo.pm
  +  ./cgi/tool2/tool2.pl
  +</PRE>
  +<P>
  +And change the scripts:
   
  -<P><LI>
   <P>
  -Speed. Squid is not very fast today when compared to plain file based web
  -servers available. Only if you are using a lot of dynamic features such as
  -mod_perl or similar speed is a reason to use Squid, and then only if the
  -application and server is designed with caching in mind.
  +<PRE>  use Tool1::Foo;
  +  use Tool2::Foo;
  +</PRE>
  +<P>
  +For <CODE>require()</CODE> (scenario number 2) use the following:
   
  -<P><LI>
   <P>
  -Memory usage. Squid uses quite a bit of memory.
  +<PRE>  ./cgi/tool1/tool1-lib/config.pl
  +  ./cgi/tool1/tool1.pl
  +  ./cgi/tool2/tool2-lib/config.pl
  +  ./cgi/tool2/tool2.pl
  +</PRE>
  +<P>
  +And each script does respectively:
   
  -<P><LI>
   <P>
  -HTTP protocol level. Squid is pretty much a HTTP/1.0 server, which
  -seriously limits the deployment of HTTP/1.1 features.
  +<PRE>  use lib qw(.);
  +  require &quot;tool1-lib/config.pl&quot;;
  +</PRE>
  +<P>
  +<PRE>  use lib qw(.);
  +  require &quot;tool2-lib/config.pl&quot;;
  + 
  +But this solution is very bad, since while it might work for you now,
  +if you add another script that wants to use the same module or
  +C&lt;config.pl&gt; file, it still wouldn't work as we saw in the third
  +scenario. So let see better solutions.
  +</PRE>
  +<P><DT><STRONG>Solution 2</STRONG><DD>
  +<P>
  +Another option is to use a full path to the script, so it'll be compiled
  +into the name of the key in the <CODE>%INC</CODE>;
   
  -<P><LI>
  +<P>
  +<PRE>  require &quot;/full/path/to/the/config.pl&quot;;
  +</PRE>
   <P>
  -HTTP headers / dates, freshness. Your server will be giving out ``old''
  -pages, which might confuse downstream/client caches. Also chances are that
  -you will be giving out stale pages.
  +This solution solves the first two scenarios. I was surprised but it worked
  +for the third scenario as well!
   
  -<P><LI>
   <P>
  -Stability. Compared to plain web servers Squid is not the most stable.
  +But with this solution you loose portability! (If you move the tool around
  +in the file system you will have to change the base dir)
   
  -</UL>
  +<P><DT><STRONG>Solution 3</STRONG><DD>
   <P>
  -The presented pros and cons lead to an idea, that probably you might want
  -squid more for its dynamic content buffering features, but only if your
  -server serves mostly dynamic requests. So in this situation it is better to
  -have a plain apache server serving static objects, and squid proxying the
  -mod_perl enabled server only. At least when performance is the goal.
  +Declare a package in the required files! (Of course it should be unique to
  +the rest of the package names you use!) The <CODE>%INC</CODE> will use the package name for the key! It's a good idea to build at least 2
  +level package names for your private modules. (e.g. <CODE>MyProject::Carp</CODE>
  +and not <CODE>Carp</CODE> for it will collide with existent standard package - even if as of the time
  +of your coding it doesn't exist yet - it might enter the next perl
  +distribution as a standard module and your code will become broken. Foresee
  +problems like this and save you a future trouble.)
   
   <P>
  -For implementation details see: <A HREF="././scenario.html#Running_1_webserver_and_squid_in">Running 1 webserver and squid in httpd accelerator mode</A> and
  -<A HREF="././scenario.html#Running_2_webservers_and_squid_i">Running 2 webservers and squid in httpd accelerator mode</A>
  +When you <CODE>use()d</CODE> or <CODE>require()d</CODE> files without package declarations, it was very convenient since all the
  +variables and subroutines were part of the <CODE>main::</CODE> package, so any of them could be used as if they were part of the main
  +script. With package declarations things get more complicated. To be
  +correct -- not complicated, but awkward, since you will have to use
  +<CODE>Package::function()</CODE> method to call a subroutine from a package
  +<CODE>Package</CODE> and to access a global variable inside the same package you will have to
  +write <CODE>$Package::some_variable</CODE>, you get a kind of typing overhead. You will be unable to access lexically
  +defined variables inside <CODE>Package</CODE> (declared with <CODE>my()</CODE>).
   
  +<P>
  +You can make things simpler by exporting the symbols from the
  +<CODE>use()'d</CODE> package, like:
   
  +<P>
  +<PRE>  use Package qw(:mysubs sub_b $var1 :myvars);
  +</PRE>
  +<P>
  +You can export both -- subroutines and global variables. This is a bad
  +approach since it'll consume more memory for the current process. (See
  +<CODE>perldoc Exporter</CODE> for information about exporting variables)
   
   <P>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<CENTER><H1><A NAME="apache_s_mod_proxy">apache's mod_proxy</A></H1></CENTER>
  +This solution completely covers the third scenario. By using different
  +module names in package declarations, as explained above you solve the
  +first two as well.
  +
  +</DL>
   <P>
  -I do not think the difference in speed between apache's <CODE>ProxyPass</CODE>
  -and squid is relevant for most sites, since the real value of what they do
  -is buffering for slow client connections. However squid runs as a single
  -process and probably consumes fewer system resources. The trade-off is that
  -mod_rewrite is easy to use if you want to spread parts of the site across
  -different back end servers, and mod_proxy knows how to fix up redirects
  -containing the back-end server's idea of the location. With squid you can
  -run a redirector process to proxy to more than one back end, but there is a
  -problem in fixing redirects in a way that keeps the client's view of both
  -server names and port numbers in all cases. The difficult case being where
  -you have DNS aliases that map to the same IP address for an alias and you
  -want the redirect to use port 80 (when the server is really on a different
  -port) but you want it to keep the specific name the browser sent so it does
  -not change in the client's 'location' window.
  +Read also perlmodlib and perlmod manpages.
   
   <P>
  -The Advantages:
  +From the above discussion it should be clear that you cannot run a
  +development and a production versions of the tools on the same server! You
  +have to run a separate server for each (it still can be the same machine,
  +but the server will use a different port).
   
  -<UL>
  -<P><LI>
   <P>
  -No additional server is needed. We keep the 1 plain plus 1 mod_perl enabled
  -apache servers. All you need is to enable the <CODE>mod_proxy</CODE> in
  -<CODE>httpd_docs</CODE> and add a few lines to <CODE>httpd.conf</CODE> file.
  -
  -<P><LI>
  +<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>
   <P>
  -<CODE>ProxyPass</CODE> and <CODE>ProxyPassReverse</CODE> directives allow you to hide the internal redirects, so if <CODE>http://nowhere.com/modperl/</CODE> is actually
  -<CODE>http://localhost:81/modperl/</CODE>, it will be absolutely transparent for user. <CODE>ProxyPass</CODE> redirects the request to the mod_perl server, and when it gets the respond, <CODE>ProxyPassReverse</CODE> rewrites the URL back to the original one, e.g:
  +<CODE>Apache::Registry</CODE> scripts cannot contain __END__ or __DATA__ tokens.
   
   <P>
  -<PRE>  ProxyPass        /modperl/ <A HREF="http://localhost:81/modperl/">http://localhost:81/modperl/</A>
  -  ProxyPassReverse /modperl/ <A HREF="http://localhost:81/modperl/">http://localhost:81/modperl/</A>
  -</PRE>
  -<P><LI>
  +<P><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>
   <P>
  -It does mod_perl output buffering like squid does. See the <A HREF="././scenario.html#Using_mod_proxy">Using mod_proxy</A> notes for more details.
  +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><LI>
   <P>
  -It even does caching. You have to produce correct <CODE>Content-Length</CODE>,
  -<CODE>Last-Modified</CODE> and <CODE>Expires</CODE> http headers for it to work. If some dynamic content is not to change
  -constantly, you can dramatically increase performance by caching it with
  -ProxyPass.
  -
  -<P><LI>
  +<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>
   <P>
  -<CODE>ProxyPass</CODE> happens before the authentication phase, so you do not have to worry about
  -authenticating twice.
  +Currently possible only if you have perl compiled with <CODE>sfio</CODE>.
   
  -<P><LI>
   <P>
  -Apache is able to accel https requests completely, while also doing http
  -accel. (with squid you have to use an external redirection program for
  -that).
  -
  -<P><LI>
  +<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>
   <P>
  -The latest (from apache 1.3.6) Apache proxy accel mode reported to be very
  -stable.
  +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
  +irrelevant.) The <STRONG>Apache::exit()</STRONG> function should be used instead. 
   
  -</UL>
   <P>
  -The Disadvantages:
  +You might start your scripts by overriding the exit sub (if you use
  +<STRONG>Apache::exit()</STRONG> directly, you will have a problem testing the script from the shell, unless
  +you stuff <CODE>use Apache ();</CODE> into your code.) I use the following code:
   
  -<UL>
  -<P><LI>
  -</UL>
   <P>
  -For implementation see <A HREF="././scenario.html#Using_mod_proxy">Using mod_proxy</A>.
  -
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -	     The <a href="http://www.modperl.com/">
  -	     <B>Writing Apache Modules with Perl and C</B></a>
  -	     book can be purchased online from <a
  -	     href="http://www.ora.com/catalog/wrapmod/">O'Reilly </a>
  -	     and <a
  -	     href="http://www.amazon.com/exec/obidos/ASIN/156592567X/writinapachemodu">
  -	     Amazon.com</a>.
  -
  -	     <HR>
  -	     [    <A HREF="start.html">Prev</A> |      <A HREF="index.html">Main Page</A> | <A HREF="scenario.html">Next</A>      ]
  -
  -<CENTER><TABLE CELLSPACING=2 CELLPADDING=2 WIDTH="100%" >
  -<TR ALIGN=CENTER VALIGN=TOP>
  -  <TD ALIGN=CENTER VALIGN=CENTER COLSPAN="3">
  -	     <HR>
  -  </TD>
  -</TR>
  -<TR ALIGN=CENTER VALIGN=TOP>
  -  <TD ALIGN=CENTER VALIGN=CENTER>
  -    <B>
  -      <FONT SIZE=-1>
  -	     Written by <A HREF="help.html#This_document_s_Author">Stas Bekman</A>.
  -	     <BR>Last Modified at 06/19/1999
  -      </FONT>
  -    </B>
  -  </TD>
  -
  -  <TD>
  -	     <A HREF="http://perl.apache.org"><IMG SRC="images/mod_perl2.jpg" ALT="Mod Perl Icon" BORDER=0 HEIGHT=59 WIDTH=150></A>
  -  </TD>
  -
  -  <TD>
  -    <FONT SIZE=-2>
  -	     Use of the Camel for Perl is <BR>
  -	     a trademark of <A HREF="http://www.ora.com">O'Reilly &amp; Associates</A>,<BR>
  -             and is used by permission. 
  -    </FONT> 
  -  </TD>
  -</TR>
  -</TABLE></CENTER>
  -
  -</BODY>
  -</HTML>
  -	    
  -
  -<HR SIZE=6>
  -<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
  -<HTML>
  -<HEAD>
  -   <TITLE>mod_perl guide: Real World Scenarios Implementaion</TITLE>
  -   <META NAME="GENERATOR" CONTENT="Pod2HTML [Perl/Linux]">
  -   <META NAME="Author" CONTENT="Stas Bekman">
  -   <META NAME="Description" CONTENT="All Apache/Perl related information: Hints, Guidelines, Scenarios and Troubleshottings">
  -   <META NAME="keywords" CONTENT="mod_perl modperl perl apache cgi webserver speed  fast guide mod_perl apache guide help info faq mod_perl installation cgi troubleshooting help no sex speedup free open source OSS mod_perl apache guide">
  -</HEAD>
  -     <LINK REL=STYLESHEET TYPE="text/css"
  -        HREF="style.css" TITLE="refstyle">
  -     <style type="text/css">
  -     <!-- 
  -        @import url(style.css);
  -     -->
  -     
  -     </style>
  -<BODY TEXT="#000000" BGCOLOR="#E0FFFF" LINK="#0000EE" VLINK="#551A8B" ALINK="#FF0000">
  -<A NAME="toc"></A>
  -<H1 ALIGN=CENTER>
  -<A HREF="http://perl.apache.org"><IMG SRC="images/mod_perl.gif" ALT="Mod Perl Icon" BORDER=0 HEIGHT=30 WIDTH=90 ALIGN=LEFT></A>
  -<A HREF="http://perl.apache.org"><IMG SRC="images/mod_perl.gif" ALT="Mod Perl Icon" BORDER=0 HEIGHT=30 WIDTH=90 ALIGN=RIGHT></A>
  -Real World Scenarios Implementaion</H1>
  -<HR WIDTH="100%">
  -	    [    <A HREF="strategy.html">Prev</A> |      <A HREF="index.html">Main Page</A> | <A HREF="install.html">Next</A>      ]<HR><!-- INDEX BEGIN -->
  -<P><B><FONT SIZE=-1>Table of Contents:</FONT></B></P>
  -<UL>
  -
  -	<LI><A HREF="#Before_you_dive_into_the_gory_de">Before you dive into the gory details</A>
  -	<LI><A HREF="#Standalone_mod_perl_Enabled_Apac">Standalone mod_perl Enabled Apache Server</A>
  -	<UL>
  -
  -		<LI><A HREF="#Installation_in_10_lines">Installation in 10 lines</A>
  -		<LI><A HREF="#Installation_in_10_paragraphs">Installation in 10 paragraphs</A>
  -		<LI><A HREF="#Configuration_Process">Configuration Process</A>
  -	</UL>
  -
  -	<LI><A HREF="#One_Plain_and_One_mod_perl_enabl">One Plain and One mod_perl enabled Apache Servers</A>
  -	<UL>
  -
  -		<LI><A HREF="#Configuration_and_Compilation_of">Configuration and Compilation of the Sources.</A>
  -		<UL>
  -
  -			<LI><A HREF="#Building_the_httpd_docs_Server">Building the httpd_docs Server</A>
  -			<LI><A HREF="#Building_the_httpd_perl_Server_">Building the httpd_perl Server (mod_perl):</A>
  -		</UL>
  -
  -		<LI><A HREF="#Configuration_of_the_servers">Configuration of the servers</A>
  -		<UL>
  -
  -			<LI><A HREF="#Basic_httpd_docs_Server_s_Config">Basic httpd_docs Server's Configuration</A>
  -			<LI><A HREF="#Basic_httpd_perl_Server_s_Config">Basic httpd_perl Server's Configuration</A>
  -		</UL>
  -
  -	</UL>
  -
  -	<LI><A HREF="#Running_2_webservers_and_squid_i">Running 2 webservers and squid in httpd accelerator mode</A>
  -	<LI><A HREF="#Running_1_webserver_and_squid_in">Running 1 webserver and squid in httpd accelerator mode</A>
  -	<LI><A HREF="#Using_mod_proxy">Using mod_proxy</A>
  -	<LI><A HREF="#mod_perl_server_as_DSO">mod_perl server as DSO</A>
  -	<LI><A HREF="#HTTP_Authentication_with_2_serve">HTTP Authentication with 2 servers + proxy</A>
  -</UL>
  -<!-- INDEX END -->
  +<PRE>  BEGIN {
  +      # Auto-detect if we are running under mod_perl or CGI.
  +    $USE_MOD_PERL = ( (exists $ENV{'GATEWAY_INTERFACE'}
  +                   and $ENV{'GATEWAY_INTERFACE'} =~ /CGI-Perl/)
  +                      or exists $ENV{'MOD_PERL'} ) ? 1 : 0;
  +  }
  +  use subs (exit);
  +  
  +  # Select the correct exit way
  +  ########
  +  sub exit{
  +      # Apache::exit(-2) will cause the server to exit gracefully,
  +      # once logging happens and protocol, etc  (-2 == Apache::Constants::DONE)
  +    $USE_MOD_PERL ? Apache::exit(0) : CORE::exit(0);
  +  }
  +</PRE>
  +<P>
  +Now each time the select code is called, the correct <CODE>exit()</CODE> will be chosen, whether you run the script as a CGI or from the shell.
   
  -<HR>
  +<P>
  +<STRONG>Note</STRONG> that if you run the script under <CODE>Apache::Registry</CODE>, <STRONG>The
  +Apache function <CODE>exit()</CODE> overrides the Perl core built-in
  +function</STRONG>. While you see the <CODE>exit()</CODE> listed in <CODE>@EXPORT_OK</CODE> of Apache package, <CODE>Apache::Registry</CODE> makes something you don't see and imports this function for you. This means
  +that if your script is running under <CODE>Apache::Registry</CODE> handler (<CODE>Apache::PerlRun</CODE> as well), you don't have to worry about <CODE>exit().</CODE>
   
  -	     The <a href="http://www.modperl.com/">
  -	     <B>Writing Apache Modules with Perl and C</B></a>
  -	     book can be purchased online from <a
  -	     href="http://www.ora.com/catalog/wrapmod/">O'Reilly </a>
  -	     and <a
  -	     href="http://www.amazon.com/exec/obidos/ASIN/156592567X/writinapachemodu">
  -	     Amazon.com</a>.
  +<P>
  +<STRONG>Note</STRONG> that if you still use <CODE>CORE::exit()</CODE> in your scripts running under modperl, the child will exit, but neither
  +proper exit nor logging will happen on the way. <CODE>CORE::exit()</CODE> cuts off the server's legs... If you need to properly shutdown the child ,
  +use
  +<CODE>$r-&amp;gt;child_terminate</CODE> (which sets the internal
  +<CODE>MaxRequestsPerChild</CODE> so the child will exit).
   
  -	     <HR>
  +<P>
  +You can accomplish this in two ways - in the <CODE>Apache::Registry</CODE> script:
   
  -	      <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
   <P>
  -<CENTER><H1><A NAME="Before_you_dive_into_the_gory_de">Before you dive into the gory details</A></H1></CENTER>
  +<PRE>  Apache-&gt;request-&gt;child_terminate;
  +</PRE>
   <P>
  -There are many implementation schemes, each one has its benefits and
  -drawbacks. Please take your time to read the <A HREF="././strategy.html#">Picking the Right Strategy</A> chapter before you proceed. This section
  -<EM>merely</EM> details the implementation, installation and configuration. It hardly
  -mentions the pros and cons of each scheme detailed here.
  +in httpd.conf:
   
   <P>
  -This section describes a real world scenarios ready for almost blindly copy
  -and paste, you may think of it as a kick start. You will probably will want
  -to change the directories and some parameters like your hostname, but
  -basically you can use it as it is.
  -
  +<PRE>  PerlFixupHandler &quot;sub { shift-&gt;child_terminate }&quot;
  +</PRE>
   <P>
  -<STRONG>Important:</STRONG> Since both apache and mod_perl tend to release new versions so often (which
  -is good :), I will be not able to update the version numbers I present
  -here. So make sure to work with the latest version, even if you see me
  -using some older one. I prefer to use the real version number instead of <CODE>x.xx.xx</CODE>.
  +<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 CGI::Switch or CGI.pm and
  +5.004+ and do not make any direct calls to Apache-&gt;methods.
   
   <P>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<CENTER><H1><A NAME="Standalone_mod_perl_Enabled_Apac">Standalone mod_perl Enabled Apache Server</A></H1></CENTER>
  +<CENTER><H2><A NAME="I_O_is_different">I/O is different</A></H2></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 CGI.pm, use $query-&gt;print instead of plain 'ol <CODE>print().</CODE>
  +
   <P>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<CENTER><H2><A NAME="Installation_in_10_lines">Installation in 10 lines</A></H2></CENTER>
  +<CENTER><H2><A NAME="HTTP_MIME_Headers_PerlSendHea">HTTP + MIME Headers (PerlSendHeader)</A></H2></CENTER>
   <P>
  -The Installation is very very simple (example from Linux OS):
  +By default, mod_perl does not send any headers by itself, however, you may
  +wish to change this (in httpd.conf):
   
   <P>
  -<PRE>  % cd /usr/src
  -  % lwp-download <A HREF="http://www.apache.org/dist/apache_x.x.x.tar.gz">http://www.apache.org/dist/apache_x.x.x.tar.gz</A>
  -  % lwp-download <A HREF="http://perl.apache.org/dist/mod_perl-x.xx.tar.gz">http://perl.apache.org/dist/mod_perl-x.xx.tar.gz</A>
  -  % tar zvxf apache_x.xx.tar.gz
  -  % tar zvxf mod_perl-x.xx.tar.gz
  -  % cd mod_perl-x.xx
  -  % perl Makefile.PL APACHE_SRC=../apache_x.x.x/src \
  -    USE_APACI=1 DO_HTTPD=1 PERL_MARK_WHERE=1 ALL_HOOKS=1 
  -  % make &amp;&amp; make test &amp;&amp; make install
  -  % cd ../apache_x.x.x/src
  -  % make install
  +<PRE>  PerlSendHeader On
   </PRE>
   <P>
  -That's all!
  +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 a terminating newline, your script must send that itself,
  +e.g.:
   
   <P>
  -Notes: Replace x.x.x with the real version numbers of mod_perl and apache.
  -gnu tar uncompresses as well (with z flag).
  +<PRE>  print &quot;Content-type: text/html\r\n\r\n&quot;;
  +</PRE>
  +<P>
  +If you are using CGI.pm or CGI::Switch and <STRONG>print $q-&gt;header</STRONG> you do _not_ need <CODE>PerlSendHeader</CODE> On.
   
   <P>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<CENTER><H2><A NAME="Installation_in_10_paragraphs">Installation in 10 paragraphs</A></H2></CENTER>
  +<CENTER><H2><A NAME="NPH_Non_Parsed_Headers_scripts">NPH (Non Parsed Headers) scripts</A></H2></CENTER>
   <P>
  -First download the sources of both packages, e.g. you can use
  -<CODE>lwp-download</CODE> utility to do it. <CODE>lwp-download</CODE> is a part of the LWP (or libwww) package, you will need to have it
  -installed in order for mod_perl's <CODE>make test</CODE> to pass. Once you install this package unless it's already installed, <CODE>lwp-download</CODE> will be available for you as well.
  +To run a Non Parsed Header CGI script under mod_perl, simply add to your
  +code:
   
   <P>
  -<PRE>  % lwp-download <A HREF="http://www.apache.org/dist/apache_x.x.x.tar.gz">http://www.apache.org/dist/apache_x.x.x.tar.gz</A>
  -  % lwp-download <A HREF="http://perl.apache.org/dist/mod_perl-x.xx.tar.gz">http://perl.apache.org/dist/mod_perl-x.xx.tar.gz</A>
  +<PRE>  local $| = 1;
   </PRE>
   <P>
  -Extract both sources. Generally I open all the sources in
  -<CODE>/usr/src/</CODE>, your mileage may vary. So move the sources and cd to the directory you
  -want to put the sources in. Gnu <CODE>tar</CODE> utility knows to uncompress too with z flag, if you have a non-gnu <CODE>tar</CODE> utility, it will be incapable to decompress, so you would do it in 2 steps,
  -first uncompressing the packages with <CODE>gzip -d apache_x.xx.tar.gz</CODE> and
  -<CODE>gzip -d mod_perl-x.xx.tar.gz</CODE>. And untarring them with <CODE>tar xvf
  -apache_x.xx.tar</CODE> and <CODE>tar xvf mod_perl-x.xx.tar</CODE>.
  +And if you normally set <CODE>PerlSendHeader On</CODE>, add this to your
  +<CODE>httpd.conf</CODE>:
   
   <P>
  -<PRE>  % cd /usr/src
  -  % tar zvxf apache_x.xx.tar.gz
  -  % tar zvxf mod_perl-x.xx.tar.gz
  +<PRE>  &lt;Files */nph-*&gt;
  +    PerlSendHeader Off
  +  &lt;/Files&gt;
   </PRE>
  +<P>
  +<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<CENTER><H2><A NAME="BEGIN_blocks">BEGIN blocks</A></H2></CENTER>
   <P>
  -Change to the mod_perl source directory.
  +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
  +and modules once -- either in the parent server or once per-child -- <CODE>BEGIN</CODE> blocks in that code will only be run once. As <CODE>perlmod manpage</CODE> explains, once a <CODE>BEGIN</CODE> has run, it is immediately undefined. In the mod_perl environment, this
  +means <CODE>BEGIN</CODE> blocks will not be run during each incoming request unless that request
  +happens to be one that is compiling the code.
   
   <P>
  -<PRE>  % cd mod_perl-x.xx
  -</PRE>
  +<CODE>BEGIN</CODE> blocks in modules and files pulled in via <CODE>require()</CODE> and/or
  +<CODE>use()</CODE> will be executed:
  +
  +<UL>
  +<P><LI>
   <P>
  -Now build the make file, for a basic work and first time installation the
  -parameters in the example below are the only ones you would need. <CODE>APACHE_SRC</CODE> tells where the apache &lt;src&gt; directory is. If you have followed my
  -advice and extracted the sources under the same directory (e.g.
  -&lt;/usr/src&gt;), the following is correct.
  +Only once, if pulled in by the parent process.
   
  +<P><LI>
   <P>
  -<PRE>  % perl Makefile.PL APACHE_SRC=../apache_x.x.x/src \
  -    USE_APACI=1 DO_HTTPD=1 PERL_MARK_WHERE=1 ALL_HOOKS=1 
  -</PRE>
  +Once per-child process if not pulled in by the parent process.
  +
  +<P><LI>
   <P>
  -There are many additional parameters. You can find some of them in the
  -configuration dedicated chapter and other sections where any of them
  -becomes relevant. While running <CODE>perl Makefile.PL ...</CODE> the process will check for prerequisites and tell you if something is
  -missing, If you are missing some of the perl packages or other software you
  -will have to install these before you proceed.
  +An additional time, once per-child process if the module is pulled in off a
  +disk again via <CODE>Apache::StatINC</CODE>.
   
  +<P><LI>
   <P>
  -Now we <STRONG>make</STRONG> the project (by building the mod_perl extension and calling <CODE>make</CODE> in apache source directory to build a <CODE>httpd</CODE>),
  -<STRONG>make test</STRONG> it (by running various tests) and install the mod_perl modules.
  +An additional time, in the parent process on each restart if
  +<CODE>PerlFreshRestart</CODE> is <CODE>On</CODE>.
   
  +<P><LI>
   <P>
  -<PRE>  % make &amp;&amp; make test &amp;&amp; make install
  -</PRE>
  -<P>
  -Note that if <CODE>make</CODE> fails, non of the <CODE>make test</CODE> and <CODE>make
  -install</CODE> will be not executed. If <CODE>make test</CODE> fails, <CODE>make install</CODE>
  -will be not executed.
  +Unpredictable if you fiddle with <CODE>%INC</CODE> yourself.
   
  +</UL>
   <P>
  -Now change to apache source directory and run <CODE>make install</CODE> to install apache's headers, default configuration files, build apache
  -directory tree and put the <CODE>httpd</CODE> there.
  +<CODE>BEGIN</CODE> blocks in <CODE>Apache::Registry</CODE> scripts will be executed:
   
  +<UL>
  +<P><LI>
   <P>
  -<PRE>  % cd ../apache_x.x.x/src
  -  % make install
  -</PRE>
  +Only once, if pulled in by the parent process via
  +<CODE>Apache::RegistryLoader</CODE> - once per-child process if not pulled in by the parent process.
  +
  +<P><LI>
   <P>
  -When you execute the above command, apache installation process will tell
  -you how can you start the webserver (the path of the &lt;apachectl&gt;,
  -more about it later) and where the configuration files are. Remember (or
  -even better write down) both for you will need this information very soon.
  -On my machine they 2 important paths are:
  +An additional time, once per-child process if the script file has changed
  +on disk.
   
  +<P><LI>
   <P>
  -<PRE>  /usr/local/apache/bin/apachectl
  -  /usr/local/apache/conf/httpd.conf
  -</PRE>
  +An additional time, in the parent process on each restart if pulled in by
  +the parent process via <CODE>Apache::RegistryLoader</CODE> and
  +<CODE>PerlFreshRestart</CODE> is <CODE>On</CODE>.
  +
  +</UL>
   <P>
  -Now the build and the installation processes are completed. Just configure <CODE>httpd.conf</CODE> and start the webserver.
  +Make sure you read <A HREF="././warnings.html#Evil_things_might_happen_when_us">Evil things might happen when using PerlFreshRestart</A>.
   
   <P>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<CENTER><H2><A NAME="Configuration_Process">Configuration Process</A></H2></CENTER>
  +<CENTER><H2><A NAME="END_blocks">END blocks</A></H2></CENTER>
   <P>
  -A basic configuration is a simple one. First configure the apache as you
  -always do (like setting a correct <CODE>Port</CODE>, <CODE>User</CODE>, <CODE>Group</CODE>, log-file and other file paths and etc), start the server and make sure it
  -works. One of the ways to start and stop the server is to use
  -<CODE>apachectl</CODE> utility:
  +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
  +server is shutdown. However, mod_perl does make a special case for
  +<CODE>Apache::Registry</CODE> scripts.
   
   <P>
  -<PRE>  /usr/local/apache/bin/apachectl start
  -  /usr/local/apache/bin/apachectl stop
  -</PRE>
  +Normally, <CODE>END</CODE> blocks are executed by Perl during its <STRONG>perl_run()</STRONG>
  +function, which is called once each time the Perl program is executed, e.g.
  +once per (mod_cgi) CGI scripts. However, mod_perl only calls
  +<STRONG>perl_run()</STRONG> once, during server startup. Any <CODE>END</CODE> blocks encountered during main server startup, i.e. those pulled in by the
  +<CODE>PerlRequire</CODE> or by any <CODE>PerlModule</CODE>, are suspended and run at server shutdown, aka child_exit (requires apache
  +1.3b3+).
  +
   <P>
  -Put the server down, open the <CODE>httpd.conf</CODE> in your favorite editor and scroll to the end of the file, where we will
  -add the mod_perl configuration directives (of course you can place them
  -anywhere in the file).
  +Any <CODE>END</CODE> blocks that are encountered during compilation of
  +<CODE>Apache::Registry</CODE> scripts <STRONG>are called after the script has
  +completed</STRONG> (not during the cleanup phase though) including subsequent invocations when
  +the script is cached in memory. 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 $r-&gt;register_cleanup as an alternative to <CODE>END</CODE> blocks if this behavior is not desirable.
   
   <P>
  -Add the following configuration directives:
  +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>
  -<PRE>  Alias /perl/ /home/httpd/perl/
  -</PRE>
  +<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>
   <P>
  -Assuming that you put all your scripts that should be executed under
  -mod_perl into <CODE>/home/httpd/perl/</CODE> directory.
  +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
  +example, the <STRONG>$^W</STRONG> variable corresponds to the
  +<STRONG>-w</STRONG> switch. Consult <CODE>perlvar</CODE> manpage for more details. With mod_perl it is also possible to turn on
  +warnings globally via the PerlWarn directive:
   
   <P>
  -<PRE>  PerlModule Apache::Registry
  -  &lt;Location /perl&gt;
  -    SetHandler perl-script
  -    PerlHandler Apache::Registry
  -    Options ExecCGI
  -    PerlSendHeader On
  -    allow from all
  -  &lt;/Location&gt;
  +<PRE>  PerlWarn On
   </PRE>
   <P>
  -Now put a test script into <CODE>/home/httpd/perl/</CODE> directory:
  +You can turn it off with <CODE>local $^W = 0;</CODE> in your scripts on the local basis (or inside the block). If you write <CODE>$^W = 0;</CODE> you disable the warning mode everywhere, the same with <CODE>$^W = 1;</CODE>.
   
   <P>
  -<PRE>  test.pl
  -  -------
  -  #!/usr/bin/perl -w
  -  use strict;
  -  print &quot;Content-type: text/html\r\n\r\n&quot;;
  -  print &quot;It worked!!!\n&quot;;
  -  -------
  -</PRE>
  -<P>
  -Make it executable and readable by server, if your server is running as
  -user <CODE>nobody</CODE> (hint see <CODE>User</CODE> directive in <CODE>httpd.conf</CODE> file), do the following:
  +The switch which enables taint checks does not have a special variable, so
  +mod_perl provides the PerlTaintCheck directive to turn on taint checks. In
  +httpd.conf, enable with:
   
   <P>
  -<PRE>  chown nobody /home/httpd/perl/test.pl
  -  chmod u+rx   /home/httpd/perl/test.pl
  +<PRE>  PerlTaintCheck On
   </PRE>
   <P>
  -Test that the script is running from the command line, by executing it:
  +Now, any and all code compiled inside httpd will be taint checked.
   
   <P>
  -<PRE>  /home/httpd/perl/test.pl
  -</PRE>
  +The environment variable PERL5OPT can be used to set additional perl
  +startup flags such as -d and -D. See
  +<A HREF="././modules.html#Apache_PerlRun_Run_unaltered_">Apache::PerlRun</A> .
  +
   <P>
  -You should see:
  +If you have the shebang line (<CODE>#!/bin/perl -Tw</CODE>) in your script, <STRONG>-w</STRONG>
  +will be honored (which means that you have turned the warn mode on for the
  +scope of this script, <STRONG>-T</STRONG> will produce a warning if
  +<CODE>PerlTaintCheck</CODE> is not <CODE>On</CODE>.
   
   <P>
  -<PRE>  Content-type: text/html
  -  
  -  It worked!!!
  -</PRE>
  +<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<CENTER><H2><A NAME="strict_pragma">strict pragma</A></H2></CENTER>
   <P>
  -Now it is a time to test our mod_perl server, assuming that your config
  -file includes <CODE>Port 80</CODE>, go to your favorite Netscape browser and fetch the following URL:
  +It's _absolutely_ mandatory (at least for development) to start all your
  +scripts with:
   
   <P>
  -<PRE>  <A HREF="http://localhost/perl/test.pl">http://localhost/perl/test.pl</A>
  +<PRE>  use strict;
   </PRE>
   <P>
  -(Assuming that you have a loop-back device configured, if not use the real
  -server name for this test (e.g. <CODE>http://www.nowhere.com/perl/test.pl</CODE>)
  -
  -<P>
  -You should see:
  +If needed, you can always turn off the 'strict' pragma or a part of it
  +inside the block, e.g:
   
   <P>
  -<PRE>  It worked!!!
  +<PRE>  {
  +    no strict 'refs';
  +    ... some code
  +  }
   </PRE>
   <P>
  -If something went wrong, go through the installation process again, and
  -make sure you didn't make a mistake. If that doesn't help, read the <CODE>INSTALL</CODE> pod document (<CODE>perlpod INSTALL</CODE>) in the mod_perl distribution directory.
  +It's more important to have <CODE>strict</CODE> pragma enabled under mod_perl than anywhere else. While it's not required,
  +it is strongly recommended, it will save you more time in the long run.
  +And, of course, clean scripts will still run under mod_cgi (plain CGI)!
   
   <P>
  -Now migrate your CGI scripts into a <CODE>/home/httpd/perl/</CODE> directory and see them working much much faster, from the newly configured
  -base URL (<CODE>/perl/</CODE>). Not all of your scripts will work unchanges, but many will.
  -
  +<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<CENTER><H2><A NAME="Turning_warnings_ON">Turning warnings ON</A></H2></CENTER>
   <P>
  -The above setup is very basic, it will help you to have a mod_perl enabled
  -server running.
  +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
  +<CODE>-w</CODE> in the first magic (shebang) line of the script <CODE>#!/perl
  +-switches</CODE> are being ignored by mod_perl. If you write <CODE>-T</CODE> you will be warned to set <CODE>PerlTaintCheck ON</CODE> in the config file.
   
   <P>
  -As with <STRONG>perl</STRONG> you can start benefit from <STRONG>mod_perl</STRONG> from the very first moment you try it. When you become more familiar with
  -mod_perl you will want to start writing apache handlers and deploy more of
  -the mod_perl power.
  +If you need -- you can always turn off the warnings with <CODE>local
  +$^W=0</CODE> in your code if you have some section you don't want the perl compiler to
  +warn in. The correct way to do this is:
   
   <P>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<CENTER><H1><A NAME="One_Plain_and_One_mod_perl_enabl">One Plain and One mod_perl enabled Apache Servers</A></H1></CENTER>
  +<PRE>  {
  +   local $^W=0;
  +    # some code
  +  }
  +</PRE>
   <P>
  -Since we run two apache servers we will need two different configuration
  -files, log files and etc. We need a special directory layout. While some of
  -the directories can be shared between the two servers (assuming that both
  -are built from the same source distribution) others should be separated. We
  -will refer to these two servers as <STRONG>httpd_docs</STRONG> (vanilla Apache) and <STRONG>httpd_perl</STRONG>
  -(Apache/mod_perl).
  +It preserves the previous value of <CODE>$^W</CODE> when you quit the block (so if it was set before, it will return to be set
  +at the leaving of the block.
   
   <P>
  -For this illustration, we will use <CODE>/usr/local</CODE> as our <EM>root</EM>
  -directory. The Apache installation directories will be stored under this
  -root (<CODE>/usr/local/bin</CODE>, <CODE>/usr/local/etc</CODE> and etc...)
  +In production code, it can be a good idea to turn warnings off. Otherwise
  +if your code isn't very clean and spits a few lines of warnings here and
  +there, you will end up with a huge <CODE>error_log</CODE> file in a short time on the heavily loaded server. Also, enabling runtime
  +warning checking has a small performance impact -- in any script, not just
  +under mod_perl -- so your approach should be to enable warnings during
  +development, and then disable them when your code is production-ready.
  +Controlling the warnings mode through the
  +<CODE>httpd.conf</CODE> is much better, since you can control the behavior of all of the scripts
  +from a central place. I have <CODE>PerlWarn On</CODE> on my development server and <CODE>PerlWarn Off</CODE> on the production machine.
   
   <P>
  -First let's prepare the sources. We will assume that all the sources go
  -into <CODE>/usr/src</CODE> dir. It is better when you use two separate copies of apache sources. Since
  -you probably will want to tune each apache version at separate and to do
  -some modifications and recompilations as the time goes. Having two
  -independent source trees will prove helpful, unless you use <CODE>DSO</CODE>, which is covered in this section.
  +<CODE>diagnostics</CODE> pragma can shed more light on the errors and warnings you see, but again,
  +it's better not to use it in production, since otherwise you incur a huge
  +overhead of the diagnostics pragma examining your every bit of code
  +mod_perl executes. (You can run your script with <CODE>-dDprof</CODE> to check the overhead. See <CODE>Devel::Dprof</CODE> for more info).
   
   <P>
  -Make two subdirectories:
  +<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<CENTER><H2><A NAME="diagnostics_pragma">diagnostics pragma</A></H2></CENTER>
  +<P>
  +This is a Perl compiler pragma which forces verbose warning diagnostics.
  +Put at the start of your scripts:
   
   <P>
  -<PRE>  % mkdir /usr/src/httpd_docs
  -  % mkdir /usr/src/httpd_perl
  +<PRE>  use diagnostics;
   </PRE>
   <P>
  -Now we will put the Apache source into <CODE>/usr/src/httpd_docs</CODE>:
  +This pragma turns on the <CODE>-w</CODE> mode, but gives you much better diagnostics of the errors and warnings
  +encountered. Generally it explains the reason for warnings/errors you get,
  +shows you an example of code where the same kind of warning is being
  +triggered, and tells you the remedy.
   
  -<P>
  -<PRE>  % cd /usr/src/httpd_docs
  -  % gzip -dc /path/to/tarfile/apache.tar.gz | tar xvf -
  -</PRE>
   <P>
  -If you have a gnu tar:
  +Again, it's a bad idea to keep it in your production code, as it will spit
  +10 and more lines of diagnostics messages into your error_log file for
  +every warning perl will report for the first time (per invocation). Also,
  +it will add a significant overhead to the code's runtime. (I discovered
  +this by using <CODE>Devel::DProf</CODE>!)
   
   <P>
  -<PRE>  % tar xvzf /path/to/apache.tar.gz
  -</PRE>
  +<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>
   <P>
  -Replace everywhere <CODE>/path/to/tarfile</CODE> with a path to a downloaded file.
  +To pass an environment variable from a configuration file, add to it:
   
   <P>
  -<PRE>  % cd /usr/src/httpd_docs
  -  % ls -l
  -  drwxr-xr-x  8 stas  stas 2048 Apr 29 17:38 apache_1.3.6/
  +<PRE>  PerlSetEnv key val
  +  PerlPassEnv key
   </PRE>
   <P>
  -Now we will prepare the <CODE>httpd_perl</CODE> server sources:
  +e.g.:
   
   <P>
  -<PRE>  % cd /usr/src/httpd_perl
  -  % gzip -dc /path/to/apache.tar.gz | tar xvf -
  -  % gzip -dc /path/to/modperl.tar.gz | tar xvf -
  -  % ls -l
  -  drwxr-xr-x  8 stas  stas 2048 Apr 29 17:38 apache_1.3.6/
  -  drwxr-xr-x  8 stas  stas 2048 Apr 29 17:38 modperl-1.19/
  +<PRE>  PerlSetEnv PERLDB_OPTS &quot;NonStop=1 LineInfo=/tmp/db.out AutoTrace=1&quot;
   </PRE>
   <P>
  -Time to decide on the desired directory structure layout (where the apache
  -files go):
  +will set <CODE>$ENV{PERLDB_OPTS}</CODE>, and it'll be accessible in every child.
   
   <P>
  -<PRE>  ROOT = /usr/local
  -</PRE>
  +<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<CENTER><H2><A NAME="Global_Variables">Global Variables</A></H2></CENTER>
   <P>
  -The two servers can share the following directories (so we will not
  -duplicate data):
  +It's always a good idea to stay away from global variables when possible.
  +Some variables must be global so Perl can see them, such as a module's <CODE>@ISA</CODE> or <CODE>$VERSION</CODE> variables. In common practice, a combination of <CODE>strict</CODE> and <CODE>vars</CODE> pragmas keeps modules clean and reduces a bit of noise. However, <CODE>vars</CODE> pragma also creates aliases as the <CODE>Exporter</CODE> does, which eat up more space. When possible, try to use fully qualified
  +names instead of use vars. Example:
   
   <P>
  -<PRE>  /usr/local/bin/
  -  /usr/local/lib
  -  /usr/local/include/
  -  /usr/local/man/
  -  /usr/local/share/
  +<PRE>  package MyPackage;
  +  use strict;
  +  @MyPackage::ISA = qw(...);
  +  $MyPackage::VERSION = &quot;1.00&quot;;
   </PRE>
  -<P>
  -<STRONG>Important:</STRONG> we assume that both servers are built from the same Apache source version.
  -
   <P>
  -Servers store their specific files either in <CODE>httpd_docs</CODE> or
  -<CODE>httpd_perl</CODE> sub-directories:
  +vs.
   
   <P>
  -<PRE>  /usr/local/etc/httpd_docs/
  -                 httpd_perl/
  -  
  -  /usr/local/sbin/httpd_docs/
  -                  httpd_perl/
  -  
  -  /usr/local/var/httpd_docs/logs/
  -                            proxy/
  -                            run/
  -                 httpd_perl/logs/
  -                            proxy/
  -                            run/
  +<PRE>  package MyPackage;
  +  use strict;
  +  use vars qw(@ISA $VERSION);
  +  @ISA = qw(...);
  +  $VERSION = &quot;1.00&quot;;
   </PRE>
   <P>
  -After you will complete the compilation and installation of the both
  -servers, you will have to configure them. To make things clear before we
  -proceed into details, you should configure the
  -<CODE>/usr/local/etc/httpd_docs/httpd.conf</CODE> as a plain apache and <CODE>Port</CODE>
  -directive to be 80 for example. And
  -<CODE>/usr/local/etc/httpd_perl/httpd.conf</CODE> to configure for mod_perl server and of course whose <CODE>Port</CODE> should be different then the one
  -<CODE>httpd_docs</CODE> server listens to (e.g. 8080). The port numbers issue will be discussed
  -later.
  +Also see <A HREF="././perl.html#Using_global_variables_and_shari">Using global variables and sharing them</A>
   
  -<P>
  -The next step is to configure and compile the sources: Below are the
  -procedures to compile both servers taking into account the directory layout
  -we have just decided to use.
  +
   
   <P>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<CENTER><H2><A NAME="Configuration_and_Compilation_of">Configuration and Compilation of the Sources.</A></H2></CENTER>
  +<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>
   <P>
  -Important note: In the installation scenario I have used apache and
  -mod_perl release numbers. As you understand I would not change these
  -numbers every time a new version of either apache or mod_perl will be
  -released. So please if you see <CODE>apache_1.3.6</CODE> it does not mean
  -<CODE>1.3.6</CODE> is the latest apache version.
  +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><H3><A NAME="Building_the_httpd_docs_Server">Building the httpd_docs Server</A></H3></CENTER>
  -<DL>
  -<P><DT><STRONG><A NAME="item_Sources">Sources Configuration</A></STRONG><DD>
  +<CENTER><H2><A NAME="Memory_leakage">Memory leakage</A></H2></CENTER>
   <P>
  -<PRE>  % cd /usr/src/httpd_docs/apache_1.3.6
  -  % make clean
  -  % env CC=gcc \
  -  ./configure --prefix=/usr/local \
  -    --sbindir=/usr/local/sbin/httpd_docs \
  -    --sysconfdir=/usr/local/etc/httpd_docs \
  -    --localstatedir=/usr/local/var/httpd_docs \
  -    --runtimedir=/usr/local/var/httpd_docs/run \
  -    --logfiledir=/usr/local/var/httpd_docs/logs \
  -    --proxycachedir=/usr/local/var/httpd_docs/proxy
  -</PRE>
  +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
  +to them from outside of that scope.
  +
   <P>
  -If you need some other modules, like mod_rewrite and mod_include (SSI), add
  -them here as well:
  +Perl doesn't return the memory it acquired from the kernel. It does reuse
  +it though!
   
   <P>
  -<PRE>    --enable-module=include --enable-module=rewrite
  +<STRONG>First example</STRONG> demonstrates reading a file:
  +
  +<P>
  +<PRE>  open IN, $file or die $!;
  +  $/ = undef; # will read the whole file in
  +  $content = &lt;IN&gt;;
  +  close IN;
   </PRE>
   <P>
  -Note: gcc - compiles httpd by 100K+ smaller then cc on AIX, remove the
  -<CODE>env CC=gcc</CODE> if you want to use the default compiler.
  +If your file is 5Mb, the child who served that script will grow exactly by
  +that size. Now if you have 20 children and all of them will serve this CGI,
  +all of them will consume additional 20*5M = 100M of RAM! If that's the
  +case, try to use other approaches of processing the file, if possible of
  +course. Try to process a line at a time and print it back to the file. (If
  +you need to modify the file itself, use a temporary file. When finished,
  +overwrite the source file, make sure to provide a locking mechanism!)
   
   <P>
  -Note: add <CODE>--layout</CODE> to see the resulting directories' layout without actually making the
  -configuration.
  +<STRONG>Second example</STRONG> demonstrates copying variables between functions (passing variables by
  +value). Let's use the example above, assuming we have no choice but to read
  +the whole file before any data processing. Now you have some imagine <CODE>process()</CODE> subroutine that processes the data and returns it back. What happens if you
  +pass the <CODE>$content</CODE> by value? You have just copied another 5M and the child has grown by
  +another 5M in size (watch your swap space!) now multiply it again by factor
  +of 20 you have 200M of wasted RAM, which will be apparently reused but it's
  +a waste! Whenever you think the variable can grow bigger than few Kb, pass
  +it by reference!
  +
  +<P>
  +Once I wrote a script that passed a content of a little flat file DataBase
  +to a function that processed it by value -- it worked and it was processed
  +fast, but with a time the DataBase became bigger, so passing it by value
  +was an overkill -- I had to make a decision, whether to buy more memory or
  +to rewrite the code. It's obvious that adding more memory will be merely a
  +temporary solution. So it's better to plan ahead and pass the variables by
  +reference, if a variable you are going to pass might be bigger than you
  +think at the time of your coding process. There are a few approaches you
  +can use to pass and use variables passed by reference. For example:
   
  -<P><DT><STRONG>Sources Compilation:</STRONG><DD>
   <P>
  -<PRE>  % make
  -  % make install
  +<PRE>  my $content = qq{foobarfoobar};
  +  process(\$content);
  +  sub process{
  +    my $r_var = shift; 
  +    $$r_var =~ s/foo/bar/gs;
  +      # nothing returned - the variable $content outside has been
  +      # already modified
  +  }
  +  
  +  @{$var_lr} -- dereferences an array
  +  %{$var_hr} -- dereferences a hash
   </PRE>
   <P>
  -Rename <CODE>httpd</CODE> to <CODE>http_docs</CODE>
  -
  +For more info see <CODE>perldoc perlref</CODE>.
   
  +<P>
  +Another approach would be to directly use a <CODE>@_</CODE> array. Using directly the <CODE>@_</CODE> array serves the job of passing by reference!
   
   <P>
  -<PRE>  % mv /usr/local/sbin/httpd_docs/httpd \
  -  /usr/local/sbin/httpd_docs/httpd_docs
  +<PRE>  process($content);
  +  sub process{
  +    $_[0] =~ s/foo/bar/gs;
  +      # nothing returned - the variable $content outside has been
  +      # already modified
  +  }
   </PRE>
   <P>
  -Now update an <STRONG>apachectl</STRONG> utility to point to the renamed httpd via your favorite text editor or by
  -using perl:
  +From <CODE>perldoc perlsub</CODE>:
   
   <P>
  -<PRE>  % perl -p -i -e 's|httpd_docs/httpd|httpd_docs/httpd_docs|' \
  -  /usr/local/sbin/httpd_docs/apachectl
  +<PRE>      The array @_ is a local array, but its elements are aliases for
  +      the actual scalar parameters.  In particular, if an element
  +      $_[0] is updated, the corresponding argument is updated (or an
  +      error occurs if it is not possible to update)...
   </PRE>
  -</DL>
  -<P>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<CENTER><H3><A NAME="Building_the_httpd_perl_Server_">Building the httpd_perl Server (mod_perl):</A></H3></CENTER>
   <P>
  -Before you start to configure the mod_perl sources, you should be aware
  -that there are a few Perl modules that have to be installed before building
  -mod_perl. You will be alerted if any required modules are missing when you
  -run the <CODE>perl Makefile.PL</CODE> command line below. If you discover that some are missing, pick them from
  -your nearest CPAN repository (if you do not know what is it, make a visit
  -to <A HREF="http://www.perl.com/CPAN">http://www.perl.com/CPAN</A> ) or run
  -the <CODE>CPAN</CODE> interactive shell via the command line <CODE>perl -MCPAN -e shell</CODE>.
  +Be careful when you write this kind of subroutines, since it can confuse a
  +potential user. It's not obvious that call like
  +<CODE>process($content);</CODE> modifies the passed variable -- programmers (which are the users of your
  +library in this case) are used to subs that either modify variables passed
  +by reference or return the processed variable (e.g. <CODE>$content=process($content);</CODE>).
   
   <P>
  -Make sure the sources are clean:
  -
  -<P>
  -<PRE>  % cd /usr/src/httpd_perl/apache_1.3.6
  -  % make clean
  -  % cd /usr/src/httpd_perl/mod_perl-1.19
  -  % make clean
  -</PRE>
  -<P>
  -It is important to <STRONG>make clean</STRONG> since some of the versions are not binary compatible (e.g apache 1.3.3 vs
  -1.3.4) so any ``third-party'' C modules need to be re-compiled against the
  -1.3.4 header files.
  +<STRONG>Third example</STRONG> demonstrates work with DataBases. If you do some DB processing, many times
  +you encounter the need to read lots of records into your program, and then
  +print them to the browser after they are formatted. (I don't even mention
  +the horrible case where programmers read in the whole DB and then use perl
  +to process it!!! Use a relational DB and let the SQL do the job, so you get
  +only the records you need!!!).
   
   <P>
  -Here I did not find a way to compile with gcc (my perl was compiled with cc
  -so we have to compile with the same compiler!!!
  +We will use <CODE>DBI</CODE> for this (assume that we are already connected to the DB) (refer to <CODE>perldoc DBI</CODE> for a complete manual of the <CODE>DBI</CODE>
  +module):
   
  -<P>
  -<PRE>  % cd /usr/src/httpd_perl/mod_perl-1.19
  -</PRE>
   <P>
  -<PRE>  % /usr/local/bin/perl Makefile.PL \
  -  APACHE_PREFIX=/usr/local/ \
  -  APACHE_SRC=../apache_1.3.6/src \
  -  DO_HTTPD=1 \
  -  USE_APACI=1 \
  -  PERL_MARK_WHERE=1 \
  -  PERL_STACKED_HANDLERS=1 \
  -  ALL_HOOKS=1 \
  -  APACI_ARGS=--sbindir=/usr/local/sbin/httpd_perl, \
  -         --sysconfdir=/usr/local/etc/httpd_perl, \
  -         --localstatedir=/usr/local/var/httpd_perl, \
  -         --runtimedir=/usr/local/var/httpd_perl/run, \
  -         --logfiledir=/usr/local/var/httpd_perl/logs, \
  -         --proxycachedir=/usr/local/var/httpd_perl/proxy
  +<PRE>  $sth-&gt;execute;
  +  while(@row_ary  = $sth-&gt;fetchrow_array;) {
  +        &lt;do DB accumulation into some variable&gt;
  +  }
  +  &lt;print the output using the the data returned from the DB&gt;
   </PRE>
   <P>
  -Notice that <STRONG>ALL</STRONG>  <CODE>APACI_ARGS</CODE> (below) must be passed as one long line if you work with <CODE>t?csh</CODE>!!! It works correctly the way it shown above with <CODE>(ba)?sh</CODE>. If you work with <CODE>t?csh</CODE> it does not work for
  -<CODE>csh</CODE> passes to <CODE>./configure</CODE>  <CODE>APACI_ARGS</CODE> params with new lines without '' - tcsh strips the original '' - and the
  -build goes broken.
  +In the example above the httpd_process will grow up by the size of the
  +variables that have been allocated for the records that matched the query.
  +(Again remember to multiply it by the number of the children your server
  +runs!).
   
   <P>
  -As with <CODE>httpd_docs</CODE> you might need other modules like
  -<CODE>mod_rewrite</CODE>, so add them here:
  +A better approach is to not accumulate the records, but rather print them
  +as they are fetched from the DB. Moreover, we will use the
  +<CODE>bind_col()</CODE> and <CODE>$sth-&amp;gt;fetchrow_arrayref()</CODE> (aliased to
  +<CODE>$sth-&amp;gt;fetch()</CODE>) methods, to fetch the data in the fastest possible way. The example below
  +prints a HTML TABLE with matched data, the only memory that is being used
  +is a <CODE>@cols</CODE> array to hold temporary row values:
   
   <P>
  -<PRE>         --enable-module=rewrite
  +<PRE>  my @select_fields = qw(a b c);
  +      # create a list of cols values
  +  my @cols = ();
  +  @cols[0..$#select_fields] = ();
  +  $sth = $dbh-&gt;prepare($do_sql);
  +  $sth-&gt;execute;
  +    # Bind perl variables to columns.
  +  $sth-&gt;bind_columns(undef,\(@cols));
  +  print &quot;&lt;TABLE&gt;&quot;;
  +  while($sth-&gt;fetch) {
  +     print &quot;&lt;TR&gt;&quot;,
  +           map(&quot;&lt;TD&gt;$_&lt;/TD&gt;&quot;, @cols),
  +           &quot;&lt;/TR&gt;&quot;;
  +  }
  +  print &quot;&lt;/TABLE&gt;&quot;;
   </PRE>
   <P>
  -Note: <CODE>PERL_STACKED_HANDLERS=1</CODE> is needed for <CODE>Apache::DBI</CODE>
  -
  -
  +Note: the above method doesn't allow you to know how many records have been
  +matched. The workaround is to run an identical query before the code above
  +where you use <CODE>SELECT count(*) ...</CODE> instead of <CODE>'SELECT *
  +...</CODE> to get the number of matched records.
   
   <P>
  -Now, build, test and install the <CODE>httpd_perl</CODE>.
  +For those who think that <STRONG>$sth-&gt;rows</STRONG> will do the job, here is the quote from the <CODE>DBI</CODE> manpage:
   
   <P>
  -<PRE>  % make &amp;&amp; make test &amp;&amp; make install
  +<PRE>  rows();
   </PRE>
  -<P>
  -Note: Apache puts a stripped version of <CODE>httpd</CODE> at
  -<CODE>/usr/local/sbin/httpd_perl/httpd</CODE>. The original version including debugging symbols (if you need to run a
  -debugger on this executable) is located at <CODE>/usr/src/httpd_perl/apache_1.3.6/src/httpd</CODE>.
  -
   <P>
  -Note: You may have noted that we did not go to the apache's source dir and
  -run <CODE>make install</CODE>. When <CODE>USE_APACI</CODE> is enabled,
  -<CODE>APACHE_PREFIX</CODE> will specify the --prefix option for Apache's configure script, specifying
  -the installation path for Apache. When this option is used, mod_perl's <CODE>make install</CODE> will also <CODE>make
  -install</CODE> on the Apache side, installing the httpd binary, support tools, along with
  -the configuration, log and document trees.
  -
  +<PRE>  $rv = $sth-&gt;rows;
  +</PRE>
   <P>
  -If <CODE>make test</CODE> fails, look into <CODE>t/logs</CODE> and see what is in there. Also see <A HREF="././install.html#make_test_fails">make test fails</A>.
  -
  +<PRE>  Returns the number of rows affected by the last database altering
  +  command, or -1 if not known or not available.  Generally you can
  +  only rely on a row count after a do or non-select execute (for some
  +  specific operations like update and delete) or after fetching all
  +  the rows of a select statement.
  +</PRE>
   <P>
  -While doing <CODE>perl Makefile.PL ...</CODE> mod_perl might complain by warning you about missing <CODE>libgdbm</CODE>. Users reported that it is actually crucial, and you must have it in order
  -to successfully complete the mod_perl building process.
  -
  +<PRE>  For select statements it is generally not possible to know how many
  +  rows will be returned except by fetching them all.  Some drivers
  +  will return the number of rows the application has fetched so far
  +  but others may return -1 until all rows have been fetched. So use of
  +  the rows method with select statements is not recommended.
  +</PRE>
   <P>
  -Now rename the <CODE>httpd</CODE> to <CODE>httpd_perl</CODE>:
  +As a bonus, I wanted to write a single sub that flexibly processes any
  +query, accepting: conditions, call-back closure sub, select fields and
  +restrictions. 
   
   <P>
  -<PRE>  % mv /usr/local/sbin/httpd_perl/httpd \
  -  /usr/local/sbin/httpd_perl/httpd_perl
  +<PRE>  # Usage:
  +  # $o-&gt;dump(\%conditions,\&amp;callback_closure,\@select_fields,@restrictions);
  +  #
  +  sub dump{
  +    my $self = shift;
  +    my %param = %{+shift}; # dereference hash
  +    my $rsub = shift;
  +    my @select_fields = @{+shift}; # dereference list
  +    my @restrict = shift || '';
  +  
  +      # create a list of cols values
  +    my @cols = ();
  +    @cols[0..$#select_fields] = ();
  +  
  +    my $do_sql = '';
  +    my @where = ();
  +  
  +      # make a @where list 
  +    map { push @where, &quot;$_=\'$param{$_}\'&quot; if $param{$_};} keys %param;
  +  
  +      # prepare the sql statement
  +    $do_sql = &quot;SELECT &quot;;
  +    $do_sql .= join(&quot; &quot;, @restrict) if @restrict;# append the restriction list
  +    $do_sql .= &quot; &quot; .join(&quot;,&quot;, @select_fields) ;      # append the select list 
  +    $do_sql .= &quot; FROM $DBConfig{TABLE} &quot;;         # from table
  +  
  +      # we will not add the WHERE clause if @where is empty
  +    $do_sql .= &quot; WHERE &quot; . join &quot; AND &quot;, @where if @where;
  +  
  +    print &quot;SQL: $do_sql \n&quot; if $debug;
  +  
  +    $dbh-&gt;{RaiseError} = 1;     # do this, or check every call for errors
  +    $sth = $dbh-&gt;prepare($do_sql);
  +    $sth-&gt;execute;
  +      # Bind perl variables to columns.
  +    $sth-&gt;bind_columns(undef,\(@cols));
  +    while($sth-&gt;fetch) {
  +      &amp;$rsub(@cols);
  +    }
  +      # print the tail or &quot;no records found&quot; message
  +      # according to the previous calls
  +    &amp;$rsub();
  +  
  +  } # end of sub dump
   </PRE>
   <P>
  -Update the apachectl utility to point to renamed httpd name:
  +Now a callback closure sub can do lots of things. We need a closure to know
  +what stage are we in: header, body or tail. For example, we want a callback
  +closure for formatting the rows to print: 
   
   <P>
  -<PRE>  % perl -p -i -e 's|httpd_perl/httpd|httpd_perl/httpd_perl|' \
  -  /usr/local/sbin/httpd_perl/apachectl
  +<PRE>  my $rsub = eval {
  +      # make a copy of @fields list, since it might go
  +      # out of scope when this closure will be called
  +    my @fields = @fields; 
  +    my @query_fields = qw(user dir tool act); # no date field!!!
  +    my $header = 0;
  +    my $tail   = 0;
  +    my $counter = 0;
  +    my %cols = (); # columns name=&gt; value hash
  +  
  +    # Closure with the following behavior:
  +    # 1. Header's code will be executed on the first call only and
  +    #    if @_ was set
  +    # 2. Row's printing code will be executed on every call with @_ set
  +    # 3. Tail's code will be executed only if Header's code was
  +    #    printed and @_ isn't set
  +    # 4. &quot;No record found&quot; code will be executed if Header's code
  +    #    wasn't executed
  +  
  +    sub {
  +          # Header
  +        if (@_ and !$header){
  +          print &quot;&lt;TABLE&gt;\n&quot;;
  +          print $q-&gt;Tr(map{ $q-&gt;td($_) } @fields );
  +          $header = 1; 
  +        }
  +        
  +          # Body
  +        if (@_) {
  +          print $q-&gt;Tr(map{$q-&gt;td($_)} @_ );
  +          $counter++;
  +          return; 
  +        }
  +        
  +          # Tail, will be printed only at the end
  +        if ($header and !($tail or @_)){
  +          print &quot;&lt;/TABLE&gt;\n $counter records found&quot;;
  +          $tail = 1;
  +          return;
  +        }
  +        
  +          # No record found
  +        unless ($header){
  +          print $q-&gt;p($q-&gt;center($q-&gt;b(&quot;No record was found!\n&quot;)));
  +        }
  +  
  +      }  #  end of sub {}
  +  };  #  end of my $rsub = eval {
   </PRE>
  -<P>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<CENTER><H2><A NAME="Configuration_of_the_servers">Configuration of the servers</A></H2></CENTER>
   <P>
  -Now when we have completed the building process, the last stage before
  -running the servers, is to configure them.
  +You might also want to check <A HREF="././performance.html#Limiting_the_size_of_the_process">Limiting the size of the processes</A>
  +and <A HREF="././performance.html#Limiting_the_resources_used_by_h">Limiting the resources used by httpd children</A>.
   
   <P>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<CENTER><H3><A NAME="Basic_httpd_docs_Server_s_Config">Basic httpd_docs Server's Configuration</A></H3></CENTER>
  +<CENTER><H1><A NAME="Reloading_Modules_and_Required_F">Reloading Modules and Required Files</A></H1></CENTER>
   <P>
  -Configuring of <CODE>httpd_docs</CODE> server is a very easy task. Open
  -<CODE>/usr/local/etc/httpd_docs/httpd.conf</CODE> into your favorite editor (starting from version 1.3.4 of Apache - there is
  -only one file to edit). And configure it as you always do. Make sure you
  -configure the log files and other pathes according to the directory layout
  -we decided to use.
  +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>
  -Start the server with:
  +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>  /usr/local/sbin/httpd_docs/apachectl start
  -</PRE>
  +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><H3><A NAME="Basic_httpd_perl_Server_s_Config">Basic httpd_perl Server's Configuration</A></H3></CENTER>
  -<P>
  -Here we will make a basic configuration of the <CODE>httpd_perl</CODE> server. We edit the <CODE>/usr/local/etc/httpd_perl/httpd.conf</CODE> file. As with
  -<CODE>httpd_docs</CODE> server configuration, make sure that log and other files directives are set
  -to point to the right places, according to the chosen directory layout.
  -
  +<CENTER><H2><A NAME="Restarting_the_server">Restarting the server</A></H2></CENTER>
   <P>
  -One first thing to do is to set a <CODE>Port</CODE> directive - it should be different from <CODE>80</CODE> since we cannot bind 2 servers to use the same port number on the same
  -machine. Here we will use &lt;8080&gt;. Some developers use port <CODE>81</CODE>, but you can bind to it, only if you have root permissions. If you are
  -running on multiuser machine, there is a chance someone already uses that
  -port, or will start using it in the future - which as you understand might
  -cause a collision. If you are the only user on your machine, basically you
  -can pick any not used port number. Port number choosing is a controversial
  -topic, for many organizations use firewalls, which may block some of the
  -ports, or enable only a known ones. From my experience the most used port
  -numbers are: <CODE>80</CODE>, <CODE>81</CODE>, <CODE>8000</CODE> and <CODE>8080</CODE>. Personally, I prefer the port <CODE>8080</CODE>. Of course with 2 server scenario you can hide the nonstandard port number
  -from users, by either using the mod_proxy's
  -<CODE>ProxyPass</CODE> or proxy server like squid.
  +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>
  -For more details see <A HREF="././config.html#Publishing_port_numbers_differen">Publishing port numbers different from 80 </A>, <A HREF="././scenario.html#Running_1_webserver_and_squid_in">Running 1 webserver and squid in httpd accelerator mode</A>,
  -<A HREF="././scenario.html#Running_2_webservers_and_squid_i">Running 2 webservers and squid in httpd accelerator mode</A>
  -and <A HREF="././scenario.html#Using_mod_proxy">Using mod_proxy</A>.
  -
  +<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>
  -Now we proceed to mod_perl specific directives. A good idea will be to add
  -them all at the end of the <CODE>httpd.conf</CODE>, since you are going to fiddle a lot of them.
  +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>
  -First, you need to specify the location where all mod_perl scripts will be
  -located.
  +<CODE>Apache::StatINC</CODE> - Reload <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>
  -Add the following configuration directive:
  +To enable this module just add two lines to <CODE>httpd.conf</CODE> file.
   
   <P>
  -<PRE>    # mod_perl scripts will be called from
  -  Alias /perl/ /usr/local/myproject/perl/
  +<PRE>  PerlModule Apache::StatINC
  +  PerlInitHandler Apache::StatINC
   </PRE>
  -<P>
  -From now on, all requests starting with <CODE>/perl</CODE> will be executed under <CODE>mod_perl</CODE> and will be mapped to the files in
  -<CODE>/usr/local/myproject/perl/</CODE>.
  -
   <P>
  -Now we should configure the <CODE>/perl</CODE> location.
  +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::Registry
  -</PRE>
  -<P>
  -<PRE>  &lt;Location /perl&gt;
  -    #AllowOverride None
  +<PRE>  PerlModule Apache::StatINC
  +  &lt;Location /perl&gt;
       SetHandler perl-script
  -    PerlHandler Apache::Registry
  +    PerlHandler Apache::Registry::handler
       Options ExecCGI
  -    allow from all
       PerlSendHeader On
  +    PerlInitHandler Apache::StatINC
  +    PerlSetVar StatINCDebug On
     &lt;/Location&gt;
   </PRE>
   <P>
  -This configuration causes all scripts that are called with a <STRONG>/perl</STRONG>
  -path prefix to be executed under the <STRONG>Apache::Registry</STRONG> module and as a CGI (so the <STRONG>ExecCGI</STRONG>, if you omit this option the script will be printed to the caller's
  -browser as a plain text or will possibly will trigger a 'Save-As' window). <STRONG>Apache::Registry</STRONG> module lets you run almost unaltered CGI/perl scripts under <CODE>mod_perl</CODE>. <CODE>PerlModule</CODE>
  -directive is an equivalent of perl's <CODE>require()</CODE>. We load the
  -<STRONG>Apache::Registry</STRONG> module before we use it in the <CODE>PerlHandler</CODE> in the <CODE>Location</CODE> configuration.
  +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. Whatever you do in your
  +scripts/modules which are being
  +<CODE>required()</CODE> after the server startup will not have any effect on
  +<CODE>@INC</CODE>. When you do <STRONG>use lib qw(foo/bar);</STRONG>, 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 watch the bottom of the page. (I assume you have configured the &lt;Location /perl-status&gt; section in <CODE>httpd.conf</CODE> as the mod_perl docs show.)
   
   <P>
  -<STRONG>PerlSendHeader On</STRONG> tells the server to send an HTTP header to the browser on every script
  -invocation. You will want to turn this off for nph (non-parsed-headers)
  -scripts.
  -
  +<P><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>
  -This is only a very basic configuration. <A HREF="././config.html#">Server Configuration</A> section covers the rest of the details.
  +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>
  -Start the server with:
  +Assuming that you start your script with loading <CODE>Foo::Bar</CODE> and importing some tags:
   
   <P>
  -<PRE>  /usr/local/sbin/httpd_perl/apachectl start
  +<PRE>  use lib &quot;/some/private/path&quot;;
  +  use Foo::Bar qw(:tags_group tag1 tag2);
   </PRE>
   <P>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<CENTER><H1><A NAME="Running_2_webservers_and_squid_i">Running 2 webservers and squid in httpd accelerator mode</A></H1></CENTER>
  -<P>
  -While I have detailed the mod_perl server installation, you are on your own
  -with installing the squid server (See <A HREF="././help.html#">Getting Helped</A> for more details). I run linux, so I have got the rpm package, installed
  -it, configured the <CODE>/etc/squid/squid.conf</CODE>, fired off the server and was all set. Basically once you have the squid
  -installed, you just need to modify the default <CODE>squid.conf</CODE> the way I will explain below, then you are ready to run the server.
  -
  -<P>
  -First, lets understand what do we have in hands and what do we want from
  -squid. We have an <CODE>httpd_docs</CODE> and <CODE>httpd_perl</CODE> servers listening on ports 81 and 8080 accordingly (we have to move the
  -httpd_docs server to port 81, since port 80 will be taken over by squid).
  -Both reside on the same machine as squid. We want squid to listen on port
  -80, forward a single static object request to the port httpd_docs server
  -listens to, and dynamic request to httpd_perl's port. Both servers return
  -the data to the proxy server (unless it is already cached in the squid), so
  -user never sees the ports and never knows that there might be more then one
  -server running. Proxy server makes all the magic behind it transparent to
  -user. Do not confuse it with <STRONG>mod_rewrite</STRONG>, where a server redirects the request somewhere according to the rules and
  -forgets about it. The described functionality is being known as <CODE>httpd accelerator mode</CODE> in proxy dialect.
  -
  -<P>
  -You should understand that squid can be used as a straight forward proxy
  -server, generally used in companies and ISPs to save up the traffic by
  -caching the most popular requests. We want to run it in the
  -<CODE>httpd accelerator mode</CODE>. Two directives: <CODE>httpd_accel_host</CODE> and
  -<CODE>httpd_accel_port</CODE> enable this mode. We will see more details in a few seconds. If you are
  -currently using the squid in the proxy mode, you can extend its
  -functionality by running both modes concurrently. To accomplish this, you
  -just configure the <CODE>httpd
  -accelerator mode</CODE>'s related directives as you were configuring it from scratch.
  -
  -<P>
  -As stated before, proxy server listens now to the port 80, we have to move
  -the httpd_docs server to port 81 for example (your mileage may vary :). So
  -you have to modify the httpd.conf in the httpd_docs config directory and
  -restart the httpd_docs server (But not before we get the squid running if
  -you are working on the production server). And as you remember httpd_perl
  -listens to port 8080.
  -
  -<P>
  -Let's go thru the changes we should apply to the default configuration
  -file. Since this file (<CODE>/etc/squid/squid.conf</CODE>)is huge (60k+) and we would not use 99% of it, my suggestion is to write a
  -new including only the modified directives.
  -
  -<P>
  -We want to enable the redirect feature, to be able to serve requests, by
  -more then one server (in our case we have httpd_docs and httpd_perl)
  -servers. So we specify <CODE>httpd_accel_host</CODE> as virtual. This assumes that your server has multiple interfaces - Squid
  -will bind to all of them.
  +Now to make a modification testing and reload at runtime you have to use
  +something like this:
   
   <P>
  -<PRE>  httpd_accel_host virtual
  +<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>
  -Then we define the default port - by default, if not redirected, httpd_docs
  -will serve the pages. We assume that most requests will be of the static
  -nature. We have our httpd_docs listening on port 81.
  +You may want to add debug print statements to debug this code in your
  +application.
   
   <P>
  -<PRE>  httpd_accel_port 81
  -</PRE>
  -<P>
  -And as described before, squid listens to port 80.
  +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>
  -<PRE>  http_port 80
  -</PRE>
  +<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>
  -We do not use icp (icp used for cache sharing between neighbor machines),
  -which is more relevant in the proxy mode.
  +When you wrote a script running under mod_cgi, you could get away with
  +sloppy programming, by opening a file and letting the interpreter to close
  +it for you when the script had finished his run, like:
   
   <P>
  -<PRE>  icp_port 0
  +<PRE>  open IN, &quot;in.txt&quot; or die &quot;Cannot open in.txt for reading : $!\n&quot;;
   </PRE>
   <P>
  -<CODE>hierarchy_stoplist</CODE> defined a list of words which, if found in a URL, cause the object to be
  -handled directly by this cache. In other words, use this to not query
  -neighbor caches for certain objects. Note that I have configured the <CODE>/cgi-bin</CODE> and <CODE>/perl</CODE> aliases for my dynamic documents, if you named them in a different way,
  -make sure to use the correct aliases here.
  +For mod_perl you <STRONG>must</STRONG>  <CODE>close()</CODE> the files you opened!
   
   <P>
  -<PRE>  hierarchy_stoplist /cgi-bin /perl
  +<PRE>  close IN;
   </PRE>
   <P>
  -Now we tell squid not to cache dynamic pages.
  +somewhere before the end of the script, since if you forget to
  +<CODE>close()</CODE>, you might get a file descriptor leakage and unlock problem (if you <CODE>flock()ed</CODE> on this file descriptor). Even if you do have it, but for some reason the
  +interpreter was stopped before the cleanup call, because of various
  +reasons, such as user aborted script ( See
  +<A HREF="././obvious.html#Handling_the_User_pressed_Stop_">Handling the 'User pressed Stop button' case</A>) the leakage is still there. In a long run your machine might get run out
  +of file descriptors, and even worse - file might be left locked and
  +unusable by other invocations of the same and other scripts.
  +
  +<P>
  +What can you do? Use <CODE>IO::File</CODE> (and other <CODE>IO::*</CODE> modules), which allows you to assign the file handler to variable, which
  +can be
  +<CODE>my()</CODE> (lexically) scoped. And when this variable goes out of scope the file or
  +other file system entity will be properly closed and unlocked (if it was
  +locked). Lexically scoped variable will always go out of scope at the end
  +of the script's run even if it was aborted in the middle or before the end
  +if it was defined inside some internal block. For example:
   
   <P>
  -<PRE>  acl QUERY urlpath_regex /cgi-bin /perl
  -  no_cache deny QUERY
  +<PRE>  {
  +    my $fh = new IO::File(&quot;filename&quot;) or die $!;
  +    # read from $fh
  +  } # ...$fh is closed automatically at end of block, without leaks.
   </PRE>
  -<P>
  -Please note that the last 2 directives are controversial. If you want your
  -scripts to be more complying with the HTTP standards, the headers of your
  -scripts should carry the <CODE>Caching Directives</CODE> according to the HTTP specs. You will find a complete tutorial about this
  -topic in
  -<CODE>Tutorial on HTTP Headers for mod_perl users</CODE> by Andreas J. Koenig. If you set the headers correctly there is no need to
  -tell squid accelerator to NOT try to cache something. The headers I am
  -talking about are <CODE>Last-Modified</CODE> and <CODE>Expires</CODE>. What are they good for?
  -
   <P>
  -Squid would not bother your mod_perl server a second time if a request is
  -(a) cachable and (b) still in the cache. Many mod_perl applications will
  -produce identical results on identical requests at least if not much time
  -goes by between the requests. So your squid might have a hit ratio of 50%
  -which means, which means that mod_perl servers have as twice as less work
  -than before. This is only possible by setting the headers correctly.
  +As I have just mentioned, you don't have to create a special block for this
  +purpose, for a file the code is written in is a virtual block as well, so
  +you can simply write:
   
   <P>
  -Even if you insert user-ID and date in your page, caching can save
  -resources when you set the expiration time to 1 second. A user might double
  -click where a single click would do, thus sending two requests in parallel,
  -squid could serve the second.
  -
  +<PRE>  my $fh = new IO::File(&quot;filename&quot;) or die $!;
  +    # read from $fh
  +    # ...$fh is closed automatically at end of block, without leaks.
  +</PRE>
   <P>
  -But if you are lazy, or just have too many things to deal with, you can
  -leave the above directives the way I described. But keep in mind that one
  -day you will want to reread this snippet and the Andreas' tutorial and
  -squeeze even more from your servers without investing money for more memory
  -and better hardware.
  +What the first technique (using <CODE>{ BLOCK }</CODE>) makes sure is that the file will be closed the moment, the block is
  +finished.
   
   <P>
  -While testing you might want to enable the debugging options and watch the
  -log files in <CODE>/var/log/squid/</CODE>. But turn it off in your production server. I list it commented out. (28
  -== access control routes).
  +But even faster and lighter technique is to use <CODE>Symbol.pm</CODE>:
   
   <P>
  -<PRE>  # debug_options ALL,1 28,9
  +<PRE>  my $fh = Symbol::gensym();
  +  open $fh, &quot;filename&quot; or die $!
   </PRE>
   <P>
  -We need to provide a way for a squid to dispatch the requests to the
  -correct servers, static object requests should be redirected to httpd_docs
  -(unless they are already cached), while dynamic should go to the httpd_perl
  -server. The configuration below tells squid to fire off 10 redirect
  -daemons, the path to the redirect daemon and disable rewriting any <CODE>Host:</CODE> header in redirected requests (as suggested by squid's documentation). The
  -redirection daemon script is enlisted below.
  +Use these approaches to ensure you have no leakages, but don't be lazy to
  +write <CODE>close()</CODE> statements, make it a habit.
   
   <P>
  -<PRE>  redirect_program /usr/lib/squid/redirect.pl
  -  redirect_children 10
  -  redirect_rewrites_host_header off
  -</PRE>
  +<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<CENTER><H1><A NAME="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></H1></CENTER>
   <P>
  -Maximum allowed request size in kilobytes. This one is pretty obvious. If
  -you are using POST to upload files, then set this to the largest file's
  -size plus a few extra kbytes.
  +You still can win from using mod_perl. 
   
   <P>
  -<PRE>  request_size 1000 KB
  -</PRE>
  -<P>
  -Then we have access permissions, which I will not explain. But you might
  -want to read the documentation so to avoid any security flaws.
  +One approach is to replace the <CODE>Apache::Registry</CODE> handler with
  +<CODE>Apache::PerlRun</CODE> and define a new location (the script can reside in the same directory on
  +the disk. 
   
   <P>
  -<PRE>  acl all src 0.0.0.0/0.0.0.0
  -  acl manager proto cache_object
  -  acl localhost src 127.0.0.1/255.255.255.255
  -  acl myserver src 127.0.0.1/255.255.255.255
  -  acl SSL_ports port 443 563
  -  acl Safe_ports port 80 81 8080 81 443 563
  -  acl CONNECT method CONNECT
  +<PRE>  # srm.conf
  +  Alias /cgi-perl/ /home/httpd/cgi/
     
  -  http_access allow manager localhost
  -  http_access allow manager myserver
  -  http_access deny manager
  -  http_access deny !Safe_ports
  -  http_access deny CONNECT !SSL_ports
  -  # http_access allow all
  +  # httpd.conf
  +  &lt;Location /cgi-perl&gt;
  +    #AllowOverride None
  +    SetHandler perl-script
  +    PerlHandler Apache::PerlRun
  +    Options ExecCGI
  +    allow from all
  +    PerlSendHeader On
  +  &lt;/Location&gt;
   </PRE>
   <P>
  -Since squid should be run as non root, you need these if you are starting
  -the squid as root.
  +See <A HREF="#Apache_PerlRun_a_closer_look">Apache::PerlRun - a closer look</A>
   
  -<P>
  -<PRE>  cache_effective_user squid
  -  cache_effective_group squid
  -</PRE>
  -<P>
  -Memory used for caching parameter. The squid documentation warns that the
  -actual size of the squid can become 3 times higher than this value.
   
  -<P>
  -<PRE>  cache_mem 20 MB
  -</PRE>
  +
   <P>
  -Keep pools of allocated (but unused) memory available for future use. Read
  -more about it in the squid docs.
  +Another ``bad'', but working method is to set <CODE>MaxRequestsPerChild</CODE> to 1, which will force each child to exit after serving only one request,
  +so you'll get the preloaded modules, etc., the script will be compiled each
  +request, then killed off. This isn't good for ``high-traffic'' sites
  +though, as the parent server will need to fork a new child each time one is
  +killed, but you can fiddle with <CODE>MaxStartServers</CODE>,
  +<CODE>MinSpareServers</CODE>, to make the parent spawn more servers ahead so the killed one will be
  +immediately replaced with the fresh one. Again, probably that's not what
  +you want.
   
   <P>
  -<PRE>  memory_pools on
  -</PRE>
  +<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<CENTER><H1><A NAME="Apache_PerlRun_a_closer_look">Apache::PerlRun - a closer look</A></H1></CENTER>
   <P>
  -Cache manager cgi script (cachemgr.cgi - comes bundled with squid) - you
  -will want to tight the permissions for a production server.
  +<CODE>Apache::PerlRun</CODE> gives you a benefit of preloaded perl and its modules. This module's
  +handler emulates the CGI environment, allowing programmers to write scripts
  +that run under CGI or mod_perl without any change. Unlike <CODE>Apache::Registry</CODE>, the <CODE>Apache::PerlRun</CODE>
  +handler does not cache the script inside of a subroutine. Scripts will be
  +``compiled'' on each request. After the script has run, its name space is
  +flushed of all variables and subroutines. Still, you don't have the
  +overhead of loading the perl and compilation time of the standard modules
  +(If your script is very light, but uses lots of standard modules - you will
  +see no difference between
  +<CODE>Apache::PerlRun</CODE> and <CODE>Apache::Registry</CODE> !).
   
  -<P>
  -<PRE>  cachemgr_passwd disable shutdown
  -  #cachemgr_passwd none all
  -</PRE>
   <P>
  -Now the redirection daemon script (you should put it at the location you
  -have specified by <CODE>redirect_program</CODE> parameter in the config file above, and make it executable by webserver of
  -course):
  +Be aware though, that if you use packages that use internal variables that
  +have circular references, they will be not flushed!!!
  +<CODE>Apache::PerlRun</CODE> only flushes your script's name space, which does not include any other
  +required packages' name spaces. If there's a reference to a <CODE>my()</CODE> scoped variable that's keeping it from being destroyed after leaving the
  +eval scope (of <CODE>Apache::PerlRun</CODE>), that cleanup might not be taken care of until the server is shutdown and
  +<CODE>perl_destruct()</CODE> is run, which always happens after running command line scripts. Consider
  +this example:
   
   <P>
  -<PRE>  #!/usr/local/bin/perl
  -  
  -  $|=1;
  +<PRE>  package Foo;
  +  sub new { bless {} }
  +  sub DESTROY {
  +    warn &quot;Foo-&gt;DESTROY\n&quot;;
  +  }
     
  -  while (&lt;&gt;) {
  -  # redirect to mod_perl server
  -    print($_), next if 
  -   s|<A HREF="http://127">http://127</A>\.0\.0\.1:81/perl|<A HREF="http://www.nowhere.com:8080/perl">http://www.nowhere.com:8080/perl</A>|o;
  +  eval &lt;&lt;'EOF';
  +  package my_script;
  +  my $self = Foo-&gt;new;
  +  #$self-&gt;{circle} = $self;
  +  EOF
     
  -  # default - static server
  -    print;
  -  }
  +  print $@ if $@;
  +  print &quot;Done with script\n&quot;;
   </PRE>
  -<P>
  -Note: you see the 127.0.0.1 (which is a 'localhost'), because in my
  -scenario the proxy and the apache servers are running on the same machine.
  -So the requests that went through squid being converted to point to the
  -localhost in our configuration.
  -
  -<P>
  -A few notes regarding this redirector script:
  -
  -<P>
  -You must disable buffering. <CODE>$|=1;</CODE> does the job. If you do not disable buffering, the stdout will be flushed
  -only when the buffer will be full and it's about 4 or 8k if I remember
  -correctly. So your users will just wait till it will be filled up.
  -
  -<P>
  -For those who thinks that it is a very ineffective way to redirect, the
  -redirector runs as a daemon, you fire up N redirect daemons, so there is no
  -problem with perl interpreter loading, exactly like modperl - it is already
  -loaded and the code compiled, so redirect is very fast (not slower if
  -redirector was written in C or alike). I think that squid keeps a pipe
  -opened to all redirect daemons so there is no overhead of system calls as
  -well.
  -
   <P>
  -Now it is time to restart the server, at linux I do it with:
  +First you'll see:
   
   <P>
  -<PRE>  /etc/rc.d/init.d/squid restart
  +<PRE>  Foo-&gt;DESTROY
  +  Done with script
   </PRE>
  -<P>
  -Now you are done...
  -
   <P>
  -Almost... When you will try the new setup, you will be surprised and upset
  -to discover the port 81 showing up in the URLs of the static objects (like
  -htmls). Hey, we did not want the user to see the port 81 and use it since
  -it will bypass the squid server and the hard work we went through was just
  -a waste of time? The solution is to run both the squid and the httpd_docs
  -on the same port. This can be accomplished by binding each one to a
  -specific interface. Modify the <CODE>httpd.conf</CODE> in the <CODE>httpd_docs</CODE> configuration directory:
  +Then, uncomment the line where <CODE>$self</CODE> makes a circular
  +reference, and you'll see:
   
   <P>
  -<PRE>  Port 80
  -  BindAddress 127.0.0.1
  -  Listen 127.0.0.1:80
  +<PRE>  Done with script
  +  Foo-&gt;DESTROY
   </PRE>
   <P>
  -Modify the <CODE>squid.conf</CODE>
  +In this case, under mod_perl you wouldn't see <CODE>Foo-&amp;gt;DESTROY</CODE>
  +until the server shutdown, or your module properly took care of things.
   
  -
  -
  -<P>
  -<PRE>  http_port 80
  -  tcp_incoming_address 123.123.123.3
  -  tcp_outgoing_address 127.0.0.1
  -  httpd_accel_host 127.0.0.1
  -  httpd_accel_port 80
  -</PRE>
   <P>
  -Where <CODE>123.123.123.3</CODE> should be replaced with IP of your main server. Now restart the squid and
  -httpd_docs in either order you want, and voila the port number has gone.
  -
  +<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>
  -I think that you must also have in the /etc/hosts an entry:
  +To trap all/most Perl run-time errors and send the output to the client
  +instead of Apache's error log add this line to your script.
   
   <P>
  -<PRE>  127.0.0.1  localhost.localdomain   localhost
  +<PRE>  use CGI::Carp qw(fatalsToBrowser);
   </PRE>
   <P>
  -But generally it is always there in first place.
  +Refer to <CODE>CGI::Carp</CODE> man page for more related info.
   
   <P>
  -Now if you scripts were generating full self references using the port 8080
  -or other you should remove it and generate links to point to port 80 (which
  -means not using the port at all). If you do not, users will bypass the
  -squid, like if it was not setup at all. The only question left is what to
  -do with users who bookmarked your services and they still have the port
  -8080 inside. Do not worry about it. The most important thing is for your
  -scripts to return a full URLs, so if user comes from the link with 8080
  -port inside, let it be. Just make sure that all the consecutive calls to
  -you server will be pointed correctly. During some period your users will
  -change their bookmarks, nothing you can do about by send them an email if
  -you have one, or to leave a note on your pages asking users to update their
  -bookmarks. You could avoid this problem if you did not publish this non-80
  -port. See
  -<A HREF="././config.html#Publishing_port_numbers_differen">Publishing port numbers different from 80</A>.
  +Also you can write your custom DIE/WARN signal handler. I don't want users
  +to see the error message, but I want it to be emailed to me if it's severe
  +enough. The handler traps various errors and performs accordingly to the
  +defined logic. My handler was written for the modperl environment, but
  +works correctly when is being called from the shell. A stripped version of
  +the code is shown here:
   
   <P>
  -&lt;META&gt; Need to write up a section about server logging with squid.
  -One thing I sure would like to know is how requests are logged with this
  -setup. I have, as most everyone I imagine, log rotation, analysis,
  -archiving scripts and they all assume a single log. Does one have different
  -logs that have to be merged (up to 3 for each server + squid) ? Even when
  -squid responds to a request out of its cache I'd still want the thing to be
  -logged. &lt;/META&gt;
  -
  +<PRE>  # assign the DIE sighandler to call mydie(error_message) whenever a
  +  # die() sub is being called. Can be added anywhere in the code.
  +  local $SIG{'__DIE__'} = \&amp;mydie;
  +  
  +Do not forget the C&lt;local()&gt;, unless you want this signal handler to
  +be invoked every time any scripts dies (Even those where this
  +treatment is undesirable)
  +</PRE>
   <P>
  -See <A HREF="././scenario.html#Using_mod_proxy">Using mod_proxy</A> for information about
  -<CODE>X-Forwarded-For</CODE>.
  -
  -<P>
  -To save you keystrokes, here is the whole modified <CODE>squid.conf</CODE>:
  -
  -<P>
  -<PRE>  http_port 80
  -  tcp_incoming_address 123.123.123.3
  -  tcp_outgoing_address 127.0.0.1
  -  httpd_accel_host 127.0.0.1
  -  httpd_accel_port 80
  +<PRE>  # and the handler itself
  +  sub mydie{
  +    my $why = shift;
     
  -  icp_port 0
  +    my $UNDER_MOD_PERL = ( (exists $ENV{'GATEWAY_INTERFACE'} 
  +                           and $ENV{'GATEWAY_INTERFACE'} =~ /CGI-Perl/)
  +                         or exists $ENV{'MOD_PERL'} ) ? 1 : 0;
     
  -  hierarchy_stoplist /cgi-bin /perl
  -  acl QUERY urlpath_regex /cgi-bin /perl
  -  no_cache deny QUERY
  +    chomp $why;
  +    my $orig_why = $why;                # an ASCII copy for email report
     
  -  # debug_options ALL,1 28,9
  +    # handle the shell execution case (so we will not get all the HTML)
  +    print(&quot;Error: $why\n&quot;), exit unless $UNDER_MOD_PERL;
     
  -  redirect_program /usr/lib/squid/redirect.pl
  -  redirect_children 10
  -  redirect_rewrites_host_header off
  +    my $should_email = 0;
  +    my $message = '';
     
  -  request_size 1000 KB
  +    $why =~ s/[&lt;&amp;&gt;]/&quot;&amp;#&quot;.ord($&amp;).&quot;;&quot;/ge;    # entity escape
     
  -  acl all src 0.0.0.0/0.0.0.0
  -  acl manager proto cache_object
  -  acl localhost src 127.0.0.1/255.255.255.255
  -  acl myserver src 127.0.0.1/255.255.255.255
  -  acl SSL_ports port 443 563
  -  acl Safe_ports port 80 81 8080 81 443 563
  -  acl CONNECT method CONNECT
  +    # Now we need to trap various kinds of errors, that come from CGI.pm
  +    # And we don't want these errors to be emailed to us, since
  +    # these aren't programmatical errors
  +    if ($orig_why =~ /Client attempted to POST (\d+) bytes/o) {
     
  -  http_access allow manager localhost
  -  http_access allow manager myserver
  -  http_access deny manager
  -  http_access deny !Safe_ports
  -  http_access deny CONNECT !SSL_ports
  -  # http_access allow all
  +      $message = qq{
  +                  You can not POST messages bigger than 
  +                  @{[1024*$c{max_image_size}]} bytes.&lt;BR&gt;
  +                  You have tried to post $1 bytes&lt;BR&gt;
  +                  If you are trying to upload an image, make sure its size is not 
  +                  bigger than @{[1024*$c{max_image_size}]} bytes.&lt;P&gt;
  +                  Thank you!
  +                 };
     
  -  cache_effective_user squid
  -  cache_effective_group squid
  +    } elsif ($orig_why =~ /Malformed multipart POST/o) {
     
  -  cache_mem 20 MB
  +      $message = qq{
  +                  Have you tried to upload an image in the wrong way?&lt;P&gt;
  +                  To sucessfully upload an image you must use a browser that supports
  +                  image upload and use the 'Browse' button to select that image.
  +                  DO NOT type the path to the image into the upload field.&lt;P&gt;
  +                  Thank you!
  +                 };
     
  -  memory_pools on
  +    } elsif ($orig_why =~ /closed socket during multipart read/o) {
     
  -  cachemgr_passwd disable shutdown
  -</PRE>
  -<P>
  -Note that parameters' names should start at the beginning of the line.
  -
  -<P>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<CENTER><H1><A NAME="Running_1_webserver_and_squid_in">Running 1 webserver and squid in httpd accelerator mode</A></H1></CENTER>
  -<P>
  -When I was first told about the squid, I thought: ``Hey I can drop now the <CODE>httpd_docs</CODE> server and to have only squid and <CODE>httpd_perl</CODE>
  -servers``. Since all my static objects will be cached by squid, I do not
  -need the light server. But it was a wrong assumption. Why? Because you
  -still have the overhead of loading the objects into squid at first time,
  -and if your site has many of them. Not all of them will be cached (unless
  -you have devoted a huge chunk of memory to squid) and my heavy mod_perl
  -servers will still have an overhead of serving the static documents. How
  -one would measure the overhead? The difference between the two servers is
  -memory consumption, everything else (e.g. I/O) should be equal. So you have
  -to estimate the time needed for first fetches per second at a peak period
  -and thus the number of servers you need for static pages. This number you
  -have to multiply with the difference of memory requirements to get the
  -memory overhead. I can imagine, this amount could be significant in some
  -installations.
  -
  -<P>
  -So I have decided to have even more administration overhead and to stick to
  -the squid, httpd_docs and httpd_perl scenario, where I can optimize and
  -fine tune everything. Of course this can be not your case. If you are
  -feeling that the scenario from the previous section is too complicated for
  -you, make it simpler. Have only one server with mod_perl built in and let
  -the squid to do most of the job that plain light apache used to do. As I
  -have explained in the last paragraph, you should pick this lighter setup
  -only if you can make squid cache most of your static objects. If it cannot,
  -your mod_perl server will do the work we do not want it to.
  -
  -<P>
  -So if you are still with me. Install the apache with mod_perl and the
  -squid. Then use a similar configuration from the previous section, but now
  -httpd_docs is not there anymore. Also we do not need the redirector anymore
  -and we specify <CODE>httpd_accel_host</CODE> as a name of the server and not <CODE>virtual</CODE>. We also do not need to bind two servers on the same port anymore because
  -we do not redirect anymore (There is no more need for <CODE>Bind</CODE> and <CODE>Listen</CODE> directives in the httpd.conf).
  -
  -<P>
  -The modified configuration (see the explanations in the previous section):
  -
  -<P>
  -<PRE>  httpd_accel_host put.your.hostname.here
  -  httpd_accel_port 8080
  -  http_port 80
  -  icp_port 0
  +      $message = qq{
  +                  Have you pressed a 'STOP' button?&lt;BR&gt;
  +                  Please try again!&lt;P&gt;
  +                  Thank you!
  +                 };
     
  -  hierarchy_stoplist /cgi-bin /perl
  -  acl QUERY urlpath_regex /cgi-bin /perl
  -  no_cache deny QUERY
  +    } else {
     
  -  # debug_options ALL,1 28,9
  +      $message = qq{
  +                    &lt;B&gt;There is no action to be performed on your side, since
  +                  the error report has been already sent to webmaster. &lt;BR&gt;&lt;P&gt;
  +                  &lt;B&gt;Thank you for your patience!&lt;/B&gt;
  +                 };
     
  -  # redirect_program /usr/lib/squid/redirect.pl
  -  # redirect_children 10
  -  # redirect_rewrites_host_header off
  +      $should_email = 1;
  +    }
     
  -  request_size 1000 KB
     
  -  acl all src 0.0.0.0/0.0.0.0
  -  acl manager proto cache_object
  -  acl localhost src 127.0.0.1/255.255.255.255
  -  acl myserver src 127.0.0.1/255.255.255.255
  -  acl SSL_ports port 443 563
  -  acl Safe_ports port 80 81 8080 81 443 563
  -  acl CONNECT method CONNECT
  +    print qq|Content-type: text/html
     
  -  http_access allow manager localhost
  -  http_access allow manager myserver
  -  http_access deny manager
  -  http_access deny !Safe_ports
  -  http_access deny CONNECT !SSL_ports
  -  # http_access allow all
  +  &lt;HTML&gt;&lt;BODY BGCOLOR=&quot;white&quot;&gt;
  +  &lt;B&gt;Oops, An error has happened.&lt;/B&gt;&lt;P&gt;
  +    |;  
     
  -  cache_effective_user squid
  -  cache_effective_group squid
  +    print $message;
     
  -  cache_mem 20 MB
  +      # send email report if appropriate
  +    if ($should_email){
     
  -  memory_pools on
  +        # import sendmail subs
  +      use Mail ();
  +        # prepare the email error report:
  +      my $subject =&quot;Error Report&quot;;
  +      my $body = qq|
  +    An error has happened:
     
  -  cachemgr_passwd disable shutdown
  -</PRE>
  -<P>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<CENTER><H1><A NAME="Using_mod_proxy">Using mod_proxy</A></H1></CENTER>
  -<P>
  -The server on port 80 answers html requests directly and proxies the
  -modperl enabled directory like this:
  -
  -<P>
  -<PRE>  ProxyPass /modperl/ <A HREF="http://localhost:81/modperl/">http://localhost:81/modperl/</A>
  -  ProxyPassReverse /modperl/ <A HREF="http://localhost:81/modperl/">http://localhost:81/modperl/</A>
  +    $orig_why
  +  
  +      |;
  +  
  +        # send error reports to admin and author
  +      send_mail($c{email}{'admin'},$c{email}{'admin'},$subject,$body);
  +      send_mail($c{email}{'admin'},$c{email}{'author'},$subject,$body);
  +      print STDERR &quot;[&quot;.scalar localtime().&quot;] [SIGDIE] Sending Error Email\n&quot;;
  +    }
  +  
  +       # print to error_log so we will know we've sent
  +    print STDERR &quot;[&quot;.scalar localtime().&quot;] [SIGDIE] $orig_why \n&quot;;
  +  
  +    exit 1;
  +  }                             # end of sub mydie
  +  
   </PRE>
   <P>
  -<CODE>PPR</CODE> is the saving grace here, that makes Apache a win over Squid. That cleans
  -up redirects and stuff to remove the :81 from the URIs. Very nice. If you
  -want to use mod_proxy to proxy pass more than one port, you probably want
  -to take a look at mod_rewrite.
  +You may have noticed that I trap the CGI.pm's <CODE>die()</CODE> calls
  +here, I don't see any reason why my users should see an ugly error
  +messages, but that's the way CGI.pm written. The workaround is to trap them
  +myself.
   
   <P>
  -You can control the buffering feature with <CODE>ProxyReceiveBufferSize</CODE>
  -directive:
  +Please note that as of ver 2.49, CGI.pm provides a <CODE>cgi_error()</CODE>
  +method to print the errors and wouldn't <CODE>die()</CODE> unless you want
  +it.
   
   <P>
  -<PRE>  ProxyReceiveBufferSize 1048576
  -</PRE>
  +<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<CENTER><H1><A NAME="Finding_the_line_number_the_erro">Finding the line number the error/warning has been triggered at</A></H1></CENTER>
   <P>
  -will set a buffer size to be of 1Mb. If it is not set explicitly, then the
  -default buffer size is used, which depends on OS, for Linux I suspect it is
  -somewhere below 32k. So basicaly to get an immediate release of the
  -mod_perl server, <CODE>ProxyReceiveBufferSize</CODE> should be set to a value greater than the biggest generated respond
  -produced by any mod_perl script.
  +<CODE>Apache::Registry</CODE>, <CODE>Apache::PerlRun</CODE> and modules that compile-via-eval confuse the line numbering. Other files
  +that are read normally by Perl from disk have no problem with file
  +name/line number.
   
   <P>
  -The <CODE>ProxyReceiveBufferSize</CODE> directive specifies an explicit network buffer size for <STRONG>outgoing</STRONG> HTTP and FTP connections, for increased throughput. It has to be greater
  -than 512 or set to 0 to indicate that the system's default buffer size
  -should be used.
  +If you compile with the experimental <STRONG>PERL_MARK_WHERE=1</STRONG>, it shows you almost the exact line number, where this is happening.
  +Generally a compiler makes a shift in its line counter. You can always
  +stuff your code with special compiler directives, to reset its counter to
  +the value you will tell. At the beginning of the line you should write (the
  +'#' in column 1):
   
   <P>
  -As the name states its buffering applies only to <STRONG>downstream data</STRONG>
  -(coming from the origin server to the proxy) and not upstream (i.e.
  -buffering the data being uploaded from the client browser to the proxy,
  -thus freeing the httpd_perl origin server from being tied up during a large
  -POST such as a file upload)
  -
  +<PRE>  #line 298 myscript.pl
  +  or 
  +  #line 890 some_label_to_be_used_in_the_error_message
  +</PRE>
   <P>
  -Apache does caching as well. It's relevant to mod_perl only if you produce
  -proper headers so your scripts' output can be cached. See apache
  -documentation for more details on configuration of this capability.
  +The label is optional - the filename of the script will be used by default.
  +This specifies the line number of the <STRONG>following</STRONG> line, not the line the directive is on. You can use a little script to
  +stuff every N lines of your code with these directives, but then you will
  +have to rerun this script every time you add or remove code lines. The
  +script:
   
   <P>
  -Ask Bjoern Hansen has written a <CODE>mod_proxy_add_forward.c</CODE> module for Apache, that sets the <CODE>X-Forwarded-For</CODE> field when doing a
  -<CODE>ProxyPass</CODE>, similar to what Squid can do. His patch is at: <A
  -HREF="http://modules.apache.org/search?id=124">http://modules.apache.org/search?id=124</A>
  -or at <A
  -HREF="ftp://ftp.netcetera.dk/pub/apache/">ftp://ftp.netcetera.dk/pub/apache/</A>
  -. Basically, that module adds an extra HTTP header to proxying requests.
  -You can access that header in the mod_perl-enabled server, and set the IP
  -of the remote server. You won't need to compile anything into the back-end
  -server, if you are using <CODE>Apache::{Registry,PerlRun}</CODE> just put something like the following into <CODE>start-up.pl</CODE>:
  -
  +<PRE>    &lt;META&gt;
  +        This example was double incrementing $counter.
  +        I took the second increment out -- sgr.
  +    &lt;/META&gt;
  +</PRE>
   <P>
  -<PRE>  sub My::ProxyRemoteAddr ($) {
  -    my $r = shift;
  -   
  -        # we'll only look at the X-Forwarded-For header if the requests
  -        # comes from our proxy at localhost
  -        return OK unless ($r-&gt;connection-&gt;remote_ip eq &quot;127.0.0.1&quot;);
  -   
  -        if (my ($ip) = $r-&gt;header_in('X-Forwarded-For') =~ /([^,\s]+)$/) {
  -          $r-&gt;connection-&gt;remote_ip($ip);
  -        }
  -        
  -        return OK;
  +<PRE>  #!/usr/bin/perl
  +  # Puts Perl line markers in a Perl program for debugging purposes.  
  +  # Also takes out old line markers.
  +  die &quot;No filename to process.\n&quot; unless @ARGV;
  +  my $filename = $ARGV[0];
  +  my $lines = 100;
  +  open IN, $filename or die &quot;Cannot open file: $filename: $!\n&quot;;
  +  open OUT, &quot;&gt;$filename.marked&quot;
  +      or die &quot;Cannot open file: $filename.marked: $!\n&quot;;
  +  my $counter = 1;
  +  while (&lt;IN&gt;) {
  +    print OUT &quot;#line $counter\n&quot; unless $counter++ % $lines;
  +    next if $_ =~ /^#line /;
  +    print OUT $_;
     }
  +  close OUT;
  +  close IN;
  +  chmod 0755, &quot;$filename.marked&quot;;
   </PRE>
   <P>
  -And in <CODE>httpd.conf</CODE>:
  +To have a complete trace of calls add:
   
   <P>
  -<PRE>  PerlPostReadRequestHandler My::ProxyRemoteAddr
  +<PRE>  use Carp ();
  +  local $SIG{__WARN__} = \&amp;Carp::cluck;
   </PRE>
   <P>
  -Different sites have different needs. If you're using the header to set the
  -ip address Apache believes it is dealing with (in the logging and stuff)
  -you really don't want anyone but your own system to set the header.
  -
  +<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>
   <P>
  -That's why the above ``recommanded code'' includes a check for where the
  -request really is coming from before we change remote_ip.
  +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 + <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 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 function 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
  +should be loaded again for this external program to run.
   
   <P>
  -From that point on, the remote IP address is correct. You should be able to
  -access <CODE>REMOTE_ADDR</CODE> as usual.
  +Basically, you would do:
   
   <P>
  -You could do the same thing with other environment variables (though I
  -think several of them are preserved, you will want to run some tests to see
  -which ones).
  -
  -<P>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<CENTER><H1><A NAME="mod_perl_server_as_DSO">mod_perl server as DSO</A></H1></CENTER>
  +<PRE>  $params=FreezeThaw::freeze(
  +        [all data to pass to the other process]
  +        );
  +  system(&quot;program.pl $params&quot;);
  +</PRE>
   <P>
  -To build the mod_perl as DSO add <CODE>USE_DSO=1</CODE> to the rest of configuration parameters (so it will build libperl.so and
  -not libperl.a), like:
  +and in <CODE>program.pl</CODE> :
   
   <P>
  -<PRE>  perl Makefile.PL USE_DSO=1 ...
  +<PRE>  @params=FreezeThaw::thaw(shift @ARGV);
  +  # check that @params is ok
  +  close STDIN;
  +  close STDOUT;
  +  open STDERR, &quot;&gt;/dev/null&quot;;
  +  setsid(); # to detach
   </PRE>
   <P>
  -If you run <CODE>./configure</CODE> from apache source do not forget to add:
  -<CODE>--enable-shared=perl</CODE>
  -
  +At this point, <CODE>program.pl</CODE> is running in the ``background'' while the <CODE>system()</CODE> returns
  +and permits apache to get on with life.
   
  +<P>
  +This has obvious problems. Not the least of which is that
  +<CODE>$params</CODE> must not be bigger then whatever your architecture's
  +limit is (could depend on your shell).
   
   <P>
  -Then just add the <CODE>LoadModule</CODE> into your <CODE>httpd.conf</CODE>.
  +Also, the communication is only one way.
   
   <P>
  -You will find a complete explanation in the <CODE>INSTALL.apaci</CODE> pod which can be found in the mod_perl distribution.
  +However, you might want be trying to do the ``wrong thing''. If what you
  +want is to send information to the browser and then do some
  +post-processing, look into <CODE>PerlCleanupHandler</CODE>.
   
   <P>
  -Some people reported that DSO compiled mod_perl would not run on specific
  -OS/perl version. Also threads enabled perl reported sometimes to break the
  -mod_perl/DSO. But it still can work correctly for you.
  +<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>
  +<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>
  -&lt;META&gt; Incomplete &lt;/META&gt;
  +your generated <CODE>Set-Cookie</CODE> header is split over a number of print statements and gets lost. Try this:
   
   <P>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<CENTER><H1><A NAME="HTTP_Authentication_with_2_serve">HTTP Authentication with 2 servers + proxy</A></H1></CENTER>
  +<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>
  +&lt;META&gt; some leftovers... # =head1 Coding with mod_perl
  +
   <P>
  -Assuming that you have a setup of one ``front-end'' server, which provides
  -proxies the ``back-end'' (mod_perl) server, if you need to perform the
  -athentication in the ``back-end'' server, it should handle all
  -authentication. If Apache proxies correctly, it seems like it would pass
  -through all authentication information, making the ``front-end'' Apache
  -somewhat ``dumb,'' as it does nothing but pass through information.
  +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.
   
   <P>
  -The only possible caveat in config file is that your Auth stuff needs to be
  -in &lt;Directory ...&gt; ... &lt;/Directory&gt; tags because if you use a
  -&lt;Location /&gt; ... &lt;/Location&gt; the proxypass server takes the
  -auth info for its authentication and would not pass it on.
  +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;
   
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
   	     The <a href="http://www.modperl.com/">
  @@ -3168,7 +3232,7 @@
   	     Amazon.com</a>.
   
   	     <HR>
  -	     [    <A HREF="strategy.html">Prev</A> |      <A HREF="index.html">Main Page</A> | <A HREF="install.html">Next</A>      ]
  +	     [    <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%" >
   <TR ALIGN=CENTER VALIGN=TOP>
  @@ -3181,7 +3245,7 @@
       <B>
         <FONT SIZE=-1>
   	     Written by <A HREF="help.html#This_document_s_Author">Stas Bekman</A>.
  -	     <BR>Last Modified at 06/19/1999
  +	     <BR>Last Modified at 06/26/1999
         </FONT>
       </B>
     </TD>
  @@ -3208,7 +3272,7 @@
   <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
   <HTML>
   <HEAD>
  -   <TITLE>mod_perl guide: Installation Notes</TITLE>
  +   <TITLE>mod_perl guide: Performance. Benchmarks.</TITLE>
      <META NAME="GENERATOR" CONTENT="Pod2HTML [Perl/Linux]">
      <META NAME="Author" CONTENT="Stas Bekman">
      <META NAME="Description" CONTENT="All Apache/Perl related information: Hints, Guidelines, Scenarios and Troubleshottings">
  @@ -3227,41 +3291,52 @@
   <H1 ALIGN=CENTER>
   <A HREF="http://perl.apache.org"><IMG SRC="images/mod_perl.gif" ALT="Mod Perl Icon" BORDER=0 HEIGHT=30 WIDTH=90 ALIGN=LEFT></A>
   <A HREF="http://perl.apache.org"><IMG SRC="images/mod_perl.gif" ALT="Mod Perl Icon" BORDER=0 HEIGHT=30 WIDTH=90 ALIGN=RIGHT></A>
  -Installation Notes</H1>
  +Performance. Benchmarks.</H1>
   <HR WIDTH="100%">
  -	    [    <A HREF="scenario.html">Prev</A> |      <A HREF="index.html">Main Page</A> | <A HREF="config.html">Next</A>      ]<HR><!-- INDEX BEGIN -->
  +	    [    <A HREF="porting.html">Prev</A> |      <A HREF="index.html">Main Page</A> | <A HREF="strategy.html">Next</A>      ]<HR><!-- INDEX BEGIN -->
   <P><B><FONT SIZE=-1>Table of Contents:</FONT></B></P>
   <UL>
   
  -	<LI><A HREF="#Configuration_and_Installation">Configuration and Installation</A>
  +	<LI><A HREF="#Performance_The_Overall_picture">Performance: The Overall picture</A>
  +	<LI><A HREF="#Sharing_Memory">Sharing Memory</A>
  +	<LI><A HREF="#Preload_Perl_modules_at_server_s">Preload Perl modules at server startup</A>
   	<UL>
   
  -		<LI><A HREF="#Perl">Perl</A>
  -		<LI><A HREF="#Apache">Apache</A>
  -		<LI><A HREF="#Mod_Perl">Mod_Perl</A>
  +		<LI><A HREF="#Preload_Perl_modules_Real_Numb">Preload Perl modules - Real Numbers</A>
   	</UL>
   
  -	<LI><A HREF="#How_can_I_tell_whether_mod_perl_">How can I tell whether mod_perl is really installed</A>
  +	<LI><A HREF="#Preload_Registry_Scripts">Preload Registry Scripts</A>
  +	<LI><A HREF="#Avoid_Importing_Functions">Avoid Importing Functions</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 (and where)</A>
  +	<LI><A HREF="#Limiting_the_size_of_the_process">Limiting the size of the processes</A>
  +	<LI><A HREF="#Limiting_the_resources_used_by_h">Limiting the resources used by httpd children</A>
  +	<LI><A HREF="#Limiting_the_request_rate_speed_">Limiting the request rate speed (robots blocking)</A>
  +	<LI><A HREF="#Benchmarks_Impressing_your_Boss">Benchmarks. Impressing your Boss and Colleagues.</A>
   	<UL>
   
  -		<LI><A HREF="#Testing_by_checking_the_error_lo">Testing by checking the error_log file</A>
  -		<LI><A HREF="#Testing_by_viewing_perl_status">Testing by viewing /perl-status</A>
  -		<LI><A HREF="#Testing_via_telnet">Testing via telnet</A>
  -		<LI><A HREF="#Testing_via_a_CGI_script">Testing via a CGI script</A>
  -		<LI><A HREF="#Testing_via_lwp_request">Testing via lwp-request</A>
  +		<LI><A HREF="#Developers_Talk">Developers Talk</A>
  +		<LI><A HREF="#Benchmarking_a_Graphic_hits_coun">Benchmarking a Graphic hits counter with Persistent DB Connection</A>
  +		<LI><A HREF="#Benchmarking_scripts_with_execut">Benchmarking scripts with execution times below 1 second :)</A>
  +		<LI><A HREF="#PerlHandler_s_Benchmarking">PerlHandler's Benchmarking</A>
   	</UL>
   
  -	<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_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>
  +	<LI><A HREF="#Tuning_the_Apache_s_configuratio">Tuning the Apache's configuration variables for the best performance</A>
   	<UL>
   
  -		<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>
  +		<LI><A HREF="#Tuning_with_ab_ApacheBench">Tuning with ab - ApacheBench </A>
  +		<LI><A HREF="#Tuning_with_crashme_script">Tuning with crashme script</A>
  +		<LI><A HREF="#Choosing_MaxClients">Choosing MaxClients</A>
  +		<LI><A HREF="#Choosing_MaxRequestsPerChild">Choosing MaxRequestsPerChild</A>
  +		<LI><A HREF="#Choosing_MinSpareServers_MaxSpa">Choosing MinSpareServers, MaxSpareServers and StartServers</A>
  +		<LI><A HREF="#Summary_of_Benchmarking_to_tune_">Summary of Benchmarking to tune all 5 parameters</A>
   	</UL>
   
  -	<LI><A HREF="#Stripping_apache_to_make_it_almo">Stripping apache to make it almost perl-server</A>
  +	<LI><A HREF="#Persistent_DB_Connections">Persistent DB Connections</A>
  +	<LI><A HREF="#Using_1_under_mod_perl_and_be">Using $|=1 under mod_perl and better print() techniques.</A>
  +	<LI><A HREF="#More_Reducing_Memory_Usage_Tips">More Reducing Memory Usage Tips</A>
  +	<LI><A HREF="#Profiling">Profiling</A>
  +	<LI><A HREF="#CGI_pm_s_object_methods_calls_vs">CGI.pm's object methods calls vs. function calls</A>
  +	<LI><A HREF="#Sending_plain_HTML_as_a_compress">Sending plain HTML as a compressed output</A>
   </UL>
   <!-- INDEX END -->
   
  @@ -3279,1336 +3354,1798 @@
   
   	      <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>
  -<P>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<CENTER><H2><A NAME="Perl">Perl</A></H2></CENTER>
  -<P>
  -First install perl. Follow the instructions in the distribution's INSTALL
  -file. During the configuration stage (while running
  -<CODE>./Configure</CODE>), make sure you answer <CODE>YES</CODE> to:
  -
  -<P>
  -<PRE>  Do you wish to use dynamic loading? [y]
  -</PRE>
  +<CENTER><H1><A NAME="Performance_The_Overall_picture">Performance: The Overall picture</A></H1></CENTER>
   <P>
  -Answer <CODE>y</CODE> to be able to load dynamically Perl Modules extensions.
  +Before we dive into performance issues, there is something very important
  +to understand. It applies to any webserver, not only apache. All the
  +efforts are made to make user's web browsing experience a swift. Among
  +other web site usability factors, speed is one of the most crucial ones.
  +What is a correct speed measurement? Since user is the one that interacts
  +with web site, speed measurement is a time passed from the moment user
  +follows a link or presses a submit button till the resulting page is being
  +rendered by her browser. So if we trace the data packet's movement as it
  +leaves user's machine (request sent) till the reply arrives, the packet
  +travels through many entities on its way. It has to make its way through
  +the network, passing many interconnection nodes, before it enters the
  +target machine it might go through proxy (accelerator) servers, then it's
  +being served by your server, and finally it has to make the whole way back.
  +A webserver is only one of the elements the packet sees on its way. You
  +could work hard to fine tune your webserver for the best performance, but a
  +slow NIC (Network Interface Card) or slow network connection from your
  +server might defeat it all. That's why it's important to think big and to
  +be aware of possible bottlenecks between the server and the web. Of course
  +there is nothing you can do if user has a slow connection on its behalf.
  +
  +<P>
  +From the other side, you might tune your scripts and webserver to process
  +incoming requests ultra fast, so you will need a little number of working
  +servers, but you might find out that server processes are busy waiting for
  +slow clients to complete the download. You will see more examples in this
  +chapter. My point is that a web service is like car, if one of the details
  +or mechanisms is broken the car will not drive smoothly and it can even
  +stop dead if pushed further without first fixing it.
   
   <P>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<CENTER><H2><A NAME="Apache">Apache</A></H2></CENTER>
  +<CENTER><H1><A NAME="Sharing_Memory">Sharing Memory</A></H1></CENTER>
   <P>
  -It is a good idea to try to install the Apache webserver without mod_perl
  -first. This way, if something going wrong, you will know that it's not the
  -Apache server's problem. But you can skip this stage if you already have a
  -working (non-mod_perl) Apache server, or if you are just the daring type.
  -In any case you should unpack the Apache source distribution, preferably at
  -the same level as the mod_perl distribution.
  +A very important point is the sharing of memory. If your OS supports this
  +(and most sane systems do), you might save more memory by sharing it
  +between child processes. This is only possible when you preload code at
  +server startup. However during a child process' life, its memory pages
  +becomes unshared and there is no way we can control perl to make it
  +allocate memory so (dynamic) variables land on different memory pages than
  +constants, that's why the <STRONG>copy-on-write</STRONG> effect (will explain in a moment) will hit almost at random. If you are
  +pre-loading many modules you might be able to balance the memory that stays
  +shared against the time for an occasional fork by tuning the
  +<CODE>MaxRequestsPerChild</CODE> to a point where you restart before too much becomes unshared. In this case
  +the <CODE>MaxRequestsPerChild</CODE> is very specific to your scenario. You should do some measurements and you
  +might see if this really makes a difference and what a reasonable number
  +might be. Each time a child reaches this upper limit and restarts it should
  +release the unshared copies and the new child will inherit pages that are
  +shared until it scribbles on them.
   
  -<P>
  -<PRE>  % ls -l /usr/src
  -  drwxr-xr-x   8 stas  bar         2048 Oct  6 09:46 apache_1.3.6/
  -  drwxr-xr-x  19 stas  bar         4096 Oct  2 14:33 mod_perl-1.19/
  -</PRE>
   <P>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<CENTER><H2><A NAME="Mod_Perl">Mod_Perl</A></H2></CENTER>
  -<P>
  -Now we come to the main point of this document.
  +It is very important to understand that your goal is not to have
  +<CODE>MaxRequestsPerChild</CODE> to be 10000. Having a child serving 300 requests on precompiled code is
  +already a huge speedup, so if it is 100 or 10000 it does not really matter
  +if it saves you the RAM by sharing. Do not forget that if you preload most
  +of your code at the server startup, the fork to spawn a new child will be
  +very very fast, because it inherits most of the preloaded code and the perl
  +interpreter from the parent process. But then during the work of the child,
  +its memory pages (which aren't really its yet, it uses the parent's pages)
  +are getting dirty (originally inherited and shared variables are getting
  +updated/modified) and the <STRONG>copy-on-write</STRONG>
  +happens, which reduces the number of shared memory pages - thus enlarging
  +the memory demands. Killing the child and respawning a new one, allows to
  +get the pristine shared memory from the parent process again.
   
   <P>
  -Here I will give only a short example of mod_perl installation. You should
  -read the <A HREF="././scenario.html#">Real World Scenarios Implementaion</A> for a more complete description.
  +The conclusion is that <CODE>MaxRequestsPerChild</CODE> should not be too big, otherwise you loose the benefits of the memory
  +sharing.
   
   <P>
  -As with any perl package, the installation of mod_perl is very easy and
  -standard. <CODE>perldoc INSTALL</CODE> will guide you thru the configuration and installation process.
  +See <A HREF="././performance.html#Choosing_MaxRequestsPerChild">Choosing MaxRequestsPerChild</A> for more about tuning the <CODE>MaxRequestsPerChild</CODE> parameter.
   
   <P>
  -The fastest way to install would be:
  +<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<CENTER><H1><A NAME="Preload_Perl_modules_at_server_s">Preload Perl modules at server startup</A></H1></CENTER>
  +<P>
  +Use the <CODE>PerlRequire</CODE> and <CODE>PerlModule</CODE> directives to load commonly used modules such as <CODE>CGI.pm</CODE>, <CODE>DBI</CODE> and etc., when the server is started. On most systems, server children will
  +be able to share the code space used by these modules. Just add the
  +following directives into <CODE>httpd.conf</CODE>:
   
   <P>
  -<PRE>  % perl Makefile.PL APACHE_SRC=../apache_1.3.6/src \
  -    DO_HTTPD=1  USE_APACI=1 PERL_MARK_WHERE=1 EVERYTHING=1
  -  % make &amp;&amp; make test &amp;&amp; make install
  +<PRE>  PerlModule CGI;
  +  PerlModule DBI;
   </PRE>
   <P>
  -(Note: if you use an apache version different then apache_1.3.6, change the
  -version number in the example above and in all later examples
  -appropriately)
  +But even a better approach is to create a separate startup file (where you
  +code in plain perl) and put there things like:
   
   <P>
  -To change the installation target (either if you are not <CODE>root</CODE> or you need to install a second copy for testing purposes), assuming you
  -use /foo/server as a base directory root, you have to run this:
  +<PRE>  use DBI;
  +  use Carp;
  +</PRE>
  +<P>
  +Then you <CODE>require()</CODE> this startup file with help of <CODE>PerlRequire</CODE>
  +directive from <CODE>httpd.conf</CODE>, by placing it before the rest of the mod_perl configuration directives:
   
   <P>
  -<PRE>  % perl Makefile.PL APACHE_SRC=../apache_1.3.6/src \
  -    DO_HTTPD=1 PERL_MARK_WHERE=1 EVERYTHING=1 \
  -    APACHE_PREFIX=/foo/server PREFIX=/foo/server
  +<PRE>  PerlRequire /path/to/start-up.pl
   </PRE>
   <P>
  -Where <CODE>PREFIX</CODE> specifies where to install the perl modules,
  -<CODE>APACHE_PREFIX</CODE> - the same for the apache files.
  +<CODE>CGI.pm</CODE> is a special case. Ordinarily <CODE>CGI.pm</CODE> autoloads most of its functions on an as-needed basis. This speeds up the
  +loading time by deferring the compilation phase. However, if you are using
  +mod_perl, FastCGI or another system that uses a persistent Perl
  +interpreter, you will want to precompile the methods at initialization
  +time. To accomplish this, call the package function <CODE>compile()</CODE>
  +like this:
   
   <P>
  -The next step is to configure the mod_perl sections of the apache conf
  -files. See <A HREF="././config.html#">ModPerlConfiguration</A>
  -
  -
  +<PRE>    use CGI ();
  +    CGI-&gt;compile(':all');
  +</PRE>
  +<P>
  +The arguments to <CODE>compile()</CODE> are a list of method names or sets, and are identical to those accepted by
  +the <CODE>use()</CODE> and <CODE>import()</CODE>
  +operators. Note that in most cases you will want to replace <CODE>':all'</CODE>
  +with tag names you really use in your code, since generally only a subset
  +of subs is actually being used.
   
   <P>
  -Fire up the server with <CODE>/foo/server/sbin/apachectl start</CODE>, Watch the error log file if server does not start up (No error message
  -will be printed to the console!)
  +You can also preload the Registry scripts. See <A HREF="#Preload_Registry_Scripts">Preload Registry Scripts</A>.
   
   <P>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<CENTER><H1><A NAME="How_can_I_tell_whether_mod_perl_">How can I tell whether mod_perl is really installed</A></H1></CENTER>
  +<CENTER><H2><A NAME="Preload_Perl_modules_Real_Numb">Preload Perl modules - Real Numbers</A></H2></CENTER>
   <P>
  -There a few ways. In older versions of apache ( &lt; 1.3.6 ?) you could check that by running <CODE>httpd -v</CODE>, it no longer works. Now you should use <CODE>httpd -l</CODE>. Please notice that it is not enough to have it installed - you should of
  -course configure it and restart the server.
  +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
  +few of them (to see more memory saved) and also the effect of precompiling
  +the Registry modules with <CODE>Apache::RegistryLoader</CODE>.
   
  -<P>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<CENTER><H2><A NAME="Testing_by_checking_the_error_lo">Testing by checking the error_log file</A></H2></CENTER>
   <P>
  -When starting the server, just check the <CODE>error_log</CODE> file for this:
  +1. In the first test, the following script was used:
   
   <P>
  -<PRE>  [Thu Dec  3 17:27:52 1998] [notice] Apache/1.3.1 (Unix) mod_perl/1.15 configured
  -                                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  -   -- resuming normal operations
  +<PRE>  use strict;
  +  use CGI ();
  +  my $q = new CGI;
  +  print $q-&gt;header;
  +  print $q-&gt;start_html,$q-&gt;p(&quot;Hello&quot;);
   </PRE>
   <P>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<CENTER><H2><A NAME="Testing_by_viewing_perl_status">Testing by viewing /perl-status</A></H2></CENTER>
  +<STRONG>Server restarted</STRONG>
  +
  +
  +
   <P>
  -Assuming that you have configured the &lt;<CODE>Location /perl-status</CODE>&gt;
  -Section in the server configuration file (refer to
  -<A HREF="././config.html#">ModPerlConfiguration</A>), fetch: <A
  -HREF="http://www.yourserver.com/perl-status">http://www.yourserver.com/perl-status</A>
  -using your favorite Netscape browser :-)
  +Before the <CODE>CGI.pm</CODE> preload: (No other modules preloaded)
   
   <P>
  -You should see something like this:
  +<PRE>  USER        PID %CPU %MEM   SZ  RSS    TTY STAT    STIME  TIME COMMAND
  +  root      87004  0.0  0.0 1060 1524      - A    16:51:14  0:00 httpd
  +  httpd    240864  0.0  0.0 1304 1784      - A    16:51:13  0:00 httpd
  +</PRE>
  +<P>
  +After running a script which uses CGI's methods (no imports):
   
   <P>
  -<PRE>  Embedded Perl version 5.00502 for Apache/1.3.1 (Unix) mod_perl/1.19 
  -  process 50880, running since Tue Oct 6 14:31:45 1998
  +<PRE>  USER        PID %CPU %MEM   SZ  RSS    TTY STAT    STIME  TIME COMMAND
  +  root     188068  0.0  0.0 1052 1524      - A    17:04:16  0:00 httpd
  +  httpd     86952  0.0  1.0 2520 3052      - A    17:04:16  0:00 httpd
   </PRE>
   <P>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<CENTER><H2><A NAME="Testing_via_telnet">Testing via telnet</A></H2></CENTER>
  +Observation: child httpd has grown up by 1268K
  +
   <P>
  -Knowing the port you have configured Apache to listen on, you can use
  -<CODE>telnet</CODE> to talk directly to the web server.
  +<STRONG>Server restarted</STRONG>
   
  +
  +
   <P>
  -Assuming that your mod_perl enabled server listens to port 8080, telnet to
  -your server at port 8080, and type <CODE>HEAD / HTTP/1.0</CODE> then press the &lt;ENTER&gt; key TWICE!
  +After the <CODE>CGI.pm</CODE> preload:
   
   <P>
  -<PRE>  % telnet yourserver.com 8080&lt;ENTER&gt;
  -  HEAD / HTTP/1.0&lt;ENTER&gt;&lt;ENTER&gt;
  +<PRE>  USER        PID %CPU %MEM   SZ  RSS    TTY STAT    STIME  TIME COMMAND
  +  root     240796  0.0  0.0 1456 1552      - A    16:55:30  0:00 httpd
  +  httpd     86944  0.0  0.0 1688 1800      - A    16:55:30  0:00 httpd
   </PRE>
   <P>
  -You should see a response like this:
  +after running a script which uses CGI's methods (no imports):
   
   <P>
  -<PRE>  HTTP/1.1 200 OK
  -  Date: Tue, 01 Dec 1998 12:27:52 GMT
  -  Server: Apache/1.3.6 (Unix) mod_perl/1.19
  -  Connection: close
  -  Content-Type: text/html
  -  
  -  Connection closed.
  +<PRE>  USER        PID %CPU %MEM   SZ  RSS    TTY STAT    STIME  TIME COMMAND
  +  root      86872  0.0  0.0 1448 1552      - A    17:02:56  0:00 httpd
  +  httpd    187996  0.0  1.0 2808 2968      - A    17:02:56  0:00 httpd
   </PRE>
   <P>
  -So you see <CODE>Server: Apache/1.3.6 (Unix) mod_perl/1.19</CODE> - which says that you <STRONG>do</STRONG> have mod_perl installed and it is version 1.19. Of course in your case it
  -would be the version you have installed.
  +Observation: child httpd has grown up by 1168K, 100K less then without
  +preload - good!
   
   <P>
  -However, just because you have got mod_perl linked in there, that does not
  -mean that you have configured your server to handle Perl scripts with
  -mod_perl. You will find the configuration assistance at
  -<A HREF="././config.html#">ModPerlConfiguration</A>
  +<STRONG>Server restarted</STRONG>
   
   
   
  -<P>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<CENTER><H2><A NAME="Testing_via_a_CGI_script">Testing via a CGI script</A></H2></CENTER>
   <P>
  -Another method is to invoke a CGI script which dumps the server's
  -environment.
  +After <CODE>CGI.pm</CODE> preloaded and compiled with CGI-&gt;compile(':all');
   
   <P>
  -Copy and paste the script below (no need for perl line!). Let's say you
  -called it test.pl, you saved it into the root of the cgi scripts, and cgi
  -root is mapped directly to /perl of your server.
  -
  -<P>
  -<PRE>  print &quot;Content-type: text/html\n\n&quot;;
  -  print &quot;Server's environment&lt;P&gt;\n&quot;;
  -  print &quot;&lt;TABLE&gt;&quot;;
  -  foreach ( keys %ENV ) {
  -      print &quot;&lt;TR&gt;&lt;TD&gt;$_ &lt;/TD&gt;&lt;TD&gt;$ENV{$_}&lt;/TR&gt;&lt;/TD&gt;&quot;;
  -  }
  -  print &quot;&lt;/TABLE&gt;&quot;;
  +<PRE>  USER        PID %CPU %MEM   SZ  RSS    TTY STAT    STIME  TIME COMMAND
  +  root      86980  0.0  0.0 2836 1524      - A    17:05:27  0:00 httpd
  +  httpd    188104  0.0  0.0 3064 1768      - A    17:05:27  0:00 httpd
   </PRE>
   <P>
  -Make it executable:
  +After running a script which uses CGI's methods (no imports):
   
   <P>
  -<PRE>  % chmod a+x test.pl
  +<PRE>  USER        PID %CPU %MEM   SZ  RSS    TTY STAT    STIME  TIME COMMAND
  +  root      86980  0.0  0.0 2828 1524      - A    17:05:27  0:00 httpd
  +  httpd    188104  0.0  1.0 4188 2940      - A    17:05:27  0:00 httpd
   </PRE>
   <P>
  -Now fetch the URL <CODE>http://www.you.com:8080/perl/test.pl</CODE> (replace 8080 with the port your mod_perl enabled server is listening to.
  -You should see something like this (part of the output was snipped).
  +Observation: child httpd has grown up by 1172K No change! So what does
  +CGI-&gt;compile(':all') help? I think it's because we never use all of the
  +methods CGI provides - so in real use it's faster. So you might want to
  +compile only the tags you are about to use - then you will benefit for
  +sure.
   
   <P>
  -<PRE>  SERVER_SOFTWARE    Apache/1.3.6 (Unix) mod_perl/1.19
  -  GATEWAY_INTERFACE  CGI-Perl/1.1
  -  REQUEST_METHOD     GET
  -  HTTP_ACCEPT        image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, */*
  -  MOD_PERL           1.19
  -  REQUEST_URI        /perl/test.pl
  -  SCRIPT_NAME        /perl/test.pl
  -  [...snipped]
  +2. I have tried the second test to find it. I run the script:
  +
  +<P>
  +<PRE>  use strict;
  +  use CGI qw(:all);
  +  print header,start_html,p(&quot;Hello&quot;);
   </PRE>
   <P>
  -Now if I run the same script in mod_cgi mode (configured with /cgi-bin)
  -(you will need to add the perl line <CODE>#!/bin/perl</CODE> for the above script) and fetch <CODE>http://www.you.com/cgi-bin/test.pl</CODE>.
  +<STRONG>Server restarted</STRONG>
  +
   
  +
   <P>
  -<PRE>  SERVER_SOFTWARE   Apache/1.3.6 (Unix)
  -  GATEWAY_INTERFACE CGI/1.1
  -  [...snipped]
  +After <CODE>CGI.pm</CODE> was preloaded and NOT compiled with CGI-&gt;compile(':all'):
  +
  +<P>
  +<PRE>  USER        PID %CPU %MEM   SZ  RSS    TTY STAT    STIME  TIME COMMAND
  +  root      17268  0.0  0.0 1456 1552      - A    18:02:49  0:00 httpd
  +  httpd     86904  0.0  0.0 1688 1800      - A    18:02:49  0:00 httpd
   </PRE>
   <P>
  -You will see that two variables, <CODE>SERVER_SOFTWARE</CODE> and
  -<CODE>GATEWAY_INTERFACE</CODE>, are different from the case above. This gives you a hint of how to tell
  -in what mode you are running in your cgi scripts. I start all my cgi
  -scripts that are mod_perl aware with:
  +After running a script which imports symbols (all of them):
   
   <P>
  -<PRE>  BEGIN {
  -      # Auto-detect if we are running under mod_perl or CGI.
  -    $USE_MOD_PERL = ((exists $ENV{'GATEWAY_INTERFACE'}
  -                  and $ENV{'GATEWAY_INTERFACE'} =~ /CGI-Perl/)
  -                   or exists $ENV{'MOD_PERL'} );
  -      # perl5.004 is a must under mod_perl
  -    require 5.004 if $USE_MOD_PERL;
  -  }
  +<PRE>  USER        PID %CPU %MEM   SZ  RSS    TTY STAT    STIME  TIME COMMAND
  +  root      17268  0.0  0.0 1448 1552      - A    18:02:49  0:00 httpd
  +  httpd     86904  0.0  1.0 2952 3112      - A    18:02:49  0:00 httpd
   </PRE>
   <P>
  -You might wonder why in the world you would need to know in what mode you
  -are running. For example you will want to use <CODE>Apache::exit()</CODE>
  -and not <CODE>CORE::exit()</CODE> in your scripts, but if you think that your script might be used in both
  -environments (mod_cgi vs. mod_perl), you will have to override the <CODE>exit()</CODE> subroutine and to make the runtime decision of what method you will use.
  -For reasons and implementations see: <A HREF="././porting.html#Using_exit_">Using exit()</A> and the whole <A HREF="././porting.html#">Writing Mod Perl scripts and Porting plain CGIs to it</A> page.
  +Observation: child httpd has grown up by 1264K
   
  -<P>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<CENTER><H2><A NAME="Testing_via_lwp_request">Testing via lwp-request</A></H2></CENTER>
   <P>
  -Yet another one. Why do I show all these approaches? While here they are
  -serving a very simple purpose, they can be helpful in other situations.
  +<STRONG>Server restarted</STRONG>
  +
   
  +
   <P>
  -Assuming you have the libwww-perl (LWP) package installed (you will need it
  -installed in order to pass mod_perl's <CODE>make test</CODE> anyway):
  +After <CODE>CGI.pm</CODE> was preloaded and compiled with CGI-&gt;compile(':all'):
   
   <P>
  -<PRE>  % lwp-request -e -d www.site.com
  +<PRE>  USER        PID %CPU %MEM   SZ  RSS    TTY STAT    STIME  TIME COMMAND
  +  root      86812  0.0  0.0 2836 1524      - A    17:59:52  0:00 httpd
  +  httpd     99104  0.0  0.0 3064 1768      - A    17:59:52  0:00 httpd
   </PRE>
   <P>
  -Will show you all the headers. (The <CODE>-d</CODE> option disables printing the response content.)
  +After running a script which imports symbols (all of them):
   
   <P>
  -<PRE>  % lwp-request -e -d www.site.com | egrep '^Server:'
  +<PRE>  USER        PID %CPU %MEM   SZ  RSS    TTY STAT    STIME  TIME COMMAND
  +  root      86812  0.0  0.0 2832 1436      - A    17:59:52  0:00 httpd
  +  httpd     99104  0.0  1.0 4884 3636      - A    17:59:52  0:00 httpd
   </PRE>
   <P>
  -To see the server's version only.
  +Observation: child httpd has grown by 1868K. Why? Isn't
  +<CODE>CGI::compile(':all')</CODE> supposed to make children to share the compiled code with parent? It does
  +works as advertised, but if you pay attention in the code we have called
  +only three <CODE>CGI.pm</CODE>'s methods - just saying <CODE>use CGI qw(:all)</CODE> doesn't mean we compile the all available methods - we just import their
  +names. So actually this test is misleading. Execute <CODE>compile()</CODE> only on the methods you are actually using and then you will see the
  +difference.
   
   <P>
  -Again use <CODE>www.site.com:port_number</CODE> if your server is listening to a non-default 80 port.
  +3. The third script:
   
   <P>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<CENTER><H1><A NAME="Is_it_possible_to_install_and_us">Is it possible to install and use apache/mod_perl without having a root access?</A></H1></CENTER>
  +<PRE>  use strict;
  +  use CGI;
  +  use Data::Dumper;
  +  use Storable;
  +  [and many lines of code, lots of globals - so the code is huge!]
  +</PRE>
   <P>
  -Yes, no problem with that. Follow the instructions above and when you
  -encounter APACI_ARGS use your home directory (or some other directory which
  -you have write access to as a prefix, for example,
  -<CODE>/home/stas/www</CODE>) and everything will be installed there. There is a chance that some perl
  -libs will be not installed on your server by root and you will have to
  -install these locally too. See the <A
  -HREF="http://www.singlesheaven.com/stas/TULARC/webmaster/myfaq.html#7">http://www.singlesheaven.com/stas/TULARC/webmaster/myfaq.html#7</A>
  -for more information on local perl installations.
  +<STRONG>Server restarted</STRONG>
  +
  +
   
   <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.you.com:8080</CODE> in that case, but that is not a problem since generally users do not
  -directly access URLs to CGI scripts, but rather are directed to them from a
  -link on a web page or as the '<CODE>ACTION</CODE>' of an HTML form, so they should not know at all that the port is
  -different from the default port 80.
  +Nothing preloaded at startup:
   
   <P>
  -If you want your Apache server to start automatically on system reboot, you
  -will need to invoke the server startup script from somewhere within the
  -init scripts on your host. (This is often somewhere under <CODE>/etc/rc.d</CODE>, but this path can vary depending upon the flavor of Unix you are using.)
  +<PRE>  USER        PID %CPU %MEM   SZ  RSS    TTY STAT    STIME  TIME COMMAND
  +  root      90962  0.0  0.0 1060 1524      - A    17:16:45  0:00 httpd
  +  httpd     86870  0.0  0.0 1304 1784      - A    17:16:45  0:00 httpd
  +</PRE>
  +<P>
  +Script using CGI (methods), Storable, Data::Dumper called:
   
  +<P>
  +<PRE>  USER        PID %CPU %MEM   SZ  RSS    TTY STAT    STIME  TIME COMMAND
  +  root      90962  0.0  0.0 1064 1436      - A    17:16:45  0:00 httpd
  +  httpd     86870  0.0  1.0 4024 4548      - A    17:16:45  0:00 httpd
  +</PRE>
   <P>
  -One more important thing to keep in mind is system resources. Mod_perl is
  -memory hungry -- if you run a lot of mod_perl processes on that machine
  -(and it's not your own host...), most likely the system administrator of
  -the host will ask you to shutdown your mod_perl server, or to find another
  -home for it. You have a few solutions:
  +Observation: child httpd has grown by 2764K
   
  -<UL>
  -<P><LI>
   <P>
  -Reduce resource usage - see <A HREF="././performance.html#Limiting_the_size_of_the_process">Limiting the size of the processes</A>
  +<STRONG>Server restarted</STRONG>
   
   
   
  -<P><LI>
   <P>
  -Ask your ISP if you can put a dedicated machine into their computer room
  -and be root there.
  +Preloaded CGI (compiled), Storable, Data::Dumper at startup:
   
  -<P><LI>
   <P>
  -Look for another ISP with lots of resources or one that supports mod_perl.
  +<PRE>  USER        PID %CPU %MEM   SZ  RSS    TTY STAT    STIME  TIME COMMAND
  +  root      26792  0.0  0.0 3120 1528      - A    17:19:21  0:00 httpd
  +  httpd     91052  0.0  0.0 3340 1764      - A    17:19:21  0:00 httpd
  +</PRE>
  +<P>
  +Script using CGI (methods), Storable, Data::Dumper called
   
  -</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_determine_whic">Is it possible to determine which options were given to modperl's Makefile.PL</A></H1></CENTER>
  +<PRE>  USER        PID %CPU %MEM   SZ  RSS    TTY STAT    STIME  TIME COMMAND
  +  root      26792  0.0  0.0 3124 1440      - A    17:19:21  0:00 httpd
  +  httpd     91052  0.0  1.0 6568 5040      - A    17:19:21  0:00 httpd
  +</PRE>
   <P>
  -It is possible to determine which options were given to modperl's
  -<CODE>Makefile.PL</CODE> during the configuration stage, so to be used later in recreating the same
  -build tree when rebuilding the server. This is relevant only if did not use
  -the default config parameters and altered some of them during the
  -configuration stage.
  +Observation: child httpd has grown by 3276K. Great difference: 512K less!!!
   
   <P>
  -I was into this problem many times. I am going to build something by
  -passing some non default parameters to the config script and then later
  -when I need to rebuild the tool either to upgrade it or to make an
  -identical copy at some other machine, I have found that I do not remember
  -what parameters did I altered.
  +<STRONG>Server restarted</STRONG>
   
  -<P>
  -The best solution for this problem is to prepare the run file with all the
  -parameters that are about to be used and then run it instead of typing it
  -all by hand. So later I will have the script handy to be reused.
  +
   
   <P>
  -mod_perl suggests using the <CODE>makepl_args.mod_perl</CODE> file which comes with mod_perl distribution. This is the file you specify
  -all the parameters you are going to use.
  +All the above modules + the above script PreCompiled with
  +<CODE>Apache::RegistryLoader</CODE> at startup:
   
   <P>
  -But if you have found yourself with a compiled tool and no traces of the
  -specified parameters left, you can still find them out if the sources were
  -not <CODE>make clean</CODE>'d. So you will find the apache specific parameters in <CODE>apache_x.x.x/config.status</CODE> and modperl's at in <CODE>mod_perl_x.xx/apaci/mod_perl.config</CODE>.
  +<PRE>  USER        PID %CPU %MEM   SZ  RSS    TTY STAT    STIME  TIME COMMAND
  +  root      43224  0.0  0.0 3256 1528      - A    17:23:12  0:00 httpd
  +  httpd     26844  0.0  0.0 3488 1776      - A    17:23:12  0:00 httpd
  +</PRE>
  +<P>
  +Script using CGI (methods), Storable, Data::Dumper called:
   
   <P>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<CENTER><H1><A NAME="Server_Installation_problems">Server Installation problems</A></H1></CENTER>
  +<PRE>  USER        PID %CPU %MEM   SZ  RSS    TTY STAT    STIME  TIME COMMAND
  +  root      43224  0.0  0.0 3252 1440      - A    17:23:12  0:00 httpd
  +  httpd     26844  0.0  1.0 6748 5092      - A    17:23:12  0:00 httpd
  +</PRE>
   <P>
  -<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>
  +Observation: child httpd has grown even more 3316K ! Does not seem to be
  +good!
  +
   <P>
  -There are two configuration parameters <CODE>PREP_HTTPD</CODE> and <CODE>DO_HTTPD</CODE>
  -you can use in <CODE>perl Makefile.PL [options]</CODE>.
  +<STRONG>Summary</STRONG>:
  +
  +<P>
  +1. Library Perl Modules Preloading gave good results everywhere.
   
   <P>
  -<CODE>DO_HTTPD=1</CODE> means default to 'y' for the two prompts (which source tree to configure
  -against and to build the httpd in that tree).
  -<CODE>PREP_HTTPD=1</CODE> just means default 'n' to the second prompt, meaning, do not build httpd
  -(make) in the Apache source tree.
  +2. <CODE>CGI.pm</CODE>'s <CODE>compile()</CODE> method seems to use even more memory. It's because we never use all of the
  +methods CGI provides. Do <CODE>compile()</CODE>
  +only the tags that you are going to use and you will save the overhead of
  +the first call for each has not yet been called method, and the memory -
  +since compiled code will be shared across all the children.
   
   <P>
  -In other words if you use <CODE>PREP_HTTPD=1</CODE> the httpd will be not build. It will be build only if you use <CODE>DO_HTTPD=1</CODE> option and not use
  -<CODE>PREP_HTTPD=1</CODE>.
  +3. <CODE>Apache::RegistryLoader</CODE> might make scripts load faster on the first request after the child has
  +just started but the memory usage is worse!!! See the numbers by yourself.
   
   <P>
  -If you did not build the httpd, chdir to the apache source, and execute:
  +HW/SW used : The server is apache 1.3.2, mod_perl 1.16 running on AIX 4.1.5
  +RS6000 1G RAM.
   
   <P>
  -<PRE>  make
  -</PRE>
  +<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<CENTER><H1><A NAME="Preload_Registry_Scripts">Preload Registry Scripts</A></H1></CENTER>
   <P>
  -Then return to the mod_perl source and run:
  +<CODE>Apache::RegistryLoader</CODE> compiles <CODE>Apache::Registry</CODE> scripts at server startup. It can be a good idea to preload the scripts you
  +are going to use as well. So the code will be shared among the children.
   
   <P>
  -<PRE>  make test
  -  make install
  +Here is an example of the use of this technique. This code is included in a <CODE>PerlRequire</CODE>'d file, and walks the directory tree under which all registry scripts are
  +installed. For each <CODE>.pl</CODE> file encountered, it calls the <CODE>Apache::RegistryLoader::handler()</CODE> method to preload the script in the parent server (before pre-forking the
  +child processes):
  +
  +<P>
  +<PRE>  use File::Find 'finddepth';
  +  use Apache::RegistryLoader ();
  +  {
  +      my $perl_dir = &quot;perl/&quot;;
  +      my $rl = Apache::RegistryLoader-&gt;new;
  +      finddepth(sub {
  +          return unless /\.pl$/;
  +          my $url = &quot;/$File::Find::dir/$_&quot;;
  +          print &quot;pre-loading $url\n&quot;;
  +  
  +          my $status = $rl-&gt;handler($url);
  +          unless($status == 200) {
  +              warn &quot;pre-load of `$url' failed, status=$status\n&quot;;
  +          }
  +      }, $perl_dir);
  +  }
   </PRE>
   <P>
  -Note that you will have to do the same if you did not pass
  -<CODE>APACHE_PREFIX=/path_to_installation_prefix</CODE> during the <CODE>perl
  -Makefile.PL [options]</CODE> stage.
  +Note that we didn't use the second argument to <CODE>handler()</CODE> here, as module's manpage suggests. To make the loader smarter about the
  +uri-&gt;filename translation, you might need to provide a <CODE>trans()</CODE>
  +function to translate the uri to filename. URI to filename translation
  +normally doesn't happen until HTTP request time, so the module is forced to
  +roll its own translation. If filename is omitted and a <CODE>trans()</CODE> routine was not defined, the loader will try using the URI relative to <STRONG>ServerRoot</STRONG>.
   
  -<P>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<CENTER><H2><A NAME="mod_perl_c_is_incompatible_with_">mod_perl.c is incompatible with this version of apache</A></H2></CENTER>
   <P>
  -You will see this message when you try to run a httpd, if you have had a
  -stale old apache header layout in one of the <CODE>include</CODE> paths. Do
  -<CODE>find</CODE> for <CODE>ap_mmn.h</CODE>, In my case I have had a
  -<CODE>/usr/local/include/ap_mmn.h</CODE> which was installed by RedHat install process. If this is the case get rid
  -of it, and rebuild it again.
  +You have to check whether this makes any improvement for you though, I did
  +some testing [ <A HREF="#Preload_Perl_modules_Real_Numb">Preload Perl modules - Real Numbers</A> ], and it seems that it takes more memory than when the scripts are being
  +called from the child - This is only a first impression and needs better
  +investigation. If you aren't concerned about few script invocations which
  +will take some time to respond while they load the code, you might not need
  +it all!
   
   <P>
  -For all RH fans, before you are going to build the apache by yourself, do: <CODE>rpm -e apache</CODE> to remove the preinstalled one first!
  +See also <A HREF="././porting.html#BEGIN_blocks">BEGIN blocks</A>
   
  +
  +
   <P>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<CENTER><H2><A NAME="Should_I_rebuild_mod_perl_if_I_h">Should I rebuild mod_perl if I have upgraded my perl?</A></H2></CENTER>
  +<CENTER><H1><A NAME="Avoid_Importing_Functions">Avoid Importing Functions</A></H1></CENTER>
   <P>
  -Yes, you should. You have to rebuild mod_perl since it has a hardcoded
  -<CODE>@INC</CODE> which points to the old perl and it is is probably linked to the an old <CODE>libperl</CODE> library. You can try to modify the <CODE>@INC</CODE> in the startup script (if you keep the old perl version around), but it is
  -better to build a fresh one to save you a mess.
  +When possible, avoid importing a module's functions into your name space.
  +The aliases which are created can take up quite a bit of space. Try to use
  +method interfaces and fully qualified
  +<CODE>Package::function</CODE> or <CODE>$Package::variable</CODE> like names instead.
   
   <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>
  +<CENTER><H1><A NAME="How_can_I_find_if_my_mod_perl_sc">How can I find if my mod_perl scripts have memory leaks (and where)</A></H1></CENTER>
   <P>
  -Since most of the functionality that various apache mod_* modules provide
  -is being implemented in <CODE>Apache::{*}</CODE> perl modules, it was reported that one can build an apache server with
  -mod_perl only. If you can reduce the problems down to whatever mod_perl can
  -handle, you can eliminate nearly every other module. Then basically you
  -will have a perl-server, with C code to handle the tricky HTTP bits. The
  -only module you will need to leave in is a <CODE>mod_actions</CODE>.
  -
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -	     The <a href="http://www.modperl.com/">
  -	     <B>Writing Apache Modules with Perl and C</B></a>
  -	     book can be purchased online from <a
  -	     href="http://www.ora.com/catalog/wrapmod/">O'Reilly </a>
  -	     and <a
  -	     href="http://www.amazon.com/exec/obidos/ASIN/156592567X/writinapachemodu">
  -	     Amazon.com</a>.
  +<CODE>Apache::Leak</CODE> (derived from <CODE>Devel::Leak</CODE>) should help you with this task. Example:
   
  -	     <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%" >
  -<TR ALIGN=CENTER VALIGN=TOP>
  -  <TD ALIGN=CENTER VALIGN=CENTER COLSPAN="3">
  -	     <HR>
  -  </TD>
  -</TR>
  -<TR ALIGN=CENTER VALIGN=TOP>
  -  <TD ALIGN=CENTER VALIGN=CENTER>
  -    <B>
  -      <FONT SIZE=-1>
  -	     Written by <A HREF="help.html#This_document_s_Author">Stas Bekman</A>.
  -	     <BR>Last Modified at 06/12/1999
  -      </FONT>
  -    </B>
  -  </TD>
  -
  -  <TD>
  -	     <A HREF="http://perl.apache.org"><IMG SRC="images/mod_perl2.jpg" ALT="Mod Perl Icon" BORDER=0 HEIGHT=59 WIDTH=150></A>
  -  </TD>
  -
  -  <TD>
  -    <FONT SIZE=-2>
  -	     Use of the Camel for Perl is <BR>
  -	     a trademark of <A HREF="http://www.ora.com">O'Reilly &amp; Associates</A>,<BR>
  -             and is used by permission. 
  -    </FONT> 
  -  </TD>
  -</TR>
  -</TABLE></CENTER>
  -
  -</BODY>
  -</HTML>
  -	    
  -
  -<HR SIZE=6>
  -<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
  -<HTML>
  -<HEAD>
  -   <TITLE>mod_perl guide: Server Configuration</TITLE>
  -   <META NAME="GENERATOR" CONTENT="Pod2HTML [Perl/Linux]">
  -   <META NAME="Author" CONTENT="Stas Bekman">
  -   <META NAME="Description" CONTENT="All Apache/Perl related information: Hints, Guidelines, Scenarios and Troubleshottings">
  -   <META NAME="keywords" CONTENT="mod_perl modperl perl apache cgi webserver speed  fast guide mod_perl apache guide help info faq mod_perl installation cgi troubleshooting help no sex speedup free open source OSS mod_perl apache guide">
  -</HEAD>
  -     <LINK REL=STYLESHEET TYPE="text/css"
  -        HREF="style.css" TITLE="refstyle">
  -     <style type="text/css">
  -     <!-- 
  -        @import url(style.css);
  -     -->
  -     
  -     </style>
  -<BODY TEXT="#000000" BGCOLOR="#E0FFFF" LINK="#0000EE" VLINK="#551A8B" ALINK="#FF0000">
  -<A NAME="toc"></A>
  -<H1 ALIGN=CENTER>
  -<A HREF="http://perl.apache.org"><IMG SRC="images/mod_perl.gif" ALT="Mod Perl Icon" BORDER=0 HEIGHT=30 WIDTH=90 ALIGN=LEFT></A>
  -<A HREF="http://perl.apache.org"><IMG SRC="images/mod_perl.gif" ALT="Mod Perl Icon" BORDER=0 HEIGHT=30 WIDTH=90 ALIGN=RIGHT></A>
  -Server Configuration</H1>
  -<HR WIDTH="100%">
  -	    [    <A HREF="install.html">Prev</A> |      <A HREF="index.html">Main Page</A> | <A HREF="frequent.html">Next</A>      ]<HR><!-- INDEX BEGIN -->
  -<P><B><FONT SIZE=-1>Table of Contents:</FONT></B></P>
  -<UL>
  -
  -	<LI><A HREF="#mod_perl_Specific_Configuration">mod_perl Specific Configuration</A>
  -	<UL>
  -
  -		<LI><A HREF="#Alias_Configurations">Alias Configurations</A>
  -		<LI><A HREF="#Location_Configuration">Location Configuration</A>
  -		<LI><A HREF="#PerlFreshRestart">PerlFreshRestart</A>
  -		<LI><A HREF="#_perl_status_location">/perl-status location</A>
  -		<LI><A HREF="#PerlSetVar_PerlSetEnv_and_PerlP">PerlSetVar, PerlSetEnv and PerlPassEnv</A>
  -		<LI><A HREF="#perl_startup_file">perl-startup file</A>
  -		<UL>
  -
  -			<LI><A HREF="#Sample_perl_startup_file">Sample perl-startup file</A>
  -			<LI><A HREF="#What_modules_should_you_add_to_t">What modules should you add to the startup file and why.</A>
  -			<LI><A HREF="#Is_it_possible_to_preopen_a_DB_c">Is it possible to preopen a DB connection at the server startup?</A>
  -			<LI><A HREF="#The_confusion_with_use_clause_">The confusion with use() clause at the server startup?</A>
  -			<LI><A HREF="#The_confusion_with_defining_glob">The confusion with defining globals in startup</A>
  -		</UL>
  -
  -	</UL>
  -
  -	<LI><A HREF="#Running_apachectl_configtest_o">Running 'apachectl configtest' or 'httpd -t'</A>
  -	<LI><A HREF="#Perl_behavior_controls">Perl behavior controls</A>
  -	<LI><A HREF="#Tuning_MinSpareServers_MaxSpareS">Tuning MinSpareServers MaxSpareServers StartServers MaxClients</A>
  -	<LI><A HREF="#Publishing_port_numbers_differen">Publishing port numbers different from 80</A>
  -	<LI><A HREF="#Perl_Sections">Perl Sections</A>
  -	<LI><A HREF="#Configuring_Apache_mod_perl_wi">Configuring Apache + mod_perl with mod_macro</A>
  -	<LI><A HREF="#General_pitfalls">General pitfalls</A>
  -	<UL>
  -
  -		<LI><A HREF="#My_cgi_perl_code_is_being_return">My cgi/perl code is being returned as a plain text instead of being executed by the webserver?</A>
  -		<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="#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>
  -</UL>
  -<!-- INDEX END -->
  -
  -<HR>
  -
  -	     The <a href="http://www.modperl.com/">
  -	     <B>Writing Apache Modules with Perl and C</B></a>
  -	     book can be purchased online from <a
  -	     href="http://www.ora.com/catalog/wrapmod/">O'Reilly </a>
  -	     and <a
  -	     href="http://www.amazon.com/exec/obidos/ASIN/156592567X/writinapachemodu">
  -	     Amazon.com</a>.
  -
  -	     <HR>
  -
  -	      <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>
  +<PRE>  use Apache::Leak;
  +  
  +  my $global = &quot;FooAAA&quot;;
  +  
  +  leak_test {
  +    $$global = 1;
  +    ++$global;
  +  };
  +</PRE>
   <P>
  -The next step after building and installing your new mod_perl-enabled
  -Apache server, is to configure the server's configuration files. To learn
  -how to modify Apache's configuration files, please refer to the
  -documentation included with the Apache distribution. or just view the files
  -in conf directory and follow the instructions in these files - the embedded
  -comments within the file do a good job of explaining the options.
  +The argument to <CODE>leak_test()</CODE> is an anonymous sub, so you can just throw it around any code you suspect
  +might be leaking. beware, it will run the code twice, because the first
  +time in, new <CODE>SV</CODE>s are created, but does not mean you are leaking, the second pass will give
  +better evidence. you do not need to be inside mod_perl to use it, from the
  +command line, the above script outputs:
   
   <P>
  -Before you start the mod_perl configuration, configure Apache, and see that
  -it works. When done, return here to continue...
  -
  +<PRE>  ENTER: 1482 SVs
  +  new c28b8 : new c2918 : 
  +  LEAVE: 1484 SVs
  +  ENTER: 1484 SVs
  +  new db690 : new db6a8 : 
  +  LEAVE: 1486 SVs
  +  !!! 2 SVs leaked !!!
  +</PRE>
   <P>
  -[ Note that prior to version 1.3.4, the default Apache install used three
  -configuration files -- <STRONG>httpd.conf</STRONG>, <STRONG>srm.conf</STRONG>, and
  -<STRONG>access.conf</STRONG>. The 1.3.4 version began distributing the configuration directives in a
  -single file -- <STRONG>httpd.conf</STRONG>. The remainder of this chapter refers to the location of the configuration
  -directives using their historical location. ]
  +Build a debuggable perl to see dumps of the <CODE>SV</CODE>s. the simple way to have both a normal perl and debuggable perl, is to
  +follow hints in the
  +<CODE>SUPPORT</CODE> doc for building <CODE>libperld.a</CODE>, when that is built copy the
  +<CODE>perl</CODE> from that directory to your perl bin directory, but name it
  +<CODE>dperl</CODE>.
   
   <P>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<CENTER><H2><A NAME="Alias_Configurations">Alias Configurations</A></H2></CENTER>
  +<CENTER><H1><A NAME="Limiting_the_size_of_the_process">Limiting the size of the processes</A></H1></CENTER>
   <P>
  -First, you need to specify the location where all mod_perl scripts will be
  -located.
  +<CODE>Apache::SizeLimit</CODE> allows you to kill off Apache httpd processes if they grow too large. see
  +perldoc <CODE>Apache::SizeLimit</CODE> for more details.
   
   <P>
  -Add the following configuration directives:
  +By using this module, you should be able to discontinue using the Apache
  +configuration directive <CODE>MaxRequestsPerChild</CODE>, although for some folks, using both in combination does the job.
   
   <P>
  -<PRE>    # for plain cgi-bin:
  -  ScriptAlias /cgi-bin/ /usr/local/myproject/cgi/
  -    
  -    # for Apache::Registry mode
  -  Alias /perl/ /usr/local/myproject/cgi/
  -    
  -    # Apache::PerlRun mode
  -  Alias /cgi-perl/ /usr/local/myproject/cgi/
  -</PRE>
  +<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<CENTER><H1><A NAME="Limiting_the_resources_used_by_h">Limiting the resources used by httpd children</A></H1></CENTER>
   <P>
  -<CODE>Alias</CODE> provides a mapping of URL to file system object under
  -<CODE>mod_perl</CODE>. <CODE>ScriptAlias</CODE> is being used for <CODE>mod_cgi</CODE>.
  +<CODE>Apache::Resource</CODE> uses the <CODE>BSD::Resource</CODE> module, which uses the C function <CODE>setrlimit()</CODE> to set limits on system resources such as memory and cpu usage.
   
   <P>
  -Alias defines the start of the URL path to the script you are referencing.
  -For example, using the above configuration, fetching
  -<STRONG>http://www.you.com/perl/test.pl</STRONG>, will cause the server to look for the file <STRONG>test.pl</STRONG> at <STRONG>/usr/local/myproject/cgi</STRONG>, and execute it as an <STRONG>Apache::Registry</STRONG> script if we define Apache::Register to be the handler of <CODE>/perl</CODE> location (see below). The URL
  -<STRONG>http://www.you.com/perl/test.pl</STRONG> will be mapped to
  -<STRONG>/usr/local/myproject/cgi/test.pl</STRONG>. This means you can have all your CGIs located at the same place at file
  -system, and call the script in any of three modes simply by changing the
  -directory name component of the URL (cgi-bin|perl|cgi-perl) - is not this
  -cool? (That is the configuration you see above - all three Aliases point to
  -the same directory within your file system, but of course they can be
  -different). If your script does not seem to be working while running under
  -mod_perl, you can easily call the script in straight mod_cgi mode without
  -making any script changes (in most cases), but rather by changing the URL
  -you invoke it by.
  -
  -<P>
  -FYI: for modperl <CODE>ScriptAlias</CODE> is the same thing as an <CODE>Alias</CODE>
  -directive + <CODE>sethandler cgi-handler</CODE>. The latter will be overwritten if you enable <CODE>Apache::Registry</CODE>. In other words, <CODE>ScriptAlias</CODE> does not work for mod_perl, it only appears to work when the additional
  -configuration is in there. If the <CODE>Apache::Registry</CODE> configuration came before the <CODE>ScriptAlias</CODE>, scripts would be run under mod_cgi. While handy, <CODE>ScriptAlias</CODE> is a known kludge, always better to use
  -<CODE>Alias</CODE> and <CODE>SetHandler</CODE>.
  -
  -<P>
  -Of course you can choose any other alias (you will use it later in
  -http.conf), you can choose to use all three modes or only one of these (It
  -is undesirable to run plain cgi-bin scripts from a mod_perl-enabled server
  -- the price is too high, it is better to run these on plain Apache server.
  -(META: add link to strategies)
  +To configure use:
   
   <P>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<CENTER><H2><A NAME="Location_Configuration">Location Configuration</A></H2></CENTER>
  +<PRE>  PerlModule Apache::Resource
  +    # set child memory limit in megabytes
  +    # (default is 64 Meg)
  +  PerlSetEnv PERL_RLIMIT_DATA 32:48
  +  
  +    # set child CPU limit in seconds
  +    # (default is 360 seconds)
  +  PerlSetEnv PERL_RLIMIT_CPU 120
  +  
  +  PerlChildInitHandler Apache::Resource
  +</PRE>
   <P>
  -Now we will work with the <CODE>httpd.conf</CODE> file. I add all the mod_perl stuff at the end of the file, after the native
  -Apache configurations.
  +The following limit values are in megabytes: <CODE>DATA</CODE>, <CODE>RSS</CODE>,
  +<CODE>STACK</CODE>, <CODE>FSIZE</CODE>, <CODE>CORE</CODE>, <CODE>MEMLOCK</CODE>; all others are treated as their natural unit. Prepend <CODE>PERL_RLIMIT_</CODE> for each one you want to use. Refer to <CODE>setrlimit</CODE> man page on your OS for other possible resources.
   
   <P>
  -First we add:
  +If the value of the variable is of the form <CODE>S:H</CODE>, <CODE>S</CODE> is treated as the soft limit, and <CODE>H</CODE> is the hard limit. If it is just a single number, it is used for both soft
  +and hard limits.
   
   <P>
  -<PRE>  &lt;Location /perl&gt;
  -    #AllowOverride None
  -    SetHandler perl-script
  -    PerlHandler Apache::Registry
  -    Options ExecCGI
  -    allow from all
  -    PerlSendHeader On
  -  &lt;/Location&gt;
  +To debug add:
  +
  +<P>
  +<PRE>  &lt;Perl&gt;
  +    $Apache::Resource::Debug = 1;
  +    require Apache::Resource;
  +  &lt;/Perl&gt;
  +  PerlChildInitHandler Apache::Resource
   </PRE>
   <P>
  -This configuration causes all scripts that are called with a <STRONG>/perl</STRONG>
  -path prefix to be executed under the <STRONG>Apache::Registry</STRONG> module and as a CGI (so the <STRONG>ExecCGI</STRONG>, if you omit this option the script will be printed to the caller's
  -browser as a plain text or will possibly will trigger a 'Save-As' window).
  +and look in the error_log to see what it's doing.
   
   <P>
  -<STRONG>PerlSendHeader On</STRONG> tells the server to send an HTTP header to the browser on every script
  -invocation. You will want to turn this off for nph (non-parsed-headers)
  -scripts. <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
  -CGI-&gt;header or $r-&gt;send_http_header directly.
  +Refer to <CODE>perldoc Apache::Resource</CODE> and <CODE>man 2 setrlimit</CODE> for more info.
   
   <P>
  -Remember the <STRONG>Alias</STRONG> from the section above? We must use the same Alias here, if you use
  -Location that does not have the same Alias defined in srm.conf, the server
  -will fail to locate the script in the file system. (We are talking about
  -script execution here -- there are cases where Location is something that
  -is being executed by the server itself, without having the corresponding
  -file, like <A HREF="#_perl_status_location">perl-status location</A>.)
  -
  +<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<CENTER><H1><A NAME="Limiting_the_request_rate_speed_">Limiting the request rate speed (robots blocking)</A></H1></CENTER>
   <P>
  -Note that sometimes you will have to add : PerlModule Apache::Registry
  +A limitation of using pattern matching to identify robots is that it only
  +catches the robots that you know about, and only those that identify
  +themselves by name. A few devious robots masquerade as users by using user
  +agent strings that identify themselves as conventional browsers. To catch
  +such robots, you'll have to be more sophisticated.
   
   <P>
  -before you specify the location that uses Apache::Registry as a
  -PerlHandler. Basically you can start running the scripts in the
  -Apache::Registry mode...
  +<CODE>Apache::SpeedLimit</CODE> comes for you to help, see:
   
   <P>
  -You have to do nothing about /cgi-bin (mod_cgi), since it has nothing to do
  -with mod_perl
  +<A
  +HREF="http://www.modperl.com/chapters/ch6.html#Blocking_Greedy_Clients">http://www.modperl.com/chapters/ch6.html#Blocking_Greedy_Clients</A>
   
  -<P>
  -Here is a similar location configuration for Apache::PerlRun. (More about
  -<A HREF="././porting.html#Apache_PerlRun_a_closer_look">Apache::PerlRun</A>)
   
   <P>
  -<PRE>  &lt;Location /cgi-perl&gt;
  -    #AllowOverride None
  -    SetHandler perl-script
  -    PerlHandler Apache::PerlRun
  -    Options ExecCGI
  -    allow from all
  -    PerlSendHeader On
  -  &lt;/Location&gt;
  -</PRE>
  -<P>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<CENTER><H2><A NAME="PerlFreshRestart">PerlFreshRestart</A></H2></CENTER>
  +<CENTER><H1><A NAME="Benchmarks_Impressing_your_Boss">Benchmarks. Impressing your Boss and Colleagues.</A></H1></CENTER>
   <P>
  -To reload <STRONG>PerlRequire</STRONG>, <STRONG>PerlModule</STRONG>, other <CODE>use()'d</CODE> modules and flush the Apache::Registry cache
  -on server restart, add:
  +How much faster is mod_perl than mod_cgi (aka plain perl/CGI)? There are
  +many ways to benchmark the two. I'll present a few examples and numbers
  +below. Checkout the <CODE>benchmark</CODE> directory of mod_perl distribution for more examples.
   
  -<P>
  -<PRE>  PerlFreshRestart On
  -</PRE>
   <P>
  -Make sure you read <A HREF="././warnings.html#Evil_things_might_happen_when_us">Evil things might happen when using PerlFreshRestart</A>.
  +If you are going to write your own benchmarking utility -- use
  +<CODE>Benchmark</CODE> module for heavy scripts and <CODE>Time::HiRes</CODE> module for very fast scripts (faster than 1 sec) where you need better time
  +precision.
   
   <P>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<CENTER><H2><A NAME="_perl_status_location">/perl-status location</A></H2></CENTER>
  +There is no need to write a special benchmark though. If you want to
  +impress your boss or colleagues, just take some heavy CGI script you have
  +(e.g. a script that crunches some data and prints the results to STDOUT),
  +open 2 xterms and call the same script in mod_perl mode in one xterm and in
  +mod_cgi mode in the other. You can use <CODE>lwp-get</CODE>
  +from <CODE>LWP</CODE> package to emulate the web agent (browser). (<CODE>benchmark</CODE>
  +directory of mod_perl distribution includes such an example)
  +
   <P>
  -Adding a directive to enable a <STRONG>/perl-status</STRONG> location allows you to see many things about your server. See
  -<A HREF="././status.html#Configuration">perl-status</A>
  +See also 2 tools for benchmarking:
  +<A HREF="././performance.html#Tuning_with_ab_ApacheBench">ApacheBench</A> and <A HREF="././performance.html#Tuning_with_crashme_script">crashme test</A>
   
   
   
   <P>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<CENTER><H2><A NAME="PerlSetVar_PerlSetEnv_and_PerlP">PerlSetVar, PerlSetEnv and PerlPassEnv</A></H2></CENTER>
  -<P>
  -<PRE>  PerlSetEnv key val
  -  PerlPassEnv key
  -</PRE>
  +<CENTER><H2><A NAME="Developers_Talk">Developers Talk</A></H2></CENTER>
   <P>
  -Set and Pass the ENV variables to your scripts. So you can read them in
  -your scripts from <CODE>%ENV</CODE> (e.g. <CODE>$ENV{&quot;key&quot;}</CODE>)
  +Perrin Harkins writes on benchmarks or comparisons, official or unofficial:
  +
  +<BLOCKQUOTE>
   
   <P>
  -<CODE>PerlSetVar</CODE> is very similar to <CODE>PerlSetEnv</CODE>, but you extract it with another method. In &lt;Perl&gt; sections:
  +I have used some of the platforms you mentioned and researched others. What
  +I can tell you for sure, is that no commercially available system offers
  +the depth, power, and ease of use that mod_perl has. Either they don't let
  +you access the web server internals, or they make you use less productive
  +languages than Perl, sometimes forcing you into restrictive and confusing
  +APIs and/or GUI development environments. None of them offer the level of
  +support available from simply posting a message to this list, at any price.
   
   <P>
  -<PRE>  push @{ $Location{&quot;/&quot;}-&gt;{PerlSetVar} }, [ 'FOO' =&gt; BAR ];
  -</PRE>
  +As for performance, beyond doing several important things (code-caching,
  +pre-forking/threading, and persistent database connections) there isn't
  +much these tools can do, and it's mostly in your hands as the developer to
  +see that the things which really take the time (like database queries) are
  +optimized.
  +
   <P>
  -and in the code you read it with:
  +The downside of all this is that most manager types seem to be unable to
  +believe that web development software available for free could be better
  +than the stuff that cost $25,000 per CPU. This appears to be the major
  +reason most of the web tools companies are still in business. They send a
  +bunch of suits to give PowerPoint presentations and hand out glossy
  +literature to your boss, and you end up with an expensive disaster and an
  +approaching deadline.
   
   <P>
  -<PRE>  my $r = Apache-&gt;request;
  -  print $r-&gt;dir_config('FOO');
  -</PRE>
  +But I'm not bitter or anything...
  +
  +</BLOCKQUOTE>
  +
   <P>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<CENTER><H2><A NAME="perl_startup_file">perl-startup file</A></H2></CENTER>
  +Jonathan Peterson adds:
  +
  +<BLOCKQUOTE>
  +
   <P>
  -Since many times you have to add many perl directives to the configuration
  -file, it can be a good idea to put all of these into one file, so the
  -configuration file will be cleaner, also you can call
  -<STRONG>perl -c perl-startup</STRONG> to test the file's syntax. What does this take? Add this line to
  -httpd.conf:
  +Most of the major solutions have something that they do better than the
  +others, and each of them has faults. Microsoft's ASP has a very nice
  +objects model, and has IMO the best data access object (better than DBI to
  +use - but less portable) It has the worst scripting language. PHP has many
  +of the advantages of Perl-based solutions, but is less complicated for
  +developers. Netscape's Livewire has a good object model too, and provides
  +good server-side Java integration - if you want to leverage Java skills,
  +it's good. Also, it has a compiled scripting language - which is great if
  +you aren't selling your clients the source code (and a pain otherwise).
   
   <P>
  -<PRE>    # startup.perl loads all functions that we want to use within
  -    # mod_perl
  -  Perlrequire /path/to/startup.pl
  -</PRE>
  +mod_perl's advantage is that it is the most powerful. It offers the
  +greatest degree of control with one of the more powerful languages. It also
  +offers the greatest granularity. You can use an embedding module (eg eperl)
  +from one place, a session module (Session) from another, and your data
  +access module from yet another.
  +
   <P>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<CENTER><H3><A NAME="Sample_perl_startup_file">Sample perl-startup file</A></H3></CENTER>
  +I think the <CODE>Apache::ASP</CODE> module looks very promising. It has very easy to use and adequately
  +powerful state maintenance, a good embedding system, and a sensible object
  +model (that emulates the Microsoft ASP one). It doesn't replicate MS's ADO
  +for data access, but
  +<CODE>DBI</CODE> is fine for that.
  +
   <P>
  -An example of perl-startup file:
  +I have always found that the developers available make the greatest impact
  +on the decision. If you have a team with no Perl experience, and a small or
  +medium task, using something like PHP, or Microsoft ASP, makes more sense
  +than driving your staff into the vertical learning curve they'll need to
  +use mod_perl.
   
   <P>
  -<PRE>  use strict;
  -  
  -  #modify @INC if needed
  -  use lib qw(/some/other/dir /some/bar/dir);
  -  
  -  # make sure we are in a sane environment.
  -  $ENV{GATEWAY_INTERFACE} =~ /^CGI-Perl/
  -     or die &quot;GATEWAY_INTERFACE not Perl!&quot;;
  -   
  -  # for things in the &quot;/perl&quot; URL
  -  use Apache::Registry;          
  -   
  -  #load perl modules of your choice here
  -  #this code is interpreted *once* when the server starts
  -  use LWP::UserAgent ();
  -  use DBI ();
  -  
  -  # tell me more about warnings
  -  use Carp ();
  -  $SIG{__WARN__} = \&amp;Carp::cluck;
  -  
  -  # Load CGI.pm and call its compile() method to precompile 
  -  # (but not to import) its autoloaded methods. 
  -  use CGI ();
  -  CGI-&gt;compile(':all');
  -</PRE>
  +For very large jobs, it may be worth finding the best technical solution,
  +and then recruiting the team with the necessary skills.
  +
  +</BLOCKQUOTE>
  +
   <P>
  -Note that starting with CGI::VERSION 2.46, the recommended method to
  -precompile the code in CGI.pm is:
  +<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<CENTER><H2><A NAME="Benchmarking_a_Graphic_hits_coun">Benchmarking a Graphic hits counter with Persistent DB Connection</A></H2></CENTER>
  +<P>
  +Here are the numbers from Michael Parker's mod_perl presentation at Perl
  +Conference (Aug, 98) <A
  +HREF="http://www.realtime.net/~parkerm/perl/conf98/index.htm">http://www.realtime.net/~parkerm/perl/conf98/index.htm</A>
  +. The script is a standard hits counter, but it logs the counts into the
  +mysql relational DataBase:
   
   <P>
  -<PRE>  use CGI qw(-compile :all);
  +<PRE>    Benchmark: timing 100 iterations of cgi, perl...  [rate 1:28]
  +    
  +    cgi: 56 secs ( 0.33 usr 0.28 sys = 0.61 cpu) 
  +    perl: 2 secs ( 0.31 usr 0.27 sys = 0.58 cpu) 
  +    
  +    Benchmark: timing 1000 iterations of cgi,perl...  [rate 1:21]
  +     
  +    cgi: 567 secs ( 3.27 usr 2.83 sys = 6.10 cpu) 
  +    perl: 26 secs ( 3.11 usr 2.53 sys = 5.64 cpu)      
  +    
  +    Benchmark: timing 10000 iterations of cgi, perl   [rate 1:21]
  +     
  +    cgi: 6494 secs (34.87 usr 26.68 sys = 61.55 cpu) 
  +    perl: 299 secs (32.51 usr 23.98 sys = 56.49 cpu) 
   </PRE>
   <P>
  -But the old method is still available for backward compatibility.
  +We don't know what server configurations was used for these tests, but I
  +guess the numbers speak for themselves.
   
   <P>
  -See also <A HREF="././status.html#Configuration">Apache::Status</A>
  +The source code of the script is available at <A
  +HREF="http://www.realtime.net/~parkerm/perl/conf98/sld006.htm">http://www.realtime.net/~parkerm/perl/conf98/sld006.htm</A>
  +.
   
  +<P>
  +<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<CENTER><H2><A NAME="Benchmarking_scripts_with_execut">Benchmarking scripts with execution times below 1 second :)</A></H2></CENTER>
  +<P>
  +As noted before, for very fast scripts you will have to use the
  +<CODE>Time::HiRes</CODE> module, its usage is similar to the <CODE>Benchmark</CODE>'s.
   
  +<P>
  +<PRE>  use Time::HiRes qw(gettimeofday tv_interval);
  +  my $start_time = [ gettimeofday ];
  +  &amp;sub_that_takes_a_teeny_bit_of_time()
  +  my $end_time = [ gettimeofday ];
  +  my $elapsed = tv_interval($start_time,$end_time);
  +  print &quot;the sub took $elapsed secs.&quot;
  +</PRE>
  +<P>
  +See also <A HREF="././performance.html#Tuning_with_crashme_script">crashme test</A>.
   
   <P>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<CENTER><H3><A NAME="What_modules_should_you_add_to_t">What modules should you add to the startup file and why.</A></H3></CENTER>
  +<CENTER><H2><A NAME="PerlHandler_s_Benchmarking">PerlHandler's Benchmarking</A></H2></CENTER>
   <P>
  -Modules that are being loaded at the server startup will be shared among
  -server children, so only one copy of each module will be loaded, thus
  -saving a lot of RAM for you. 
  +At <A
  +HREF="http://perl.apache.org/dist/contrib/">http://perl.apache.org/dist/contrib/</A>
  +you will find
  +<CODE>Apache::Timeit</CODE> package which does <CODE>PerlHandler</CODE>'s Benchmarking.
   
  +<P>
  +<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<CENTER><H1><A NAME="Tuning_the_Apache_s_configuratio">Tuning the Apache's configuration variables for the best performance</A></H1></CENTER>
   <P>
  -See <A HREF="././performance.html#Preload_Perl_modules_at_server_s">Preload Perl modules at server startup</A> 
  +It's very important to make a correct configuration of the
  +<CODE>MinSpareServers</CODE>, <CODE>MaxSpareServers</CODE>, <CODE>StartServers</CODE>,
  +<CODE>MaxClients</CODE>, and <CODE>MaxRequestsPerChild</CODE> parameters. There are no defaults, the values of these variable are very
  +important, as if too ``low'' you will under-use the system's capabilities,
  +and if too ``high'' chances that the server will bring the machine to its
  +knees.
   
  - 
  +<P>
  +All the above parameters should be specified on the basis of the resources
  +you have. While with a plain apache server, there is no big deal if you run
  +too many servers (not too many of course) since the processes are of ~1Mb
  +and aren't eating a lot of your RAM. Generally the numbers are even smaller
  +if memory sharing is taking place. The situation is different with
  +mod_perl. I have seen mod_perl processes of 20Mb and more. Now if you have <CODE>MaxClients</CODE> set to 50: 50x20Mb = 1Gb - do you have 1Gb of RAM? Probably not. So how do
  +you tune these parameters? Generally by trying different combinations and
  +benchmarking the server. Again mod_perl processes can be of much smaller
  +size if sharing is in place.
   
   <P>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<CENTER><H3><A NAME="Is_it_possible_to_preopen_a_DB_c">Is it possible to preopen a DB connection at the server startup?</A></H3></CENTER>
  +Before you start this task you should be armed with a proper weapon. You
  +need a <STRONG>crashme</STRONG> utility, which will load your server with mod_perl scripts you possess. You
  +need it to have an ability to emulate a multiuser environment and to
  +emulate multiple clients behavior which will call the mod_perl scripts at
  +your server simultaneously. While there are commercial solutions, you can
  +get away with free ones which do the same job. You can use an
  +<A HREF="././performance.html#Tuning_with_ab_ApacheBench">ApacheBench</A>  <STRONG><CODE>ab</CODE></STRONG> utility that comes with apache distribution, a <A HREF="././performance.html#Tuning_with_crashme_script">crashme script</A> which uses
  +<CODE>LWP::Parallel::UserAgent</CODE> or <CODE>httperf</CODE> (see <A HREF="././download.html#">Download page</A>).
  +
  +<P>
  +Another important issue is to make sure to run testing client (load
  +generator) on a system that is more powerful than the system being tested.
  +After all we are trying to simulate the Internet users, where many users
  +are trying to reach your service at once -- since a number of concurrent
  +users can be quite large, your testing machine much be very powerful and
  +capable to generate a heavy load. Of course you should not run the clients
  +and the server on the same machine. If you do -- your testing results would
  +be incorrect, since clients will eat a CPU and a memory that have to be
  +dedicated to the server, and vice versa.
  +
   <P>
  -Yes! See <A HREF="././performance.html#Persistent_DB_Connections">Persistent DB Connections</A>
  +See also 2 tools for benchmarking:
  +<A HREF="././performance.html#Tuning_with_ab_ApacheBench">ApacheBench</A> and <A HREF="././performance.html#Tuning_with_crashme_script">crashme test</A>
   
   
   
   <P>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<CENTER><H3><A NAME="The_confusion_with_use_clause_">The confusion with use() clause at the server startup?</A></H3></CENTER>
  +<CENTER><H2><A NAME="Tuning_with_ab_ApacheBench">Tuning with ab - ApacheBench</A></H2></CENTER>
   <P>
  -Many people wonder, why there is a need for duplication of <CODE>use()</CODE>
  -clause both in startup file and in the script itself. The question rises
  -from misunderstanding of the <CODE>use()</CODE> operand. <CODE>use()</CODE> consists of two other operands, namely <CODE>require()</CODE> and <CODE>import()</CODE>. So when you write:
  +<STRONG>ab</STRONG> is a tool for benchmarking your Apache HTTP server. It is designed to give
  +you an impression on how much performance your current Apache installation
  +can give. In particular, it shows you how many requests per secs your
  +Apache server is capable of serving. The
  +<STRONG>ab</STRONG> tool comes bundled with apache source distribution (and it's free :).
   
   <P>
  -<PRE>  use Foo qw(bar);
  +Let's try it. We will simulate 10 users concurrently requesting a very
  +light script at <CODE>www.nowhere.com:81/test/test.pl</CODE>. Each ``user'' makes 10 requests.
  +
  +<P>
  +<PRE>  % ./ab -n 100 -c 10 www.nowhere.com:81/test/test.pl
   </PRE>
   <P>
  -perl actually does:
  +The results are:
   
   <P>
  -<PRE>  require Foo.pm;
  -  import qw(bar);
  +<PRE>  Concurrency Level:      10
  +  Time taken for tests:   0.715 seconds
  +  Complete requests:      100
  +  Failed requests:        0
  +  Non-2xx responses:      100
  +  Total transferred:      60700 bytes
  +  HTML transferred:       31900 bytes
  +  Requests per second:    139.86
  +  Transfer rate:          84.90 kb/s received
  +  
  +  Connection Times (ms)
  +                min   avg   max
  +  Connect:        0     0     3
  +  Processing:    13    67    71
  +  Total:         13    67    74
   </PRE>
   <P>
  -When you write:
  +The only numbers we really care about are:
   
   <P>
  -<PRE>  use Foo qw();
  +<PRE>  Complete requests:      100
  +  Failed requests:        0
  +  Requests per second:    139.86
   </PRE>
   <P>
  -perl actually does:
  +Let's raise the load of requests to 100 x 10 (10 users, each makes 100
  +requests)
   
   <P>
  -<PRE>  require Foo.pm;
  -  import qw();
  +<PRE>  % ./ab -n 1000 -c 10 www.nowhere.com:81/perl/access/access.cgi
  +  Concurrency Level:      10
  +  Complete requests:      1000
  +  Failed requests:        0
  +  Requests per second:    139.76
   </PRE>
   <P>
  -which means that the caller does not want any symbols to be imported. Why
  -is this important? Since some modules has <CODE>@EXPORT</CODE> set to some tags to be exported by default and when write:
  +As expected nothing changes -- we have the same 10 concurrent users. Now
  +let's raise the number of concurrent users to 50:
   
   <P>
  -<PRE>  use Foo;
  +<PRE>  % ./ab -n 1000 -c 50 www.nowhere.com:81/perl/access/access.cgi
  +  Complete requests:      1000
  +  Failed requests:        0
  +  Requests per second:    133.01
   </PRE>
   <P>
  -And you think nothing is being imported, the <CODE>import()</CODE> call is being executed and probably some symbols do being imported. See the
  -docs/source of the module in question to make sure you code correctly.
  +We see that the server is capable of serving 50 concurrent users at an
  +amazing 133 req/sec! Let's find the upper boundary. Using <CODE>-n 10000
  +-c 1000</CODE> failed to get results (Broken Pipe?). Using <CODE>-n 10000 -c
  +500</CODE> derived 94.82 req/sec. The server's performance went down with the high
  +load.
   
   <P>
  -Since the symbols that you might import into a startup's script namespace
  -will be visible by none of the children, scripts that needs a <CODE>Foo</CODE>'s module functionality have to pull it in like if you did not preload <CODE>Foo</CODE> at the startup file. For example, just because you have <CODE>use()d</CODE>  <CODE>Apache::Constants</CODE> in a startup script does not mean you can have the following handler:
  +The above tests were performed with the following configuration:
   
   <P>
  -<PRE>  package MyModule;
  -  
  -  sub {
  -    my $r = shift;
  -  
  -    ## Cool stuff goes here
  -  
  -    return OK;
  -  }
  -</PRE>
  -<P>
  -<PRE>  1;
  +<PRE>  MinSpareServers 8
  +  MaxSpareServers 6
  +  StartServers 10
  +  MaxClients 50
  +  MaxRequestsPerChild 1500
   </PRE>
   <P>
  -You would either need to add:
  +Now let's kill a child after a single request, we will use the following
  +configuration:
   
   <P>
  -<PRE>  use Apache::Constants qw( OK );
  +<PRE>  MinSpareServers 8
  +  MaxSpareServers 6
  +  StartServers 10
  +  MaxClients 100
  +  MaxRequestsPerChild 1
   </PRE>
   <P>
  -Or instead of <CODE>return OK;</CODE> say:
  +Simulate 50 users each generating a total of 20 requests:
   
   <P>
  -<PRE>  return Apache::Constants::OK;
  +<PRE>  % ./ab -n 1000 -c 50 www.nowhere.com:81/perl/access/access.cgi
   </PRE>
   <P>
  -See the manpage/perldoc on <CODE>Exporter</CODE> and <CODE>perlmod</CODE> for more on import.
  +The benchmark timed out with the above configuration.... I watched the
  +output of <STRONG><CODE>ps</CODE></STRONG> as I ran it, the parent process just wasn't capable of respawning the
  +killed children at that rate...When I raised the
  +<CODE>MaxRequestsPerChild</CODE> to 10 I've got 8.34 req/sec - very bad (18 times slower!) (You can't
  +benchmark the importance of the
  +<CODE>MinSpareServers</CODE>, <CODE>MaxSpareServers</CODE> and <CODE>StartServers</CODE> with this kind of test).
   
   <P>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<CENTER><H3><A NAME="The_confusion_with_defining_glob">The confusion with defining globals in startup</A></H3></CENTER>
  -<P>
  -<CODE>PerlRequire</CODE> allows you to preload modules and do a few more things. Imported or defined
  -variables are visible in the scope of the startup file. It is a wrong
  -assumption that global variables that were defined in the startup file,
  -will be accessable by child processes.
  +Now let's try to return <CODE>MaxRequestsPerChild</CODE> to 1500, but to lower the
  +<CODE>MaxClients</CODE> to 10 and run the same test:
   
   <P>
  -You do have to define/import variables in your scripts and they will be
  -visible inside a child process who run this script. They will be not shared
  -between siblings. Remember that every script is running is a specially
  -(uniquely) named package - so it cannot access variables from other
  -packages unless it inherits from them or <CODE>use()</CODE>s them.
  -
  +<PRE>  MinSpareServers 8
  +  MaxSpareServers 6
  +  StartServers 10
  +  MaxClients 10
  +  MaxRequestsPerChild 1500
  +</PRE>
   <P>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<CENTER><H1><A NAME="Running_apachectl_configtest_o">Running 'apachectl configtest' or 'httpd -t'</A></H1></CENTER>
  +I've got 27.12 req/sec, which is better but still 4-5 times slower (133
  +with <CODE>MaxClients</CODE> of 50)
  +
   <P>
  -<CODE>apachectl configtest</CODE> tests the configuration file without starting the server. You can safely
  -modify the configuration file on your production server, if you run this
  -test before you restart the server. Of course it is not 100% errorprone,
  -but it will reveal any syntaxical errors you might do while editing the
  -file.
  +<STRONG>Summary:</STRONG> I have tested a few combinations of server configuration variables (<CODE>MinSpareServers</CODE>  <CODE>MaxSpareServers</CODE>  <CODE>StartServers</CODE>
  +
  +<CODE>MaxClients</CODE>  <CODE>MaxRequestsPerChild</CODE>). And the results we have received are as follows:
   
   <P>
  -<CODE>apachectl configtest</CODE> is the same as <CODE>httpd -t</CODE> and it actually executes the code in startup.pl, not just parses it. &lt;Perl&gt; configuration has always started Perl during the configuration
  -read,
  -<CODE>Perl{Require,Module}</CODE> do so as well.
  +<CODE>MinSpareServers</CODE>, <CODE>MaxSpareServers</CODE> and <CODE>StartServers</CODE> are only important for user response times (sometimes user will have to
  +wait a bit).
   
   <P>
  -If you want your startup code to get a control over the <CODE>-t</CODE>
  -(configtest) server launch, start the server configuration test with 
  +The important parameters are <CODE>MaxClients</CODE> and
  +<CODE>MaxRequestsPerChild</CODE>. <CODE>MaxClients</CODE> should be not to big so it will not abuse your machine's memory resources
  +and not too small, when users will be forced to wait for the children to
  +become free to come serve them. <CODE>MaxRequestsPerChild</CODE> should be as big as possible, to take the full benefit of mod_perl, but
  +watch your server at the beginning to make sure your scripts are not
  +leaking memory, thereby causing your server (and your service) to die very
  +fast.
   
   <P>
  -<PRE>  httpd -t -Dsyntax_check
  -</PRE>
  +Also it is important to understand that we didn't test the response times
  +in the tests above, but the ability of the server to respond under a heavy
  +load of requests. If the script that was used to test was heavier, the
  +numbers would be different but the conclusions are very similar.
  +
   <P>
  -and in your startup file, add:
  +The benchmarks were run with:
   
   <P>
  -<PRE>  return if Apache-&gt;define('syntax_check');
  +<PRE>  HW: RS6000, 1Gb RAM
  +  SW: AIX 4.1.5 . mod_perl 1.16, apache 1.3.3
  +  Machine running only mysql, httpd docs and mod_perl servers.
  +  Machine was _completely_ unloaded during the benchmarking.
   </PRE>
  -<P>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<CENTER><H1><A NAME="Perl_behavior_controls">Perl behavior controls</A></H1></CENTER>
   <P>
  -For <STRONG>PerlWarn</STRONG> and <STRONG>PerlTaintCheck</STRONG> see <A HREF="././porting.html#Switches_w_T">Switches -w, -T</A>
  -
  -
  +After each server restart when I did changes to the server's
  +configurations, I made sure the scripts were preloaded by fetching a script
  +at least once by every child.
   
  -<P>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<CENTER><H1><A NAME="Tuning_MinSpareServers_MaxSpareS">Tuning MinSpareServers MaxSpareServers StartServers MaxClients
  -MaxRequestsPerChild</A></H1></CENTER>
   <P>
  -See <A HREF="././performance.html#Tuning_the_Apache_s_configuratio">Tuning the Apache's configuration variables for the best performance</A>
  +It is important to notice that none of requests timed out, even if was kept
  +in server's queue for more than 1 minute! (That is the way <STRONG>ab</STRONG>
  +works, which is OK for the testing purposes but will be unacceptable in the
  +real world - users will not wait for more than 5-10 secs for a request to
  +complete, and the client (browser) will timeout in a few minutes.)
   
  +<P>
  +Now let's take a look at some real code whose execution time is more than a
  +few millisecs. We will do real testing and collect the data in tables for
  +easier viewing.
   
  +<P>
  +I will use the following abbreviations:
   
   <P>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<CENTER><H1><A NAME="Publishing_port_numbers_differen">Publishing port numbers different from 80</A></H1></CENTER>
  +<PRE>  NR    = Total Number of Request
  +  NC    = Concurrency
  +  MC    = MaxClients
  +  MRPC  = MaxRequestsPerChild
  +  RPS   = Requests per second
  +</PRE>
   <P>
  -It is advised not to publish the 8080 (or alike) port number in URLs, but
  -rather using a proxying rewrite rule in the thin (httpd_docs) server:
  +Running a mod_perl script with lots of mysql queries (the script under test
  +is mysqld bounded)
  +(http://www.nowhere.com:81/perl/access/access.cgi?do_sub=query_form), with
  +configuration:
   
   <P>
  -<PRE>  RewriteRule .*/perl/(.*) <A HREF="http://my.url:8080/perl/">http://my.url:8080/perl/</A>$1 [P]
  +<PRE>  MinSpareServers        8
  +  MaxSpareServers       16
  +  StartServers          10
  +  MaxClients            50
  +  MaxRequestsPerChild 5000
   </PRE>
   <P>
  -One problem with publishing 8080 port numbers is that I was told that IE
  -4.x has a bug when re-posting data to a non-port-80 url. It drops the port
  -designator, and uses port 80 anyway.
  +gives us:
   
   <P>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<CENTER><H1><A NAME="Perl_Sections">Perl Sections</A></H1></CENTER>
  +<PRE>     NR   NC    RPS     comment
  +  ------------------------------------------------
  +     10   10    3.33    # not a reliable statistics
  +    100   10    3.94    
  +   1000   10    4.62    
  +   1000   50    4.09    
  +</PRE>
   <P>
  -With <STRONG>&lt;Perl&gt;&lt;/Perl&gt;</STRONG> sections, it is possible to configure your server entirely in Perl.
  +Conclusions: Here I wanted to show that when the application is slow -- not
  +due to perl loading, code compilation and execution, but bounded to some
  +external operation like mysqld querying which made the bottleneck -- it
  +almost does not matter what load we place on the server. The RPS (Requests
  +per second) is almost the same (given that all the requests have been
  +served, you have an ability to queue the clients, but be aware that
  +something that goes to queue means a waiting client and a client (browser)
  +that might time out!)
   
   <P>
  -<STRONG>&lt;Perl&gt;</STRONG> sections can contain *any* and as much Perl code as you wish. These
  -sections are compiled into a special package whose symbol table mod_perl
  -can then walk and grind the names and values of Perl variables/structures
  -through the Apache core configuration gears. Most of the configurations
  -directives can be represented as scalars (<STRONG>$scalar</STRONG>) or lists (<STRONG>@list</STRONG>). An <CODE>@List</CODE> inside these sections is simply converted into a space delimited string for
  -you inside. Here is an example:
  +Now we will benchmark the same script without using the mysql (perl only
  +bounded code) (http://www.nowhere.com:81/perl/access/access.cgi), it's the
  +same script that just returns a HTML form, without making any SQL queries.
   
   <P>
  -<PRE>  #httpd.conf
  -  &lt;Perl&gt;
  -  @PerlModule = qw(Mail::Send Devel::Peek);
  - 
  -  #run the server as whoever starts it
  -  $User  = getpwuid($&gt;) || $&gt;;
  -  $Group = getgrgid($)) || $); 
  - 
  -  $ServerAdmin = $User;
  - 
  -  &lt;/Perl&gt;
  +<PRE>  MinSpareServers        8
  +  MaxSpareServers       16
  +  StartServers          10
  +  MaxClients            50
  +  MaxRequestsPerChild 5000
   </PRE>
  -<P>
  -Block sections such as &lt;Location&gt;&lt;/Location&gt; are represented in
  -a %Hash, e.g.:
  -
   <P>
  -<PRE>  $Location{&quot;/~dougm/&quot;} = {
  -    AuthUserFile =&gt; '/tmp/htpasswd',
  -    AuthType =&gt; 'Basic',
  -    AuthName =&gt; 'test',
  -    DirectoryIndex =&gt; [qw(index.html index.htm)],  
  -    Limit =&gt; {
  -    METHODS =&gt; 'GET POST',
  -    require =&gt; 'user dougm',
  -    },
  -  };
  +<PRE>     NR   NC      RPS   comment
  +  ------------------------------------------------
  +     10   10    26.95   # not a reliable statistics
  +    100   10    30.88   
  +   1000   10    29.31
  +   1000   50    28.01
  +   1000  100    29.74
  +  10000  200    24.92
  + 100000  400    24.95
   </PRE>
   <P>
  -If a Directive can take two *or* three arguments you may push strings and
  -the lowest number of arguments will be shifted off the <CODE>@List</CODE> or use array reference to handle any number greater than the minimum for
  -that directive:
  +Conclusions: This time the script we executed was pure perl (not bounded to
  +I/O or mysql), so we see that the server serves the requests much faster.
  +You can see the <CODE>RequestPerSecond</CODE> (RPS) is almost the same for any load, but goes lower when the number of
  +concurrent clients goes beyond the <CODE>MaxClients</CODE>. With 25 RPS, the client supplying a load of 400 concurrent clients will
  +be served in 16 secs. But to get more realistic and assume the max
  +concurrency of 100, with 30 RPS, the client will be served in 3.5 secs,
  +which is pretty good for a highly loaded server.
   
   <P>
  -<PRE>  push @Redirect, &quot;/foo&quot;, &quot;<A HREF="http://www.foo.com/&quot">http://www.foo.com/&quot</A>;;
  -  
  -  push @Redirect, &quot;/imdb&quot;, &quot;<A HREF="http://www.imdb.com/&quot">http://www.imdb.com/&quot</A>;;
  +Now we will use the server for its full capacity, by keeping all
  +<CODE>MaxClients</CODE> alive all the time and having a big
  +<CODE>MaxRequestsPerChild</CODE>, so no server will be killed during the benchmarking.
  +
  +<P>
  +<PRE>  MinSpareServers       50
  +  MaxSpareServers       50
  +  StartServers          50
  +  MaxClients            50
  +  MaxRequestsPerChild 5000
     
  -  push @Redirect, [qw(temp &quot;/here&quot; &quot;<A HREF="http://www.there.com&quot">http://www.there.com&quot</A>;)];
  +     NR   NC      RPS   comment
  +  ------------------------------------------------
  +    100   10    32.05
  +   1000   10    33.14
  +   1000   50    33.17
  +   1000  100    31.72
  +  10000  200    31.60
   </PRE>
  -<P>
  -Other section counterparts include <STRONG>%VirtualHost</STRONG>, <STRONG>%Directory</STRONG> and
  -<STRONG>%Files</STRONG>.
  -
   <P>
  -To pass all environment variables to the children with a single
  -configuration directive, rather than listing each one via PassEnv or
  -PerlPassEnv, a <STRONG>&lt;Perl&gt;</STRONG> section could read in a file and:
  +Conclusion: In this scenario there is no overhead involving the parent
  +server loading new children, all the servers are available, and the only
  +bottleneck is contention for the CPU.
   
  -<P>
  -<PRE>  push @PerlPassEnv, [$key =&gt; $val];
  -</PRE>
   <P>
  -or
  +Now we will try to change the <CODE>MaxClients</CODE> and to watch the results: Let's reduce MC to 10.
   
   <P>
  -<PRE>  Apache-&gt;httpd_conf(&quot;PerlPassEnv $key $val&quot;);
  +<PRE>  MinSpareServers        8
  +  MaxSpareServers       10
  +  StartServers          10
  +  MaxClients            10
  +  MaxRequestsPerChild 5000
  +  
  +     NR   NC      RPS   comment
  +  ------------------------------------------------
  +     10   10    23.87   # not a reliable statistics
  +    100   10    32.64 
  +   1000   10    32.82
  +   1000   50    30.43
  +   1000  100    25.68
  +   1000  500    26.95
  +   2000  500    32.53
   </PRE>
   <P>
  -These are somewhat simple examples, but they should give you the basic
  -idea. You can mix in any Perl code your heart desires. See
  -<CODE>eg/httpd.conf.pl</CODE> and <CODE>eg/perl_sections.txt</CODE> in mod_perl distribution for some examples.
  +Conclusions: Very little difference! Almost no change! 10 servers were able
  +to serve almost with the same throughput as 50 servers. Why? My guess it's
  +because of CPU throttling. It seems that 10 servers were serving requests 5
  +times faster than when in the test above we worked with 50 servers. In the
  +case above each child received its CPU time slice 5 times less frequently.
  +So having a big value for
  +<CODE>MaxClients</CODE>, doesn't mean that the performance will be better. You have just seen the
  +numbers!
   
   <P>
  -A tip for syntax checking outside of httpd:
  +Now we will start to drastically reduce the <CODE>MaxRequestsPerChild</CODE>:
   
   <P>
  -<PRE>  &lt;Perl&gt;
  -  # !perl
  -  
  -  #... code here ...
  +<PRE>  MinSpareServers        8
  +  MaxSpareServers       16
  +  StartServers          10
  +  MaxClients            50
     
  -  __END__
  -  &lt;/Perl&gt;
  +     NR   NC    MRPC     RPS    comment
  +  ------------------------------------------------
  +    100   10      10    5.77 
  +    100   10       5    3.32
  +   1000   50      20    8.92
  +   1000   50      10    5.47
  +   1000   50       5    2.83
  +   1000  100      10    6.51
   </PRE>
   <P>
  -Now you may run <STRONG>perl -cx httpd.conf</STRONG>.
  +Conclusions: When we drastically reduce the <CODE>MaxRequestsPerChild</CODE>, the performance starts to become closer to the plain mod_cgi. Just for
  +comparison with mod_cgi, here are the numbers of this run with mod_cgi:
   
   <P>
  -To configure this feature build with <STRONG>perl Makefile.PL 
  -PERL_SECTIONS=1</STRONG>
  -
  -
  +<PRE>  MinSpareServers        8
  +  MaxSpareServers       16
  +  StartServers          10
  +  MaxClients            50
  +  
  +     NR   NC    RPS     comment
  +  ------------------------------------------------
  +    100   10    1.12
  +   1000   50    1.14
  +   1000  100    1.13
  +</PRE>
  +<P>
  +Conclusion: mod_cgi is much slower :) in test NReq/NClients 100/10 the RPS
  +in mod_cgi was of 1.12 and in mod_perl of 32, which is 30 times faster!!!
  +In the first test each child waited about 100 secs to be served. In the
  +second and third 1000 secs!
   
   <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>
  +<CENTER><H2><A NAME="Tuning_with_crashme_script">Tuning with crashme script</A></H2></CENTER>
   <P>
  -mod_macro is an Apache module written by Fabien Coelho that lets you define
  -and use macros in the Apache configuration file.
  +This is another crashme suite originally written by Michael Schilli and
  +located at <A
  +HREF="http://www.linux-magazin.de/ausgabe.1998.08/Pounder/pounder.html">http://www.linux-magazin.de/ausgabe.1998.08/Pounder/pounder.html</A>
  +. I did a few modifications (mostly adding <CODE>my()</CODE> operands). I
  +also allowed it to accept more than one url to test, since sometimes you
  +want to test an overall and not just one script.
   
   <P>
  -mod_macro proved really useful when you have many virtual hosts, each
  -virtual host has a number of scripts/modules, most of them with a
  -moderately complex configuration setup.
  +The tool provides the same results as <STRONG>ab</STRONG> above but it also allows you to set the timeout value, so requests will
  +fail if not served within the time out period. You also get Latency
  +(secs/Request) and Throughput (Requests/sec) numbers. It can give you a
  +better picture and make a complete simulation of your favorite Netscape
  +browser :).
   
   <P>
  -First download the latest version of mod_macro from <A
  -HREF="http://www.cri.ensmp.fr/~coelho/mod_macro/">http://www.cri.ensmp.fr/~coelho/mod_macro/</A>
  -, and configure your Apache server to use this module.
  +I have noticed while running these 2 benchmarking suites - <STRONG>ab</STRONG> gave me results 2.5-3.0 times better. Both suites run on the same machine
  +with the same load with the same parameters. But the implementations are
  +different.
   
   <P>
  -Here are some useful macros for mod_perl users:
  +Sample output:
   
   <P>
  -<PRE>        # set up a registry script
  -        &lt;Macro registry&gt;
  -        SetHandler &quot;perl-script&quot;
  -        PerlHandler Apache::Registry
  -        Options +ExecCGI
  -        &lt;/Macro&gt;
  +<PRE>  URL(s):          <A HREF="http://www.nowhere.com:81/perl/access/access.cgi">http://www.nowhere.com:81/perl/access/access.cgi</A>
  +  Total Requests:  100
  +  Parallel Agents: 10
  +  Succeeded:       100 (100.00%)
  +  Errors:          NONE
  +  Total Time:      9.39 secs
  +  Throughput:      10.65 Requests/sec
  +  Latency:         0.85 secs/Request
   </PRE>
   <P>
  -<PRE>        # example
  -        Alias /stuff /usr/www/scripts/stuff
  -        &lt;Location /stuff&gt;
  -        Use registry
  -        &lt;/Location&gt;
  +And the code:
  +
  +<P>
  +<PRE>  #!/usr/apps/bin/perl -w
  +  
  +  use LWP::Parallel::UserAgent;
  +  use Time::HiRes qw(gettimeofday tv_interval);
  +  use strict;
  +  
  +  ###
  +  # Configuration
  +  ###
  +  
  +  my $nof_parallel_connections = 10; 
  +  my $nof_requests_total = 100; 
  +  my $timeout = 10;
  +  my @urls = (
  +            '<A HREF="http://www.nowhere.com:81/perl/faq_manager/faq_manager.pl">http://www.nowhere.com:81/perl/faq_manager/faq_manager.pl</A>',
  +            '<A HREF="http://www.nowhere.com:81/perl/access/access.cgi">http://www.nowhere.com:81/perl/access/access.cgi</A>',
  +           );
  +  
  +  
  +  ##################################################
  +  # Derived Class for latency timing
  +  ##################################################
  +  
  +  package MyParallelAgent;
  +  @MyParallelAgent::ISA = qw(LWP::Parallel::UserAgent);
  +  use strict;
  +  
  +  ###
  +  # Is called when connection is opened
  +  ###
  +  sub on_connect {
  +    my ($self, $request, $response, $entry) = @_;
  +    $self-&gt;{__start_times}-&gt;{$entry} = [Time::HiRes::gettimeofday];
  +  }
  +  
  +  ###
  +  # Are called when connection is closed
  +  ###
  +  sub on_return {
  +    my ($self, $request, $response, $entry) = @_;
  +    my $start = $self-&gt;{__start_times}-&gt;{$entry};
  +    $self-&gt;{__latency_total} += Time::HiRes::tv_interval($start);
  +  }
  +  
  +  sub on_failure {
  +    on_return(@_);  # Same procedure
  +  }
  +  
  +  ###
  +  # Access function for new instance var
  +  ###
  +  sub get_latency_total {
  +    return shift-&gt;{__latency_total};
  +  }
  +  
  +  ##################################################
  +  package main;
  +  ##################################################
  +  ###
  +  # Init parallel user agent
  +  ###
  +  my $ua = MyParallelAgent-&gt;new();
  +  $ua-&gt;agent(&quot;pounder/1.0&quot;);
  +  $ua-&gt;max_req($nof_parallel_connections);
  +  $ua-&gt;redirect(0);    # No redirects
  +  
  +  ###
  +  # Register all requests
  +  ###
  +  foreach (1..$nof_requests_total) {
  +    foreach my $url (@urls) {
  +      my $request = HTTP::Request-&gt;new('GET', $url);
  +      $ua-&gt;register($request);
  +    }
  +  }
  +  
  +  ###
  +  # Launch processes and check time
  +  ###
  +  my $start_time = [gettimeofday];
  +  my $results = $ua-&gt;wait($timeout);
  +  my $total_time = tv_interval($start_time);
  +  
  +  ###
  +  # Requests all done, check results
  +  ###
  +  
  +  my $succeeded     = 0;
  +  my %errors = ();
  +  
  +  foreach my $entry (values %$results) {
  +    my $response = $entry-&gt;response();
  +    if($response-&gt;is_success()) {
  +      $succeeded++; # Another satisfied customer
  +    } else {
  +      # Error, save the message
  +      $response-&gt;message(&quot;TIMEOUT&quot;) unless $response-&gt;code();
  +      $errors{$response-&gt;message}++;
  +    }
  +  }
  +  
  +  ###
  +  # Format errors if any from %errors 
  +  ###
  +  my $errors = join(',', map &quot;$_ ($errors{$_})&quot;, keys %errors);
  +  $errors = &quot;NONE&quot; unless $errors;
  +  
  +  ###
  +  # Format results
  +  ###
  +  
  +  #@urls = map {($_,&quot;.&quot;)} @urls;
  +  my @P = (
  +        &quot;URL(s)&quot;          =&gt; join(&quot;\n\t\t &quot;, @urls),
  +        &quot;Total Requests&quot;  =&gt; &quot;$nof_requests_total&quot;,
  +        &quot;Parallel Agents&quot; =&gt; $nof_parallel_connections,
  +        &quot;Succeeded&quot;       =&gt; sprintf(&quot;$succeeded (%.2f%%)\n&quot;,
  +                                   $succeeded * 100 / $nof_requests_total),
  +        &quot;Errors&quot;          =&gt; $errors,
  +        &quot;Total Time&quot;      =&gt; sprintf(&quot;%.2f secs\n&quot;, $total_time),
  +        &quot;Throughput&quot;      =&gt; sprintf(&quot;%.2f Requests/sec\n&quot;, 
  +                                   $nof_requests_total / $total_time),
  +        &quot;Latency&quot;         =&gt; sprintf(&quot;%.2f secs/Request&quot;, 
  +                                   $ua-&gt;get_latency_total() / 
  +                                   $nof_requests_total),
  +       );
  +  
  +  
  +  my ($left, $right);
  +  ###
  +  # Print out statistics
  +  ###
  +  format STDOUT =
  +  @&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt; @*
  +  &quot;$left:&quot;,        $right
  +  .
  +  
  +  while(($left, $right) = splice(@P, 0, 2)) {
  +    write;
  +  }
  +</PRE>
  +<P>
  +<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<CENTER><H2><A NAME="Choosing_MaxClients">Choosing MaxClients</A></H2></CENTER>
  +<P>
  +The <CODE>MaxClients</CODE> directive sets the limit on the number of simultaneous requests that can be
  +supported; not more than this number of child server processes will be
  +created. To configure more than 256 clients, you must edit the <CODE>HARD_SERVER_LIMIT</CODE> entry in <CODE>httpd.h</CODE>
  +and recompile. In our case we want this variable to be as small as
  +possible, this way we can virtually bound the resources used by the server
  +children. Since we can restrict each child's process size (see
  +<A HREF="././performance.html#Limiting_the_size_of_the_process">Limiting the size of the processes</A>) -- the calculation of <CODE>MaxClients</CODE> is pretty straightforward :
  +
  +<P>
  +<PRE>  MaxClients = Total RAM Dedicated to the Webserver / MAX child's process size
  +</PRE>
  +<P>
  +So if I have 400Mb left for the webserver to run with, I can set the
  +<CODE>MaxClients</CODE> to be of 40 if I know that each child is bounded to the 10Mb of memory
  +(e.g. with
  +<A HREF="././performance.html#Limiting_the_size_of_the_process"><CODE>Apache::SizeLimit</CODE></A>).
  +
  +<P>
  +Certainly you will wonder what happens to your server if there are more
  +than <CODE>MaxClients</CODE> concurrent users at some moment. This situation is accompanied by the
  +following warning message into the
  +<CODE>error.log</CODE> file:
  +
  +<P>
  +<PRE>  [Sun Jan 24 12:05:32 1999] [error] server reached MaxClients setting,
  +  consider raising the MaxClients setting
  +</PRE>
  +<P>
  +There is no problem -- any connection attempts over the <CODE>MaxClients</CODE>
  +limit will normally be queued, up to a number based on the
  +<CODE>ListenBacklog</CODE> directive. Once a child process is freed at the end of a different request,
  +the connection will then be served.
  +
  +<P>
  +But it <STRONG>is an error</STRONG> because clients are being put in the queue rather than getting served at
  +once, despite the fact that they do not get an error response. The error
  +can be allowed to persist to balance available system resources and
  +response time, but sooner or later you will need to get more RAM so you can
  +start more children. The best approach is to try not to have this condition
  +reached at all, and if reached you should start to worry about it.
  +
  +<P>
  +It's important to understand how much real memory a child occupies. Your
  +children can share the memory between them (when OS supports that and you
  +take action to allow the sharing happen - See
  +<A HREF="././performance.html#Preload_Perl_modules_at_server_s">Preload Perl modules at server startup</A>). If this is the case, chances are that your <CODE>MaxClients</CODE> can be even higher. But it seems that it's not so simple to calculate the
  +absolute number. (If you come up with solution please let us know!). If the
  +shared memory was of the same size through the child's life, we could
  +derive a much better formula:
  +
  +<P>
  +<PRE>  MaxClients=(Total_RAM+Shared_RAM_per_Child*MaxClients)/Max_Process_Size-1
  +</PRE>
  +<P>
  +which is:
  +
  +<P>
  +<PRE>  MaxClients=(Total_RAM-Max_Process_Size)/(Max_Process_Size-Shared_RAM_per_Child)
  +</PRE>
  +<P>
  +<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<CENTER><H2><A NAME="Choosing_MaxRequestsPerChild">Choosing MaxRequestsPerChild</A></H2></CENTER>
  +<P>
  +The <CODE>MaxRequestsPerChild</CODE> directive sets the limit on the number of requests that an individual child
  +server process will handle. After
  +<CODE>MaxRequestsPerChild</CODE> requests, the child process will die. If
  +<CODE>MaxRequestsPerChild</CODE> is 0, then the process will live forever.
  +
  +<P>
  +Setting <CODE>MaxRequestsPerChild</CODE> to a non-zero limit has two beneficial effects: it solves memory leakages
  +and helps reduce the number of processes when the server load reduces.
  +
  +<P>
  +The first reason is the most crucial for mod_perl, since sloppy programming
  +will cause a child process to consume more memory after each request. If
  +left unbounded, then after a certain number of requests the children will
  +use up all the available memory and leave the server to die from memory
  +starvation. Note, that sometimes standard system libraries leak memory too,
  +especially on OSes with bad memory management (e.g. Solaris 2.5 on x86
  +arch). If this is your case you can set <CODE>MaxRequestsPerChild</CODE> to a small number, which will allow the system to reclaim the memory,
  +greedy child process consumed, when it exits after <CODE>MaxRequestsPerChild</CODE> requests. But beware -- if you set this number too low, you will loose the
  +speed bonus you receive with mod_perl. Consider using <CODE>Apache::PerlRun</CODE> if this is the case. Also setting <CODE>MaxSpareServers</CODE> to a number close to
  +<CODE>MaxClients</CODE>, will improve the response time (but your parent process will be busy
  +respawning new children all the time!)
  +
  +<P>
  +Another approach is to use <CODE>Apache::SizeLimit</CODE> (See <A HREF="././performance.html#Limiting_the_size_of_the_process">Limiting the size of the processes</A>). By using this module, you should be able to discontinue using the
  +<CODE>MaxRequestsPerChild</CODE>, although for some folks, using both in combination does the job.
  +
  +<P>
  +See also <A HREF="././performance.html#Preload_Perl_modules_at_server_s">Preload Perl modules at server startup</A> and
  +<A HREF="././performance.html#Sharing_Memory">Sharing Memory</A>.
  +
  +<P>
  +<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<CENTER><H2><A NAME="Choosing_MinSpareServers_MaxSpa">Choosing MinSpareServers, MaxSpareServers and StartServers</A></H2></CENTER>
  +<P>
  +With mod_perl enabled, it might take as much as 30 seconds from the time
  +you start the server until it is ready to serve incoming requests. This
  +delay depends on the OS, the number of preloaded modules and the process
  +load of the machine. So it's best to set
  +<CODE>StartServers</CODE> and <CODE>MinSpareServers</CODE> to high numbers, so that if you get a high load just after the server has
  +been restarted, the fresh servers will be ready to serve requests
  +immediately. With mod_perl, it's usually a good idea to raise all 3
  +variables higher than normal. In order to maximize the benefits of
  +mod_perl, you don't want to kill servers when they are idle, rather you
  +want them to stay up and available to immediately handle new requests. I
  +think an ideal configuration is to set <CODE>MinSpareServers</CODE> and <CODE>MaxSpareServers</CODE> to similar values, maybe even the same. Having the <CODE>MaxSpareServers</CODE>
  +close to <CODE>MaxClients</CODE> will completely use all of your resources (if
  +<CODE>MaxClients</CODE> has been chosen to take the full advantage of the resources), but it'll
  +make sure that at any given moment your system will be capable of
  +responding to requests with the maximum speed (given that number of
  +concurrent requests is not higher then
  +<CODE>MaxClients</CODE>.)
  +
  +<P>
  +Let's try some numbers. For a heavily loaded web site and a dedicated
  +machine I would think of (note 400Mb is just for example):
  +
  +<P>
  +<PRE>  Available to webserver RAM:   400Mb
  +  Child's memory size bounded:  10Mb
  +  MaxClients:                   400/10 = 40 (larger with mem sharing)
  +  StartServers:                 20
  +  MinSpareServers:              20
  +  MaxSpareServers:              35
  +</PRE>
  +<P>
  +However if I want to use the server for many other tasks, but make it
  +capable of handling a high load, I'd think of:
  +
  +<P>
  +<PRE>  Available to webserver RAM:   400Mb
  +  Child's memory size bounded:  10Mb
  +  MaxClients:                   400/10 = 40
  +  StartServers:                 5
  +  MinSpareServers:              5
  +  MaxSpareServers:              10
  +</PRE>
  +<P>
  +(These numbers are taken off the top of my head, and it shouldn't be used
  +as a rule, but rather as examples to show you some possible scenarios. Use
  +this information wisely!)
  +
  +<P>
  +<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<CENTER><H2><A NAME="Summary_of_Benchmarking_to_tune_">Summary of Benchmarking to tune all 5 parameters</A></H2></CENTER>
  +<P>
  +OK, we've run various benchmarks -- let's summarize the conclusions:
  +
  +<UL>
  +<P><LI><STRONG><A NAME="item_MaxRequestsPerChild">MaxRequestsPerChild</A></STRONG>
  +<P>
  +If your scripts are clean and don't leak memory, set this variable to a
  +number as large as possible (10000?). If you use
  +<CODE>Apache::SizeLimit</CODE>, you can set this parameter to 0 (equal to infinity). You will want this
  +parameter to be smaller if your code becomes unshared over the process'
  +life.
  +
  +<P><LI><STRONG><A NAME="item_StartServers">StartServers</A></STRONG>
  +<P>
  +If you keep a small number of servers active most of the time, keep this
  +number low. Especially if <CODE>MaxSpareServers</CODE> is low as it'll kill the just loaded servers before they were utilized at
  +all (if there is no load). If your service is heavily loaded, make this
  +number close to
  +<CODE>MaxClients</CODE> (and keep <CODE>MaxSpareServers</CODE> equal to <CODE>MaxClients</CODE> as well.)
  +
  +<P><LI><STRONG><A NAME="item_MinSpareServers">MinSpareServers</A></STRONG>
  +<P>
  +If your server performs other work besides web serving, make this low so
  +the memory of unused children will be freed when there is no big load. If
  +your server's load varies (you get loads in bursts) and you want fast
  +response for all clients at any time, you will want to make it high, so
  +that new children will be respawned in advance and be waiting to handle
  +bursts of requests.
  +
  +<P><LI><STRONG><A NAME="item_MaxSpareServers">MaxSpareServers</A></STRONG>
  +<P>
  +The logic is the same as of <CODE>MinSpareServers</CODE> - low if you need the machine for other tasks, high if it's a dedicated web
  +host and you want a minimal response delay.
  +
  +<P><LI><STRONG><A NAME="item_MaxClients">MaxClients</A></STRONG>
  +<P>
  +Not too low, so you don't get into a situation where clients are waiting
  +for the server to start serving them (they might wait, but not for too
  +long). Do not set it too high, since if you get a high load and all
  +requests will be immediately granted and served, your CPU will have a hard
  +time keeping up, and if the child's size * number of running children is
  +larger than the total available RAM, your server will start swapping (which
  +will slow down everything, which in turn will make things even more slower,
  +until eventually your machine will die). It's important that you take pains
  +to ensure that swapping does not normally happen. Swap space is an
  +emergency pool, not a resource to be used on a consistent basis. If you are
  +low on memory and you badly need it - buy it, memory is amazingly cheap
  +these days. 
  +
  +<P>
  +But based on the test I conducted above, even if you have plenty of memory
  +like I have (1Gb), increasing <CODE>MaxClients</CODE> sometimes will give you no speedup. The more clients are running, the more
  +CPU time will be required, the less CPU time slices each process will
  +receive. The response latency (the time to respond to a request) will grow,
  +so you won't see the expected improvement. The best approach is to find the
  +minimum requirement for your kind of service and the maximum capability of
  +your machine. Then start at the minimum and test like I did, successively
  +raising this parameter until you find the point on the curve of the graph
  +of the latency or/and throughput where the improvement becomes smaller.
  +Stop there and use it. Of course when you use these parameters in
  +production server, you will have the ability to tune them more precisely,
  +since then you will see the real numbers. Also don't forget that if you add
  +more scripts, or just modify the running ones -- most probably that the
  +parameters need to be recalculated, since the processes will grow in size
  +as you compile in more code.
  +
  +</UL>
  +<P>
  +<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<CENTER><H1><A NAME="Persistent_DB_Connections">Persistent DB Connections</A></H1></CENTER>
  +<P>
  +Another popular use of mod_perl is to take advantage of its ability to
  +maintain persistent open database connections. The basic approach is as
  +follows:
  +
  +<P>
  +<PRE>  # Apache::Registry script
  +  -------------------------
  +  use strict;
  +  use vars qw($dbh);
  +  
  +  $dbh ||= SomeDbPackage-&gt;connect(...);
   </PRE>
   <P>
  -If your registry scripts are all located in the same directory, and your
  -aliasing rules consistent, you can use this macro:
  +Since <CODE>$dbh</CODE> is a global variable for the child, once the child has opened the
  +connection it will use it over and over again, unless you perform <CODE>disconnect()</CODE>.
   
   <P>
  -<PRE>        # set up a registry script for a specific location
  -        &lt;Macro registry $location $script&gt;
  -        Alias /script /usr/www/scripts/$script
  -        &lt;Location $location&gt;
  -        SetHandler &quot;perl-script&quot;
  -        PerlHandler Apache::Registry
  -        Options +ExecCGI
  -        &lt;/Location&gt;
  -        &lt;/Macro&gt;
  -</PRE>
  +Be careful to use different names for handlers if you open connection to
  +different databases!
  +
   <P>
  -<PRE>        # example
  -        Use registry stuff stuff.pl
  -</PRE>
  +<CODE>Apache::DBI</CODE> allows you to make a persistent database connection. With this module
  +enabled, every <CODE>connect()</CODE> request to the plain <CODE>DBI</CODE> module will be forwarded to the <CODE>Apache::DBI</CODE>
  +module. This looks to see whether a database handle from a previous
  +<CODE>connect()</CODE> request has already been opened, and if this handle is still valid using
  +the ping method. If these two conditions are fulfilled it just returns the
  +database handle. If there is no appropriate database handle or if the ping
  +method fails, a new connection is established and the handle is stored for
  +later re-use. <STRONG>There is no need to delete the <CODE>disconnect()</CODE> statements
  +from your code</STRONG>. They will not do a thing, as the <CODE>Apache::DBI</CODE>
  +module overloads the <CODE>disconnect()</CODE> method with a NOP. On child's exit there is no explicit disconnect, the
  +child dies and so does the database connection. You may leave the <CODE>use DBI;</CODE> statement inside the scripts as well.
  +
   <P>
  -If you're using content handlers packaged as modules, you can use the
  -following macro:
  +The usage is simple -- add to <CODE>httpd.conf</CODE>:
   
   <P>
  -<PRE>        # set up a mod_perl content handler module
  -        &lt;Macro modperl $module&gt;
  -        SetHandler &quot;perl-script&quot;
  -        Options +ExecCGI
  -        PerlHandler $module
  -        &lt;/Macro&gt;
  +<PRE>  PerlModule Apache::DBI
   </PRE>
   <P>
  -<PRE>        #examples
  -        &lt;Location /perl-status&gt;
  -        PerlSetVar StatusPeek On
  -        PerlSetVar StatusGraph On
  -        PerlSetVar StatusDumper On
  -        Use modperl Apache::Status
  -        &lt;/Location&gt;
  +It is important, to load this module before any other <CODE>ApacheDBI*</CODE> module!
  +
  +<P>
  +<PRE>  db.pl
  +  ------------
  +  use DBI;
  +  use strict;
  +  
  +  my $dbh = DBI-&gt;connect( 'DBI:mysql:database', 'user', 'password',
  +                          { autocommit =&gt; 0 }
  +                        ) || die $DBI::errstr;
  +  
  +  ...rest of the program
   </PRE>
   <P>
  -The following macro sets up a Location for use with HTML::Embperl. Here we
  -define all ``.html'' files to be processed by Embperl.
  +If you use <CODE>DBI</CODE> for DB connections, and you use <CODE>Apache::DBI</CODE> to make them persistent, it also allows you to preopen connections to DB
  +for each child with <CODE>connect_on_init()</CODE> method, thus saving up a connection overhead on the very first request of
  +every child.
   
   <P>
  -<PRE>        &lt;Macro embperl&gt;
  -        SetHandler &quot;perl-script&quot;
  -        Options +ExecCGI
  -        PerlHandler HTML::Embperl
  -        PerlSetEnv EMBPERL_FILESMATCH \.html$
  -        &lt;/Macro&gt;
  +<PRE>  use Apache::DBI ();
  +  Apache::DBI-&gt;connect_on_init(&quot;DBI:mysql:test&quot;,
  +                               &quot;login&quot;,
  +                               &quot;passwd&quot;,
  +                               {
  +                                RaiseError =&gt; 1,
  +                                PrintError =&gt; 0,
  +                                AutoCommit =&gt; 1,
  +                               }
  +                              );
   </PRE>
   <P>
  -<PRE>        # examples
  -        &lt;Location /mrtg&gt;
  -        Use embperl
  -        &lt;/Location&gt;
  -</PRE>
  +This can be used as a simple way to have apache children establish
  +connections on server startup. This call should be in a startup file
  +<CODE>require()d</CODE> by <CODE>PerlRequire</CODE> or inside &lt;Perl&gt; section. It will establish a connection when a child is started in
  +that child process. See the <CODE>Apache::DBI</CODE> manpage to see the requirements for this method.
  +
   <P>
  -Macros are also very useful for things that tend to be verbose, such as
  -setting up Basic Authentication:
  +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
  +<CODE>DBD</CODE> drivers don't have this method, check the <CODE>Apache::DBI</CODE>
  +manpage to see how to write a <CODE>ping()</CODE> method.
   
   <P>
  -<PRE>        # Sets up Basic Authentication
  -        &lt;Macro BasicAuth $realm $group&gt;
  -        Order deny,allow
  -        Satisfy any
  -        AuthType Basic
  -        AuthName $realm
  -        AuthGroupFile /usr/www/auth/groups
  -        AuthUserFile /usr/www/auth/users
  -        Require group $group
  -        Deny from all
  -        &lt;/Macro&gt;
  -</PRE>
  +Another approach is to change the client's connection timeout. For mysql
  +users, starting from mysql-3.22.x you can set a <CODE>wait_timeout</CODE>
  +option at mysqld server startup to change the default value. Setting it to
  +36 hours probably would fix the timeout problem.
  +
   <P>
  -<PRE>        # example of use
  -        &lt;Location /stats&gt;
  -        Use BasicAuth WebStats Admin
  -        &lt;/Location&gt;
  -</PRE>
  +<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<CENTER><H1><A NAME="Using_1_under_mod_perl_and_be">Using $|=1 under mod_perl and better print() techniques.</A></H1></CENTER>
   <P>
  -Finally, here is a complete example that uses macros to set up simple
  -virtual hosts. It uses the BasicAuth macro defined previously (yes, macros
  -can be nested!).
  +As you know <CODE>local $|=1;</CODE> disables the buffering of the currently selected file handle (default is <CODE>STDOUT</CODE>). If you enable it,
  +<CODE>ap_rflush()</CODE> is called after each <CODE>print()</CODE>, unbuffering Apache's IO.
   
   <P>
  -<PRE>        &lt;Macro vhost $ip $domain $docroot $admingroup&gt;
  -        &lt;VirtualHost $ip&gt;
  -        ServerAdmin webmaster@$domain
  -        DocumentRoot /usr/www/htdocs/$docroot
  -        ServerName www.$domain
  -        &lt;Location /stats&gt;
  -        Use BasicAuth Stats-$domain $admingroup
  -        &lt;/Location&gt;
  -        &lt;/VirtualHost&gt;
  -        &lt;/Macro&gt;
  -</PRE>
  +If you are using a _bad_ style in generating output, which consist of
  +multiple <CODE>print()</CODE> calls, or you just have too many of them, you will experience a degradation
  +in performance. The severity depends on the number of the calls you make.
  +
   <P>
  -<PRE>        # define some virtual hosts
  -        Use vhost 10.1.1.1 example.com example example-admin
  -        Use vhost 10.1.1.2 example.net examplenet examplenet-admin
  +Many old CGIs were written in the style of:
  +
  +<P>
  +<PRE>  print &quot;&lt;BODY BGCOLOR=\&quot;black\&quot; TEXT=\&quot;white\&quot;&gt;&quot;;
  +  print &quot;&lt;H1&gt;&quot;;
  +  print &quot;Hello&quot;;
  +  print &quot;&lt;/H1&gt;&quot;;
  +  print &quot;&lt;A HREF=\&quot;foo.html\&quot;&gt; foo &lt;/A&gt;&quot;;
  +  print &quot;&lt;/BODY&gt;&quot;;
   </PRE>
   <P>
  -mod_macro also useful in a non vhost setting. Some sites for example have
  -lots of scripts where people use to view various statistics, email settings
  -and etc. It is much easier to read things like:
  +which reveals the following drawbacks: multiple <CODE>print()</CODE> calls - performance degradation with <CODE>$|=1</CODE>, backslashism which makes the code less readable and more difficult to
  +format the HTML to be easily readable as CGI's output. The code below
  +solves them all:
   
   <P>
  -<PRE>  use /forwards email/showforwards
  -  use /webstats web/showstats
  +<PRE>  print qq{
  +    &lt;BODY BGCOLOR=&quot;black&quot; TEXT=&quot;white&quot;&gt;
  +      &lt;H1&gt;
  +        Hello
  +      &lt;/H1&gt;
  +      &lt;A HREF=&quot;foo.html&quot;&gt; foo &lt;/A&gt;
  +    &lt;/BODY&gt;
  +  };
   </PRE>
   <P>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<CENTER><H1><A NAME="General_pitfalls">General pitfalls</A></H1></CENTER>
  +I guess you see the difference. Be careful though, when printing a
  +<CODE>&lt;HTML</CODE>&gt; tag. The correct way is:
  +
   <P>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<CENTER><H2><A NAME="My_cgi_perl_code_is_being_return">My cgi/perl code is being returned as a plain text instead of being executed by the webserver?</A></H2></CENTER>
  +<PRE>  print qq{&lt;HTML&gt;
  +    &lt;HEAD&gt;&lt;/HEAD&gt;
  +    &lt;BODY&gt;
  +  }
  +</PRE>
   <P>
  -Check your configuration files and make sure that the ``ExecCGI'' is turned
  -on in your configurations. 
  +If you try the following:
   
   <P>
  -<PRE>  &lt;Location /perl&gt;
  -    SetHandler perl-script
  -    PerlHandler Apache::Registry
  -    Options ExecCGI
  -    allow from all
  -    PerlSendHeader On
  -  &lt;/Location&gt;
  +<PRE>  print qq{
  +    &lt;HTML&gt;
  +    &lt;HEAD&gt;&lt;/HEAD&gt;
  +    &lt;BODY&gt;
  +  }
   </PRE>
  -<P>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<CENTER><H2><A NAME="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></H2></CENTER>
   <P>
  -Did you put <STRONG>PerlSendHeader On</STRONG> in the configuration part of the &lt;Location foo&gt;&lt;/Location&gt;?
  +Some older browsers might not accept the output as HTML, but rather print
  +it as a plain text, since they expect the first characters after the
  +headers and empty line to be <CODE>&lt;HTML</CODE>&gt; and not spaces and/or additional newline and then <CODE>&lt;HTML</CODE>&gt;. Even if it works with your browser, it might not work for others.
   
   <P>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<CENTER><H2><A NAME="Is_there_a_way_to_provide_a_diff">Is there a way to provide a different startup.pl file for each individual virtual host</A></H2></CENTER>
  +Now let's go back to the <CODE>$|=1</CODE> topic. I still disable buffering, for 2 reasons: I use few <CODE>print()</CODE> calls by printing out multiline HTML and not a line per <CODE>print()</CODE> and I want my users to see the output immediately. So if I am about to
  +produce the results of the DB query, which might take some time to
  +complete, I want users to get some titles ahead. This improves the
  +usability of my site. Recall yourself: What do you like better: getting the
  +output a bit slower, but steadily from the moment you've pressed the Submit
  +button or having to watch the ``falling stars'' for awhile and then to
  +receive the whole output at once, even a few millisecs faster (if the
  +client (browser) did not time out till then).
  +
   <P>
  -No. Any virtual host will be able to see the routines from a startup.pl
  -loaded for any other virtual host.  
  +Conclusion: Do not blindly follow suggestions, but think what is best for
  +you in every given case.
   
   <P>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<CENTER><H2><A NAME="Is_there_a_way_to_modify_INC_on">Is there a way to modify @INC on a per-virtual-host or per-location basis.</A></H2></CENTER>
  +<CENTER><H1><A NAME="More_Reducing_Memory_Usage_Tips">More Reducing Memory Usage Tips</A></H1></CENTER>
   <P>
  -You can use 'PerlSetEnv PERL5LIB ...' or a PerlFixupHandler w/ the lib
  -pragma.
  +One of the important issues in improving the performance is reduction of
  +memory usage - the less memory each server uses, the more server processes
  +you can start, and thus the more performance you have (from the user's
  +point of view - the response speed )
   
   <P>
  -Even a better way is to use <A HREF="././modules.html#Apache_PerlVINC_set_a_differe">Apache::PerlVINC</A>
  +See <A HREF="././porting.html#Global_Variables">Global Variables</A>
  +
  +
  +
  +<P>
  +See <A HREF="././porting.html#Memory_leakage">Memory "leakages"</A>
   
   
   
   <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><H1><A NAME="Profiling">Profiling</A></H1></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
  -file (PerlRequire):
  +Profiling process helps you to determine which subroutines or just snippets
  +of code take the longest execution time and which subroutines are being
  +called most often. Probably you will want to optimize those, and to improve
  +the code toward efficiency.
   
   <P>
  -<PRE>  $Apache::Registry::NameWithVirtualHost = 1;
  -</PRE>
  -<P>
  -But, as we know sometimes bug turns into a feature. If there is the same
  -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)
  +It is possible to profile code running under mod_perl with the
  +<CODE>Devel::DProf</CODE> module, available on CPAN. However, you must have apache version 1.3b3 or
  +higher and the <CODE>PerlChildExitHandler</CODE> enabled (during the httpd build process). When the server is started,
  +<CODE>Devel::DProf</CODE> installs an <CODE>END</CODE> block to write the <CODE>tmon.out</CODE>
  +file. This block will be called at the server shutdown. Here is how to
  +start and stop a server with the profiler enabled:
   
   <P>
  -<PRE>  $Apache::Registry::NameWithVirtualHost = 0;
  +<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>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<CENTER><H2><A NAME="the_server_no_longer_retrieves_t">the server no longer retrieves the DirectoryIndex files for a directory</A></H2></CENTER>
  +The <CODE>Devel::DProf</CODE> package is a Perl code profiler. It will collect information on the
  +execution time of a Perl script and of the subs in that script (remember
  +that <CODE>print()</CODE> and <CODE>map()</CODE> are just like any other subroutines you write, but they are come bundled
  +with Perl!)
  +
   <P>
  -The problem was reported by users who declared mod_perl configuration
  -inside a &lt;Directory&gt; section for all files matching to *.pl. The
  -problem has gone away after placing the usage of mod_perl in a
  -&lt;File&gt;- section.
  +Another approach is to use <CODE>Apache::DProf</CODE>, which hooks
  +<CODE>Devel::DProf</CODE> into mod_perl. The <CODE>Apache::DProf</CODE> module will run a
  +<CODE>Devel::DProf</CODE> profiler inside each child server and write the
  +<CODE>tmon.out</CODE> file in the directory <CODE>$ServerRoot/logs/dprof/$$</CODE> when the child is shutdown (where <CODE>$$</CODE> is a number of the child process). All it takes is to add to <CODE>httpd.conf</CODE>:
   
   <P>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<CENTER><H1><A NAME="Configuration_Security_Concerns">Configuration Security Concerns</A></H1></CENTER>
  +<PRE>  PerlModule Apache::DProf
  +</PRE>
   <P>
  -It is better not to advertise the port mod_perl server running at to the
  -outside world for it creates a potential security risk by revealing which
  -<CODE>module(s)</CODE> and/or OS you are running your web server on.
  +Remember that any PerlHandler that was pulled in before
  +<CODE>Apache::DProf</CODE> in the <CODE>httpd.conf</CODE> or &lt;startup.pl&gt;, would not have its code debugging info inserted. To run <CODE>dprofpp</CODE>, chdir to
  +<CODE>$ServerRoot/logs/dprof/$$</CODE> and run:
   
   <P>
  -The more modules you have in your web server, the more complex the code in
  -your webserver.
  -
  +<PRE>  % dprofpp
  +</PRE>
   <P>
  -The more complex the code in your web server, the more chances for bugs.
  +<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<CENTER><H1><A NAME="CGI_pm_s_object_methods_calls_vs">CGI.pm's object methods calls vs. function calls</A></H1></CENTER>
  +<P>
  +Which approach is better?
   
  +<P>
  +<PRE>  use CGI;
  +  my $q = new CGI;
  +  print $q-&gt;param('x');
  +</PRE>
   <P>
  -The more chance for bugs, the more chance that some of those bugs may
  -involve security.
  +versus
   
   <P>
  -Never was completely sure why the default of the ServerToken directive in
  -Apache is Full rather than Minimal. Seems like you would only make it full
  -if you are debugging.
  -
  +<PRE>  use CGI (:standard);
  +  print param('x');
  +</PRE>
   <P>
  -For more information see <A HREF="././config.html#Publishing_port_numbers_differen">Publishing port numbers different from 80</A>
  -
  -
  +There is not any performance benefit of using the object calls rather than
  +the function calls, but there is a real memory hit when you import all of <CODE>CGI.pm</CODE>'s function calls into your process memory. This can be significant,
  +particularly when there are many child daemons.
   
   <P>
  -Another approach is to modify httpd sources to reveal no unwanted
  -information, so if you know the port the <CODE>HEAD</CODE> request will return an empty or phony <CODE>Server:</CODE> field.
  +I strongly endorse <A HREF="././modules.html#Apache_Request_libapreq_Gen">Apache::Request (libapreq) - Generic Apache Request Library</A>. Its guts are all written in C, giving it a significant memory and
  +performance benefit.
   
   <P>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<CENTER><H1><A NAME="Logical_grouping_of_Location_Di">Logical grouping of Location, Directory and FilesMatch directives</A></H1></CENTER>
  +<CENTER><H1><A NAME="Sending_plain_HTML_as_a_compress">Sending plain HTML as a compressed output</A></H1></CENTER>
   <P>
  -Let's say that you want all the file in a specific directory and below to
  -be handled the same way, but a few of them to be handled somewhat
  -different. For example:
  +See <A HREF="././modules.html#Apache_GzipChain_compress_HTM">Apache::GzipChain - compress HTML (or anything) in the OutputChain</A>
   
  -<P>
  -<PRE>  &lt;Directory /home/foo&gt;
  -    &lt;FilesMatch &quot;\.(html|txt)$&quot;&gt;
  -      SetHandler perl-script
  -      PerlHandler Apache::AddrMunge
  -    &lt;/FilesMatch&gt;
  -  &lt;/Directory&gt;
  -</PRE>
  -<P>
  -Alternatively you can use &lt;Files&gt; inside an <CODE>.htaccess</CODE> file.
   
  -<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><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
   	     The <a href="http://www.modperl.com/">
  @@ -4620,7 +5157,7 @@
   	     Amazon.com</a>.
   
   	     <HR>
  -	     [    <A HREF="install.html">Prev</A> |      <A HREF="index.html">Main Page</A> | <A HREF="frequent.html">Next</A>      ]
  +	     [    <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%" >
   <TR ALIGN=CENTER VALIGN=TOP>
  @@ -4633,7 +5170,7 @@
       <B>
         <FONT SIZE=-1>
   	     Written by <A HREF="help.html#This_document_s_Author">Stas Bekman</A>.
  -	     <BR>Last Modified at 06/05/1999
  +	     <BR>Last Modified at 06/26/1999
         </FONT>
       </B>
     </TD>
  @@ -4660,7 +5197,7 @@
   <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
   <HTML>
   <HEAD>
  -   <TITLE>mod_perl guide: Frequent mod_perl problems</TITLE>
  +   <TITLE>mod_perl guide: Choosing the Right Strategy</TITLE>
      <META NAME="GENERATOR" CONTENT="Pod2HTML [Perl/Linux]">
      <META NAME="Author" CONTENT="Stas Bekman">
      <META NAME="Description" CONTENT="All Apache/Perl related information: Hints, Guidelines, Scenarios and Troubleshottings">
  @@ -4679,15 +5216,20 @@
   <H1 ALIGN=CENTER>
   <A HREF="http://perl.apache.org"><IMG SRC="images/mod_perl.gif" ALT="Mod Perl Icon" BORDER=0 HEIGHT=30 WIDTH=90 ALIGN=LEFT></A>
   <A HREF="http://perl.apache.org"><IMG SRC="images/mod_perl.gif" ALT="Mod Perl Icon" BORDER=0 HEIGHT=30 WIDTH=90 ALIGN=RIGHT></A>
  -Frequent mod_perl problems</H1>
  +Choosing the Right Strategy</H1>
   <HR WIDTH="100%">
  -	    [    <A HREF="config.html">Prev</A> |      <A HREF="index.html">Main Page</A> | <A HREF="porting.html">Next</A>      ]<HR><!-- INDEX BEGIN -->
  +	    [    <A HREF="performance.html">Prev</A> |      <A HREF="index.html">Main Page</A> | <A HREF="scenario.html">Next</A>      ]<HR><!-- INDEX BEGIN -->
   <P><B><FONT SIZE=-1>Table of Contents:</FONT></B></P>
   <UL>
   
  -	<LI><A HREF="#Coverage">Coverage</A>
  -	<LI><A HREF="#my_scoped_variable_in_nested_s">my() scoped variable in nested subroutines</A>
  -	<LI><A HREF="#Segfaults_caused_by_PerlFreshRes">Segfaults caused by PerlFreshRestart</A>
  +	<LI><A HREF="#Do_it_like_me_">Do it like me?!</A>
  +	<LI><A HREF="#mod_perl_Deployment_Overview">mod_perl Deployment Overview</A>
  +	<LI><A HREF="#Standalone_mod_perl_Enabled_Apac">Standalone mod_perl Enabled Apache Server</A>
  +	<LI><A HREF="#One_Plain_and_One_mod_perl_enabl">One Plain and One mod_perl-enabled Apache Servers</A>
  +	<LI><A HREF="#One_light_non_Apache_and_One_mod">One light non-Apache and One mod_perl enabled Apache Servers</A>
  +	<LI><A HREF="#Adding_a_Proxy_Server_in_http_Ac">Adding a Proxy Server in http Accelerator Mode</A>
  +	<LI><A HREF="#The_Squid_Server">The Squid Server</A>
  +	<LI><A HREF="#An_Apache_s_mod_proxy">An Apache's mod_proxy</A>
   </UL>
   <!-- INDEX END -->
   
  @@ -4705,3459 +5247,3487 @@
   
   	      <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>
  +<CENTER><H1><A NAME="Do_it_like_me_">Do it like me?!</A></H1></CENTER>
   <P>
  -This new document was born because some problems come up so often on the
  -mailing list that should be stressed in the guide as one of the most
  -important things to read/beware of. So I have tried to enlist them in this
  -document. If you think some important problem that is being reported
  -frequently on the list and covered in the guide but not included below,
  -please tell.
  +There is no such a thing as a single <STRONG>RIGHT</STRONG> strategy in web server business, though there are many wrong ones. Never
  +believe a person who says: <EM>"Do it this way, this is the best!"</EM>. As the old saying goes:
  +<EM>"Trust but verify"</EM>. There are too many technologies out there to choose from, and it would
  +take an enormous investment of time and money to try to validate each one
  +before deciding which is the best choice for your situation. Keeping this
  +idea in mind, I will present some different combinations of mod_perl and
  +other technologies or just standalone mod_perl. I'll describe how these
  +things work together, and offer my opinions on the pros and cons of each,
  +the relative degree of difficulty in installing and maintaining them, some
  +hints on approaches that should be used and things to avoid.
   
   <P>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<CENTER><H1><A NAME="my_scoped_variable_in_nested_s">my() scoped variable in nested subroutines</A></H1></CENTER>
  +To be clear, I will not address all technologies and tools, but limit this
  +discussion to those complementing mod_perl.
  +
   <P>
  -See <A HREF="././obvious.html#my_scoped_variable_in_nested_s">my() scoped variable in nested subroutines</A>.
  +Please let me stress it again: <STRONG>DO NOT</STRONG> blindly copy someone's setup and hope for a good result. Choose what is
  +best for your situation -- it might take <STRONG>some</STRONG> effort to find it out.
   
   <P>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<CENTER><H1><A NAME="Segfaults_caused_by_PerlFreshRes">Segfaults caused by PerlFreshRestart</A></H1></CENTER>
  +<CENTER><H1><A NAME="mod_perl_Deployment_Overview">mod_perl Deployment Overview</A></H1></CENTER>
   <P>
  -See <A HREF="././warnings.html#Evil_things_might_happen_when_us">Evil things might happen when using PerlFreshRestart</A>
  +There are several different ways to build, configure and deploy your
  +mod_perl enabled server. Some of them are:
  +
  +<OL>
  +<P><LI>
  +<P>
  +Having one binary and one config file (one big binary for mod_perl).
  +
  +<P><LI>
  +<P>
  +Having two binaries and two config files (one big binary for mod_perl and
  +one small for static objects like images.)
  +
  +<P><LI>
  +<P>
  +Having one DSO-style binary, mod_perl loadable object and two config files
  +(Dynamic linking lets you compile once and have a big and a small binary in
  +memory BUT you have to deal with a freshly made solution that has weak
  +documentation and is still subject to change and is rather more complex.)
  +
  +<P><LI>
  +<P>
  +Any of the above plus a reverse proxy server in http accelerator mode.
  +
  +</OL>
  +<P>
  +If you are a newbie, I would recommend that you start with the first option
  +and work on getting your feet wet with apache and mod_perl. Later, you can
  +decide whether to move to the second one which allows better tuning at the
  +expense of more complicated administration, or to the third option -- the
  +more state-of-the-art-yet-suspiciously-new DSO system, or to the forth
  +option which gives you even more power.
  +
  +<OL>
  +<P><LI>
  +<P>
  +The first option will kill your production site if you serve a lot of
  +static data with ~2-12 MB webserver processes. On the other hand, while
  +testing you will have no other server interaction to mask or add to your
  +errors.
  +
  +<P><LI>
  +<P>
  +The second option allows you to seriously tune the two servers for maximum
  +performance. On the other hand you have to deal with proxying or fancy site
  +design to keep the two servers in synchronization. In this configuration,
  +you also need to choose between running the two servers on multiple ports,
  +multiple IPs, etc... This adds the burden of administrating more than one
  +server.
  +
  +<P><LI>
  +<P>
  +The third option (DSO) -- as mentioned above -- means playing with the
  +bleeding edge. In addition <CODE>mod_so</CODE> (the DSO module) adds size and complexity to your binaries. With DSO,
  +modules can be added and removed without recompiling the server, and
  +modules are even shared among multiple servers. Again, it is bleeding edge
  +and still somewhat platform specific, but your mileage may vary. See <A HREF="././scenario.html#mod_perl_server_as_DSO">mod_perl server as DSO</A>.
   
  +<P><LI>
  +<P>
  +The fourth option (proxy in http accelerator mode), once correctly
  +configured and tuned, improves the performance of any of the above three
  +options by caching and buffering page results.
   
  +</OL>
  +<P>
  +The rest of this chapter discusses the pros and the cons of each of these
  +presented configurations.  <A HREF="././scenario.html#">Real World Scenarios Implementaion</A> describes the implementation techniques of these schemas.
   
  +<P>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -	     The <a href="http://www.modperl.com/">
  -	     <B>Writing Apache Modules with Perl and C</B></a>
  -	     book can be purchased online from <a
  -	     href="http://www.ora.com/catalog/wrapmod/">O'Reilly </a>
  -	     and <a
  -	     href="http://www.amazon.com/exec/obidos/ASIN/156592567X/writinapachemodu">
  -	     Amazon.com</a>.
  +<CENTER><H1><A NAME="Standalone_mod_perl_Enabled_Apac">Standalone mod_perl Enabled Apache Server</A></H1></CENTER>
  +<P>
  +The first approach is to implement a straightforward mod_perl server. Just
  +take your plain apache server and add mod_perl, like you add any other
  +apache module. You continue to run it at the port it was running before.
  +You probably want to try this before you proceed to more sophisticated and
  +complex techniques.
   
  -	     <HR>
  -	     [    <A HREF="config.html">Prev</A> |      <A HREF="index.html">Main Page</A> | <A HREF="porting.html">Next</A>      ]
  +<P>
  +The advantages:
   
  -<CENTER><TABLE CELLSPACING=2 CELLPADDING=2 WIDTH="100%" >
  -<TR ALIGN=CENTER VALIGN=TOP>
  -  <TD ALIGN=CENTER VALIGN=CENTER COLSPAN="3">
  -	     <HR>
  -  </TD>
  -</TR>
  -<TR ALIGN=CENTER VALIGN=TOP>
  -  <TD ALIGN=CENTER VALIGN=CENTER>
  -    <B>
  -      <FONT SIZE=-1>
  -	     Written by <A HREF="help.html#This_document_s_Author">Stas Bekman</A>.
  -	     <BR>Last Modified at 05/08/1999
  -      </FONT>
  -    </B>
  -  </TD>
  +<UL>
  +<P><LI>
  +<P>
  +Simplicity. You just follow the installation instructions, configure it,
  +restart the server and you are done.
   
  -  <TD>
  -	     <A HREF="http://perl.apache.org"><IMG SRC="images/mod_perl2.jpg" ALT="Mod Perl Icon" BORDER=0 HEIGHT=59 WIDTH=150></A>
  -  </TD>
  +<P><LI>
  +<P>
  +No network changes. You do not have to worry about using additional ports
  +as we will see later.
   
  -  <TD>
  -    <FONT SIZE=-2>
  -	     Use of the Camel for Perl is <BR>
  -	     a trademark of <A HREF="http://www.ora.com">O'Reilly &amp; Associates</A>,<BR>
  -             and is used by permission. 
  -    </FONT> 
  -  </TD>
  -</TR>
  -</TABLE></CENTER>
  +<P><LI>
  +<P>
  +Speed. You get a very fast server, you see an enormous speedup from the
  +first moment you start to use it.
   
  -</BODY>
  -</HTML>
  -	    
  +</UL>
  +<P>
  +The disadvantages:
   
  -<HR SIZE=6>
  -<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
  -<HTML>
  -<HEAD>
  -   <TITLE>mod_perl guide: CGI to mod_perl Porting. mod_perl Coding guidelines.</TITLE>
  -   <META NAME="GENERATOR" CONTENT="Pod2HTML [Perl/Linux]">
  -   <META NAME="Author" CONTENT="Stas Bekman">
  -   <META NAME="Description" CONTENT="All Apache/Perl related information: Hints, Guidelines, Scenarios and Troubleshottings">
  -   <META NAME="keywords" CONTENT="mod_perl modperl perl apache cgi webserver speed  fast guide mod_perl apache guide help info faq mod_perl installation cgi troubleshooting help no sex speedup free open source OSS mod_perl apache guide">
  -</HEAD>
  -     <LINK REL=STYLESHEET TYPE="text/css"
  -        HREF="style.css" TITLE="refstyle">
  -     <style type="text/css">
  -     <!-- 
  -        @import url(style.css);
  -     -->
  -     
  -     </style>
  -<BODY TEXT="#000000" BGCOLOR="#E0FFFF" LINK="#0000EE" VLINK="#551A8B" ALINK="#FF0000">
  -<A NAME="toc"></A>
  -<H1 ALIGN=CENTER>
  -<A HREF="http://perl.apache.org"><IMG SRC="images/mod_perl.gif" ALT="Mod Perl Icon" BORDER=0 HEIGHT=30 WIDTH=90 ALIGN=LEFT></A>
  -<A HREF="http://perl.apache.org"><IMG SRC="images/mod_perl.gif" ALT="Mod Perl Icon" BORDER=0 HEIGHT=30 WIDTH=90 ALIGN=RIGHT></A>
  -CGI to mod_perl Porting. mod_perl Coding guidelines.</H1>
  -<HR WIDTH="100%">
  -	    [    <A HREF="frequent.html">Prev</A> |      <A HREF="index.html">Main Page</A> | <A HREF="performance.html">Next</A>      ]<HR><!-- INDEX BEGIN -->
  -<P><B><FONT SIZE=-1>Table of Contents:</FONT></B></P>
   <UL>
  +<P><LI>
  +<P>
  +The process size of a mod_perl-enabled Apache server is huge (starting from
  +4Mb at startup and growing to 10Mb and more, depending on how you use it)
  +compared to the typical plain Apache. Of course if memory sharing is in
  +place -- RAM requirements will be smaller.
   
  -	<LI><A HREF="#Document_Coverage">Document Coverage</A>
  -	<LI><A HREF="#Before_you_start_to_code">Before you start to code</A>
  -	<LI><A HREF="#Coding_with_mod_perl">Coding with mod_perl</A>
  -	<UL>
  +<P>
  +You probably have a few tens of children processes. The additional memory
  +requirements add up in direct relation to the number of children processes.
  +Your memory demands are growing by an order of magnitude, but this is the
  +price you pay for the additional performance boost of mod_perl. With memory
  +prices so cheap nowadays, the additional cost is low -- especially when you
  +consider the dramatic performance boost mod_perl gives to your services
  +with every 100Mb of RAM you add.
   
  -		<LI><A HREF="#What_s_different_about_modperl">What's different about modperl</A>
  -		<UL>
  +<P>
  +While you will be happy to have these monster processes serving your
  +scripts with monster speed, you should be very worried about having them
  +serve static objects such as images and html files. Each static request
  +served by a mod_perl-enabled server means another large process running,
  +competing for system resources such as memory and CPU cycles. The real
  +overhead depends on static objects request rate. Remember that if your
  +mod_perl code produces HTML code which includes images, each one will turn
  +into another static object request. Having another plain webserver to serve
  +the static objects solves this not pleasant obstacle. Having a proxy server
  +as a front end, caching the static objects and freeing the mod_perl
  +processes from this burden is another solution. We will discuss both below.
   
  -			<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="#_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>
  -		</UL>
  +<P><LI>
  +<P>
  +Another drawback of this approach is that when serving output to a client
  +with a slow connection, the huge mod_perl-enabled server process (with all
  +of its system resources) will be tied up until the response is completely
  +written to the client. While it might take a few milliseconds for your
  +script to complete the request, there is a chance it will be still busy for
  +some number of seconds or even minutes if the request is from a slow
  +connection client. As in the previous drawback, a proxy solution can solve
  +this problem. More on proxies later.
   
  -		<LI><A HREF="#strict_pragma">strict pragma</A>
  -		<LI><A HREF="#Turning_warnings_ON">Turning warnings ON</A>
  -		<LI><A HREF="#diagnostics_pragma">diagnostics pragma</A>
  -		<LI><A HREF="#Global_Variables">Global Variables</A>
  -		<LI><A HREF="#Passing_ENV_variables_to_CGI">Passing ENV variables to CGI</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="#Memory_leakage">Memory leakage</A>
  -	</UL>
  +<P>
  +Proxying dynamic content is not going to help much if all the clients are
  +on a fast local net (for example, if you are administering an Intranet.) On
  +the contrary, it can decrease performance. Still, remember that some of
  +your Intranet users might work from home through the slow modem links.
   
  -	<LI><A HREF="#Filehandlers_and_locks_leakages">Filehandlers and locks leakages</A>
  -	<LI><A HREF="#Sometimes_it_Works_Sometimes_it_">Sometimes it Works Sometimes it does Not (Very important!)</A>
  -	<LI><A HREF="#The_Script_is_too_dirty_It_does">The Script is too dirty, It does the job and I can't afford rewriting it.</A>
  -	<LI><A HREF="#Apache_PerlRun_a_closer_look">Apache::PerlRun - a closer look</A>
  -	<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>
   </UL>
  -<!-- INDEX END -->
  +<P>
  +If you are new to mod_perl, this is probably the best way to get yourself
  +started.
   
  -<HR>
  +<P>
  +And of course, if your site is serving only mod_perl scripts (close to zero
  +static objects, like images), this might be the perfect choice for you!
   
  -	     The <a href="http://www.modperl.com/">
  -	     <B>Writing Apache Modules with Perl and C</B></a>
  -	     book can be purchased online from <a
  -	     href="http://www.ora.com/catalog/wrapmod/">O'Reilly </a>
  -	     and <a
  -	     href="http://www.amazon.com/exec/obidos/ASIN/156592567X/writinapachemodu">
  -	     Amazon.com</a>.
  +<P>
  +For implementation notes see : <A HREF="././scenario.html#One_Plain_and_One_mod_perl_enabl">One Plain and One mod_perl enabled Apache Servers</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>
  +<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<CENTER><H1><A NAME="One_Plain_and_One_mod_perl_enabl">One Plain and One mod_perl-enabled Apache Servers</A></H1></CENTER>
   <P>
  -This document is relevant to both writing a new CGI from scratch and
  -migrating an application from plain CGI to mod_perl.
  +As I have mentioned before, when running scripts under mod_perl, you will
  +notice that the httpd processes consume a huge amount of memory, from 5M to
  +25M, or even more. That is the price you pay for the enormous speed
  +improvements under mod_perl. (Again -- shared memory keeps them smaller :)
   
   <P>
  -If you are in the porting stage, use it as a reference for possible
  -problems you might encounter when running the existent CGI in the new mode.
  +Using these large processes to serve static objects like images and html
  +documents is overkill. A better approach is to run two servers: a very
  +light, plain apache server to serve static objects and a heavier
  +mod_perl-enabled apache server to serve requests for dynamic (generated)
  +objects (aka CGI).
   
   <P>
  -If you are about to write a new CGI from scratch, it would be a good idea
  -to learn most of the possible pitfalls and to avoid them in first place.
  +From here on, I will refer to these two servers as <STRONG>httpd_docs</STRONG>
  +(vanilla apache) and <STRONG>httpd_perl</STRONG> (mod_perl enabled apache).
   
   <P>
  -It covers also the case where the CGI script being ported does the job, but
  -is too dirty to be easily altered to run as a mod_perl program.
  -(Apache::PerlRun)
  +The advantages:
   
  +<UL>
  +<P><LI>
   <P>
  -If your project schedule is tight, I would suggest converting to mod_perl
  -in the following steps: Initially, run all the scripts in the
  -Apache::PerlRun mode. Then as time allows, move them into Apache::Registry
  -mode.
  +The heavy mod_perl processes serve only dynamic requests, which allows the
  +deployment of fewer of these large servers.
   
  -<P>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<CENTER><H1><A NAME="Before_you_start_to_code">Before you start to code</A></H1></CENTER>
  +<P><LI>
   <P>
  -It can be a good idea to tighten up some of your Perl programming
  -practices, since Apache::Registry doesn't allow sloppy programming.
  +<CODE>MaxClients</CODE>, <CODE>MaxRequestsPerChild</CODE> and related parameters can now be optimally tuned for both <CODE>httpd_docs</CODE> and <CODE>httpd_perl</CODE> servers, something we could not do before. This allows us to fine tune the
  +memory usage and get a better server performance.
   
   <P>
  -You might want to read:
  +Now we can run many lightweight <CODE>httpd_docs</CODE> servers and just a few heavy <CODE>httpd_perl</CODE> servers.
   
  -<UL>
  -<P><LI><STRONG><A NAME="item_Perl">Perl Module Mechanics</A></STRONG>
  +</UL>
   <P>
  -This page describes the mechanics of creating, compiling, releasing, and
  -maintaining Perl modules. <A
  -HREF="http://world.std.com/~swmcd/steven/perl/module_mechanics.html">http://world.std.com/~swmcd/steven/perl/module_mechanics.html</A>
  +An <STRONG>important</STRONG> note: When user browses static pages and the base URL in the <STRONG>Location</STRONG> window points to the static server, for example
  +<CODE>http://www.nowhere.com/index.html</CODE> -- all relative URLs (e.g. <CODE>&lt;A
  +HREF=&quot;/main/download.html&quot;</CODE>&gt;) are being served by the light plain apache server. But this is not
  +the case with dynamically generated pages. For example when the base URL in
  +the <STRONG>Location</STRONG> window points to the dynamic server -- (e.g. <CODE>http://www.nowhere.com:8080/perl/index.pl</CODE>) all relative URLs in the dynamically generated HTML will be served by the
  +heavy mod_perl processes. You must use a fully qualified URLs and not the
  +relative ones! <CODE>http://www.nowhere.com/icons/arrow.gif</CODE> is a full URL, while
  +<CODE>/icons/arrow.gif</CODE> is a relative one. Using <CODE>&lt;BASE
  +HREF=&quot;http://www.nowhere.com/&quot;</CODE>&gt; in the generated HTML is another way to handle this problem. Also the <CODE>httpd_perl</CODE> server could rewrite the requests back to <CODE>httpd_docs</CODE> (much slower) and you still need an attention of the heavy servers. This is
  +not an issue if you hide the internal port implementations, so client sees
  +only one server running on port <CODE>80</CODE>. (See <A HREF="././config.html#Publishing_port_numbers_differen">Publishing port numbers different from 80</A>)
   
  +<P>
  +The disadvantages:
   
  -<P><LI><STRONG><A NAME="item_Mod">Mod Perl Book</A></STRONG>
  +<UL>
  +<P><LI>
   <P>
  -A must have book! See the details at <A
  -HREF="http://www.modperl.com">http://www.modperl.com</A> .
  +An administration overhead.
   
  -</UL>
  +<UL>
  +<P><LI>
   <P>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<CENTER><H1><A NAME="Coding_with_mod_perl">Coding with mod_perl</A></H1></CENTER>
  +A need for two different sets of configuration, log and other files. We
  +need a special directory layout to manage these. While some directories can
  +be shared between the two servers (like the <CODE>include</CODE>
  +directory, containing the apache include files -- assuming that both are
  +built from the same source distribution), most of them should be separated
  +and the configuration files updated to reflect the changes.
  +
  +<P><LI>
   <P>
  -Before you start coding for Apache::Registry, 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.
  +A need for two sets of controlling scripts (startup/shutdown) and
  +watchdogs.
   
  +<P><LI>
   <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.
  +If you are processing log files, now you probably will have to merge the
  +two separate log files into one before processing them.
   
  +</UL>
  +<P><LI>
   <P>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<CENTER><H2><A NAME="What_s_different_about_modperl">What's different about modperl</A></H2></CENTER>
  +We still have the problem of a mod_perl process spending its precious time
  +serving slow clients, when the processing portion of the request was
  +completed long time ago, exactly as in the one server approach. Deploying a
  +proxy solves this, and will be covered in the next sections.
  +
   <P>
  -There are a few things that behave differently under mod_perl. It's good to
  -know what they are.
  +As with only one server approach, this is not a major disadvantage if you
  +are on a fast local Intranet. It is likely that you do not want a buffering
  +server in this case.
   
  +</UL>
   <P>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<CENTER><H3><A NAME="Script_s_name_space">Script's name space</A></H3></CENTER>
  +Before you go on with this solution you really want to look at the
  +<A HREF="././strategy.html#Adding_a_Proxy_Server_in_http_Ac">Adding a Proxy Server in http Accelerator Mode</A> section.
  +
   <P>
  -Scripts under Apache::Registry 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 
  -<STRONG>Apache::ROOT::perl::test_2epl;</STRONG>
  +For implementation notes see : <A HREF="././scenario.html#One_Plain_and_One_mod_perl_enabl">One Plain and One mod_perl enabled Apache Servers</A>
   
   
   
   <P>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<CENTER><H3><A NAME="Name_collisions_with_Modules_and">Name collisions with Modules and libs</A></H3></CENTER>
  +<CENTER><H1><A NAME="One_light_non_Apache_and_One_mod">One light non-Apache and One mod_perl enabled Apache Servers</A></H1></CENTER>
   <P>
  -Just to make things clear before we go into detail: each server 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> The values are the real paths
  -to these modules. So if you do (assume it's in the <CODE>@INC</CODE> path)
  +If the only requirement from the light server is for it to serve static
  +objects, then you can get away with non-apache servers having an even
  +smaller memory footprint. <CODE>thttpd</CODE> has been reported to be about 5 times faster then apache (especially under
  +a heavy load), since it is very simple and uses almost no memory (260k) and
  +does not spawn child processes.
   
  -<P>
  -<PRE>  require &quot;./my/lib.pl&quot;;
  -</PRE>
   <P>
  -where <CODE>./my/lib.pl</CODE> is actually a <CODE>/home/httpd/perl/my/lib.pl</CODE>. The following entry will show up in the <CODE>%INC</CODE>
  +Meta: Hey, No personal experience here, only rumours. Please let me know if
  +I have missed some pros/cons here. Thanks!
   
  -<P>
  -<PRE>  $INC{&quot;./my/lib.pl&quot;} = &quot;/home/httpd/perl/my/lib.pl&quot;;
  -</PRE>
   <P>
  -I'm talking about single server child below!
  +The Advantages:
   
  +<UL>
  +<P><LI>
   <P>
  -You can't have 2 identical module names running under the same server! Only
  -the first one <CODE>use()'d</CODE> or <CODE>require()'d</CODE> will be
  -compiled into the package, the request to the other identical module will
  -be skipped since server will think that it's already compiled. It'll be
  -already in child's %INC. (See <A HREF="././status.html#Watching_the_server">Watching the server</A> 
  -section to find out how you can know what is loaded and where)
  +All the advantages of the 2 servers scenario.
   
  +<P><LI>
   <P>
  -So if you have 
  +More memory saving. Apache is about 4 times bigger then <STRONG>thttpd</STRONG>, if you spawn 30 children you use about 30M of memory, while <STRONG>thttpd</STRONG>
  +uses only 260k - 100 times less! You could use the saved 30M to run more
  +mod_perl servers.
   
  -<P>
  -<PRE>  cgi/tool1/Foo.pm 
  -  cgi/tool1/tool1.pl
  -  cgi/tool2/Foo.pm 
  -  cgi/tool2/tool2.pl
  -</PRE>
   <P>
  -And both scripts do: <CODE>use Foo;</CODE> only the first one called will know about Foo, when you will call the
  -second script it will not know about Foo at all - it's like you've
  -forgotten to write <CODE>use Foo;</CODE>. Run the server in <A HREF="././control.html#Running_server_in_a_single_mode">single server mode</A> to solve that kind of bug immediately.
  +Note that this is not true if your OS supports memory sharing and you
  +configured apache to use it (it is a DSO approach. There is no memory
  +sharing if apache modules are being statically compiled into httpd). If you
  +do allow memory sharing -- 30 light apache servers ought to use about 3-4Mb
  +only, because most of it will be shared. If this is the case -- the save
  +ups are much smaller with <STRONG>thttpd</STRONG>.
   
  +<P><LI>
   <P>
  -You will see the following in the error_log file:
  +Reported to be about 5 times faster then plain apache serving static
  +objects.
   
  -<P>
  -<PRE>  Undefined subroutine
  -  &amp;Apache::ROOT::perl::test_2epl::some_function called at
  -  /home/httpd/perl/test.pl line 10. 
  -</PRE>
  +</UL>
   <P>
  -The above is true for the files you require as well (assuming that the
  -required files do not declare a package). If you have:
  +The Disadvantages:
   
  -<P>
  -<PRE>  cgi/tool1/config.pl
  -  cgi/tool1/tool1.pl
  -  cgi/tool2/config.pl
  -  cgi/tool2/tool2.pl
  -</PRE>
  +<UL>
  +<P><LI>
   <P>
  -And both scripts do:
  +Lacks some of apache's features, like access control, error redirection,
  +customizable log file formats, and so on.
   
  +</UL>
   <P>
  -<PRE>  use lib qw(.);
  -  require &quot;config.pl&quot;;
  -</PRE>
  +<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<CENTER><H1><A NAME="Adding_a_Proxy_Server_in_http_Ac">Adding a Proxy Server in http Accelerator Mode</A></H1></CENTER>
   <P>
  -Only the first one will do the require, all for the same reason that
  -<CODE>%INC</CODE> already includes the key ``config.pl''!
  +At the beginning there were 2 servers: one - plain apache server, which was <STRONG>very light</STRONG>, and configured to serve static objects, the other -- mod_perl enabled,
  +which was <STRONG>very heavy</STRONG> and aimed to serve mod_perl scripts. We named them: <CODE>httpd_docs</CODE> and <CODE>httpd_perl</CODE>
  +appropriately. The two servers coexisted at the same <CODE>IP(DNS)</CODE>
  +by listening to different ports: 80 -- for httpd_docs (e.g. <A
  +HREF="http://www.nowhere.com/images/test.gif">http://www.nowhere.com/images/test.gif</A>
  +) and 8080 -- for httpd_perl (e.g. <A
  +HREF="http://www.nowhere.com:8080/perl/test.pl">http://www.nowhere.com:8080/perl/test.pl</A>
  +). Note that I did not write <A
  +HREF="http://www.nowhere.com:80">http://www.nowhere.com:80</A> for the
  +first example, since port 80 is a default http port. (Later on, I will be
  +moving the httpd_docs server to port 81.)
   
   <P>
  -There are 3 workarounds for that: (make sure you read the whole item 3)
  +Now I am going to convince you that you <STRONG>want</STRONG> to use a proxy server (in the http accelerator mode). The advantages are:
   
  -<OL>
  +<UL>
   <P><LI>
   <P>
  -Place your library modules in a subdirectory structure so that they have
  -different path prefixes. The file system layout will be something like
  +Allow serving of static objects from the proxy's cache (objects that
  +previously were entirely served by the httpd_docs server).
   
  -<P>
  -<PRE>  cgi/tool1/Tool1/Foo.pm 
  -  cgi/tool1/tool1.pl
  -  cgi/tool2/Tool2/Foo.pm 
  -  cgi/tool2/tool2.pl
  -</PRE>
  +<P><LI>
   <P>
  -And change the scripts:
  +You get less I/O activity reading static objects from the disk (proxy
  +serves the most ``popular'' objects from the RAM memory - of course you
  +benefit more if you allow the proxy server to consume more RAM). Since you
  +do not wait for the I/O to be completed you are able to serve the static
  +objects much faster.
   
  -<P>
  -<PRE>  use Tool1::Foo;
  -  use Tool2::Foo;
  -</PRE>
  +<P><LI>
   <P>
  -and respectively, the package declaration in the modules: 
  +The proxy server acts as a sort of output buffer for the dynamic content.
  +The mod_perl server sends the entire response to the proxy and is then free
  +to deal with other requests. The proxy server is responsible for sending
  +the response to the browser. So if the transfer is over a slow link, the
  +mod_perl server is not waiting around for the data to move.
   
  -<P>
  -<PRE>  package Tool1::Foo;
  -  package Tool2::Foo;
  -</PRE>
   <P>
  -For require:
  +Using numbers is always more convincing :) Let's take a user connected to
  +your site with 28.8 kbps (bps == bits/sec) modem. It means that the speed
  +of the user's link is 28.8/8 = 3.6 kbytes/sec. I assume an average
  +generated HTML page to be of 10kb (kb == kilobytes) and an average script
  +that generates this output in 0.5 secs. How much time will the server wait
  +before the user gets the whole output response? A simple calculation
  +reveals pretty scary numbers - it will have to wait for another 6 secs
  +(20kb/3.6kb), when it could serve another 12 (6/0.5) dynamic requests in
  +this time. This very simple example shows us that we need a twelve the
  +number of children running, which means you will need only one twelve of
  +the memory (which is not quite true because some parts of the code are
  +being shared). But you know that nowadays scripts return pages which
  +sometimes are being blown up with javascript code and similar, which makes
  +them of 100kb size and download time to be of... (This calculation is left
  +to you as an exercise :)
   
   <P>
  -<PRE>  cgi/tool1/tool1-lib/config.pl
  -  cgi/tool1/tool1.pl
  -  cgi/tool2/tool2-lib/config.pl
  -  cgi/tool2/tool2.pl
  -</PRE>
  +To make your download time numbers even worse, let me remind you that many
  +users like to open many browser windows and do many things at once
  +(download files and browse <STRONG>heavy</STRONG> sites). So the speed of 3.6kb/sec we were assuming before, may many times
  +be 5-10 times slower.
  +
  +<P><LI>
   <P>
  -And each script does respectively:
  +Also we are going to hide the details of the server's implementation. Users
  +will never see ports in the URLs (more on that topic later). And you can
  +have a few boxes serving the requests, and only one serving as a front end,
  +which spreads the jobs between the servers in a way you configured it too.
  +So you can actually put down one server down for upgrade, but end user will
  +never notice that because the front end server will dispatch the jobs to
  +other servers. (Of course this is a pretty big issue, and it would not be
  +discussed in the scope of this document)
   
  +<P><LI>
   <P>
  -<PRE>  use lib qw(.);
  -  require &quot;tool1-lib/config.pl&quot;;
  -</PRE>
  +For security reasons, using any httpd accelerator (or a proxy in httpd
  +accelerator mode) is essential because you do not let your internal server
  +get directly attacked by arbitrary packets from whomever. The httpd
  +accelerator and internal server communicate in expected HTTP requests. This
  +allows for only your public ``bastion'' accelerating www server to get
  +hosed in a successful attack, while leaving your internal data safe.
  +
  +</UL>
   <P>
  -<PRE>  use lib qw(.);
  -  require &quot;tool2-lib/config.pl&quot;;
  - 
  -</PRE>
  +The disadvantages are:
  +
  +<UL>
   <P><LI>
   <P>
  -Another option is to use a full path to the script, so it'll be compiled
  -into the name of the key in the %INC;
  +Of course there are drawbacks. Luckily, these are not functionality
  +drawbacks, but more of administration hassle. You add another daemon to
  +worry about, and while proxies are generally stable, you have to make sure
  +to prepare proper startup and shutdown scripts, which are being run at the
  +boot and reboot appropriately. Also, maybe a watchdog script running at the
  +crontab.
   
  +<P><LI>
   <P>
  -<PRE>  require &quot;/full/path/to/the/config.pl&quot;;
  -</PRE>
  +Proxy servers can be configured to be light or heavy, the admin must decide
  +what gives the highest performance for his application. A proxy server like
  +squid is light in the concept of having only one process serving all
  +requests. But it can appear pretty heavy when it loads objects into memory
  +for faster service.
  +
  +</UL>
   <P>
  -But then you lose portability! (I mean if you move the tool around in the
  -file system you will have to change the base dir)
  +Have I succeeded in convincing you that you want the proxy server?
   
  -<P><LI>
   <P>
  -Declare a package in the required files! (Of course it should be unique to
  -the rest of the package names you use!) The <CODE>%INC</CODE> will use the
  -package name for the key!
  +If you are on a local area network (LAN), then the big benefit of the proxy
  +buffering the output and feeding a slow client is gone. You are probably
  +better off sticking with a straight mod_perl server in this case.
   
   <P>
  -But then you will have to use <STRONG>Package::function()</STRONG> method unless you will export the symbols from the <CODE>use()'d</CODE>
  -package like:
  +As of this writing the two proxy implementations are known to be used in
  +bundle with mod_perl - <STRONG>squid</STRONG> proxy server and <STRONG>mod_proxy</STRONG> which is a part of the apache server. Let's compare the two of them.
   
   <P>
  -<PRE>  use Package qw(:all_subs);
  -</PRE>
  +<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<CENTER><H1><A NAME="The_Squid_Server">The Squid Server</A></H1></CENTER>
   <P>
  -This is a bad approach since it'll consume more memory for the current
  -process.
  +The Advantages:
   
  +<UL>
  +<P><LI>
   <P>
  -<STRONG>Important:</STRONG> This solution will only work if you have two scripts that
  -<CODE>require()</CODE> the same file! 
  +Caching of static objects. So these are being served much faster assuming
  +that your cache size is big enough to keep the most requested objects in
  +the cache.
   
  -<P>
  -<PRE>  cgi/tool1/config.pl
  -  cgi/tool1/tool_1.pl
  -  cgi/tool1/tool_2.pl
  -</PRE>
  +<P><LI>
   <P>
  -and both tool_1.pl and tool_2.pl do:   
  +Buffering of dynamic content, by taking the burden of returning the content
  +generated by mod_perl servers to slow clients, thus freeing mod_perl
  +servers from waiting for the slow clients to download the data. Freed
  +servers immediately switch to serve other requests, thus your number of
  +required servers goes dramatically down.
   
  -<P>
  -<PRE>  use lib qw(.);
  -  require &quot;config.pl&quot;;
  -</PRE>
  +<P><LI>
   <P>
  -Here playing with dir name or using the full path will not help! You must
  -declare a package inside the files that are being <CODE>require()d!</CODE>
  +Non-linear URL space / server setup. You can use Squid to play some tricks
  +with the URL space and/or domain based virtual server support.
   
  -</OL>
  +</UL>
   <P>
  -Read also perlmodlib and perlmod manpages.
  +The Disadvantages:
   
  +<UL>
  +<P><LI>
   <P>
  -From the above discussion it should be clear that you can't run a
  -development and a production versions of the tools on the same server! You
  -have to run a separate server for each.
  +Proxying dynamic content is not going to help much if all the clients are
  +on a fast local net. Also, a message on the squid mailing list implied that
  +squid only buffers in 16k chunks so it would not allow a mod_perl to
  +complete immediately if the output is larger.
   
  -<P>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<CENTER><H3><A NAME="_END_or_DATA_tokens">__END__ or __DATA__ tokens</A></H3></CENTER>
  +<P><LI>
   <P>
  -Apache::Registry scripts cannot contain __END__ or __DATA__ tokens 
  +Speed. Squid is not very fast today when compared to plain file based web
  +servers available. Only if you are using a lot of dynamic features such as
  +mod_perl or similar speed is a reason to use Squid, and then only if the
  +application and server is designed with caching in mind.
   
  -<P>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<CENTER><H3><A NAME="Output_from_system_calls">Output from system calls</A></H3></CENTER>
  +<P><LI>
   <P>
  -Output of <STRONG>system</STRONG>, <STRONG>exec</STRONG>, and <STRONG>open PIPE "|program"</STRONG> calls will not be sent to the browser unless your Perl was configured with
  -sfio.
  +Memory usage. Squid uses quite a bit of memory.
   
  -<P>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<CENTER><H3><A NAME="Using_format_">Using format()</A></H3></CENTER>
  +<P><LI>
   <P>
  -Currently possible only if you have perl compiled with sfio
  +HTTP protocol level. Squid is pretty much a HTTP/1.0 server, which
  +seriously limits the deployment of HTTP/1.1 features.
   
  -<P>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<CENTER><H3><A NAME="Using_exit_">Using exit()</A></H3></CENTER>
  +<P><LI>
   <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
  -irrelevant.) The <STRONG>Apache::exit()</STRONG> function should be used instead. 
  +HTTP headers / dates, freshness. The squid server might give out ``old''
  +pages, confusing downstream/client caches. Also chances are that you will
  +be giving out stale pages.
   
  +<P><LI>
   <P>
  -You might start your scripts by overriding the exit sub (if you use
  -<STRONG>Apache::exit()</STRONG> directly, you will have a problem testing the script from the shell, unless
  -you stuff <CODE>use Apache ();</CODE> into your code.) I use the following code:
  +Stability. Compared to plain web servers Squid is not the most stable.
   
  -<P>
  -<PRE>  BEGIN {
  -      # Auto-detect if we are running under mod_perl or CGI.
  -    $USE_MOD_PERL = ( (exists $ENV{'GATEWAY_INTERFACE'}
  -                   and $ENV{'GATEWAY_INTERFACE'} =~ /CGI-Perl/)
  -                      or exists $ENV{'MOD_PERL'} ) ? 1 : 0;
  -  }
  -  use subs (exit);
  -  
  -  # Select the correct exit way
  -  ########
  -  sub exit{
  -      # Apache::exit(-2) will cause the server to exit gracefully,
  -      # once logging happens and protocol, etc  (-2 == Apache::Constants::DONE)
  -    $USE_MOD_PERL ? Apache::exit(0) : CORE::exit(0);
  -  }
  -</PRE>
  +</UL>
   <P>
  -Now each time the select code is called, the correct <STRONG>exit</STRONG>
  -will be chosen, whether you run the script as a CGI or from the shell.
  +The presented pros and cons lead to an idea, that probably you might want
  +squid more for its dynamic content buffering features, but only if your
  +server serves mostly dynamic requests. So in this situation it is better to
  +have a plain apache server serving static objects, and squid proxying the
  +mod_perl enabled server only. At least when performance is the goal.
   
   <P>
  -<STRONG>Note</STRONG> that if you run the script under <CODE>Apache::Registry</CODE>, <STRONG>The
  -Apache function `exit' overrides the Perl core built-in
  -function</STRONG>. While you see the <CODE>exit()</CODE> listed in <CODE>@EXPORT_OK</CODE>
  -of Apache package, Apache::Registry makes something you don't see and
  -imports this function for you. This means that if your script is running
  -under Apache::Registry handler (Apache::PerlRun as well), you don't have to
  -worry about <CODE>exit().</CODE>
  -
  -<P>
  -<STRONG>Note</STRONG> that if you still use CORE::exit() in your scripts running under modperl,
  -the child will exit, but neither proper exit nor logging will happen on the
  -way. CORE::exit() cuts off the server's legs... If you need to properly
  -shutdown the child , use $r-&gt;child_terminate (which sets the internal MaxRequestsPerChild so the child
  -will exit).
  +For implementation details see: <A HREF="././scenario.html#Running_1_webserver_and_squid_in">Running 1 webserver and squid in httpd accelerator mode</A> and
  +<A HREF="././scenario.html#Running_2_webservers_and_squid_i">Running 2 webservers and squid in httpd accelerator mode</A>
   
  -<P>
  -You can accomplish this in 2 ways - in the Apache::Registry 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><H3><A NAME="Running_from_shell">Running from shell</A></H3></CENTER>
  +<CENTER><H1><A NAME="An_Apache_s_mod_proxy">An Apache's mod_proxy</A></H1></CENTER>
   <P>
  -Your scripts <CODE>*will</CODE> not* run from the command line (yet) unless
  -you use CGI::Switch or CGI.pm and 5.004+ and do not make any direct calls
  -to Apache-&gt;methods. 
  +I do not think the difference in speed between apache's <CODE>ProxyPass</CODE>
  +and squid is relevant for most sites, since the real value of what they do
  +is buffering for slow client connections. However squid runs as a single
  +process and probably consumes fewer system resources. The trade-off is that
  +mod_rewrite is easy to use if you want to spread parts of the site across
  +different back end servers, and mod_proxy knows how to fix up redirects
  +containing the back-end server's idea of the location. With squid you can
  +run a redirector process to proxy to more than one back end, but there is a
  +problem in fixing redirects in a way that keeps the client's view of both
  +server names and port numbers in all cases. The difficult case being where
  +you have DNS aliases that map to the same IP address for an alias and you
  +want the redirect to use port 80 (when the server is really on a different
  +port) but you want it to keep the specific name the browser sent so it does
  +not change in the client's <STRONG>Location</STRONG> window.
   
   <P>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<CENTER><H3><A NAME="I_O_is_different">I/O is different</A></H3></CENTER>
  -<P>
  -If you are using Perl 5.004 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 CGI.pm, use $query-&gt;print instead of plain 'ol <CODE>print().</CODE>
  +The Advantages:
   
  -<P>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<CENTER><H3><A NAME="HTTP_MIME_Headers_PerlSendHea">HTTP + MIME Headers (PerlSendHeader)</A></H3></CENTER>
  +<UL>
  +<P><LI>
   <P>
  -By default, mod_perl does not send any headers by itself, however, you may
  -wish to change this (in httpd.conf):
  +No additional server is needed. We keep the one plain plus one mod_perl
  +enabled apache servers. All you need is to enable the
  +<CODE>mod_proxy</CODE> in the <CODE>httpd_docs</CODE> server and add a few lines to
  +<CODE>httpd.conf</CODE> file.
   
  -<P>
  -<PRE>  PerlSendHeader On
  -</PRE>
  +<P><LI>
   <P>
  -Now the response line and common headers will be sent as they are by
  -mod_cgi. And, just as with mod_cgi, PerlSendHeader will not send a
  -terminating newline, your script must send that itself, e.g.:
  +<CODE>ProxyPass</CODE> and <CODE>ProxyPassReverse</CODE> directives allow you to hide the internal redirects, so if <CODE>http://nowhere.com/modperl/</CODE> is actually
  +<CODE>http://localhost:81/modperl/</CODE>, it will be absolutely transparent for user. <CODE>ProxyPass</CODE> redirects the request to the mod_perl server, and when it gets the respond, <CODE>ProxyPassReverse</CODE> rewrites the URL back to the original one, e.g:
   
   <P>
  -<PRE>  print &quot;Content-type: text/html\r\n\r\n&quot;;
  +<PRE>  ProxyPass        /modperl/ <A HREF="http://localhost:81/modperl/">http://localhost:81/modperl/</A>
  +  ProxyPassReverse /modperl/ <A HREF="http://localhost:81/modperl/">http://localhost:81/modperl/</A>
   </PRE>
  +<P><LI>
   <P>
  -If you are using CGI.pm or CGI::Switch and <STRONG>print $q-&gt;header</STRONG> you do _not_ need PerlSendHeader On.
  +It does mod_perl output buffering like squid does. See the <A HREF="././scenario.html#Using_mod_proxy">Using mod_proxy</A> notes for more details.
   
  -<P>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<CENTER><H3><A NAME="NPH_Non_Parsed_Headers_scripts">NPH (Non Parsed Headers) scripts</A></H3></CENTER>
  +<P><LI>
   <P>
  -To run a Non Parsed Header CGI script under mod_perl, simply add to your
  -code:
  +It even does caching. You have to produce correct <CODE>Content-Length</CODE>,
  +<CODE>Last-Modified</CODE> and <CODE>Expires</CODE> http headers for it to work. If some dynamic content is not to change
  +constantly, you can dramatically increase performance by caching it with <CODE>ProxyPass</CODE>.
   
  -<P>
  -<PRE>  local $| = 1;
  -</PRE>
  +<P><LI>
   <P>
  -And if you normally set PerlSendHeader On, add this to your httpd.conf:
  +<CODE>ProxyPass</CODE> happens before the authentication phase, so you do not have to worry about
  +authenticating twice.
   
  -<P>
  -<PRE>  &lt;Files */nph-*&gt;
  -    PerlSendHeader Off
  -  &lt;/Files&gt;
  -</PRE>
  +<P><LI>
   <P>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<CENTER><H3><A NAME="BEGIN_blocks">BEGIN blocks</A></H3></CENTER>
  +Apache is able to accel https (secure) requests completely, while also
  +doing http accel. (with squid you have to use an external redirection
  +program for that).
  +
  +<P><LI>
   <P>
  -Perl executes BEGIN blocks during the compile time of code as soon as
  -possible. The same is true under mod_perl. However, since mod_perl normally
  -only compiles scripts and modules once -- either in the parent server or
  -once per-child -- BEGIN blocks in that code will only be run once. As
  -perlmod explains, once a BEGIN has run, it is immediately undefined. In the
  -mod_perl environment, this means BEGIN blocks will not be run during each
  -incoming request unless that request happens to be one that is compiling
  -the code.
  +The latest (from apache 1.3.6) Apache proxy accel mode reported to be very
  +stable.
   
  +</UL>
   <P>
  -Modules and files pulled in via require/use which contain BEGIN blocks will
  -be executed:
  +The Disadvantages:
   
   <UL>
   <P><LI>
   <P>
  -only once, if pulled in by the parent process.
  +Users reported that it might be a bit slow, but the latest version is fast
  +enough. (How fast is enough? :)
   
  -<P><LI>
  +</UL>
   <P>
  -once per-child process if not pulled in by the parent process.
  +For implementation see <A HREF="././scenario.html#Using_mod_proxy">Using mod_proxy</A>.
   
  -<P><LI>
  -<P>
  -an additional time, once per-child process if the module is pulled in off
  -of disk again via Apache::StatINC.
  +<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +	     The <a href="http://www.modperl.com/">
  +	     <B>Writing Apache Modules with Perl and C</B></a>
  +	     book can be purchased online from <a
  +	     href="http://www.ora.com/catalog/wrapmod/">O'Reilly </a>
  +	     and <a
  +	     href="http://www.amazon.com/exec/obidos/ASIN/156592567X/writinapachemodu">
  +	     Amazon.com</a>.
   
  -<P><LI>
  -<P>
  -an additional time, in the parent process on each restart if
  -PerlFreshRestart is On.
  +	     <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%" >
  +<TR ALIGN=CENTER VALIGN=TOP>
  +  <TD ALIGN=CENTER VALIGN=CENTER COLSPAN="3">
  +	     <HR>
  +  </TD>
  +</TR>
  +<TR ALIGN=CENTER VALIGN=TOP>
  +  <TD ALIGN=CENTER VALIGN=CENTER>
  +    <B>
  +      <FONT SIZE=-1>
  +	     Written by <A HREF="help.html#This_document_s_Author">Stas Bekman</A>.
  +	     <BR>Last Modified at 07/02/1999
  +      </FONT>
  +    </B>
  +  </TD>
  +
  +  <TD>
  +	     <A HREF="http://perl.apache.org"><IMG SRC="images/mod_perl2.jpg" ALT="Mod Perl Icon" BORDER=0 HEIGHT=59 WIDTH=150></A>
  +  </TD>
  +
  +  <TD>
  +    <FONT SIZE=-2>
  +	     Use of the Camel for Perl is <BR>
  +	     a trademark of <A HREF="http://www.ora.com">O'Reilly &amp; Associates</A>,<BR>
  +             and is used by permission. 
  +    </FONT> 
  +  </TD>
  +</TR>
  +</TABLE></CENTER>
  +
  +</BODY>
  +</HTML>
  +	    
  +
  +<HR SIZE=6>
  +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
  +<HTML>
  +<HEAD>
  +   <TITLE>mod_perl guide: Real World Scenarios Implementation</TITLE>
  +   <META NAME="GENERATOR" CONTENT="Pod2HTML [Perl/Linux]">
  +   <META NAME="Author" CONTENT="Stas Bekman">
  +   <META NAME="Description" CONTENT="All Apache/Perl related information: Hints, Guidelines, Scenarios and Troubleshottings">
  +   <META NAME="keywords" CONTENT="mod_perl modperl perl apache cgi webserver speed  fast guide mod_perl apache guide help info faq mod_perl installation cgi troubleshooting help no sex speedup free open source OSS mod_perl apache guide">
  +</HEAD>
  +     <LINK REL=STYLESHEET TYPE="text/css"
  +        HREF="style.css" TITLE="refstyle">
  +     <style type="text/css">
  +     <!-- 
  +        @import url(style.css);
  +     -->
  +     
  +     </style>
  +<BODY TEXT="#000000" BGCOLOR="#E0FFFF" LINK="#0000EE" VLINK="#551A8B" ALINK="#FF0000">
  +<A NAME="toc"></A>
  +<H1 ALIGN=CENTER>
  +<A HREF="http://perl.apache.org"><IMG SRC="images/mod_perl.gif" ALT="Mod Perl Icon" BORDER=0 HEIGHT=30 WIDTH=90 ALIGN=LEFT></A>
  +<A HREF="http://perl.apache.org"><IMG SRC="images/mod_perl.gif" ALT="Mod Perl Icon" BORDER=0 HEIGHT=30 WIDTH=90 ALIGN=RIGHT></A>
  +Real World Scenarios Implementation</H1>
  +<HR WIDTH="100%">
  +	    [    <A HREF="strategy.html">Prev</A> |      <A HREF="index.html">Main Page</A> | <A HREF="install.html">Next</A>      ]<HR><!-- INDEX BEGIN -->
  +<P><B><FONT SIZE=-1>Table of Contents:</FONT></B></P>
  +<UL>
  +
  +	<LI><A HREF="#Standalone_mod_perl_Enabled_Apac">Standalone mod_perl Enabled Apache Server</A>
  +	<UL>
  +
  +		<LI><A HREF="#Installation_in_10_lines">Installation in 10 lines</A>
  +		<LI><A HREF="#Installation_in_10_paragraphs">Installation in 10 paragraphs</A>
  +		<LI><A HREF="#Configuration_Process">Configuration Process</A>
  +	</UL>
  +
  +	<LI><A HREF="#One_Plain_and_One_mod_perl_enabl">One Plain and One mod_perl enabled Apache Servers</A>
  +	<UL>
   
  -<P><LI>
  -<P>
  -unpredictable if you fiddle with <CODE>%INC</CODE> yourself.
  +		<LI><A HREF="#Configuration_and_Compilation_of">Configuration and Compilation of the Sources.</A>
  +		<UL>
   
  -</UL>
  -<P>
  -Apache::Registry scripts which contain BEGIN blocks will be executed:
  +			<LI><A HREF="#Building_the_httpd_docs_Server">Building the httpd_docs Server</A>
  +			<LI><A HREF="#Building_the_httpd_perl_mod_per">Building the httpd_perl (mod_perl enabled) Server</A>
  +		</UL>
   
  -<UL>
  -<P><LI>
  -<P>
  -only once, if pulled in by the parent process via Apache::RegistryLoader -
  -once per-child process if not pulled in by the parent process.
  +		<LI><A HREF="#Configuration_of_the_servers">Configuration of the servers</A>
  +		<UL>
   
  -<P><LI>
  -<P>
  -an additional time, once per-child process if the script file has changed
  -on disk.
  +			<LI><A HREF="#Basic_httpd_docs_Server_s_Config">Basic httpd_docs Server's Configuration</A>
  +			<LI><A HREF="#Basic_httpd_perl_Server_s_Config">Basic httpd_perl Server's Configuration</A>
  +		</UL>
   
  -<P><LI>
  -<P>
  -an additional time, in the parent process on each restart if pulled in by
  -the parent process via Apache::RegistryLoader and PerlFreshRestart is On.
  +	</UL>
   
  +	<LI><A HREF="#Running_2_webservers_and_squid_i">Running 2 webservers and squid in httpd accelerator mode</A>
  +	<LI><A HREF="#Running_1_webserver_and_squid_in">Running 1 webserver and squid in httpd accelerator mode</A>
  +	<LI><A HREF="#Using_mod_proxy">Using mod_proxy</A>
  +	<LI><A HREF="#mod_perl_server_as_DSO">mod_perl server as DSO</A>
  +	<LI><A HREF="#HTTP_Authentication_with_2_serve">HTTP Authentication with 2 servers + proxy</A>
   </UL>
  -<P>
  -Make sure you read <A HREF="././warnings.html#Evil_things_might_happen_when_us">Evil things might happen when using PerlFreshRestart</A>.
  +<!-- INDEX END -->
   
  -<P>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<CENTER><H3><A NAME="END_blocks">END blocks</A></H3></CENTER>
  -<P>
  -As perlmod explains, an END subroutine is executed as late as possible,
  -that is, when the interpreter is being exited. In the mod_perl environment,
  -the interpreter does not exit until the server is shutdown. However,
  -mod_perl does make a special case for Apache::Registry scripts.
  +<HR>
   
  -<P>
  -Normally, END blocks are executed by Perl during its <STRONG>perl_run()</STRONG>
  -function, which is called once each time the Perl program is executed, e.g.
  -once per (mod_cgi) CGI scripts. However, mod_perl only calls
  -<STRONG>perl_run()</STRONG> once, during server startup. Any END blocks encountered during main server
  -startup, i.e. those pulled in by the PerlRequire or by any PerlModule, are
  -suspended and run at server shutdown, aka child_exit (requires apache
  -1.3b3+). 
  +	     The <a href="http://www.modperl.com/">
  +	     <B>Writing Apache Modules with Perl and C</B></a>
  +	     book can be purchased online from <a
  +	     href="http://www.ora.com/catalog/wrapmod/">O'Reilly </a>
  +	     and <a
  +	     href="http://www.amazon.com/exec/obidos/ASIN/156592567X/writinapachemodu">
  +	     Amazon.com</a>.
   
  -<P>
  -Any END blocks that are encountered during compilation of Apache::Registry
  -scripts <STRONG>are called after the script has completed</STRONG>
  -(not during the cleanup phase though) including subsequent invocations when
  -the script is cached in memory. All other END blocks encountered during
  -other Perl*Handler callbacks, e.g. PerlChildInitHandler, will be suspended
  -while the process is running and called during child_exit when the process
  -is shutting down. Module authors may be wish to use $r-&gt;register_cleanup as an alternative to END blocks if this behavior is not
  -desirable.
  +	     <HR>
   
  +	      <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
   <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>.
  -
  +<CENTER><H1><A NAME="Standalone_mod_perl_Enabled_Apac">Standalone mod_perl Enabled Apache Server</A></H1></CENTER>
   <P>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<CENTER><H3><A NAME="Switches_w_T">Switches -w, -T</A></H3></CENTER>
  +<CENTER><H2><A NAME="Installation_in_10_lines">Installation in 10 lines</A></H2></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
  -example, the <STRONG>$^W</STRONG> variable corresponds to the <STRONG>-w</STRONG>
  -switch. Consult perlvar for more details. With mod_perl it is also possible
  -to turn on warnings globally via the PerlWarn directive:
  +The Installation is very very simple (example of installation on Linux OS):
   
   <P>
  -<PRE>  PerlWarn On
  +<PRE>  % cd /usr/src
  +  % lwp-download <A HREF="http://www.apache.org/dist/apache_x.x.x.tar.gz">http://www.apache.org/dist/apache_x.x.x.tar.gz</A>
  +  % lwp-download <A HREF="http://perl.apache.org/dist/mod_perl-x.xx.tar.gz">http://perl.apache.org/dist/mod_perl-x.xx.tar.gz</A>
  +  % tar zvxf apache_x.xx.tar.gz
  +  % tar zvxf mod_perl-x.xx.tar.gz
  +  % cd mod_perl-x.xx
  +  % perl Makefile.PL APACHE_SRC=../apache_x.x.x/src \
  +    DO_HTTPD=1 USE_APACI=1 PERL_MARK_WHERE=1 EVERYTHING=1
  +  % make &amp;&amp; make test &amp;&amp; make install
  +  % cd ../apache_x.x.x/src
  +  % make install
   </PRE>
   <P>
  -You can turn it off with <CODE>local $^W = 0;</CODE> in your scripts on the local basis (or inside the block). If you write <CODE>$^W = 0;</CODE> you disable the warning mode everywhere, the same with <CODE>$^W = 1;</CODE>.
  +That's all!
   
   <P>
  -The switch which enables taint checks does not have a special variable, so
  -mod_perl provides the PerlTaintCheck directive to turn on taint checks. In
  -httpd.conf, enable with:
  +Notes: Replace x.x.x with the real version numbers of mod_perl and apache.
  +gnu <CODE>tar</CODE> uncompresses as well (with <CODE>z</CODE> flag).
   
   <P>
  -<PRE>  PerlTaintCheck On
  -</PRE>
  +<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<CENTER><H2><A NAME="Installation_in_10_paragraphs">Installation in 10 paragraphs</A></H2></CENTER>
   <P>
  -Now, any and all code compiled inside httpd will be taint checked.
  +First download the sources of both packages, e.g. you can use
  +<CODE>lwp-download</CODE> utility to do it. <CODE>lwp-download</CODE> is a part of the LWP (or <CODE>libwww</CODE>) package, you will need to have it installed in order for mod_perl's <CODE>make test</CODE> to pass. Once you install this package unless it's already installed, <CODE>lwp-download</CODE> will be available for you as well.
   
   <P>
  -The environment variable PERL5OPT can be used to set additional perl
  -startup flags such as -d and -D. See
  -<A HREF="././modules.html#Apache_PerlRun_Run_unaltered_">Apache::PerlRun</A> .
  -
  +<PRE>  % lwp-download <A HREF="http://www.apache.org/dist/apache_x.x.x.tar.gz">http://www.apache.org/dist/apache_x.x.x.tar.gz</A>
  +  % lwp-download <A HREF="http://perl.apache.org/dist/mod_perl-x.xx.tar.gz">http://perl.apache.org/dist/mod_perl-x.xx.tar.gz</A>
  +</PRE>
   <P>
  -If you have the shebang line (#!/bin/perl -Tw) in your script, <STRONG>-w</STRONG>
  -will be honored (which means that you have turned the warn mode on for the
  -scope of this script, <STRONG>-T</STRONG> will produce a warning if
  -<CODE>PerlTaintCheck</CODE> is not <CODE>On</CODE>.
  +Extract both sources. Usually I open all the sources in <CODE>/usr/src/</CODE>, your mileage may vary. So move the sources and <CODE>chdir</CODE> to the directory, you want to put the sources in. Gnu <CODE>tar</CODE> utility knows to uncompress too with <CODE>z</CODE> flag, if you have a non-gnu <CODE>tar</CODE> utility, it will be incapable to decompress, so you would do it in two
  +steps: first uncompressing the packages with <CODE>gzip -d apache_x.xx.tar.gz</CODE>
  +and <CODE>gzip -d mod_perl-x.xx.tar.gz</CODE>, second un-tarring them with <CODE>tar
  +xvf apache_x.xx.tar</CODE> and <CODE>tar xvf mod_perl-x.xx.tar</CODE>.
   
   <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>
  +<PRE>  % cd /usr/src
  +  % tar zvxf apache_x.xx.tar.gz
  +  % tar zvxf mod_perl-x.xx.tar.gz
  +</PRE>
   <P>
  -It's _absolutely_ mandatory (at least for development) to start all your
  -scripts with:
  +<CODE>chdir</CODE> to the mod_perl source directory:
   
   <P>
  -<PRE>  use strict;
  +<PRE>  % cd mod_perl-x.xx
   </PRE>
   <P>
  -If needed, you can always turn off the 'strict' pragma or a part of it
  -inside the block, e.g:
  +Now build the make file, for a basic work and first time installation the
  +parameters in the example below are the only ones you would need. <CODE>APACHE_SRC</CODE> tells where the apache <CODE>src</CODE> directory is. If you have followed my suggestion and have extracted the
  +both sources under the same directory (<CODE>/usr/src</CODE>), do:
   
   <P>
  -<PRE>  {
  -    no strict 'refs';
  -    ... some code
  -  }
  +<PRE>  % perl Makefile.PL APACHE_SRC=../apache_x.x.x/src \
  +    DO_HTTPD=1 USE_APACI=1 PERL_MARK_WHERE=1 EVERYTHING=1
   </PRE>
   <P>
  -It's more important to have <STRONG>use strict;</STRONG> enabled under mod_perl than anywhere else. While it's not required, it is
  -strongly recommended, it will save you more time in the long run. And, of
  -course, clean scripts will still run under mod_cgi (plain CGI)!
  +There are many additional parameters. You can find some of them in the
  +configuration dedicated and other sections. While running <CODE>perl
  +Makefile.PL ...</CODE> the process will check for prerequisites and tell you if something is
  +missing, If you are missing some of the perl packages or other software --
  +you will have to install these before you proceed.
   
  -<P>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<CENTER><H2><A NAME="Turning_warnings_ON">Turning warnings ON</A></H2></CENTER>
   <P>
  -Have a <CODE>$^W=1</CODE> in the script or PerlWarn ON at the server configuration file. Turning the
  -warning on will save you a lot of troubles with debugging your code. Note
  -that first magic line <CODE>#!/perl -switches</CODE>
  -is ignored by mod_perl, so too are the switches you used to write there.
  +Now we <STRONG>make</STRONG> the project (by building the mod_perl extension and calling <CODE>make</CODE> in apache source directory to build a <CODE>httpd</CODE>),
  +<STRONG>test</STRONG> it (by running various tests) and <STRONG>install</STRONG> the mod_perl modules.
   
   <P>
  -If you need you can always turn off the warning with <CODE>$^W = 0</CODE> in your code if you have some section you don't want the perl compiler to
  -warn in.
  -
  +<PRE>  % make &amp;&amp; make test &amp;&amp; make install
  +</PRE>
   <P>
  -In production code, it can be a good idea to turn warnings off. Otherwise
  -if your code isn't very clean and spits a few lines of warnings here and
  -there, you will end up with a huge error_log file in a short time on the
  -loaded server. Also, enabling runtime warning checking has a small
  -performance impact -- in any script, not just under mod_perl -- so your
  -approach should be to enable warnings during development, and then disable
  -them when your code is production-ready.
  +Note that if <CODE>make</CODE> fails, neither <CODE>make test</CODE> nor <CODE>make
  +install</CODE> will be executed. If <CODE>make test</CODE> fails, <CODE>make install</CODE>
  +will be not executed.
   
   <P>
  -<CODE>use diagnostics;</CODE> can shed more light on the errors and warnings you see, but again, it's
  -better to not use <CODE>use diagnostics;</CODE>
  -in production, since otherwise you incur the overhead of the diagnostics
  -pragma. (You can run your script with -dDprof to check the overhead. See
  -Devel::Dprof for more info)
  +Now change to apache source directory and run <CODE>make install</CODE> to install apache's headers, default configuration files, to build apache
  +directory tree and to put the <CODE>httpd</CODE> there.
   
   <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>
  +<PRE>  % cd ../apache_x.x.x/src
  +  % make install
  +</PRE>
   <P>
  -This is a Perl compiler pragma which forces verbose warning diagnostics.
  -Put at the start of your scripts:
  +When you execute the above command, apache installation process will tell
  +you how to start a freshly built webserver (the path of the
  +<CODE>apachectl</CODE>, more about it later) and where the configuration files are. Remember (or
  +even better write down) both, since you will need this information very
  +soon. On my machine they two important paths are:
   
   <P>
  -<PRE>  use diagnostics;
  +<PRE>  /usr/local/apache/bin/apachectl
  +  /usr/local/apache/conf/httpd.conf
   </PRE>
   <P>
  -This pragma turns on the -w mode, but gives you much better diagnostics of
  -the errors and warnings encountered. Generally it explains the reason for
  -warnings/errors you get, shows you an example of code where the same kind
  -of warning is being triggered, and tells you the remedy.
  -
  -<P>
  -Again, it's a bad idea to keep this in your production code, as it will
  -spit zillions of diagnostics lines into your error_log file. Also, it will
  -add significant overhead to the CGI's runtime. (I discovered this by using
  -Devel::DProf!)
  +Now the build and the installation processes are completed. Just configure <CODE>httpd.conf</CODE> and start the webserver.
   
   <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><H2><A NAME="Configuration_Process">Configuration Process</A></H2></CENTER>
   <P>
  -It's always a good idea to stay away from global variables when possible.
  -Some variables must be global so Perl can see them, such as a module's <STRONG>@ISA</STRONG> or
  -<STRONG>$VERSION</STRONG> variables. In common practice, a combination of <STRONG>use strict</STRONG> and <STRONG>use vars</STRONG> keeps modules clean and reduces a bit of noise. However, <STRONG>use vars</STRONG> also creates aliases as the Exporter does, which eat up more space. When
  -possible, try to use fully qualified names instead of use vars. Example:
  +A basic configuration is a simple one. First configure the apache as you
  +always do (set <CODE>Port</CODE>, <CODE>User</CODE>, <CODE>Group</CODE>, correct <CODE>ErrorLog</CODE> and other file paths and etc), start the server and make sure it works. One
  +of the ways to start and stop the server is to use
  +<CODE>apachectl</CODE> utility:
   
   <P>
  -<PRE>  package MyPackage;
  -  use strict;
  -  @MyPackage::ISA = qw(...);
  -  $MyPackage::VERSION = &quot;1.00&quot;;
  +<PRE>  % /usr/local/apache/bin/apachectl start
  +  % /usr/local/apache/bin/apachectl stop
   </PRE>
   <P>
  -vs.
  +Shut the server down, open the <CODE>httpd.conf</CODE> in your favorite editor and scroll to the end of the file, where we will
  +add the mod_perl configuration directives (of course you can place them
  +anywhere in the file).
   
  -<P>
  -<PRE>  package MyPackage;
  -  use strict;
  -  use vars qw(@ISA $VERSION);
  -  @ISA = qw(...);
  -  $VERSION = &quot;1.00&quot;;
  -</PRE>
   <P>
  -Also see <A HREF="././perl.html#Using_global_variables_and_shari">Using global variables and sharing them</A>
  -
  -
  +Add the following configuration directives:
   
   <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>
  +<PRE>  Alias /perl/ /home/httpd/perl/
  +</PRE>
   <P>
  -To pass an environment variable from a configuration file, add to it:
  +Assuming that you put all your scripts, that should be executed by mod_perl
  +enabled server, under <CODE>/home/httpd/perl/</CODE> directory.
   
   <P>
  -<PRE>  PerlSetEnv key val
  -  PerlPassEnv key
  +<PRE>  PerlModule Apache::Registry
  +  &lt;Location /perl&gt;
  +    SetHandler perl-script
  +    PerlHandler Apache::Registry
  +    Options ExecCGI
  +    PerlSendHeader On
  +    allow from all
  +  &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="Code_has_been_changed_but_it_se">Code has been changed, but it seems the script is running the old code</A></H2></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="././obvious.html#Reloading_Modules_and_Required_F">Reloading Modules and Required Files</A> for more info.
  +Now put a test script into <CODE>/home/httpd/perl/</CODE> directory:
   
   <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>
  +<PRE>  test.pl
  +  -------
  +  #!/usr/bin/perl -w
  +  use strict;
  +  print &quot;Content-type: text/html\r\n\r\n&quot;;
  +  print &quot;It worked!!!\n&quot;;
  +  -------
  +</PRE>
   <P>
  -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
  -to them from outside of that scope. 
  +Make it executable and readable by server, if your server is running as
  +user <CODE>nobody</CODE> (hint: look for <CODE>User</CODE> directive in <CODE>httpd.conf</CODE>
  +file), do the following:
   
   <P>
  -Perl doesn't return the memory it acquired from the kernel. It does reuse
  -it though!
  -
  +<PRE>  % chown nobody /home/httpd/perl/test.pl
  +  % chmod u+rx   /home/httpd/perl/test.pl
  +</PRE>
   <P>
  -<STRONG>First example</STRONG> demonstrates reading a file:
  +Test that the script is running from the command line, by executing it:
   
   <P>
  -<PRE>  open IN, $file or die $!;
  -  $/ = undef; # will read the whole file in
  -  $content = &lt;IN&gt;;
  -  close IN;
  +<PRE>  % /home/httpd/perl/test.pl
   </PRE>
   <P>
  -If your file is 5Mb, the child who served that script will grow exactly by
  -that size. Now if you have 20 children and all of them will serve this CGI,
  -all of them will consume additional 20*5M = 100M of RAM! If that's the
  -case, try to use other approaches of processing the file, if possible of
  -course. Try to process a line at a time and print it back to the file. (If
  -you need to modify the file itself, use a temporary file. When finished,
  -overwrite the source file, making sure to provide a locking mechanism!)
  +You should see:
   
   <P>
  -<STRONG>Second example</STRONG> demonstrates copying variables between functions (passing variables by
  -value). Let's use the example above, assuming we have no choice but to read
  -the whole file before any data processing. Now you have a very nice sub
  -<CODE>process()</CODE> that processes the data and returns it back. What
  -happens if you pass the <CODE>$content</CODE> by value? You have just
  -copied another 5M and the child has grown by another 5M in size (watch your
  -swap space!) now multiply it again by factor of 20 you have 200M of wasted
  -RAM, which will be apparently reused but it's a waste! Whenever you think
  -the variable can grow bigger than few Kb, pass it by reference!
  -
  -<P>
  -Once I wrote the script that passed a content of the little DB to the
  -function and it was OK, but then the DB become huge - I had to make a
  -decision, whether to buy more memory or to rewrite the code. So it's better
  -to plan ahead and pass the variables by reference. There are few approaches
  -for that:
  -
  -<P>
  -<PRE>  sub process{
  -    my $content_r = shift; 
  -    ... some processing on $$content here
  -        ($$var_r - dereference the scalar)
  -        [nothing returned - the variable $content
  -         outside is already changed]
  -  }
  -  process(\$content);
  +<PRE>  Content-type: text/html
     
  -  @{$var_lr} - dereference an array
  -  %{$var_hr} = dereference a hash
  +  It worked!!!
   </PRE>
  -<P>
  -For more see <CODE>perldoc perlref</CODE>
  -
  -
  -
   <P>
  -Another approach would be to directly use the <CODE>@_</CODE> variable.
  -Using directly the <CODE>@_</CODE> array serves the job of passing by
  -reference!
  +Now it is a time to test our mod_perl server, assuming that your config
  +file includes <CODE>Port 80</CODE>, go to your favorite Netscape browser and fetch the following URL (after
  +you have started the server):
   
   <P>
  -<PRE>  sub process{
  -    $_[0] =~ s/A/a/gs;
  -    ... some processing on $_[0] here
  -    [nothing returned - the variable $content
  -     outside is already changed]
  -  }
  -  process($content);
  +<PRE>  <A HREF="http://localhost/perl/test.pl">http://localhost/perl/test.pl</A>
   </PRE>
   <P>
  -From <CODE>perldoc perlsub</CODE>: The array <CODE>@_</CODE> is a local array, but its elements are aliases
  -for the actual scalar parameters. In particular, if an element $_[0] is
  -updated, the corresponding argument is updated (or an error occurs if it is
  -not possible to update)... 
  +Make sure that you have a loop-back device configured, if not -- use the
  +real server name for this test, for example:
   
   <P>
  -<STRONG>Third example</STRONG> demonstrates work with DataBases. If you do some DB processing, many times
  -you encounter the need to read lots of records into your program, and then
  -print them to the browser after they are formatted. (I don't even mention
  -the horrible case where programmers read in the whole DB and then use perl
  -to process it!!! Use a relational DB and let the SQL do the job, so you get
  -only the records you need!!!).
  -
  +<PRE>  <A HREF="http://www.nowhere.com/perl/test.pl">http://www.nowhere.com/perl/test.pl</A>
  +</PRE>
   <P>
  -We will use DBI for this (assume we are already connected to the DB) (read
  -perldoc DBI for complete info):
  +You should see:
   
   <P>
  -<PRE>  $sth-&gt;execute;
  -  while(@row_ary  = $sth-&gt;fetchrow_array;) {
  -        &lt;do DB accumulation into some variable&gt;
  -  }
  -  &lt;print the output using the the data returned from the DB&gt;
  +<PRE>  It worked!!!
   </PRE>
  -<P>
  -In the example above the httpd_process will grow up by the size of the
  -variables that have been allocated for the records that matched the query.
  -(Again remember to multiply it by the number of the children your server
  -runs!).
  -
   <P>
  -A better approach is to not accumulate the records, but rather print them
  -as they are fetched from the DB. Moreover, we use the <STRONG>bind_col</STRONG>
  -and <STRONG>$sth-&gt;fetchrow_arrayref</STRONG> (aliased to <STRONG>$sth-&gt;fetch</STRONG>) methods, to fetch the data in the fastest possible way. The example below
  -prints the TABLE with matched data, the only memory that is being used is a
  -@cols.
  +If something went wrong, go through the installation process again, and
  +make sure you didn't make a mistake. If that doesn't help, read the <CODE>INSTALL</CODE> pod document (<CODE>perlpod INSTALL</CODE>) in the mod_perl distribution directory.
   
   <P>
  -<PRE>  my @select_fields = qw(a b c);
  -      # create a list of cols values
  -  my @cols = ();
  -  @cols[0..$#select_fields] = ();
  -  $sth = $dbh-&gt;prepare($do_sql);
  -  $sth-&gt;execute;
  -    # Bind perl variables to columns.
  -  $sth-&gt;bind_columns(undef,\(@cols));
  -  print &quot;&lt;TABLE&gt;&quot;;
  -  while($sth-&gt;fetch) {
  -     print &quot;&lt;TR&gt;&quot;,
  -           map(&quot;&lt;TD&gt;$_&lt;/TD&gt;&quot;, @cols),
  -           &quot;&lt;/TR&gt;&quot;;
  -  }
  -  print &quot;&lt;/TABLE&gt;&quot;;
  -</PRE>
  +Now copy some of your perl/CGI scripts into a <CODE>/home/httpd/perl/</CODE>
  +directory and see them working much much faster, from the newly configured
  +base URL (<CODE>/perl/</CODE>). Some of your scripts will not work out of box and will demand some minor
  +tweaking or major rewrite to make them work properly with mod_perl enabled
  +server. Chances are that if you are not practicing a sloppy programming
  +techniques -- the scripts will work without any modifications at all.
  +
   <P>
  -Note: the above method doesn't allow you to know how many records have been
  -matched. The workaround is to run an identical query before the code above
  -where you use <STRONG>SELECT count(*) ...</STRONG> instead of <STRONG>'SELECT *
  -...</STRONG> to get the number of matched records.
  +The above setup is very basic, it will help you to have a mod_perl enabled
  +server running and to get a good feeling from watching your previously slow
  +CGIs now flying.
   
   <P>
  -For those who think that <STRONG>$sth-&gt;rows</STRONG> will do the job, here is the quote from the DBI manpage: 
  +As with <STRONG>perl</STRONG> you can start benefit from <STRONG>mod_perl</STRONG> from the very first moment you try it. When you become more familiar with
  +mod_perl you will want to start writing apache handlers and deploy more of
  +the mod_perl power.
   
  -<BLOCKQUOTE>
  +<P>
  +<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<CENTER><H1><A NAME="One_Plain_and_One_mod_perl_enabl">One Plain and One mod_perl enabled Apache Servers</A></H1></CENTER>
  +<P>
  +Since we are going to run two apache servers we will need two different
  +sets of configuration, log and other files. We need a special directory
  +layout. While some of the directories can be shared between the two servers
  +(assuming that both are built from the same source distribution), others
  +should be separated. From now on I will refer to these two servers as <STRONG>httpd_docs</STRONG> (vanilla Apache) and
  +<STRONG>httpd_perl</STRONG> (Apache/mod_perl).
   
   <P>
  -rows <CODE>$rv</CODE> = $sth-&gt;rows;
  +For this illustration, we will use <CODE>/usr/local</CODE> as our <EM>root</EM>
  +directory. The Apache installation directories will be stored under this
  +root (<CODE>/usr/local/bin</CODE>, <CODE>/usr/local/etc</CODE> and etc...)
   
   <P>
  -Returns the number of rows affected by the last database altering command,
  -or -1 if not known or not available. Generally you can only rely on a row
  -count after a do or non-select execute (for some specific operations like
  -update and delete) or after fetching all the rows of a select statement.
  +First let's prepare the sources. We will assume that all the sources go
  +into <CODE>/usr/src</CODE> dir. It is better when you use two separate copies of apache sources. Since
  +you probably will want to tune each apache version at separate and to do
  +some modifications and recompilations as the time goes. Having two
  +independent source trees will prove helpful, unless you use <CODE>DSO</CODE>, which is covered later in this section.
   
   <P>
  -For select statements it is generally not possible to know how many rows
  -will be returned except by fetching them all. Some drivers will return the
  -number of rows the application has fetched so far but others may return -1
  -until all rows have been fetched. So use of the rows method with select
  -statements is not recommended.
  +Make two subdirectories:
   
  -</BLOCKQUOTE>
  +<P>
  +<PRE>  % mkdir /usr/src/httpd_docs
  +  % mkdir /usr/src/httpd_perl
  +</PRE>
  +<P>
  +Put the Apache sources into a <CODE>/usr/src/httpd_docs</CODE> directory:
   
   <P>
  -As a bonus, I wanted to write a single sub that flexibly processes any
  -query, accepting: conditions, callback closure sub, select fields and
  -restrictions. 
  +<PRE>  % cd /usr/src/httpd_docs
  +  % gzip -dc /tmp/apache_x.x.x.tar.gz | tar xvf -
  +</PRE>
  +<P>
  +If you have a gnu tar:
   
   <P>
  -<PRE>  # $o-&gt;dump(\%conditions,\&amp;callback_closure,\@select_fields,@restrictions)
  -  sub dump{
  -    my $self = shift;
  -    my %param = %{+shift}; # dereference hash
  -    my $rsub = shift;
  -    my @select_fields = @{+shift}; # dereference list
  -    my @restrict = shift || '';
  -  
  -      # create a list of cols values
  -    my @cols = ();
  -    @cols[0..$#select_fields] = ();
  -  
  -    my $do_sql = '';
  -    my @where = ();
  -  
  -      # make a @where list 
  -    map { push @where, &quot;$_='$param{$_}'&quot; if $param{$_};} keys %param;
  -  
  -      # prepare the sql statement
  -    $do_sql = &quot;SELECT &quot;;
  -    $do_sql .= join(&quot; &quot;, @restrict) if @restrict;# append the restriction list
  -    $do_sql .= &quot; &quot; .join(&quot;,&quot;, @select_fields) ;      # append the select list 
  -    $do_sql .= &quot; FROM $DBConfig{TABLE} &quot;;         # from table
  -  
  -      # we will not add the WHERE clause if @where is empty
  -    $do_sql .= &quot; WHERE &quot; . join &quot; AND &quot;, @where if @where;
  -  
  -    print &quot;SQL: $do_sql \n&quot; if $debug;
  -  
  -    $dbh-&gt;{RaiseError} = 1;     # do this, or check every call for errors
  -    $sth = $dbh-&gt;prepare($do_sql);
  -    $sth-&gt;execute;
  -      # Bind perl variables to columns.
  -    $sth-&gt;bind_columns(undef,\(@cols));
  -    while($sth-&gt;fetch) {
  -      &amp;$rsub(@cols);
  -    }
  -      # print the tail or &quot;no records found&quot; message
  -      # according to the previous calls
  -    &amp;$rsub();
  -  
  -  } # end of sub dump
  +<PRE>  % tar xvzf /tmp/apache_x.x.x.tar.gz
   </PRE>
   <P>
  -Now a callback closure sub can do lots of things. We need a closure to know
  -what stage are we in: header, body or tail. For example, we want a callback
  -closure for formatting the rows to print: 
  +Replace <CODE>/tmp</CODE> directory with a path to a downloaded file and
  +<CODE>x.x.x</CODE> with the version of the server you have.
   
   <P>
  -<PRE>  my $rsub = eval {
  -      # make a copy of @fields list, since it might go
  -      # out of scope when this closure will be called
  -    my @fields = @fields; 
  -    my @query_fields = qw(user dir tool act); # no date field!!!
  -    my $header = 0;
  -    my $tail   = 0;
  -    my $counter = 0;
  -    my %cols = (); # columns name=&gt; value hash
  -  
  -    # Closure with the following behavior:
  -    # 1. Header's code will be executed on the first call only and
  -    #    if @_ was set
  -    # 2. Row's printing code will be executed on every call with @_ set
  -    # 3. Tail's code will be executed only if Header's code was
  -    #    printed and @_ isn't set
  -    # 4. &quot;No record found&quot; code will be executed if Header's code
  -    #    wasn't executed
  -  
  -    sub {
  -          # Header
  -        if (@_ and !$header){
  -          print &quot;&lt;TABLE&gt;\n&quot;;
  -          print $q-&gt;Tr(map{ $q-&gt;td($_) } @fields );
  -          $header = 1; 
  -        }
  -        
  -          # Body
  -        if (@_) {
  -          print $q-&gt;Tr(map{$q-&gt;td($_)} @_ );
  -          $counter++;
  -          return; 
  -        }
  -        
  -          # Tail, will be printed only at the end
  -        if ($header and !($tail or @_)){
  -          print &quot;&lt;/TABLE&gt;\n $counter records found&quot;;
  -          $tail = 1;
  -          return;
  -        }
  -        
  -          # No record found
  -        unless ($header){
  -          print $q-&gt;p($q-&gt;center($q-&gt;b(&quot;No record was found!\n&quot;)));
  -        }
  +<PRE>  % cd /usr/src/httpd_docs
     
  -      }  #  end of sub {}
  -  };  #  end of my $rsub = eval {
  +  % ls -l
  +  drwxr-xr-x  8 stas  stas 2048 Apr 29 17:38 apache_x.x.x/
   </PRE>
   <P>
  -You might also want to check <A HREF="././performance.html#Limiting_the_size_of_the_process">Limiting the size of the processes</A>
  -and <A HREF="././performance.html#Limiting_the_resources_used_by_h">Limiting the resources used by httpd children</A>.
  +Now we will prepare the <CODE>httpd_perl</CODE> server sources:
   
   <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>
  +<PRE>  % cd /usr/src/httpd_perl
  +  % gzip -dc /tmp/apache_x.x.x.tar.gz | tar xvf -
  +  % gzip -dc /tmp/modperl-x.xx.tar.gz | tar xvf -
  +  
  +  % ls -l
  +  drwxr-xr-x  8 stas  stas 2048 Apr 29 17:38 apache_x.x.x/
  +  drwxr-xr-x  8 stas  stas 2048 Apr 29 17:38 modperl-x.xx/
  +</PRE>
   <P>
  -At the beginning there was:
  +Time to decide on the desired directory structure layout (where the apache
  +files go):
   
   <P>
  -<PRE>  open IN, &quot;in.txt&quot; or die &quot;Cannot open in.txt for reading : $!\n&quot;;
  +<PRE>  ROOT = /usr/local
   </PRE>
   <P>
  -But it was not perfect for mod_perl, since you have had to make sure you
  -do:
  +The two servers can share the following directories (so we will not
  +duplicate data):
   
   <P>
  -<PRE>  close IN;
  +<PRE>  /usr/local/bin/
  +  /usr/local/lib
  +  /usr/local/include/
  +  /usr/local/man/
  +  /usr/local/share/
   </PRE>
   <P>
  -somewhere before the end of the script, since if you do not, you will get a
  -file descriptor leakage and unlock problem. Even if you do have it, but for
  -some reason the interpreter did not make it to it, because of various
  -reasons, such as user aborted script (<A HREF="././obvious.html#Handling_the_User_pressed_Stop_">Handling the 'User pressed Stop button' case</A>) the leakage is still there.
  +<STRONG>Important:</STRONG> we assume that both servers are built from the same Apache source version.
   
   <P>
  -What do we do? We use <CODE>IO::File</CODE> (and other <CODE>IO::*</CODE>), which allows us to assign the file handler to variable, which can be <CODE>my()</CODE>
  -scoped. And when this variable goes out of scope the file or other file
  -system entity will be properly closed and unlocked (if was locked).
  +Servers store their specific files either in <CODE>httpd_docs</CODE> or
  +<CODE>httpd_perl</CODE> sub-directories:
   
   <P>
  -<PRE>  {
  -    my $fh = new IO::File(&quot;filename&quot;) or die $!;
  -    # read from $fh
  -  } # ...$fh is closed automatically at end of block, without leaks.
  +<PRE>  /usr/local/etc/httpd_docs/
  +                 httpd_perl/
  +  
  +  /usr/local/sbin/httpd_docs/
  +                  httpd_perl/
  +  
  +  /usr/local/var/httpd_docs/logs/
  +                            proxy/
  +                            run/
  +                 httpd_perl/logs/
  +                            proxy/
  +                            run/
   </PRE>
   <P>
  -But even faster and lighter technique is to use <CODE>Symbol.pm</CODE>:
  +After completion of the compilation and the installation of the both
  +servers, you will need to configure them. To make things clear before we
  +proceed into details, you should configure the
  +<CODE>/usr/local/etc/httpd_docs/httpd.conf</CODE> as a plain apache and <CODE>Port</CODE>
  +directive to be 80 for example. And
  +<CODE>/usr/local/etc/httpd_perl/httpd.conf</CODE> to configure for mod_perl server and of course whose <CODE>Port</CODE> should be different from the one
  +<CODE>httpd_docs</CODE> server listens to (e.g. 8080). The port numbers issue will be discussed
  +later.
   
   <P>
  -<PRE>  {
  -    my $fh = Symbol::gensym();
  -    open $fh, &quot;filename&quot; or die $!
  -  }
  -</PRE>
  +The next step is to configure and compile the sources: Below are the
  +procedures to compile both servers taking into account the directory layout
  +I have just suggested to use.
  +
   <P>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<CENTER><H1><A NAME="Sometimes_it_Works_Sometimes_it_">Sometimes it Works Sometimes it does Not (Very important!)</A></H1></CENTER>
  +<CENTER><H2><A NAME="Configuration_and_Compilation_of">Configuration and Compilation of the Sources.</A></H2></CENTER>
   <P>
  -When you start running your scripts under mod_perl, you might find yourself
  -in situation where a script seems to work, but sometimes it screws up. And
  -the more it runs without a restart, the more it screws up. Many times you
  -can resolve this problem very easily. You have to test your script under
  -with Server running as a 
  -<A HREF="././control.html#Running_server_in_a_single_mode">single process</A>.
  +Let's proceed with instalation. I will use x.x.x instead of real version
  +numbers so this document will never become obsolete :).
   
   <P>
  -Generally the problem you have is using global variables. Since global
  -variables don't change from one script invocation to another unless you
  -change them, you can find your scripts do ``fancy'' things.
  +<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<CENTER><H3><A NAME="Building_the_httpd_docs_Server">Building the httpd_docs Server</A></H3></CENTER>
  +<DL>
  +<P><DT><STRONG><A NAME="item_Sources">Sources Configuration:</A></STRONG><DD>
  +<P>
  +<PRE>  % cd /usr/src/httpd_docs/apache_x.x.x
  +  % make clean
  +  % env CC=gcc \
  +  ./configure --prefix=/usr/local \
  +    --sbindir=/usr/local/sbin/httpd_docs \
  +    --sysconfdir=/usr/local/etc/httpd_docs \
  +    --localstatedir=/usr/local/var/httpd_docs \
  +    --runtimedir=/usr/local/var/httpd_docs/run \
  +    --logfiledir=/usr/local/var/httpd_docs/logs \
  +    --proxycachedir=/usr/local/var/httpd_docs/proxy
  +</PRE>
  +<P>
  +If you need some other modules, like mod_rewrite and mod_include (SSI), add
  +them here as well:
   
   <P>
  -The first example is amazing -- Web Services. Imagine that you enter some
  -site you have your account on (Free Email Account?). Now you want to see
  -what other users read.
  +<PRE>    --enable-module=include --enable-module=rewrite
  +</PRE>
  +<P>
  +Note: <CODE>gcc</CODE> -- compiles httpd by 100K+ smaller then <CODE>cc</CODE> on AIX OS. Remove the line <CODE>env CC=gcc</CODE> if you want to use the default compiler. If you want to use it and you are
  +a (ba)?sh user you will not need the
  +<CODE>env</CODE> function, t?csh users will have to keep it in.
   
   <P>
  -You type in your name and passwd, and you expect to enter to your account,
  -but instead you enter the account of someone else. This is cool isn't it?
  -Is it a bug or feature. (For some of us it's a feature, while for others
  -it's a bug.) You say, why in the world does this happen? The answer is
  -simple: Global Variables. You have entered the account of someone who
  -happened to be served by the same server child as you. Because of sloppy
  -programming, a global variable was not reset at the beginning of the
  -program and voila, you can easily peek into other people's emails! You
  -would think that it can't happen, since you have entered the login and
  -passwd. I tell you, it happens! See for yourself:
  +Note: add <CODE>--layout</CODE> to see the resulting directories' layout without actually running the
  +configuration process.
   
  +<P><DT><STRONG>Sources Compilation:</STRONG><DD>
   <P>
  -<PRE>  use vars ($authenticated);
  -  my $q = new CGI; 
  -  my $username = $q-&gt;param('username');
  -  my $passwd   = $q-&gt;param('passwd');
  -  authenticate($username,$passwd);
  -    # failed, break out
  -  die &quot;Wrong passwd&quot; unless $authenticated == 1;
  -    # user is OK, fetch user's data
  -  show_user($username);
  -  
  -  sub authenticate{
  -    my ($username,$passwd) = @_;
  -        # some checking
  -    $authenticated = 1 if (SOMETHING);
  -  }
  +<PRE>  % make
  +  % make install
   </PRE>
   <P>
  -Do you see the catch? With the code above, I can type in any valid username
  -and any dummy passwd and enter that user's account, if someone has
  -successfully entered his account before me using the same child process!
  -Since <STRONG>$authenticated</STRONG> is global - if it becomes 1 once it'll be 1 for the remainder of the
  -child's life!!! The solution is trivial -- reset <STRONG>$authenticated</STRONG> to 0 at the beginning of the program. (Or many other different solutions).
  -Of course this example is trivial -- but believe me it happens!
  +Rename <CODE>httpd</CODE> to <CODE>http_docs</CODE>
  +
  +
  +
  +<P>
  +<PRE>  % mv /usr/local/sbin/httpd_docs/httpd \
  +  /usr/local/sbin/httpd_docs/httpd_docs
  +</PRE>
  +<P>
  +Now update an <STRONG>apachectl</STRONG> utility to point to the renamed httpd via your favorite text editor or by
  +using perl:
  +
  +<P>
  +<PRE>  % perl -p -i -e 's|httpd_docs/httpd|httpd_docs/httpd_docs|' \
  +  /usr/local/sbin/httpd_docs/apachectl
  +</PRE>
  +</DL>
  +<P>
  +<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<CENTER><H3><A NAME="Building_the_httpd_perl_mod_per">Building the httpd_perl (mod_perl enabled) Server</A></H3></CENTER>
  +<P>
  +Before you start to configure the mod_perl sources, you should be aware
  +that there are a few Perl modules that have to be installed before building
  +mod_perl. You will be alerted if any required modules are missing when you
  +run the <CODE>perl Makefile.PL</CODE> command line below. If you discover that some are missing, pick them from
  +your nearest CPAN repository (if you do not know what is it, make a visit
  +to <A HREF="http://www.perl.com/CPAN">http://www.perl.com/CPAN</A> ) or run
  +the <CODE>CPAN</CODE> interactive shell via the command line <CODE>perl -MCPAN -e shell</CODE>.
   
   <P>
  -Just another little one liner that can spoil your day, assuming you forgot
  -to reset the <STRONG>$allowed</STRONG> variable. It works perfectly OK in plain mod_cgi:
  +Make sure the sources are clean:
   
   <P>
  -<PRE>  $allowed = 1 if $username eq 'admin';
  +<PRE>  % cd /usr/src/httpd_perl/apache_x.x.x
  +  % make clean
  +  % cd /usr/src/httpd_perl/mod_perl-x.xx
  +  % make clean
   </PRE>
   <P>
  -But you will let any user to admin your system with the line above (again
  -assuming you have used the same child prior to some user request).
  +It is important to <STRONG>make clean</STRONG> since some of the versions are not binary compatible (e.g apache 1.3.3 vs
  +1.3.4) so any ``third-party'' C modules need to be re-compiled against the
  +latest header files.
   
   <P>
  -Another good example is usage of the <STRONG>/o</STRONG> regular expression qualifier, which compiles a regular expression once, on
  -its first execution. This problem can be difficult to detect, as after
  -restarting the server each request you make will be served by a different
  -child process, and thus the regex pattern for that child will be compiled
  -fresh. Only when you make a request that happens to be served by a child
  -which has already cached the regexp will you see the problem. Generally you
  -miss that and when you press reload, you see that it works (with a new,
  -fresh child) and then it doesn't (with a child that already cached the
  -regexp and wouldn't recompile because of <STRONG>/o</STRONG>.)
  +Here I did not find a way to compile with <CODE>gcc</CODE> (my perl was compiled with <CODE>cc</CODE> so we have to compile with the same compiler!!!
   
   <P>
  -To make sure you don't miss these bugs always test your CGI in
  -<A HREF="././control.html#Running_server_in_a_single_mode">single process</A>. To solve this particular <STRONG>/o</STRONG> problem refer to <A HREF="././obvious.html#Compiled_Regular_Expressions">Compiled Regular Expressions</A>.
  -
  +<PRE>  % cd /usr/src/httpd_perl/mod_perl-x.xx
  +</PRE>
   <P>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<CENTER><H1><A NAME="The_Script_is_too_dirty_It_does">The Script is too dirty, It does the job and I can't afford rewriting it.</A></H1></CENTER>
  +<PRE>  % /usr/local/bin/perl Makefile.PL \
  +  APACHE_PREFIX=/usr/local/ \
  +  APACHE_SRC=../apache_x.x.x/src \
  +  DO_HTTPD=1 \
  +  USE_APACI=1 \
  +  PERL_MARK_WHERE=1 \
  +  PERL_STACKED_HANDLERS=1 \
  +  ALL_HOOKS=1 \
  +  APACI_ARGS=--sbindir=/usr/local/sbin/httpd_perl, \
  +         --sysconfdir=/usr/local/etc/httpd_perl, \
  +         --localstatedir=/usr/local/var/httpd_perl, \
  +         --runtimedir=/usr/local/var/httpd_perl/run, \
  +         --logfiledir=/usr/local/var/httpd_perl/logs, \
  +         --proxycachedir=/usr/local/var/httpd_perl/proxy
  +</PRE>
   <P>
  -You still can win from using mod_perl. 
  +Notice that <STRONG>all</STRONG>  <CODE>APACI_ARGS</CODE> (above) must be passed as one long line if you work with <CODE>t?csh</CODE>!!! However it works correctly the way it shown above with <CODE>(ba)?sh</CODE> (by breaking the long lines with '<CODE>\</CODE>'). If you work with <CODE>t?csh</CODE> it does not work, since <CODE>t?csh</CODE>
  +passes <CODE>APACI_ARGS</CODE> arguments to <CODE>./configure</CODE> by keeping the new lines untouched, but stripping the original '<CODE>\</CODE>', thus breaking the configuration process.
   
   <P>
  -One approach is to replace the Apache::Registry handler with
  -Apache::PerlRun and define a new location (the script can reside in the
  -same directory on the disk. 
  +As with <CODE>httpd_docs</CODE> you might need other modules like
  +<CODE>mod_rewrite</CODE>, so add them here:
   
   <P>
  -<PRE>  # srm.conf
  -  Alias /cgi-perl/ /home/httpd/cgi/
  -  
  -  # httpd.conf
  -  &lt;Location /cgi-perl&gt;
  -    #AllowOverride None
  -    SetHandler perl-script
  -    PerlHandler Apache::PerlRun
  -    Options ExecCGI
  -    allow from all
  -    PerlSendHeader On
  -  &lt;/Location&gt;
  +<PRE>         --enable-module=rewrite
   </PRE>
   <P>
  -See <A HREF="#Apache_PerlRun_a_closer_look">Apache::PerlRun - a closer look</A>
  +Note: <CODE>PERL_STACKED_HANDLERS=1</CODE> is needed for <CODE>Apache::DBI</CODE>
   
   
   
   <P>
  -Another ``bad'', but working method is to set MaxRequestsPerChild to 1,
  -which will force each child to exit after serving only one request, so
  -you'll get the preloaded modules, etc., the script will be compiled each
  -request, then killed off. This isn't good for ``high-traffic'' sites
  -though, as the parent server will need to fork a new child each time one is
  -killed, but you can fiddle with MaxStartServers, MinSpareServers, to make
  -the parent spawn more servers ahead so the killed one will be immediately
  -replaced with the fresh one. Again, probably that's not what you want.
  +Now, build, test and install the <CODE>httpd_perl</CODE>.
   
   <P>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<CENTER><H1><A NAME="Apache_PerlRun_a_closer_look">Apache::PerlRun - a closer look</A></H1></CENTER>
  +<PRE>  % make &amp;&amp; make test &amp;&amp; make install
  +</PRE>
   <P>
  -Apache::PerlRun gives you a benefit of preloaded perl and its modules. This
  -module's handler emulates the CGI environment, allowing programmers to
  -write scripts that run under CGI or mod_perl without any change. Unlike
  -Apache::Registry, the Apache::PerlRun handler does not cache the script
  -inside of a subroutine. Scripts will be ``compiled'' on each request. After
  -the script has run, its name space is flushed of all variables and
  -subroutines. Still, you don't have the overhead of loading the perl and
  -compilation time of the standard modules (If your script is very light, but
  -uses lots of standard modules - you will see no difference between
  -Apache::PerlRun and Apache::Registry !).
  +Note: apache puts a stripped version of <CODE>httpd</CODE> at
  +<CODE>/usr/local/sbin/httpd_perl/httpd</CODE>. The original version which includes debugging symbols (if you need to run
  +a debugger on this executable) is located at
  +<CODE>/usr/src/httpd_perl/apache_x.x.x/src/httpd</CODE>.
   
   <P>
  -Be aware though, that if you use packages that use internal variables that
  -have circular references, they will be not flushed!!!
  +Note: You may have noticed that we did not run <CODE>make install</CODE> in the apache's source directory. When <CODE>USE_APACI</CODE> is enabled,
  +<CODE>APACHE_PREFIX</CODE> will specify the <CODE>--prefix</CODE> option for apache's
  +<CODE>configure</CODE> utility, specifying the installation path for apache. When this option is
  +used, mod_perl's <CODE>make install</CODE> will also
  +<CODE>make install</CODE> on the apache side, installing the httpd binary, support tools, along with
  +the configuration, log and document trees.
   
   <P>
  -Apache::PerlRun only flushes your script's name space, which does not
  -include any other required packages' name spaces. If there's a reference to
  -a <STRONG>my()</STRONG> scoped variable that's keeping it from being DESTROYed after leaving the
  -eval scope (of Apache::PerlRun), that cleanup might not be taken care of
  -until the server is shutdown and <CODE>perl_destruct()</CODE> is run, which
  -always happens after running command line scripts. Consider this example:
  +If <CODE>make test</CODE> fails, look into <CODE>t/logs</CODE> and see what is in there. Also see <A HREF="././install.html#make_test_fails">make test fails</A>.
   
   <P>
  -<PRE>  package Foo;
  -  sub new { bless {} }
  -  sub DESTROY {
  -    warn &quot;Foo-&gt;DESTROY\n&quot;;
  -  }
  -  
  -  eval &lt;&lt;'EOF';
  -  package my_script;
  -  my $self = Foo-&gt;new;
  -  #$self-&gt;{circle} = $self;
  -  EOF
  -  
  -  print $@ if $@;
  -  print &quot;Done with script\n&quot;;
  -</PRE>
  +While doing <CODE>perl Makefile.PL ...</CODE> mod_perl might complain by warning you about missing <CODE>libgdbm</CODE>. Users reported that it is actually crucial, and you must have it in order
  +to successfully complete the mod_perl building process.
  +
   <P>
  -First you'll see:
  +Now rename the <CODE>httpd</CODE> to <CODE>httpd_perl</CODE>:
   
   <P>
  -<PRE>  Foo-&gt;DESTROY
  -  Done with script
  +<PRE>  % mv /usr/local/sbin/httpd_perl/httpd \
  +  /usr/local/sbin/httpd_perl/httpd_perl
   </PRE>
   <P>
  -Then, uncomment the line where <CODE>$self</CODE> makes a circular
  -reference, and you'll see:
  +Update the apachectl utility to point to renamed httpd name:
   
   <P>
  -<PRE>  Done with script
  -  Foo-&gt;DESTROY
  +<PRE>  % perl -p -i -e 's|httpd_perl/httpd|httpd_perl/httpd_perl|' \
  +  /usr/local/sbin/httpd_perl/apachectl
   </PRE>
  +<P>
  +<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<CENTER><H2><A NAME="Configuration_of_the_servers">Configuration of the servers</A></H2></CENTER>
   <P>
  -In this case, under mod_perl you wouldn't see 'Foo-&gt;DESTROY' until the
  -server shutdown, or your module properly took care of things.
  +Now when we have completed the building process, the last stage before
  +running the servers, is to configure them.
   
   <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>
  +<CENTER><H3><A NAME="Basic_httpd_docs_Server_s_Config">Basic httpd_docs Server's Configuration</A></H3></CENTER>
   <P>
  -To trap all/most Perl run-time errors and send the output to the client
  -instead of Apache's error log add this line to your script.
  +Configuring of <CODE>httpd_docs</CODE> server is a very easy task. Open
  +<CODE>/usr/local/etc/httpd_docs/httpd.conf</CODE> into your favorite editor (starting from version 1.3.4 of Apache - there is
  +only one file to edit). And configure it as you always do. Make sure you
  +configure the log files and other paths according to the directory layout
  +we decided to use.
   
   <P>
  -<PRE>  use CGI::Carp qw(fatalsToBrowser);
  +Start the server with:
  +
  +<P>
  +<PRE>  /usr/local/sbin/httpd_docs/apachectl start
   </PRE>
   <P>
  -Refer to <CODE>CGI::Carp</CODE> man page for more related info.
  +<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<CENTER><H3><A NAME="Basic_httpd_perl_Server_s_Config">Basic httpd_perl Server's Configuration</A></H3></CENTER>
  +<P>
  +Here we will make a basic configuration of the <CODE>httpd_perl</CODE> server. We edit the <CODE>/usr/local/etc/httpd_perl/httpd.conf</CODE> file. As with
  +<CODE>httpd_docs</CODE> server configuration, make sure that <CODE>ErrorLog</CODE> and other file's location directives are set to point to the right places,
  +according to the chosen directory layout.
   
   <P>
  -Also you can write your custom DIE/WARN signal handler. I don't want users
  -to see the error message, but I want it to be emailed to me if it's severe
  -enough. The handler traps various errors and performs accordingly to the
  -defined logic. My handler was written for the modperl environment, but
  -works correctly when is being called from the shell. A stripped version of
  -the code is shown here:
  +The first thing to do is to set a <CODE>Port</CODE> directive - it should be different from <CODE>80</CODE> since we cannot bind 2 servers to use the same port number on the same
  +machine. Here we will use &lt;8080&gt;. Some developers use port <CODE>81</CODE>, but you can bind to it, only if you have root permissions. If you are
  +running on multiuser machine, there is a chance someone already uses that
  +port, or will start using it in the future - which as you understand might
  +cause a collision. If you are the only user on your machine, basically you
  +can pick any not used port number. Port number choosing is a controversial
  +topic, since many organizations use firewalls, which may block some of the
  +ports, or enable only a known ones. From my experience the most used port
  +numbers are: <CODE>80</CODE>, <CODE>81</CODE>, <CODE>8000</CODE> and <CODE>8080</CODE>. Personally, I prefer the port <CODE>8080</CODE>. Of course with 2 server scenario you can hide the nonstandard port number
  +from firewalls and users, by either using the mod_proxy's <CODE>ProxyPass</CODE> or proxy server like squid.
   
   <P>
  -<PRE>  # assign the DIE sighandler to call mydie(error_message) whenever a
  -  # die() sub is being called. Can be added anywhere in the code.
  -  local $SIG{'__DIE__'} = \&amp;mydie;
  -  
  -Do not forget the C&lt;local()&gt;, unless you want this signal handler to
  -be invoked every time any scripts dies (Even those where this
  -treatment is undesirable)
  -</PRE>
  +For more details see <A HREF="././config.html#Publishing_port_numbers_differen">Publishing port numbers different from 80 </A>, <A HREF="././scenario.html#Running_1_webserver_and_squid_in">Running 1 webserver and squid in httpd accelerator mode</A>,
  +<A HREF="././scenario.html#Running_2_webservers_and_squid_i">Running 2 webservers and squid in httpd accelerator mode</A>
  +and <A HREF="././scenario.html#Using_mod_proxy">Using mod_proxy</A>.
  +
   <P>
  -<PRE>  # and the handler itself
  -  sub mydie{
  -    my $why = shift;
  -  
  -    my $UNDER_MOD_PERL = ( (exists $ENV{'GATEWAY_INTERFACE'} 
  -                           and $ENV{'GATEWAY_INTERFACE'} =~ /CGI-Perl/)
  -                         or exists $ENV{'MOD_PERL'} ) ? 1 : 0;
  -  
  -    chomp $why;
  -    my $orig_why = $why;                # an ascii copy for email report
  -  
  -    # handle the shell execution case (so we will not get all the HTML)
  -    print(&quot;Error: $why\n&quot;), exit unless $UNDER_MOD_PERL;
  -  
  -    my $should_email = 0;
  -    my $message = '';
  -  
  -    $why =~ s/[&lt;&amp;&gt;]/&quot;&amp;#&quot;.ord($&amp;).&quot;;&quot;/ge;    # entity escape
  -  
  -    # Now we need to trap various kinds of errors, that come from CGI.pm
  -    # And we don't want these errors to be emailed to us, since
  -    # these aren't programmatical errors
  -    if ($orig_why =~ /Client attempted to POST (\d+) bytes/o) {
  -  
  -      $message = qq{
  -                  You can not POST messages bigger than 
  -                  @{[1024*$c{max_image_size}]} bytes.&lt;BR&gt;
  -                  You have tried to post $1 bytes&lt;BR&gt;
  -                  If you are trying to upload an image, make sure its size is not 
  -                  bigger than @{[1024*$c{max_image_size}]} bytes.&lt;P&gt;
  -                  Thank you!
  -                 };
  -  
  -    } elsif ($orig_why =~ /Malformed multipart POST/o) {
  -  
  -      $message = qq{
  -                  Have you tried to upload an image in the wrong way?&lt;P&gt;
  -                  To sucessfully upload an image you must use a browser that supports
  -                  image upload and use the 'Browse' button to select that image.
  -                  DO NOT type the path to the image into the upload field.&lt;P&gt;
  -                  Thank you!
  -                 };
  -  
  -    } elsif ($orig_why =~ /closed socket during multipart read/o) {
  -  
  -      $message = qq{
  -                  Have you pressed a 'STOP' button?&lt;BR&gt;
  -                  Please try again!&lt;P&gt;
  -                  Thank you!
  -                 };
  -  
  -    } else {
  -  
  -      $message = qq{
  -                    &lt;B&gt;There is no action to be performed on your side, since
  -                  the error report has been already sent to webmaster. &lt;BR&gt;&lt;P&gt;
  -                  &lt;B&gt;Thank you for your patience!&lt;/B&gt;
  -                 };
  -  
  -      $should_email = 1;
  -    }
  -  
  -  
  -    print qq|Content-type: text/html
  -  
  -  &lt;HTML&gt;&lt;BODY BGCOLOR=&quot;white&quot;&gt;
  -  &lt;B&gt;Oops, An error has happened.&lt;/B&gt;&lt;P&gt;
  -    |;  
  -  
  -    print $message;
  -  
  -      # send email report if appropriate
  -    if ($should_email){
  -  
  -        # import sendmail subs
  -      use Mail ();
  -        # prepare the email error report:
  -      my $subject =&quot;Error Report&quot;;
  -      my $body = qq|
  -    An error has happened:
  -  
  -    $orig_why
  -  
  -      |;
  -  
  -        # send error reports to admin and author
  -      send_mail($c{email}{'admin'},$c{email}{'admin'},$subject,$body);
  -      send_mail($c{email}{'admin'},$c{email}{'author'},$subject,$body);
  -      print STDERR &quot;[&quot;.scalar localtime().&quot;] [SIGDIE] Sending Error Email\n&quot;;
  -    }
  -  
  -       # print to error_log so we will know we've sent
  -    print STDERR &quot;[&quot;.scalar localtime().&quot;] [SIGDIE] $orig_why \n&quot;;
  -  
  -    exit 1;
  -  }                             # end of sub mydie
  -  
  -</PRE>
  +Now we proceed to mod_perl specific directives. A good idea will be to add
  +them all at the end of the <CODE>httpd.conf</CODE>, since you are going to fiddle a lot with them at the beginning.
  +
   <P>
  -You may have noticed that I trap the CGI.pm's <CODE>die()</CODE> calls
  -here, I don't see any reason why my users should see an ugly error
  -messages, but that's the way CGI.pm written. The workaround is to trap them
  -myself.
  +First, you need to specify the location where all mod_perl scripts will be
  +located.
   
   <P>
  -Please note that as of ver 2.49, CGI.pm provides a <CODE>cgi_error()</CODE>
  -method to print the errors and wouldn't <CODE>die()</CODE> unless you want
  -it.
  +Add the following configuration directive:
   
   <P>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<CENTER><H1><A NAME="Finding_the_line_number_the_erro">Finding the line number the error/warning has been triggered at</A></H1></CENTER>
  +<PRE>    # mod_perl scripts will be called from
  +  Alias /perl/ /usr/local/myproject/perl/
  +</PRE>
   <P>
  -<CODE>Apache::Registry</CODE>, <CODE>Apache::PerlRun</CODE> and modules that compile-via-eval confuse the line numbering. Other files
  -that are read normally by Perl from disk have no problem with file
  -name/line number.
  +From now on, all requests starting with <CODE>/perl</CODE> will be executed under <CODE>mod_perl</CODE> and will be mapped to the files in
  +<CODE>/usr/local/myproject/perl/</CODE>.
   
   <P>
  -If you compile with the experimental <STRONG>PERL_MARK_WHERE=1</STRONG>, it shows you ``exactly'' where this is happening. Generally compiler
  -makes a shift in its line counter. You can always stuff your code with
  -special compiler directives, to reset its counter to the value you will
  -tell. At the beginning of the line you should write (the '#' in column 1):
  +Now we should configure the <CODE>/perl</CODE> location.
   
   <P>
  -<PRE>  #line 298 myscript.pl
  -  or 
  -  #line 890 some_label_to_be_used_in_the_error_message
  +<PRE>  PerlModule Apache::Registry
   </PRE>
   <P>
  -The label is optional - the filename of the script will be used by default.
  -This specifies the line number of the <STRONG>following</STRONG> line, not the line the directive is on. You can use a little script to
  -stuff every N lines of your code with these directives, but then you will
  -have to rerun this script every time you add or remove code lines. The
  -script:
  +<PRE>  &lt;Location /perl&gt;
  +    #AllowOverride None
  +    SetHandler perl-script
  +    PerlHandler Apache::Registry
  +    Options ExecCGI
  +    allow from all
  +    PerlSendHeader On
  +  &lt;/Location&gt;
  +</PRE>
  +<P>
  +This configuration causes all scripts that are called with a <CODE>/perl</CODE>
  +path prefix to be executed under the <CODE>Apache::Registry</CODE> module and as a CGI (so the <CODE>ExecCGI</CODE>, if you omit this option the script will be printed to the user's browser
  +as a plain text or will possibly trigger a '<STRONG>Save-As</STRONG>' window). <CODE>Apache::Registry</CODE> module lets you run almost unaltered CGI/perl scripts under <CODE>mod_perl</CODE>. <CODE>PerlModule</CODE> directive is an equivalent of perl's <CODE>require()</CODE>. We load the
  +<CODE>Apache::Registry</CODE> module before we use it in the <CODE>PerlHandler</CODE> in the <CODE>Location</CODE> configuration.
   
   <P>
  -<PRE>    &lt;META&gt;
  -        This example was double incrementing $counter.
  -        I took the second increment out -- sgr.
  -    &lt;/META&gt;
  -</PRE>
  +<CODE>PerlSendHeader On</CODE> tells the server to send an HTTP header to the browser on every script
  +invocation. You will want to turn this off for nph (non-parsed-headers)
  +scripts.
  +
   <P>
  -<PRE>  #!/usr/bin/perl
  -  # Puts Perl line markers in a Perl program for debugging purposes.  
  -  # Also takes out old line markers.
  -  die &quot;No filename to process.\n&quot; unless @ARGV;
  -  my $filename = $ARGV[0];
  -  my $lines = 100;
  -  open IN, $filename or die &quot;Cannot open file: $filename: $!\n&quot;;
  -  open OUT, &quot;&gt;$filename.marked&quot;
  -      or die &quot;Cannot open file: $filename.marked: $!\n&quot;;
  -  my $counter = 1;
  -  while (&lt;IN&gt;) {
  -    print OUT &quot;#line $counter\n&quot; unless $counter++ % $lines;
  -    next if $_ =~ /^#line /;
  -    print OUT $_;
  -  }
  -  close OUT;
  -  close IN;
  -  chmod 0755, &quot;$filename.marked&quot;;
  -</PRE>
  +This is only a very basic configuration. <A HREF="././config.html#">Server Configuration</A> section covers the rest of the details.
  +
   <P>
  -To have a complete trace of calls add:
  +Now start the server with:
   
   <P>
  -<PRE>  use Carp ();
  -  local $SIG{__WARN__} = \&amp;Carp::cluck;
  +<PRE>  /usr/local/sbin/httpd_perl/apachectl start
   </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="Running_2_webservers_and_squid_i">Running 2 webservers and squid in httpd accelerator mode</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_speling or whatever modules you have used in your
  -server, all the core routines and so on. A much wiser approche 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 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
  -function 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
  -should be loaded again for this extenal program to run.
  +While I have detailed the mod_perl server installation, you are on your own
  +with installing the squid server (See <A HREF="././help.html#">Getting Helped</A> for more details). I run linux, so I downloaded the rpm package, installed
  +it, configured the <CODE>/etc/squid/squid.conf</CODE>, fired off the server and was all set. Basically once you have the squid
  +installed, you just need to modify the default <CODE>squid.conf</CODE> the way I will explain below, then you are ready to run it.
   
   <P>
  -Basically, you would do:
  +First, lets understand what do we have in hands and what do we want from
  +squid. We have an <CODE>httpd_docs</CODE> and <CODE>httpd_perl</CODE> servers listening on ports 81 and 8080 accordingly (we have to move the
  +httpd_docs server to port 81, since port 80 will be taken over by squid).
  +Both reside on the same machine as squid. We want squid to listen on port
  +80, forward a single static object request to the port httpd_docs server
  +listens to, and dynamic request to httpd_perl's port. Both servers return
  +the data to the proxy server (unless it is already cached in the squid), so
  +user never sees the other ports and never knows that there might be more
  +then one server running. Proxy server makes all the magic behind it
  +transparent to user. Do not confuse it with <STRONG>mod_rewrite</STRONG>, where a server redirects the request somewhere according to the rules and
  +forgets about it. The described functionality is being known as <CODE>httpd accelerator mode</CODE> in proxy dialect.
   
  -<P>
  -<PRE>  $params=FreezeThaw::freeze(
  -        [all data to pass to the other process]
  -        );
  -  system(&quot;program.pl $params&quot;);
  -</PRE>
   <P>
  -and in <CODE>program.pl</CODE> :
  +You should understand that squid can be used as a straight forward proxy
  +server, generally used at companies and ISPs to cut down the incoming
  +traffic by caching the most popular requests. However we want to run it in
  +the <CODE>httpd accelerator mode</CODE>. Two directives:
  +<CODE>httpd_accel_host</CODE> and <CODE>httpd_accel_port</CODE> enable this mode. We will see more details in a few seconds. If you are
  +currently using the squid in the regular proxy mode, you can extend its
  +functionality by running both modes concurrently. To accomplish this, you
  +extend the existent squid configuration with <CODE>httpd accelerator mode</CODE>'s related directives or you just create one from scratch.
   
   <P>
  -<PRE>  @params=FreezeThaw::thaw(shift @ARGV);
  -  # check that @params is ok
  -  close STDIN;
  -  close STDOUT;
  -  open STDERR, &quot;&gt;/dev/null&quot;;
  -  setsid(); # to detach
  -</PRE>
  +As stated before, squid listens now to the port 80, we have to move the
  +httpd_docs server to listen for example to the port 81 (your mileage may
  +vary :). So you have to modify the httpd.conf in the httpd_docs
  +configuration directory and restart the httpd_docs server (But not before
  +we get the squid running if you are working on the production server). And
  +as you remember httpd_perl listens to port 8080.
  +
   <P>
  -At this point, <CODE>program.pl</CODE> is running in the ``background'' while the <CODE>system()</CODE> returns
  -and permits apache to get on with life.
  +Let's go through the changes we should make to the default configuration
  +file. Since this file (<CODE>/etc/squid/squid.conf</CODE>) is huge (about 60k+) and we would not use 95% of it, my suggestion is to
  +write a new one including only the modified directives.
   
   <P>
  -This has obvious problems. Not the least of which is that
  -<CODE>$params</CODE> must not be bigger then whatever your architecture's
  -limit is (could depend on your shell).
  +We want to enable the redirect feature, to be able to serve requests, by
  +more then one server (in our case we have httpd_docs and httpd_perl)
  +servers. So we specify <CODE>httpd_accel_host</CODE> as virtual. This assumes that your server has multiple interfaces - Squid
  +will bind to all of them.
   
   <P>
  -Also, the communication is only one way.
  +<PRE>  httpd_accel_host virtual
  +</PRE>
  +<P>
  +Then we define the default port - by default, if not redirected, httpd_docs
  +will serve the pages. We assume that most requests will be of the static
  +nature. We have our httpd_docs listening on port 81.
   
   <P>
  -However, you might want be trying to do the ``wrong thing''. If what you
  -want is to send information to the browser and then do some
  -post-processing, look into <CODE>PerlCleanupHandler</CODE>.
  +<PRE>  httpd_accel_port 81
  +</PRE>
  +<P>
  +And as described before, squid listens to port 80.
   
   <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>
  +<PRE>  http_port 80
  +</PRE>
   <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:
  +We do not use icp (icp used for cache sharing between neighbor machines),
  +which is more relevant in the proxy mode.
   
   <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>  icp_port 0
   </PRE>
   <P>
  -your generated <CODE>Set-Cookie</CODE> header is split over a number of print statements and gets lost. Try this:
  +<CODE>hierarchy_stoplist</CODE> defines a list of words which, if found in a URL, causes the object to be
  +handled directly by this cache. In other words, use this to not query
  +neighbor caches for certain objects. Note that I have configured the <CODE>/cgi-bin</CODE> and <CODE>/perl</CODE> aliases for my dynamic documents, if you named them in a different way,
  +make sure to use the correct aliases here.
   
   <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>  hierarchy_stoplist /cgi-bin /perl
   </PRE>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -	     The <a href="http://www.modperl.com/">
  -	     <B>Writing Apache Modules with Perl and C</B></a>
  -	     book can be purchased online from <a
  -	     href="http://www.ora.com/catalog/wrapmod/">O'Reilly </a>
  -	     and <a
  -	     href="http://www.amazon.com/exec/obidos/ASIN/156592567X/writinapachemodu">
  -	     Amazon.com</a>.
  +<P>
  +Now we tell squid not to cache dynamic pages.
   
  -	     <HR>
  -	     [    <A HREF="frequent.html">Prev</A> |      <A HREF="index.html">Main Page</A> | <A HREF="performance.html">Next</A>      ]
  +<P>
  +<PRE>  acl QUERY urlpath_regex /cgi-bin /perl
  +  no_cache deny QUERY
  +</PRE>
  +<P>
  +Please note that the last two directives are controversial ones. If you
  +want your scripts to be more complying with the HTTP standards, the headers
  +of your scripts should carry the <CODE>Caching Directives</CODE>
  +according to the HTTP specs. You will find a complete tutorial about this
  +topic in <CODE>Tutorial on HTTP Headers for mod_perl users</CODE> by Andreas J. Koenig. If you set the headers correctly there is no need to
  +tell squid accelerator to <STRONG>NOT</STRONG> try to cache something. The headers I am talking about are <CODE>Last-Modified</CODE> and <CODE>Expires</CODE>. What are they good for? Squid would not bother your mod_perl server a
  +second time if a request is (a) cachable and (b) still in the cache. Many
  +mod_perl applications will produce identical results on identical requests
  +at least if not much time goes by between the requests. So your squid might
  +have a hit ratio of 50%, which means that mod_perl servers will have as
  +twice as less work to do than before. This is only possible by setting the
  +headers correctly.
   
  -<CENTER><TABLE CELLSPACING=2 CELLPADDING=2 WIDTH="100%" >
  -<TR ALIGN=CENTER VALIGN=TOP>
  -  <TD ALIGN=CENTER VALIGN=CENTER COLSPAN="3">
  -	     <HR>
  -  </TD>
  -</TR>
  -<TR ALIGN=CENTER VALIGN=TOP>
  -  <TD ALIGN=CENTER VALIGN=CENTER>
  -    <B>
  -      <FONT SIZE=-1>
  -	     Written by <A HREF="help.html#This_document_s_Author">Stas Bekman</A>.
  -	     <BR>Last Modified at 06/12/1999
  -      </FONT>
  -    </B>
  -  </TD>
  +<P>
  +Even if you insert user-ID and date in your page, caching can save
  +resources when you set the expiration time to 1 second. A user might double
  +click where a single click would do, thus sending two requests in parallel,
  +squid could serve the second request.
   
  -  <TD>
  -	     <A HREF="http://perl.apache.org"><IMG SRC="images/mod_perl2.jpg" ALT="Mod Perl Icon" BORDER=0 HEIGHT=59 WIDTH=150></A>
  -  </TD>
  +<P>
  +But if you are lazy, or just have too many things to deal with, you can
  +leave the above directives the way I described. But keep in mind that one
  +day you will want to reread this snippet and the Andreas' tutorial and
  +squeeze even more power from your servers without investing money for
  +additional memory and better hardware.
   
  -  <TD>
  -    <FONT SIZE=-2>
  -	     Use of the Camel for Perl is <BR>
  -	     a trademark of <A HREF="http://www.ora.com">O'Reilly &amp; Associates</A>,<BR>
  -             and is used by permission. 
  -    </FONT> 
  -  </TD>
  -</TR>
  -</TABLE></CENTER>
  +<P>
  +While testing you might want to enable the debugging options and watch the
  +log files in <CODE>/var/log/squid/</CODE>. But turn it off in your production server. I list it commented out. (28
  +== access control routes).
   
  -</BODY>
  -</HTML>
  -	    
  +<P>
  +<PRE>  # debug_options ALL, 1, 28, 9
  +</PRE>
  +<P>
  +We need to provide a way for squid to dispatch the requests to the correct
  +servers, static object requests should be redirected to httpd_docs (unless
  +they are already cached), while dynamic should go to the httpd_perl server.
  +The configuration below tells squid to fire off 10 redirect daemons at the
  +specified path of the redirect daemon and disables rewriting of any <CODE>Host:</CODE> headers in redirected requests (as suggested by squid's documentation). The
  +redirection daemon script is enlisted below.
   
  -<HR SIZE=6>
  -<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
  -<HTML>
  -<HEAD>
  -   <TITLE>mod_perl guide: Performance. Benchmarks.</TITLE>
  -   <META NAME="GENERATOR" CONTENT="Pod2HTML [Perl/Linux]">
  -   <META NAME="Author" CONTENT="Stas Bekman">
  -   <META NAME="Description" CONTENT="All Apache/Perl related information: Hints, Guidelines, Scenarios and Troubleshottings">
  -   <META NAME="keywords" CONTENT="mod_perl modperl perl apache cgi webserver speed  fast guide mod_perl apache guide help info faq mod_perl installation cgi troubleshooting help no sex speedup free open source OSS mod_perl apache guide">
  -</HEAD>
  -     <LINK REL=STYLESHEET TYPE="text/css"
  -        HREF="style.css" TITLE="refstyle">
  -     <style type="text/css">
  -     <!-- 
  -        @import url(style.css);
  -     -->
  -     
  -     </style>
  -<BODY TEXT="#000000" BGCOLOR="#E0FFFF" LINK="#0000EE" VLINK="#551A8B" ALINK="#FF0000">
  -<A NAME="toc"></A>
  -<H1 ALIGN=CENTER>
  -<A HREF="http://perl.apache.org"><IMG SRC="images/mod_perl.gif" ALT="Mod Perl Icon" BORDER=0 HEIGHT=30 WIDTH=90 ALIGN=LEFT></A>
  -<A HREF="http://perl.apache.org"><IMG SRC="images/mod_perl.gif" ALT="Mod Perl Icon" BORDER=0 HEIGHT=30 WIDTH=90 ALIGN=RIGHT></A>
  -Performance. Benchmarks.</H1>
  -<HR WIDTH="100%">
  -	    [    <A HREF="porting.html">Prev</A> |      <A HREF="index.html">Main Page</A> | <A HREF="obvious.html">Next</A>      ]<HR><!-- INDEX BEGIN -->
  -<P><B><FONT SIZE=-1>Table of Contents:</FONT></B></P>
  -<UL>
  +<P>
  +<PRE>  redirect_program /usr/lib/squid/redirect.pl
  +  redirect_children 10
  +  redirect_rewrites_host_header off
  +</PRE>
  +<P>
  +Maximum allowed request size in kilobytes. This one is pretty obvious. If
  +you are using POST to upload files, then set this to the largest file's
  +size plus a few extra kbytes.
   
  -	<LI><A HREF="#Preload_Perl_modules_at_server_s">Preload Perl modules at server startup</A>
  -	<UL>
  +<P>
  +<PRE>  request_size 1000 KB
  +</PRE>
  +<P>
  +Then we have access permissions, which I will not explain. But you might
  +want to read the documentation so to avoid any security flaws.
   
  -		<LI><A HREF="#Preload_Perl_modules_Real_Numb">Preload Perl modules - Real Numbers</A>
  -	</UL>
  +<P>
  +<PRE>  acl all src 0.0.0.0/0.0.0.0
  +  acl manager proto cache_object
  +  acl localhost src 127.0.0.1/255.255.255.255
  +  acl myserver src 127.0.0.1/255.255.255.255
  +  acl SSL_ports port 443 563
  +  acl Safe_ports port 80 81 8080 81 443 563
  +  acl CONNECT method CONNECT
  +  
  +  http_access allow manager localhost
  +  http_access allow manager myserver
  +  http_access deny manager
  +  http_access deny !Safe_ports
  +  http_access deny CONNECT !SSL_ports
  +  # http_access allow all
  +</PRE>
  +<P>
  +Since squid should be run as non-root user, you need these if you are
  +invoking the squid as root.
   
  -	<LI><A HREF="#Preload_Registry_Scripts">Preload Registry Scripts</A>
  -	<LI><A HREF="#Sharing_Memory">Sharing Memory</A>
  -	<LI><A HREF="#Avoid_Importing_Functions">Avoid Importing Functions</A>
  -	<LI><A HREF="#How_can_I_find_if_my_modperl_scr">How can I find if my modperl scripts have memory leaks (and where)</A>
  -	<LI><A HREF="#Limiting_the_size_of_the_process">Limiting the size of the processes</A>
  -	<LI><A HREF="#Limiting_the_resources_used_by_h">Limiting the resources used by httpd children</A>
  -	<LI><A HREF="#Limiting_the_request_rate_speed_">Limiting the request rate speed (robots blocking)</A>
  -	<LI><A HREF="#Benchmarks_Impressing_your_Boss">Benchmarks. Impressing your Boss and Colleagues.</A>
  -	<UL>
  +<P>
  +<PRE>  cache_effective_user squid
  +  cache_effective_group squid
  +</PRE>
  +<P>
  +Now configure a memory size to be used for caching. A squid documentation
  +warns that the actual size of squid can grow three times larger than the
  +value you are going to set.
   
  -		<LI><A HREF="#Developers_Talk">Developers Talk</A>
  -		<LI><A HREF="#Benchmarking_a_Graphic_hits_coun">Benchmarking a Graphic hits counter with Persistent DB Connection</A>
  -		<LI><A HREF="#Benchmarking_scripts_with_execut">Benchmarking scripts with execution times below 1 second :)</A>
  -		<LI><A HREF="#PerlHandler_s_Benchmarking">PerlHandler's Benchmarking</A>
  -	</UL>
  +<P>
  +<PRE>  cache_mem 20 MB
  +</PRE>
  +<P>
  +Keep pools of allocated (but unused) memory available for future use. Read
  +more about it in the squid documents.
   
  -	<LI><A HREF="#Tuning_the_Apache_s_configuratio">Tuning the Apache's configuration variables for the best performance</A>
  -	<UL>
  +<P>
  +<PRE>  memory_pools on
  +</PRE>
  +<P>
  +Now tight the runtime permissions of the cache manager CGI script (<CODE>cachemgr.cgi</CODE>,that comes bundled with squid) on your production server.
   
  -		<LI><A HREF="#Tuning_with_ab_ApacheBench">Tuning with ab - ApacheBench </A>
  -		<LI><A HREF="#Tuning_with_crashme_script">Tuning with crashme script</A>
  -		<LI><A HREF="#Choosing_MaxClients">Choosing MaxClients</A>
  -		<LI><A HREF="#Choosing_MaxRequestsPerChild">Choosing MaxRequestsPerChild</A>
  -		<LI><A HREF="#Choosing_MinSpareServers_MaxSpa">Choosing MinSpareServers, MaxSpareServers and StartServers</A>
  -		<LI><A HREF="#Summary_of_Benchmarking_to_tune_">Summary of Benchmarking to tune all 5 parameters</A>
  -	</UL>
  +<P>
  +<PRE>  cachemgr_passwd disable shutdown
  +  #cachemgr_passwd none all
  +</PRE>
  +<P>
  +Now the redirection daemon script (you should put it at the location you
  +have specified by <CODE>redirect_program</CODE> parameter in the config file above, and make it executable by webserver of
  +course):
   
  -	<LI><A HREF="#Preopen_DB_connection_at_server_">Preopen DB connection at server startup:</A>
  -	<LI><A HREF="#Persistent_DB_Connections">Persistent DB Connections</A>
  -	<LI><A HREF="#Using_1_under_mod_perl_and_be">Using $|=1 under mod_perl and better print() techniques.</A>
  -	<LI><A HREF="#More_Reducing_Memory_Usage_Tips">More Reducing Memory Usage Tips</A>
  -	<LI><A HREF="#Profiling">Profiling</A>
  -	<LI><A HREF="#CGI_pm_s_object_methods_calls_vs">CGI.pm's object methods calls vs. function calls</A>
  -	<LI><A HREF="#Sending_plain_HTML_as_a_compress">Sending plain HTML as a compressed output</A>
  -</UL>
  -<!-- INDEX END -->
  +<P>
  +<PRE>  #!/usr/local/bin/perl
  +  
  +  $|=1;
  +  
  +  while (&lt;&gt;) {
  +      # redirect to mod_perl server (httpd_perl)
  +    print($_), next if s|(:81)?/perl/|:8080/perl/|o;
  +</PRE>
  +<P>
  +<PRE>      # send it unchanged to plain apache server (http_docs)
  +    print;
  +  }
  +</PRE>
  +<P>
  +In my scenario the proxy and the apache servers are running on the same
  +machine, that's why I just substitute the port. In the presented squid
  +configuration, requests that passed through squid are converted to point to
  +the <STRONG>localhost</STRONG> (which is <CODE>127.0.0.1</CODE>). The above redirector can be more complex of course, but you know the
  +perl, right?
  +
  +<P>
  +A few notes regarding redirector script:
  +
  +<P>
  +You must disable buffering. <CODE>$|=1;</CODE> does the job. If you do not disable buffering, the <CODE>STDOUT</CODE> will be flushed only when the buffer becomes full and its default size is
  +about 4096 characters. So if you have an average URL of 70 chars, only
  +after 59 (4096/70) requests the buffer will be flushed, and the requests
  +will finally achieve the server in target. Your users will just wait till
  +it will be filled up.
  +
  +<P>
  +If you think that it is a very ineffective way to redirect, I'll try to
  +prove you the opposite. The redirector runs as a daemon, it fires up N
  +redirect daemons, so there is no problem with perl interpreter loading,
  +exactly like mod_perl -- perl is loaded all the time and the code was
  +already compiled, so redirect is very fast (not slower if redirector was
  +written in C or alike). Squid keeps an open pipe to each redirect daemon,
  +thus there is even no overhead of the expensive system calls.
   
  -<HR>
  +<P>
  +Now it is time to restart the server, at linux I do it with:
   
  -	     The <a href="http://www.modperl.com/">
  -	     <B>Writing Apache Modules with Perl and C</B></a>
  -	     book can be purchased online from <a
  -	     href="http://www.ora.com/catalog/wrapmod/">O'Reilly </a>
  -	     and <a
  -	     href="http://www.amazon.com/exec/obidos/ASIN/156592567X/writinapachemodu">
  -	     Amazon.com</a>.
  +<P>
  +<PRE>  /etc/rc.d/init.d/squid restart
  +</PRE>
  +<P>
  +Now the setup is complete ...
   
  -	     <HR>
  +<P>
  +Almost... When you try the new setup, you will be surprised and upset to
  +discover the port 81 showing up in the URLs of the static objects (like
  +htmls). Hey, we did not want the user to see the port 81 and use it instead
  +of 80, since than it will bypass the squid server and the hard work we went
  +through was just a waste of time? The solution is to run both squid and
  +httpd_docs on the same port. This can be accomplished by binding each one
  +to a specific interface. Modify the
  +<CODE>httpd.conf</CODE> in the <CODE>httpd_docs</CODE> configuration directory:
   
  -	      <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
   <P>
  -<CENTER><H1><A NAME="Preload_Perl_modules_at_server_s">Preload Perl modules at server startup</A></H1></CENTER>
  +<PRE>  Port 80
  +  BindAddress 127.0.0.1
  +  Listen 127.0.0.1:80
  +</PRE>
   <P>
  -Use the <CODE>PerlRequire</CODE> and <CODE>PerlModule</CODE> directives to load commonly used modules such as <CODE>CGI.pm</CODE>, <CODE>DBI</CODE> and etc., when the server is started. On most systems, server children will
  -be able to share the code space used by these modules. Just add the
  -following directives into <CODE>httpd.conf</CODE>:
  +Modify the <CODE>squid.conf</CODE>:
   
   <P>
  -<PRE>  PerlModule CGI;
  -  PerlModule DBI;
  +<PRE>  http_port 80
  +  tcp_incoming_address 123.123.123.3
  +  tcp_outgoing_address 127.0.0.1
  +  httpd_accel_host 127.0.0.1
  +  httpd_accel_port 80
   </PRE>
  +<P>
  +Where <CODE>123.123.123.3</CODE> should be replaced with IP of your main server. Now restart squid and
  +httpd_docs in either order you want, and voila the port number has gone.
  +
   <P>
  -But even better to create a separate startup file (with regular perl code)
  -and put there things like:
  +You must also have in the <CODE>/etc/hosts</CODE> an entry (most chances that it's already there):
   
   <P>
  -<PRE>  use DBI;
  -  use Carp;
  +<PRE>  127.0.0.1  localhost.localdomain   localhost
   </PRE>
   <P>
  -Then you <CODE>require()</CODE> this file with help of <CODE>PerlRequire</CODE> directive from <CODE>httpd.conf</CODE>, before the rest of the mod_perl configuration directives:
  +Now if your scripts were generating HTML including fully qualified self
  +references, using the 8080 or other port -- you should fix them to generate
  +links to point to port 80 (which means not using the port at all). If you
  +do not, users will bypass squid, like if it was not there at all, by making
  +direct requests to the mod_perl server's port. The only question left is
  +what to do with users who bookmarked your services and they still have the
  +port 8080 inside the URL. Do not worry about it. The most important thing
  +is for your scripts to return a full URLs, so if the user comes from the
  +link with 8080 port inside, let it be. Just make sure that all the
  +consecutive calls to your server will be rewritten correctly. During a
  +period of time users will change their bookmarks. What can be done is to
  +send them an email if you have one, or to leave a note on your pages asking
  +users to update their bookmarks. You could avoid this problem if you did
  +not publish this non-80 port in first place. See <A HREF="././config.html#Publishing_port_numbers_differen">Publishing port numbers different from 80</A>.
   
   <P>
  -<PRE>  PerlRequire /path/to/start-up.pl
  -</PRE>
  +&lt;META&gt; Need to write up a section about server logging with squid.
  +One thing I sure would like to know is how requests are logged with this
  +setup. I have, as most everyone I imagine, log rotation, analysis,
  +archiving scripts and they all assume a single log. Does one have different
  +logs that have to be merged (up to 3 for each server + squid) ? Even when
  +squid responds to a request out of its cache I'd still want the thing to be
  +logged. &lt;/META&gt;
  +
   <P>
  -<CODE>CGI.pm</CODE> is a special case. Ordinarily <CODE>CGI.pm</CODE> autoloads most of its functions on an as-needed basis. This speeds up the
  -loading time by deferring the compilation phase. However, if you are using
  -mod_perl, FastCGI or another system that uses a persistent Perl
  -interpreter, you will want to precompile the methods at initialization
  -time. To accomplish this, call the package function <CODE>compile()</CODE>
  -like this:
  +See <A HREF="././scenario.html#Using_mod_proxy">Using mod_proxy</A> for information about
  +<CODE>X-Forwarded-For</CODE>.
   
   <P>
  -<PRE>    use CGI ();
  -    CGI-&gt;compile(':all');
  +To save you some keystrokes, here is the whole modified <CODE>squid.conf</CODE>:
  +
  +<P>
  +<PRE>  http_port 80
  +  tcp_incoming_address 123.123.123.3
  +  tcp_outgoing_address 127.0.0.1
  +  httpd_accel_host 127.0.0.1
  +  httpd_accel_port 80
  +  
  +  icp_port 0
  +  
  +  hierarchy_stoplist /cgi-bin /perl
  +  acl QUERY urlpath_regex /cgi-bin /perl
  +  no_cache deny QUERY
  +  
  +  # debug_options ALL,1 28,9
  +  
  +  redirect_program /usr/lib/squid/redirect.pl
  +  redirect_children 10
  +  redirect_rewrites_host_header off
  +  
  +  request_size 1000 KB
  +  
  +  acl all src 0.0.0.0/0.0.0.0
  +  acl manager proto cache_object
  +  acl localhost src 127.0.0.1/255.255.255.255
  +  acl myserver src 127.0.0.1/255.255.255.255
  +  acl SSL_ports port 443 563
  +  acl Safe_ports port 80 81 8080 81 443 563
  +  acl CONNECT method CONNECT
  +  
  +  http_access allow manager localhost
  +  http_access allow manager myserver
  +  http_access deny manager
  +  http_access deny !Safe_ports
  +  http_access deny CONNECT !SSL_ports
  +  # http_access allow all
  +  
  +  cache_effective_user squid
  +  cache_effective_group squid
  +  
  +  cache_mem 20 MB
  +  
  +  memory_pools on
  +  
  +  cachemgr_passwd disable shutdown
   </PRE>
   <P>
  -The arguments to <CODE>compile()</CODE> are a list of method names or sets, and are identical to those accepted by
  -the use operator. Note that in most cases you will want to replace <CODE>':all'</CODE> with the tags' names you really use in your code. 
  +Note that all directives should start at the beginning of the line.
   
   <P>
  -You can also preload the Registry scripts. See <A HREF="#Preload_Registry_Scripts">Preload Registry Scripts</A>.
  +<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<CENTER><H1><A NAME="Running_1_webserver_and_squid_in">Running 1 webserver and squid in httpd accelerator mode</A></H1></CENTER>
  +<P>
  +When I was first told about squid, I thought: ``Hey, Now I can drop the
  +<CODE>httpd_docs</CODE> server and to have only squid and <CODE>httpd_perl</CODE>
  +servers``. Since all my static objects will be cached by squid, I do not
  +need the light <CODE>httpd_docs</CODE> server. But it was a wrong assumption. Why? Because you still have the
  +overhead of loading the objects into squid at first time, and if your site
  +has many of them -- not all of them will be cached (unless you have devoted
  +a huge chunk of memory to squid) and my heavy mod_perl servers will still
  +have an overhead of serving the static objects. How one would measure the
  +overhead? The difference between the two servers is memory consumption,
  +everything else (e.g. I/O) should be equal. So you have to estimate the
  +time needed for first time fetching of each static object at a peak period
  +and thus the number of additional servers you need for serving the static
  +objects. This will allow you to calculate additional memory requirements. I
  +can imagine, this amount could be significant in some installations.
   
   <P>
  -<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>
  +So I have decided to have even more administration overhead and to stick
  +with squid, httpd_docs and httpd_perl scenario, where I can optimize and
  +fine tune everything. Of course this can be not your case. If you are
  +feeling that the scenario from the previous section is too complicated for
  +you, make it simpler. Have only one server with mod_perl built in and let
  +the squid to do most of the job that plain light apache used to do. As I
  +have explained in the previous paragraph, you should pick this lighter
  +setup only if you can make squid cache most of your static objects. If it
  +cannot, your mod_perl server will do the work we do not want it to.
  +
   <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
  -few of them (to see more memory saved) and also the effect of precompiling
  -the Registry modules with <CODE>Apache::RegistryLoader</CODE>.
  +If you are still with me, install apache with mod_perl and squid. Then use
  +a similar configuration from the previous section, but now httpd_docs is
  +not there anymore. Also we do not need the redirector anymore and we
  +specify <CODE>httpd_accel_host</CODE> as a name of the server and not <CODE>virtual</CODE>. There is no need to bind two servers on the same port, because we do not
  +redirect and there is neither <CODE>Bind</CODE> nor <CODE>Listen</CODE>
  +directives in the <CODE>httpd.conf</CODE> anymore.
   
   <P>
  ---------------------------------------------------------------------------------
  +The modified configuration (see the explanations in the previous section):
   
  +<P>
  +<PRE>  httpd_accel_host put.your.hostname.here
  +  httpd_accel_port 8080
  +  http_port 80
  +  icp_port 0
  +  
  +  hierarchy_stoplist /cgi-bin /perl
  +  acl QUERY urlpath_regex /cgi-bin /perl
  +  no_cache deny QUERY
  +  
  +  # debug_options ALL, 1, 28, 9
  +  
  +  # redirect_program /usr/lib/squid/redirect.pl
  +  # redirect_children 10
  +  # redirect_rewrites_host_header off
  +  
  +  request_size 1000 KB
  +  
  +  acl all src 0.0.0.0/0.0.0.0
  +  acl manager proto cache_object
  +  acl localhost src 127.0.0.1/255.255.255.255
  +  acl myserver src 127.0.0.1/255.255.255.255
  +  acl SSL_ports port 443 563
  +  acl Safe_ports port 80 81 8080 81 443 563
  +  acl CONNECT method CONNECT
  +  
  +  http_access allow manager localhost
  +  http_access allow manager myserver
  +  http_access deny manager
  +  http_access deny !Safe_ports
  +  http_access deny CONNECT !SSL_ports
  +  # http_access allow all
  +  
  +  cache_effective_user squid
  +  cache_effective_group squid
  +  
  +  cache_mem 20 MB
  +  
  +  memory_pools on
  +  
  +  cachemgr_passwd disable shutdown
  +</PRE>
  +<P>
  +<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<CENTER><H1><A NAME="Using_mod_proxy">Using mod_proxy</A></H1></CENTER>
  +<P>
  +Now we will talk about apache's mod_proxy and understand how it works.
   
   <P>
  -1. In the first test, the following script was used:
  +The server on port 80 answers http requests directly and proxies the
  +mod_perl enabled server in the following way:
   
   <P>
  -<PRE>  use strict;
  -  use CGI ();
  -  my $q = new CGI;
  -  print $q-&gt;header;
  -  print $q-&gt;start_html,$q-&gt;p(&quot;Hello&quot;);
  +<PRE>  ProxyPass /modperl/ <A HREF="http://localhost:81/modperl/">http://localhost:81/modperl/</A>
  +  ProxyPassReverse /modperl/ <A HREF="http://localhost:81/modperl/">http://localhost:81/modperl/</A>
   </PRE>
   <P>
  -&lt;Server restarted&gt;
  +<CODE>PPR</CODE> is the saving grace here, that makes apache a win over Squid. It rewrites
  +the redirect on its way back to the original URI.
   
   <P>
  -Before the <CODE>CGI.pm</CODE> preload: (No other modules preloaded)
  +You can control the buffering feature with <CODE>ProxyReceiveBufferSize</CODE>
  +directive:
   
   <P>
  -<PRE>  USER        PID %CPU %MEM   SZ  RSS    TTY STAT    STIME  TIME COMMAND
  -  root      87004  0.0  0.0 1060 1524      - A    16:51:14  0:00 httpd
  -  httpd    240864  0.0  0.0 1304 1784      - A    16:51:13  0:00 httpd
  +<PRE>  ProxyReceiveBufferSize 1048576
   </PRE>
   <P>
  -After running a script which uses CGI's methods (no imports):
  +The above setting will set a buffer size to be of 1Mb. If it is not set
  +explicitly, then the default buffer size is used, which depends on OS, for
  +Linux I suspect it is somewhere below 32k. So basically to get an immediate
  +release of the mod_perl server from stale awaiting,
  +<CODE>ProxyReceiveBufferSize</CODE> should be set to a value greater than the biggest generated respond
  +produced by any mod_perl script.
   
   <P>
  -<PRE>  USER        PID %CPU %MEM   SZ  RSS    TTY STAT    STIME  TIME COMMAND
  -  root     188068  0.0  0.0 1052 1524      - A    17:04:16  0:00 httpd
  -  httpd     86952  0.0  1.0 2520 3052      - A    17:04:16  0:00 httpd
  -</PRE>
  +The <CODE>ProxyReceiveBufferSize</CODE> directive specifies an explicit buffer size for <STRONG>outgoing</STRONG> HTTP and FTP connections. It has to be greater than 512 or set to 0 to
  +indicate that the system's default buffer size should be used.
  +
   <P>
  -Observation: child httpd has grown up by 1268K
  +As the name states, its buffering feature applies only to <STRONG>downstream
  +data</STRONG> (coming from the origin server to the proxy) and not upstream (i.e.
  +buffering the data being uploaded from the client browser to the proxy,
  +thus freeing the httpd_perl origin server from being tied up during a large
  +POST such as a file upload).
   
   <P>
  -&lt;Server restarted&gt;
  +Apache does caching as well. It's relevant to mod_perl only if you produce
  +proper headers, so your scripts' output can be cached. See apache
  +documentation for more details on configuration of this capability.
   
   <P>
  -After the <CODE>CGI.pm</CODE> preload:
  +Ask Bjoern Hansen has written a <CODE>mod_proxy_add_forward</CODE> module for apache, that sets the <CODE>X-Forwarded-For</CODE> field when doing a
  +<CODE>ProxyPass</CODE>, similar to what squid can do. (Its location is specified in the help
  +section). Basically, that module adds an extra HTTP header to proxying
  +requests. You can access that header in the mod_perl-enabled server, and
  +set the IP of the remote server. You won't need to compile anything into
  +the back-end server, if you are using <CODE>Apache::{Registry,PerlRun}</CODE> just put something like the following into <CODE>start-up.pl</CODE>:
   
   <P>
  -<PRE>  USER        PID %CPU %MEM   SZ  RSS    TTY STAT    STIME  TIME COMMAND
  -  root     240796  0.0  0.0 1456 1552      - A    16:55:30  0:00 httpd
  -  httpd     86944  0.0  0.0 1688 1800      - A    16:55:30  0:00 httpd
  +<PRE>  sub My::ProxyRemoteAddr ($) {
  +    my $r = shift;
  +   
  +        # we'll only look at the X-Forwarded-For header if the requests
  +        # comes from our proxy at localhost
  +        return OK unless ($r-&gt;connection-&gt;remote_ip eq &quot;127.0.0.1&quot;);
  +   
  +        if (my ($ip) = $r-&gt;header_in('X-Forwarded-For') =~ /([^,\s]+)$/) {
  +          $r-&gt;connection-&gt;remote_ip($ip);
  +        }
  +        
  +        return OK;
  +  }
   </PRE>
   <P>
  -after running a script which uses CGI's methods (no imports):
  +And in <CODE>httpd.conf</CODE>:
   
   <P>
  -<PRE>  USER        PID %CPU %MEM   SZ  RSS    TTY STAT    STIME  TIME COMMAND
  -  root      86872  0.0  0.0 1448 1552      - A    17:02:56  0:00 httpd
  -  httpd    187996  0.0  1.0 2808 2968      - A    17:02:56  0:00 httpd
  +<PRE>  PerlPostReadRequestHandler My::ProxyRemoteAddr
   </PRE>
   <P>
  -Observation: child httpd has grown up by 1168K, 100K less then without
  -preload - good!
  +Different sites have different needs. If you're using the header to set the
  +IP address, apache believes it is dealing with (in the logging and stuff),
  +you really don't want anyone but your own system to set the header. That's
  +why the above ``recommended code'' checks where the request is really
  +coming from, before changing the <CODE>remote_ip</CODE>.
   
   <P>
  -&lt;Server restarted&gt;
  +From that point on, the remote IP address is correct. You should be able to
  +access <CODE>REMOTE_ADDR</CODE> as usual.
   
   <P>
  -After <CODE>CGI.pm</CODE> preloaded and compiled with CGI-&gt;compile(':all');
  +You could do the same thing with other environment variables (though I
  +think several of them are preserved, you will want to run some tests to see
  +which ones).
   
   <P>
  -<PRE>  USER        PID %CPU %MEM   SZ  RSS    TTY STAT    STIME  TIME COMMAND
  -  root      86980  0.0  0.0 2836 1524      - A    17:05:27  0:00 httpd
  -  httpd    188104  0.0  0.0 3064 1768      - A    17:05:27  0:00 httpd
  -</PRE>
  +<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<CENTER><H1><A NAME="mod_perl_server_as_DSO">mod_perl server as DSO</A></H1></CENTER>
   <P>
  -After running a script which uses CGI's methods (no imports):
  +To build the mod_perl as DSO add <CODE>USE_DSO=1</CODE> to the rest of configuration parameters (to build <CODE>libperl.so</CODE> instead of
  +<CODE>libperl.a</CODE>), like:
   
   <P>
  -<PRE>  USER        PID %CPU %MEM   SZ  RSS    TTY STAT    STIME  TIME COMMAND
  -  root      86980  0.0  0.0 2828 1524      - A    17:05:27  0:00 httpd
  -  httpd    188104  0.0  1.0 4188 2940      - A    17:05:27  0:00 httpd
  +<PRE>  perl Makefile.PL USE_DSO=1 ...
   </PRE>
   <P>
  -Observation: child httpd has grown up by 1172K No change! So what does
  -CGI-&gt;compile(':all') help? I think it's because we never use all of the
  -methods CGI provides - so in real use it's faster. So you might want to
  -compile only the tags you are about to use - then you will benefit for
  -sure.
  +If you run <CODE>./configure</CODE> from apache source do not forget to add:
  +<CODE>--enable-shared=perl</CODE>
   
  -<P>
  ---------------------------------------------------------------------------------
   
   
   <P>
  -2. I have tried the second test to find it. I run the script:
  +Then just add the <CODE>LoadModule</CODE> directive into your <CODE>httpd.conf</CODE>.
   
  -<P>
  -<PRE>  use strict;
  -  use CGI qw(:all);
  -  print header,start_html,p(&quot;Hello&quot;);
  -</PRE>
   <P>
  -&lt;Server restarted&gt;
  +You will find a complete explanation in the <CODE>INSTALL.apaci</CODE> pod which can be found in the mod_perl distribution.
   
   <P>
  -After <CODE>CGI.pm</CODE> was preloaded and NOT compiled with CGI-&gt;compile(':all'):
  +Some people reported that DSO compiled mod_perl would not run on specific
  +OS/perl version. Also threads enabled perl reported sometimes to break the
  +mod_perl/DSO. But it still can work for you.
   
   <P>
  -<PRE>  USER        PID %CPU %MEM   SZ  RSS    TTY STAT    STIME  TIME COMMAND
  -  root      17268  0.0  0.0 1456 1552      - A    18:02:49  0:00 httpd
  -  httpd     86904  0.0  0.0 1688 1800      - A    18:02:49  0:00 httpd
  -</PRE>
  +<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<CENTER><H1><A NAME="HTTP_Authentication_with_2_serve">HTTP Authentication with 2 servers + proxy</A></H1></CENTER>
   <P>
  -After running a script which imports symbols (all of them):
  +Assuming that you have a setup of one ``front-end'' server, which proxies
  +the ``back-end'' (mod_perl) server, if you need to perform the
  +authentication in the ``back-end'' server, it should handle all
  +authentication itself. If apache proxies correctly, it seems like it would
  +pass through all authentication information, making the ``front-end''
  +apache somewhat ``dumb'', as it does nothing, but passes through all the
  +information.
   
  -<P>
  -<PRE>  USER        PID %CPU %MEM   SZ  RSS    TTY STAT    STIME  TIME COMMAND
  -  root      17268  0.0  0.0 1448 1552      - A    18:02:49  0:00 httpd
  -  httpd     86904  0.0  1.0 2952 3112      - A    18:02:49  0:00 httpd
  -</PRE>
   <P>
  -Observation: child httpd has grown up by 1264K
  +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>
  -&lt;Server restarted&gt;
  +<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +	     The <a href="http://www.modperl.com/">
  +	     <B>Writing Apache Modules with Perl and C</B></a>
  +	     book can be purchased online from <a
  +	     href="http://www.ora.com/catalog/wrapmod/">O'Reilly </a>
  +	     and <a
  +	     href="http://www.amazon.com/exec/obidos/ASIN/156592567X/writinapachemodu">
  +	     Amazon.com</a>.
   
  -<P>
  -After <CODE>CGI.pm</CODE> was preloaded and compiled with CGI-&gt;compile(':all'):
  +	     <HR>
  +	     [    <A HREF="strategy.html">Prev</A> |      <A HREF="index.html">Main Page</A> | <A HREF="install.html">Next</A>      ]
   
  -<P>
  -<PRE>  USER        PID %CPU %MEM   SZ  RSS    TTY STAT    STIME  TIME COMMAND
  -  root      86812  0.0  0.0 2836 1524      - A    17:59:52  0:00 httpd
  -  httpd     99104  0.0  0.0 3064 1768      - A    17:59:52  0:00 httpd
  -</PRE>
  -<P>
  -After running a script which imports symbols (all of them):
  +<CENTER><TABLE CELLSPACING=2 CELLPADDING=2 WIDTH="100%" >
  +<TR ALIGN=CENTER VALIGN=TOP>
  +  <TD ALIGN=CENTER VALIGN=CENTER COLSPAN="3">
  +	     <HR>
  +  </TD>
  +</TR>
  +<TR ALIGN=CENTER VALIGN=TOP>
  +  <TD ALIGN=CENTER VALIGN=CENTER>
  +    <B>
  +      <FONT SIZE=-1>
  +	     Written by <A HREF="help.html#This_document_s_Author">Stas Bekman</A>.
  +	     <BR>Last Modified at 07/02/1999
  +      </FONT>
  +    </B>
  +  </TD>
   
  -<P>
  -<PRE>  USER        PID %CPU %MEM   SZ  RSS    TTY STAT    STIME  TIME COMMAND
  -  root      86812  0.0  0.0 2832 1436      - A    17:59:52  0:00 httpd
  -  httpd     99104  0.0  1.0 4884 3636      - A    17:59:52  0:00 httpd
  -</PRE>
  -<P>
  -Observation: child httpd has grown by 1868K. Why? Isn't
  -<CODE>CGI::compile(':all')</CODE> supposed to make children to share the compiled code with parent? It does
  -works as advertised, but if you pay attention in the code we have called
  -only three <CODE>CGI.pm</CODE>'s methods - just saying <CODE>use CGI qw(:all)</CODE> doesn't mean we compile the all available methods - we just import their
  -names. So actually this test is misleading. Execute <CODE>compile()</CODE> only on the methods you are actually using and then you will see the
  -difference.
  +  <TD>
  +	     <A HREF="http://perl.apache.org"><IMG SRC="images/mod_perl2.jpg" ALT="Mod Perl Icon" BORDER=0 HEIGHT=59 WIDTH=150></A>
  +  </TD>
   
  -<P>
  ---------------------------------------------------------------------------------
  +  <TD>
  +    <FONT SIZE=-2>
  +	     Use of the Camel for Perl is <BR>
  +	     a trademark of <A HREF="http://www.ora.com">O'Reilly &amp; Associates</A>,<BR>
  +             and is used by permission. 
  +    </FONT> 
  +  </TD>
  +</TR>
  +</TABLE></CENTER>
   
  +</BODY>
  +</HTML>
  +	    
   
  -<P>
  -3. The third script:
  +<HR SIZE=6>
  +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
  +<HTML>
  +<HEAD>
  +   <TITLE>mod_perl guide: Installation Notes</TITLE>
  +   <META NAME="GENERATOR" CONTENT="Pod2HTML [Perl/Linux]">
  +   <META NAME="Author" CONTENT="Stas Bekman">
  +   <META NAME="Description" CONTENT="All Apache/Perl related information: Hints, Guidelines, Scenarios and Troubleshottings">
  +   <META NAME="keywords" CONTENT="mod_perl modperl perl apache cgi webserver speed  fast guide mod_perl apache guide help info faq mod_perl installation cgi troubleshooting help no sex speedup free open source OSS mod_perl apache guide">
  +</HEAD>
  +     <LINK REL=STYLESHEET TYPE="text/css"
  +        HREF="style.css" TITLE="refstyle">
  +     <style type="text/css">
  +     <!-- 
  +        @import url(style.css);
  +     -->
  +     
  +     </style>
  +<BODY TEXT="#000000" BGCOLOR="#E0FFFF" LINK="#0000EE" VLINK="#551A8B" ALINK="#FF0000">
  +<A NAME="toc"></A>
  +<H1 ALIGN=CENTER>
  +<A HREF="http://perl.apache.org"><IMG SRC="images/mod_perl.gif" ALT="Mod Perl Icon" BORDER=0 HEIGHT=30 WIDTH=90 ALIGN=LEFT></A>
  +<A HREF="http://perl.apache.org"><IMG SRC="images/mod_perl.gif" ALT="Mod Perl Icon" BORDER=0 HEIGHT=30 WIDTH=90 ALIGN=RIGHT></A>
  +Installation Notes</H1>
  +<HR WIDTH="100%">
  +	    [    <A HREF="scenario.html">Prev</A> |      <A HREF="index.html">Main Page</A> | <A HREF="config.html">Next</A>      ]<HR><!-- INDEX BEGIN -->
  +<P><B><FONT SIZE=-1>Table of Contents:</FONT></B></P>
  +<UL>
   
  -<P>
  -<PRE>  use strict;
  -  use CGI;
  -  use Data::Dumper;
  -  use Storable;
  -  [and many lines of code, lots of globals - so the code is huge!]
  -</PRE>
  -<P>
  -&lt;Server restarted&gt;
  +	<LI><A HREF="#Configuration_and_Installation">Configuration and Installation</A>
  +	<UL>
   
  -<P>
  -Nothing preloaded at startup:
  +		<LI><A HREF="#perl">perl</A>
  +		<LI><A HREF="#apache">apache</A>
  +		<LI><A HREF="#mod_perl">mod_perl</A>
  +	</UL>
   
  -<P>
  -<PRE>  USER        PID %CPU %MEM   SZ  RSS    TTY STAT    STIME  TIME COMMAND
  -  root      90962  0.0  0.0 1060 1524      - A    17:16:45  0:00 httpd
  -  httpd     86870  0.0  0.0 1304 1784      - A    17:16:45  0:00 httpd
  -</PRE>
  -<P>
  -Script using CGI (methods), Storable, Data::Dumper called:
  +	<LI><A HREF="#How_can_I_tell_whether_mod_perl_">How can I tell whether mod_perl is running</A>
  +	<UL>
   
  -<P>
  -<PRE>  USER        PID %CPU %MEM   SZ  RSS    TTY STAT    STIME  TIME COMMAND
  -  root      90962  0.0  0.0 1064 1436      - A    17:16:45  0:00 httpd
  -  httpd     86870  0.0  1.0 4024 4548      - A    17:16:45  0:00 httpd
  -</PRE>
  -<P>
  -Observation: child httpd has grown by 2764K
  +		<LI><A HREF="#Testing_by_checking_the_error_lo">Testing by checking the error_log file</A>
  +		<LI><A HREF="#Testing_by_viewing_perl_status">Testing by viewing /perl-status</A>
  +		<LI><A HREF="#Testing_via_telnet">Testing via telnet</A>
  +		<LI><A HREF="#Testing_via_a_CGI_script">Testing via a CGI script</A>
  +		<LI><A HREF="#Testing_via_lwp_request">Testing via lwp-request</A>
  +	</UL>
   
  -<P>
  -&lt;Server restarted&gt;
  +	<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_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>
   
  -<P>
  -Preloaded CGI (compiled), Storable, Data::Dumper at startup:
  +		<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>
   
  -<P>
  -<PRE>  USER        PID %CPU %MEM   SZ  RSS    TTY STAT    STIME  TIME COMMAND
  -  root      26792  0.0  0.0 3120 1528      - A    17:19:21  0:00 httpd
  -  httpd     91052  0.0  0.0 3340 1764      - A    17:19:21  0:00 httpd
  -</PRE>
  -<P>
  -Script using CGI (methods), Storable, Data::Dumper called
  +	<LI><A HREF="#Stripping_apache_to_make_it_almo">Stripping apache to make it almost perl-server</A>
  +</UL>
  +<!-- INDEX END -->
   
  -<P>
  -<PRE>  USER        PID %CPU %MEM   SZ  RSS    TTY STAT    STIME  TIME COMMAND
  -  root      26792  0.0  0.0 3124 1440      - A    17:19:21  0:00 httpd
  -  httpd     91052  0.0  1.0 6568 5040      - A    17:19:21  0:00 httpd
  -</PRE>
  -<P>
  -Observation: child httpd has grown by 3276K. Great difference: 512K less!!!
  +<HR>
  +
  +	     The <a href="http://www.modperl.com/">
  +	     <B>Writing Apache Modules with Perl and C</B></a>
  +	     book can be purchased online from <a
  +	     href="http://www.ora.com/catalog/wrapmod/">O'Reilly </a>
  +	     and <a
  +	     href="http://www.amazon.com/exec/obidos/ASIN/156592567X/writinapachemodu">
  +	     Amazon.com</a>.
   
  -<P>
  -&lt;Server restarted&gt;
  +	     <HR>
   
  +	      <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
   <P>
  -All the above modules + the above script PreCompiled with
  -<CODE>Apache::RegistryLoader</CODE> at startup:
  -
  +<CENTER><H1><A NAME="Configuration_and_Installation">Configuration and Installation</A></H1></CENTER>
   <P>
  -<PRE>  USER        PID %CPU %MEM   SZ  RSS    TTY STAT    STIME  TIME COMMAND
  -  root      43224  0.0  0.0 3256 1528      - A    17:23:12  0:00 httpd
  -  httpd     26844  0.0  0.0 3488 1776      - A    17:23:12  0:00 httpd
  -</PRE>
  +<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<CENTER><H2><A NAME="perl">perl</A></H2></CENTER>
   <P>
  -Script using CGI (methods), Storable, Data::Dumper called:
  +Make sure you have perl installed -- the newer stable version you have the
  +better (minimum perl.5.004!). If you don't have it -- install it. Follow
  +the instructions in the distribution's <CODE>INSTALL</CODE>
  +file. During the configuration stage (while running <CODE>./Configure</CODE>), make sure you answer <CODE>YES</CODE> to the question:
   
   <P>
  -<PRE>  USER        PID %CPU %MEM   SZ  RSS    TTY STAT    STIME  TIME COMMAND
  -  root      43224  0.0  0.0 3252 1440      - A    17:23:12  0:00 httpd
  -  httpd     26844  0.0  1.0 6748 5092      - A    17:23:12  0:00 httpd
  +<PRE>  Do you wish to use dynamic loading? [y]
   </PRE>
   <P>
  -Observation: child httpd has grown even more 3316K ! Does not seem to be
  -good!
  +Answer <CODE>y</CODE> to be able to load dynamically Perl Modules extensions.
   
   <P>
  -<STRONG>Summary</STRONG>:
  +<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<CENTER><H2><A NAME="apache">apache</A></H2></CENTER>
  +<P>
  +It is a good idea to try to install the apache webserver without mod_perl
  +first. This way, if something goes wrong, you will know that it's not the
  +apache server's problem. But you can skip this stage if you already have a
  +working (non-mod_perl) apache server, or if you are just the daring type.
  +In any case you should unpack the apache source distribution, preferably at
  +the same level as the mod_perl distribution.
   
   <P>
  -1. Library Perl Modules Preloading gave good results everywhere.
  +<PRE>  % ls -l /usr/src
  +  drwxr-xr-x   8 stas  bar         2048 Oct  6 09:46 apache_x.x.x/
  +  drwxr-xr-x  19 stas  bar         4096 Oct  2 14:33 mod_perl-x.xx/
  +</PRE>
  +<P>
  +<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<CENTER><H2><A NAME="mod_perl">mod_perl</A></H2></CENTER>
  +<P>
  +Now we come to the main point of this document.
   
   <P>
  -2. <CODE>CGI.pm</CODE>'s <CODE>compile()</CODE> method seems to use even more memory. It's because we never use all of the
  -methods CGI provides. Do <CODE>compile()</CODE>
  -only the tags that you are going to use and you will save the overhead of
  -the first call for each has not yet been called method, and the memory -
  -since compiled code will be shared across all the children.
  +Here I will give only a short example of mod_perl installation. You should
  +read the <A HREF="././scenario.html#">Real World Scenarios Implementaion</A> for a more complete description.
   
   <P>
  -3. <CODE>Apache::RegistryLoader</CODE> might make scripts load faster on the first request after the child has
  -just started but the memory usage is worse!!! See the numbers by yourself.
  +As with any perl package, the installation of mod_perl is very easy and
  +standard. <CODE>perldoc INSTALL</CODE> will guide you through the configuration and the installation processes.
   
   <P>
  -HW/SW used : The server is apache 1.3.2, mod_perl 1.16 running on AIX 4.1.5
  -RS6000 1G RAM.
  +The fastest way to install would be:
   
   <P>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<CENTER><H1><A NAME="Preload_Registry_Scripts">Preload Registry Scripts</A></H1></CENTER>
  +<PRE>  % 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
  +</PRE>
   <P>
  -<CODE>Apache::RegistryLoader</CODE> compiles Apache::Registry scripts at server startup. It can be a good idea
  -to preload these as well. So the code will be shared among the child
  -servers.
  +Note: replace x.x.x with the version numbers you actually use.
   
   <P>
  -Here is an example of the use of this technique. This code is included in a <CODE>PerlRequire</CODE>'d file, and walks the directory tree under which all registry scripts are
  -installed. For each <CODE>.pl</CODE> file encountered, it calls the <CODE>Apache::RegistryLoader::handler()</CODE> method to preload the script in the parent server (before preforking the
  -child processes):
  +To change the installation target (either if you are not <CODE>root</CODE> or you need to install a second copy for testing purposes), assuming you
  +use <CODE>/foo/server</CODE> as a base directory, you have to run this:
   
   <P>
  -<PRE>  use File::Find 'finddepth';
  -  use Apache::RegistryLoader ();
  -  {
  -      my $perl_dir = &quot;perl/&quot;;
  -      my $rl = Apache::RegistryLoader-&gt;new;
  -      finddepth(sub {
  -          return unless /\.pl$/;
  -          my $url = &quot;/$File::Find::dir/$_&quot;;
  -          print &quot;pre-loading $url\n&quot;;
  -  
  -          my $status = $rl-&gt;handler($url);
  -          unless($status == 200) {
  -              warn &quot;pre-load of `$url' failed, status=$status\n&quot;;
  -          }
  -      }, $perl_dir);
  -  }
  +<PRE>  % perl Makefile.PL APACHE_SRC=../apache_x.x.x/src \
  +    DO_HTTPD=1 PERL_MARK_WHERE=1 EVERYTHING=1 \
  +    APACHE_PREFIX=/foo/server PREFIX=/foo/server
   </PRE>
   <P>
  -Note that we don't use the second argument to <CODE>handler()</CODE> here. You might need to provide a <CODE>trans()</CODE> method, since it's very dependent on your server's configuration. See <CODE>perldoc Apache::RegistryLoader</CODE>
  -for the complete information.
  +Where <CODE>PREFIX</CODE> specifies where to install the perl modules,
  +<CODE>APACHE_PREFIX</CODE> -- the same for the apache files.
   
   <P>
  -You have to check whether this makes any improvement for you though, I did
  -some testing [ <A HREF="#Preload_Perl_modules_Real_Numb">Preload Perl modules - Real Numbers</A> ], and it seems that it takes more memory than when the scripts are being
  -called from the child - This is only a first impression and needs better
  -investigation. If you aren't concerned about few script invocations which
  -will take some time to respond while they load the code, you might not need
  -it all!
  +The next step is to configure the mod_perl sections of the apache
  +configuration file. (See <A HREF="././config.html#">ModPerlConfiguration</A>).
   
   <P>
  -See also <A HREF="././porting.html#BEGIN_blocks">BEGIN blocks</A>
  -
  -
  +Fire up the server with <CODE>/foo/server/sbin/apachectl start</CODE>, Look for the error reports at the <CODE>error_log</CODE> file in case the server does not start up (No error message will be printed
  +to the console!).
   
   <P>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<CENTER><H1><A NAME="Sharing_Memory">Sharing Memory</A></H1></CENTER>
  +<CENTER><H1><A NAME="How_can_I_tell_whether_mod_perl_">How can I tell whether mod_perl is running</A></H1></CENTER>
   <P>
  -Another important point is the sharing of memory. If your OS supports this
  -(and most sane systems do), you might save more memory by sharing it
  -between child processes. This is only possible when you preload code at
  -server startup. However during a child process' life, its memory pages
  -becomes unshared and there is no way we can control perl to make it
  -allocate memory so (dynamic) variables land on different memory pages than
  -constants so the copy-on-write effect will hit almost at random. If you are
  -pre-loading many modules you might be able to balance the memory that stays
  -shared against the time for an occasional fork by tuning the <CODE>MaxRequestsperChild</CODE> to a point where you restart before too much becomes unshared. In this case
  -the
  -<CODE>MaxRequestsPerChild</CODE> is very specific to your scenario. You should do some measurements and you
  -might see if this really makes a difference and what a reasonable number
  -might be. Each time a child reaches this upper limit and restarts it should
  -release the unshared copies and the new child will inherit pages that are
  -shared until it scribbles on them.
  +There are a few ways. In older versions of apache ( &lt; 1.3.6 ?) you could check that by running <CODE>httpd -v</CODE>, it no longer works. Now you should use <CODE>httpd -l</CODE>. Please notice that it is not enough to have it installed - you should of
  +course configure it for mod_perl and restart the server.
   
   <P>
  -It is very important to understand that your goal is not to have
  -<CODE>MaxRequestsperChild</CODE> to be 10000. Having a child serve 300 requests on precompiled code is
  -already a huge speedup, so if it is 100 or 10000 it does not really matter
  -if it saves you the RAM by sharing. Do not forget that if you preload most
  -of your code at the server startup, the fork to spawn a new child will be
  -very very fast, because it inherits most of the preloaded code and the perl
  -interpreter from the parent process. But then during the work of the child,
  -its memory pages (which aren't really its yet, it uses the parent's pages)
  -are getting dirty (originally inherited and shared variables are getting
  -updated) and the copy-on-write happens, which reduce the sharing number of
  -memory pages - thus enlarging the memory usage. Killing the child and
  -spawning a new one allows to get the pristine shared memory from the parent
  -process again.
  -
  +<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<CENTER><H2><A NAME="Testing_by_checking_the_error_lo">Testing by checking the error_log file</A></H2></CENTER>
   <P>
  -The conclusion is that <CODE>MaxRequestsperChild</CODE> should not be too big, otherwise you loose the benefits of the memory
  -sharing.
  +When starting the server, just check the <CODE>error_log</CODE> file for the following message:
   
   <P>
  -See <A HREF="././performance.html#Choosing_MaxRequestsPerChild">Choosing MaxRequestsPerChild</A> for more about tuning the <CODE>MaxRequestsperChild</CODE> parameter.
  -
  +<PRE>  [Thu Dec  3 17:27:52 1998] [notice] Apache/1.3.1 (Unix) mod_perl/1.15 configured 
  +                                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  +    -- resuming normal operations
  +</PRE>
   <P>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<CENTER><H1><A NAME="Avoid_Importing_Functions">Avoid Importing Functions</A></H1></CENTER>
  +<CENTER><H2><A NAME="Testing_by_viewing_perl_status">Testing by viewing /perl-status</A></H2></CENTER>
   <P>
  -When possible, avoid importing a module's functions into your name space.
  -The aliases which are created can take up quite a bit of space. Try to use
  -method interfaces and fully qualified
  -<CODE>Package::function</CODE> or <CODE>$Package::variable</CODE> like names instead.
  +Assuming that you have configured the <CODE>&lt;Location /perl-status</CODE>&gt; section in the server configuration file fetch: <A
  +HREF="http://www.nowhere.com/perl-status">http://www.nowhere.com/perl-status</A>
  +using your favorite Netscape browser :-)
   
  -<P>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<CENTER><H1><A NAME="How_can_I_find_if_my_modperl_scr">How can I find if my modperl scripts have memory leaks (and where)</A></H1></CENTER>
   <P>
  -<CODE>Apache::Leak</CODE> (derived from <CODE>Devel::Leak</CODE>) should help you with this task. Example:
  +You should see something like this:
   
   <P>
  -<PRE>  use Apache::Leak;
  -  
  -  my $global = &quot;FooAAA&quot;;
  -  
  -  leak_test {
  -    $$global = 1;
  -    ++$global;
  -  };
  +<PRE>  Embedded Perl version 5.00502 for Apache/1.3.1 (Unix) mod_perl/1.19 
  +  process 50880, running since Tue Oct 6 14:31:45 1998
   </PRE>
   <P>
  -The argument to <CODE>leak_test()</CODE> is an anonymous sub, so you can just throw it around any code you suspect
  -might be leaking. beware, it will run the code twice, because the first
  -time in, new <CODE>SV</CODE>s are created, but does not mean you are leaking, the second pass will give
  -better evidence. you do not need to be inside mod_perl to use it, from the
  -command line, the above script outputs:
  +<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<CENTER><H2><A NAME="Testing_via_telnet">Testing via telnet</A></H2></CENTER>
  +<P>
  +Knowing the port you have configured apache to listen on, you can use
  +<CODE>telnet</CODE> to talk directly to it.
   
   <P>
  -<PRE>  ENTER: 1482 SVs
  -  new c28b8 : new c2918 : 
  -  LEAVE: 1484 SVs
  -  ENTER: 1484 SVs
  -  new db690 : new db6a8 : 
  -  LEAVE: 1486 SVs
  -  !!! 2 SVs leaked !!!
  +Assuming that your mod_perl enabled server listens to port 8080, telnet to
  +your server at port 8080, and type <CODE>HEAD / HTTP/1.0</CODE> then press the &lt;ENTER&gt; key TWICE:
  +
  +<P>
  +<PRE>  % telnet localhost 8080&lt;ENTER&gt;
  +  HEAD / HTTP/1.0&lt;ENTER&gt;&lt;ENTER&gt;
   </PRE>
   <P>
  -Build a debuggable perl to see dumps of the <CODE>SV</CODE>s. the simple way to have both a normal perl and debuggable perl, is to
  -follow hints in the
  -<CODE>SUPPORT</CODE> doc for building <CODE>libperld.a</CODE>, when that is built copy the
  -<CODE>perl</CODE> from that directory to your perl bin directory, but name it
  -<CODE>dperl</CODE>.
  +You should see a response like this:
   
   <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>
  +<PRE>  HTTP/1.1 200 OK
  +  Date: Tue, 01 Dec 1998 12:27:52 GMT
  +  Server: Apache/1.3.6 (Unix) mod_perl/1.19
  +  Connection: close
  +  Content-Type: text/html
  +  
  +  Connection closed.
  +</PRE>
   <P>
  -<CODE>Apache::SizeLimit</CODE> allows you to kill off Apache httpd processes if they grow too large. see
  -perldoc <CODE>Apache::SizeLimit</CODE> for more details.
  +The line: <CODE>Server: Apache/1.3.6 (Unix) mod_perl/1.19</CODE> --confirms that you <STRONG>do</STRONG> have mod_perl installed and its version is <CODE>1.19</CODE>. Of course in your case it would be the version you have installed.
   
   <P>
  -By using this module, you should be able to discontinue using the Apache
  -configuration directive <CODE>MaxRequestsPerChild</CODE>, although for some folks, using both in combination does the job.
  +However, just because you have got mod_perl linked in there, that does not
  +mean that you have configured your server to handle Perl scripts with
  +mod_perl. You will find the configuration assistance at
  +<A HREF="././config.html#">ModPerlConfiguration</A>
  +
  +
   
   <P>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<CENTER><H1><A NAME="Limiting_the_resources_used_by_h">Limiting the resources used by httpd children</A></H1></CENTER>
  +<CENTER><H2><A NAME="Testing_via_a_CGI_script">Testing via a CGI script</A></H2></CENTER>
   <P>
  -<CODE>Apache::Resource</CODE> uses the <CODE>BSD::Resource</CODE> module, which uses the C function <CODE>setrlimit</CODE> to set limits on system resources such as memory and cpu usage.
  +Another method is to invoke a CGI script which dumps the server's
  +environment.
   
   <P>
  -To configure use:
  +Copy and paste the script below (no need for the first perl calling
  +(shebang) line!). Let's say you named it <CODE>test.pl</CODE>, saved it at the root of the CGI scripts and CGI root is mapped directly
  +to the
  +<CODE>/perl</CODE> location of your server.
   
   <P>
  -<PRE>  PerlModule Apache::Resource
  -    # set child memory limit in megabytes
  -    # (default is 64 Meg)
  -  PerlSetEnv PERL_RLIMIT_DATA 32:48
  -  
  -    # set child cpu limit in seconds
  -    # (default is 360 seconds)
  -  PerlSetEnv PERL_RLIMIT_CPU 120
  -  
  -  PerlChildInitHandler Apache::Resource
  +<PRE>  print &quot;Content-type: text/html\n\n&quot;;
  +  print &quot;Server's environment&lt;P&gt;\n&quot;;
  +  print &quot;&lt;TABLE&gt;&quot;;
  +  foreach ( keys %ENV ) {
  +      print &quot;&lt;TR&gt;&lt;TD&gt;$_ &lt;/TD&gt;&lt;TD&gt;$ENV{$_}&lt;/TR&gt;&lt;/TD&gt;&quot;;
  +  }
  +  print &quot;&lt;/TABLE&gt;&quot;;
   </PRE>
   <P>
  -The following limit values are in megabytes: <CODE>DATA</CODE>, <CODE>RSS</CODE>,
  -<CODE>STACK</CODE>, <CODE>FSIZE</CODE>, <CODE>CORE</CODE>, <CODE>MEMLOCK</CODE>; all others are treated as their natural unit. Prepend <CODE>PERL_RLIMIT_</CODE> for each one you want to use. Refer to <CODE>setrlimit</CODE> man page on your OS for other possible resources.
  +Make it readable and executable by server:
   
   <P>
  -If the value of the variable is of the form <CODE>S:H</CODE>, <CODE>S</CODE> is treated as the soft limit, and <CODE>H</CODE> is the hard limit. If it is just a single number, it is used for both soft
  -and hard limits.
  +<PRE>  % chmod a+rx test.pl
  +</PRE>
  +<P>
  +(you will want to tune permissions on the public host).
   
   <P>
  -To debug add:
  +Now fetch the URL <CODE>http://www.nowhere.com:8080/perl/test.pl</CODE> (replace 8080 with the port your mod_perl enabled server is listening to.
  +You should see something like this (the generated output was trimmed):
   
   <P>
  -<PRE>  &lt;Perl&gt;
  -    $Apache::Resource::Debug = 1;
  -    require Apache::Resource;
  -  &lt;/Perl&gt;
  -  PerlChildInitHandler Apache::Resource
  +<PRE>  SERVER_SOFTWARE    Apache/1.3.6 (Unix) mod_perl/1.19
  +  GATEWAY_INTERFACE  CGI-Perl/1.1
  +  REQUEST_METHOD     GET
  +  HTTP_ACCEPT        image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, */*
  +  MOD_PERL           1.19
  +  REQUEST_URI        /perl/test.pl
  +  SCRIPT_NAME        /perl/test.pl
  +  [...snipped]
   </PRE>
   <P>
  -and look in the error_log to see what it's doing.
  +Now if I run the same script in mod_cgi mode (configured with
  +<CODE>/cgi-bin</CODE> Alias) (you will need to add the perl invocation line
  +<CODE>#!/bin/perl</CODE> for the above script) and fetch
  +<CODE>http://www.nowhere.com/cgi-bin/test.pl</CODE>.
   
   <P>
  -Refer to <CODE>perldoc Apache::Resource</CODE> and <CODE>man 2 setrlimit</CODE> for more info.
  +<PRE>  SERVER_SOFTWARE   Apache/1.3.6 (Unix)
  +  GATEWAY_INTERFACE CGI/1.1
  +  [...snipped]
  +</PRE>
  +<P>
  +You will see that two variables, <CODE>SERVER_SOFTWARE</CODE> and
  +<CODE>GATEWAY_INTERFACE</CODE>, are different from the case above. This gives you a hint of how to tell
  +in what mode you are running in your cgi scripts. I start all my cgi
  +scripts that are mod_perl aware with:
  +
  +<P>
  +<PRE>  BEGIN {
  +      # Auto-detect if we are running under mod_perl or CGI.
  +    $USE_MOD_PERL = ((exists $ENV{'GATEWAY_INTERFACE'}
  +                  and $ENV{'GATEWAY_INTERFACE'} =~ /CGI-Perl/)
  +                   or exists $ENV{'MOD_PERL'} );
  +      # perl5.004 is a must under mod_perl
  +    require 5.004 if $USE_MOD_PERL;
  +  }
  +</PRE>
  +<P>
  +You might wonder why in the world you would need to know in what mode you
  +are running. For example you will want to use <CODE>Apache::exit()</CODE>
  +and not <CODE>CORE::exit()</CODE> in your modules, but if you think that your script might be used in both
  +environments (mod_cgi vs. mod_perl), you will have to override the <CODE>exit()</CODE> subroutine and to make the runtime decision of what method you will use.
  +Not that if you run scripts under <CODE>Apache::Registry</CODE> handler, it takes care of overriding the
  +<CODE>exit()</CODE> call for you, so it's not an issue if this is your case. For reasons and
  +implementations see: <A HREF="././porting.html#Using_exit_">Using exit()</A> and the whole <A HREF="././porting.html#">Writing Mod Perl scripts and Porting plain CGIs to it</A> page.
   
   <P>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<CENTER><H1><A NAME="Limiting_the_request_rate_speed_">Limiting the request rate speed (robots blocking)</A></H1></CENTER>
  +<CENTER><H2><A NAME="Testing_via_lwp_request">Testing via lwp-request</A></H2></CENTER>
   <P>
  -A limitation of using pattern matching to identify robots is that it only
  -catches the robots that you know about, and only those that identify
  -themselves by name. A few devious robots masquerade as users by using user
  -agent strings that identify themselves as conventional browsers. To catch
  -such robots, you'll have to be more sophisticated.
  +Yet another one. Why do I show all these approaches? While here they are
  +serving a very simple purpose, they can be helpful in other situations.
   
  +<P>
  +Assuming you have the <CODE>libwww-perl</CODE> (<CODE>LWP</CODE>) package installed (you will need it installed in order to pass mod_perl's <CODE>make test</CODE> anyway):
  +
  +<P>
  +<PRE>  % lwp-request -e -d <A HREF="http://www.nowhere.com">http://www.nowhere.com</A>
  +</PRE>
   <P>
  -<CODE>Apache::SpeedLimit</CODE> comes for you to help, see:
  +Will show you all the headers. (The <CODE>-d</CODE> option disables printing the response content.)
   
   <P>
  -<A
  -HREF="http://www.modperl.com/chapters/ch6.html#Blocking_Greedy_Clients">http://www.modperl.com/chapters/ch6.html#Blocking_Greedy_Clients</A>
  +<PRE>  % lwp-request -e -d <A HREF="http://www.nowhere.com">http://www.nowhere.com</A> | egrep '^Server:'
  +</PRE>
  +<P>
  +To see the server's version only.
   
  +<P>
  +Use <CODE>http://www.nowhere.com:port_number</CODE> if your server is listening to a non-default 80 port.
   
   <P>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<CENTER><H1><A NAME="Benchmarks_Impressing_your_Boss">Benchmarks. Impressing your Boss and Colleagues.</A></H1></CENTER>
  +<CENTER><H1><A NAME="Is_it_possible_to_install_and_us">Is it possible to install and use apache/mod_perl without having a root access?</A></H1></CENTER>
  +<P>
  +Yes, no problem with that. Follow the installation instructions and when
  +you encounter <CODE>APACI_ARGS</CODE> use your home directory (or some other directory which you have write
  +access to) as a prefix, (e.g. <CODE>/home/stas/www</CODE>), and everything will be installed there. There is a chance that some perl
  +libs will be not installed on your server by root and you will have to
  +install these locally too. See the <A
  +HREF="http://www.singlesheaven.com/stas/TULARC/webmaster/myfaq.html#7">http://www.singlesheaven.com/stas/TULARC/webmaster/myfaq.html#7</A>
  +for more information on local perl installations.
  +
   <P>
  -How much faster is mod_perl that CGI? There are many ways to benchmark the
  -two. See a few examples and numbers below, also checkout the benchmark/
  -directory of mod_perl dist for more examples.
  +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
  +access URLs to CGI scripts, but rather are directed to them from a link on
  +a web page or as the '<CODE>ACTION</CODE>' of a HTML form, so they should not know at all that the port is different
  +from the default port 80.
   
   <P>
  -If you write a benchmark for your own, use <CODE>Benchmark</CODE> for heavy scripts or use <CODE>Time::HiRes</CODE> for very fast scripts where you need better precision.
  +If you want your apache server to start automatically on system reboot, you
  +will need to invoke the server startup script from somewhere within the
  +init scripts on your host. This is often somewhere under <CODE>/etc/rc.d</CODE>, but this path can vary depending upon the flavor of Unix you are using.
   
   <P>
  -There is no need to write a special benchmark though. If you want to
  -impress your boss or colleagues, just take the heaviest cgi script you
  -have, open 2 xterms and call the same script in mod_perl mode in one xterm
  -and in mod_cgi mode in the other. You can use lwp-get from
  -<CODE>LWP</CODE> package to emulate the web agent (browser). (benchmark/ directory of
  -mod_perl dist includes such an example)
  +One more important thing to keep in mind is system resources. mod_perl is
  +memory hungry -- if you run a lot of mod_perl processes on a public,
  +multiuser (not dedicated) machine -- most likely the system administrator
  +of the host will ask you to use less resources and even to shut down your
  +mod_perl server and to find another home for it. You have a few solutions:
   
  +<UL>
  +<P><LI>
   <P>
  -See also 2 tools for benchmarking:
  -<A HREF="././performance.html#Tuning_with_ab_ApacheBench">ApacheBench</A> and <A HREF="././performance.html#Tuning_with_crashme_script">crashme test</A>
  +Reduce resources usage (see <A HREF="././performance.html#Limiting_the_size_of_the_process">Limiting the size of the processes</A>).
   
  +<P><LI>
  +<P>
  +Ask your ISP if you can put a dedicated machine into their computer room
  +and be root there.
   
  +<P><LI>
  +<P>
  +Look for another ISP with lots of resources or one that supports mod_perl.
  +You can find a list of these ISP at <A
  +HREF="http://perl.apache.org">http://perl.apache.org</A> .
   
  +</UL>
   <P>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<CENTER><H2><A NAME="Developers_Talk">Developers Talk</A></H2></CENTER>
  +<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>
  -Perrin Harkins writes on benchmarks or comparisons, official or unofficial:
  -
  -<BLOCKQUOTE>
  +It is possible to determine which options were given to modperl's
  +<CODE>Makefile.PL</CODE> during the configuration stage, so to be used later in recreating the same
  +build tree when rebuilding the server. This is relevant only if you did not
  +use the default config parameters and altered some of them during the
  +configuration stage.
   
   <P>
  -I have used some of the platforms you mentioned and researched others. What
  -I can tell you for sure, is that no commercially available system offers
  -the depth, power, and ease of use that mod_perl has. Either they don't let
  -you access the web server internals, or they make you use less productive
  -languages than Perl, sometimes forcing you into restrictive and confusing
  -APIs and/or GUI development environments. None of them offer the level of
  -support available from simply posting a message to this list, at any price.
  +I was into this problem many times. I am going to build something by
  +passing some non-default parameters to the config script and then later
  +when I need to rebuild the tool either to upgrade it or to make an
  +identical copy at another machine, I would find that I do not remember what
  +parameters I altered.
   
   <P>
  -As for performance, beyond doing several important things (code-caching,
  -pre-forking/threading, and persistent database connections) there isn't
  -much these tools can do, and it's mostly in your hands as the developer to
  -see that the things which really take the time (like database queries) are
  -optimized.
  +The best solution for this problem is to prepare the run file with all the
  +parameters that are about to be used and then run it instead of typing it
  +all by hand. So later I will have the script handy to be reused.
   
   <P>
  -The downside of all this is that most manager types seem to be unable to
  -believe that web development software available for free could be better
  -than the stuff that cost $25,000 per CPU. This appears to be the major
  -reason most of the web tools companies are still in business. They send a
  -bunch of suits to give PowerPoint presentations and hand out glossy
  -literature to your boss, and you end up with an expensive disaster and an
  -approaching deadline.
  +mod_perl suggests using the <CODE>makepl_args.mod_perl</CODE> file which comes with mod_perl distribution. This is the file where you
  +should specify all the parameters you are going to use.
   
   <P>
  -But I'm not bitter or anything...
  -
  -</BLOCKQUOTE>
  +But if you have found yourself with a compiled tool and no traces of the
  +specified parameters left, usually you can still find them out, if the
  +sources were not <CODE>make clean</CODE>'d. You will find the apache specific parameters in <CODE>apache_x.x.x/config.status</CODE> and modperl's at in <CODE>mod_perl_x.xx/apaci/mod_perl.config</CODE>.
   
   <P>
  -Jonathan Peterson adds:
  -
  -<BLOCKQUOTE>
  -
  +<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<CENTER><H1><A NAME="Server_Installation_problems">Server Installation problems</A></H1></CENTER>
   <P>
  -Most of the major solutions have something that they do better than the
  -others, and each of them has faults. Microsoft's ASP has a very nice
  -objects model, and has IMO the best data access object (better than DBI to
  -use - but less portable) It has the worst scripting language. PHP has many
  -of the advantages of Perl-based solutions, but is less complicated for
  -developers. Netscape's Livewire has a good object model too, and provides
  -good server-side Java integration - if you want to leverage Java skills,
  -it's good. Also, it has a compiled scripting language - which is great if
  -you aren't selling your clients the source code (and a pain otherwise).
  -
  +<P><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>
  -mod_perl's advantage is that it is the most powerful. It offers the
  -greatest degree of control with one of the more powerful languages. It also
  -offers the greatest granularity. You can use an embedding module (eg eperl)
  -from one place, a session module (Session) from another, and your data
  -access module from yet another.
  +There are two configuration parameters: <CODE>PREP_HTTPD</CODE> and <CODE>DO_HTTPD</CODE>, that you can use in:
   
   <P>
  -I think the <CODE>Apache::ASP</CODE> module looks very promising. It has very easy to use and adequately
  -powerful state maintenance, a good embedding system, and a sensible object
  -model (that emulates the Microsoft ASP one). It doesn't replicate MS's ADO
  -for data access, but
  -<CODE>DBI</CODE> is fine for that.
  +<PRE>  perl Makefile.PL [options]
  +</PRE>
  +<P>
  +<CODE>DO_HTTPD=1</CODE> means default to '<CODE>y</CODE>' for the two apache's
  +<CODE>configure</CODE> utility prompts: (a) 'which source tree to configure against' and (b)
  +'whether to build the httpd in that tree'. <CODE>PREP_HTTPD=1</CODE> just means default '<CODE>n</CODE>' to the second prompt -- meaning, <EM>do not build httpd (make) in the
  +apache source tree</EM>. In other words if you use <CODE>PREP_HTTPD=1</CODE> the httpd will be not build. It will be build only if you use
  +<CODE>DO_HTTPD=1</CODE> option and not use <CODE>PREP_HTTPD=1</CODE>.
   
   <P>
  -I have always found that the developers available make the greatest impact
  -on the decision. If you have a team with no Perl experience, and a small or
  -medium task, using something like PHP, or Microsoft ASP, makes more sense
  -than driving your staff into the vertical learning curve they'll need to
  -use mod_perl.
  +If you did not build the httpd, chdir to the apache source, and execute:
   
   <P>
  -For very large jobs, it may be worth finding the best technical solution,
  -and then recruiting the team with the necessary skills.
  +<PRE>  make
  +</PRE>
  +<P>
  +Then return to the mod_perl source and run:
   
  -</BLOCKQUOTE>
  +<P>
  +<PRE>  make test
  +  make install
  +</PRE>
  +<P>
  +Note that you would have to do the same if you do not pass
  +<CODE>APACHE_PREFIX=/path_to_installation_prefix</CODE> during the <CODE>perl
  +Makefile.PL [options]</CODE> stage.
   
   <P>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<CENTER><H2><A NAME="Benchmarking_a_Graphic_hits_coun">Benchmarking a Graphic hits counter with Persistent DB Connection</A></H2></CENTER>
  +<CENTER><H2><A NAME="mod_perl_c_is_incompatible_with_">mod_perl.c is incompatible with this version of apache</A></H2></CENTER>
   <P>
  -Here are the numbers from Michael Parker's mod_perl presentation at Perl
  -Conference (Aug, 98) <A
  -HREF="http://www.realtime.net/~parkerm/perl/conf98/index.htm">http://www.realtime.net/~parkerm/perl/conf98/index.htm</A>
  -. The script is a standard hits counter, but it logs the counts into the
  -mysql relational DataBase:
  +You will see this message when you try to run a httpd, if you have had a
  +stale old apache header layout in one of the <CODE>include</CODE> paths during the build process. Do run <CODE>find</CODE> (or <CODE>locate</CODE>) utility in order to locate <CODE>ap_mmn.h</CODE> file. In my case I have had a
  +<CODE>/usr/local/include/ap_mmn.h</CODE> which was installed by RedHat install process. If this is the case get rid
  +of it, and rebuild it again.
   
   <P>
  -<PRE>    Benchmark: timing 100 iterations of cgi, perl...  [rate 1:28]
  -    
  -    cgi: 56 secs ( 0.33 usr 0.28 sys = 0.61 cpu) 
  -    perl: 2 secs ( 0.31 usr 0.27 sys = 0.58 cpu) 
  -    
  -    Benchmark: timing 1000 iterations of cgi,perl...  [rate 1:21]
  -     
  -    cgi: 567 secs ( 3.27 usr 2.83 sys = 6.10 cpu) 
  -    perl: 26 secs ( 3.11 usr 2.53 sys = 5.64 cpu)      
  -    
  -    Benchmark: timing 10000 iterations of cgi, perl   [rate 1:21]
  -     
  -    cgi: 6494 secs (34.87 usr 26.68 sys = 61.55 cpu) 
  -    perl: 299 secs (32.51 usr 23.98 sys = 56.49 cpu) 
  -</PRE>
  -<P>
  -We don't know what server configurations was used for these tests, but I
  -guess the numbers speak for themselves.
  +For all RH fans, before you are going to build the apache by yourself, do:
   
   <P>
  -The source code of the script is available at <A
  -HREF="http://www.realtime.net/~parkerm/perl/conf98/sld006.htm">http://www.realtime.net/~parkerm/perl/conf98/sld006.htm</A>
  -.
  +<PRE>  rpm -e apache
  +</PRE>
  +<P>
  +to remove the pre-installed package first!
   
   <P>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<CENTER><H2><A NAME="Benchmarking_scripts_with_execut">Benchmarking scripts with execution times below 1 second :)</A></H2></CENTER>
  +<CENTER><H2><A NAME="Should_I_rebuild_mod_perl_if_I_h">Should I rebuild mod_perl if I have upgraded my perl?</A></H2></CENTER>
   <P>
  -As noted before, for very fast scripts you will have to use the Time::HiRes
  -module, its usage is similar to the Benchmark's.
  +Yes, you should. You have to rebuild mod_perl enabled server since it has a
  +hard coded <CODE>@INC</CODE> which points to the old perl and it is is probably linked to the an old <CODE>libperl</CODE> library. You can try to modify the <CODE>@INC</CODE> in the startup script (if you keep the old perl version around), but it is
  +better to build a fresh one to save you a mess.
   
   <P>
  -<PRE>  use Time::HiRes qw(gettimeofday tv_interval);
  -  my $start_time = [ gettimeofday ];
  -  &amp;sub_that_takes_a_teeny_bit_of_time()
  -  my $end_time = [ gettimeofday ];
  -  my $elapsed = tv_interval($start_time,$end_time);
  -  print &quot;the sub took $elapsed secs.&quot;
  -</PRE>
  +<P><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>
  -See also <A HREF="././performance.html#Tuning_with_crashme_script">crashme test</A>.
  +Since most of the functionality that various apache mod_* modules provide
  +is being implemented in <CODE>Apache::{*}</CODE> perl modules, it was reported that one can build an apache server with
  +mod_perl only. If you can reduce the problems down to whatever mod_perl can
  +handle, you can eliminate nearly every other module. Then basically you
  +will have a perl-server, with C code to handle the tricky HTTP bits. The
  +only module you will need to leave in is a <CODE>mod_actions</CODE>.
  +
  +<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +	     The <a href="http://www.modperl.com/">
  +	     <B>Writing Apache Modules with Perl and C</B></a>
  +	     book can be purchased online from <a
  +	     href="http://www.ora.com/catalog/wrapmod/">O'Reilly </a>
  +	     and <a
  +	     href="http://www.amazon.com/exec/obidos/ASIN/156592567X/writinapachemodu">
  +	     Amazon.com</a>.
  +
  +	     <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%" >
  +<TR ALIGN=CENTER VALIGN=TOP>
  +  <TD ALIGN=CENTER VALIGN=CENTER COLSPAN="3">
  +	     <HR>
  +  </TD>
  +</TR>
  +<TR ALIGN=CENTER VALIGN=TOP>
  +  <TD ALIGN=CENTER VALIGN=CENTER>
  +    <B>
  +      <FONT SIZE=-1>
  +	     Written by <A HREF="help.html#This_document_s_Author">Stas Bekman</A>.
  +	     <BR>Last Modified at 07/02/1999
  +      </FONT>
  +    </B>
  +  </TD>
  +
  +  <TD>
  +	     <A HREF="http://perl.apache.org"><IMG SRC="images/mod_perl2.jpg" ALT="Mod Perl Icon" BORDER=0 HEIGHT=59 WIDTH=150></A>
  +  </TD>
  +
  +  <TD>
  +    <FONT SIZE=-2>
  +	     Use of the Camel for Perl is <BR>
  +	     a trademark of <A HREF="http://www.ora.com">O'Reilly &amp; Associates</A>,<BR>
  +             and is used by permission. 
  +    </FONT> 
  +  </TD>
  +</TR>
  +</TABLE></CENTER>
  +
  +</BODY>
  +</HTML>
  +	    
  +
  +<HR SIZE=6>
  +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
  +<HTML>
  +<HEAD>
  +   <TITLE>mod_perl guide: Server Configuration</TITLE>
  +   <META NAME="GENERATOR" CONTENT="Pod2HTML [Perl/Linux]">
  +   <META NAME="Author" CONTENT="Stas Bekman">
  +   <META NAME="Description" CONTENT="All Apache/Perl related information: Hints, Guidelines, Scenarios and Troubleshottings">
  +   <META NAME="keywords" CONTENT="mod_perl modperl perl apache cgi webserver speed  fast guide mod_perl apache guide help info faq mod_perl installation cgi troubleshooting help no sex speedup free open source OSS mod_perl apache guide">
  +</HEAD>
  +     <LINK REL=STYLESHEET TYPE="text/css"
  +        HREF="style.css" TITLE="refstyle">
  +     <style type="text/css">
  +     <!-- 
  +        @import url(style.css);
  +     -->
  +     
  +     </style>
  +<BODY TEXT="#000000" BGCOLOR="#E0FFFF" LINK="#0000EE" VLINK="#551A8B" ALINK="#FF0000">
  +<A NAME="toc"></A>
  +<H1 ALIGN=CENTER>
  +<A HREF="http://perl.apache.org"><IMG SRC="images/mod_perl.gif" ALT="Mod Perl Icon" BORDER=0 HEIGHT=30 WIDTH=90 ALIGN=LEFT></A>
  +<A HREF="http://perl.apache.org"><IMG SRC="images/mod_perl.gif" ALT="Mod Perl Icon" BORDER=0 HEIGHT=30 WIDTH=90 ALIGN=RIGHT></A>
  +Server Configuration</H1>
  +<HR WIDTH="100%">
  +	    [    <A HREF="install.html">Prev</A> |      <A HREF="index.html">Main Page</A> | <A HREF="frequent.html">Next</A>      ]<HR><!-- INDEX BEGIN -->
  +<P><B><FONT SIZE=-1>Table of Contents:</FONT></B></P>
  +<UL>
  +
  +	<LI><A HREF="#mod_perl_Specific_Configuration">mod_perl Specific Configuration</A>
  +	<UL>
  +
  +		<LI><A HREF="#Alias_Configurations">Alias Configurations</A>
  +		<LI><A HREF="#Location_Configuration">Location Configuration</A>
  +		<LI><A HREF="#PerlFreshRestart">PerlFreshRestart</A>
  +		<LI><A HREF="#_perl_status_location">/perl-status location</A>
  +		<UL>
  +
  +			<LI><A HREF="#Configuration">Configuration</A>
  +			<LI><A HREF="#Usage">Usage</A>
  +			<LI><A HREF="#Compiled_Registry_Scripts_sectio">Compiled Registry Scripts section seems to be empty.</A>
  +		</UL>
  +
  +		<LI><A HREF="#PerlSetVar_PerlSetEnv_and_PerlP">PerlSetVar, PerlSetEnv and PerlPassEnv</A>
  +		<LI><A HREF="#perl_startup_file">perl-startup file</A>
  +		<UL>
   
  -<P>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<CENTER><H2><A NAME="PerlHandler_s_Benchmarking">PerlHandler's Benchmarking</A></H2></CENTER>
  -<P>
  -At <A
  -HREF="http://perl.apache.org/dist/contrib/">http://perl.apache.org/dist/contrib/</A>
  -you will find
  -<CODE>Apache::Timeit</CODE> package which does PerlHandler's Benchmarking.
  +			<LI><A HREF="#Sample_perl_startup_file">Sample perl-startup file</A>
  +			<LI><A HREF="#What_modules_should_you_add_to_t">What modules should you add to the startup file and why.</A>
  +			<LI><A HREF="#The_confusion_with_use_clause_">The confusion with use() clause at the server startup?</A>
  +			<LI><A HREF="#The_confusion_with_defining_glob">The confusion with defining globals in startup</A>
  +		</UL>
   
  -<P>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<CENTER><H1><A NAME="Tuning_the_Apache_s_configuratio">Tuning the Apache's configuration variables for the best performance</A></H1></CENTER>
  -<P>
  -It's very important to make a correct configuration of the
  -<CODE>MinSpareServers</CODE>, <CODE>MaxSpareServers</CODE>, <CODE>StartServers</CODE>,
  -<CODE>MaxClients</CODE>, and <CODE>MaxRequestsPerChild</CODE> parameters. There are no defaults, the values of these variable are very
  -important, as if too ``low'' you will not use the system for its full
  -ability, and if too ``high'' chances your server will bring the machine to
  -its knees.
  +	</UL>
   
  -<P>
  -All the above parameters should be specified on the basis of the resources
  -you have. While with a plain apache server, there is no big deal if you run
  -too many servers (not too many of course) since the processes are of ~1Mb
  -and aren't eating a lot of your RAM. The situation is different with
  -mod_perl. I have seen mod_perl processes of 20Mb and more. Now if you have <CODE>MaxClients</CODE> set to 50: 50x20Mb = 1Gb - do you have 1Gb of RAM? Probably not. So how do
  -you tune these numbers? Generally by trying different combinations and
  -testing the server.
  +	<LI><A HREF="#Running_apachectl_configtest_o">Running 'apachectl configtest' or 'httpd -t'</A>
  +	<LI><A HREF="#Perl_behavior_controls">Perl behavior controls</A>
  +	<LI><A HREF="#Tuning_MinSpareServers_MaxSpareS">Tuning MinSpareServers MaxSpareServers StartServers MaxClients</A>
  +	<LI><A HREF="#Publishing_port_numbers_differen">Publishing port numbers different from 80</A>
  +	<LI><A HREF="#Perl_Sections">Perl Sections</A>
  +	<LI><A HREF="#Configuring_Apache_mod_perl_wi">Configuring Apache + mod_perl with mod_macro</A>
  +	<LI><A HREF="#General_pitfalls">General pitfalls</A>
  +	<UL>
   
  -<P>
  -Before you start this task you should be armed with the proper weapon. You
  -need a crashme utility, which will load your server with mod_perl scripts
  -you possess. While there are commercial solutions, you can get away with
  -free ones who do the same job. You can use an
  -<A HREF="././performance.html#Tuning_with_ab_ApacheBench">ApacheBench</A>  <STRONG><CODE>ab</CODE></STRONG> utility that comes with apache distribution, a <A HREF="././performance.html#Tuning_with_crashme_script">crashme script</A> which uses
  -<CODE>LWP::Parallel::UserAgent</CODE> or <CODE>httperf</CODE> (see <A HREF="././download.html#">Download page</A>). You need these to have an ability to emulate a multiuser environment and
  -to emulate multiple clients behaviour which will call the mod_perl scripts
  -at your server simultaneously.
  +		<LI><A HREF="#My_cgi_perl_code_is_being_return">My cgi/perl code is being returned as a plain text instead of being executed by the webserver?</A>
  +		<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="#the_server_no_longer_retrieves_t">the server no longer retrieves the DirectoryIndex files for a directory</A>
  +	</UL>
   
  -<P>
  -Another important issue is to make sure to run testing client (load
  -generator) on a system that is more powerful than the system being tested.
  -After all we are trying to simulate the Internet users, where many users
  -are trying to reach your service at once -- since a number of concurrent
  -users can be quite big, your testing machine much be very powerful and
  -capable to generate a big load. Of course you should not run the clients
  -and server on the same machine. If you do -- your testing results would be
  -incorrect, since clients will eat a CPU and a memory that have to be
  -dedicated to the server, and vice versa.
  +	<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>
  +</UL>
  +<!-- INDEX END -->
   
  -<P>
  -See also 2 tools for benchmarking:
  -<A HREF="././performance.html#Tuning_with_ab_ApacheBench">ApacheBench</A> and <A HREF="././performance.html#Tuning_with_crashme_script">crashme test</A>
  +<HR>
   
  +	     The <a href="http://www.modperl.com/">
  +	     <B>Writing Apache Modules with Perl and C</B></a>
  +	     book can be purchased online from <a
  +	     href="http://www.ora.com/catalog/wrapmod/">O'Reilly </a>
  +	     and <a
  +	     href="http://www.amazon.com/exec/obidos/ASIN/156592567X/writinapachemodu">
  +	     Amazon.com</a>.
   
  +	     <HR>
   
  +	      <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
   <P>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<CENTER><H2><A NAME="Tuning_with_ab_ApacheBench">Tuning with ab - ApacheBench</A></H2></CENTER>
  +<CENTER><H1><A NAME="mod_perl_Specific_Configuration">mod_perl Specific Configuration</A></H1></CENTER>
   <P>
  -<STRONG>ab</STRONG> is a tool for benchmarking your Apache HTTP server. It is designed to give
  -you an impression on how much performance your current Apache installation
  -can give. In particular, it shows you how many requests per secs your
  -Apache server is capable of serving. The
  -<STRONG>ab</STRONG> tool comes bundled with apache source distribution (and it's free :).
  +The next step after building and installing your new mod_perl enabled
  +apache server, is to configure the server. To learn how to modify apache's
  +configuration files, please refer to the documentation included with the
  +apache distribution, or just view the files in
  +<CODE>conf</CODE> directory and follow the instructions in these files - the embedded
  +comments within the file do a good job of explaining the options.
   
   <P>
  -Lets try it. We will simulate 10 users concurrently requesting the script <CODE>www.you.com:81/test/test.pl</CODE> which is a very light one. Each one makes 10 requests.
  +Before you start with mod_perl specific configuration, first configure
  +apache, and see that it works. When done, return here to continue...
   
  -<P>
  -<PRE>  % ./ab -n 100 -c 10 www.you.com:81/test/test.pl
  -  
  -  Concurrency Level:      10
  -  Time taken for tests:   0.715 seconds
  -  Complete requests:      100
  -  Failed requests:        0
  -  Non-2xx responses:      100
  -  Total transferred:      60700 bytes
  -  HTML transferred:       31900 bytes
  -  Requests per second:    139.86
  -  Transfer rate:          84.90 kb/s received
  -  
  -  Connection Times (ms)
  -                min   avg   max
  -  Connect:        0     0     3
  -  Processing:    13    67    71
  -  Total:         13    67    74
  -</PRE>
   <P>
  -The only numbers we are really care about are:
  +[ Note that prior to version 1.3.4, the default apache install used three
  +configuration files -- <STRONG>httpd.conf</STRONG>, <STRONG>srm.conf</STRONG>, and
  +<STRONG>access.conf</STRONG>. The 1.3.4 version began distributing the configuration directives in a
  +single file -- <STRONG>httpd.conf</STRONG>. The remainder of this chapter refers to the location of the configuration
  +directives using their historical location. ]
   
   <P>
  -<PRE>  Complete requests:      100
  -  Failed requests:        0
  -  Requests per second:    139.86
  -</PRE>
  +<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<CENTER><H2><A NAME="Alias_Configurations">Alias Configurations</A></H2></CENTER>
   <P>
  -Let's raise the load of requests to 100 x 10 (10 users each 100 requests)
  +First, you need to specify the locations on a file-system for the scripts
  +to be found.
   
  -<P>
  -<PRE>  % ./ab -n 1000 -c 10 www-pais:81/perl/access/access.cgi
  -  Concurrency Level:      10
  -  Complete requests:      1000
  -  Failed requests:        0
  -  Requests per second:    139.76
  -</PRE>
   <P>
  -As expected nothing changes (Since the situation didn't changed, we have
  -the same 10 concurrent users). Now let's raise the number of concurrent
  -users:
  +Add the following configuration directives:
   
   <P>
  -<PRE>  % ./ab -n 1000 -c 50 www-pais:81/perl/access/access.cgi
  -  Complete requests:      1000
  -  Failed requests:        0
  -  Requests per second:    133.01
  +<PRE>    # for plain cgi-bin:
  +  ScriptAlias /cgi-bin/ /usr/local/myproject/cgi/
  +    
  +    # for Apache::Registry mode
  +  Alias /perl/ /usr/local/myproject/cgi/
  +    
  +    # Apache::PerlRun mode
  +  Alias /cgi-perl/ /usr/local/myproject/cgi/
   </PRE>
   <P>
  -We see that the server is capable of serving 50 concurrent users at an
  -amazing 133 req/sec! Lets find the upper bound. Using <CODE>-n 10000 -c
  -1000</CODE> failed to get results (Broken Pipe?). Using <CODE>-n 10000 -c
  -500</CODE> derived 94.82 req/sec. It went down with the high load.
  +<CODE>Alias</CODE> provides a mapping of URL to file system object under
  +<CODE>mod_perl</CODE>. <CODE>ScriptAlias</CODE> is being used for <CODE>mod_cgi</CODE>.
   
   <P>
  -This test was performed with the following configuration:
  +Alias defines the start of the URL path to the script you are referencing.
  +For example, using the above configuration, fetching
  +<CODE>http://www.nowhere.com/perl/test.pl</CODE>, will cause the server to look for the file <CODE>test.pl</CODE> at <CODE>/usr/local/myproject/cgi</CODE>, and execute it as an <CODE>Apache::Registry</CODE> script if we define <CODE>Apache::Registry</CODE> to be the handler of <CODE>/perl</CODE> location (see below). The URL
  +<CODE>http://www.nowhere.com/perl/test.pl</CODE> will be mapped to
  +<CODE>/usr/local/myproject/cgi/test.pl</CODE>. This means that you can have all your CGIs located at the same place at
  +the file-system, and call the script in any of three modes simply by
  +changing the directory name component of the URL (<CODE>cgi-bin|perl|cgi-perl</CODE>) - is not this neat? (That is the configuration you see above - all three
  +Aliases point to the same directory within your file system, but of course
  +they can be different). If your script does not seem to be working while
  +running under mod_perl, you can easily call the script in straight mod_cgi
  +mode without making any script changes (in most cases), but rather by
  +changing the URL you invoke it by.
   
   <P>
  -<PRE>  MinSpareServers 8
  -  MaxSpareServers 6
  -  StartServers 10
  -  MaxClients 50
  -  MaxRequestsPerChild 1500
  -</PRE>
  -<P>
  -Now let's try this:
  +FYI: for modperl <CODE>ScriptAlias</CODE> is the same thing as:
   
  -<P>
  -<PRE>  MinSpareServers 8
  -  MaxSpareServers 6
  -  StartServers 10
  -  MaxClients 100
  -  MaxRequestsPerChild 1
  -</PRE>
   <P>
  -<PRE>  % ./ab -n 1000 -c 50 www-pais:81/perl/access/access.cgi
  +<PRE>  Alias /foo/ /path/to/foo/
  +  SetHandler cgi-handler
   </PRE>
   <P>
  -The benchmark timed out with the above configuration.... I watched the
  -output of ps as I ran it, the parent process just wasn't capable of
  -respawning the killed children at that rate...When I raised the
  -<CODE>MaxRequestsPerChild</CODE> to 10 I've got 8.34 req/sec - very bad (18 times slower!) (You can't
  -benchmark the importance of the
  -<CODE>MinSpareServers</CODE>, <CODE>MaxSpareServers</CODE> and <CODE>StartServers</CODE> with this kind of test).
  +where <CODE>SetHandler cgi-handler</CODE> invokes mod_cgi. The latter will be overwritten if you enable <CODE>Apache::Registry</CODE>. In other words,
  +<CODE>ScriptAlias</CODE> does not work for mod_perl, it only appears to work when the additional
  +configuration is in there. If the
  +<CODE>Apache::Registry</CODE> configuration came before the <CODE>ScriptAlias</CODE>, scripts would be run under mod_cgi. While handy, <CODE>ScriptAlias</CODE> is a known kludge, always better to use <CODE>Alias</CODE> and <CODE>SetHandler</CODE>.
   
   <P>
  -Now let's try to return <CODE>MaxRequestsPerChild</CODE> to 1500, but to lower the
  -<CODE>MaxClients</CODE> to 10 and run the same test:
  +Of course you can choose any other Alias (you will use it later in
  +<CODE>httpd.conf</CODE>), you can choose to use all three modes or only one of these (It is
  +undesirable to run plain cgi-bin scripts from a mod_perl-enabled server -
  +the price is too high, it is better to run these on plain Apache server.
  +(See <A HREF="././strategy.html#Standalone_mod_perl_Enabled_Apac">Standalone mod_perl Enabled Apache Server</A>)
   
   <P>
  -<PRE>  MinSpareServers 8
  -  MaxSpareServers 6
  -  StartServers 10
  -  MaxClients 10
  -  MaxRequestsPerChild 1500
  -</PRE>
  +<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<CENTER><H2><A NAME="Location_Configuration">Location Configuration</A></H2></CENTER>
   <P>
  -I got 27.12 req/sec, which is better but still 4-5 times slower (133 with <CODE>MaxClients</CODE> of 50)
  +Now we will work with the <CODE>httpd.conf</CODE> file. I add all the mod_perl stuff at the end of the file, after the native
  +apache configurations.
   
   <P>
  -<STRONG>Summary:</STRONG> I have tested a few combinations of server configuration variables (<CODE>MinSpareServers</CODE>  <CODE>MaxSpareServers</CODE>  <CODE>StartServers</CODE>
  -
  -<CODE>MaxClients</CODE>  <CODE>MaxRequestsPerChild</CODE>). And the results we have received are as follows:
  +First we add:
   
   <P>
  -<CODE>MinSpareServers</CODE>, <CODE>MaxSpareServers</CODE> and <CODE>StartServers</CODE> are only important for user response times (sometimes user will have to
  -wait a bit).
  +<PRE>  &lt;Location /perl&gt;
  +    #AllowOverride None
  +    SetHandler perl-script
  +    PerlHandler Apache::Registry
  +    Options ExecCGI
  +    allow from all
  +    PerlSendHeader On
  +  &lt;/Location&gt;
  +</PRE>
  +<P>
  +This configuration causes all scripts that are called with a <CODE>/perl</CODE>
  +path prefix to be executed under the <CODE>Apache::Registry</CODE> module and as a CGI (so the <STRONG>ExecCGI</STRONG>, if you omit this option the script will be printed to the caller's
  +browser as a plain text or possibly will trigger a 'Save-As' window).
   
   <P>
  -The important parameters are <CODE>MaxClients</CODE> and
  -<CODE>MaxRequestsPerChild</CODE>. <CODE>MaxClients</CODE> should be not to big so it will not abuse your machine's memory resources
  -and not too small, when users will be forced to wait for the children to
  -become free to come serve them. <CODE>MaxRequestsPerChild</CODE> should be as big as possible, to take the full benefit of mod_perl, but
  -watch your server at the beginning to make sure your scripts are not
  -leaking memory, thereby causing your server (and your service) to die very
  -fast.
  +<CODE>PerlSendHeader On</CODE> tells the server to send an HTTP header to the browser on every script
  +invocation. You will want to turn this off for nph (non-parsed-headers)
  +scripts. <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.
   
   <P>
  -Also it is important to understand that we didn't test the response times
  -in the tests above, but the ability of the server to respond. If the script
  -that was used to test was heavier, the numbers would be different but the
  -conclusions are very similar.
  +Remember the <STRONG>Alias</STRONG> from the section above? We must use the same
  +<CODE>Alias</CODE> here, if you use <CODE>Location</CODE> that does not have the same
  +<CODE>Alias</CODE> defined in <CODE>srm.conf</CODE>, the server will fail to locate the script in the file system. (We are
  +talking about script execution here -- there are cases where <CODE>Location</CODE> is something that is being executed by the server itself, without having
  +the corresponding file, like <CODE>/perl-status</CODE> location.)
   
   <P>
  -The benchmarks were run with:
  +Note that sometimes you will have to add :
   
   <P>
  -<PRE>  HW: RS6000, 1Gb RAM
  -  SW: AIX 4.1.5 . mod_perl 1.16, apache 1.3.3
  -  Machine running only mysql, httpd docs and mod_perl servers.
  -  Machine was _completely_ unloaded during the benchmarking.
  +<PRE>  PerlModule Apache::Registry
   </PRE>
  -<P>
  -After each server restart when I did changes to the server's
  -configurations, I made sure the scripts were preloaded by fetching a script
  -at least one time by each child.
  -
   <P>
  -It is important to notice that none of requests timed out, even if was kept
  -in server's queue for more than 1 minute! (That is the way <STRONG>ab</STRONG>
  -works, which is OK for the test but will not for the real world - users
  -will not wait for more than 5-10 secs for a request to complete, and the
  -browser will timeout in 30 secs or so.)
  +before you specify the location that uses <CODE>Apache::Registry</CODE> as a
  +<CODE>PerlHandler</CODE>. Basically you can start running the scripts in the
  +<CODE>Apache::Registry</CODE> mode...
   
   <P>
  -Now let's take a look at some real code whose execution time is more than a
  -few msecs. We will do real testing and collect the data in tables for
  -easier viewing.
  +You have nothing to do about <CODE>/cgi-bin</CODE> location (mod_cgi), since it has nothing to do with mod_perl.
   
   <P>
  -I will use the following abbreviations
  +Here is a similar location configuration for <CODE>Apache::PerlRun</CODE> (More about <A HREF="././porting.html#Apache_PerlRun_a_closer_look">Apache::PerlRun</A>):
   
   <P>
  -<PRE>  NR    = Number of Request Total 
  -  NC    = Number of multiple requests to make
  -  MC    = MaxClients
  -  MRPC  = MaxRequestsPerChild
  -  RPS   = Requests per second
  +<PRE>  &lt;Location /cgi-perl&gt;
  +    #AllowOverride None
  +    SetHandler perl-script
  +    PerlHandler Apache::PerlRun
  +    Options ExecCGI
  +    allow from all
  +    PerlSendHeader On
  +  &lt;/Location&gt;
   </PRE>
   <P>
  -Running a mod_perl script with lots of mysql queries (script mysqld
  -bounded) (http://www:81/perl/access/access.cgi?do_sub=query_form)
  -
  +<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>
  -<PRE>  MinSpareServers        8
  -  MaxSpareServers       16
  -  StartServers          10
  -  MaxClients            50
  -  MaxRequestsPerChild 5000
  -</PRE>
  +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:
  +
   <P>
  -<PRE>     NR   NC    RPS     comment
  -  ------------------------------------------------
  -     10   10    3.33    # not a reliable stat
  -    100   10    3.94    
  -   1000   10    4.62    
  -   1000   50    4.09    
  +<PRE>  PerlFreshRestart On
  +Make sure you read L&lt;Evil things might happen when using
  +PerlFreshRestart|warnings/Evil_things_might_happen_when_us&gt;.
   </PRE>
   <P>
  -Conclusions: Here I wanted to show that when the application is slow -- not
  -due to perl loading, script compiling and execution, but bounded to some
  -external operation like mysqld querying which made the bottleneck -- it
  -almost does not matter what load we place on the server. The RPS (Requests
  -per second) is almost the same (given that all the requests have been
  -served, you have an ability to queue the clients, but be aware that
  -something that goes to queue means a waiting client and browser can time
  -out!)
  -
  +<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<CENTER><H2><A NAME="_perl_status_location">/perl-status location</A></H2></CENTER>
   <P>
  -Now we will benchmark the same script without using the mysql (perl only
  -bounded) (http://www.you.com:81/perl/access/access.cgi)
  +A very useful feature. You can watch what happens to the perl guts of the
  +server. Below you will find the instructions of configuration and usage of
  +this feature
   
  -<P>
  -<PRE>  MinSpareServers        8
  -  MaxSpareServers       16
  -  StartServers          10
  -  MaxClients            50
  -  MaxRequestsPerChild 5000
  -</PRE>
  -<P>
  -<PRE>     NR   NC      RPS   comment
  -  ------------------------------------------------
  -     10   10    26.95   # not a reliable stat
  -    100   10    30.88   
  -   1000   10    29.31
  -   1000   50    28.01
  -   1000  100    29.74
  -  10000  200    24.92
  - 100000  400    24.95
  -</PRE>
   <P>
  -Conclusions: This time the script we executed was pure perl (not bounded to
  -I/O or mysql), so we see that the server serves the requests much faster.
  -You can see the RequestPerSecond (RPS) is almost the same for any load, but
  -goes lower when the number of concurrent clients goes beyond the <CODE>MaxClients</CODE>. With 25 RPS, the client supplying a load of 400 concurrent clients will
  -be served in 16 secs. But to get more realistic and assume the max
  -concurrency of 100, with 30 RPS, the client will be served in 3.5 secs,
  -which is pretty good for a highly loaded server.
  +<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<CENTER><H3><A NAME="Configuration">Configuration</A></H3></CENTER>
  +<P>
  +Add this to <CODE>httpd.conf</CODE>:
   
   <P>
  -Now we will use the server for its full capacity, by keeping all
  -<CODE>MaxClients</CODE> alive all the time and having a big
  -<CODE>MaxRequestsPerChild</CODE>, so no server will be killed during the benchmarking.
  +<PRE>  &lt;Location /perl-status&gt;
  +    SetHandler perl-script
  +    PerlHandler Apache::Status
  +    order deny,allow
  +    #deny from all
  +    #allow from 
  +  &lt;/Location&gt;
  +</PRE>
  +<P>
  +If you are going to use <CODE>Apache::Status</CODE>. It's important to put it as a first module in the start-up file, or in
  +the <CODE>httpd.conf</CODE> (after
  +<CODE>Apache::Registry</CODE>):
   
   <P>
  -<PRE>  MinSpareServers       50
  -  MaxSpareServers       50
  -  StartServers          50
  -  MaxClients            50
  -  MaxRequestsPerChild 5000
  -  
  -     NR   NC      RPS   comment
  -  ------------------------------------------------
  -    100   10    32.05
  -   1000   10    33.14
  -   1000   50    33.17
  -   1000  100    31.72
  -  10000  200    31.60
  +<PRE>  # startup.pl
  +  use Apache::Registry ();
  +  use Apache::Status ();
  +  use Apache::DBI ();
   </PRE>
   <P>
  -Conclusion: In this scenario there is no overhead involving the parent
  -server loading new children, all the servers are available, and the only
  -bottleneck is contention for the CPU.
  +If you don't put <CODE>Apache::Status</CODE> before <CODE>Apache::DBI</CODE> then you don't get <CODE>Apache::DBI</CODE>'s menu entry in status.
   
   <P>
  -Now we will try to change the <CODE>MaxClients</CODE> and to watch the results: Let's reduce MC to 10.
  +<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<CENTER><H3><A NAME="Usage">Usage</A></H3></CENTER>
  +<P>
  +Assuming that your mod_perl server listens to port 81, fetch <A
  +HREF="http://www.nowhere.com:81/perl-status">http://www.nowhere.com:81/perl-status</A>
   
  +
   <P>
  -<PRE>  MinSpareServers        8
  -  MaxSpareServers       10
  -  StartServers          10
  -  MaxClients            10
  -  MaxRequestsPerChild 5000
  -  
  -     NR   NC      RPS   comment
  -  ------------------------------------------------
  -     10   10    23.87   # not a reliable stats
  -    100   10    32.64 
  -   1000   10    32.82
  -   1000   50    30.43
  -   1000  100    25.68
  -   1000  500    26.95
  -   2000  500    32.53
  +<PRE>  Embedded Perl version 5.00502 for Apache/1.3.2 (Unix) mod_perl/1.16 
  +  process 187138, running since Thu Nov 19 09:50:33 1998
   </PRE>
   <P>
  -Conclusions: Very little difference! Almost no change! 10 servers were able
  -to serve almost with the same throughput as 50 servers. Why? My guess it's
  -because of CPU throttling. It seems that 10 servers were serving requests 5
  -times faster than when in the test above we worked with 50 servers. In the
  -case above each child received its CPU time slice 5 times less frequently.
  -So having a big value for
  -<CODE>MaxClients</CODE>, doesn't mean that the performance will be better. You have just seen the
  -numbers!
  +This is the linked menu that you should see:
   
  +<P>
  +<PRE>  Signal Handlers
  +  Enabled mod_perl Hooks
  +  PerlRequire'd Files
  +  Environment
  +  Perl Section Configuration
  +  Loaded Modules
  +  Perl Configuration
  +  ISA Tree
  +  Inheritance Tree
  +  Compiled Registry Scripts
  +  Symbol Table Dump
  +</PRE>
   <P>
  -Now we will start to drastically reduce the MaxRequestsPerClient:
  +Let's follow for example : <STRONG>PerlRequire'd Files</STRONG> -- we see:
   
   <P>
  -<PRE>  MinSpareServers        8
  -  MaxSpareServers       16
  -  StartServers          10
  -  MaxClients            50
  -  
  -     NR   NC    MRPC     RPS    comment
  -  ------------------------------------------------
  -    100   10      10    5.77 
  -    100   10       5    3.32
  -   1000   50      20    8.92
  -   1000   50      10    5.47
  -   1000   50       5    2.83
  -   1000  100      10    6.51
  +<PRE>  PerlRequire                          Location
  +  /usr/myproject/lib/apache-startup.pl /usr/myproject/lib/apache-startup.pl
   </PRE>
   <P>
  -Conclusions: When we drastically reduce the <CODE>MaxRequestsPerClient</CODE>, the performance starts to become closer to the plain mod_cgi. Just for
  -comparison with mod_cgi, here are the numbers of this run with mod_cgi:
  +From some menus you can continue deeper to peek at the perl internals of
  +the server, to watch the values of the global variables in the packages, to
  +the list of cached scripts and modules and much more. Just click around...
   
   <P>
  -<PRE>  MinSpareServers        8
  -  MaxSpareServers       16
  -  StartServers          10
  -  MaxClients            50
  -  
  -     NR   NC    RPS     comment
  -  ------------------------------------------------
  -    100   10    1.12
  -   1000   50    1.14
  -   1000  100    1.13
  -</PRE>
  +<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<CENTER><H3><A NAME="Compiled_Registry_Scripts_sectio">Compiled Registry Scripts section seems to be empty.</A></H3></CENTER>
   <P>
  -Conclusion: mod_cgi is much slower :) in test NReq/NClients 100/10 the RPS
  -in mod_cgi 1.12 and in mod_perl 32 =&gt; 30 times faster !!! In the first
  -test each child waited about 100 secs to be served. In the second and third
  -1000 secs!
  +Sometimes when you fetch <CODE>/perl-status</CODE> you and follow the <STRONG>Compiled
  +Registry Scripts</STRONG> link from the status menu -- you see no listing of scripts at all. This is
  +absolutely correct -- <CODE>Apache::Status</CODE> shows the registry scripts compiled in the httpd child which is serving
  +your request for <CODE>/perl-status</CODE>. If a child has not compiled yet the script you are asking for, <CODE>/perl-status</CODE> will just show you the main menu. This usually happens when the child was
  +just spawned.
   
   <P>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<CENTER><H2><A NAME="Tuning_with_crashme_script">Tuning with crashme script</A></H2></CENTER>
  +<CENTER><H2><A NAME="PerlSetVar_PerlSetEnv_and_PerlP">PerlSetVar, PerlSetEnv and PerlPassEnv</A></H2></CENTER>
   <P>
  -This is another crashme suite originally written by Michael Schilli and
  -located at <A
  -HREF="http://www.linux-magazin.de/ausgabe.1998.08/Pounder/pounder.html">http://www.linux-magazin.de/ausgabe.1998.08/Pounder/pounder.html</A>
  -. I did a few modifications (mostly adding <CODE>my()</CODE> ops :). I also
  -allowed it to accept more than one url, since sometimes you want to test an
  -overall and not just one script.
  +<PRE>  PerlSetEnv key val
  +  PerlPassEnv key
  +</PRE>
  +<P>
  +<CODE>PerlPassEnv</CODE> passes, <CODE>PerlSetEnv</CODE> sets and passes the
  +<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>
  -The tool provides the same results as <STRONG>ab</STRONG> above but it also allows you to set the timeout value, so requests will
  -fail if not served within the time out period. You also get Latency
  -(secs/Request) and Throughput (Requests/sec) numbers. It can give you a
  -better picture and make a complete simulation of your favorite Netscape
  -browser :)
  +<CODE>PerlSetVar</CODE> is very similar to <CODE>PerlSetEnv</CODE>, but you extract it with another method. In &lt;Perl&gt; sections:
   
   <P>
  -I have noticed while running these 2 benchmarking suites - <STRONG>ab</STRONG> gave me results 2.5-3.0 times better. Both suites run on the same machine
  -with the same load with the same parameters. Weird ha? Any ideas why? Again
  -C vs Perl question :(
  +<PRE>  push @{ $Location{&quot;/&quot;}-&gt;{PerlSetVar} }, [ 'FOO' =&gt; BAR ];
  +</PRE>
  +<P>
  +and in the code you read it with:
   
  +<P>
  +<PRE>  my $r = Apache-&gt;request;
  +  print $r-&gt;dir_config('FOO');
  +</PRE>
  +<P>
  +<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<CENTER><H2><A NAME="perl_startup_file">perl-startup file</A></H2></CENTER>
   <P>
  -Sample output: 
  +Since many times you have to add many perl directives to the configuration
  +file, it can be a good idea to put all of these into a one file, so the
  +configuration file will be cleaner. Add the following line to <CODE>httpd.conf</CODE>:
   
   <P>
  -<PRE>  URL(s):          <A HREF="http://www.you.com:81/perl/access/access.cgi">http://www.you.com:81/perl/access/access.cgi</A>
  -  Total Requests:  100
  -  Parallel Agents: 10
  -  Succeeded:       100 (100.00%)
  -  Errors:          NONE
  -  Total Time:      9.39 secs
  -  Throughput:      10.65 Requests/sec
  -  Latency:         0.85 secs/Request
  +<PRE>    # startup.perl loads all functions that we want to use within
  +    # mod_perl
  +  Perlrequire /path/to/startup.pl
   </PRE>
   <P>
  -And the code:
  +before the rest of the mod_perl configuration directives.
   
   <P>
  -<PRE>  #!/usr/apps/bin/perl -w
  -  
  -  use LWP::Parallel::UserAgent;
  -  use Time::HiRes qw(gettimeofday tv_interval);
  -  use strict;
  -  
  -  ###
  -  # Configuration
  -  ###
  -  
  -  my $nof_parallel_connections = 10; 
  -  my $nof_requests_total = 100; 
  -  my $timeout = 10;
  -  my @urls = (
  -            '<A HREF="http://www.you.com:81/perl/faq_manager/faq_manager.pl">http://www.you.com:81/perl/faq_manager/faq_manager.pl</A>',
  -            '<A HREF="http://www.you.com:81/perl/access/access.cgi">http://www.you.com:81/perl/access/access.cgi</A>',
  -           );
  -  
  -  
  -  ##################################################
  -  # Derived Class for latency timing
  -  ##################################################
  -  
  -  package MyParallelAgent;
  -  @MyParallelAgent::ISA = qw(LWP::Parallel::UserAgent);
  -  use strict;
  -  
  -  ###
  -  # Is called when connection is opened
  -  ###
  -  sub on_connect {
  -    my ($self, $request, $response, $entry) = @_;
  -    $self-&gt;{__start_times}-&gt;{$entry} = [Time::HiRes::gettimeofday];
  -  }
  -  
  -  ###
  -  # Are called when connection is closed
  -  ###
  -  sub on_return {
  -    my ($self, $request, $response, $entry) = @_;
  -    my $start = $self-&gt;{__start_times}-&gt;{$entry};
  -    $self-&gt;{__latency_total} += Time::HiRes::tv_interval($start);
  -  }
  -  
  -  sub on_failure {
  -    on_return(@_);  # Same procedure
  -  }
  -  
  -  ###
  -  # Access function for new instance var
  -  ###
  -  sub get_latency_total {
  -    return shift-&gt;{__latency_total};
  -  }
  -  
  -  ##################################################
  -  package main;
  -  ##################################################
  -  ###
  -  # Init parallel user agent
  -  ###
  -  my $ua = MyParallelAgent-&gt;new();
  -  $ua-&gt;agent(&quot;pounder/1.0&quot;);
  -  $ua-&gt;max_req($nof_parallel_connections);
  -  $ua-&gt;redirect(0);    # No redirects
  -  
  -  ###
  -  # Register all requests
  -  ###
  -  foreach (1..$nof_requests_total) {
  -    foreach my $url (@urls) {
  -      my $request = HTTP::Request-&gt;new('GET', $url);
  -      $ua-&gt;register($request);
  -    }
  -  }
  -  
  -  ###
  -  # Launch processes and check time
  -  ###
  -  my $start_time = [gettimeofday];
  -  my $results = $ua-&gt;wait($timeout);
  -  my $total_time = tv_interval($start_time);
  -  
  -  ###
  -  # Requests all done, check results
  -  ###
  -  
  -  my $succeeded     = 0;
  -  my %errors = ();
  -  
  -  foreach my $entry (values %$results) {
  -    my $response = $entry-&gt;response();
  -    if($response-&gt;is_success()) {
  -      $succeeded++; # Another satisfied customer
  -    } else {
  -      # Error, save the message
  -      $response-&gt;message(&quot;TIMEOUT&quot;) unless $response-&gt;code();
  -      $errors{$response-&gt;message}++;
  -    }
  -  }
  -  
  -  ###
  -  # Format errors if any from %errors 
  -  ###
  -  my $errors = join(',', map &quot;$_ ($errors{$_})&quot;, keys %errors);
  -  $errors = &quot;NONE&quot; unless $errors;
  -  
  -  ###
  -  # Format results
  -  ###
  +Also you can call <CODE>perl -c perl-startup</CODE> to test the file's syntax. What does this take?
  +
  +<P>
  +<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<CENTER><H3><A NAME="Sample_perl_startup_file">Sample perl-startup file</A></H3></CENTER>
  +<P>
  +An example of perl-startup file:
  +
  +<P>
  +<PRE>  use strict;
     
  -  #@urls = map {($_,&quot;.&quot;)} @urls;
  -  my @P = (
  -        &quot;URL(s)&quot;          =&gt; join(&quot;\n\t\t &quot;, @urls),
  -        &quot;Total Requests&quot;  =&gt; &quot;$nof_requests_total&quot;,
  -        &quot;Parallel Agents&quot; =&gt; $nof_parallel_connections,
  -        &quot;Succeeded&quot;       =&gt; sprintf(&quot;$succeeded (%.2f%%)\n&quot;,
  -                                   $succeeded * 100 / $nof_requests_total),
  -        &quot;Errors&quot;          =&gt; $errors,
  -        &quot;Total Time&quot;      =&gt; sprintf(&quot;%.2f secs\n&quot;, $total_time),
  -        &quot;Throughput&quot;      =&gt; sprintf(&quot;%.2f Requests/sec\n&quot;, 
  -                                   $nof_requests_total / $total_time),
  -        &quot;Latency&quot;         =&gt; sprintf(&quot;%.2f secs/Request&quot;, 
  -                                   $ua-&gt;get_latency_total() / 
  -                                   $nof_requests_total),
  -       );
  +  # extend @INC if needed
  +  use lib qw(/dir/foo /dir/bar);
     
  +  # make sure we are in a sane environment.
  +  $ENV{GATEWAY_INTERFACE} =~ /^CGI-Perl/
  +     or die &quot;GATEWAY_INTERFACE not Perl!&quot;;
  +   
  +  # for things in the &quot;/perl&quot; URL
  +  use Apache::Registry;          
  +   
  +  #load perl modules of your choice here
  +  #this code is interpreted *once* when the server starts
  +  use LWP::UserAgent ();
  +  use DBI ();
     
  -  my ($left, $right);
  -  ###
  -  # Print out statistics
  -  ###
  -  format STDOUT =
  -  @&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt; @*
  -  &quot;$left:&quot;,        $right
  -  .
  +  # tell me more about warnings
  +  use Carp ();
  +  $SIG{__WARN__} = \&amp;Carp::cluck;
     
  -  while(($left, $right) = splice(@P, 0, 2)) {
  -    write;
  -  }
  +  # Load CGI.pm and call its compile() method to precompile 
  +  # (but not to import) its autoloaded methods. 
  +  use CGI ();
  +  CGI-&gt;compile(':all');
  +</PRE>
  +<P>
  +Note that starting with <CODE>$CGI::VERSION</CODE> 2.46, the recommended method to precompile the code in <CODE>CGI.pm</CODE> is:
  +
  +<P>
  +<PRE>  use CGI qw(-compile :all);
   </PRE>
   <P>
  +But the old method is still available for backward compatibility.
  +
  +<P>
  +See also <A HREF="././status.html#Configuration">Apache::Status</A>
  +
  +
  +
  +<P>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<CENTER><H2><A NAME="Choosing_MaxClients">Choosing MaxClients</A></H2></CENTER>
  +<CENTER><H3><A NAME="What_modules_should_you_add_to_t">What modules should you add to the startup file and why.</A></H3></CENTER>
   <P>
  -The <CODE>MaxClients</CODE> directive sets the limit on the number of simultaneous requests that can be
  -supported; not more than this number of child server processes will be
  -created. To configure more than 256 clients, you must edit the
  -HARD_SERVER_LIMIT entry in httpd.h and recompile. In our case we want to
  -set this variable as small as possible, this way we can virtually bound the
  -resources used by the server children. If we know that we have X Mb of RAM,
  -each child consumes a maximum of Y Mb of RAM (we can restrict each child.
  -See
  -<A HREF="././performance.html#Limiting_the_size_of_the_process">Limiting the size of the processes</A>) and we have all these X Mb dedicated for the webserver. Then calculation
  -of
  -<CODE>MaxClients</CODE> is pretty straightforward :
  +Modules that are being loaded at the server startup will be shared among
  +server children, so only one copy of each module will be loaded, thus
  +saving a lot of RAM for you. Usually I put most of the code I develop into
  +modules and preload them from here. You can even preload your CGI script
  +with <CODE>Apache::RegistryLoader</CODE> and preopen the DB connections with <CODE>Apache::DBI</CODE>. (See <A HREF="././performance.html#Preload_Perl_modules_at_server_s">Preload Perl modules at server startup</A>).
  +
  +<P>
  +<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<CENTER><H3><A NAME="The_confusion_with_use_clause_">The confusion with use() clause at the server startup?</A></H3></CENTER>
  +<P>
  +Many people wonder, why there is a need for duplication of <CODE>use()</CODE>
  +clause both in startup file and in the script itself. The question rises
  +from misunderstanding of the <CODE>use()</CODE> operand. <CODE>use()</CODE> consists of two other operands, namely <CODE>require()</CODE> and <CODE>import()</CODE>. So when you write:
   
   <P>
  -<PRE>  MaxClients = Total Available to the webserver RAM / MAX child's size
  +<PRE>  use Foo qw(bar);
   </PRE>
   <P>
  -So if I have 400Mb left for the webserver to run in, I can set the
  -<CODE>MaxClients</CODE> to be of 40 if I know that each child is bounded to the 10Mb of memory
  -(with <CODE>Apache::SizeLimit</CODE>, See the reference above.)
  +perl actually does:
   
   <P>
  -Certainly you will wonder what happens to your server if there are more
  -than <CODE>MaxClients</CODE> concurrent users at some moment. This situation is accompanied by the
  -following warning message into the
  -<CODE>error.log</CODE> file:
  +<PRE>  require Foo.pm;
  +  import qw(bar);
  +</PRE>
  +<P>
  +When you write:
   
   <P>
  -<PRE>  [Sun Jan 24 12:05:32 1999] [error] server reached MaxClients setting,
  -  consider raising the MaxClients setting
  +<PRE>  use Foo qw();
  +</PRE>
  +<P>
  +perl actually does:
  +
  +<P>
  +<PRE>  require Foo.pm;
  +  import qw();
  +</PRE>
  +<P>
  +which means that the caller does not want any symbols to be imported. Why
  +is this important? Since some modules has <CODE>@EXPORT</CODE> set to a list of tags to be exported by default and when you write:
  +
  +<P>
  +<PRE>  use Foo;
  +</PRE>
  +<P>
  +and think nothing is being imported, the <CODE>import()</CODE> call is being executed and probably some symbols do being imported. See the
  +docs/source of the module in question to make sure you <CODE>use()</CODE> it correctly. When you write your own modules, always remember that it's
  +better to use <CODE>@EXPORT_OK</CODE> instead of <CODE>@EXPORT</CODE>, since the former doesn't export tags unless it was asked to.
  +
  +<P>
  +Since the symbols that you might import into a startup's script namespace
  +will be visible by none of the children, scripts that need a
  +<CODE>Foo</CODE>'s module exported tags have to pull it in like if you did not preload <CODE>Foo</CODE> at the startup file. For example, just because you have
  +<CODE>use()d</CODE>  <CODE>Apache::Constants</CODE> in the startup script, does not mean you can have the following handler:
  +
  +<P>
  +<PRE>  package MyModule;
  +  
  +  sub {
  +    my $r = shift;
  +  
  +    ## Cool stuff goes here
  +  
  +    return OK;
  +  }
  +</PRE>
  +<P>
  +<PRE>  1;
  +</PRE>
  +<P>
  +You would either need to add:
  +
  +<P>
  +<PRE>  use Apache::Constants qw( OK );
  +</PRE>
  +<P>
  +Or instead of <CODE>return OK;</CODE> say:
  +
  +<P>
  +<PRE>  return Apache::Constants::OK;
   </PRE>
   <P>
  -No problem - any connection attempts over the <CODE>MaxClients</CODE> limit will normally be queued, up to a number based on the ListenBacklog
  -directive. Once a child process is freed at the end of a different request,
  -the connection will then be serviced.
  -
  -<P>
  -It <STRONG>is</STRONG> an error because clients are being put in the queue rather than getting
  -serviced at once, but they do not get an error response. The error can be
  -allowed to persist to balance available system resources and response time,
  -but sooner or later you will need to get more RAM so you can start more
  -children. The best thing is not to have this condition reached at all.
  -
  -<P>
  -It's important to understand how much memory a child occupies. If your
  -children can share some memory (when the OS supports that and you take
  -action to allow the sharing happen - See <A HREF="././performance.html#Preload_Perl_modules_at_server_s">Preload Perl modules at server startup</A>). If this is the case, chances are that your <CODE>MaxClients</CODE> can be even higher. But it seems that it's not so simple to calculate the
  -absolute number. (If you come up with solution please let me know)
  +See the manpage/perldoc on <CODE>Exporter</CODE> and <CODE>perlmod</CODE> for more on
  +<CODE>import()</CODE>.
   
   <P>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<CENTER><H2><A NAME="Choosing_MaxRequestsPerChild">Choosing MaxRequestsPerChild</A></H2></CENTER>
  +<CENTER><H3><A NAME="The_confusion_with_defining_glob">The confusion with defining globals in startup</A></H3></CENTER>
   <P>
  -The <CODE>MaxRequestsPerChild</CODE> directive sets the limit on the number of requests that an individual child
  -server process will handle. After
  -<CODE>MaxRequestsPerChild</CODE> requests, the child process will die. If
  -<CODE>MaxRequestsPerChild</CODE> is 0, then the process will never expire.
  +<CODE>PerlRequire</CODE> allows you to execute code that preloads modules and does more things.
  +Imported or defined variables are visible in the scope of the startup file.
  +It is a wrong assumption that global variables that were defined in the
  +startup file, will be accessible by child processes.
   
   <P>
  -Setting <CODE>MaxRequestsPerChild</CODE> to a non-zero limit has two beneficial effects: it solves memory leakages
  -and helps reduce the number of processes when the server load reduces.
  +You do have to define/import variables in your scripts and they will be
  +visible inside a child process who run this script. They will be not shared
  +between siblings. Remember that every script is running in a specially
  +(uniquely) named package - so it cannot access variables from other
  +packages unless it inherits from them or <CODE>use()</CODE>'s them.
   
   <P>
  -The first reason is the most crucial for mod_perl, since sloppy programming
  -will cause a child process to consume more memory after each request. If
  -left unbounded, then after a certain number of requests the children will
  -use up all the available memory and leave the server to die from memory
  -starvation :). Note, that sometimes some standard modules leak memory,
  -especially on OSes where memory managements is bad (Solaris 2.5 on x86 ?)
  +<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<CENTER><H1><A NAME="Running_apachectl_configtest_o">Running 'apachectl configtest' or 'httpd -t'</A></H1></CENTER>
  +<P>
  +<CODE>apachectl configtest</CODE> tests the configuration file without starting the server. You can safely
  +modify the configuration file on your production server, if you run this
  +test before you restart the server. Of course it is not 100% error prone,
  +but it will reveal any syntax errors you might do while editing the file.
   
   <P>
  -If this is your case you can set <CODE>MaxRequestsPerChild</CODE> to a small number, which will allow the system to reclaim the memory,
  -greedy child process consumed, when it exits after <CODE>MaxRequestsPerChild</CODE>
  -requests. But beware -- if you set this number too low, you will lose the
  -speed bonus you receive with mod_perl, so maybe you should consider falling
  -back to plain mod_cgi, since the overhead of reloading the script and the
  -perl interpreter for each request will be too high. Consider using <CODE>Apache::PerlRun</CODE> if this is the case. Also setting <CODE>MaxSpareServers</CODE> to a number close to <CODE>MaxClients</CODE>, will improve the response time (but your parent process will be busy
  -respawning new children all the time!)
  +'<CODE>apachectl configtest</CODE>' is the same as '<CODE>httpd -t</CODE>' and it actually executes the code in startup.pl, not just parses it. <CODE>&lt;Perl</CODE>&gt; configuration has always started Perl during the configuration read,
  +<CODE>Perl{Require,Module}</CODE> do so as well.
   
   <P>
  -Another approach is to use <CODE>Apache::SizeLimit</CODE> (See <A HREF="././performance.html#Limiting_the_size_of_the_process">Limiting the size of the processes</A>). By using this module, you should be able to discontinue using the
  -<CODE>MaxRequestsPerChild</CODE>, although for some folks, using both in combination does the job.
  +If you want your startup code to get a control over the <CODE>-t</CODE>
  +(<CODE>configtest</CODE>) server launch, start the server configuration test with:
   
   <P>
  -See also <A HREF="././performance.html#Preload_Perl_modules_at_server_s">Preload Perl modules at server startup</A> and
  -<A HREF="././performance.html#Sharing_Memory">Sharing Memory</A>.
  +<PRE>  httpd -t -Dsyntax_check
  +</PRE>
  +<P>
  +and in your startup file, add (at the top):
  +
  +<P>
  +<PRE>  return if Apache-&gt;define('syntax_check');
  +</PRE>
  +<P>
  +if you want to prevent the code in the file from being executed.
   
   <P>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<CENTER><H2><A NAME="Choosing_MinSpareServers_MaxSpa">Choosing MinSpareServers, MaxSpareServers and StartServers</A></H2></CENTER>
  +<CENTER><H1><A NAME="Perl_behavior_controls">Perl behavior controls</A></H1></CENTER>
   <P>
  -With mod_perl enabled, it might take as much as 3-30 seconds from the time
  -you start the server until it is ready to serve incoming requests. This
  -delay depends on the OS, the number of preloaded modules and the process
  -load of the machine. So it's best to set
  -<CODE>StartServers</CODE> and <CODE>MinSpareServers</CODE> to high numbers, so that if you get a high load just after the server has
  -been restarted, the fresh servers will be ready to serve requests
  -immediately. With mod_perl, it's usually a good idea to raise all 3
  -variables higher than normal. In order to maximize the benefits of
  -mod_perl, you don't want to kill servers when they are idle, rather you
  -want them to stay up and available to immediately handle new requests. I
  -think an ideal configuration is to set <CODE>MinSpareServers</CODE> and <CODE>MaxSpareServers</CODE> to similar values, maybe even the same. Having the <CODE>MaxSpareServers</CODE>
  -close to <CODE>MaxClients</CODE> will completely use all of your resources (if
  -<CODE>MaxClients</CODE> has been chosen to take the full advantage of the resources), but it'll
  -make sure that at any given moment your system will be capable of
  -responding to requests with the maximum speed (given that number of
  -concurrent requests is not higher then
  -<CODE>MaxClients</CODE>.)
  +For <STRONG>PerlWarn</STRONG> and <STRONG>PerlTaintCheck</STRONG> see <A HREF="././porting.html#Switches_w_T">Switches -w, -T</A>
  +
  +
   
   <P>
  -Let's try some numbers. For a heavily loaded web site and a dedicated
  -machine I would think of (note 400Mb is just for example):
  +<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<CENTER><H1><A NAME="Tuning_MinSpareServers_MaxSpareS">Tuning MinSpareServers MaxSpareServers StartServers MaxClients
  +MaxRequestsPerChild</A></H1></CENTER>
  +<P>
  +See <A HREF="././performance.html#Tuning_the_Apache_s_configuratio">Tuning the Apache's configuration variables for the best performance</A>
  +
   
  +
   <P>
  -<PRE>  Available to webserver RAM:   400Mb
  -  Child's memory size bounded:    10Mb
  -  MaxClients:                   400/10 = 40
  -  StartServers:                 20
  -  MinSpareServers:              20
  -  MaxSpareServers:              35
  +<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<CENTER><H1><A NAME="Publishing_port_numbers_differen">Publishing port numbers different from 80</A></H1></CENTER>
  +<P>
  +It is advised not to publish the 8080 (or alike) port number in URLs, but
  +rather using a proxying rewrite rule in the thin (httpd_docs) server:
  +
  +<P>
  +<PRE>  RewriteRule .*/perl/(.*) <A HREF="http://my.url:8080/perl/">http://my.url:8080/perl/</A>$1 [P]
   </PRE>
   <P>
  -However if I want to use the server for many other tasks, but make it
  -capable of handling a high load, I'd think of:
  +One problem with publishing 8080 port numbers is that I was told that IE
  +4.x has a bug when re-posting data to a non-port-80 url. It drops the port
  +designator, and uses port 80 anyway.
   
   <P>
  -<PRE>  Available to webserver RAM:   400Mb
  -  Child's memory size bounded:    10Mb
  -  MaxClients:                   400/10 = 40
  -  StartServers:                 5
  -  MinSpareServers:              5
  -  MaxSpareServers:              10
  +<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<CENTER><H1><A NAME="Perl_Sections">Perl Sections</A></H1></CENTER>
  +<P>
  +With <CODE>&amp;lt;Perl&amp;gt;&amp;lt;/Perl&amp;gt;</CODE> sections, it is possible to configure your server entirely in Perl.
  +
  +<P>
  +<STRONG>&lt;Perl&gt;</STRONG> sections can contain *any* and as much Perl code as you wish. These
  +sections are compiled into a special package whose symbol table mod_perl
  +can then walk and grind the names and values of Perl variables/structures
  +through the apache core configuration gears. Most of the configurations
  +directives can be represented as scalars (<STRONG>$scalar</STRONG>) or lists (<STRONG>@list</STRONG>). An <CODE>@List</CODE> inside these sections is simply converted into a space delimited string for
  +you inside. Here is an example:
  +
  +<P>
  +<PRE>  #httpd.conf
  +  &lt;Perl&gt;
  +  @PerlModule = qw(Mail::Send Devel::Peek);
  + 
  +  #run the server as whoever starts it
  +  $User  = getpwuid($&gt;) || $&gt;;
  +  $Group = getgrgid($)) || $); 
  + 
  +  $ServerAdmin = $User;
  + 
  +  &lt;/Perl&gt;
  +</PRE>
  +<P>
  +Block sections such as <CODE>&lt;Location</CODE>..&lt;/Location&gt;&gt; are represented in a
  +<CODE>%Location</CODE> hash, e.g.:
  +
  +<P>
  +<PRE>  $Location{&quot;/~dougm/&quot;} = {
  +    AuthUserFile =&gt; '/tmp/htpasswd',
  +    AuthType =&gt; 'Basic',
  +    AuthName =&gt; 'test',
  +    DirectoryIndex =&gt; [qw(index.html index.htm)],  
  +    Limit =&gt; {
  +    METHODS =&gt; 'GET POST',
  +    require =&gt; 'user dougm',
  +    },
  +  };
   </PRE>
   <P>
  -(These numbers are taken off the top of my head, and it shouldn't be used
  -as a rule, but rather as examples to show you some possible scenarios. Use
  -this information wisely!)
  +If a Directive can take two *or* three arguments you may push strings and
  +the lowest number of arguments will be shifted off the <CODE>@List</CODE> or use array reference to handle any number greater than the minimum for
  +that directive:
   
   <P>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<CENTER><H2><A NAME="Summary_of_Benchmarking_to_tune_">Summary of Benchmarking to tune all 5 parameters</A></H2></CENTER>
  +<PRE>  push @Redirect, &quot;/foo&quot;, &quot;<A HREF="http://www.foo.com/&quot">http://www.foo.com/&quot</A>;;
  +  
  +  push @Redirect, &quot;/imdb&quot;, &quot;<A HREF="http://www.imdb.com/&quot">http://www.imdb.com/&quot</A>;;
  +  
  +  push @Redirect, [qw(temp &quot;/here&quot; &quot;<A HREF="http://www.there.com&quot">http://www.there.com&quot</A>;)];
  +</PRE>
   <P>
  -OK, we've run various benchmarks let's summarize the conclusions:
  +Other section counterparts include <CODE>%VirtualHost</CODE>, <CODE>%Directory</CODE> and
  +<CODE>%Files</CODE>.
   
  -<UL>
  -<P><LI><STRONG><A NAME="item_MaxRequestsPerChild">MaxRequestsPerChild</A></STRONG>
   <P>
  -If your scripts are clean and don't leak memory, set this variable to a
  -number as large as possible (10000?). If you use
  -<CODE>Apache::SizeLimit</CODE>, you can set this parameter to 0 (equal to infinity).
  +To pass all environment variables to the children with a single
  +configuration directive, rather than listing each one via PassEnv or
  +PerlPassEnv, a <STRONG>&lt;Perl&gt;</STRONG> section could read in a file and:
   
  -<P><LI><STRONG><A NAME="item_StartServers">StartServers</A></STRONG>
   <P>
  -If you keep a small number of servers active most of the time, keep this
  -number low. Especially if <CODE>MaxSpareServers</CODE> is low as it'll kill the just loaded servers before they were utilized at
  -all (if there is no load). If your service is heavily loaded, make this
  -number close to
  -<CODE>MaxClients</CODE> (and keep <CODE>MaxSpareServers</CODE> equal to <CODE>MaxClients</CODE> as well.)
  -
  -<P><LI><STRONG><A NAME="item_MinSpareServers">MinSpareServers</A></STRONG>
  +<PRE>  push @PerlPassEnv, [$key =&gt; $val];
  +</PRE>
   <P>
  -If your server performs other work besides web serving, make this low so
  -the memory of unused children will be freed when there is no big load. If
  -your server's load varies (you get loads in bursts) and you want fast
  -response for all clients at any time, you will want to make it high, so
  -that new children will be respawned in advance and be waiting to handle
  -bursts of requests.
  +or
   
  -<P><LI><STRONG><A NAME="item_MaxSpareServers">MaxSpareServers</A></STRONG>
   <P>
  -The logic is the same as of <CODE>MinSpareServers</CODE> - low if you need the machine for other tasks, high if it's a dedicated web
  -host and you want a minimal response delay.
  +<PRE>  Apache-&gt;httpd_conf(&quot;PerlPassEnv $key $val&quot;);
  +</PRE>
  +<P>
  +These are somewhat simple examples, but they should give you the basic
  +idea. You can mix in any Perl code your heart desires. See
  +<CODE>eg/httpd.conf.pl</CODE> and <CODE>eg/perl_sections.txt</CODE> in mod_perl distribution for some examples.
   
  -<P><LI><STRONG><A NAME="item_MaxClients">MaxClients</A></STRONG>
   <P>
  -Not too low, so you don't get into a situation where clients are waiting
  -for the server to start serving them (they might wait, but not too long).
  -Don't make it high, since if you get a high load and all requests will be
  -immediately granted, your CPU will have a hard time keeping up, and if the
  -child's size * number of running children is larger than the total
  -available RAM, your server will start swapping (which will slow down
  -everything, which in turn will make things even more slower, until
  -eventually your machine could die). It's important that you take pains to
  -ensure that swapping does not normally happen. Swap space is an emergency
  -pool, not a resource to be used on a consistent basis. If you are low on
  -memory and you badly need it - buy it, memory is amazingly cheap these
  -days. But based on the test I conducted above, even if you have plenty of
  -memory like I have (1Gb), increasing <CODE>MaxClients</CODE> sometimes will give you no speedup. The more clients that are running, the
  -more CPU time will be required, the less CPU time slices each process will
  -receive. The response latency (the time to respond to a request) will grow,
  -so you won't see the expected improvement. The best approach is to find the
  -minimum requirement for your kind of service and the maximum capability of
  -your machine. Then start at the minimum and start testing like I did,
  -successively raising this parameter until you find the point on the curve
  -of the graph of the latency or throughput where the improvement becomes
  -smaller. Stop there and use it. Of course when you use these parameters in
  -production server, you will have the ability to tune them more precisely.
  -Also don't forget that if you add more scripts, most probably that the
  -parameters need to be recalculated, since the processes will grow in size
  -as you compile in more code.
  +A tip for syntax checking outside of httpd:
   
  -</UL>
   <P>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<CENTER><H1><A NAME="Preopen_DB_connection_at_server_">Preopen DB connection at server startup:</A></H1></CENTER>
  +<PRE>  &lt;Perl&gt;
  +  # !perl
  +  
  +  #... code here ...
  +  
  +  __END__
  +  &lt;/Perl&gt;
  +</PRE>
   <P>
  -If you use DBI for DB connections, you can preopen connections to DB for
  -each child with Apache::DBI.
  +Now you may run:
   
   <P>
  -<PRE>  use Apache::DBI ();
  -  Apache::DBI-&gt;connect_on_init(&quot;DBI:mysql:test&quot;, 'login','passwd', 
  -                               {
  -                                RaiseError =&gt; 1,
  -                                PrintError =&gt; 1,
  -                                AutoCommit =&gt; 1,
  -                               };
  +<PRE>  perl -cx httpd.conf
   </PRE>
   <P>
  -See also <A HREF="#Persistent_DB_Connections">Persistent DB Connections</A>.
  +To enable <CODE>&lt;Perl</CODE>&gt; sections you should build mod_perl with <STRONG>perl
  +Makefile.PL PERL_SECTIONS=1</STRONG>.
   
   <P>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<CENTER><H1><A NAME="Persistent_DB_Connections">Persistent DB Connections</A></H1></CENTER>
  +<CENTER><H1><A NAME="Configuring_Apache_mod_perl_wi">Configuring Apache + mod_perl with mod_macro</A></H1></CENTER>
   <P>
  -Another popular use of mod_perl is to take advantage of its ability to
  -maintain persistent open database connections. The basic approach is as
  -follows:
  +mod_macro is an Apache module written by Fabien Coelho that lets you define
  +and use macros in the Apache configuration file.
   
  -<P>
  -<PRE>  #Apache::Registry script
  -  use strict;
  -  use vars qw($dbh);
  -  
  -  $dbh ||= SomeDbPackage-&gt;connect(...);
  -</PRE>
   <P>
  -Since <CODE>$dbh</CODE> is a global variable for the child, once the child has opened the
  -connection it will use it over and over again, unless you perform <CODE>disconnect()</CODE>.
  +mod_macro proved really useful when you have many virtual hosts, each
  +virtual host has a number of scripts/modules, most of them with a
  +moderately complex configuration setup.
   
   <P>
  -Be careful to use different names for handlers if you open connection to
  -different databases!
  +First download the latest version of mod_macro from <A
  +HREF="http://www.cri.ensmp.fr/~coelho/mod_macro/">http://www.cri.ensmp.fr/~coelho/mod_macro/</A>
  +, and configure your Apache server to use this module.
   
   <P>
  -<CODE>Apache::DBI</CODE> allows you to make a persistent database connection. With this module
  -enabled, every connect request to the plain DBI module will be forwarded to
  -the <CODE>Apache::DBI</CODE> module. This looks to see whether a database handle from a previous connect
  -request has already been opened, and if this handle is still valid using
  -the ping method. If these two conditions are fulfilled it just returns the
  -database handle. If there is no appropriate database handle or if the ping
  -method fails, a new connection is established and the handle is stored for
  -later re-use. <STRONG>There is no need to delete the disconnect
  -statements from your code</STRONG>. They will not do anything, as the
  -<CODE>Apache::DBI</CODE> module overloads the disconnect method with a NOP. On child exit there is
  -no explicit disconnect, the child dies and so does the database connection.
  +Here are some useful macros for mod_perl users:
   
   <P>
  -The usage is simple -- add to <CODE>httpd.conf</CODE>:
  -
  +<PRE>        # set up a registry script
  +        &lt;Macro registry&gt;
  +        SetHandler &quot;perl-script&quot;
  +        PerlHandler Apache::Registry
  +        Options +ExecCGI
  +        &lt;/Macro&gt;
  +</PRE>
   <P>
  -<PRE>  PerlModule Apache::DBI
  +<PRE>        # example
  +        Alias /stuff /usr/www/scripts/stuff
  +        &lt;Location /stuff&gt;
  +        Use registry
  +        &lt;/Location&gt;
   </PRE>
   <P>
  -It is important, to load this module before any other <CODE>ApacheDBI*</CODE> module!
  +If your registry scripts are all located in the same directory, and your
  +aliasing rules consistent, you can use this macro:
   
   <P>
  -<PRE>  a script.perl
  -  ------------
  -  use DBI;
  -  use strict;
  -  
  -  my $dbh = DBI-&gt;connect( 'DBI:mysql:database', 'user', 'password',
  -                          { autocommit =&gt; 0 }
  -                        ) || die $DBI::errstr;
  -  
  -  ...rest of the program
  +<PRE>        # set up a registry script for a specific location
  +        &lt;Macro registry $location $script&gt;
  +        Alias /script /usr/www/scripts/$script
  +        &lt;Location $location&gt;
  +        SetHandler &quot;perl-script&quot;
  +        PerlHandler Apache::Registry
  +        Options +ExecCGI
  +        &lt;/Location&gt;
  +        &lt;/Macro&gt;
   </PRE>
  -<P>
  -The module provides the additional method:
  -
   <P>
  -<PRE>  Apache::DBI-&gt;connect_on_init($data_source, $username, $auth, \%attr)
  +<PRE>        # example
  +        Use registry stuff stuff.pl
   </PRE>
   <P>
  -This can be used as a simple way to have apache children establish
  -connections on server startup. This call should be in a startup file
  -(PerlModule, &lt;Perl&gt; or PerlRequire). It will establish a connection when a child is
  -started in that child process. See the <CODE>Apache::DBI</CODE>
  -manpage to see the requirements for this method.
  +If you're using content handlers packaged as modules, you can use the
  +following macro:
   
   <P>
  -Beware however, as some old DBD drivers do not support this feature (ping
  -method), so check the documentation of the driver you use.
  -
  +<PRE>        # set up a mod_perl content handler module
  +        &lt;Macro modperl $module&gt;
  +        SetHandler &quot;perl-script&quot;
  +        Options +ExecCGI
  +        PerlHandler $module
  +        &lt;/Macro&gt;
  +</PRE>
   <P>
  -Another problem is with timeouts: some databases disconnect the client
  -after a certain time of inactivity. The ping method ensures that this will
  -not happen. Some DBD drivers don't have this method, check the Apache::DBI
  -manpage to see how to write a ping method.
  -
  +<PRE>        #examples
  +        &lt;Location /perl-status&gt;
  +        PerlSetVar StatusPeek On
  +        PerlSetVar StatusGraph On
  +        PerlSetVar StatusDumper On
  +        Use modperl Apache::Status
  +        &lt;/Location&gt;
  +</PRE>
   <P>
  -Another approach is to change the client's connection timeout. Starting
  -from mysql-3.22.x you can set a <CODE>wait_timeout</CODE>
  -option at mysqld server startup to change the default value, setting it to
  -36 hours probably would fix the timeout problem.
  +The following macro sets up a Location for use with HTML::Embperl. Here we
  +define all ``.html'' files to be processed by Embperl.
   
   <P>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<CENTER><H1><A NAME="Using_1_under_mod_perl_and_be">Using $|=1 under mod_perl and better print() techniques.</A></H1></CENTER>
  +<PRE>        &lt;Macro embperl&gt;
  +        SetHandler &quot;perl-script&quot;
  +        Options +ExecCGI
  +        PerlHandler HTML::Embperl
  +        PerlSetEnv EMBPERL_FILESMATCH \.html$
  +        &lt;/Macro&gt;
  +</PRE>
   <P>
  -As you know <CODE>$|=1;</CODE> disables the buffering of the currently selected file handle (default is <CODE>STDOUT</CODE>). If you enable it, <CODE>ap_rflush()</CODE>
  -is called after each <CODE>print()</CODE>, unbuffering Apache's IO.
  -
  +<PRE>        # examples
  +        &lt;Location /mrtg&gt;
  +        Use embperl
  +        &lt;/Location&gt;
  +</PRE>
   <P>
  -If you are using a _bad_ style in generating output, which consist of
  -multiple <CODE>print()</CODE> calls, or you just have too many of them, you will experience a degradation
  -in performance. The severity depends on the number of the calls.
  +Macros are also very useful for things that tend to be verbose, such as
  +setting up Basic Authentication:
   
   <P>
  -Many old CGIs were written in the style of:
  -
  +<PRE>        # Sets up Basic Authentication
  +        &lt;Macro BasicAuth $realm $group&gt;
  +        Order deny,allow
  +        Satisfy any
  +        AuthType Basic
  +        AuthName $realm
  +        AuthGroupFile /usr/www/auth/groups
  +        AuthUserFile /usr/www/auth/users
  +        Require group $group
  +        Deny from all
  +        &lt;/Macro&gt;
  +</PRE>
   <P>
  -<PRE>  print &quot;&lt;BODY BGCOLOR=&quot;black&quot; TEXT=&quot;white&quot;&gt;&quot;;
  -  print &quot;&lt;H1&gt;&quot;;
  -  print &quot;Hello&quot;;
  -  print &quot;&lt;/H1&gt;&quot;;
  -  print &quot;&lt;A HREF=&quot;foo.html&quot;&gt; foo &lt;/A&gt;&quot;;
  -  print &quot;&lt;/BODY&gt;&quot;;
  +<PRE>        # example of use
  +        &lt;Location /stats&gt;
  +        Use BasicAuth WebStats Admin
  +        &lt;/Location&gt;
   </PRE>
   <P>
  -which reveals the following drawbacks: multiple <CODE>print()</CODE> calls - performance degradation with $|=1, backslashism which makes the
  -code less readable and more difficult to format the HTML to be easily
  -readable as CGI's output. The code below solves them all:
  +Finally, here is a complete example that uses macros to set up simple
  +virtual hosts. It uses the BasicAuth macro defined previously (yes, macros
  +can be nested!).
   
   <P>
  -<PRE>  print qq{
  -    &lt;BODY BGCOLOR=&quot;black&quot; TEXT=&quot;white&quot;&gt;
  -      &lt;H1&gt;
  -        Hello
  -      &lt;/H1&gt;
  -      &lt;A HREF=&quot;foo.html&quot;&gt; foo &lt;/A&gt;
  -    &lt;/BODY&gt;
  -  };
  +<PRE>        &lt;Macro vhost $ip $domain $docroot $admingroup&gt;
  +        &lt;VirtualHost $ip&gt;
  +        ServerAdmin webmaster@$domain
  +        DocumentRoot /usr/www/htdocs/$docroot
  +        ServerName www.$domain
  +        &lt;Location /stats&gt;
  +        Use BasicAuth Stats-$domain $admingroup
  +        &lt;/Location&gt;
  +        &lt;/VirtualHost&gt;
  +        &lt;/Macro&gt;
   </PRE>
  -<P>
  -I guess you see the difference. Be careful though, when printing a
  -<CODE>&amp;lt;HTML&amp;gt;</CODE> tag. The correct way is:
  -
   <P>
  -<PRE>  print qq{&lt;HTML&gt;
  -    &lt;HEAD&gt;&lt;/HEAD&gt;
  -    &lt;BODY&gt;
  -  }
  +<PRE>        # define some virtual hosts
  +        Use vhost 10.1.1.1 example.com example example-admin
  +        Use vhost 10.1.1.2 example.net examplenet examplenet-admin
   </PRE>
   <P>
  -If you try the following:
  +mod_macro also useful in a non vhost setting. Some sites for example have
  +lots of scripts where people use to view various statistics, email settings
  +and etc. It is much easier to read things like:
   
   <P>
  -<PRE>  print qq{
  -    &lt;HTML&gt;
  -    &lt;HEAD&gt;&lt;/HEAD&gt;
  -    &lt;BODY&gt;
  -  }
  +<PRE>  use /forwards email/showforwards
  +  use /webstats web/showstats
   </PRE>
   <P>
  -Some older browsers might not accept the output as HTML, but rather print
  -it as a plain text, since they expect the first characters after the
  -headers and empty line to be <CODE>&amp;lt;HTML&amp;gt;</CODE> and not spaces and/or additional newline and then <CODE>&amp;lt;HTML&amp;gt;</CODE>. Even if it works with your browser, it might not work for others.
  +<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<CENTER><H1><A NAME="General_pitfalls">General pitfalls</A></H1></CENTER>
  +<P>
  +<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<CENTER><H2><A NAME="My_cgi_perl_code_is_being_return">My cgi/perl code is being returned as a plain text instead of being executed by the webserver?</A></H2></CENTER>
  +<P>
  +Check your configuration files and make sure that the ``ExecCGI'' is turned
  +on in your configurations. 
   
   <P>
  -Now let's go back to the <CODE>$|=1</CODE> topic. I still disable buffering, for 2 reasons: I use few <CODE>print()</CODE> calls and I want my users to see the output immediately. So if I am about
  -to produce the results of the DB query, which might take some time to
  -complete, I want users to get some titles ahead. This improves the
  -usability of my site. Recall yourself:
  -
  +<PRE>  &lt;Location /perl&gt;
  +    SetHandler perl-script
  +    PerlHandler Apache::Registry
  +    Options ExecCGI
  +    allow from all
  +    PerlSendHeader On
  +  &lt;/Location&gt;
  +</PRE>
   <P>
  -What do you like better: getting the output ``slowly'' but steadily or
  -having to watch the ``falling stars'' for awhile and then to receive the
  -whole output at once (if the browser did not timeout till then).
  -
  +<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<CENTER><H2><A NAME="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></H2></CENTER>
   <P>
  -Conclusion: Do not blindly follow suggestions, but think what is best for
  -you in every given case.
  +Did you put <STRONG>PerlSendHeader On</STRONG> in the configuration part of the &lt;Location foo&gt;&lt;/Location&gt;?
   
   <P>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<CENTER><H1><A NAME="More_Reducing_Memory_Usage_Tips">More Reducing Memory Usage Tips</A></H1></CENTER>
  +<CENTER><H2><A NAME="Is_there_a_way_to_provide_a_diff">Is there a way to provide a different startup.pl file for each individual virtual host</A></H2></CENTER>
   <P>
  -One of the important issues in improving the performance is reduction of
  -memory usage - the less memory each server uses, the more server processes
  -you can start, and thus the more performance you have (from the user's
  -point of view - the response speed )
  +No. Any virtual host will be able to see the routines from a startup.pl
  +loaded for any other virtual host.  
   
   <P>
  -See <A HREF="././porting.html#Global_Variables">Global Variables</A>
  -
  -
  +<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<CENTER><H2><A NAME="Is_there_a_way_to_modify_INC_on">Is there a way to modify @INC on a per-virtual-host or per-location basis.</A></H2></CENTER>
  +<P>
  +You can use 'PerlSetEnv PERL5LIB ...' or a PerlFixupHandler w/ the lib
  +pragma.
   
   <P>
  -See <A HREF="././porting.html#Memory_leakage">Memory "leakages"</A>
  +Even a better way is to use <A HREF="././modules.html#Apache_PerlVINC_set_a_differe">Apache::PerlVINC</A>
   
   
   
   <P>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<CENTER><H1><A NAME="Profiling">Profiling</A></H1></CENTER>
  -<P>
  -Profiling will help you to determine which subroutines or just snippets of
  -code take the longest execution time and which subroutines are being called
  -most often, then you will probably will want to optimize those, and to
  -improve the code toward efficiency.
  -
  +<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>
   <P>
  -It is possible to profile code running under mod_perl with the
  -<CODE>Devel::DProf</CODE> module, available on CPAN. However, you must have apache version 1.3b3 or
  -higher and the <CODE>PerlChildExitHandler</CODE>
  -enabled. 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 called at the server shutdown. Here is how to start and
  -stop a server with the profiler enabled:
  +This has been a bug before, last fixed in 1.15_01, i.e. if you are running
  +1.15, that could be the problem. You should set this variable in a startup
  +file (PerlRequire):
   
   <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>  $Apache::Registry::NameWithVirtualHost = 1;
   </PRE>
  -<P>
  -The <CODE>Devel::DProf</CODE> package is a Perl code profiler. It will collect information on the
  -execution time of a Perl script and of the subs in that script (remember
  -that that <CODE>print()</CODE> and <CODE>map()</CODE> are subs as well, they come together with Perl!).
  -
   <P>
  -Another approach is to use <CODE>Apache::DProf</CODE>, which hooks
  -<CODE>Devel::DProf</CODE> into mod_perl. The <CODE>Apache::DProf</CODE> module will run a
  -<CODE>Devel::DProf</CODE> profiler inside each child server and write the
  -<CODE>tmon.out</CODE> file in the directory <CODE>$ServerRoot/logs/dprof/$$</CODE> when the child is shutdown. All it takes is to add to <CODE>httpd.conf</CODE>:
  +But, as we know sometimes bug turns into a feature. If there is the same
  +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)
   
   <P>
  -<PRE>  PerlModule Apache::DProf
  +<PRE>  $Apache::Registry::NameWithVirtualHost = 0;
   </PRE>
  +<P>
  +<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<CENTER><H2><A NAME="the_server_no_longer_retrieves_t">the server no longer retrieves the DirectoryIndex files for a directory</A></H2></CENTER>
   <P>
  -Remember that any PerlHandler .pm that was pulled in before
  -<CODE>Apache::DProf</CODE>, would not have its code debugging info inserted.
  +The problem was reported by users who declared mod_perl configuration
  +inside a &lt;Directory&gt; section for all files matching to *.pl. The
  +problem has gone away after placing the usage of mod_perl in a
  +&lt;File&gt;- section.
   
   <P>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<CENTER><H1><A NAME="CGI_pm_s_object_methods_calls_vs">CGI.pm's object methods calls vs. function calls</A></H1></CENTER>
  +<CENTER><H1><A NAME="Configuration_Security_Concerns">Configuration Security Concerns</A></H1></CENTER>
   <P>
  -Which approach is better?
  +It is better not to advertise the port mod_perl server running at to the
  +outside world for it creates a potential security risk by revealing which
  +<CODE>module(s)</CODE> and/or OS you are running your web server on.
   
   <P>
  -<PRE>  use CGI;
  -  my $q = new CGI;
  -  print $q-&gt;param('x');
  -</PRE>
  +The more modules you have in your web server, the more complex the code in
  +your webserver.
  +
   <P>
  -versus
  +The more complex the code in your web server, the more chances for bugs.
   
   <P>
  -<PRE>  use CGI (:standard);
  -  print param('x');
  -</PRE>
  +The more chance for bugs, the more chance that some of those bugs may
  +involve security.
  +
   <P>
  -There is not any performance benefit of using the object calls rather than
  -the function calls, but there is a real memory hit when you import all of <CODE>CGI.pm</CODE>'s function calls into your process memory. This can be significant,
  -particularly when there are many child daemons.
  +Never was completely sure why the default of the ServerToken directive in
  +Apache is Full rather than Minimal. Seems like you would only make it full
  +if you are debugging.
   
   <P>
  -I strongly endorse <A HREF="././modules.html#Apache_Request_libapreq_Gen">Apache::Request (libapreq) - Generic Apache Request Library</A>. Its guts are all written in C, giving it a significant memory and
  -performance benefit.
  +For more information see <A HREF="././config.html#Publishing_port_numbers_differen">Publishing port numbers different from 80</A>
  +
  +
   
   <P>
  +Another approach is to modify httpd sources to reveal no unwanted
  +information, so if you know the port the <CODE>HEAD</CODE> request will return an empty or phony <CODE>Server:</CODE> field.
  +
  +<P>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<CENTER><H1><A NAME="Sending_plain_HTML_as_a_compress">Sending plain HTML as a compressed output</A></H1></CENTER>
  +<CENTER><H1><A NAME="Logical_grouping_of_Location_Di">Logical grouping of Location, Directory and FilesMatch directives</A></H1></CENTER>
   <P>
  -See <A HREF="././modules.html#Apache_GzipChain_compress_HTM">Apache::GzipChain - compress HTML (or anything) in the OutputChain</A>
  +Let's say that you want all the file in a specific directory and below to
  +be handled the same way, but a few of them to be handled somewhat
  +different. For example:
   
  +<P>
  +<PRE>  &lt;Directory /home/foo&gt;
  +    &lt;FilesMatch &quot;\.(html|txt)$&quot;&gt;
  +      SetHandler perl-script
  +      PerlHandler Apache::AddrMunge
  +    &lt;/FilesMatch&gt;
  +  &lt;/Directory&gt;
  +</PRE>
  +<P>
  +Alternatively you can use &lt;Files&gt; inside an <CODE>.htaccess</CODE> file.
   
  +<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><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
   	     The <a href="http://www.modperl.com/">
  @@ -8169,7 +8739,7 @@
   	     Amazon.com</a>.
   
   	     <HR>
  -	     [    <A HREF="porting.html">Prev</A> |      <A HREF="index.html">Main Page</A> | <A HREF="obvious.html">Next</A>      ]
  +	     [    <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%" >
   <TR ALIGN=CENTER VALIGN=TOP>
  @@ -8182,7 +8752,7 @@
       <B>
         <FONT SIZE=-1>
   	     Written by <A HREF="help.html#This_document_s_Author">Stas Bekman</A>.
  -	     <BR>Last Modified at 06/19/1999
  +	     <BR>Last Modified at 07/02/1999
         </FONT>
       </B>
     </TD>
  @@ -8209,7 +8779,7 @@
   <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
   <HTML>
   <HEAD>
  -   <TITLE>mod_perl guide: Things obvious to others, but not to you</TITLE>
  +   <TITLE>mod_perl guide: Frequent mod_perl problems</TITLE>
      <META NAME="GENERATOR" CONTENT="Pod2HTML [Perl/Linux]">
      <META NAME="Author" CONTENT="Stas Bekman">
      <META NAME="Description" CONTENT="All Apache/Perl related information: Hints, Guidelines, Scenarios and Troubleshottings">
  @@ -8228,37 +8798,15 @@
   <H1 ALIGN=CENTER>
   <A HREF="http://perl.apache.org"><IMG SRC="images/mod_perl.gif" ALT="Mod Perl Icon" BORDER=0 HEIGHT=30 WIDTH=90 ALIGN=LEFT></A>
   <A HREF="http://perl.apache.org"><IMG SRC="images/mod_perl.gif" ALT="Mod Perl Icon" BORDER=0 HEIGHT=30 WIDTH=90 ALIGN=RIGHT></A>
  -Things obvious to others, but not to you</H1>
  +Frequent mod_perl problems</H1>
   <HR WIDTH="100%">
  -	    [    <A HREF="performance.html">Prev</A> |      <A HREF="index.html">Main Page</A> | <A HREF="warnings.html">Next</A>      ]<HR><!-- INDEX BEGIN -->
  +	    [    <A HREF="config.html">Prev</A> |      <A HREF="index.html">Main Page</A> | <A HREF="control.html">Next</A>      ]<HR><!-- INDEX BEGIN -->
   <P><B><FONT SIZE=-1>Table of Contents:</FONT></B></P>
   <UL>
   
   	<LI><A HREF="#Coverage">Coverage</A>
   	<LI><A HREF="#my_scoped_variable_in_nested_s">my() scoped variable in nested subroutines</A>
  -	<UL>
  -
  -		<LI><A HREF="#The_poison">The poison</A>
  -		<LI><A HREF="#The_diagnosis">The diagnosis</A>
  -		<LI><A HREF="#The_remedy">The remedy</A>
  -		<LI><A HREF="#Additional_reading_references">Additional reading references</A>
  -	</UL>
  -
  -	<LI><A HREF="#Reloading_Modules_and_Required_F">Reloading Modules and Required Files</A>
  -	<UL>
  -
  -		<LI><A HREF="#Restarting_the_server">Restarting the server</A>
  -		<LI><A HREF="#Using_Apache_StatINC">Using Apache::StatINC</A>
  -		<LI><A HREF="#Reloading_only_specific_files">Reloading only specific files</A>
  -	</UL>
  -
  -	<LI><A HREF="#Compiled_Regular_Expressions">Compiled Regular Expressions </A>
  -	<LI><A HREF="#Debugging_your_code_in_Single_Se">Debugging your code in Single Server Mode</A>
  -	<LI><A HREF="#_M_and_other_time_file_tests_u">-M and other time() file tests under mod_perl</A>
  -	<LI><A HREF="#Handling_the_User_pressed_Stop_">Handling the 'User pressed Stop button' case</A>
  -	<LI><A HREF="#Handling_the_server_timeout_case">Handling the server timeout cases and working with $SIG{ALRM}</A>
  -	<LI><A HREF="#Where_do_the_warnings_errors_go_">Where do the warnings/errors go?</A>
  -	<LI><A HREF="#Setting_environment_variables_fo">Setting environment variables for scripts called from CGI.</A>
  +	<LI><A HREF="#Segfaults_caused_by_PerlFreshRes">Segfaults caused by PerlFreshRestart</A>
   </UL>
   <!-- INDEX END -->
   
  @@ -8278,714 +8826,1016 @@
   <P>
   <CENTER><H1><A NAME="Coverage">Coverage</A></H1></CENTER>
   <P>
  -This document describes ``special'' traps you may encounter when running
  -your plain CGIs under Apache::Registry and Apache::PerlRun.
  +This new document was born because some problems come up so often on the
  +mailing list that should be stressed in the guide as one of the most
  +important things to read/beware of. So I have tried to enlist them in this
  +document. If you think some important problem that is being reported
  +frequently on the list and covered in the guide but not included below,
  +please tell.
   
   <P>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
   <CENTER><H1><A NAME="my_scoped_variable_in_nested_s">my() scoped variable in nested subroutines</A></H1></CENTER>
  -<P>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<CENTER><H2><A NAME="The_poison">The poison</A></H2></CENTER>
   <P>
  -In a non modperl script (stand alone or CGI), there is no problem writing
  -code like this:
  +See <A HREF="././obvious.html#my_scoped_variable_in_nested_s">my() scoped variable in nested subroutines</A>.
   
   <P>
  -<PRE>    use CGI qw/param/;
  -    my $x = param('x');
  -    sub printit {
  -       print &quot;$x\n&quot;;
  -    }
  -</PRE>
  +<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<CENTER><H1><A NAME="Segfaults_caused_by_PerlFreshRes">Segfaults caused by PerlFreshRestart</A></H1></CENTER>
   <P>
  -However, the script is run under Apache::Registry, it will in fact be
  -repackaged into something like this:
  +See <A HREF="././warnings.html#Evil_things_might_happen_when_us">Evil things might happen when using PerlFreshRestart</A>
   
  -<P>
  -<PRE>  package $mangled_package_name;
  -  sub handler {
  -    #line1 $original_filename
  -    use CGI qw/param/;
  -    my $x = param('x');
  -    sub printit {
  -       print &quot;$x\n&quot;;
  -    }
  -  }
  -</PRE>
  -<P>
  -Now <CODE>printit</CODE> is an inner named subroutine. Because it is referencing a lexical variable
  -from an enclosing scope, a closure is created.
   
  -<P>
  -The first time the script is run, the correct value of <CODE>$x</CODE> will
  -be printed. However on subsequent runs, <CODE>printit</CODE> will retain the initial value of <CODE>$x</CODE> -- not what you want.
   
  -<P>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<CENTER><H2><A NAME="The_diagnosis">The diagnosis</A></H2></CENTER>
  -<P>
  -Always use -w (or/and PerlWarn ON)! Perl will then emit a warning like:
  +	     The <a href="http://www.modperl.com/">
  +	     <B>Writing Apache Modules with Perl and C</B></a>
  +	     book can be purchased online from <a
  +	     href="http://www.ora.com/catalog/wrapmod/">O'Reilly </a>
  +	     and <a
  +	     href="http://www.amazon.com/exec/obidos/ASIN/156592567X/writinapachemodu">
  +	     Amazon.com</a>.
  +
  +	     <HR>
  +	     [    <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%" >
  +<TR ALIGN=CENTER VALIGN=TOP>
  +  <TD ALIGN=CENTER VALIGN=CENTER COLSPAN="3">
  +	     <HR>
  +  </TD>
  +</TR>
  +<TR ALIGN=CENTER VALIGN=TOP>
  +  <TD ALIGN=CENTER VALIGN=CENTER>
  +    <B>
  +      <FONT SIZE=-1>
  +	     Written by <A HREF="help.html#This_document_s_Author">Stas Bekman</A>.
  +	     <BR>Last Modified at 05/08/1999
  +      </FONT>
  +    </B>
  +  </TD>
  +
  +  <TD>
  +	     <A HREF="http://perl.apache.org"><IMG SRC="images/mod_perl2.jpg" ALT="Mod Perl Icon" BORDER=0 HEIGHT=59 WIDTH=150></A>
  +  </TD>
  +
  +  <TD>
  +    <FONT SIZE=-2>
  +	     Use of the Camel for Perl is <BR>
  +	     a trademark of <A HREF="http://www.ora.com">O'Reilly &amp; Associates</A>,<BR>
  +             and is used by permission. 
  +    </FONT> 
  +  </TD>
  +</TR>
  +</TABLE></CENTER>
  +
  +</BODY>
  +</HTML>
  +	    
  +
  +<HR SIZE=6>
  +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
  +<HTML>
  +<HEAD>
  +   <TITLE>mod_perl guide: Controlling and Monitoring the Server</TITLE>
  +   <META NAME="GENERATOR" CONTENT="Pod2HTML [Perl/Linux]">
  +   <META NAME="Author" CONTENT="Stas Bekman">
  +   <META NAME="Description" CONTENT="All Apache/Perl related information: Hints, Guidelines, Scenarios and Troubleshottings">
  +   <META NAME="keywords" CONTENT="mod_perl modperl perl apache cgi webserver speed  fast guide mod_perl apache guide help info faq mod_perl installation cgi troubleshooting help no sex speedup free open source OSS mod_perl apache guide">
  +</HEAD>
  +     <LINK REL=STYLESHEET TYPE="text/css"
  +        HREF="style.css" TITLE="refstyle">
  +     <style type="text/css">
  +     <!-- 
  +        @import url(style.css);
  +     -->
  +     
  +     </style>
  +<BODY TEXT="#000000" BGCOLOR="#E0FFFF" LINK="#0000EE" VLINK="#551A8B" ALINK="#FF0000">
  +<A NAME="toc"></A>
  +<H1 ALIGN=CENTER>
  +<A HREF="http://perl.apache.org"><IMG SRC="images/mod_perl.gif" ALT="Mod Perl Icon" BORDER=0 HEIGHT=30 WIDTH=90 ALIGN=LEFT></A>
  +<A HREF="http://perl.apache.org"><IMG SRC="images/mod_perl.gif" ALT="Mod Perl Icon" BORDER=0 HEIGHT=30 WIDTH=90 ALIGN=RIGHT></A>
  +Controlling and Monitoring the Server</H1>
  +<HR WIDTH="100%">
  +	    [    <A HREF="frequent.html">Prev</A> |      <A HREF="index.html">Main Page</A> | <A HREF="obvious.html">Next</A>      ]<HR><!-- INDEX BEGIN -->
  +<P><B><FONT SIZE=-1>Table of Contents:</FONT></B></P>
  +<UL>
   
  -<P>
  -<PRE>  Value of $x will not stay shared at - line 5.
  -</PRE>
  -<P>
  -NOTE: Subroutines defined inside <STRONG>BEGIN{}</STRONG> and <STRONG>END{}</STRONG> cannot trigger this message, since each <STRONG>BEGIN{}</STRONG> and <STRONG>END{}</STRONG> is defined to be called exactly once. (To understand why, read about the
  -closures at
  -<CODE>perlref</CODE> or <CODE>perlfaq</CODE> 13.12)
  +	<LI><A HREF="#Restarting_techniques">Restarting techniques</A>
  +	<LI><A HREF="#Implications_of_sending_TERM_HU">Implications of sending TERM, HUP, and USR1 to the server</A>
  +	<LI><A HREF="#Using_apachectl_to_control_the_s">Using apachectl to control the server</A>
  +	<LI><A HREF="#SUID_start_up_scripts">SUID start-up scripts</A>
  +	<LI><A HREF="#Monitoring_the_Server_A_watchdo">Monitoring the Server. A watchdog.</A>
  +	<LI><A HREF="#Running_server_in_a_single_mode">Running server in a single mode</A>
  +	<LI><A HREF="#Starting_a_personal_server_for_e">Starting a personal server for each developer</A>
  +	<LI><A HREF="#Wrapper_to_emulate_the_server_en">Wrapper to emulate the server environment</A>
  +	<LI><A HREF="#Log_Rotation">Log Rotation</A>
  +	<LI><A HREF="#Preventing_from_modperl_process_">Preventing from modperl process from going wild</A>
  +</UL>
  +<!-- INDEX END -->
   
  -<P>
  -PERLDIAG manpage says:
  +<HR>
   
  -<P>
  -<PRE>  An inner (nested) named subroutine is referencing a lexical variable
  -  defined in an outer subroutine.
  -</PRE>
  -<P>
  -When the inner subroutine is called, it will probably see the value of the
  -outer subroutine's variable as it was before and during the *first* call to
  -the outer subroutine; in this case, after the first call to the outer
  -subroutine is complete, the inner and outer subroutines will no longer
  -share a common value for the variable. In other words, the variable will no
  -longer be shared.
  +	     The <a href="http://www.modperl.com/">
  +	     <B>Writing Apache Modules with Perl and C</B></a>
  +	     book can be purchased online from <a
  +	     href="http://www.ora.com/catalog/wrapmod/">O'Reilly </a>
  +	     and <a
  +	     href="http://www.amazon.com/exec/obidos/ASIN/156592567X/writinapachemodu">
  +	     Amazon.com</a>.
   
  -<P>
  -Check your code by running Apache in single-child mode (httpd -X). Since
  -the value of a my variable retain its initial value <CODE>per
  -child process</CODE>, the closure problem can be difficult to track down in multi-user mode. It
  -will appear to work fine until you have cycled through all the httpd
  -children.
  +	     <HR>
   
  +	      <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
   <P>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<CENTER><H2><A NAME="The_remedy">The remedy</A></H2></CENTER>
  +<CENTER><H1><A NAME="Restarting_techniques">Restarting techniques</A></H1></CENTER>
   <P>
  -If a variable needs file scope, use a global variable:
  +All of these techniques require that you know the server PID (Process ID).
  +The easiest way to find the PID is to look it up in the httpd.pid file.
  +With my configuration it exists as
  +<CODE>/usr/apps/var/httpd_perl/run/httpd.pid</CODE>. It's easy to discover where to look at, by checking out the httpd.conf
  +file. Open the file and locate the entry <CODE>PidFile</CODE>:
   
   <P>
  -<PRE>    use vars qw/$x/;
  -    use CGI qw/param/;
  -    $x = param('x');
  -    sub printit {
  -       print &quot;$x\n&quot;;
  -    }
  +<PRE>  PidFile /usr/apps/var/httpd_perl/run/httpd.pid
   </PRE>
   <P>
  -You can safely use a <CODE>my()</CODE> scoped variable if its value is constant:
  +Another way is to use the <CODE>ps</CODE> and <CODE>grep</CODE> utilities:
   
   <P>
  -<PRE>    use vars qw/$x/;
  -    use CGI qw/param/;
  -    $x = param('x');
  -    my $y = 5;
  -    sub printit {
  -       print &quot;$x, $y\n&quot;;
  -    }
  +<PRE>  % ps auxc | grep httpd_perl
   </PRE>
   <P>
  -Also see the clarification of <CODE>my()</CODE> vs. <CODE>use vars</CODE> - Ken Williams writes:
  +or maybe:
   
   <P>
  -<PRE>  Yes, there is quite a bit of difference!  With use vars(), you are
  -  making an entry in the symbol table, and you are telling the
  -  compiler that you are going to be referencing that entry without an
  -  explicit package name.
  -  
  -  With my(), NO ENTRY IS PUT IN THE SYMBOL TABLE.  The compiler
  -  figures out _at_ _compile_time_ which my() variables (i.e. lexical
  -  variables) are the same as each other, and once you hit execute time
  -  you can not go looking those variables up in the symbol table.
  +<PRE>  % ps -ef | grep httpd_perl
   </PRE>
   <P>
  -And <CODE>my()</CODE> vs. <CODE>local()</CODE> - Randal Schwartz writes:
  +This will produce a list of all httpd_perl (the parent and the children)
  +processes. You are looking for the parent process. If you run your server
  +as root - you will easily locate it, since it belongs to root. If you run
  +the server as user (when you <A HREF="././install.html#Is_it_possible_to_install_and_us">don't have a root access</A>, most likely all the processes will belong to that user (unless defined
  +differently in the
  +<CODE>httpd.conf</CODE>), but it's still easy to know 'who is the parent' -- the one of the
  +smallest size...
   
   <P>
  -<PRE>  local() creates a temporal-limited package-based scalar, array,
  -  hash, or glob -- when the scope of definition is exited at runtime,
  -  the previous value (if any) is restored.  References to such a
  -  variable are *also* global... only the value changes.  (Aside: that
  -  is what causes variable suicide. :)
  -  
  -  my() creates a lexically-limited non-package-based scalar, array, or
  -  hash -- when the scope of definition is exited at compile-time, the
  -  variable ceases to be accessible.  Any references to such a variable
  -  at runtime turn into unique anonymous variables on each scope exit.
  -</PRE>
  +You will notice many httpd_perl executables running on your system, but you
  +should not send signals to any of them except the parent, whose pid is in
  +the <CODE>PidFile</CODE>. That is to say you shouldn't ever need to send signals to any process
  +except the parent. There are three signals that you can send the parent: <STRONG>TERM</STRONG>, <STRONG>HUP</STRONG>, and <STRONG>USR1</STRONG>.
  +
   <P>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<CENTER><H2><A NAME="Additional_reading_references">Additional reading references</A></H2></CENTER>
  +<CENTER><H1><A NAME="Implications_of_sending_TERM_HU">Implications of sending TERM, HUP, and USR1 to the server</A></H1></CENTER>
   <P>
  -For more information see: <A HREF="././perl.html#Using_global_variables_and_shari">Using global variables and sharing them between modules/packages</A> and an article by Mark-Jason Dominus about how Perl handles variables and
  -namespaces, and the difference between `use vars' and `my' - <A
  -HREF="http://www.plover.com/~mjd/perl/FAQs/Namespaces.html">http://www.plover.com/~mjd/perl/FAQs/Namespaces.html</A>
  +We will concentrate here on the implications of sending these signals to a
  +mod_perl enabled server. For documentation on the implications of sending
  +these signals to a plain Apache server see <A
  +HREF="http://www.apache.org/docs/stopping.html">http://www.apache.org/docs/stopping.html</A>
   .
   
  -<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>
  +<DL>
  +<P><DT><STRONG><A NAME="item_TERM">TERM Signal: stop now</A></STRONG><DD>
   <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.
  +Sending the <STRONG>TERM</STRONG> signal to the parent causes it to immediately attempt to kill off all of
  +its children. This process may take several seconds to complete, following
  +which the parent itself exits. Any requests in progress are terminated, and
  +no further requests are served.
   
   <P>
  -The situation is different with Apache::Registry, 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
  -<STRONG>use</STRONG>/<STRONG>require</STRONG>-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 <STRONG>use</STRONG> (or <STRONG>require</STRONG>) 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 <STRONG>use()</STRONG> or <STRONG>require()</STRONG> aren't being checked to see if they have been modified.
  +That's the moment that the accumulated <CODE>END</CODE> blocks will be executed! Note that if you use <CODE>Apache::Registry</CODE> or <CODE>Apache::PerlRun</CODE>, then
  +<CODE>END</CODE> blocks are being executed upon each request (at the end).
   
  +<P><DT><STRONG><A NAME="item_HUP">HUP Signal: restart now</A></STRONG><DD>
   <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:
  +Sending the <STRONG>HUP</STRONG> signal to the parent causes it to kill off its children like in <STRONG>TERM</STRONG> (Any requests in progress are terminated) but the parent doesn't exit. It
  +re-reads its configuration files, and re-opens any log files. Then it
  +spawns a new set of children and continues serving hits.
   
   <P>
  -<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>
  +The server will reread its configuration files, flush all the compiled and
  +preloaded modules, and rerun any startup files. It's equivalent to
  +stopping, then restarting a server.
  +
   <P>
  -See <A HREF="././control.html#Restarting_techniques">Server Restarting techniques</A>.
  +Note: If your configuration file has errors in it when you issue a restart
  +then your parent will not restart but exit with an error. See below for a
  +method of avoiding this.
   
  +<P><DT><STRONG><A NAME="item_USR1">USR1 Signal: graceful restart</A></STRONG><DD>
   <P>
  -<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>
  +The <STRONG>USR1</STRONG> signal causes the parent process to advise the children to exit after their
  +current request (or to exit immediately if they're not serving anything).
  +The parent re-reads its configuration files and re-opens its log files. As
  +each child dies off the parent replaces it with a child from the new
  +generation of the configuration, which begins serving new requests
  +immediately. 
  +
   <P>
  -After restarting the server about 100 times, you will be tired and will
  -look for another solutions. Help comes from the Apache::StatINC module. 
  +The only difference between <STRONG>USR1</STRONG> and <STRONG>HUP</STRONG> is that <STRONG>USR1</STRONG> allows children to complete any in-progress request prior to killing them
  +off.
   
   <P>
  -Read its pod pages, but beware of the following note: Only the modules
  -located in <STRONG>@INC</STRONG> are being reloaded on change, and you can change the <STRONG>@INC</STRONG> only before the server has been started. Whatever you do in your
  -scripts/modules which are being <CODE>required()</CODE> after the server
  -startup will not have any effect on <STRONG>@INC</STRONG>.
  -
  -<P>
  -When you do <STRONG>use lib qw(foo/bar);</STRONG>, the <STRONG>@INC</STRONG> is being changed only for the time the code is being parsed. When it's over
  -the <STRONG>@INC</STRONG> is being reset to its original value. To make sure that you have set a
  -correct <STRONG>@INC</STRONG> fetch <A
  -HREF="http://your.perl.server/perl-status?inc">http://your.perl.server/perl-status?inc</A>
  -and watch the bottom of the page. (I assume you have configured the
  -&lt;Location /perl-status&gt; section in httpd.conf as the mod_perl docs
  -show.)
  +By default, if a server is restarted (ala <CODE>kill -USR1 `cat
  +logs/httpd.pid`</CODE> or with <STRONG>HUP</STRONG> signal), Perl scripts and modules are not reloaded. To reload <STRONG>PerlRequire</STRONG>'s, <STRONG>PerlModule</STRONG>'s, other
  +<CODE>use()</CODE>'d modules and flush the <CODE>Apache::Registry</CODE> cache, enable with this command:
   
   <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>
  +<PRE> PerlFreshRestart On              (in httpd.conf) 
  +</PRE>
   <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.
  +Make sure you read <A HREF="././warnings.html#Evil_things_might_happen_when_us">Evil things might happen when using PerlFreshRestart</A>.
   
  +</DL>
   <P>
  -Assuming that you start your script with loading <CODE>Foo::Bar</CODE> and importing some tags:
  +It's worth mentioning that restart or termination can sometimes take quite
  +a lot of time. Check out the <CODE>PERL_DESTRUCT_LEVEL=-1</CODE> option during the mod_perl <CODE>./Configure</CODE> stage, which speeds this up and leads to more robust operation in the face
  +of problems, like running out of memory. It is only usable if no
  +significant cleanup has to be done by perl <CODE>END</CODE> blocks and <CODE>DESTROY</CODE> methods when the child terminates, of course. What constitutes significant
  +cleanup? Any change of state outside of the current process that would not
  +be handled by the operating system itself. So committing database
  +transactions is significant but closing an ordinary file isn't.
   
  -<P>
  -<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:
  +Some folks prefer to specify signals using numerical values, rather than
  +symbolics. If you are looking for these, check out your
  +<CODE>kill(3)</CODE> man page. My page points to <CODE>/usr/include/sys/signal.h</CODE>, the relevant entries are:
   
   <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>  #define SIGHUP     1    /* hangup, generated when terminal disconnects */ 
  +  #define SIGTERM   15    /* software termination signal */
  +  #define SIGUSR1   30    /* user defined signal 1 */
   </PRE>
   <P>
  -You may want to add debug print statements to debug this code in your
  -application.
  +<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<CENTER><H1><A NAME="Using_apachectl_to_control_the_s">Using apachectl to control the server</A></H1></CENTER>
  +<P>
  +Apache's distribution provides a nice script to control the server. It's
  +called <STRONG>apachectl</STRONG> and it's installed into the same location with httpd. In our scenario -
  +it's
  +<CODE>/usr/apps/sbin/httpd_perl/apachectl</CODE>.
   
   <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>
  -)
  +Start httpd:
   
   <P>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<CENTER><H1><A NAME="Compiled_Regular_Expressions">Compiled Regular Expressions</A></H1></CENTER>
  +<PRE>        % /usr/apps/sbin/httpd_perl/apachectl start 
  +</PRE>
   <P>
  -When using a regular expression that contains an interpolated Perl
  -variable, if it is known that the variable (or variables) will not vary
  -during the execution of the program, a standard optimization technique
  -consists of adding the <STRONG>/o</STRONG> modifier to the regexp pattern. This directs the compiler to build the
  -internal table once, for the entire lifetime of the script, rather than
  -every time the pattern is executed. Consider:
  +Stop httpd:
   
   <P>
  -<PRE>  my $pat = '^foo$'; # likely to be input from an HTML form field
  -  foreach( @list ) {
  -    print if /$pat/o;
  -  }
  +<PRE>        % /usr/apps/sbin/httpd_perl/apachectl stop
   </PRE>
   <P>
  -This is usually a big win in loops over lists, or when using
  -<STRONG>grep</STRONG> or <STRONG>map</STRONG>. 
  +Restart httpd if running by sending a <STRONG>SIGHUP</STRONG> or start if not running:
   
   <P>
  -In long-lived mod_perl scripts, however, this can pose a problem if the
  -variable changes according to the invocation. The first invocation of a
  -fresh httpd child will compile the regex and perform the search correctly.
  -However, all subsequent uses by the httpd child will continue to match the
  -original pattern, regardless of the current contents of the Perl variables
  -the pattern is dependent on. Your script will appear broken.
  -
  +<PRE>        % /usr/apps/sbin/httpd_perl/apachectl restart
  +</PRE>
   <P>
  -There are two solutions to this problem. 
  +Do a graceful restart by sending a <STRONG>SIGUSR1</STRONG> or start if not running:
   
   <P>
  -The first is to use <STRONG>eval q//</STRONG>, to force the code to be evaluated each time. Just make sure that the eval
  -block covers the entire loop of processing, and not just the pattern match
  -itself.
  -
  +<PRE>        % /usr/apps/sbin/httpd_perl/apachectl graceful    
  +</PRE>
   <P>
  -The above code fragment would be rewritten as: 
  +Do a configuration syntax test:
   
   <P>
  -<PRE>  my $pat = '^foo$';
  -  eval q{
  -    foreach( @list ) {
  -      print if /$pat/o;
  -    }
  -  }
  +<PRE>        % /usr/apps/sbin/httpd_perl/apachectl configtest 
   </PRE>
  +<P>
  +See the next section for the implication of the above calls.
  +
   <P>
  -Just saying:
  +Replace <CODE>httpd_perl</CODE> with <CODE>httpd_docs</CODE> in the above calls to control the <STRONG>httpd_docs</STRONG> server.
   
   <P>
  -<PRE>  eval q{ print if /$pat/o; };
  -</PRE>
  +There are other options for <STRONG>apachectl</STRONG>, use <CODE>help</CODE> option to see them all.
  +
   <P>
  -is going to be a horribly expensive proposition. 
  +It's important to understand that this script is based on the PID file
  +which is <CODE>PIDFILE=/usr/apps/var/httpd_perl/run/httpd.pid</CODE>. If you delete the file by hand - <STRONG>apachectl</STRONG> will fail to run.
   
   <P>
  -You can use this approach if you require more than one pattern match
  -operator in a given section of code. If the section contains only one
  -operator (be it an <STRONG>m//</STRONG> or <STRONG>s///</STRONG>), you can rely on the property of the null pattern, that reuses the last
  -pattern seen. This leads to the second solution, which also eliminates the
  -use of eval.
  +Also, notice that <STRONG>apachectl</STRONG> is suitable to use from within your Unix system's startup files so that
  +your web server is automatically restarted upon system reboot. Either copy
  +the <STRONG>apachectl</STRONG> file to the appropriate location (<CODE>/etc/rc.d/rc3.d/S99apache</CODE> works on my RedHat Linux system) or create a symlink with that name
  +pointing to the the canonical location. (If you do this, make certain that
  +the script is writable only by root -- the startup scripts have root
  +privileges during init processing, and you don't want to be opening any
  +security holes.)
   
   <P>
  -The above code fragment becomes: 
  +<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<CENTER><H1><A NAME="SUID_start_up_scripts">SUID start-up scripts</A></H1></CENTER>
  +<P>
  +For those who wants to use <STRONG>SUID</STRONG> startup script, here is an example for you. This script is <STRONG>SUID</STRONG> to <STRONG>root</STRONG>, and should be executable only by members of some special group at your
  +site. Note the 10th line, which ``fixes an obscure error when starting
  +apache/mod_perl'' by setting the real to the effective UID. As others have
  +pointed out, it is the mismatch between the real and the effective UIDs
  +that causes Perl to croak on the -e switch.
   
   <P>
  -<PRE>  my $pat = '^foo$';
  -  &quot;something&quot; =~ /$pat/; # dummy match (MUST NOT FAIL!)
  -  foreach( @list ) {
  -    print if //;
  -  }
  +Note that you must be using a version of Perl that recognizes and emulates
  +the suid bits in order for this to work. The script will do different
  +things depending on whether it is named <CODE>start_http</CODE>,
  +<CODE>stop_http</CODE> or <CODE>restart_http</CODE>. You can use symbolic links for this purpose.
  +
  +<P>
  +<PRE> #!/usr/bin/perl
  + 
  + # These constants will need to be adjusted.
  + $PID_FILE = '/home/www/logs/httpd.pid';
  + $HTTPD = '/home/www/httpd -d /home/www';
  + 
  + # These prevent taint warnings while running suid
  + $ENV{PATH}='/bin:/usr/bin';
  + $ENV{IFS}='';
  + 
  + # This sets the real to the effective ID, and prevents
  + # an obscure error when starting apache/mod_perl
  + $&lt; = $&gt;;
  + $( = $) = 0; # set the group to root too
  + 
  + # Do different things depending on our name
  + ($name) = $0 =~ m|([^/]+)$|;
  + 
  + if ($name eq 'start_http') {
  +     system $HTTPD and die &quot;Unable to start HTTP&quot;;
  +     print &quot;HTTP started.\n&quot;;
  +     exit 0;
  + }
  + 
  + # extract the process id and confirm that it is numeric
  + $pid = `cat $PID_FILE`;
  + $pid =~ /(\d+)/ or die &quot;PID $pid not numeric&quot;;
  + $pid = $1;
  + 
  + if ($name eq 'stop_http') {
  +     kill 'TERM',$pid or die &quot;Unable to signal HTTP&quot;;
  +     print &quot;HTTP stopped.\n&quot;;
  +     exit 0;
  + }
  + 
  + if ($name eq 'restart_http') {
  +     kill 'HUP',$pid or die &quot;Unable to signal HTTP&quot;;
  +     print &quot;HTTP restarted.\n&quot;;
  +     exit 0;
  + }
  + 
  + die &quot;Script must be named start_http, stop_http, or restart_http.\n&quot;;
   </PRE>
   <P>
  -The only gotcha is that the dummy match that boots the regular expression
  -engine must absolutely, positively succeed, otherwise the pattern will not
  -be cached, and the <STRONG>//</STRONG> will match everything. If you can't count on fixed text to ensure the match
  -succeeds, you have two possibilities.
  +<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<CENTER><H1><A NAME="Monitoring_the_Server_A_watchdo">Monitoring the Server. A watchdog.</A></H1></CENTER>
  +<P>
  +With mod_perl many things can happen to your server. The worst one is the
  +possibility that the server will die when you will be not around. As with
  +any other critical service you need to run some kind of watchdog.
   
   <P>
  -If you can guarantee that the pattern variable contains no meta-characters
  -(things like *, +, ^, $...), you can use the dummy match:
  +One simple solution is to use a slightly modified <STRONG>apachectl</STRONG> script which I called apache.watchdog and to put it into the crontab to be
  +called every 30 minutes or even every minute - if it's so critical to make
  +sure the server will be up all the time.
   
   <P>
  -<PRE>  &quot;$pat&quot; =~ /\Q$pat\E/; # guaranteed if no meta-characters present
  +The crontab entry:
  +
  +<P>
  +<PRE>  0,30 * * * * /path/to/the/apache.watchdog &gt;/dev/null 2&gt;&amp;1
   </PRE>
   <P>
  -If there is a possibility that the pattern can contain meta-characters, you
  -should search for the pattern or the unsearchable \377 character as
  -follows:
  +The script:
   
   <P>
  -<PRE>  &quot;\377&quot; =~ /$pat|^[\377]$/; # guaranteed if meta-characters present
  +<PRE>  #!/bin/sh
  +    
  +  # this script is a watchdog to see whether the server is online
  +  # It tries to restart the server if it's
  +  # down and sends an email alert to admin 
  +  
  +  # admin's email
  +  EMAIL=webmaster@somewhere.far
  +  #EMAIL=root@localhost
  +    
  +  # the path to your PID file
  +  PIDFILE=/usr/apps/var/httpd_perl/run/httpd.pid
  +    
  +  # the path to your httpd binary, including options if necessary
  +  HTTPD=/usr/apps/sbin/httpd_perl/httpd_perl
  +        
  +  # check for pidfile
  +  if [ -f $PIDFILE ] ; then
  +    PID=`cat $PIDFILE`
  +    
  +    if kill -0 $PID; then
  +      STATUS=&quot;httpd (pid $PID) running&quot;
  +      RUNNING=1
  +    else
  +      STATUS=&quot;httpd (pid $PID?) not running&quot;
  +      RUNNING=0
  +    fi
  +  else
  +    STATUS=&quot;httpd (no pid file) not running&quot;
  +    RUNNING=0
  +  fi
  +      
  +  if [ $RUNNING -eq 0 ]; then
  +    echo &quot;$0 $ARG: httpd not running, trying to start&quot;
  +    if $HTTPD ; then
  +      echo &quot;$0 $ARG: httpd started&quot;
  +      mail $EMAIL -s &quot;$0 $ARG: httpd started&quot; &lt;/dev/null &gt;&amp; /dev/null
  +    else
  +      echo &quot;$0 $ARG: httpd could not be started&quot;
  +      mail $EMAIL -s &quot;$0 $ARG: httpd could not be started&quot; &lt;/dev/null &gt;&amp; /dev/null
  +    fi
  +  fi
   </PRE>
   <P>
  -Phil. Chu contributed this:
  +Another approach, probably even more practical, is to use the cool
  +<CODE>LWP</CODE> perl package , to test the server by trying to fetch some document (script)
  +served by the server. Why is it more practical? While server can be up as a
  +process, it can be stuck and not working, So failing to get the document
  +will trigger restart, and ``probably'' the problem will go away. (Just
  +replace <CODE>start</CODE> with <CODE>restart</CODE> in the <CODE>$restart_command</CODE> below.
   
   <P>
  -It depends on the complexity of the regexp you apply this technique to. One
  -common usage where compiled regexp is usually more efficient is to ``match
  -any one of a group of patterns'' over and over again.
  +Again we put this script into a crontab to call it every 30 minutes.
  +Personally I call it every minute, to fetch some very light script. Why so
  +often? If your server starts to spin and trash your disk's space with
  +multiply error messages. In a 5 minutes you might run out of free space,
  +which might bring your system to its knees. And most chances that no other
  +child will be able to serve requests, since the system will be too busy,
  +writing to an <CODE>error_log</CODE> file. Think big - if you running a heavy service, which is very fast, since
  +you are running under mod_perl, adding one more request every minute, will
  +be not felt by the server at all.
   
   <P>
  -Maybe with some helper routine, it's easier to remember. Here is one
  -slightly modified from Jeffery Friedl's example in his book ``Mastering
  -Regex.''. I find it quite useful:
  +So we end up with crontab entry:
   
   <P>
  -<PRE>  #####################################################
  -  # Build_MatchMany_Function
  -  # -- Input:  list of patterns
  -  # -- Output: A code ref which matches its $_[0]
  -  #            against ANY of the patterns given in the
  -  #            &quot;Input&quot;, efficiently.
  -  #
  -  sub Build_MatchMany_Function {
  -    my @R = @_;
  -    my $expr = join '||', map { &quot;\$_[0] =~ m/\$R[$_]/o&quot; } ( 0..$#R );
  -    my $matchsub = eval &quot;sub { $expr }&quot;;
  -    die &quot;Failed in building regex @R: $@&quot; if $@;
  -    $matchsub;
  -  }
  +<PRE>  * * * * * /path/to/the/watchdog.pl &gt;/dev/null 2&gt;&amp;1
   </PRE>
   <P>
  -Example usage:
  +And the watchdog itself:
   
  -<P>
  -<PRE>  @some_browsers = qw(Mozilla Lynx MSIE AmigaVoyager lwp libwww);
  -  $Known_Browser=Build_MatchMany_Function(@some_browsers);
  -</PRE>
   <P>
  -<PRE>  while (&lt;ACCESS_LOG&gt;) {
  -    # ...
  -    $browser = get_browser_field($_);
  -    if ( ! &amp;$Known_Browser($browser) ) {
  -      print STDERR &quot;Unknown Browser: $browser\n&quot;;
  -    }
  -    # ...
  -  }
  +<PRE>  #!/usr/local/bin/perl -w
  +  
  +  use strict;
  +  use diagnostics;
  +  use URI::URL;
  +  use LWP::MediaTypes qw(media_suffix);
  +  
  +  my $VERSION = '0.01';
  +  use vars qw($ua $proxy);
  +  
  +  require LWP::UserAgent;
  +  use HTTP::Status;
  +  
  +  ###### Config ########
  +  my $test_script_url = '<A HREF="http://www.stas.com:81/perl/test.pl">http://www.stas.com:81/perl/test.pl</A>';
  +  my $monitor_email   = 'root@localhost';
  +  my $restart_command = '/usr/apps/sbin/httpd_perl/apachectl start';
  +  my $mail_program    = '/usr/lib/sendmail -t -n';
  +  ######################
  +  
  +  $ua  = new LWP::UserAgent;
  +  $ua-&gt;agent(&quot;$0/Stas &quot; . $ua-&gt;agent);
  +  # Uncomment the proxy if you don't use it!
  +  #  $proxy=&quot;<A HREF="http://www-proxy.com&quot">http://www-proxy.com&quot</A>;;
  +  $ua-&gt;proxy('http', $proxy) if $proxy;
  +  
  +  # If returns '1' it's we are alive
  +  exit 1 if checkurl($test_script_url);
  +  
  +  # We have got the problem - the server seems to be down. Try to
  +  # restart it. 
  +  my $status = system $restart_command;
  +  #  print &quot;Status $status\n&quot;;
  +  
  +  my $message = ($status == 0) 
  +              ? &quot;Server was down and successfully restarted!&quot; 
  +              : &quot;Server is down. Can't restart.&quot;;
  +    
  +  my $subject = ($status == 0) 
  +              ? &quot;Attention! Webserver restarted&quot;
  +              : &quot;Attention! Webserver is down. can't restart&quot;;
  +  
  +  # email the monitoring person
  +  my $to = $monitor_email;
  +  my $from = $monitor_email;
  +  send_mail($from,$to,$subject,$message);
  +  
  +  # input:  URL to check 
  +  # output: 1 if success, o for fail  
  +  #######################  
  +  sub checkurl{
  +    my ($url) = @_;
  +  
  +    # Fetch document 
  +    my $res = $ua-&gt;request(HTTP::Request-&gt;new(GET =&gt; $url));
  +  
  +    # Check the result status
  +    return 1 if is_success($res-&gt;code);
  +  
  +    # failed
  +    return 0;
  +  } #  end of sub checkurl
  +  
  +  # sends email about the problem 
  +  #######################  
  +  sub send_mail{
  +    my($from,$to,$subject,$messagebody) = @_;
  +  
  +    open MAIL, &quot;|$mail_program&quot;
  +        or die &quot;Can't open a pipe to a $mail_program :$!\n&quot;;
  +   
  +    print MAIL &lt;&lt;__END_OF_MAIL__;
  +  To: $to
  +  From: $from
  +  Subject: $subject
  +  
  +  $messagebody
  +  
  +  __END_OF_MAIL__
  +  
  +    close MAIL;
  +  } 
   </PRE>
   <P>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<CENTER><H1><A NAME="Debugging_your_code_in_Single_Se">Debugging your code in Single Server Mode</A></H1></CENTER>
  -<P>
  -Running in httpd -X mode. (good only for testing during development phase).
  -
  +<CENTER><H1><A NAME="Running_server_in_a_single_mode">Running server in a single mode</A></H1></CENTER>
   <P>
  -You want to test that your application correctly handles global variables
  -(if you have any - the less you have of them the better, but sometimes you
  -just can't without them). It's hard to test with multiple servers serving
  -your cgi since each child has a different value for its global variables.
  -Imagine that you have a <CODE>random()</CODE> sub that returns a random
  -number and you have the following script.
  +Often while developing new code, you will want to run the server in single
  +process mode. See <A HREF="././porting.html#Sometimes_it_Works_Sometimes_it_">Sometimes it works Sometimes it does Not</A> and <A HREF="././porting.html#Name_collisions_with_Modules_and">Names collisions with Modules and libs</A>
  +Running in single process mode inhibits the server from ``daemonizing'',
  +allowing you to run it more easily under debugger control.
   
   <P>
  -<PRE>  use vars qw($num);
  -  $num ||= random();
  -  print ++$num;
  +<PRE>  % /usr/apps/sbin/httpd_perl/httpd_perl -X
   </PRE>
  -<P>
  -This script initializes the variable <STRONG>$num</STRONG> with a random value, then increments it on each request and prints it out.
  -Running this script in multiple server environments will result in
  -something like 1,9,4,19 (number per reload), since each time your script
  -will be served by a different child. (On some OSes, the parent httpd
  -process will assign all of the requests to the same child process if all of
  -the children are idle... AIX...). But if you run in httpd -X single server
  -mode you will get 2,3,4,5... (taken that the <CODE>random()</CODE> returned
  -1 at the first call)
  -
   <P>
  -But do not get too obsessive with this mode, since working only in single
  -server mode sometimes hides problems that show up when you switch to multi
  -server mode. Consider an application that allows you to change the
  -configuration at run time.
  -
  -<P>
  -Let's say the script produces a form to change the background color of the
  -page. It's not a good design, but for the sake of demonstrating the
  -potential problem, we will assume that our script doesn't write the changed
  -background color to the disk, but simply changes it in memory.
  -
  -<P>
  -So you have typed in a new color, and in response, your script prints back
  -the html with a new color - you think that's it! It was so simple. And if
  -you keep running in single server mode you will never notice that you have
  -a problem...
  +When you execute the above the server will run in the fg (foreground) of
  +the shell you have called it from. So to kill you just kill it with
  +<STRONG>Ctrl-C</STRONG>.
   
   <P>
  -If you run the same code in the multi server environment, after you submit
  -the color change you will get the result as expected, but when you will
  -call the same URL again (not reload!) chances are that you will get back
  -the old color, since except the child who processed the color change
  -request no one knows about their global variable change. Just remember that
  -children can't share information, other than that which they inherited from
  -their parent on their load.
  +Note that in <CODE>-X</CODE> mode the server will run very slowly while fetching images. If you use
  +Netscape while your server is running in single-process mode, HTTP's <CODE>KeepAlive</CODE> feature gets in the way. Netscape tries to open multiple connections and
  +keep them open. Because there is only one server process listening, each
  +connection has to time-out before the next succeeds. Turn off
  +<CODE>KeepAlive</CODE> in <CODE>httpd.conf</CODE> to avoid this effect while developing or you can press <STRONG>STOP</STRONG> after a few seconds (assuming you use the image size params, so the
  +Netscape will be able to render the rest of the page).
   
   <P>
  -Also note that since the server is running in single mode, if the output
  -returns HTML with IMG tags, then the load of these will take a lot of time
  -(read apache docs of httpd -X to learn why).
  +In addition you should know that when running with <CODE>-X</CODE> you will not see any control messages that the parent server normally
  +writes to the error_log. (Like ``server started, server stopped and etc''.)
  +Since
  +<CODE>httpd -X</CODE> causes the server to handle all requests itself, without forking any
  +children, there is no controlling parent to write status messages.
   
   <P>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<CENTER><H1><A NAME="_M_and_other_time_file_tests_u">-M and other time() file tests under mod_perl</A></H1></CENTER>
  +<CENTER><H1><A NAME="Starting_a_personal_server_for_e">Starting a personal server for each developer</A></H1></CENTER>
   <P>
  -Under mod_perl, files that have been created after the server's (child?)
  -startup are being reported with negative age with -M (-C -A) test. This is
  -obvious if you remember that you will get the negative result if the server
  -was started before the file was created and it's a normal behavior with any
  -perl.
  +If you are the only developer working on the specific server:port - you
  +have no problems, since you have a complete control over the server.
  +However, many times you have a group of developers who need to concurrently
  +develop their own mod_perl scripts. This means that each one will want to
  +have control over the server - to kill it, to run it in single server mode,
  +to restart it again, etc., as well to have control over the location of the
  +log files and other configuration settings like <STRONG>MaxClients</STRONG>, etc. You can work around this problem by preparing a few httpd.conf file
  +and forcing each developer to use:
   
   <P>
  -If you want to have -M test to count the time relative to the current
  -request, you should reset the $^T variable as with any other perl script.
  -Just add <CODE>$^T = time;</CODE> at the beginning of the scripts.
  +<PRE>  httpd_perl -f /path/to/httpd.conf  
  +</PRE>
  +<P>
  +I have approached it in other way. I have used the <CODE>-Dparameter</CODE>
  +startup option of the server. I call my version of the server
   
   <P>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<CENTER><H1><A NAME="Handling_the_User_pressed_Stop_">Handling the 'User pressed Stop button' case</A></H1></CENTER>
  +<PRE>  % http_perl -Dsbekman
  +</PRE>
   <P>
  -When a user presses the stop button, Apache will detect that via
  -SIG{'PIPE'} and will cease the script execution. When we are talking about
  -mod_cgi, there is generally no problem, since all opened files will be
  -closed and all the resources will be freed (almost all -- if you happened
  -to use external lock files, most likely the resources that are being locked
  -by these will be left blocked and non-usable by any others who use this
  -advisory locking scheme.)
  +In <CODE>httpd.conf</CODE> I wrote:
   
  +<P>
  +<PRE>  # Personal development Server for sbekman
  +  # sbekman use the server running on port 8000
  +  &lt;IfDefine sbekman&gt;
  +  Port 8000
  +  PidFile /usr/apps/var/httpd_perl/run/httpd.pid.sbekman
  +  ErrorLog /usr/apps/var/httpd_perl/logs/error_log.sbekman
  +  Timeout 300
  +  KeepAlive On
  +  MinSpareServers 2
  +  MaxSpareServers 2
  +  StartServers 1
  +  MaxClients 3
  +  MaxRequestsPerChild 15
  +  &lt;/IfDefine&gt;
  +  
  +  # Personal development Server for userfoo
  +  # userfoo use the server running on port 8001
  +  &lt;IfDefine userfoo&gt;
  +  Port 8001
  +  PidFile /usr/apps/var/httpd_perl/run/httpd.pid.userfoo
  +  ErrorLog /usr/apps/var/httpd_perl/logs/error_log.userfoo
  +  Timeout 300
  +  KeepAlive Off
  +  MinSpareServers 1
  +  MaxSpareServers 2
  +  StartServers 1
  +  MaxClients 5
  +  MaxRequestsPerChild 0
  +  &lt;/IfDefine&gt;
  +</PRE>
   <P>
  -Important to notice that when the user hits ``stop'' on the browser, the
  -mod_perl script is blissfully unaware until it tries to send some data to
  -the browser. At that point, Apache realizes that the browser is gone, and
  -all the good cleanup stuff happens.
  +What we have achieved with this technique: Full control over start/stop,
  +number of children, separate error log file, and port selection. This saves
  +me from getting called every few minutes - ``Stas, I'm going to restart the
  +server''.
   
   <P>
  -Starting from apache 1.3.6 apache will not catch SIGPIPE anymore and
  -modperl will do it much better. Here is something from CHANGES from Apache
  -1.3.6.
  +To make things even easier. (In the above technique, you have to discover
  +the PID of your parent httpd_perl process - written in
  +<CODE>/usr/apps/var/httpd_perl/run/httpd.pid.userfoo</CODE>) . We change the
  +<STRONG>apachectl</STRONG> script to do the work for us. We make a copy for each developer called <STRONG>apachectl.username</STRONG> and we change 2 lines in script:
   
   <P>
  -<PRE>  *) SIGPIPE is now ignored by the server core.  The request write
  -  routines (ap_rputc, ap_rputs, ap_rvputs, ap_rwrite, ap_rprintf,
  -  ap_rflush) now correctly check for output errors and mark the
  -  connection as aborted.
  -  Replaced many direct (unchecked) calls to ap_b* routines with the
  -  analogous ap_r* calls.  [Roy Fielding]
  +<PRE>  PIDFILE=/usr/apps/var/httpd_perl/run/httpd.pid.sbekman
  +  HTTPD='/usr/apps/sbin/httpd_perl/httpd_perl -Dsbekman'
   </PRE>
   <P>
  -What happens if your mod_perl script has some global variables, that are
  -being used for resource locking?
  +Of course you think you can use only one control file and know who is
  +calling by using uid, but since you have to be root to start the server -
  +it is not so simple.
   
   <P>
  -It's possible not to notice the pitfall if the critical code section
  -between lock and unlock is very short and finishes fast, so you never see
  -this happens (you aren't fast enough to stop the code in the middle). But
  -look at the following scenario:
  +The last thing was to let developers an option to run in single process
  +mode by:
   
   <P>
  -<PRE>  1. lock resource
  -     &lt;b&gt;&lt;critical section starts&gt;
  -  2. sleep 20 (== do some time consuming processing)
  -     &lt;critical section ends&gt;&lt;/b&gt;
  -  3. unlock resource
  +<PRE>  /usr/apps/sbin/httpd_perl/httpd_perl -Dsbekman -X
   </PRE>
   <P>
  -If user presses 'Stop' and Apache sends SIGPIPE before step 3, since we are
  -in the mod_perl mode and we want the lock variable to be cached, it will be
  -not unlocked. A kind of ``deadlock'' exists.
  +In addition to making life easier, we decided to use relative links
  +everywhere in the static docs (including the calls to CGIs). You may ask
  +how using the relative link you will get to the right server? Very simple -
  +we have utilized the mod_rewrite to solve our problems:
   
   <P>
  -Here is the working example. Run the server with -X, Press 'Stop' before
  -the count-up to 10 has been finished. Then rerun the script, it'll hang in
  -<CODE>while(1)!</CODE> The resource is not available anymore.
  +In access.conf of the httpd_docs server we have the following code: (you
  +have to configure your httpd_docs server with
  +<CODE>--enable-module=rewrite</CODE> )
   
   <P>
  -<PRE>  -------------------------------------------------------------
  -  use vars qw(%CACHE);
  -  use CGI;
  -  $|=1;
  -  my $q = new CGI;
  -  print $q-&gt;header,$q-&gt;start_html;
  +<PRE>  # sbekman' server
  +  # port = 8000
  +  RewriteCond  %{REQUEST_URI} ^/(perl|cgi-perl)  
  +  RewriteCond  %{REMOTE_ADDR} 123.34.45.56
  +  RewriteRule ^(.*)           <A HREF="http://ourserver.com:8000/">http://ourserver.com:8000/</A>$1 [R,L]
     
  -  print $q-&gt;p(&quot;$$ Going to lock!\n&quot;);
  +  # userfoo's server
  +  # port = 8001
  +  RewriteCond  %{REQUEST_URI} ^/(perl|cgi-perl)  
  +  RewriteCond  %{REMOTE_ADDR} 123.34.45.57
  +  RewriteRule ^(.*)           <A HREF="http://ourserver.com:8001/">http://ourserver.com:8001/</A>$1 [R,L]
     
  -   # actually the while loop below is not needed 
  -   # (since it's an internal lock and accessible only 
  -   # by the same process and it if it's locked... it's locked for the
  -   # whole child's life
  -  while (1) {
  -    unless (defined $CACHE{LOCK} and $CACHE{LOCK} == 1) {
  -      $CACHE{LOCK} = 1;
  -      print $q-&gt;p(&quot;Got the lock!\n&quot;);
  -      last;
  -    }
  -  }
  -  print $q-&gt;p(&quot;Going to sleep (I mean working)!&quot;);
  -  my $c=0;
  -  foreach (1..10) {
  -    sleep 1;
  -    print $c++,&quot;\n&lt;BR&gt;&quot;;
  -  }
  +  # all the rest
  +  RewriteCond  %{REQUEST_URI} ^/(perl|cgi-perl)  
  +  RewriteRule ^(.*)           <A HREF="http://ourserver.com:81/">http://ourserver.com:81/</A>$1 [R]
     
  -  print $q-&gt;p(&quot;Going to unlock!&quot;);
  -  $CACHE{LOCK} = 0;
  -  print $q-&gt;p(&quot;Unlock!\n&quot;);
  -  -------------------------------------------------------------
   </PRE>
   <P>
  -You may ask, what is the solution for this problem? As noted in the
  -<A HREF="././porting.html#END_blocks">END blocks</A> any END blocks that are encountered during compilation of Apache::Registry
  -scripts are called after the script done is running, including subsequent
  -invocations when the script is cached in memory. So if you are running in
  -Apache::Registry mode, the following is your remedy:
  +where IP numbers are the IPs of the developer client machines (where they
  +are running their web browser.) (I have tried to use
  +<CODE>REMOTE_USER</CODE> since we have all the users authenticated but it did not work for me)
   
   <P>
  -<PRE>  END {
  -    $CACHE{LOCK} = 0;
  -  }
  -</PRE>
  +So if I have a relative URL like <CODE>/perl/test.pl</CODE> written in some html or even <CODE>http://www.nowhere.com/perl/test.pl</CODE> in my case (user at machine of <CODE>sbekman</CODE>) it will be redirected by httpd_docs to
  +<CODE>http://www.nowhere.com:8000/perl/test.pl</CODE>.
  +
   <P>
  -Notice that the END block will be run after the Apache::Registry::handler
  -is finished (not during the cleanup phase though).
  +Of course you have another problem: The CGI generates some html, which
  +should be called again. If it generates a URL with hard coded PORT the
  +above scheme will not work. There 2 solutions:
   
   <P>
  -If you are into a perl API, use the <STRONG>register_cleanup()</STRONG> method of Apache.
  +First, generate relative URL so it will reuse the technique above, with
  +redirect (which is transparent for user) but it will not work if you have
  +something to <CODE>POST</CODE> (redirect looses all the data!).
   
   <P>
  -<PRE>  $r-&gt;register_cleanup(sub {$CACHE{LOCK} = 0;});
  -</PRE>
  +Second, use a general configuration module which generates a correct full
  +URL according to <CODE>REMOTE_USER</CODE>, so if <CODE>$ENV{REMOTE_USER} eq
  +'sbekman'</CODE>, I return <CODE>http://www.nowhere.com:8000/perl/</CODE> as
  +<CODE>cgi_base_url</CODE>. Again this will work if the user is authenticated.
  +
   <P>
  -If you are into Apache API <CODE>Apache-</CODE>request-&gt;connection-&gt;aborted()&gt; construct can be used to test for
  -the aborted connection.
  +All this is good for development. It is better to use the full URLs in
  +production, since if you have a static form and the <CODE>Action</CODE> is relative but the static document located on another server, pressing the
  +form's submit will cause a redirect to mod_perl server, but all the form's
  +data will be lost during the redirect.
   
   <P>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<CENTER><H1><A NAME="Handling_the_server_timeout_case">Handling the server timeout cases and working with $SIG{ALRM}</A></H1></CENTER>
  +<CENTER><H1><A NAME="Wrapper_to_emulate_the_server_en">Wrapper to emulate the server environment</A></H1></CENTER>
   <P>
  -A similar situation to <A HREF="././obvious.html#Handling_the_User_pressed_Stop_">Pressed Stop button disease</A> happens when client (browser) timeouts the connection (is it about 2
  -minutes?) . There are cases when your script is about to perform a very
  -long operation and there is a chance that its duration will be longer than
  -the client's timeout. One case I can think about is the DataBase
  -interaction, where the DB engine hangs or needs a lot of time to return
  -results. If this is the case, use <CODE>$SIG{ALRM}</CODE> to prevent the timeouts:
  +Many times you start off debugging your script by running it from your
  +favorite shell. Sometimes you encounter a very weird situation when script
  +runs from the shell but dies when called as a CGI. The real problem lies in
  +the difference between the environment that is being used by your server
  +and your shell. An example can be a different perl path or having <CODE>PERL5LIB</CODE> env variable which includes paths that are not in the <CODE>@INC</CODE> of the perl compiled with mod_perl server and configured during the
  +startup.
   
   <P>
  -<PRE>  eval {
  -    local $SIG{ALRM} = sub { die &quot;timeout\n&quot; };
  -    alarm $timeout;
  -    ... db stuff ...
  -    alarm 0;
  -  };
  +The best debugging approach is to write a wrapper that emulates the exact
  +environment of the server, by first deleting the environment variables like <CODE>PERL5LIB</CODE> and calling the same perl binary that it is being used by the server. Next,
  +set the environment identical to the server's by copying the perl run
  +directives from server startup and configuration files. It will also allow
  +you to remove completely the first line of the script - since mod_perl
  +skips it and the wrapper knows how to call the script.
  +
  +<P>
  +Below is the example of such a script. Note that we force the <CODE>-Tw</CODE>
  +when we call the real script. (I have also added the ability to pass
  +params, which will not happen when you call the cgi from the web)
  +
  +<P>
  +<PRE>  #!/usr/apps/bin/perl -w    
      
  -  die $@ if $@;
  +  # This is a wrapper example 
  +   
  +  # It simulates the web server environment by setting the @INC and other
  +  # stuff, so what will run under this wrapper will run under web and
  +  # vice versa. 
  +  
  +  #
  +  # Usage: wrap.pl some_cgi.pl
  +  #
  +  
  +  BEGIN{
  +    use vars qw($basedir);
  +    $basedir = &quot;/usr/apps&quot;;
  +  
  +    # we want to make a complete emulation, so we must remove the
  +    # user's environment
  +    @INC = ();
  +  
  +    # local perl libs
  +    push @INC, (&quot;$basedir/lib/perl5/5.00502/aix&quot;,
  +                &quot;$basedir/lib/perl5/5.00502&quot;,
  +                &quot;$basedir/lib/perl5/site_perl/5.005/aix&quot;,
  +                &quot;$basedir/lib/perl5/site_perl/5.005&quot;,
  +               );
  +  }
  +  
  +  use strict;
  +  use File::Basename;
  +  
  +    # process the passed params
  +  my $cgi = shift || '';
  +  my $params = (@ARGV) ? join(&quot; &quot;, @ARGV) : '';
  +  
  +  die &quot;Usage:\n\t$0 some_cgi.pl\n&quot; unless $cgi;
  +  
  +    # Set the environment
  +  my $PERL5LIB = join &quot;:&quot;, @INC;
  +  
  +    # if the path includes the directory we extract it and chdir there
  +  if ($cgi =~ m|/|) {
  +    my $dirname = dirname($cgi);
  +    chdir $dirname or die &quot;Can't chdir to $dirname: $! \n&quot;;
  +    $cgi =~ m|$dirname/(.*)|;
  +    $cgi = $1;
  +  }
  +  
  +    # run the cgi from the script's directory
  +    # Note that we invoke warnings and Taintness ON!!!
  +  system qq{$basedir/bin/perl -I$PERL5LIB -Tw $cgi $params};
   </PRE>
   <P>
  -But, as lately it was discovered <CODE>local $SIG{'ALRM'}</CODE> does not restore the original underlying C handler. It was fixed in the
  -mod_perl 1.19_01 (CVS version). As a matter of fact none of the 'local
  -$SIG{FOO}' restore the original C handler - read <A HREF="././debug.html#Debugging_Signal_Handlers_SIG_">Debugging Signal Handlers ($SIG{FOO})</A> for a debug technique and a possible workaround.
  -
  -<P>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<CENTER><H1><A NAME="Where_do_the_warnings_errors_go_">Where do the warnings/errors go?</A></H1></CENTER>
  +<CENTER><H1><A NAME="Log_Rotation">Log Rotation</A></H1></CENTER>
   <P>
  -Your CGI does not work and you want to see what the problem is. The best
  -idea is to check out any errors that the server may be reporting. Where I
  -can find these errors?
  +A little bit off topic but good to know and use with mod_perl where your
  +error_log can grow at a 10-100Mb per day rate if your scripts spit out lots
  +of warnings...
   
   <P>
  -Generally all errors are logged into an error_log file. The exact file
  -location and name are defined in the http.conf file. Look for the <CODE>ErrorLog</CODE> parameter. My httpd.conf says:
  +To rotate the logs do:
   
   <P>
  -<PRE>  ErrorLog var/logs/error_log
  +<PRE>  mv access_log access_log.renamed
  +  kill -HUP `cat httpd.pid`
  +  sleep 10; # allow some children to complete requests and logging
  +  # now it's safe to use access_log.renamed
  +  .....
   </PRE>
   <P>
  -Hey, where is the beginning of the path? There is another Apache parameter
  -called <CODE>ServerRoot</CODE>. Every time apache sees a value of the parameter with no absolute path
  -(e.g <CODE>/tmp/my.txt</CODE>) but with relative path (e.g <CODE>my.txt</CODE>) it prepends the value of the <CODE>ServerRoot</CODE> to this value. I have:
  +The effect of <STRONG>SIGUSR1</STRONG> and <STRONG>SIGHUP</STRONG> is detailed in: <A
  +HREF="http://www.apache.org/docs/stopping.html">http://www.apache.org/docs/stopping.html</A>
  +.
   
   <P>
  -<PRE>  ServerRoot /usr/local/apache
  +I use this script:
  +
  +<P>
  +<PRE>  #!/usr/apps/bin/perl -Tw
  +  
  +  # this script does a log rotation. Called from crontab.
  +  
  +  use strict;
  +  $ENV{PATH}='/bin:/usr/bin';
  +  
  +  ### configuration
  +  my @logfiles = qw(access_log error_log);
  +  umask 0;
  +  my $server = &quot;httpd_perl&quot;;
  +  my $logs_dir = &quot;/usr/apps/var/$server/logs&quot;;
  +  my $restart_command = &quot;/usr/apps/sbin/$server/apachectl restart&quot;;
  +  my $gzip_exec = &quot;/usr/intel/bin/gzip&quot;;
  +  
  +  my ($sec,$min,$hour,$mday,$mon,$year) = localtime(time);
  +  my $time = sprintf &quot;%0.2d.%0.2d.%0.2d-%0.2d.%0.2d.%0.2d&quot;, $year,++$mon,$mday,$hour,$min,$sec;
  +  $^I = &quot;.&quot;.$time;
  +  
  +  # rename log files
  +  chdir $logs_dir;
  +  @ARGV = @logfiles;
  +  while (&lt;&gt;) {
  +    close ARGV;
  +  }
  +  
  +  # now restart the server so the logs will be restarted
  +  system $restart_command;
  +  
  +  # compress log files
  +  foreach (@logfiles) {
  +      system &quot;$gzip_exec $_.$time&quot;;
  +  }
   </PRE>
   <P>
  -So I will look for error_log file at
  -<CODE>/usr/local/apache/var/logs/error_log</CODE>. Of course you can also use an absolute path to define the file's location
  -at the file system.
  +Randal L. Schwartz contributed this:
   
  -<P>
  -&lt;META&gt;: is this 100% correct?
  +<BLOCKQUOTE>
   
   <P>
  -But there are cases when errors don't go to the error_log file. For example
  -some errors are being printed to the console (tty) you have executed the
  -httpd from (unless you redirected the httpd's stderr flow). This happens
  -when the server didn't open the error_log file for writing yet.
  +Cron fires off setuid script called log-roller that looks like this:
   
   <P>
  -For example, if you have mistakenly entered a non-existent directory path
  -in your <STRONG>ErrorLog</STRONG> directive, the error message will be printed on the controlling tty. Or, if
  -the error happens when server executes PerlRequire or PerlModule directive
  -you might see the errors here also.
  -
  +<PRE>    #!/usr/bin/perl -Tw
  +    use strict;
  +    use File::Basename;
  +    
  +    $ENV{PATH} = &quot;/usr/ucb:/bin:/usr/bin&quot;;
  +    
  +    my $ROOT = &quot;/WWW/apache&quot;; # names are relative to this
  +    my $CONF = &quot;$ROOT/conf/httpd.conf&quot;; # master conf
  +    my $MIDNIGHT = &quot;MIDNIGHT&quot;;  # name of program in each logdir
  +    
  +    my ($user_id, $group_id, $pidfile); # will be set during parse of conf
  +    die &quot;not running as root&quot; if $&gt;;
  +    
  +    chdir $ROOT or die &quot;Cannot chdir $ROOT: $!&quot;;
  +    
  +    my %midnights;
  +    open CONF, &quot;&lt;$CONF&quot; or die &quot;Cannot open $CONF: $!&quot;;
  +    while (&lt;CONF&gt;) {
  +      if (/^User (\w+)/i) {
  +        $user_id = getpwnam($1);
  +        next;
  +      }
  +      if (/^Group (\w+)/i) {
  +        $group_id = getgrnam($1);
  +        next;
  +      }
  +      if (/^PidFile (.*)/i) {
  +        $pidfile = $1;
  +        next;
  +      }
  +     next unless /^ErrorLog (.*)/i;
  +      my $midnight = (dirname $1).&quot;/$MIDNIGHT&quot;;
  +      next unless -x $midnight;
  +      $midnights{$midnight}++;
  +    }
  +    close CONF;
  +    
  +    die &quot;missing User definition&quot; unless defined $user_id;
  +    die &quot;missing Group definition&quot; unless defined $group_id;
  +    die &quot;missing PidFile definition&quot; unless defined $pidfile;
  +    
  +    open PID, $pidfile or die &quot;Cannot open $pidfile: $!&quot;;
  +    &lt;PID&gt; =~ /(\d+)/;
  +    my $httpd_pid = $1;
  +    close PID;
  +    die &quot;missing pid definition&quot; unless defined $httpd_pid and $httpd_pid;
  +    kill 0, $httpd_pid or die &quot;cannot find pid $httpd_pid: $!&quot;;
  +    
  +    
  +    for (sort keys %midnights) {
  +      defined(my $pid = fork) or die &quot;cannot fork: $!&quot;;
  +      if ($pid) {
  +        ## parent:
  +        waitpid $pid, 0;
  +      } else {
  +        my $dir = dirname $_;
  +        ($(,$)) = ($group_id,$group_id);
  +        ($&lt;,$&gt;) = ($user_id,$user_id);
  +        chdir $dir or die &quot;cannot chdir $dir: $!&quot;;
  +        exec &quot;./$MIDNIGHT&quot;;
  +        die &quot;cannot exec $MIDNIGHT: $!&quot;;
  +      }
  +    }
  +    
  +    kill 1, $httpd_pid or die &quot;Cannot sighup $httpd_pid: $!&quot;;
  +</PRE>
   <P>
  -You are probably wonder where all the errors go when you are running the
  -server in single mode (httpd -X). They go to the console. That is because
  -when running in the single mode there is no parent httpd process to perform
  -all the logging. It includes all the status messages that generally show up
  -in the error_log file.
  +And then individual MIDNIGHT scripts can look like this:
   
   <P>
  -&lt;/META&gt;
  +<PRE>    #!/usr/bin/perl -Tw
  +    use strict;
  +    
  +    die &quot;bad guy&quot; unless getpwuid($&lt;) =~ /^(root|nobody)$/;
  +    my @LOGFILES = qw(access_log error_log);
  +    umask 0;
  +    $^I = &quot;.&quot;.time;
  +    @ARGV = @LOGFILES;
  +    while (&lt;&gt;) {
  +      close ARGV;
  +    }
  +</PRE>
  +<P>
  +Can you spot the security holes? Our trusted user base can't or won't. :)
  +But these shouldn't be used in hostile situations.
  +
  +</BLOCKQUOTE>
   
   <P>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<CENTER><H1><A NAME="Setting_environment_variables_fo">Setting environment variables for scripts called from CGI.</A></H1></CENTER>
  +<CENTER><H1><A NAME="Preventing_from_modperl_process_">Preventing from modperl process from going wild</A></H1></CENTER>
   <P>
  -Perl uses <CODE>sh()</CODE> for its iteractions for <CODE>system()</CODE> and <CODE>open()</CODE>
  -calls. So when you want to set a temporary variable when you call a script
  -from your CGI you do:
  +Sometimes calling an undefined subroutine in a module can cause a tight
  +loop that consumes all memory. Here is a way to catch such errors. Define
  +an autoload subroutine:
   
   <P>
  -<PRE> open UTIL, &quot;USER=stas ; script.pl | &quot; or die &quot;...: $!\n&quot;;
  +<PRE>  sub UNIVERSAL::AUTOLOAD {
  +          my $class = shift;
  +          warn &quot;$class can't \$UNIVERSAL::AUTOLOAD!\n&quot;;
  +  }
   </PRE>
   <P>
  -or
  +It will produce a nice error in error_log, giving the line number of the
  +call and the name of the undefined subroutine.
   
  -<P>
  -<PRE>  system &quot;USER=stas ; script.pl&quot;;
  -</PRE>
   <P>
  -This is useful for example if you need to invoke a script that uses CGI.pm
  -from within a mod_perl script. We are tricking the perl script to think
  -it's a simple CGI, which is not running under mod_perl.
  +Sometimes an error happens and causes the server to write millions of lines
  +into your <CODE>error_log</CODE> file and in a few minutes to put your server down on its knees. For example
  +I get an error <CODE>Callback called
  +exit</CODE> show up in my error_log file many times. The <CODE>error_log</CODE> file grows to 300 Mbytes in size in a few minutes. You should run a cron
  +job to make sure this does not happen and if it does to take care of it.
  +Andreas J. Koenig is running this shell script every minute:
   
   <P>
  -<PRE>  open(PUBLISH, &quot;GATEWAY_INTERFACE=CGI/1.1 ; script.cgi
  -       &quot;param1=value1&amp;param2=value2&quot; |&quot;) or die &quot;...: $!\n&quot;;
  +<PRE>  S=`ls -s /usr/local/apache/logs/error_log | awk '{print $1}'`
  +  if [ &quot;$S&quot; -gt 100000 ] ; then
  +    /etc/rc.d/init.d/httpd restart
  +    date | /bin/mail -s &quot;error_log $S kB on inx&quot; myemail@domain.com
  +  fi
   </PRE>
   <P>
  -Make sure, that the parameters you pass are shell safe (All ``unsafe''
  -characters like single-tick should be properly escaped).
  +It seems that his script will trigger restart every minute, since once the
  +logfile grows to be of 100000 lines, it will stay of this size, unless you
  +remove or rename it, before you do restart. On my server I run a watchdog
  +every five minutes which restarts the server if it is getting stuck (it
  +always works since when some modperl child process goes wild, the I/O it
  +causes is so heavy that other brother processes cannot normally to serve
  +the requests.) See <A HREF="././control.html#Monitoring_the_Server_A_watchdo">Monitoring the Server</A> for more hints.
   
   <P>
  -However you are fork-ing to run a Perl script, so you have thrown the so
  -hardly gained performance out the window. Whatever script.cgi is now, it
  -should be moved to a module with a subroutine you can call directly from
  -your script, to avoid the fork.
  +Also check out the daemontools from <A
  +HREF="ftp://koobera.math.uic.edu/www/daemontools.html">ftp://koobera.math.uic.edu/www/daemontools.html</A>
  +:
   
  +<P>
  +<PRE>  ,-----
  +  | cyclog writes a log to disk. It automatically synchronizes the log
  +  | every 100KB (by default) to guarantee data integrity after a crash. It
  +  | automatically rotates the log to keep it below 1MB (by default). If
  +  | the disk fills up, cyclog pauses and then tries again, without losing
  +  | any data.
  +  `-----
  +</PRE>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
   	     The <a href="http://www.modperl.com/">
   	     <B>Writing Apache Modules with Perl and C</B></a>
  @@ -8996,7 +9846,7 @@
   	     Amazon.com</a>.
   
   	     <HR>
  -	     [    <A HREF="performance.html">Prev</A> |      <A HREF="index.html">Main Page</A> | <A HREF="warnings.html">Next</A>      ]
  +	     [    <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%" >
   <TR ALIGN=CENTER VALIGN=TOP>
  @@ -9009,7 +9859,7 @@
       <B>
         <FONT SIZE=-1>
   	     Written by <A HREF="help.html#This_document_s_Author">Stas Bekman</A>.
  -	     <BR>Last Modified at 06/05/1999
  +	     <BR>Last Modified at 06/27/1999
         </FONT>
       </B>
     </TD>
  @@ -9036,7 +9886,7 @@
   <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
   <HTML>
   <HEAD>
  -   <TITLE>mod_perl guide: Runtime Warnings and Errors: Where and Why.</TITLE>
  +   <TITLE>mod_perl guide: Things obvious to others, but not to you</TITLE>
      <META NAME="GENERATOR" CONTENT="Pod2HTML [Perl/Linux]">
      <META NAME="Author" CONTENT="Stas Bekman">
      <META NAME="Description" CONTENT="All Apache/Perl related information: Hints, Guidelines, Scenarios and Troubleshottings">
  @@ -9054,32 +9904,30 @@
   <A NAME="toc"></A>
   <H1 ALIGN=CENTER>
   <A HREF="http://perl.apache.org"><IMG SRC="images/mod_perl.gif" ALT="Mod Perl Icon" BORDER=0 HEIGHT=30 WIDTH=90 ALIGN=LEFT></A>
  -<A HREF="http://perl.apache.org"><IMG SRC="images/mod_perl.gif" ALT="Mod Perl Icon" BORDER=0 HEIGHT=30 WIDTH=90 ALIGN=RIGHT></A>
  -Runtime Warnings and Errors: Where and Why.</H1>
  -<HR WIDTH="100%">
  -	    [    <A HREF="obvious.html">Prev</A> |      <A HREF="index.html">Main Page</A> | <A HREF="control.html">Next</A>      ]<HR><!-- INDEX BEGIN -->
  -<P><B><FONT SIZE=-1>Table of Contents:</FONT></B></P>
  -<UL>
  -
  -	<LI><A HREF="#General_Advice">General Advice </A>
  -	<LI><A HREF="#Incorrect_line_number_reporting_">Incorrect line number reporting in error/warn log messages</A>
  -	<LI><A HREF="#Value_of_x_will_not_stay_shared">Value of $x will not stay shared at - line 5</A>
  -	<LI><A HREF="#Value_of_x_may_be_unavailable_a">Value of $x may be unavailable at - line 5.</A>
  -	<LI><A HREF="#mod_perl_rwrite_returned_1">mod_perl: rwrite returned -1</A>
  -	<LI><A HREF="#caught_SIGPIPE_in_process">caught SIGPIPE in process</A>
  -	<LI><A HREF="#Client_hit_STOP_or_Netscape_bit_">Client hit STOP or Netscape bit it!</A>
  -	<LI><A HREF="#Constant_subroutine_redefine">Constant subroutine ... redefined</A>
  -	<LI><A HREF="#Global_symbol_foo_requires_ex">Global symbol &quot;$foo&quot; requires explicit package name</A>
  -	<LI><A HREF="#Can_t_undef_active_subroutine">Can't undef active subroutine</A>
  -	<LI><A HREF="#Use_of_uninitialized_value_at_e">Use of uninitialized value at (eval 80) line 12.</A>
  -	<LI><A HREF="#Undefined_subroutine_Apache_RO">Undefined subroutine &amp;Apache::ROOT::perl::test_2epl::some_function called at</A>
  -	<LI><A HREF="#Can_t_load_auto_DBI_DBI_so_">Can't load '.../auto/DBI/DBI.so' for module DBI</A>
  -	<LI><A HREF="#Callback_called_exit">Callback called exit</A>
  -	<LI><A HREF="#Out_of_memory_">Out of memory!</A>
  -	<LI><A HREF="#_warn_child_process_30388_did_n">[warn] child process 30388 did not exit, sending another SIGHUP</A>
  -	<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>
  +<A HREF="http://perl.apache.org"><IMG SRC="images/mod_perl.gif" ALT="Mod Perl Icon" BORDER=0 HEIGHT=30 WIDTH=90 ALIGN=RIGHT></A>
  +Things obvious to others, but not to you</H1>
  +<HR WIDTH="100%">
  +	    [    <A HREF="control.html">Prev</A> |      <A HREF="index.html">Main Page</A> | <A HREF="warnings.html">Next</A>      ]<HR><!-- INDEX BEGIN -->
  +<P><B><FONT SIZE=-1>Table of Contents:</FONT></B></P>
  +<UL>
  +
  +	<LI><A HREF="#Coverage">Coverage</A>
  +	<LI><A HREF="#my_scoped_variable_in_nested_s">my() scoped variable in nested subroutines</A>
  +	<UL>
  +
  +		<LI><A HREF="#The_poison">The poison</A>
  +		<LI><A HREF="#The_diagnosis">The diagnosis</A>
  +		<LI><A HREF="#The_remedy">The remedy</A>
  +		<LI><A HREF="#Additional_reading_references">Additional reading references</A>
  +	</UL>
  +
  +	<LI><A HREF="#Compiled_Regular_Expressions">Compiled Regular Expressions </A>
  +	<LI><A HREF="#Debugging_your_code_in_Single_Se">Debugging your code in Single Server Mode</A>
  +	<LI><A HREF="#_M_and_other_time_file_tests_u">-M and other time() file tests under mod_perl</A>
  +	<LI><A HREF="#Handling_the_User_pressed_Stop_">Handling the 'User pressed Stop button' case</A>
  +	<LI><A HREF="#Handling_the_server_timeout_case">Handling the server timeout cases and working with $SIG{ALRM}</A>
  +	<LI><A HREF="#Where_do_the_warnings_errors_go_">Where do the warnings/errors go?</A>
  +	<LI><A HREF="#Setting_environment_variables_fo">Setting environment variables for scripts called from CGI.</A>
   </UL>
   <!-- INDEX END -->
   
  @@ -9097,351 +9945,627 @@
   
   	      <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>
  +<CENTER><H1><A NAME="Coverage">Coverage</A></H1></CENTER>
   <P>
  -Enabling <CODE>use diagnostics;</CODE> generally helps you to determine the source of the problem and how to solve
  -it. See <A HREF="././porting.html#diagnostics_pragma">diagnostics pragma</A> for more info.
  +This document describes ``special'' traps you may encounter when running
  +your plain CGIs under <CODE>Apache::Registry</CODE> and <CODE>Apache::PerlRun</CODE>.
   
   <P>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<CENTER><H1><A NAME="Incorrect_line_number_reporting_">Incorrect line number reporting in error/warn log messages</A></H1></CENTER>
  +<CENTER><H1><A NAME="my_scoped_variable_in_nested_s">my() scoped variable in nested subroutines</A></H1></CENTER>
   <P>
  -See <A HREF="././warnings.html#Use_of_uninitialized_value_at_e">Use of uninitialized value at (eval 80) line 12.</A>
  +<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<CENTER><H2><A NAME="The_poison">The poison</A></H2></CENTER>
  +<P>
  +In a non modperl script (stand alone or CGI), there is no problem writing
  +code like this:
  +
  +<P>
  +<PRE>    use CGI qw/param/;
  +    my $x = param('x');
  +    sub printit {
  +       print &quot;$x\n&quot;;
  +    }
  +</PRE>
  +<P>
  +However, the script is run under <CODE>Apache::Registry</CODE>, it will in fact be repackaged into something like this:
   
  +<P>
  +<PRE>  package $mangled_package_name;
  +  sub handler {
  +    #line1 $original_filename
  +    use CGI qw/param/;
  +    my $x = param('x');
  +    sub printit {
  +       print &quot;$x\n&quot;;
  +    }
  +  }
  +</PRE>
  +<P>
  +Now <CODE>printit()</CODE> is an inner named subroutine. Because it is referencing a lexical variable
  +from an enclosing scope, a closure is created.
   
  +<P>
  +The first time the script is run, the correct value of <CODE>$x</CODE> will
  +be printed. However on subsequent runs, <CODE>printit()</CODE> will retain the initial value of <CODE>$x</CODE> -- not what you want.
   
   <P>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<CENTER><H1><A NAME="Value_of_x_will_not_stay_shared">Value of $x will not stay shared at - line 5</A></H1></CENTER>
  +<CENTER><H2><A NAME="The_diagnosis">The diagnosis</A></H2></CENTER>
   <P>
  -<A HREF="././obvious.html#my_scoped_variable_in_nested_s">my() scoped variable in nested subroutines</A>.
  +Always use <CODE>-w</CODE> (or/and <CODE>PerlWarn ON</CODE>)! Perl will then emit a warning like:
   
   <P>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<CENTER><H1><A NAME="Value_of_x_may_be_unavailable_a">Value of $x may be unavailable at - line 5.</A></H1></CENTER>
  +<PRE>  Value of $x will not stay shared at - line 5.
  +</PRE>
   <P>
  -<A HREF="././obvious.html#my_scoped_variable_in_nested_s">my() scoped variable in nested subroutines</A>.
  +NOTE: Subroutines defined inside <CODE>BEGIN{}</CODE> and <CODE>END{}</CODE> cannot trigger this message, since each <CODE>BEGIN{}</CODE> and <CODE>END{}</CODE> is defined to be called exactly once. (To understand why, read about the
  +closures at
  +<CODE>perlref</CODE> or <CODE>perlfaq</CODE> 13.12)
   
   <P>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<CENTER><H1><A NAME="mod_perl_rwrite_returned_1">mod_perl: rwrite returned -1</A></H1></CENTER>
  +PERLDIAG manpage says:
  +
   <P>
  -That message happens when the client breaks the connection while your
  -script is trying to write to the client. With Apache 1.3.x, you should only
  -see the rwrite messages if LogLevel is set to debug.
  +<PRE>  An inner (nested) named subroutine is referencing a lexical variable
  +  defined in an outer subroutine.
  +</PRE>
  +<P>
  +When the inner subroutine is called, it will probably see the value of the
  +outer subroutine's variable as it was before and during the *first* call to
  +the outer subroutine; in this case, after the first call to the outer
  +subroutine is complete, the inner and outer subroutines will no longer
  +share a common value for the variable. In other words, the variable will no
  +longer be shared.
   
   <P>
  -This bug has been fixed in mod_perl 1.19_01 (CVS version).
  +Check your code by running Apache in single-child mode (<CODE>httpd
  +-X</CODE>). Since the value of a my variable retain its initial value <CODE>per
  +child process</CODE>, the closure problem can be difficult to track down in multi-user mode. It
  +will appear to work fine until you have cycled through all the httpd
  +children.
   
   <P>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<CENTER><H1><A NAME="caught_SIGPIPE_in_process">caught SIGPIPE in process</A></H1></CENTER>
  +<CENTER><H2><A NAME="The_remedy">The remedy</A></H2></CENTER>
   <P>
  -<PRE>  [modperl] caught SIGPIPE in process 1234
  -  [modperl] process 1234 going to Apache::exit with status...
  +If a variable needs file scope, use a global variable:
  +
  +<P>
  +<PRE>    use vars qw/$x/;
  +    use CGI qw/param/;
  +    $x = param('x');
  +    sub printit {
  +       print &quot;$x\n&quot;;
  +    }
   </PRE>
   <P>
  -That's the <STRONG>$SIG{PIPE}</STRONG> handler installed by mod_perl/Apache::SIG, called if a connection timesout
  -or Client presses the 'Stop' button. It gives you an opportunity to do
  -cleanups if the script was aborted in the middle of its execution. See <A HREF="././obvious.html#Handling_the_User_pressed_Stop_">Handling the 'User pressed Stop button' case</A> for more info.
  +You can safely use a <CODE>my()</CODE> scoped variable if its value is constant:
   
   <P>
  -If your mod_perl version &lt; 1.17 you might get the message in the
  -following section...
  +<PRE>    use vars qw/$x/;
  +    use CGI qw/param/;
  +    $x = param('x');
  +    my $y = 5;
  +    sub printit {
  +       print &quot;$x, $y\n&quot;;
  +    }
  +</PRE>
  +<P>
  +Also see the clarification of <CODE>my()</CODE> vs. <CODE>use vars</CODE> - Ken Williams writes:
   
   <P>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<CENTER><H1><A NAME="Client_hit_STOP_or_Netscape_bit_">Client hit STOP or Netscape bit it!</A></H1></CENTER>
  +<PRE>  Yes, there is quite a bit of difference!  With use vars(), you are
  +  making an entry in the symbol table, and you are telling the
  +  compiler that you are going to be referencing that entry without an
  +  explicit package name.
  +  
  +  With my(), NO ENTRY IS PUT IN THE SYMBOL TABLE.  The compiler
  +  figures out _at_ _compile_time_ which my() variables (i.e. lexical
  +  variables) are the same as each other, and once you hit execute time
  +  you can not go looking those variables up in the symbol table.
  +</PRE>
   <P>
  -<PRE>  Client hit STOP or Netscape bit it!
  -  Process 2493 going to Apache::exit with status=-2
  +And <CODE>my()</CODE> vs. <CODE>local()</CODE> - Randal Schwartz writes:
  +
  +<P>
  +<PRE>  local() creates a temporal-limited package-based scalar, array,
  +  hash, or glob -- when the scope of definition is exited at runtime,
  +  the previous value (if any) is restored.  References to such a
  +  variable are *also* global... only the value changes.  (Aside: that
  +  is what causes variable suicide. :)
  +  
  +  my() creates a lexically-limited non-package-based scalar, array, or
  +  hash -- when the scope of definition is exited at compile-time, the
  +  variable ceases to be accessible.  Any references to such a variable
  +  at runtime turn into unique anonymous variables on each scope exit.
   </PRE>
   <P>
  -You will see this message in mod_perl &lt; 1.17. See <A HREF="././warnings.html#caught_SIGPIPE_in_process">caught SIGPIPE in process</A>.
  +<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<CENTER><H2><A NAME="Additional_reading_references">Additional reading references</A></H2></CENTER>
  +<P>
  +For more information see: <A HREF="././perl.html#Using_global_variables_and_shari">Using global variables and sharing them between modules/packages</A> and an article by Mark-Jason Dominus about how Perl handles variables and
  +namespaces, and the difference between <CODE>use vars()</CODE> and <CODE>my()</CODE> - <A
  +HREF="http://www.plover.com/~mjd/perl/FAQs/Namespaces.html">http://www.plover.com/~mjd/perl/FAQs/Namespaces.html</A>
  +.
   
   <P>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<CENTER><H1><A NAME="Constant_subroutine_redefine">Constant subroutine ... redefined</A></H1></CENTER>
  +<CENTER><H1><A NAME="Compiled_Regular_Expressions">Compiled Regular Expressions</A></H1></CENTER>
   <P>
  -That's a mandatory warning inside Perl. It happens only if you modify your
  -script and Apache::Registry reloads it. Perl is warning you that the
  -<CODE>subroutine(s)</CODE> were redefined. It is mostly harmless. If you
  -don't like seeing those, just <CODE>kill -USR2</CODE> (graceful restart) apache when you modify your scripts.
  +When using a regular expression that contains an interpolated Perl
  +variable, if it is known that the variable (or variables) will not vary
  +during the execution of the program, a standard optimization technique
  +consists of adding the <CODE>/o</CODE> modifier to the regexp pattern. This directs the compiler to build the
  +internal table once, for the entire lifetime of the script, rather than
  +every time the pattern is executed. Consider:
  +
  +<P>
  +<PRE>  my $pat = '^foo$'; # likely to be input from an HTML form field
  +  foreach( @list ) {
  +    print if /$pat/o;
  +  }
  +</PRE>
  +<P>
  +This is usually a big win in loops over lists, or when using <CODE>grep()</CODE>
  +or <CODE>map()</CODE> operators.
  +
  +<P>
  +In long-lived mod_perl scripts, however, this can pose a problem if the
  +variable changes according to the invocation. The first invocation of a
  +fresh httpd child will compile the regex and perform the search correctly.
  +However, all subsequent uses by the httpd child will continue to match the
  +original pattern, regardless of the current contents of the Perl variables
  +the pattern is dependent on. Your script will appear broken.
  +
  +<P>
  +There are two solutions to this problem:
  +
  +<P>
  +The first -- is to use <CODE>eval q//</CODE>, to force the code to be evaluated each time. Just make sure that the eval
  +block covers the entire loop of processing, and not just the pattern match
  +itself.
  +
  +<P>
  +The above code fragment would be rewritten as: 
  +
  +<P>
  +<PRE>  my $pat = '^foo$';
  +  eval q{
  +    foreach( @list ) {
  +      print if /$pat/o;
  +    }
  +  }
  +</PRE>
  +<P>
  +Just saying:
  +
  +<P>
  +<PRE>  foreach( @list ) {
  +    eval q{ print if /$pat/o; };
  +  }
  +</PRE>
  +<P>
  +is going to be a horribly expensive proposition. 
  +
  +<P>
  +You can use this approach if you require more than one pattern match
  +operator in a given section of code. If the section contains only one
  +operator (be it an <CODE>m//</CODE> or <CODE>s///</CODE>), you can rely on the property of the null pattern, that reuses the last
  +pattern seen. This leads to the second solution, which also eliminates the
  +use of eval.
  +
  +<P>
  +The above code fragment becomes: 
  +
  +<P>
  +<PRE>  my $pat = '^foo$';
  +  &quot;something&quot; =~ /$pat/; # dummy match (MUST NOT FAIL!)
  +  foreach( @list ) {
  +    print if //;
  +  }
  +</PRE>
  +<P>
  +The only gotcha is that the dummy match that boots the regular expression
  +engine must absolutely, positively succeed, otherwise the pattern will not
  +be cached, and the <CODE>//</CODE> will match everything. If you can't count on fixed text to ensure the match
  +succeeds, you have two possibilities.
  +
  +<P>
  +If you can guarantee that the pattern variable contains no meta-characters
  +(things like *, +, ^, $...), you can use the dummy match:
  +
  +<P>
  +<PRE>  &quot;$pat&quot; =~ /\Q$pat\E/; # guaranteed if no meta-characters present
  +</PRE>
  +<P>
  +If there is a possibility that the pattern can contain meta-characters, you
  +should search for the pattern or the unsearchable \377 character as
  +follows:
  +
  +<P>
  +<PRE>  &quot;\377&quot; =~ /$pat|^[\377]$/; # guaranteed if meta-characters present
  +</PRE>
  +<P>
  +Phil. Chu contributed this:
  +
  +<P>
  +It depends on the complexity of the regexp you apply this technique to. One
  +common usage where compiled regexp is usually more efficient is to ``match
  +any one of a group of patterns'' over and over again.
  +
  +<P>
  +Maybe with some helper routine, it's easier to remember. Here is one
  +slightly modified from Jeffery Friedl's example in his book ``Mastering
  +Regex.''. I find it quite useful:
   
   <P>
  -<PRE>  &lt;META&gt;
  -  Someone said: 
  -  You won't see that warning in this case with 5.004_05 or 5.005+. 
  +<PRE>  #####################################################
  +  # Build_MatchMany_Function
  +  # -- Input:  list of patterns
  +  # -- Output: A code ref which matches its $_[0]
  +  #            against ANY of the patterns given in the
  +  #            &quot;Input&quot;, efficiently.
  +  #
  +  sub Build_MatchMany_Function {
  +    my @R = @_;
  +    my $expr = join '||', map { &quot;\$_[0] =~ m/\$R[$_]/o&quot; } ( 0..$#R );
  +    my $matchsub = eval &quot;sub { $expr }&quot;;
  +    die &quot;Failed in building regex @R: $@&quot; if $@;
  +    $matchsub;
  +  }
   </PRE>
   <P>
  -<PRE>  I'm running perl5.00502 and I still get these warnings???
  +Example usage:
  +
  +<P>
  +<PRE>  @some_browsers = qw(Mozilla Lynx MSIE AmigaVoyager lwp libwww);
  +  $Known_Browser=Build_MatchMany_Function(@some_browsers);
   </PRE>
   <P>
  -<PRE>  Who is right?
  -  &lt;/META&gt;
  +<PRE>  while (&lt;ACCESS_LOG&gt;) {
  +    # ...
  +    $browser = get_browser_field($_);
  +    if ( ! &amp;$Known_Browser($browser) ) {
  +      print STDERR &quot;Unknown Browser: $browser\n&quot;;
  +    }
  +    # ...
  +  }
   </PRE>
   <P>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<CENTER><H1><A NAME="Global_symbol_foo_requires_ex">Global symbol &quot;$foo&quot; requires explicit package name</A></H1></CENTER>
  +<CENTER><H1><A NAME="Debugging_your_code_in_Single_Se">Debugging your code in Single Server Mode</A></H1></CENTER>
   <P>
  -The script below will print a warning like above, moreover it will print
  -the whole script as a part of the warning message:
  +Running in httpd -X mode. (good only for testing during development phase).
   
  -<P>
  -<PRE>  #!/usr/bin/perl -w
  -  use strict;
  -  print &quot;Content-type: text/html\n\n&quot;;
  -  print &quot;Hello $undefined&quot;;
  -</PRE>
   <P>
  -The warning:
  +You want to test that your application correctly handles global variables
  +(if you have any - the less you have of them the better, but sometimes you
  +just can't without them). It's hard to test with multiple servers serving
  +your cgi since each child has a different value for its global variables.
  +Imagine that you have a <CODE>random()</CODE>
  +sub that returns a random number and you have the following script.
   
   <P>
  -<PRE>  Global symbol &quot;$undefined&quot; requires explicit package name at /usr/apps/foo/cgi/tmp.pl line 4.
  -          eval 'package Apache::ROOT::perl::tmp_2epl;use Apache qw(exit);sub handler {
  -  #line 1 /usr/apps/foo/cgi/tmp.pl
  -  BEGIN {$^W = 1;}#!/usr/bin/perl -w
  -  use strict;
  -  print &quot;Content-type: text/html\\n\\n&quot;;
  -  print &quot;Hello $undefined&quot;;
  -  
  -  
  -  }
  -  ;' called at /usr/apps/lib/perl5/site_perl/5.005/aix/Apache/Registry.pm line 168
  -          Apache::Registry::compile('package
  -        Apache::ROOT::perl::tmp_2epl;use Apache qw(exit);sub han...') 
  -        called at /usr/apps/lib/perl5/site_perl/5.005/aix/Apache/Registry.pm line 121
  -          Apache::Registry::handler('Apache=SCALAR(0x205026c0)') called at /usr/apps/foo/cgi/tmp.pl line 4
  -          eval {...} called at /usr/apps/foo/cgi/tmp.pl line 4
  -  [Sun Nov 15 15:15:30 1998] [error] Undefined subroutine &amp;Apache::ROOT::perl::tmp_2epl::handler called at /
  -  usr/apps/lib/perl5/site_perl/5.005/aix/Apache/Registry.pm line 135.
  -  
  -  [Sun Nov 15 15:15:30 1998] [error] Goto undefined subroutine &amp;Apache::Constants::SERVER_ERROR at /usr/apps
  -  /lib/perl5/site_perl/5.005/aix/Apache/Constants.pm line 23.
  +<PRE>  use vars qw($num);
  +  $num ||= random();
  +  print ++$num;
   </PRE>
   <P>
  -The error is simple to fix. When you use the <CODE>use strict;</CODE> pragma (and you should...), all variables should be defined before being
  -used.
  +This script initializes the variable <CODE>$num</CODE> with a random value, then increments it on each request and prints it out.
  +Running this script in multiple server environments will result in
  +something like <CODE>1</CODE>,
  +<CODE>9</CODE>, <CODE>4</CODE>, <CODE>19</CODE> (number per reload), since each time your script will be served by a
  +different child. (On some OSes, the parent httpd process will assign all of
  +the requests to the same child process if all of the children are idle...
  +AIX...). But if you run in <CODE>httpd -X</CODE>
  +single server mode you will get <CODE>2</CODE>, <CODE>3</CODE>, <CODE>4</CODE>, <CODE>5</CODE>... (assuming that the <CODE>random()</CODE> returned <CODE>1</CODE> at the first call)
   
   <P>
  -The bad thing is that sometimes the whole script (possibly, thousands of
  -lines) is printed to error_log file as a code that the server has tried to <STRONG>eval()</STRONG>uate.
  +But do not get too obsessive with this mode, since working only in single
  +server mode sometimes hides problems that show up when you switch to a
  +normal (multi) server mode. Consider an application that allows you to
  +change the configuration at run time.
   
   <P>
  -As Doug answered to this question:
  +Let's say the script produces a form to change the background color of the
  +page. It's not a good design, but for the sake of demonstrating the
  +potential problem, we will assume that our script doesn't write the changed
  +background color to the disk, but simply changes it in memory, like:
   
   <P>
  -<PRE> Looks like you have a $SIG{__DIE__} handler installed (Carp::confess?).
  - That's what's expected if so.
  +<PRE>  use vars qw($bgcolor);
  +    # assign default value at first invocation
  +  $bgcolor ||= &quot;white&quot;;
  +    # modify the color if requested to
  +  $bgcolor = $q-&gt;param('bgcolor') || $bgcolor;
   </PRE>
   <P>
  -It wasn't in my case, but may be yours. 
  +So you have typed in a new color, and in response, your script prints back
  +the html with a new color - you think that's it! It was so simple. And if
  +you keep running in single server mode you will never notice that you have
  +a problem...
   
   <P>
  -Bryan Miller said:
  +If you run the same code in the normal server mode, after you submit the
  +color change you will get the result as expected, but when you will call
  +the same URL again (not reload!) chances are that you will get back the
  +original default color (white in our case), since except the child who
  +processed the color change request no one knows about their global variable
  +change. Just remember that children can't share information, other than
  +that which they inherited from their parent on their load. Of course you
  +should use a hidden variable for the color to be remembered or store it on
  +the server side (database, shared memory, etc).
   
   <P>
  -<PRE> You might wish to try something more terse such as 
  - &quot;local $SIG{__WARN__} = \&amp;Carp::cluck;&quot;  The confess method is _very_
  - verbose and will tell you more than you might wish to know including
  - full source.
  -</PRE>
  +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
  +connection has to time-out before the next succeeds. Turn off
  +<CODE>KeepAlive</CODE> in <CODE>httpd.conf</CODE> to avoid this effect while developing or you can press <STRONG>STOP</STRONG> after a few seconds (assuming you use the image size params, so the
  +Netscape will be able to render the rest of the page).
  +
  +<P>
  +In addition you should know that when running with <CODE>-X</CODE> you will not see any control messages that the parent server normally
  +writes to the error_log. (Like ``server started, server stopped and etc''.)
  +Since
  +<CODE>httpd -X</CODE> causes the server to handle all requests itself, without forking any
  +children, there is no controlling parent to write status messages.
  +
   <P>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<CENTER><H1><A NAME="Can_t_undef_active_subroutine">Can't undef active subroutine</A></H1></CENTER>
  +<CENTER><H1><A NAME="_M_and_other_time_file_tests_u">-M and other time() file tests under mod_perl</A></H1></CENTER>
   <P>
  -<PRE>  Can't undef active subroutine at /usr/apps/lib/perl5/site_perl/5.005/aix/Apache/Registry.pm line 102. 
  -  Called from package Apache::Registry, filename /usr/apps/lib/perl5/site_perl/5.005/aix/Apache/Registry.pm, line 102 
  -</PRE>
  +Under mod_perl, files that have been created after the server's (child?)
  +startup are being reported with negative age with <CODE>-M</CODE>
  +(<CODE>-C</CODE>  <CODE>-A</CODE>) test. This is obvious if you remember that you will get the negative
  +result if the server was started before the file was created and it's a
  +normal behavior with any perl.
  +
   <P>
  -This problem is caused when, a client drops the connection while httpd is
  -in the middle of a write, httpd timeout happens, sending a SIGPIPE, and
  -Perl in that child is stuck in the middle of its eval context. This is
  -fixed by the Apache::SIG module which is called by default. This should not
  -happen unless you have code that is messing with <STRONG>$SIG{PIPE}</STRONG>. It's also triggered only when you've changed your script on disk and
  -mod_perl is trying to reload it.
  +If you want to have <CODE>-M</CODE> test to count the time relative to the current request, you should reset
  +the <CODE>$^T</CODE> variable as with any other perl script. Just add <CODE>$^T=time;</CODE> at the beginning of the scripts.
   
   <P>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<CENTER><H1><A NAME="Use_of_uninitialized_value_at_e">Use of uninitialized value at (eval 80) line 12.</A></H1></CENTER>
  +<CENTER><H1><A NAME="Handling_the_User_pressed_Stop_">Handling the 'User pressed Stop button' case</A></H1></CENTER>
   <P>
  -Your code includes some undefined variable that you have used as if it was
  -already defined and initialized. For example:
  +When a user presses the <STRONG>STOP</STRONG> button, Apache will detect that via
  +<CODE>$SIG{PIPE}</CODE> and will cease the script execution. When we are talking about mod_cgi,
  +there is generally no problem, since all opened files will be closed and
  +all the resources will be freed (almost all -- if you happened to use
  +external lock files, most likely the resources that are being locked by
  +these will be left blocked and non-usable by any others who use the same
  +advisory locking scheme.)
   
   <P>
  -<PRE>  $param = $q-&gt;param('test');
  -  print $param;
  -</PRE>
  +It's important to notice that when the user hits the browser's <STRONG>STOP</STRONG>
  +button, the mod_perl script is blissfully unaware until it tries to send
  +some data to the browser. At that point, Apache realizes that the browser
  +is gone, and all the good cleanup stuff happens.
  +
   <P>
  -<PRE>  vs.
  -</PRE>
  +Starting from apache 1.3.6 apache will not catch SIGPIPE anymore and
  +modperl will do it much better. Here is something from CHANGES from Apache
  +1.3.6.
  +
   <P>
  -<PRE>  $param = $q-&gt;param('test') || '';
  -  print $param;
  +<PRE>  *) SIGPIPE is now ignored by the server core.  The request write
  +  routines (ap_rputc, ap_rputs, ap_rvputs, ap_rwrite, ap_rprintf,
  +  ap_rflush) now correctly check for output errors and mark the
  +  connection as aborted.  Replaced many direct (unchecked) calls to
  +  ap_b* routines with the analogous ap_r* calls.  [Roy Fielding]
   </PRE>
   <P>
  -In the second case, <CODE>$param</CODE> will always be <CODE>defined</CODE>, either
  -<CODE>$q-&amp;gt;param('test')</CODE> returns some value or <CODE>undef</CODE>.
  +What happens if your mod_perl script has some global variables, that are
  +being used for resource locking?
   
   <P>
  -Also read about <A HREF="././porting.html#Finding_the_line_number_the_erro">finding the line number the error/warning has been triggered at</A>.
  +It's possible not to notice the pitfall if the critical code section
  +between lock and unlock is very short and finishes fast, so you never see
  +this happens (you aren't fast enough to stop the code in the middle). But
  +look at the following scenario:
   
   <P>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<CENTER><H1><A NAME="Undefined_subroutine_Apache_RO">Undefined subroutine &amp;Apache::ROOT::perl::test_2epl::some_function called at</A></H1></CENTER>
  +<PRE>  1. lock resource
  +     &lt;critical section starts&gt;
  +  2. sleep 20 (== do some time consuming processing)
  +     &lt;critical section ends&gt;
  +  3. unlock resource
  +</PRE>
   <P>
  -See <A HREF="././porting.html#Name_collisions_with_Modules_and">Names collisions with Modules and libs</A>.
  +If user presses <STRONG>STOP</STRONG> and Apache sends <CODE>SIGPIPE</CODE> before step 3, since we are in the mod_perl mode and we want the lock
  +variable to be cached, it will be not unlocked. A kind of <STRONG>deadlock</STRONG> exists.
   
   <P>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<CENTER><H1><A NAME="Can_t_load_auto_DBI_DBI_so_">Can't load '.../auto/DBI/DBI.so' for module DBI</A></H1></CENTER>
  -<P>
  -Check that all your modules are compiled with the same perl that is being
  -compiled into mod_perl. perl 5.005 and 5.004 are not binary compatible by
  -default.
  +Here is the working example. Run the server with <CODE>-X</CODE>, Press <STRONG>STOP</STRONG>
  +before the count-up to 10 has been finished. Then rerun the script, it'll
  +hang in <CODE>while(1)</CODE>! The resource is not available anymore.
   
   <P>
  -Other known causes of this problem: OS distributions that ship with a
  -(broken) binary Perl installation. The `perl' program and `libperl.a'
  -library are somehow built with different binary compatibility flags.
  -
  +<PRE>  use vars qw(%CACHE);
  +  use CGI;
  +  $|=1;
  +  my $q = new CGI;
  +  print $q-&gt;header,$q-&gt;start_html;
  +  
  +  print $q-&gt;p(&quot;$$ Going to lock!\n&quot;);
  +  
  +   # actually the while loop below is not needed 
  +   # (since it's an internal lock and accessible only 
  +   # by the same process and it if it's locked... it's locked for the
  +   # whole child's life
  +  while (1) {
  +    unless (defined $CACHE{LOCK} and $CACHE{LOCK} == 1) {
  +      $CACHE{LOCK} = 1;
  +      print $q-&gt;p(&quot;Got the lock!\n&quot;);
  +      last;
  +    }
  +  }
  +  print $q-&gt;p(&quot;Going to sleep (I mean working)!&quot;);
  +  my $c=0;
  +  foreach (1..10) {
  +    sleep 1;
  +    print $c++,&quot;\n&lt;BR&gt;&quot;;
  +  }
  +  
  +  print $q-&gt;p(&quot;Going to unlock!&quot;);
  +  $CACHE{LOCK} = 0;
  +  print $q-&gt;p(&quot;Unlock!\n&quot;);
  +</PRE>
   <P>
  -The solution to these problems is to rebuild Perl and any extension modules
  -from a fresh source tree. Tip for running Perl's Configure script: use the
  -`-des' flags to accepts defaults and `-D' flag to override certain
  -attributes:
  +You may ask, what is the solution for this problem? As noted in the
  +<A HREF="././porting.html#END_blocks">END blocks</A> any <CODE>END</CODE> blocks that are encountered during compilation of <CODE>Apache::Registry</CODE> scripts are called after the script done is running, including subsequent
  +invocations when the script is cached in memory. So if you are running in <CODE>Apache::Registry</CODE>
  +mode, the following is your remedy:
   
   <P>
  -<PRE>  % ./Configure -des -Dcc=gcc ... &amp;&amp; make test &amp;&amp; make install
  - 
  -Read Perl's INSTALL doc for more details.
  +<PRE>  END {
  +    $CACHE{LOCK} = 0;
  +  }
   </PRE>
   <P>
  -Solaris OS specific: 
  +Notice that the <CODE>END</CODE> block will be run after the
  +<CODE>Apache::Registry::handler</CODE> is finished (not during the cleanup phase though).
   
   <P>
  -Can't load DBI or similar Error for the IO module or whatever dynamic
  -module mod_perl tries to pull in first. The solution is to re-configure,
  -re-build and re-install Perl and dynamic modules with the following flags
  -when Configure asks for ``additional LD flags'': -Xlinker --export-dynamic
  -or
  +If you are into a perl API, use the <CODE>register_cleanup()</CODE> method of Apache.
   
   <P>
  -<PRE>  -Xlinker -E
  +<PRE>  $r-&gt;register_cleanup(sub {$CACHE{LOCK} = 0;});
   </PRE>
   <P>
  -This problem is only known to be caused by installing gnu ld under Solaris.
  +If you are into Apache API <CODE>Apache-</CODE>request-&gt;connection-&gt;aborted()&gt; construct can be used to test for
  +the aborted connection.
   
  -<P>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<CENTER><H1><A NAME="Callback_called_exit">Callback called exit</A></H1></CENTER>
   <P>
  -See <A HREF="#Out_of_memory_">Out_of_memory!</A>
  -
  +I hope you noticed, that this example is very misleading, since there is a
  +different instance of <CODE>%CACHE</CODE> in every child, so if you modify it -- it is known only inside the same
  +child, none of global <CODE>%CACHE</CODE>
  +variables in other children is getting affected. But if you are going to
  +work with code that allows you to control variables that are being visible
  +to every child (some external shared memory or other approach) -- the
  +hazard this example still applies. Make sure you unlock the resources
  +either when you stop using them or when the script is being aborted in the
  +middle, before the actual unlocking is being happening.
   
  -
   <P>
  -I've just discovered that my server is not responding and its error log has
  -filled up the remaining space on the file system (about a gig's worth). The
  -error_log includes millions of lines:
  +<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<CENTER><H1><A NAME="Handling_the_server_timeout_case">Handling the server timeout cases and working with $SIG{ALRM}</A></H1></CENTER>
  +<P>
  +A similar situation to <A HREF="././obvious.html#Handling_the_User_pressed_Stop_">Pressed Stop button disease</A> happens when client (browser) timeouts the connection (is it about 2
  +minutes?) . There are cases when your script is about to perform a very
  +long operation and there is a chance that its duration will be longer than
  +the client's timeout. One case I can think about is the DataBase
  +interaction, where the DB engine hangs or needs a lot of time to return
  +results. If this is the case, use <CODE>$SIG{ALRM}</CODE> to prevent the timeouts:
   
   <P>
  -<PRE>  Callback called exit at -e line 33, &lt;HTML&gt; chunk 1.
  +<PRE>    $timeout = 10; # seconds
  +  eval {
  +    local $SIG{ALRM} =
  +        sub { die &quot;Sorry timed out. Please try again\n&quot; };
  +    alarm $timeout;
  +    ... db stuff ...
  +    alarm 0;
  +  };
  +  
  +  die $@ if $@;
   </PRE>
   <P>
  -Why the looping?
  +But, as lately it was discovered <CODE>local $SIG{'ALRM'}</CODE> does not restore the original underlying C handler. It was fixed in the
  +mod_perl 1.19_01 (CVS version). As a matter of fact none of the
  +<CODE>local $SIG{FOO}</CODE> restore the original C handler - read <A HREF="././debug.html#Debugging_Signal_Handlers_SIG_">Debugging Signal Handlers ($SIG{FOO})</A> for a debug technique and a possible workaround.
   
   <P>
  -Perl can get *very* confused inside an endless loop in your code, it
  -doesn't mean your code called 'exit', but Perl's malloc went haywire and
  -called <CODE>croak(),</CODE> but no memory is left to properly report the
  -error, so Perl is stuck in a loop writing that same message to stderr.
  -
  +<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<CENTER><H1><A NAME="Where_do_the_warnings_errors_go_">Where do the warnings/errors go?</A></H1></CENTER>
   <P>
  -Perl 5.005+ plus is recommended for its improved malloc.c and features
  -mentioned in mod_perl_traps.pod on by default.
  +Your CGI does not work and you want to see what the problem is. The best
  +idea is to check out any errors that the server may be reporting. Where I
  +can find these errors?
   
  -<P>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<CENTER><H1><A NAME="Out_of_memory_">Out of memory!</A></H1></CENTER>
   <P>
  -If something goes really wrong with your code, Perl may die with an ``Out
  -of memory!'' message and/or ``Callback called exit''. Common causes of this
  -are never-ending loops, deep recursion, or calling an undefined subroutine.
  -Here's one way to catch the problem: See Perl's INSTALL document for this
  -item: 
  +Generally all errors are logged into an error_log file. The exact file
  +location and name are defined in the http.conf file. Look for the
  +<CODE>ErrorLog</CODE> parameter. My httpd.conf says:
   
   <P>
  -<PRE>  =item -DPERL_EMERGENCY_SBRK
  +<PRE>  ErrorLog var/logs/error_log
   </PRE>
   <P>
  -<PRE>  If PERL_EMERGENCY_SBRK is defined, running out of memory need not be a
  -  fatal error: a memory pool can allocated by assigning to the special
  -  variable $^M.  See perlvar(1) for more details.
  +Hey, where is the beginning of the path? There is another Apache parameter
  +called <CODE>ServerRoot</CODE>. Every time apache sees a value of the parameter with no absolute path
  +(e.g <CODE>/tmp/my.txt</CODE>) but with relative path (e.g <CODE>my.txt</CODE>) it prepends the value of the <CODE>ServerRoot</CODE> to this value. I have:
  +
  +<P>
  +<PRE>  ServerRoot /usr/local/apache
   </PRE>
   <P>
  -If you compile with that option and add '<CODE>use Apache::Debug level =&amp;gt;
  -4;</CODE>' to your PerlScript, it will allocate the $^M emergency pool and the
  -$SIG{__DIE__} handler will call Carp::confess, giving you a stack trace
  -which should reveal where the problem is. See the Apache::Resource module
  -for prevention of spinning httpds.
  +So I will look for error_log file at
  +<CODE>/usr/local/apache/var/logs/error_log</CODE>. Of course you can also use an absolute path to define the file's location
  +at the file system.
   
   <P>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<CENTER><H1><A NAME="_warn_child_process_30388_did_n">[warn] child process 30388 did not exit, sending another SIGHUP</A></H1></CENTER>
  +&lt;META&gt;: is this 100% correct?
  +
   <P>
  -From mod_perl.pod: With Apache versions 1.3.0 and higher, mod_perl will
  -call the <CODE>perl_destruct()</CODE> Perl API function during the child
  -exit phase. This will cause proper execution of <STRONG>END</STRONG> blocks found during server startup along with invoking the <STRONG>DESTROY</STRONG> method on global objects who are still alive. It is possible that this
  -operation may take a long time to finish, causing problems during a
  -restart. If your code does not contain and <STRONG>END</STRONG> blocks or <STRONG>DESTROY</STRONG> methods which need to be run during child server shutdown, this destruction
  -can be avoided by setting the <EM>PERL_DESTRUCT_LEVEL</EM> environment variable to <CODE>-1</CODE>.
  +But there are cases when errors don't go to the error_log file. For example
  +some errors are being printed to the console (tty) you have executed the
  +httpd from (unless you redirected the httpd's stderr flow). This happens
  +when the server didn't open the error_log file for writing yet.
   
   <P>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<CENTER><H1><A NAME="RegistryLoader_Cannot_translate">RegistryLoader: Cannot translate the URI /home/httpd/perl/test.pl</A></H1></CENTER>
  +For example, if you have mistakenly entered a non-existent directory path
  +in your <CODE>ErrorLog</CODE> directive, the error message will be printed on the controlling tty. Or, if
  +the error happens when server executes
  +<CODE>PerlRequire</CODE> or <CODE>PerlModule</CODE> directive you might see the errors here also.
  +
   <P>
  -<PRE>  RegistryLoader: Cannot translate the URI /home/httpd/perl/test.pl
  -              into a real path to the filename. Please refer to the
  -              manpage for more information
  -              or use the complete method's call like:
  -              $r-&gt;handler(uri,filename);\n&quot;;
  -</PRE>
  +You are probably wonder where all the errors go when you are running the
  +server in single mode (<CODE>httpd -X</CODE>). They go to the console. That is because when running in the single mode
  +there is no parent httpd process to perform all the logging. It includes
  +all the status messages that generally show up in the error_log file.
  +
   <P>
  -This warning shows up when RegistryLoader fails to translate the URI into
  -the corresponding filesystem path. Most of failures happen when one passes
  -a file path instead of URI. (A reminder: /home/httpd/perl/test.pl is a file
  -path, while /perl/test.pl is an URI). In most cases all you have to do is
  -to pass something that RegistryLoader expects to get - the URI, but there
  -are more complex cases. RegistryLoader's man page shows how to handle these
  -cases as well (watch for the <CODE>trans()</CODE> sub).
  +&lt;/META&gt;
   
   <P>
   <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>
  +<CENTER><H1><A NAME="Setting_environment_variables_fo">Setting environment variables for scripts called from CGI.</A></H1></CENTER>
   <P>
  -Not all Perl modules can survive a reload. PerlFreshRestart does not much
  -more than:
  +Perl uses <CODE>sh()</CODE> for its iteractions for <CODE>system()</CODE> and <CODE>open()</CODE>
  +calls. So when you want to set a temporary variable when you call a script
  +from your CGI you do:
   
   <P>
  -<PRE>  while (my($k,$v) = each %INC) {
  -    delete $INC{$k};
  -    require $k;
  -  }
  +<PRE> open UTIL, &quot;USER=stas ; script.pl | &quot; or die &quot;...: $!\n&quot;;
   </PRE>
   <P>
  -Besides that, it flushes the Apache::Registry cache, and empties any
  -dynamic stacked handlers (e.g. PerlChildInitHandler).
  +or
   
   <P>
  -Lots of SegFaults and other problems were reported by users who have turned <CODE>PerlFreshRestart</CODE>  <STRONG>On</STRONG>. Most of them have gone away when it was turned off. It doesn't mean that
  -you shouldn't use it, if it works for you. Just be aware of the dragons...
  +<PRE>  system &quot;USER=stas ; script.pl&quot;;
  +</PRE>
  +<P>
  +This is useful for example if you need to invoke a script that uses CGI.pm
  +from within a mod_perl script. We are tricking the perl script to think
  +it's a simple CGI, which is not running under mod_perl.
   
   <P>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<CENTER><H1><A NAME="server_reached_MaxClients_settin">server reached MaxClients setting, consider raising the MaxClients setting</A></H1></CENTER>
  +<PRE>  open(PUBLISH, &quot;GATEWAY_INTERFACE=CGI/1.1 ; script.cgi
  +       \&quot;param1=value1&amp;param2=value2\&quot; |&quot;) or die &quot;...: $!\n&quot;;
  +</PRE>
   <P>
  -See <A HREF="././performance.html#Choosing_MaxClients">Choosing MaxClients</A>.
  +Make sure, that the parameters you pass are shell safe (All ``unsafe''
  +characters like single-tick should be properly escaped).
  +
  +<P>
  +However you are fork-ing to run a Perl script, so you have thrown the so
  +hardly gained performance out the window. Whatever script.cgi is now, it
  +should be moved to a module with a subroutine you can call directly from
  +your script, to avoid the fork.
   
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
   	     The <a href="http://www.modperl.com/">
  @@ -9453,7 +10577,7 @@
   	     Amazon.com</a>.
   
   	     <HR>
  -	     [    <A HREF="obvious.html">Prev</A> |      <A HREF="index.html">Main Page</A> | <A HREF="control.html">Next</A>      ]
  +	     [    <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%" >
   <TR ALIGN=CENTER VALIGN=TOP>
  @@ -9466,7 +10590,7 @@
       <B>
         <FONT SIZE=-1>
   	     Written by <A HREF="help.html#This_document_s_Author">Stas Bekman</A>.
  -	     <BR>Last Modified at 06/19/1999
  +	     <BR>Last Modified at 06/27/1999
         </FONT>
       </B>
     </TD>
  @@ -9493,7 +10617,7 @@
   <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
   <HTML>
   <HEAD>
  -   <TITLE>mod_perl guide: Controlling and Monitoring the Server</TITLE>
  +   <TITLE>mod_perl guide: Runtime Warnings and Errors: Where and Why.</TITLE>
      <META NAME="GENERATOR" CONTENT="Pod2HTML [Perl/Linux]">
      <META NAME="Author" CONTENT="Stas Bekman">
      <META NAME="Description" CONTENT="All Apache/Perl related information: Hints, Guidelines, Scenarios and Troubleshottings">
  @@ -9512,22 +10636,31 @@
   <H1 ALIGN=CENTER>
   <A HREF="http://perl.apache.org"><IMG SRC="images/mod_perl.gif" ALT="Mod Perl Icon" BORDER=0 HEIGHT=30 WIDTH=90 ALIGN=LEFT></A>
   <A HREF="http://perl.apache.org"><IMG SRC="images/mod_perl.gif" ALT="Mod Perl Icon" BORDER=0 HEIGHT=30 WIDTH=90 ALIGN=RIGHT></A>
  -Controlling and Monitoring the Server</H1>
  +Runtime Warnings and Errors: Where and Why.</H1>
   <HR WIDTH="100%">
  -	    [    <A HREF="warnings.html">Prev</A> |      <A HREF="index.html">Main Page</A> | <A HREF="security.html">Next</A>      ]<HR><!-- INDEX BEGIN -->
  +	    [    <A HREF="obvious.html">Prev</A> |      <A HREF="index.html">Main Page</A> | <A HREF="security.html">Next</A>      ]<HR><!-- INDEX BEGIN -->
   <P><B><FONT SIZE=-1>Table of Contents:</FONT></B></P>
   <UL>
   
  -	<LI><A HREF="#Restarting_techniques">Restarting techniques</A>
  -	<LI><A HREF="#Implications_of_sending_TERM_HU">Implications of sending TERM, HUP, and USR1 to the server</A>
  -	<LI><A HREF="#Using_apachectl_to_control_the_s">Using apachectl to control the server</A>
  -	<LI><A HREF="#SUID_start_up_scripts">SUID start-up scripts</A>
  -	<LI><A HREF="#Monitoring_the_Server_A_watchdo">Monitoring the Server. A watchdog.</A>
  -	<LI><A HREF="#Running_server_in_a_single_mode">Running server in a single mode</A>
  -	<LI><A HREF="#Starting_a_personal_server_for_e">Starting a personal server for each developer</A>
  -	<LI><A HREF="#Wrapper_to_emulate_the_server_en">Wrapper to emulate the server environment</A>
  -	<LI><A HREF="#Log_Rotation">Log Rotation</A>
  -	<LI><A HREF="#Preventing_from_modperl_process_">Preventing from modperl process from going wild</A>
  +	<LI><A HREF="#General_Advice">General Advice </A>
  +	<LI><A HREF="#Incorrect_line_number_reporting_">Incorrect line number reporting in error/warn log messages</A>
  +	<LI><A HREF="#Value_of_x_will_not_stay_shared">Value of $x will not stay shared at - line 5</A>
  +	<LI><A HREF="#Value_of_x_may_be_unavailable_a">Value of $x may be unavailable at - line 5.</A>
  +	<LI><A HREF="#mod_perl_rwrite_returned_1">mod_perl: rwrite returned -1</A>
  +	<LI><A HREF="#caught_SIGPIPE_in_process">caught SIGPIPE in process</A>
  +	<LI><A HREF="#Client_hit_STOP_or_Netscape_bit_">Client hit STOP or Netscape bit it!</A>
  +	<LI><A HREF="#Constant_subroutine_redefine">Constant subroutine ... redefined</A>
  +	<LI><A HREF="#Global_symbol_foo_requires_ex">Global symbol &quot;$foo&quot; requires explicit package name</A>
  +	<LI><A HREF="#Can_t_undef_active_subroutine">Can't undef active subroutine</A>
  +	<LI><A HREF="#Use_of_uninitialized_value_at_e">Use of uninitialized value at (eval 80) line 12.</A>
  +	<LI><A HREF="#Undefined_subroutine_Apache_RO">Undefined subroutine &amp;Apache::ROOT::perl::test_2epl::some_function called at</A>
  +	<LI><A HREF="#Can_t_load_auto_DBI_DBI_so_">Can't load '.../auto/DBI/DBI.so' for module DBI</A>
  +	<LI><A HREF="#Callback_called_exit">Callback called exit</A>
  +	<LI><A HREF="#Out_of_memory_">Out of memory!</A>
  +	<LI><A HREF="#_warn_child_process_30388_did_n">[warn] child process 30388 did not exit, sending another SIGHUP</A>
  +	<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>
   </UL>
   <!-- INDEX END -->
   
  @@ -9544,915 +10677,353 @@
   	     <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>
  -<P>
  -All of these techniques require that you know the server PID (Process ID).
  -The easiest way to find the PID is to look it up in the httpd.pid file.
  -With my configuration it exists as
  -<CODE>/usr/apps/var/httpd_perl/run/httpd.pid</CODE>. It's easy to discover where to look at, by checking out the httpd.conf
  -file. Open the file and locate the entry <CODE>PidFile</CODE>:
  -
  -<P>
  -<PRE>  PidFile /usr/apps/var/httpd_perl/run/httpd.pid
  -</PRE>
  -<P>
  -Another way is to use the <CODE>ps</CODE> and <CODE>grep</CODE> utilities:
  -
  -<P>
  -<PRE>  % ps auxc | grep httpd_perl
  -</PRE>
  -<P>
  -or maybe:
  -
  -<P>
  -<PRE>  % ps -ef | grep httpd_perl
  -</PRE>
  -<P>
  -This will produce a list of all httpd_perl (the parent and the children)
  -processes. You are looking for the parent process. If you run your server
  -as root - you will easily locate it, since it belongs to root. If you run
  -the server as user (when you <A HREF="././install.html#Is_it_possible_to_install_and_us">don't have a root access</A>, most likely all the processes will belong to that user (unless defined
  -differently in the httpd.conf), but it's still easy to know 'who is the
  -parent' -- the one of the smallest size...
  -
  -<P>
  -You will notice many httpd_perl executables running on your system, but you
  -should not send signals to any of them except the parent, whose pid is in
  -the <CODE>PidFile</CODE>. That is to say you shouldn't ever need to send signals to any process
  -except the parent. There are three signals that you can send the parent:
  -TERM, HUP, and USR1.
  -
  -<P>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<CENTER><H1><A NAME="Implications_of_sending_TERM_HU">Implications of sending TERM, HUP, and USR1 to the server</A></H1></CENTER>
  -<P>
  -We will concentrate here on the implications of sending these signals to a
  -mod_perl-enabled server. For documentation on the implications of sending
  -these signals to a plain Apache server see <A
  -HREF="http://www.apache.org/docs/stopping.html">http://www.apache.org/docs/stopping.html</A>
  -.
  -
  -<DL>
  -<P><DT><STRONG><A NAME="item_TERM">TERM Signal: stop now</A></STRONG><DD>
  -<P>
  -Sending the TERM signal to the parent causes it to immediately attempt to
  -kill off all of its children. This process may take several seconds to
  -complete, following which the parent itself exits. Any requests in progress
  -are terminated, and no further requests are served. 
  -
  -<P>
  -That's the moment that the accumulated END{} blocks will be executed! Note
  -that if you use <STRONG>Apache::Registry</STRONG> or <STRONG>Apache::PerlRun</STRONG>, then END {} blocks are being executed upon each request (at the end).
  -
  -<P><DT><STRONG><A NAME="item_HUP">HUP Signal: restart now</A></STRONG><DD>
  -<P>
  -Sending the HUP signal to the parent causes it to kill off its children
  -like in TERM (Any requests in progress are terminated) but the parent
  -doesn't exit. It re-reads its configuration files, and re-opens any log
  -files. Then it spawns a new set of children and continues serving hits.
  -
  -<P>
  -The server will reread its configuration files, flush all the compiled and
  -preloaded modules, and rerun any startup files. It's equivalent to
  -stopping, then restarting a server.
  -
  -<P>
  -Note: If your configuration file has errors in it when you issue a restart
  -then your parent will not restart but exit with an error. See below for a
  -method of avoiding this.
  -
  -<P><DT><STRONG><A NAME="item_USR1">USR1 Signal: graceful restart</A></STRONG><DD>
  -<P>
  -The USR1 signal causes the parent process to advise the children to exit
  -after their current request (or to exit immediately if they're not serving
  -anything). The parent re-reads its configuration files and re-opens its log
  -files. As each child dies off the parent replaces it with a child from the
  -new generation of the configuration, which begins serving new requests
  -immediately. 
  -
  -<P>
  -The only difference between USR1 and HUP is that USR1 allows children to
  -complete any in-progress request prior to killing them off.
  -
  -<P>
  -By default, if a server is restarted (ala <CODE>kill -USR1 `cat
  -logs/httpd.pid`</CODE> or with HUP signal), Perl scripts and modules are not reloaded. To reload <STRONG>PerlRequire</STRONG>'s, <STRONG>PerlModule</STRONG>'s, other <CODE>use()'d</CODE> modules and flush the Apache::Registry
  -cache, enable with this command:
  -
  -<P>
  -<PRE> PerlFreshRestart On              (in httpd.conf) 
  -</PRE>
  -<P>
  -Make sure you read <A HREF="././warnings.html#Evil_things_might_happen_when_us">Evil things might happen when using PerlFreshRestart</A>.
  -
  -</DL>
  -<P>
  -It's worth mentioning that restart or termination can sometimes take quite
  -a lot of time. Check out the PERL_DESTRUCT_LEVEL=-1 option during the
  -mod_perl ./Configure stage, which speeds this up and leads to more robust
  -operation in the face of problems, like running out of memory. It is only
  -usable if no significant cleanup has to be done by perl END{} blocks and
  -DESTROY methods when the child terminates, of course. What constitutes
  -significant cleanup? Any change of state outside of the current process
  -that would not be handled by the operating system itself. So committing
  -database transactions is significant but closing an ordinary file isn't.
  -
  -<P>
  -Some folks prefer to specify signals using numerical values, rather than
  -symbolics. If you are looking for these, check out your
  -<CODE>kill(3)</CODE> man page. My page points to
  -<CODE>/usr/include/sys/signal.h</CODE>, the relevant entries are:
  -
  -<P>
  -<PRE>  #define SIGHUP     1    /* hangup, generated when terminal disconnects */ 
  -  #define SIGTERM   15    /* software termination signal */
  -  #define SIGUSR1   30    /* user defined signal 1 */
  -</PRE>
  -<P>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<CENTER><H1><A NAME="Using_apachectl_to_control_the_s">Using apachectl to control the server</A></H1></CENTER>
  -<P>
  -Apache's distribution provides a nice script to control the server. It's
  -called <STRONG>apachectl</STRONG> and it's installed into the same location with httpd. In our scenario -
  -it's /usr/apps/sbin/httpd_perl/apachectl
  -
  -<P>
  -Start httpd
  -
  -<P>
  -<PRE>        % /usr/apps/sbin/httpd_perl/apachectl start 
  -</PRE>
  -<P>
  -Stop httpd
  -
  -<P>
  -<PRE>        % /usr/apps/sbin/httpd_perl/apachectl stop
  -</PRE>
  -<P>
  -Restart httpd if running by sending a SIGHUP or start if not running
  -
  -<P>
  -<PRE>        % /usr/apps/sbin/httpd_perl/apachectl restart
  -</PRE>
  -<P>
  -Do a graceful restart by sending a SIGUSR1 or start if not running
  -
  -<P>
  -<PRE>        % /usr/apps/sbin/httpd_perl/apachectl graceful    
  -</PRE>
  -<P>
  -Do a configuration syntax test:
  -
   <P>
  -<PRE>        % /usr/apps/sbin/httpd_perl/apachectl configtest 
  -</PRE>
  +<CENTER><H1><A NAME="General_Advice">General Advice</A></H1></CENTER>
   <P>
  -See the next section for the implication of the above calls.
  +Enabling <CODE>use diagnostics;</CODE> generally helps you to determine the source of the problem and how to solve
  +it. See <A HREF="././porting.html#diagnostics_pragma">diagnostics pragma</A> for more info.
   
   <P>
  -Replace 'httpd_perl' with 'httpd_docs' in the above calls to control the
  -httpd_docs server.
  -
  +<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<CENTER><H1><A NAME="Incorrect_line_number_reporting_">Incorrect line number reporting in error/warn log messages</A></H1></CENTER>
   <P>
  -There are other options for <STRONG>apachectl</STRONG>, use 'help' option to see them all.
  +See <A HREF="././warnings.html#Use_of_uninitialized_value_at_e">Use of uninitialized value at (eval 80) line 12.</A>
   
  -<P>
  -It's important to understand that this script is based on the PID file
  -which is PIDFILE=/usr/apps/var/httpd_perl/run/httpd.pid. If you delete the
  -file by hand - <STRONG>apachectl</STRONG> will fail to run.
   
  -<P>
  -Also, note that <STRONG>apachectl</STRONG> is suitable to use from within your Unix system's startup files so that
  -your web server is automatically restarted upon system reboot. Either copy
  -the <STRONG>apachectl</STRONG> file to the appropriate location (<CODE>/etc/rc.d/rc3.d/S99apache</CODE> works on my RedHat Linux system) or create a symlink with that name
  -pointing to the the canonical location. (If you do this, make certain that
  -the script is writable only by root -- the startup scripts have root
  -privileges during init processing, and you don't want to be opening any
  -security holes.)
   
   <P>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<CENTER><H1><A NAME="SUID_start_up_scripts">SUID start-up scripts</A></H1></CENTER>
  -<P>
  -For those who wants to use SUID startup script, here is an example for you.
  -This script is SUID to <STRONG>root</STRONG>, and should be executable only by members of some special group at your
  -site. Note the 10th line, which ``fixes an obscure error when starting
  -apache/mod_perl'' by setting the real to the effective UID. As others have
  -pointed out, it is the mismatch between the real and the effective UIDs
  -that causes Perl to croak on the -e switch.
  -
  +<CENTER><H1><A NAME="Value_of_x_will_not_stay_shared">Value of $x will not stay shared at - line 5</A></H1></CENTER>
   <P>
  -Note that you must be using a version of Perl that recognizes and emulates
  -the suid bits in order for this to work. The script will do different
  -things depending on whether it is named ``start_http'', ``stop_http'' or
  -``restart_http''. You can use symbolic links for this purpose.
  +<A HREF="././obvious.html#my_scoped_variable_in_nested_s">my() scoped variable in nested subroutines</A>.
   
   <P>
  -<PRE> #!/usr/bin/perl
  - 
  - # These constants will need to be adjusted.
  - $PID_FILE = '/home/www/logs/httpd.pid';
  - $HTTPD = '/home/www/httpd -d /home/www';
  - 
  - # These prevent taint warnings while running suid
  - $ENV{PATH}='/bin:/usr/bin';
  - $ENV{IFS}='';
  - 
  - # This sets the real to the effective ID, and prevents
  - # an obscure error when starting apache/mod_perl
  - $&lt; = $&gt;;
  - $( = $) = 0; # set the group to root too
  - 
  - # Do different things depending on our name
  - ($name) = $0 =~ m|([^/]+)$|;
  - 
  - if ($name eq 'start_http') {
  -     system $HTTPD and die &quot;Unable to start HTTP&quot;;
  -     print &quot;HTTP started.\n&quot;;
  -     exit 0;
  - }
  - 
  - # extract the process id and confirm that it is numeric
  - $pid = `cat $PID_FILE`;
  - $pid =~ /(\d+)/ or die &quot;PID $pid not numeric&quot;;
  - $pid = $1;
  - 
  - if ($name eq 'stop_http') {
  -     kill 'TERM',$pid or die &quot;Unable to signal HTTP&quot;;
  -     print &quot;HTTP stopped.\n&quot;;
  -     exit 0;
  - }
  - 
  - if ($name eq 'restart_http') {
  -     kill 'HUP',$pid or die &quot;Unable to signal HTTP&quot;;
  -     print &quot;HTTP restarted.\n&quot;;
  -     exit 0;
  - }
  - 
  - die &quot;Script must be named start_http, stop_http, or restart_http.\n&quot;;
  -</PRE>
  -<P>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<CENTER><H1><A NAME="Monitoring_the_Server_A_watchdo">Monitoring the Server. A watchdog.</A></H1></CENTER>
  +<CENTER><H1><A NAME="Value_of_x_may_be_unavailable_a">Value of $x may be unavailable at - line 5.</A></H1></CENTER>
   <P>
  -With mod_perl many things can happen to your server. The worst one is the
  -possibility that the server will die when you will be not around. As with
  -any other critical service you need to run some kind of watchdog.
  +<A HREF="././obvious.html#my_scoped_variable_in_nested_s">my() scoped variable in nested subroutines</A>.
   
   <P>
  -One simple solution is to use a slightly modified <STRONG>apachectl</STRONG> script which I called apache.watchdog and to put it into the crontab to be
  -called every 30 minutes or even every minute - if it's so critical to make
  -sure the server will be up all the time.
  -
  +<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<CENTER><H1><A NAME="mod_perl_rwrite_returned_1">mod_perl: rwrite returned -1</A></H1></CENTER>
   <P>
  -Crontab entry:
  +That message happens when the client breaks the connection while your
  +script is trying to write to the client. With Apache 1.3.x, you should only
  +see the rwrite messages if LogLevel is set to debug.
   
  -<P>
  -<PRE>  0,30 * * * * /path/to/the/apache.watchdog &gt;/dev/null 2&gt;&amp;1
  -</PRE>
   <P>
  -The script:
  +This bug has been fixed in mod_perl 1.19_01 (CVS version).
   
   <P>
  -<PRE>  #!/bin/sh
  -    
  -  # this script is a watchdog to see whether the server is online
  -  # It tries to restart the server if it's
  -  # down and sends an email alert to admin 
  -  
  -  # admin's email
  -  EMAIL=webmaster@somewhere.far
  -  #EMAIL=root@localhost
  -    
  -  # the path to your PID file
  -  PIDFILE=/usr/apps/var/httpd_perl/run/httpd.pid
  -    
  -  # the path to your httpd binary, including options if necessary
  -  HTTPD=/usr/apps/sbin/httpd_perl/httpd_perl
  -        
  -  # check for pidfile
  -  if [ -f $PIDFILE ] ; then
  -    PID=`cat $PIDFILE`
  -    
  -    if kill -0 $PID; then
  -      STATUS=&quot;httpd (pid $PID) running&quot;
  -      RUNNING=1
  -    else
  -      STATUS=&quot;httpd (pid $PID?) not running&quot;
  -      RUNNING=0
  -    fi
  -  else
  -    STATUS=&quot;httpd (no pid file) not running&quot;
  -    RUNNING=0
  -  fi
  -      
  -  if [ $RUNNING -eq 0 ]; then
  -    echo &quot;$0 $ARG: httpd not running, trying to start&quot;
  -    if $HTTPD ; then
  -      echo &quot;$0 $ARG: httpd started&quot;
  -      mail $EMAIL -s &quot;$0 $ARG: httpd started&quot; &lt;/dev/null &gt;&amp; /dev/null
  -    else
  -      echo &quot;$0 $ARG: httpd could not be started&quot;
  -      mail $EMAIL -s &quot;$0 $ARG: httpd could not be started&quot; &lt;/dev/null &gt;&amp; /dev/null
  -    fi
  -  fi
  +<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<CENTER><H1><A NAME="caught_SIGPIPE_in_process">caught SIGPIPE in process</A></H1></CENTER>
  +<P>
  +<PRE>  [modperl] caught SIGPIPE in process 1234
  +  [modperl] process 1234 going to Apache::exit with status...
   </PRE>
   <P>
  -Another approach, probably even more practical, is to use the Cool LWP perl
  -package , to test the server by trying to fetch some document (script)
  -served by the server. Why is it more practical? While server can be up as a
  -process, it can be stuck and not working (SYN_RECV state - anyone??? Am I
  -getting a SYNC flood attack), So failing to get the document will trigger
  -restart, and ``probably'' the problem will go away. (Just replace <CODE>start</CODE> with <CODE>restart</CODE> in the
  -<CODE>$restart_command</CODE> below.
  +That's the <STRONG>$SIG{PIPE}</STRONG> handler installed by mod_perl/Apache::SIG, called if a connection timesout
  +or Client presses the 'Stop' button. It gives you an opportunity to do
  +cleanups if the script was aborted in the middle of its execution. See <A HREF="././obvious.html#Handling_the_User_pressed_Stop_">Handling the 'User pressed Stop button' case</A> for more info.
   
   <P>
  -Again we put this script into a crontab to call it every 30 minutes.
  -Personally I call it every minute, to fetch some very light script. Why so
  -often? If your server starts to spin and trash your disk's space with
  -multiply error messages. In a 5 minutes you might run out of free space,
  -which might bring your system to its knees. And most chances that no other
  -child will be able to serve requests, since the system will be too busy,
  -writing to an <CODE>error_log</CODE> file. Think big - if you running a heavy service, which is very fast, since
  -you are running under mod_perl, adding one more request every minute, will
  -be not felt by the server at all.
  +If your mod_perl version &lt; 1.17 you might get the message in the
  +following section...
   
   <P>
  -So we end up with crontab entry:
  -
  +<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<CENTER><H1><A NAME="Client_hit_STOP_or_Netscape_bit_">Client hit STOP or Netscape bit it!</A></H1></CENTER>
   <P>
  -<PRE>  * * * * * /path/to/the/watchdog.pl &gt;/dev/null 2&gt;&amp;1
  +<PRE>  Client hit STOP or Netscape bit it!
  +  Process 2493 going to Apache::exit with status=-2
   </PRE>
   <P>
  -And the watchdog itself:
  +You will see this message in mod_perl &lt; 1.17. See <A HREF="././warnings.html#caught_SIGPIPE_in_process">caught SIGPIPE in process</A>.
   
   <P>
  -<PRE>  #!/usr/local/bin/perl -w
  -  
  -  use strict;
  -  use diagnostics;
  -  use URI::URL;
  -  use LWP::MediaTypes qw(media_suffix);
  -  
  -  my $VERSION = '0.01';
  -  use vars qw($ua $proxy);
  -  
  -  require LWP::UserAgent;
  -  use HTTP::Status;
  -  
  -  ###### Config ########
  -  my $test_script_url = '<A HREF="http://www.stas.com:81/perl/test.pl">http://www.stas.com:81/perl/test.pl</A>';
  -  my $monitor_email   = 'root@localhost';
  -  my $restart_command = '/usr/apps/sbin/httpd_perl/apachectl start';
  -  my $mail_program    = '/usr/lib/sendmail -t -n';
  -  ######################
  -  
  -  $ua  = new LWP::UserAgent;
  -  $ua-&gt;agent(&quot;$0/Stas &quot; . $ua-&gt;agent);
  -  # Uncomment the proxy if you don't use it!
  -  #  $proxy=&quot;<A HREF="http://www-proxy.com&quot">http://www-proxy.com&quot</A>;;
  -  $ua-&gt;proxy('http', $proxy) if $proxy;
  -  
  -  # If returns '1' it's we are alive
  -  exit 1 if checkurl($test_script_url);
  -  
  -  # We have got the problem - the server seems to be down. Try to
  -  # restart it. 
  -  my $status = system $restart_command;
  -  #  print &quot;Status $status\n&quot;;
  -  
  -  my $message = ($status == 0) 
  -              ? &quot;Server was down and successfully restarted!&quot; 
  -              : &quot;Server is down. Can't restart.&quot;;
  -    
  -  my $subject = ($status == 0) 
  -              ? &quot;Attention! Webserver restarted&quot;
  -              : &quot;Attention! Webserver is down. can't restart&quot;;
  -  
  -  # email the monitoring person
  -  my $to = $monitor_email;
  -  my $from = $monitor_email;
  -  send_mail($from,$to,$subject,$message);
  -  
  -  # input:  URL to check 
  -  # output: 1 if success, o for fail  
  -  #######################  
  -  sub checkurl{
  -    my ($url) = @_;
  -  
  -    # Fetch document 
  -    my $res = $ua-&gt;request(HTTP::Request-&gt;new(GET =&gt; $url));
  -  
  -    # Check the result status
  -    return 1 if is_success($res-&gt;code);
  -  
  -    # failed
  -    return 0;
  -  } #  end of sub checkurl
  -  
  -  # sends email about the problem 
  -  #######################  
  -  sub send_mail{
  -    my($from,$to,$subject,$messagebody) = @_;
  -  
  -    open MAIL, &quot;|$mail_program&quot;
  -        or die &quot;Can't open a pipe to a $mail_program :$!\n&quot;;
  -   
  -    print MAIL &lt;&lt;__END_OF_MAIL__;
  -  To: $to
  -  From: $from
  -  Subject: $subject
  -  
  -  $messagebody
  -  
  -  __END_OF_MAIL__
  -  
  -    close MAIL;
  -  } 
  -</PRE>
  -<P>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<CENTER><H1><A NAME="Running_server_in_a_single_mode">Running server in a single mode</A></H1></CENTER>
  +<CENTER><H1><A NAME="Constant_subroutine_redefine">Constant subroutine ... redefined</A></H1></CENTER>
   <P>
  -Often while developing new code, you will want to run the server in single
  -process mode. See <A HREF="././porting.html#Sometimes_it_Works_Sometimes_it_">Sometimes it works Sometimes it does Not</A> and <A HREF="././porting.html#Name_collisions_with_Modules_and">Names collisions with Modules and libs</A>
  -Running in single process mode inhibits the server from ``daemonizing'',
  -allowing you to run it more easily under debugger control.
  +That's a mandatory warning inside Perl. It happens only if you modify your
  +script and Apache::Registry reloads it. Perl is warning you that the
  +<CODE>subroutine(s)</CODE> were redefined. It is mostly harmless. If you
  +don't like seeing those, just <CODE>kill -USR2</CODE> (graceful restart) apache when you modify your scripts.
   
   <P>
  -<PRE>  % /usr/apps/sbin/httpd_perl/httpd_perl -X
  +<PRE>  &lt;META&gt;
  +  Someone said: 
  +  You won't see that warning in this case with 5.004_05 or 5.005+. 
   </PRE>
  -<P>
  -When you execute the above the server will run in the fg (foreground) of
  -the shell you have called it from. So to kill you just kill it with Ctrl-C.
  -
   <P>
  -Note that in -X mode the server will run very slowly while fetching images.
  -If you use Netscape while your server is running in single-process mode,
  -HTTP's ``KeepAlive'' feature gets in the way. Netscape tries to open
  -multiple connections and keep them open. Because there is only one server
  -process listening, each connection has to time-out before the next
  -succeeds. Turn off KeepAlive in httpd.conf to avoid this effect while
  -developing or you can press <STRONG>STOP</STRONG> after a few seconds (assuming you use the image size params, so the
  -Netscape will be able to render the rest of the page).
  -
  +<PRE>  I'm running perl5.00502 and I still get these warnings???
  +</PRE>
   <P>
  -In addition you should know that when running with -X you will not see any
  -control messages that the parent server normally writes to the error_log.
  -(Like ``server started, server stopped and etc''.) Since
  -<CODE>httpd -X</CODE> causes the server to handle all requests itself, without forking any
  -children, there is no controlling parent to write status messages.
  -
  +<PRE>  Who is right?
  +  &lt;/META&gt;
  +</PRE>
   <P>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<CENTER><H1><A NAME="Starting_a_personal_server_for_e">Starting a personal server for each developer</A></H1></CENTER>
  +<CENTER><H1><A NAME="Global_symbol_foo_requires_ex">Global symbol &quot;$foo&quot; requires explicit package name</A></H1></CENTER>
   <P>
  -If you are the only developer working on the specific server:port - you
  -have no problems, since you have a complete control over the server.
  -However, many times you have a group of developers who need to concurrently
  -develop their own mod_perl scripts. This means that each one will want to
  -have control over the server - to kill it, to run it in single server mode,
  -to restart it again, etc., as well to have control over the location of the
  -log files and other configuration settings like <STRONG>MaxClients</STRONG>, etc. You can work around this problem by preparing a few httpd.conf file
  -and forcing each developer to use:
  +The script below will print a warning like above, moreover it will print
  +the whole script as a part of the warning message:
   
   <P>
  -<PRE>  httpd_perl -f /path/to/httpd.conf  
  +<PRE>  #!/usr/bin/perl -w
  +  use strict;
  +  print &quot;Content-type: text/html\n\n&quot;;
  +  print &quot;Hello $undefined&quot;;
   </PRE>
   <P>
  -I have approached it in other way. I have used the -Dparameter startup
  -option of the server. I call my version of the server
  +The warning:
   
   <P>
  -<PRE>  % http_perl -Dsbekman
  +<PRE>  Global symbol &quot;$undefined&quot; requires explicit package name at /usr/apps/foo/cgi/tmp.pl line 4.
  +          eval 'package Apache::ROOT::perl::tmp_2epl;use Apache qw(exit);sub handler {
  +  #line 1 /usr/apps/foo/cgi/tmp.pl
  +  BEGIN {$^W = 1;}#!/usr/bin/perl -w
  +  use strict;
  +  print &quot;Content-type: text/html\\n\\n&quot;;
  +  print &quot;Hello $undefined&quot;;
  +  
  +  
  +  }
  +  ;' called at /usr/apps/lib/perl5/site_perl/5.005/aix/Apache/Registry.pm line 168
  +          Apache::Registry::compile('package
  +        Apache::ROOT::perl::tmp_2epl;use Apache qw(exit);sub han...') 
  +        called at /usr/apps/lib/perl5/site_perl/5.005/aix/Apache/Registry.pm line 121
  +          Apache::Registry::handler('Apache=SCALAR(0x205026c0)') called at /usr/apps/foo/cgi/tmp.pl line 4
  +          eval {...} called at /usr/apps/foo/cgi/tmp.pl line 4
  +  [Sun Nov 15 15:15:30 1998] [error] Undefined subroutine &amp;Apache::ROOT::perl::tmp_2epl::handler called at /
  +  usr/apps/lib/perl5/site_perl/5.005/aix/Apache/Registry.pm line 135.
  +  
  +  [Sun Nov 15 15:15:30 1998] [error] Goto undefined subroutine &amp;Apache::Constants::SERVER_ERROR at /usr/apps
  +  /lib/perl5/site_perl/5.005/aix/Apache/Constants.pm line 23.
   </PRE>
   <P>
  -In <CODE>httpd.conf</CODE> I wrote:
  +The error is simple to fix. When you use the <CODE>use strict;</CODE> pragma (and you should...), all variables should be defined before being
  +used.
   
  -<P>
  -<PRE>  # Personal development Server for sbekman
  -  # sbekman use the server running on port 8000
  -  &lt;IfDefine sbekman&gt;
  -  Port 8000
  -  PidFile /usr/apps/var/httpd_perl/run/httpd.pid.sbekman
  -  ErrorLog /usr/apps/var/httpd_perl/logs/error_log.sbekman
  -  Timeout 300
  -  KeepAlive On
  -  MinSpareServers 2
  -  MaxSpareServers 2
  -  StartServers 1
  -  MaxClients 3
  -  MaxRequestsPerChild 15
  -  &lt;/IfDefine&gt;
  -  
  -  # Personal development Server for userfoo
  -  # userfoo use the server running on port 8001
  -  &lt;IfDefine userfoo&gt;
  -  Port 8001
  -  PidFile /usr/apps/var/httpd_perl/run/httpd.pid.userfoo
  -  ErrorLog /usr/apps/var/httpd_perl/logs/error_log.userfoo
  -  Timeout 300
  -  KeepAlive Off
  -  MinSpareServers 1
  -  MaxSpareServers 2
  -  StartServers 1
  -  MaxClients 5
  -  MaxRequestsPerChild 0
  -  &lt;/IfDefine&gt;
  -</PRE>
   <P>
  -What we have achieved with this technique: Full control over start/stop,
  -number of children, separate error log file, and port selection. This saves
  -me from getting called every few minutes - ``Stas, I'm going to restart the
  -server''.
  +The bad thing is that sometimes the whole script (possibly, thousands of
  +lines) is printed to error_log file as a code that the server has tried to <STRONG>eval()</STRONG>uate.
   
   <P>
  -To make things even easier. (In the above technique, you have to discover
  -the PID of your parent httpd_perl process - written in
  -/usr/apps/var/httpd_perl/run/httpd.pid.userfoo) . We change the
  -<STRONG>apachectl</STRONG> script to do the work for us. We make a copy for each developer called <STRONG>apachectl.username</STRONG> and we change 2 lines in script:
  +As Doug answered to this question:
   
   <P>
  -<PRE>  PIDFILE=/usr/apps/var/httpd_perl/run/httpd.pid.sbekman
  -  HTTPD='/usr/apps/sbin/httpd_perl/httpd_perl -Dsbekman'
  +<PRE> Looks like you have a $SIG{__DIE__} handler installed (Carp::confess?).
  + That's what's expected if so.
   </PRE>
   <P>
  -Of course you think you can use only one control file and know who is
  -calling by using uid, but since you have to be root to start the server -
  -it is not so simple.
  +It wasn't in my case, but may be yours. 
   
   <P>
  -The last thing was to let developers an option to run in single process
  -mode by:
  +Bryan Miller said:
   
   <P>
  -<PRE>  /usr/apps/sbin/httpd_perl/httpd_perl -Dsbekman -X
  +<PRE> You might wish to try something more terse such as 
  + &quot;local $SIG{__WARN__} = \&amp;Carp::cluck;&quot;  The confess method is _very_
  + verbose and will tell you more than you might wish to know including
  + full source.
   </PRE>
   <P>
  -In addition to making life easier, we decided to use relative links
  -everywhere in the static docs (including the calls to CGIs). You may ask
  -how using the relative link you will get to the right server? Very simple -
  -we have utilized the mod_rewrite to solve our problems:
  +<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<CENTER><H1><A NAME="Can_t_undef_active_subroutine">Can't undef active subroutine</A></H1></CENTER>
  +<P>
  +<PRE>  Can't undef active subroutine at /usr/apps/lib/perl5/site_perl/5.005/aix/Apache/Registry.pm line 102. 
  +  Called from package Apache::Registry, filename /usr/apps/lib/perl5/site_perl/5.005/aix/Apache/Registry.pm, line 102 
  +</PRE>
  +<P>
  +This problem is caused when, a client drops the connection while httpd is
  +in the middle of a write, httpd timeout happens, sending a SIGPIPE, and
  +Perl in that child is stuck in the middle of its eval context. This is
  +fixed by the Apache::SIG module which is called by default. This should not
  +happen unless you have code that is messing with <STRONG>$SIG{PIPE}</STRONG>. It's also triggered only when you've changed your script on disk and
  +mod_perl is trying to reload it.
   
   <P>
  -In access.conf of the httpd_docs server we have the following code: (you
  -have to configure your httpd_docs server with
  -<CODE>--enable-module=rewrite</CODE> )
  +<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<CENTER><H1><A NAME="Use_of_uninitialized_value_at_e">Use of uninitialized value at (eval 80) line 12.</A></H1></CENTER>
  +<P>
  +Your code includes some undefined variable that you have used as if it was
  +already defined and initialized. For example:
   
   <P>
  -<PRE>  # sbekman' server
  -  # port = 8000
  -  RewriteCond  %{REQUEST_URI} ^/(perl|cgi-perl)  
  -  RewriteCond  %{REMOTE_ADDR} 123.34.45.56
  -  RewriteRule ^(.*)           <A HREF="http://ourserver.com:8000/">http://ourserver.com:8000/</A>$1 [R,L]
  -  
  -  # userfoo's server
  -  # port = 8001
  -  RewriteCond  %{REQUEST_URI} ^/(perl|cgi-perl)  
  -  RewriteCond  %{REMOTE_ADDR} 123.34.45.57
  -  RewriteRule ^(.*)           <A HREF="http://ourserver.com:8001/">http://ourserver.com:8001/</A>$1 [R,L]
  -  
  -  # all the rest
  -  RewriteCond  %{REQUEST_URI} ^/(perl|cgi-perl)  
  -  RewriteRule ^(.*)           <A HREF="http://ourserver.com:81/">http://ourserver.com:81/</A>$1 [R]
  -  
  +<PRE>  $param = $q-&gt;param('test');
  +  print $param;
   </PRE>
   <P>
  -where IP numbers are the IPs of the developers' client machines (where they
  -are running their web browser.) (I have tried to use REMOTE_USER since we
  -have all the users authenticated but it did not work for me)
  -
  +<PRE>  vs.
  +</PRE>
   <P>
  -So if I have a relative URL like <CODE>/perl/test.pl</CODE> written in some html or even <A
  -HREF="http://ourserver.com/perl/test.pl">http://ourserver.com/perl/test.pl</A>
  -in my case (user at machine of sbekman) it will be redirected by httpd_docs
  -to <A
  -HREF="http://ourserver.com:8000/perl/test.pl">http://ourserver.com:8000/perl/test.pl</A>
  -
  -
  +<PRE>  $param = $q-&gt;param('test') || '';
  +  print $param;
  +</PRE>
   <P>
  -Of course you have another problem: The cgi generates some html, which
  -should be called again. If it generates a URL with hard coded PORT the
  -above scheme will not work. There 2 solutions:
  +In the second case, <CODE>$param</CODE> will always be <CODE>defined</CODE>, either
  +<CODE>$q-&amp;gt;param('test')</CODE> returns some value or <CODE>undef</CODE>.
   
   <P>
  -First, generate relative URL so it will reuse the technique above, with
  -redirect (which is transparent for user) but it will not work if you have
  -something to POST (redirect looses all the data!).
  +Also read about <A HREF="././porting.html#Finding_the_line_number_the_erro">finding the line number the error/warning has been triggered at</A>.
   
   <P>
  -Second, use a general configuration module which generates a correct full
  -URL according to REMOTE_USER, so if <CODE>$ENV{REMOTE_USER} eq
  -'sbekman'</CODE>, I return <A
  -HREF="http://ourserver.com:8000/perl/">http://ourserver.com:8000/perl/</A>
  -as
  -<CODE>cgi_base_url</CODE>. Again this will work if the user is authenticated.
  -
  +<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<CENTER><H1><A NAME="Undefined_subroutine_Apache_RO">Undefined subroutine &amp;Apache::ROOT::perl::test_2epl::some_function called at</A></H1></CENTER>
   <P>
  -All this is good for development. It is better to use the full URLs in
  -production, since if you have a static form and the <CODE>Action</CODE> is relative but the static document located on another server, pressing the
  -form's submit will cause a redirect to mod_perl server, but all the form's
  -data will be lost during the redirect.
  +See <A HREF="././porting.html#Name_collisions_with_Modules_and">Names collisions with Modules and libs</A>.
   
   <P>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<CENTER><H1><A NAME="Wrapper_to_emulate_the_server_en">Wrapper to emulate the server environment</A></H1></CENTER>
  +<CENTER><H1><A NAME="Can_t_load_auto_DBI_DBI_so_">Can't load '.../auto/DBI/DBI.so' for module DBI</A></H1></CENTER>
   <P>
  -Many times you start off debugging your script by running it from your
  -favorite shell. Sometimes you encounter a very weird situation when script
  -runs from the shell but dies when called as a CGI. The real problem lies in
  -the difference between the environment that is being used by your server
  -and your shell. An example can be a different perl path or having PERL5LIB
  -env variable which includes paths that are not in the <CODE>@INC</CODE> of
  -the perl compiled with mod_perl server and configured during the startup.
  +Check that all your modules are compiled with the same perl that is being
  +compiled into mod_perl. perl 5.005 and 5.004 are not binary compatible by
  +default.
   
   <P>
  -The best debugging approach is to write a wrapper that emulates the exact
  -environment of the server, by first deleting the environment variables like
  -PERL5LIB and calling the same perl binary that it is being used by the
  -server. Next, set the environment identical to the server's by copying the
  -perl run directives from server startup and configuration files. It will
  -also allow you to remove completely the first line of the script - since
  -mod_perl skips it and the wrapper knows how to call the script.
  +Other known causes of this problem: OS distributions that ship with a
  +(broken) binary Perl installation. The `perl' program and `libperl.a'
  +library are somehow built with different binary compatibility flags.
   
   <P>
  -Below is the example of such a script. Note that we force the -Tw when we
  -call the real script. (I have also added the ability to pass params, which
  -will not happen when you call the cgi from the web)
  +The solution to these problems is to rebuild Perl and any extension modules
  +from a fresh source tree. Tip for running Perl's Configure script: use the
  +`-des' flags to accepts defaults and `-D' flag to override certain
  +attributes:
   
   <P>
  -<PRE>  #!/usr/apps/bin/perl -w    
  -   
  -  # This is a wrapper example 
  -   
  -  # It simulates the web server environment by setting the @INC and other
  -  # stuff, so what will run under this wrapper will run under web and
  -  # vice versa. 
  -  
  -  #
  -  # Usage: wrap.pl some_cgi.pl
  -  #
  -  
  -  BEGIN{
  -    use vars qw($basedir);
  -    $basedir = &quot;/usr/apps&quot;;
  -  
  -    # we want to make a complete emulation, so we must remove the
  -    # user's environment
  -    @INC = ();
  -  
  -    # local perl libs
  -    push @INC, (&quot;$basedir/lib/perl5/5.00502/aix&quot;,
  -                &quot;$basedir/lib/perl5/5.00502&quot;,
  -                &quot;$basedir/lib/perl5/site_perl/5.005/aix&quot;,
  -                &quot;$basedir/lib/perl5/site_perl/5.005&quot;,
  -               );
  -  }
  -  
  -  use strict;
  -  use File::Basename;
  -  
  -    # process the passed params
  -  my $cgi = shift || '';
  -  my $params = (@ARGV) ? join(&quot; &quot;, @ARGV) : '';
  -  
  -  die &quot;Usage:\n\t$0 some_cgi.pl\n&quot; unless $cgi;
  -  
  -    # Set the environment
  -  my $PERL5LIB = join &quot;:&quot;, @INC;
  -  
  -    # if the path includes the directory we extract it and chdir there
  -  if ($cgi =~ m|/|) {
  -    my $dirname = dirname($cgi);
  -    chdir $dirname or die &quot;Can't chdir to $dirname: $! \n&quot;;
  -    $cgi =~ m|$dirname/(.*)|;
  -    $cgi = $1;
  -  }
  -  
  -    # run the cgi from the script's directory
  -    # Note that we invoke warnings and Taintness ON!!!
  -  system qq{$basedir/bin/perl -I$PERL5LIB -Tw $cgi $params};
  +<PRE>  % ./Configure -des -Dcc=gcc ... &amp;&amp; make test &amp;&amp; make install
  + 
  +Read Perl's INSTALL doc for more details.
   </PRE>
  -<P>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<CENTER><H1><A NAME="Log_Rotation">Log Rotation</A></H1></CENTER>
   <P>
  -A little bit off topic but good to know and use with mod_perl where your
  -error_log can grow at a 10-100Mb per day rate if your scripts spit out lots
  -of warnings...
  +Solaris OS specific: 
   
   <P>
  -To rotate the logs do:
  +Can't load DBI or similar Error for the IO module or whatever dynamic
  +module mod_perl tries to pull in first. The solution is to re-configure,
  +re-build and re-install Perl and dynamic modules with the following flags
  +when Configure asks for ``additional LD flags'': -Xlinker --export-dynamic
  +or
   
   <P>
  -<PRE>  mv access_log access_log.renamed
  -  kill -HUP `cat httpd.pid`
  -  sleep 10; # allow some children to complete requests and logging
  -  # now it's safe to use access_log.renamed
  -  .....
  +<PRE>  -Xlinker -E
   </PRE>
   <P>
  -The effect of SIGUSR1 and SIGHUP is detailed in: <A
  -HREF="http://www.apache.org/docs/stopping.html">http://www.apache.org/docs/stopping.html</A>
  -
  +This problem is only known to be caused by installing gnu ld under Solaris.
   
  +<P>
  +<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<CENTER><H1><A NAME="Callback_called_exit">Callback called exit</A></H1></CENTER>
   <P>
  -&lt;META&gt;I tried to kill -USR1 and it did not reset the logs!!! kill
  --HUP did work&lt;/META&gt;
  +See <A HREF="#Out_of_memory_">Out_of_memory!</A>
  +
   
  +
   <P>
  -I use this script:
  +I've just discovered that my server is not responding and its error log has
  +filled up the remaining space on the file system (about a gig's worth). The
  +error_log includes millions of lines:
   
   <P>
  -<PRE>  #!/usr/apps/bin/perl -Tw
  -  
  -  # this script does a log rotation. Called from crontab.
  -  
  -  use strict;
  -  $ENV{PATH}='/bin:/usr/bin';
  -  
  -  ### configuration
  -  my @logfiles = qw(access_log error_log);
  -  umask 0;
  -  my $server = &quot;httpd_perl&quot;;
  -  my $logs_dir = &quot;/usr/apps/var/$server/logs&quot;;
  -  my $restart_command = &quot;/usr/apps/sbin/$server/apachectl restart&quot;;
  -  my $gzip_exec = &quot;/usr/intel/bin/gzip&quot;;
  -  
  -  my ($sec,$min,$hour,$mday,$mon,$year) = localtime(time);
  -  my $time = sprintf &quot;%0.2d.%0.2d.%0.2d-%0.2d.%0.2d.%0.2d&quot;, $year,++$mon,$mday,$hour,$min,$sec;
  -  $^I = &quot;.&quot;.$time;
  -  
  -  # rename log files
  -  chdir $logs_dir;
  -  @ARGV = @logfiles;
  -  while (&lt;&gt;) {
  -    close ARGV;
  -  }
  -  
  -  # now restart the server so the logs will be restarted
  -  system $restart_command;
  -  
  -  # compress log files
  -  foreach (@logfiles) {
  -      system &quot;$gzip_exec $_.$time&quot;;
  -  }
  +<PRE>  Callback called exit at -e line 33, &lt;HTML&gt; chunk 1.
   </PRE>
   <P>
  -Randal L. Schwartz contributed this:
  +Why the looping?
   
  -<BLOCKQUOTE>
  +<P>
  +Perl can get *very* confused inside an endless loop in your code, it
  +doesn't mean your code called 'exit', but Perl's malloc went haywire and
  +called <CODE>croak(),</CODE> but no memory is left to properly report the
  +error, so Perl is stuck in a loop writing that same message to stderr.
   
   <P>
  -Cron fires off setuid script called log-roller that looks like this:
  +Perl 5.005+ plus is recommended for its improved malloc.c and features
  +mentioned in mod_perl_traps.pod on by default.
   
   <P>
  -<PRE>    #!/usr/bin/perl -Tw
  -    use strict;
  -    use File::Basename;
  -    
  -    $ENV{PATH} = &quot;/usr/ucb:/bin:/usr/bin&quot;;
  -    
  -    my $ROOT = &quot;/WWW/apache&quot;; # names are relative to this
  -    my $CONF = &quot;$ROOT/conf/httpd.conf&quot;; # master conf
  -    my $MIDNIGHT = &quot;MIDNIGHT&quot;;  # name of program in each logdir
  -    
  -    my ($user_id, $group_id, $pidfile); # will be set during parse of conf
  -    die &quot;not running as root&quot; if $&gt;;
  -    
  -    chdir $ROOT or die &quot;Cannot chdir $ROOT: $!&quot;;
  -    
  -    my %midnights;
  -    open CONF, &quot;&lt;$CONF&quot; or die &quot;Cannot open $CONF: $!&quot;;
  -    while (&lt;CONF&gt;) {
  -      if (/^User (\w+)/i) {
  -        $user_id = getpwnam($1);
  -        next;
  -      }
  -      if (/^Group (\w+)/i) {
  -        $group_id = getgrnam($1);
  -        next;
  -      }
  -      if (/^PidFile (.*)/i) {
  -        $pidfile = $1;
  -        next;
  -      }
  -     next unless /^ErrorLog (.*)/i;
  -      my $midnight = (dirname $1).&quot;/$MIDNIGHT&quot;;
  -      next unless -x $midnight;
  -      $midnights{$midnight}++;
  -    }
  -    close CONF;
  -    
  -    die &quot;missing User definition&quot; unless defined $user_id;
  -    die &quot;missing Group definition&quot; unless defined $group_id;
  -    die &quot;missing PidFile definition&quot; unless defined $pidfile;
  -    
  -    open PID, $pidfile or die &quot;Cannot open $pidfile: $!&quot;;
  -    &lt;PID&gt; =~ /(\d+)/;
  -    my $httpd_pid = $1;
  -    close PID;
  -    die &quot;missing pid definition&quot; unless defined $httpd_pid and $httpd_pid;
  -    kill 0, $httpd_pid or die &quot;cannot find pid $httpd_pid: $!&quot;;
  -    
  -    
  -    for (sort keys %midnights) {
  -      defined(my $pid = fork) or die &quot;cannot fork: $!&quot;;
  -      if ($pid) {
  -        ## parent:
  -        waitpid $pid, 0;
  -      } else {
  -        my $dir = dirname $_;
  -        ($(,$)) = ($group_id,$group_id);
  -        ($&lt;,$&gt;) = ($user_id,$user_id);
  -        chdir $dir or die &quot;cannot chdir $dir: $!&quot;;
  -        exec &quot;./$MIDNIGHT&quot;;
  -        die &quot;cannot exec $MIDNIGHT: $!&quot;;
  -      }
  -    }
  -    
  -    kill 1, $httpd_pid or die &quot;Cannot sighup $httpd_pid: $!&quot;;
  -</PRE>
  +<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<CENTER><H1><A NAME="Out_of_memory_">Out of memory!</A></H1></CENTER>
   <P>
  -And then individual MIDNIGHT scripts can look like this:
  +If something goes really wrong with your code, Perl may die with an ``Out
  +of memory!'' message and/or ``Callback called exit''. Common causes of this
  +are never-ending loops, deep recursion, or calling an undefined subroutine.
  +Here's one way to catch the problem: See Perl's INSTALL document for this
  +item: 
   
   <P>
  -<PRE>    #!/usr/bin/perl -Tw
  -    use strict;
  -    
  -    die &quot;bad guy&quot; unless getpwuid($&lt;) =~ /^(root|nobody)$/;
  -    my @LOGFILES = qw(access_log error_log);
  -    umask 0;
  -    $^I = &quot;.&quot;.time;
  -    @ARGV = @LOGFILES;
  -    while (&lt;&gt;) {
  -      close ARGV;
  -    }
  +<PRE>  =item -DPERL_EMERGENCY_SBRK
   </PRE>
   <P>
  -Can you spot the security holes? Our trusted user base can't or won't. :)
  -But these shouldn't be used in hostile situations.
  -
  -</BLOCKQUOTE>
  +<PRE>  If PERL_EMERGENCY_SBRK is defined, running out of memory need not be a
  +  fatal error: a memory pool can allocated by assigning to the special
  +  variable $^M.  See perlvar(1) for more details.
  +</PRE>
  +<P>
  +If you compile with that option and add '<CODE>use Apache::Debug level =&amp;gt;
  +4;</CODE>' to your PerlScript, it will allocate the $^M emergency pool and the
  +$SIG{__DIE__} handler will call Carp::confess, giving you a stack trace
  +which should reveal where the problem is. See the Apache::Resource module
  +for prevention of spinning httpds.
   
   <P>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<CENTER><H1><A NAME="Preventing_from_modperl_process_">Preventing from modperl process from going wild</A></H1></CENTER>
  +<CENTER><H1><A NAME="_warn_child_process_30388_did_n">[warn] child process 30388 did not exit, sending another SIGHUP</A></H1></CENTER>
   <P>
  -Sometimes calling an undefined subroutine in a module can cause a tight
  -loop that consumes all memory. Here is a way to catch such errors. Define
  -an autoload subroutine:
  +From mod_perl.pod: With Apache versions 1.3.0 and higher, mod_perl will
  +call the <CODE>perl_destruct()</CODE> Perl API function during the child
  +exit phase. This will cause proper execution of <STRONG>END</STRONG> blocks found during server startup along with invoking the <STRONG>DESTROY</STRONG> method on global objects who are still alive. It is possible that this
  +operation may take a long time to finish, causing problems during a
  +restart. If your code does not contain and <STRONG>END</STRONG> blocks or <STRONG>DESTROY</STRONG> methods which need to be run during child server shutdown, this destruction
  +can be avoided by setting the <EM>PERL_DESTRUCT_LEVEL</EM> environment variable to <CODE>-1</CODE>.
   
   <P>
  -<PRE>  sub UNIVERSAL::AUTOLOAD {
  -          my $class = shift;
  -          warn &quot;$class can't \$UNIVERSAL::AUTOLOAD!\n&quot;;
  -  }
  +<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<CENTER><H1><A NAME="RegistryLoader_Cannot_translate">RegistryLoader: Cannot translate the URI /home/httpd/perl/test.pl</A></H1></CENTER>
  +<P>
  +<PRE>  RegistryLoader: Cannot translate the URI /home/httpd/perl/test.pl
  +              into a real path to the filename. Please refer to the
  +              manpage for more information
  +              or use the complete method's call like:
  +              $r-&gt;handler(uri,filename);\n&quot;;
   </PRE>
   <P>
  -It will produce a nice error in error_log, giving the line number of the
  -call and the name of the undefined subroutine.
  +This warning shows up when RegistryLoader fails to translate the URI into
  +the corresponding filesystem path. Most of failures happen when one passes
  +a file path instead of URI. (A reminder: /home/httpd/perl/test.pl is a file
  +path, while /perl/test.pl is an URI). In most cases all you have to do is
  +to pass something that RegistryLoader expects to get - the URI, but there
  +are more complex cases. RegistryLoader's man page shows how to handle these
  +cases as well (watch for the <CODE>trans()</CODE> sub).
   
   <P>
  -Sometimes an error happens and causes the server to write millions of lines
  -into your error_log file and in a few minutes to put your server down on
  -its knees. For example I get an error <CODE>Callback called exit</CODE>
  -show up in my error_log file many times. The error_log files grows to 300
  -Mbytes in size in a few minutes. You should run a cron job to make sure
  -this does not happen and if it does to take care of it. Andreas J. Koenig
  -is running this shell script every minute:
  +<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:
   
   <P>
  -<PRE>  S=`ls -s /usr/local/apache/logs/error_log | awk '{print $1}'`
  -  if [ &quot;$S&quot; -gt 100000 ] ; then
  -    /etc/rc.d/init.d/httpd restart
  -    date | /bin/mail -s &quot;error_log $S kB on inx&quot; myemail@domain.com
  -  fi
  +<PRE>  while (my($k,$v) = each %INC) {
  +    delete $INC{$k};
  +    require $k;
  +  }
   </PRE>
   <P>
  -It seems that his script will trigger restart every minute, since once the
  -logfile grows to be of 100000 lines, it will stay of this size, unless you
  -remove or rename it, before you do restart. On my server I run a watchdog
  -every five minutes which restarts the server if it is getting stuck (it
  -always works since when some modperl child process goes wild, the I/O it
  -causes is so heavy that other brother processes cannot normally to serve
  -the requests.) See <A HREF="././control.html#Monitoring_the_Server_A_watchdo">Monitoring the Server</A> for more hints.
  +Besides that, it flushes the Apache::Registry cache, and empties any
  +dynamic stacked handlers (e.g. PerlChildInitHandler).
   
   <P>
  -Also check out the daemontools from <A
  -HREF="ftp://koobera.math.uic.edu/www/daemontools.html">ftp://koobera.math.uic.edu/www/daemontools.html</A>
  -
  +Lots of SegFaults and other problems were reported by users who have turned <CODE>PerlFreshRestart</CODE>  <STRONG>On</STRONG>. Most of them have gone away when it was turned off. It doesn't mean that
  +you shouldn't use it, if it works for you. Just be aware of the dragons...
   
   <P>
  -<PRE>  ,-----
  -  | cyclog writes a log to disk. It automatically synchronizes the log
  -  | every 100KB (by default) to guarantee data integrity after a crash. It
  -  | automatically rotates the log to keep it below 1MB (by default). If
  -  | the disk fills up, cyclog pauses and then tries again, without losing
  -  | any data.
  -  `-----
  -</PRE>
  +<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<CENTER><H1><A NAME="server_reached_MaxClients_settin">server reached MaxClients setting, consider raising the MaxClients setting</A></H1></CENTER>
  +<P>
  +See <A HREF="././performance.html#Choosing_MaxClients">Choosing MaxClients</A>.
  +
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
   	     The <a href="http://www.modperl.com/">
   	     <B>Writing Apache Modules with Perl and C</B></a>
  @@ -10463,7 +11034,7 @@
   	     Amazon.com</a>.
   
   	     <HR>
  -	     [    <A HREF="warnings.html">Prev</A> |      <A HREF="index.html">Main Page</A> | <A HREF="security.html">Next</A>      ]
  +	     [    <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%" >
   <TR ALIGN=CENTER VALIGN=TOP>
  @@ -10476,7 +11047,7 @@
       <B>
         <FONT SIZE=-1>
   	     Written by <A HREF="help.html#This_document_s_Author">Stas Bekman</A>.
  -	     <BR>Last Modified at 06/15/1999
  +	     <BR>Last Modified at 06/19/1999
         </FONT>
       </B>
     </TD>
  @@ -10524,7 +11095,7 @@
   <A HREF="http://perl.apache.org"><IMG SRC="images/mod_perl.gif" ALT="Mod Perl Icon" BORDER=0 HEIGHT=30 WIDTH=90 ALIGN=RIGHT></A>
   Protecting Your Site</H1>
   <HR WIDTH="100%">
  -	    [    <A HREF="control.html">Prev</A> |      <A HREF="index.html">Main Page</A> | <A HREF="databases.html">Next</A>      ]<HR><!-- INDEX BEGIN -->
  +	    [    <A HREF="warnings.html">Prev</A> |      <A HREF="index.html">Main Page</A> | <A HREF="databases.html">Next</A>      ]<HR><!-- INDEX BEGIN -->
   <P><B><FONT SIZE=-1>Table of Contents:</FONT></B></P>
   <UL>
   
  @@ -10729,7 +11300,7 @@
   	     Amazon.com</a>.
   
   	     <HR>
  -	     [    <A HREF="control.html">Prev</A> |      <A HREF="index.html">Main Page</A> | <A HREF="databases.html">Next</A>      ]
  +	     [    <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%" >
   <TR ALIGN=CENTER VALIGN=TOP>
  @@ -10742,7 +11313,7 @@
       <B>
         <FONT SIZE=-1>
   	     Written by <A HREF="help.html#This_document_s_Author">Stas Bekman</A>.
  -	     <BR>Last Modified at 05/17/1999
  +	     <BR>Last Modified at 06/26/1999
         </FONT>
       </B>
     </TD>
  @@ -11717,13 +12288,13 @@
     # Quote the list of parameters , alldigits parameters are unquoted (int)
     # print sql_quote(&quot;one&quot;,2,&quot;three&quot;); =&gt; 'one' 2 'three'
     #############
  -  sub sql_quote{ map{ /^(\d+|NULL)$/ ? $_ : &quot;'$_'&quot; } @_ }
  +  sub sql_quote{ map{ /^(\d+|NULL)$/ ? $_ : &quot;\'$_\'&quot; } @_ }
     
     # Escape the list of parameters (all unsafe chars like &quot;,' are escaped )
     # must make a copy of @_ since we might try to change the passed
     # (Modification of a read-only value attempted)
     ##############
  -  sub sql_escape{ my @a = @_; map { s/(['])/\\$1/g;$_} @a }
  +  sub sql_escape{ my @a = @_; map { s/([\'])/\\$1/g;$_} @a }
     
     
     # DESTROY makes all kinds of cleanups if the fuctions were interuppted
  @@ -11929,7 +12500,7 @@
       <B>
         <FONT SIZE=-1>
   	     Written by <A HREF="help.html#This_document_s_Author">Stas Bekman</A>.
  -	     <BR>Last Modified at 06/19/1999
  +	     <BR>Last Modified at 06/26/1999
         </FONT>
       </B>
     </TD>
  @@ -12199,7 +12770,7 @@
     
     BEGIN {
         # RCS/CVS complient:  must be all one line, for MakeMaker
  -    $DB_File::Wrap::VERSION = do { my @r = (q$Revision: 1.14 $ =~ /\d+/g); sprintf &quot;%d.&quot;.&quot;%02d&quot; x $#r, @r };
  +    $DB_File::Wrap::VERSION = do { my @r = (q$Revision: 1.15 $ =~ /\d+/g); sprintf &quot;%d.&quot;.&quot;%02d&quot; x $#r, @r };
     
     }
     
  @@ -12419,7 +12990,7 @@
       <B>
         <FONT SIZE=-1>
   	     Written by <A HREF="help.html#This_document_s_Author">Stas Bekman</A>.
  -	     <BR>Last Modified at 05/08/1999
  +	     <BR>Last Modified at 06/26/1999
         </FONT>
       </B>
     </TD>
  @@ -12679,7 +13250,7 @@
       <B>
         <FONT SIZE=-1>
   	     Written by <A HREF="help.html#This_document_s_Author">Stas Bekman</A>.
  -	     <BR>Last Modified at 04/19/1999
  +	     <BR>Last Modified at 06/26/1999
         </FONT>
       </B>
     </TD>
  @@ -12868,7 +13439,7 @@
       <B>
         <FONT SIZE=-1>
   	     Written by <A HREF="help.html#This_document_s_Author">Stas Bekman</A>.
  -	     <BR>Last Modified at 04/19/1999
  +	     <BR>Last Modified at 06/26/1999
         </FONT>
       </B>
     </TD>
  @@ -13254,7 +13825,7 @@
       <B>
         <FONT SIZE=-1>
   	     Written by <A HREF="help.html#This_document_s_Author">Stas Bekman</A>.
  -	     <BR>Last Modified at 06/05/1999
  +	     <BR>Last Modified at 06/26/1999
         </FONT>
       </B>
     </TD>
  @@ -13587,16 +14158,16 @@
   <CENTER><H1><A NAME="Apache_GzipChain_compress_HTM">Apache::GzipChain - compress HTML (or anything) in the OutputChain</A></H1></CENTER>
   <P>
   Have you ever served a huge HTML file (e.g. a file bloated with JavaScript
  -code) and wandered how could you compress it, thus drammatically cutting
  -down the download times. After all java applets can be compressed into a
  -jar and benefit from a faster download. Why cannot we do the same with a
  -plain ASCII (HTML,JS and etc), it is a known fact that ASCII can be
  -compressed 10 times smaller than the original size.
  +code) and wandered how could you send it compressed, thus drammatically
  +cutting down the download times. After all java applets can be compressed
  +into a jar and benefit from a faster download times. Why cannot we do the
  +same with a plain ASCII (HTML,JS and etc), it is a known fact that ASCII
  +text can be compressed by a factor of 10.
   
   <P>
  -<CODE>Apache::GzipChain</CODE> comes to help you with this task. If a client (browser) understands <CODE>gzip</CODE> encoding this module compresses the output and send it downstream. A client
  -decompress the data upon receive and renders the HTML as if it was a plain
  -HTML fetch.
  +<CODE>Apache::GzipChain</CODE> comes to help you with this task. If a client (browser) understands <CODE>gzip</CODE> encoding this module compresses the output and sends it downstream. A
  +client decompresses the data upon receive and renders the HTML as if it was
  +a plain HTML fetch.
   
   <P>
   For example to compress all html files on the fly, do:
  @@ -13608,7 +14179,7 @@
     &lt;/Files&gt;
   </PRE>
   <P>
  -Remember that it will work only if the browsers claims to accept compressed
  +Remember that it will work only if the browser claims to accept compressed
   input, thru <CODE>Accept-Encoding</CODE> header. <CODE>Apache::GzipChain</CODE>
   keeps a list of user-agents, thus it also looks at <CODE>User-Agent</CODE>
   header, for known to accept compressed output browsers.
  @@ -13619,15 +14190,16 @@
   
   <P>
   <PRE>  &lt;Location /test&gt;
  -    SetHandler &quot;perl-script&quot;
  +    SetHandler perl-script
       PerlHandler Apache::OutputChain Apache::GzipChain Apache::EmbperlChain Apache::PassFile
     &lt;/Location&gt;
   </PRE>
   <P>
  -Hint: Watch an <CODE>access_log</CODE> file to see how many bytes were actually send.
  +Hint: Watch an <CODE>access_log</CODE> file to see how many bytes were actually send, compare with a regular
  +configuration send.
   
   <P>
  -See the module's documentaion for more details.
  +(See <CODE>perldoc Apache::GzipChain</CODE>).
   
   <P>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  @@ -13697,7 +14269,7 @@
       <B>
         <FONT SIZE=-1>
   	     Written by <A HREF="help.html#This_document_s_Author">Stas Bekman</A>.
  -	     <BR>Last Modified at 06/15/1999
  +	     <BR>Last Modified at 06/26/1999
         </FONT>
       </B>
     </TD>
  @@ -14835,7 +15407,7 @@
       <B>
         <FONT SIZE=-1>
   	     Written by <A HREF="help.html#This_document_s_Author">Stas Bekman</A>.
  -	     <BR>Last Modified at 06/19/1999
  +	     <BR>Last Modified at 06/26/1999
         </FONT>
       </B>
     </TD>
  @@ -15359,7 +15931,7 @@
       <B>
         <FONT SIZE=-1>
   	     Written by <A HREF="help.html#This_document_s_Author">Stas Bekman</A>.
  -	     <BR>Last Modified at 06/19/1999
  +	     <BR>Last Modified at 06/26/1999
         </FONT>
       </B>
     </TD>
  
  
  
  1.16      +204 -117  modperl-site/guide/config.html
  
  Index: config.html
  ===================================================================
  RCS file: /export/home/cvs/modperl-site/guide/config.html,v
  retrieving revision 1.15
  retrieving revision 1.16
  diff -u -r1.15 -r1.16
  --- config.html	1999/06/19 21:15:02	1.15
  +++ config.html	1999/07/02 13:42:17	1.16
  @@ -33,13 +33,19 @@
   		<LI><A HREF="#Location_Configuration">Location Configuration</A>
   		<LI><A HREF="#PerlFreshRestart">PerlFreshRestart</A>
   		<LI><A HREF="#_perl_status_location">/perl-status location</A>
  +		<UL>
  +
  +			<LI><A HREF="#Configuration">Configuration</A>
  +			<LI><A HREF="#Usage">Usage</A>
  +			<LI><A HREF="#Compiled_Registry_Scripts_sectio">Compiled Registry Scripts section seems to be empty.</A>
  +		</UL>
  +
   		<LI><A HREF="#PerlSetVar_PerlSetEnv_and_PerlP">PerlSetVar, PerlSetEnv and PerlPassEnv</A>
   		<LI><A HREF="#perl_startup_file">perl-startup file</A>
   		<UL>
   
   			<LI><A HREF="#Sample_perl_startup_file">Sample perl-startup file</A>
   			<LI><A HREF="#What_modules_should_you_add_to_t">What modules should you add to the startup file and why.</A>
  -			<LI><A HREF="#Is_it_possible_to_preopen_a_DB_c">Is it possible to preopen a DB connection at the server startup?</A>
   			<LI><A HREF="#The_confusion_with_use_clause_">The confusion with use() clause at the server startup?</A>
   			<LI><A HREF="#The_confusion_with_defining_glob">The confusion with defining globals in startup</A>
   		</UL>
  @@ -84,19 +90,19 @@
   <P>
   <CENTER><H1><A NAME="mod_perl_Specific_Configuration">mod_perl Specific Configuration</A></H1></CENTER>
   <P>
  -The next step after building and installing your new mod_perl-enabled
  -Apache server, is to configure the server's configuration files. To learn
  -how to modify Apache's configuration files, please refer to the
  -documentation included with the Apache distribution. or just view the files
  -in conf directory and follow the instructions in these files - the embedded
  +The next step after building and installing your new mod_perl enabled
  +apache server, is to configure the server. To learn how to modify apache's
  +configuration files, please refer to the documentation included with the
  +apache distribution, or just view the files in
  +<CODE>conf</CODE> directory and follow the instructions in these files - the embedded
   comments within the file do a good job of explaining the options.
   
   <P>
  -Before you start the mod_perl configuration, configure Apache, and see that
  -it works. When done, return here to continue...
  +Before you start with mod_perl specific configuration, first configure
  +apache, and see that it works. When done, return here to continue...
   
   <P>
  -[ Note that prior to version 1.3.4, the default Apache install used three
  +[ Note that prior to version 1.3.4, the default apache install used three
   configuration files -- <STRONG>httpd.conf</STRONG>, <STRONG>srm.conf</STRONG>, and
   <STRONG>access.conf</STRONG>. The 1.3.4 version began distributing the configuration directives in a
   single file -- <STRONG>httpd.conf</STRONG>. The remainder of this chapter refers to the location of the configuration
  @@ -106,8 +112,8 @@
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
   <CENTER><H2><A NAME="Alias_Configurations">Alias Configurations</A></H2></CENTER>
   <P>
  -First, you need to specify the location where all mod_perl scripts will be
  -located.
  +First, you need to specify the locations on a file-system for the scripts
  +to be found.
   
   <P>
   Add the following configuration directives:
  @@ -129,37 +135,43 @@
   <P>
   Alias defines the start of the URL path to the script you are referencing.
   For example, using the above configuration, fetching
  -<STRONG>http://www.you.com/perl/test.pl</STRONG>, will cause the server to look for the file <STRONG>test.pl</STRONG> at <STRONG>/usr/local/myproject/cgi</STRONG>, and execute it as an <STRONG>Apache::Registry</STRONG> script if we define Apache::Register to be the handler of <CODE>/perl</CODE> location (see below). The URL
  -<STRONG>http://www.you.com/perl/test.pl</STRONG> will be mapped to
  -<STRONG>/usr/local/myproject/cgi/test.pl</STRONG>. This means you can have all your CGIs located at the same place at file
  -system, and call the script in any of three modes simply by changing the
  -directory name component of the URL (cgi-bin|perl|cgi-perl) - is not this
  -cool? (That is the configuration you see above - all three Aliases point to
  -the same directory within your file system, but of course they can be
  -different). If your script does not seem to be working while running under
  -mod_perl, you can easily call the script in straight mod_cgi mode without
  -making any script changes (in most cases), but rather by changing the URL
  -you invoke it by.
  -
  -<P>
  -FYI: for modperl <CODE>ScriptAlias</CODE> is the same thing as an <CODE>Alias</CODE>
  -directive + <CODE>sethandler cgi-handler</CODE>. The latter will be overwritten if you enable <CODE>Apache::Registry</CODE>. In other words, <CODE>ScriptAlias</CODE> does not work for mod_perl, it only appears to work when the additional
  -configuration is in there. If the <CODE>Apache::Registry</CODE> configuration came before the <CODE>ScriptAlias</CODE>, scripts would be run under mod_cgi. While handy, <CODE>ScriptAlias</CODE> is a known kludge, always better to use
  -<CODE>Alias</CODE> and <CODE>SetHandler</CODE>.
  -
  -<P>
  -Of course you can choose any other alias (you will use it later in
  -http.conf), you can choose to use all three modes or only one of these (It
  -is undesirable to run plain cgi-bin scripts from a mod_perl-enabled server
  -- the price is too high, it is better to run these on plain Apache server.
  -(META: add link to strategies)
  +<CODE>http://www.nowhere.com/perl/test.pl</CODE>, will cause the server to look for the file <CODE>test.pl</CODE> at <CODE>/usr/local/myproject/cgi</CODE>, and execute it as an <CODE>Apache::Registry</CODE> script if we define <CODE>Apache::Registry</CODE> to be the handler of <CODE>/perl</CODE> location (see below). The URL
  +<CODE>http://www.nowhere.com/perl/test.pl</CODE> will be mapped to
  +<CODE>/usr/local/myproject/cgi/test.pl</CODE>. This means that you can have all your CGIs located at the same place at
  +the file-system, and call the script in any of three modes simply by
  +changing the directory name component of the URL (<CODE>cgi-bin|perl|cgi-perl</CODE>) - is not this neat? (That is the configuration you see above - all three
  +Aliases point to the same directory within your file system, but of course
  +they can be different). If your script does not seem to be working while
  +running under mod_perl, you can easily call the script in straight mod_cgi
  +mode without making any script changes (in most cases), but rather by
  +changing the URL you invoke it by.
   
   <P>
  +FYI: for modperl <CODE>ScriptAlias</CODE> is the same thing as:
  +
  +<P>
  +<PRE>  Alias /foo/ /path/to/foo/
  +  SetHandler cgi-handler
  +</PRE>
  +<P>
  +where <CODE>SetHandler cgi-handler</CODE> invokes mod_cgi. The latter will be overwritten if you enable <CODE>Apache::Registry</CODE>. In other words,
  +<CODE>ScriptAlias</CODE> does not work for mod_perl, it only appears to work when the additional
  +configuration is in there. If the
  +<CODE>Apache::Registry</CODE> configuration came before the <CODE>ScriptAlias</CODE>, scripts would be run under mod_cgi. While handy, <CODE>ScriptAlias</CODE> is a known kludge, always better to use <CODE>Alias</CODE> and <CODE>SetHandler</CODE>.
  +
  +<P>
  +Of course you can choose any other Alias (you will use it later in
  +<CODE>httpd.conf</CODE>), you can choose to use all three modes or only one of these (It is
  +undesirable to run plain cgi-bin scripts from a mod_perl-enabled server -
  +the price is too high, it is better to run these on plain Apache server.
  +(See <A HREF="././strategy.html#Standalone_mod_perl_Enabled_Apac">Standalone mod_perl Enabled Apache Server</A>)
  +
  +<P>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
   <CENTER><H2><A NAME="Location_Configuration">Location Configuration</A></H2></CENTER>
   <P>
   Now we will work with the <CODE>httpd.conf</CODE> file. I add all the mod_perl stuff at the end of the file, after the native
  -Apache configurations.
  +apache configurations.
   
   <P>
   First we add:
  @@ -175,40 +187,41 @@
     &lt;/Location&gt;
   </PRE>
   <P>
  -This configuration causes all scripts that are called with a <STRONG>/perl</STRONG>
  -path prefix to be executed under the <STRONG>Apache::Registry</STRONG> module and as a CGI (so the <STRONG>ExecCGI</STRONG>, if you omit this option the script will be printed to the caller's
  -browser as a plain text or will possibly will trigger a 'Save-As' window).
  +This configuration causes all scripts that are called with a <CODE>/perl</CODE>
  +path prefix to be executed under the <CODE>Apache::Registry</CODE> module and as a CGI (so the <STRONG>ExecCGI</STRONG>, if you omit this option the script will be printed to the caller's
  +browser as a plain text or possibly will trigger a 'Save-As' window).
   
   <P>
  -<STRONG>PerlSendHeader On</STRONG> tells the server to send an HTTP header to the browser on every script
  +<CODE>PerlSendHeader On</CODE> tells the server to send an HTTP header to the browser on every script
   invocation. You will want to turn this off for nph (non-parsed-headers)
  -scripts. <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
  -CGI-&gt;header or $r-&gt;send_http_header directly.
  +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.
   
   <P>
  -Remember the <STRONG>Alias</STRONG> from the section above? We must use the same Alias here, if you use
  -Location that does not have the same Alias defined in srm.conf, the server
  -will fail to locate the script in the file system. (We are talking about
  -script execution here -- there are cases where Location is something that
  -is being executed by the server itself, without having the corresponding
  -file, like <A HREF="#_perl_status_location">perl-status location</A>.)
  +Remember the <STRONG>Alias</STRONG> from the section above? We must use the same
  +<CODE>Alias</CODE> here, if you use <CODE>Location</CODE> that does not have the same
  +<CODE>Alias</CODE> defined in <CODE>srm.conf</CODE>, the server will fail to locate the script in the file system. (We are
  +talking about script execution here -- there are cases where <CODE>Location</CODE> is something that is being executed by the server itself, without having
  +the corresponding file, like <CODE>/perl-status</CODE> location.)
   
   <P>
  -Note that sometimes you will have to add : PerlModule Apache::Registry
  +Note that sometimes you will have to add :
   
  +<P>
  +<PRE>  PerlModule Apache::Registry
  +</PRE>
   <P>
  -before you specify the location that uses Apache::Registry as a
  -PerlHandler. Basically you can start running the scripts in the
  -Apache::Registry mode...
  +before you specify the location that uses <CODE>Apache::Registry</CODE> as a
  +<CODE>PerlHandler</CODE>. Basically you can start running the scripts in the
  +<CODE>Apache::Registry</CODE> mode...
   
   <P>
  -You have to do nothing about /cgi-bin (mod_cgi), since it has nothing to do
  -with mod_perl
  +You have nothing to do about <CODE>/cgi-bin</CODE> location (mod_cgi), since it has nothing to do with mod_perl.
   
   <P>
  -Here is a similar location configuration for Apache::PerlRun. (More about
  -<A HREF="././porting.html#Apache_PerlRun_a_closer_look">Apache::PerlRun</A>)
  +Here is a similar location configuration for <CODE>Apache::PerlRun</CODE> (More about <A HREF="././porting.html#Apache_PerlRun_a_closer_look">Apache::PerlRun</A>):
   
   <P>
   <PRE>  &lt;Location /cgi-perl&gt;
  @@ -224,34 +237,110 @@
   <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 <STRONG>PerlRequire</STRONG>, <STRONG>PerlModule</STRONG>, other <CODE>use()'d</CODE> modules and flush the Apache::Registry cache
  -on server restart, add:
  +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:
   
   <P>
   <PRE>  PerlFreshRestart On
  +Make sure you read L&lt;Evil things might happen when using
  +PerlFreshRestart|warnings/Evil_things_might_happen_when_us&gt;.
   </PRE>
  +<P>
  +<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<CENTER><H2><A NAME="_perl_status_location">/perl-status location</A></H2></CENTER>
   <P>
  -Make sure you read <A HREF="././warnings.html#Evil_things_might_happen_when_us">Evil things might happen when using PerlFreshRestart</A>.
  +A very useful feature. You can watch what happens to the perl guts of the
  +server. Below you will find the instructions of configuration and usage of
  +this feature
   
   <P>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<CENTER><H2><A NAME="_perl_status_location">/perl-status location</A></H2></CENTER>
  +<CENTER><H3><A NAME="Configuration">Configuration</A></H3></CENTER>
   <P>
  -Adding a directive to enable a <STRONG>/perl-status</STRONG> location allows you to see many things about your server. See
  -<A HREF="././status.html#Configuration">perl-status</A>
  +Add this to <CODE>httpd.conf</CODE>:
   
  +<P>
  +<PRE>  &lt;Location /perl-status&gt;
  +    SetHandler perl-script
  +    PerlHandler Apache::Status
  +    order deny,allow
  +    #deny from all
  +    #allow from 
  +  &lt;/Location&gt;
  +</PRE>
  +<P>
  +If you are going to use <CODE>Apache::Status</CODE>. It's important to put it as a first module in the start-up file, or in
  +the <CODE>httpd.conf</CODE> (after
  +<CODE>Apache::Registry</CODE>):
   
  +<P>
  +<PRE>  # startup.pl
  +  use Apache::Registry ();
  +  use Apache::Status ();
  +  use Apache::DBI ();
  +</PRE>
  +<P>
  +If you don't put <CODE>Apache::Status</CODE> before <CODE>Apache::DBI</CODE> then you don't get <CODE>Apache::DBI</CODE>'s menu entry in status.
   
   <P>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<CENTER><H3><A NAME="Usage">Usage</A></H3></CENTER>
  +<P>
  +Assuming that your mod_perl server listens to port 81, fetch <A
  +HREF="http://www.nowhere.com:81/perl-status">http://www.nowhere.com:81/perl-status</A>
  +
  +
  +<P>
  +<PRE>  Embedded Perl version 5.00502 for Apache/1.3.2 (Unix) mod_perl/1.16 
  +  process 187138, running since Thu Nov 19 09:50:33 1998
  +</PRE>
  +<P>
  +This is the linked menu that you should see:
  +
  +<P>
  +<PRE>  Signal Handlers
  +  Enabled mod_perl Hooks
  +  PerlRequire'd Files
  +  Environment
  +  Perl Section Configuration
  +  Loaded Modules
  +  Perl Configuration
  +  ISA Tree
  +  Inheritance Tree
  +  Compiled Registry Scripts
  +  Symbol Table Dump
  +</PRE>
  +<P>
  +Let's follow for example : <STRONG>PerlRequire'd Files</STRONG> -- we see:
  +
  +<P>
  +<PRE>  PerlRequire                          Location
  +  /usr/myproject/lib/apache-startup.pl /usr/myproject/lib/apache-startup.pl
  +</PRE>
  +<P>
  +From some menus you can continue deeper to peek at the perl internals of
  +the server, to watch the values of the global variables in the packages, to
  +the list of cached scripts and modules and much more. Just click around...
  +
  +<P>
  +<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  +<CENTER><H3><A NAME="Compiled_Registry_Scripts_sectio">Compiled Registry Scripts section seems to be empty.</A></H3></CENTER>
  +<P>
  +Sometimes when you fetch <CODE>/perl-status</CODE> you and follow the <STRONG>Compiled
  +Registry Scripts</STRONG> link from the status menu -- you see no listing of scripts at all. This is
  +absolutely correct -- <CODE>Apache::Status</CODE> shows the registry scripts compiled in the httpd child which is serving
  +your request for <CODE>/perl-status</CODE>. If a child has not compiled yet the script you are asking for, <CODE>/perl-status</CODE> will just show you the main menu. This usually happens when the child was
  +just spawned.
  +
  +<P>
  +<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
   <CENTER><H2><A NAME="PerlSetVar_PerlSetEnv_and_PerlP">PerlSetVar, PerlSetEnv and PerlPassEnv</A></H2></CENTER>
   <P>
   <PRE>  PerlSetEnv key val
     PerlPassEnv key
   </PRE>
   <P>
  -Set and Pass the ENV variables to your scripts. So you can read them in
  -your scripts from <CODE>%ENV</CODE> (e.g. <CODE>$ENV{&quot;key&quot;}</CODE>)
  +<CODE>PerlPassEnv</CODE> passes, <CODE>PerlSetEnv</CODE> sets and passes the
  +<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>
   <CODE>PerlSetVar</CODE> is very similar to <CODE>PerlSetEnv</CODE>, but you extract it with another method. In &lt;Perl&gt; sections:
  @@ -271,10 +360,8 @@
   <CENTER><H2><A NAME="perl_startup_file">perl-startup file</A></H2></CENTER>
   <P>
   Since many times you have to add many perl directives to the configuration
  -file, it can be a good idea to put all of these into one file, so the
  -configuration file will be cleaner, also you can call
  -<STRONG>perl -c perl-startup</STRONG> to test the file's syntax. What does this take? Add this line to
  -httpd.conf:
  +file, it can be a good idea to put all of these into a one file, so the
  +configuration file will be cleaner. Add the following line to <CODE>httpd.conf</CODE>:
   
   <P>
   <PRE>    # startup.perl loads all functions that we want to use within
  @@ -282,6 +369,12 @@
     Perlrequire /path/to/startup.pl
   </PRE>
   <P>
  +before the rest of the mod_perl configuration directives.
  +
  +<P>
  +Also you can call <CODE>perl -c perl-startup</CODE> to test the file's syntax. What does this take?
  +
  +<P>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
   <CENTER><H3><A NAME="Sample_perl_startup_file">Sample perl-startup file</A></H3></CENTER>
   <P>
  @@ -290,8 +383,8 @@
   <P>
   <PRE>  use strict;
     
  -  #modify @INC if needed
  -  use lib qw(/some/other/dir /some/bar/dir);
  +  # extend @INC if needed
  +  use lib qw(/dir/foo /dir/bar);
     
     # make sure we are in a sane environment.
     $ENV{GATEWAY_INTERFACE} =~ /^CGI-Perl/
  @@ -315,8 +408,7 @@
     CGI-&gt;compile(':all');
   </PRE>
   <P>
  -Note that starting with CGI::VERSION 2.46, the recommended method to
  -precompile the code in CGI.pm is:
  +Note that starting with <CODE>$CGI::VERSION</CODE> 2.46, the recommended method to precompile the code in <CODE>CGI.pm</CODE> is:
   
   <P>
   <PRE>  use CGI qw(-compile :all);
  @@ -335,22 +427,11 @@
   <P>
   Modules that are being loaded at the server startup will be shared among
   server children, so only one copy of each module will be loaded, thus
  -saving a lot of RAM for you. 
  +saving a lot of RAM for you. Usually I put most of the code I develop into
  +modules and preload them from here. You can even preload your CGI script
  +with <CODE>Apache::RegistryLoader</CODE> and preopen the DB connections with <CODE>Apache::DBI</CODE>. (See <A HREF="././performance.html#Preload_Perl_modules_at_server_s">Preload Perl modules at server startup</A>).
   
   <P>
  -See <A HREF="././performance.html#Preload_Perl_modules_at_server_s">Preload Perl modules at server startup</A> 
  -
  - 
  -
  -<P>
  -<P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<CENTER><H3><A NAME="Is_it_possible_to_preopen_a_DB_c">Is it possible to preopen a DB connection at the server startup?</A></H3></CENTER>
  -<P>
  -Yes! See <A HREF="././performance.html#Persistent_DB_Connections">Persistent DB Connections</A>
  -
  -
  -
  -<P>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
   <CENTER><H3><A NAME="The_confusion_with_use_clause_">The confusion with use() clause at the server startup?</A></H3></CENTER>
   <P>
  @@ -383,18 +464,21 @@
   </PRE>
   <P>
   which means that the caller does not want any symbols to be imported. Why
  -is this important? Since some modules has <CODE>@EXPORT</CODE> set to some tags to be exported by default and when write:
  +is this important? Since some modules has <CODE>@EXPORT</CODE> set to a list of tags to be exported by default and when you write:
   
   <P>
   <PRE>  use Foo;
   </PRE>
   <P>
  -And you think nothing is being imported, the <CODE>import()</CODE> call is being executed and probably some symbols do being imported. See the
  -docs/source of the module in question to make sure you code correctly.
  +and think nothing is being imported, the <CODE>import()</CODE> call is being executed and probably some symbols do being imported. See the
  +docs/source of the module in question to make sure you <CODE>use()</CODE> it correctly. When you write your own modules, always remember that it's
  +better to use <CODE>@EXPORT_OK</CODE> instead of <CODE>@EXPORT</CODE>, since the former doesn't export tags unless it was asked to.
   
   <P>
   Since the symbols that you might import into a startup's script namespace
  -will be visible by none of the children, scripts that needs a <CODE>Foo</CODE>'s module functionality have to pull it in like if you did not preload <CODE>Foo</CODE> at the startup file. For example, just because you have <CODE>use()d</CODE>  <CODE>Apache::Constants</CODE> in a startup script does not mean you can have the following handler:
  +will be visible by none of the children, scripts that need a
  +<CODE>Foo</CODE>'s module exported tags have to pull it in like if you did not preload <CODE>Foo</CODE> at the startup file. For example, just because you have
  +<CODE>use()d</CODE>  <CODE>Apache::Constants</CODE> in the startup script, does not mean you can have the following handler:
   
   <P>
   <PRE>  package MyModule;
  @@ -423,23 +507,24 @@
   <PRE>  return Apache::Constants::OK;
   </PRE>
   <P>
  -See the manpage/perldoc on <CODE>Exporter</CODE> and <CODE>perlmod</CODE> for more on import.
  +See the manpage/perldoc on <CODE>Exporter</CODE> and <CODE>perlmod</CODE> for more on
  +<CODE>import()</CODE>.
   
   <P>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
   <CENTER><H3><A NAME="The_confusion_with_defining_glob">The confusion with defining globals in startup</A></H3></CENTER>
   <P>
  -<CODE>PerlRequire</CODE> allows you to preload modules and do a few more things. Imported or defined
  -variables are visible in the scope of the startup file. It is a wrong
  -assumption that global variables that were defined in the startup file,
  -will be accessable by child processes.
  +<CODE>PerlRequire</CODE> allows you to execute code that preloads modules and does more things.
  +Imported or defined variables are visible in the scope of the startup file.
  +It is a wrong assumption that global variables that were defined in the
  +startup file, will be accessible by child processes.
   
   <P>
   You do have to define/import variables in your scripts and they will be
   visible inside a child process who run this script. They will be not shared
  -between siblings. Remember that every script is running is a specially
  +between siblings. Remember that every script is running in a specially
   (uniquely) named package - so it cannot access variables from other
  -packages unless it inherits from them or <CODE>use()</CODE>s them.
  +packages unless it inherits from them or <CODE>use()</CODE>'s them.
   
   <P>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  @@ -447,29 +532,30 @@
   <P>
   <CODE>apachectl configtest</CODE> tests the configuration file without starting the server. You can safely
   modify the configuration file on your production server, if you run this
  -test before you restart the server. Of course it is not 100% errorprone,
  -but it will reveal any syntaxical errors you might do while editing the
  -file.
  +test before you restart the server. Of course it is not 100% error prone,
  +but it will reveal any syntax errors you might do while editing the file.
   
   <P>
  -<CODE>apachectl configtest</CODE> is the same as <CODE>httpd -t</CODE> and it actually executes the code in startup.pl, not just parses it. &lt;Perl&gt; configuration has always started Perl during the configuration
  -read,
  +'<CODE>apachectl configtest</CODE>' is the same as '<CODE>httpd -t</CODE>' and it actually executes the code in startup.pl, not just parses it. <CODE>&lt;Perl</CODE>&gt; configuration has always started Perl during the configuration read,
   <CODE>Perl{Require,Module}</CODE> do so as well.
   
   <P>
   If you want your startup code to get a control over the <CODE>-t</CODE>
  -(configtest) server launch, start the server configuration test with 
  +(<CODE>configtest</CODE>) server launch, start the server configuration test with:
   
   <P>
   <PRE>  httpd -t -Dsyntax_check
   </PRE>
   <P>
  -and in your startup file, add:
  +and in your startup file, add (at the top):
   
   <P>
   <PRE>  return if Apache-&gt;define('syntax_check');
   </PRE>
   <P>
  +if you want to prevent the code in the file from being executed.
  +
  +<P>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
   <CENTER><H1><A NAME="Perl_behavior_controls">Perl behavior controls</A></H1></CENTER>
   <P>
  @@ -505,13 +591,13 @@
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
   <CENTER><H1><A NAME="Perl_Sections">Perl Sections</A></H1></CENTER>
   <P>
  -With <STRONG>&lt;Perl&gt;&lt;/Perl&gt;</STRONG> sections, it is possible to configure your server entirely in Perl.
  +With <CODE>&amp;lt;Perl&amp;gt;&amp;lt;/Perl&amp;gt;</CODE> sections, it is possible to configure your server entirely in Perl.
   
   <P>
   <STRONG>&lt;Perl&gt;</STRONG> sections can contain *any* and as much Perl code as you wish. These
   sections are compiled into a special package whose symbol table mod_perl
   can then walk and grind the names and values of Perl variables/structures
  -through the Apache core configuration gears. Most of the configurations
  +through the apache core configuration gears. Most of the configurations
   directives can be represented as scalars (<STRONG>$scalar</STRONG>) or lists (<STRONG>@list</STRONG>). An <CODE>@List</CODE> inside these sections is simply converted into a space delimited string for
   you inside. Here is an example:
   
  @@ -529,8 +615,8 @@
     &lt;/Perl&gt;
   </PRE>
   <P>
  -Block sections such as &lt;Location&gt;&lt;/Location&gt; are represented in
  -a %Hash, e.g.:
  +Block sections such as <CODE>&lt;Location</CODE>..&lt;/Location&gt;&gt; are represented in a
  +<CODE>%Location</CODE> hash, e.g.:
   
   <P>
   <PRE>  $Location{&quot;/~dougm/&quot;} = {
  @@ -557,8 +643,8 @@
     push @Redirect, [qw(temp &quot;/here&quot; &quot;<A HREF="http://www.there.com&quot">http://www.there.com&quot</A>;)];
   </PRE>
   <P>
  -Other section counterparts include <STRONG>%VirtualHost</STRONG>, <STRONG>%Directory</STRONG> and
  -<STRONG>%Files</STRONG>.
  +Other section counterparts include <CODE>%VirtualHost</CODE>, <CODE>%Directory</CODE> and
  +<CODE>%Files</CODE>.
   
   <P>
   To pass all environment variables to the children with a single
  @@ -592,13 +678,14 @@
     &lt;/Perl&gt;
   </PRE>
   <P>
  -Now you may run <STRONG>perl -cx httpd.conf</STRONG>.
  +Now you may run:
   
   <P>
  -To configure this feature build with <STRONG>perl Makefile.PL 
  -PERL_SECTIONS=1</STRONG>
  -
  -
  +<PRE>  perl -cx httpd.conf
  +</PRE>
  +<P>
  +To enable <CODE>&lt;Perl</CODE>&gt; sections you should build mod_perl with <STRONG>perl
  +Makefile.PL PERL_SECTIONS=1</STRONG>.
   
   <P>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  @@ -900,7 +987,7 @@
       <B>
         <FONT SIZE=-1>
   	     Written by <A HREF="help.html#This_document_s_Author">Stas Bekman</A>.
  -	     <BR>Last Modified at 06/05/1999
  +	     <BR>Last Modified at 07/02/1999
         </FONT>
       </B>
     </TD>
  
  
  
  1.16      +92 -113   modperl-site/guide/control.html
  
  Index: control.html
  ===================================================================
  RCS file: /export/home/cvs/modperl-site/guide/control.html,v
  retrieving revision 1.15
  retrieving revision 1.16
  diff -u -r1.15 -r1.16
  --- control.html	1999/06/19 21:15:02	1.15
  +++ control.html	1999/07/02 13:42:19	1.16
  @@ -22,7 +22,7 @@
   <A HREF="http://perl.apache.org"><IMG SRC="images/mod_perl.gif" ALT="Mod Perl Icon" BORDER=0 HEIGHT=30 WIDTH=90 ALIGN=RIGHT></A>
   Controlling and Monitoring the Server</H1>
   <HR WIDTH="100%">
  -	    [    <A HREF="warnings.html">Prev</A> |      <A HREF="index.html">Main Page</A> | <A HREF="security.html">Next</A>      ]<HR><!-- INDEX BEGIN -->
  +	    [    <A HREF="frequent.html">Prev</A> |      <A HREF="index.html">Main Page</A> | <A HREF="obvious.html">Next</A>      ]<HR><!-- INDEX BEGIN -->
   <P><B><FONT SIZE=-1>Table of Contents:</FONT></B></P>
   <UL>
   
  @@ -81,22 +81,22 @@
   processes. You are looking for the parent process. If you run your server
   as root - you will easily locate it, since it belongs to root. If you run
   the server as user (when you <A HREF="././install.html#Is_it_possible_to_install_and_us">don't have a root access</A>, most likely all the processes will belong to that user (unless defined
  -differently in the httpd.conf), but it's still easy to know 'who is the
  -parent' -- the one of the smallest size...
  +differently in the
  +<CODE>httpd.conf</CODE>), but it's still easy to know 'who is the parent' -- the one of the
  +smallest size...
   
   <P>
   You will notice many httpd_perl executables running on your system, but you
   should not send signals to any of them except the parent, whose pid is in
   the <CODE>PidFile</CODE>. That is to say you shouldn't ever need to send signals to any process
  -except the parent. There are three signals that you can send the parent:
  -TERM, HUP, and USR1.
  +except the parent. There are three signals that you can send the parent: <STRONG>TERM</STRONG>, <STRONG>HUP</STRONG>, and <STRONG>USR1</STRONG>.
   
   <P>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
   <CENTER><H1><A NAME="Implications_of_sending_TERM_HU">Implications of sending TERM, HUP, and USR1 to the server</A></H1></CENTER>
   <P>
   We will concentrate here on the implications of sending these signals to a
  -mod_perl-enabled server. For documentation on the implications of sending
  +mod_perl enabled server. For documentation on the implications of sending
   these signals to a plain Apache server see <A
   HREF="http://www.apache.org/docs/stopping.html">http://www.apache.org/docs/stopping.html</A>
   .
  @@ -104,21 +104,20 @@
   <DL>
   <P><DT><STRONG><A NAME="item_TERM">TERM Signal: stop now</A></STRONG><DD>
   <P>
  -Sending the TERM signal to the parent causes it to immediately attempt to
  -kill off all of its children. This process may take several seconds to
  -complete, following which the parent itself exits. Any requests in progress
  -are terminated, and no further requests are served. 
  +Sending the <STRONG>TERM</STRONG> signal to the parent causes it to immediately attempt to kill off all of
  +its children. This process may take several seconds to complete, following
  +which the parent itself exits. Any requests in progress are terminated, and
  +no further requests are served.
   
   <P>
  -That's the moment that the accumulated END{} blocks will be executed! Note
  -that if you use <STRONG>Apache::Registry</STRONG> or <STRONG>Apache::PerlRun</STRONG>, then END {} blocks are being executed upon each request (at the end).
  +That's the moment that the accumulated <CODE>END</CODE> blocks will be executed! Note that if you use <CODE>Apache::Registry</CODE> or <CODE>Apache::PerlRun</CODE>, then
  +<CODE>END</CODE> blocks are being executed upon each request (at the end).
   
   <P><DT><STRONG><A NAME="item_HUP">HUP Signal: restart now</A></STRONG><DD>
   <P>
  -Sending the HUP signal to the parent causes it to kill off its children
  -like in TERM (Any requests in progress are terminated) but the parent
  -doesn't exit. It re-reads its configuration files, and re-opens any log
  -files. Then it spawns a new set of children and continues serving hits.
  +Sending the <STRONG>HUP</STRONG> signal to the parent causes it to kill off its children like in <STRONG>TERM</STRONG> (Any requests in progress are terminated) but the parent doesn't exit. It
  +re-reads its configuration files, and re-opens any log files. Then it
  +spawns a new set of children and continues serving hits.
   
   <P>
   The server will reread its configuration files, flush all the compiled and
  @@ -132,21 +131,21 @@
   
   <P><DT><STRONG><A NAME="item_USR1">USR1 Signal: graceful restart</A></STRONG><DD>
   <P>
  -The USR1 signal causes the parent process to advise the children to exit
  -after their current request (or to exit immediately if they're not serving
  -anything). The parent re-reads its configuration files and re-opens its log
  -files. As each child dies off the parent replaces it with a child from the
  -new generation of the configuration, which begins serving new requests
  +The <STRONG>USR1</STRONG> signal causes the parent process to advise the children to exit after their
  +current request (or to exit immediately if they're not serving anything).
  +The parent re-reads its configuration files and re-opens its log files. As
  +each child dies off the parent replaces it with a child from the new
  +generation of the configuration, which begins serving new requests
   immediately. 
   
   <P>
  -The only difference between USR1 and HUP is that USR1 allows children to
  -complete any in-progress request prior to killing them off.
  +The only difference between <STRONG>USR1</STRONG> and <STRONG>HUP</STRONG> is that <STRONG>USR1</STRONG> allows children to complete any in-progress request prior to killing them
  +off.
   
   <P>
   By default, if a server is restarted (ala <CODE>kill -USR1 `cat
  -logs/httpd.pid`</CODE> or with HUP signal), Perl scripts and modules are not reloaded. To reload <STRONG>PerlRequire</STRONG>'s, <STRONG>PerlModule</STRONG>'s, other <CODE>use()'d</CODE> modules and flush the Apache::Registry
  -cache, enable with this command:
  +logs/httpd.pid`</CODE> or with <STRONG>HUP</STRONG> signal), Perl scripts and modules are not reloaded. To reload <STRONG>PerlRequire</STRONG>'s, <STRONG>PerlModule</STRONG>'s, other
  +<CODE>use()</CODE>'d modules and flush the <CODE>Apache::Registry</CODE> cache, enable with this command:
   
   <P>
   <PRE> PerlFreshRestart On              (in httpd.conf) 
  @@ -157,20 +156,17 @@
   </DL>
   <P>
   It's worth mentioning that restart or termination can sometimes take quite
  -a lot of time. Check out the PERL_DESTRUCT_LEVEL=-1 option during the
  -mod_perl ./Configure stage, which speeds this up and leads to more robust
  -operation in the face of problems, like running out of memory. It is only
  -usable if no significant cleanup has to be done by perl END{} blocks and
  -DESTROY methods when the child terminates, of course. What constitutes
  -significant cleanup? Any change of state outside of the current process
  -that would not be handled by the operating system itself. So committing
  -database transactions is significant but closing an ordinary file isn't.
  +a lot of time. Check out the <CODE>PERL_DESTRUCT_LEVEL=-1</CODE> option during the mod_perl <CODE>./Configure</CODE> stage, which speeds this up and leads to more robust operation in the face
  +of problems, like running out of memory. It is only usable if no
  +significant cleanup has to be done by perl <CODE>END</CODE> blocks and <CODE>DESTROY</CODE> methods when the child terminates, of course. What constitutes significant
  +cleanup? Any change of state outside of the current process that would not
  +be handled by the operating system itself. So committing database
  +transactions is significant but closing an ordinary file isn't.
   
   <P>
   Some folks prefer to specify signals using numerical values, rather than
   symbolics. If you are looking for these, check out your
  -<CODE>kill(3)</CODE> man page. My page points to
  -<CODE>/usr/include/sys/signal.h</CODE>, the relevant entries are:
  +<CODE>kill(3)</CODE> man page. My page points to <CODE>/usr/include/sys/signal.h</CODE>, the relevant entries are:
   
   <P>
   <PRE>  #define SIGHUP     1    /* hangup, generated when terminal disconnects */ 
  @@ -183,28 +179,29 @@
   <P>
   Apache's distribution provides a nice script to control the server. It's
   called <STRONG>apachectl</STRONG> and it's installed into the same location with httpd. In our scenario -
  -it's /usr/apps/sbin/httpd_perl/apachectl
  +it's
  +<CODE>/usr/apps/sbin/httpd_perl/apachectl</CODE>.
   
   <P>
  -Start httpd
  +Start httpd:
   
   <P>
   <PRE>        % /usr/apps/sbin/httpd_perl/apachectl start 
   </PRE>
   <P>
  -Stop httpd
  +Stop httpd:
   
   <P>
   <PRE>        % /usr/apps/sbin/httpd_perl/apachectl stop
   </PRE>
   <P>
  -Restart httpd if running by sending a SIGHUP or start if not running
  +Restart httpd if running by sending a <STRONG>SIGHUP</STRONG> or start if not running:
   
   <P>
   <PRE>        % /usr/apps/sbin/httpd_perl/apachectl restart
   </PRE>
   <P>
  -Do a graceful restart by sending a SIGUSR1 or start if not running
  +Do a graceful restart by sending a <STRONG>SIGUSR1</STRONG> or start if not running:
   
   <P>
   <PRE>        % /usr/apps/sbin/httpd_perl/apachectl graceful    
  @@ -219,19 +216,17 @@
   See the next section for the implication of the above calls.
   
   <P>
  -Replace 'httpd_perl' with 'httpd_docs' in the above calls to control the
  -httpd_docs server.
  +Replace <CODE>httpd_perl</CODE> with <CODE>httpd_docs</CODE> in the above calls to control the <STRONG>httpd_docs</STRONG> server.
   
   <P>
  -There are other options for <STRONG>apachectl</STRONG>, use 'help' option to see them all.
  +There are other options for <STRONG>apachectl</STRONG>, use <CODE>help</CODE> option to see them all.
   
   <P>
   It's important to understand that this script is based on the PID file
  -which is PIDFILE=/usr/apps/var/httpd_perl/run/httpd.pid. If you delete the
  -file by hand - <STRONG>apachectl</STRONG> will fail to run.
  +which is <CODE>PIDFILE=/usr/apps/var/httpd_perl/run/httpd.pid</CODE>. If you delete the file by hand - <STRONG>apachectl</STRONG> will fail to run.
   
   <P>
  -Also, note that <STRONG>apachectl</STRONG> is suitable to use from within your Unix system's startup files so that
  +Also, notice that <STRONG>apachectl</STRONG> is suitable to use from within your Unix system's startup files so that
   your web server is automatically restarted upon system reboot. Either copy
   the <STRONG>apachectl</STRONG> file to the appropriate location (<CODE>/etc/rc.d/rc3.d/S99apache</CODE> works on my RedHat Linux system) or create a symlink with that name
   pointing to the the canonical location. (If you do this, make certain that
  @@ -243,8 +238,7 @@
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
   <CENTER><H1><A NAME="SUID_start_up_scripts">SUID start-up scripts</A></H1></CENTER>
   <P>
  -For those who wants to use SUID startup script, here is an example for you.
  -This script is SUID to <STRONG>root</STRONG>, and should be executable only by members of some special group at your
  +For those who wants to use <STRONG>SUID</STRONG> startup script, here is an example for you. This script is <STRONG>SUID</STRONG> to <STRONG>root</STRONG>, and should be executable only by members of some special group at your
   site. Note the 10th line, which ``fixes an obscure error when starting
   apache/mod_perl'' by setting the real to the effective UID. As others have
   pointed out, it is the mismatch between the real and the effective UIDs
  @@ -253,8 +247,8 @@
   <P>
   Note that you must be using a version of Perl that recognizes and emulates
   the suid bits in order for this to work. The script will do different
  -things depending on whether it is named ``start_http'', ``stop_http'' or
  -``restart_http''. You can use symbolic links for this purpose.
  +things depending on whether it is named <CODE>start_http</CODE>,
  +<CODE>stop_http</CODE> or <CODE>restart_http</CODE>. You can use symbolic links for this purpose.
   
   <P>
   <PRE> #!/usr/bin/perl
  @@ -314,7 +308,7 @@
   sure the server will be up all the time.
   
   <P>
  -Crontab entry:
  +The crontab entry:
   
   <P>
   <PRE>  0,30 * * * * /path/to/the/apache.watchdog &gt;/dev/null 2&gt;&amp;1
  @@ -367,13 +361,12 @@
     fi
   </PRE>
   <P>
  -Another approach, probably even more practical, is to use the Cool LWP perl
  -package , to test the server by trying to fetch some document (script)
  +Another approach, probably even more practical, is to use the cool
  +<CODE>LWP</CODE> perl package , to test the server by trying to fetch some document (script)
   served by the server. Why is it more practical? While server can be up as a
  -process, it can be stuck and not working (SYN_RECV state - anyone??? Am I
  -getting a SYNC flood attack), So failing to get the document will trigger
  -restart, and ``probably'' the problem will go away. (Just replace <CODE>start</CODE> with <CODE>restart</CODE> in the
  -<CODE>$restart_command</CODE> below.
  +process, it can be stuck and not working, So failing to get the document
  +will trigger restart, and ``probably'' the problem will go away. (Just
  +replace <CODE>start</CODE> with <CODE>restart</CODE> in the <CODE>$restart_command</CODE> below.
   
   <P>
   Again we put this script into a crontab to call it every 30 minutes.
  @@ -493,22 +486,21 @@
   </PRE>
   <P>
   When you execute the above the server will run in the fg (foreground) of
  -the shell you have called it from. So to kill you just kill it with Ctrl-C.
  +the shell you have called it from. So to kill you just kill it with
  +<STRONG>Ctrl-C</STRONG>.
   
   <P>
  -Note that in -X mode the server will run very slowly while fetching images.
  -If you use Netscape while your server is running in single-process mode,
  -HTTP's ``KeepAlive'' feature gets in the way. Netscape tries to open
  -multiple connections and keep them open. Because there is only one server
  -process listening, each connection has to time-out before the next
  -succeeds. Turn off KeepAlive in httpd.conf to avoid this effect while
  -developing or you can press <STRONG>STOP</STRONG> after a few seconds (assuming you use the image size params, so the
  +Note that in <CODE>-X</CODE> mode the server will run very slowly while fetching images. If you use
  +Netscape while your server is running in single-process mode, HTTP's <CODE>KeepAlive</CODE> feature gets in the way. Netscape tries to open multiple connections and
  +keep them open. Because there is only one server process listening, each
  +connection has to time-out before the next succeeds. Turn off
  +<CODE>KeepAlive</CODE> in <CODE>httpd.conf</CODE> to avoid this effect while developing or you can press <STRONG>STOP</STRONG> after a few seconds (assuming you use the image size params, so the
   Netscape will be able to render the rest of the page).
   
   <P>
  -In addition you should know that when running with -X you will not see any
  -control messages that the parent server normally writes to the error_log.
  -(Like ``server started, server stopped and etc''.) Since
  +In addition you should know that when running with <CODE>-X</CODE> you will not see any control messages that the parent server normally
  +writes to the error_log. (Like ``server started, server stopped and etc''.)
  +Since
   <CODE>httpd -X</CODE> causes the server to handle all requests itself, without forking any
   children, there is no controlling parent to write status messages.
   
  @@ -529,8 +521,8 @@
   <PRE>  httpd_perl -f /path/to/httpd.conf  
   </PRE>
   <P>
  -I have approached it in other way. I have used the -Dparameter startup
  -option of the server. I call my version of the server
  +I have approached it in other way. I have used the <CODE>-Dparameter</CODE>
  +startup option of the server. I call my version of the server
   
   <P>
   <PRE>  % http_perl -Dsbekman
  @@ -578,7 +570,7 @@
   <P>
   To make things even easier. (In the above technique, you have to discover
   the PID of your parent httpd_perl process - written in
  -/usr/apps/var/httpd_perl/run/httpd.pid.userfoo) . We change the
  +<CODE>/usr/apps/var/httpd_perl/run/httpd.pid.userfoo</CODE>) . We change the
   <STRONG>apachectl</STRONG> script to do the work for us. We make a copy for each developer called <STRONG>apachectl.username</STRONG> and we change 2 lines in script:
   
   <P>
  @@ -627,34 +619,28 @@
     
   </PRE>
   <P>
  -where IP numbers are the IPs of the developers' client machines (where they
  -are running their web browser.) (I have tried to use REMOTE_USER since we
  -have all the users authenticated but it did not work for me)
  +where IP numbers are the IPs of the developer client machines (where they
  +are running their web browser.) (I have tried to use
  +<CODE>REMOTE_USER</CODE> since we have all the users authenticated but it did not work for me)
   
   <P>
  -So if I have a relative URL like <CODE>/perl/test.pl</CODE> written in some html or even <A
  -HREF="http://ourserver.com/perl/test.pl">http://ourserver.com/perl/test.pl</A>
  -in my case (user at machine of sbekman) it will be redirected by httpd_docs
  -to <A
  -HREF="http://ourserver.com:8000/perl/test.pl">http://ourserver.com:8000/perl/test.pl</A>
  +So if I have a relative URL like <CODE>/perl/test.pl</CODE> written in some html or even <CODE>http://www.nowhere.com/perl/test.pl</CODE> in my case (user at machine of <CODE>sbekman</CODE>) it will be redirected by httpd_docs to
  +<CODE>http://www.nowhere.com:8000/perl/test.pl</CODE>.
   
  -
   <P>
  -Of course you have another problem: The cgi generates some html, which
  +Of course you have another problem: The CGI generates some html, which
   should be called again. If it generates a URL with hard coded PORT the
   above scheme will not work. There 2 solutions:
   
   <P>
   First, generate relative URL so it will reuse the technique above, with
   redirect (which is transparent for user) but it will not work if you have
  -something to POST (redirect looses all the data!).
  +something to <CODE>POST</CODE> (redirect looses all the data!).
   
   <P>
   Second, use a general configuration module which generates a correct full
  -URL according to REMOTE_USER, so if <CODE>$ENV{REMOTE_USER} eq
  -'sbekman'</CODE>, I return <A
  -HREF="http://ourserver.com:8000/perl/">http://ourserver.com:8000/perl/</A>
  -as
  +URL according to <CODE>REMOTE_USER</CODE>, so if <CODE>$ENV{REMOTE_USER} eq
  +'sbekman'</CODE>, I return <CODE>http://www.nowhere.com:8000/perl/</CODE> as
   <CODE>cgi_base_url</CODE>. Again this will work if the user is authenticated.
   
   <P>
  @@ -671,23 +657,21 @@
   favorite shell. Sometimes you encounter a very weird situation when script
   runs from the shell but dies when called as a CGI. The real problem lies in
   the difference between the environment that is being used by your server
  -and your shell. An example can be a different perl path or having PERL5LIB
  -env variable which includes paths that are not in the <CODE>@INC</CODE> of
  -the perl compiled with mod_perl server and configured during the startup.
  +and your shell. An example can be a different perl path or having <CODE>PERL5LIB</CODE> env variable which includes paths that are not in the <CODE>@INC</CODE> of the perl compiled with mod_perl server and configured during the
  +startup.
   
   <P>
   The best debugging approach is to write a wrapper that emulates the exact
  -environment of the server, by first deleting the environment variables like
  -PERL5LIB and calling the same perl binary that it is being used by the
  -server. Next, set the environment identical to the server's by copying the
  -perl run directives from server startup and configuration files. It will
  -also allow you to remove completely the first line of the script - since
  -mod_perl skips it and the wrapper knows how to call the script.
  +environment of the server, by first deleting the environment variables like <CODE>PERL5LIB</CODE> and calling the same perl binary that it is being used by the server. Next,
  +set the environment identical to the server's by copying the perl run
  +directives from server startup and configuration files. It will also allow
  +you to remove completely the first line of the script - since mod_perl
  +skips it and the wrapper knows how to call the script.
   
   <P>
  -Below is the example of such a script. Note that we force the -Tw when we
  -call the real script. (I have also added the ability to pass params, which
  -will not happen when you call the cgi from the web)
  +Below is the example of such a script. Note that we force the <CODE>-Tw</CODE>
  +when we call the real script. (I have also added the ability to pass
  +params, which will not happen when you call the cgi from the web)
   
   <P>
   <PRE>  #!/usr/apps/bin/perl -w    
  @@ -761,13 +745,9 @@
     .....
   </PRE>
   <P>
  -The effect of SIGUSR1 and SIGHUP is detailed in: <A
  +The effect of <STRONG>SIGUSR1</STRONG> and <STRONG>SIGHUP</STRONG> is detailed in: <A
   HREF="http://www.apache.org/docs/stopping.html">http://www.apache.org/docs/stopping.html</A>
  -
  -
  -<P>
  -&lt;META&gt;I tried to kill -USR1 and it did not reset the logs!!! kill
  --HUP did work&lt;/META&gt;
  +.
   
   <P>
   I use this script:
  @@ -924,12 +904,11 @@
   
   <P>
   Sometimes an error happens and causes the server to write millions of lines
  -into your error_log file and in a few minutes to put your server down on
  -its knees. For example I get an error <CODE>Callback called exit</CODE>
  -show up in my error_log file many times. The error_log files grows to 300
  -Mbytes in size in a few minutes. You should run a cron job to make sure
  -this does not happen and if it does to take care of it. Andreas J. Koenig
  -is running this shell script every minute:
  +into your <CODE>error_log</CODE> file and in a few minutes to put your server down on its knees. For example
  +I get an error <CODE>Callback called
  +exit</CODE> show up in my error_log file many times. The <CODE>error_log</CODE> file grows to 300 Mbytes in size in a few minutes. You should run a cron
  +job to make sure this does not happen and if it does to take care of it.
  +Andreas J. Koenig is running this shell script every minute:
   
   <P>
   <PRE>  S=`ls -s /usr/local/apache/logs/error_log | awk '{print $1}'`
  @@ -950,7 +929,7 @@
   <P>
   Also check out the daemontools from <A
   HREF="ftp://koobera.math.uic.edu/www/daemontools.html">ftp://koobera.math.uic.edu/www/daemontools.html</A>
  -
  +:
   
   <P>
   <PRE>  ,-----
  @@ -971,7 +950,7 @@
   	     Amazon.com</a>.
   
   	     <HR>
  -	     [    <A HREF="warnings.html">Prev</A> |      <A HREF="index.html">Main Page</A> | <A HREF="security.html">Next</A>      ]
  +	     [    <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%" >
   <TR ALIGN=CENTER VALIGN=TOP>
  @@ -984,7 +963,7 @@
       <B>
         <FONT SIZE=-1>
   	     Written by <A HREF="help.html#This_document_s_Author">Stas Bekman</A>.
  -	     <BR>Last Modified at 06/15/1999
  +	     <BR>Last Modified at 06/27/1999
         </FONT>
       </B>
     </TD>
  
  
  
  1.5       +3 -3      modperl-site/guide/databases.html
  
  Index: databases.html
  ===================================================================
  RCS file: /export/home/cvs/modperl-site/guide/databases.html,v
  retrieving revision 1.4
  retrieving revision 1.5
  diff -u -r1.4 -r1.5
  --- databases.html	1999/06/19 21:15:03	1.4
  +++ databases.html	1999/07/02 13:42:20	1.5
  @@ -949,13 +949,13 @@
     # Quote the list of parameters , alldigits parameters are unquoted (int)
     # print sql_quote(&quot;one&quot;,2,&quot;three&quot;); =&gt; 'one' 2 'three'
     #############
  -  sub sql_quote{ map{ /^(\d+|NULL)$/ ? $_ : &quot;'$_'&quot; } @_ }
  +  sub sql_quote{ map{ /^(\d+|NULL)$/ ? $_ : &quot;\'$_\'&quot; } @_ }
     
     # Escape the list of parameters (all unsafe chars like &quot;,' are escaped )
     # must make a copy of @_ since we might try to change the passed
     # (Modification of a read-only value attempted)
     ##############
  -  sub sql_escape{ my @a = @_; map { s/(['])/\\$1/g;$_} @a }
  +  sub sql_escape{ my @a = @_; map { s/([\'])/\\$1/g;$_} @a }
     
     
     # DESTROY makes all kinds of cleanups if the fuctions were interuppted
  @@ -1161,7 +1161,7 @@
       <B>
         <FONT SIZE=-1>
   	     Written by <A HREF="help.html#This_document_s_Author">Stas Bekman</A>.
  -	     <BR>Last Modified at 06/19/1999
  +	     <BR>Last Modified at 06/26/1999
         </FONT>
       </B>
     </TD>
  
  
  
  1.5       +1 -1      modperl-site/guide/dbm.html
  
  Index: dbm.html
  ===================================================================
  RCS file: /export/home/cvs/modperl-site/guide/dbm.html,v
  retrieving revision 1.4
  retrieving revision 1.5
  diff -u -r1.4 -r1.5
  --- dbm.html	1999/06/19 21:15:03	1.4
  +++ dbm.html	1999/07/02 13:42:21	1.5
  @@ -244,7 +244,7 @@
     
     BEGIN {
         # RCS/CVS complient:  must be all one line, for MakeMaker
  -    $DB_File::Wrap::VERSION = do { my @r = (q$Revision: 1.4 $ =~ /\d+/g); sprintf &quot;%d.&quot;.&quot;%02d&quot; x $#r, @r };
  +    $DB_File::Wrap::VERSION = do { my @r = (q$Revision: 1.5 $ =~ /\d+/g); sprintf &quot;%d.&quot;.&quot;%02d&quot; x $#r, @r };
     
     }
     
  @@ -464,7 +464,7 @@
       <B>
         <FONT SIZE=-1>
   	     Written by <A HREF="help.html#This_document_s_Author">Stas Bekman</A>.
  -	     <BR>Last Modified at 05/08/1999
  +	     <BR>Last Modified at 06/26/1999
         </FONT>
       </B>
     </TD>
  
  
  
  1.14      +1 -1      modperl-site/guide/debug.html
  
  Index: debug.html
  ===================================================================
  RCS file: /export/home/cvs/modperl-site/guide/debug.html,v
  retrieving revision 1.13
  retrieving revision 1.14
  diff -u -r1.13 -r1.14
  --- debug.html	1999/06/19 21:15:03	1.13
  +++ debug.html	1999/07/02 13:42:22	1.14
  @@ -360,7 +360,7 @@
       <B>
         <FONT SIZE=-1>
   	     Written by <A HREF="help.html#This_document_s_Author">Stas Bekman</A>.
  -	     <BR>Last Modified at 06/05/1999
  +	     <BR>Last Modified at 06/26/1999
         </FONT>
       </B>
     </TD>
  
  
  
  1.6       +2 -2      modperl-site/guide/frequent.html
  
  Index: frequent.html
  ===================================================================
  RCS file: /export/home/cvs/modperl-site/guide/frequent.html,v
  retrieving revision 1.5
  retrieving revision 1.6
  diff -u -r1.5 -r1.6
  --- frequent.html	1999/06/19 21:15:03	1.5
  +++ frequent.html	1999/07/02 13:42:22	1.6
  @@ -22,7 +22,7 @@
   <A HREF="http://perl.apache.org"><IMG SRC="images/mod_perl.gif" ALT="Mod Perl Icon" BORDER=0 HEIGHT=30 WIDTH=90 ALIGN=RIGHT></A>
   Frequent mod_perl problems</H1>
   <HR WIDTH="100%">
  -	    [    <A HREF="config.html">Prev</A> |      <A HREF="index.html">Main Page</A> | <A HREF="porting.html">Next</A>      ]<HR><!-- INDEX BEGIN -->
  +	    [    <A HREF="config.html">Prev</A> |      <A HREF="index.html">Main Page</A> | <A HREF="control.html">Next</A>      ]<HR><!-- INDEX BEGIN -->
   <P><B><FONT SIZE=-1>Table of Contents:</FONT></B></P>
   <UL>
   
  @@ -79,7 +79,7 @@
   	     Amazon.com</a>.
   
   	     <HR>
  -	     [    <A HREF="config.html">Prev</A> |      <A HREF="index.html">Main Page</A> | <A HREF="porting.html">Next</A>      ]
  +	     [    <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%" >
   <TR ALIGN=CENTER VALIGN=TOP>
  
  
  
  1.8       +820 -805  modperl-site/guide/guide-src.tar.gz
  
  	<<Binary file>>
  
  
  1.9       +1400 -1297modperl-site/guide/guide.tar.gz
  
  	<<Binary file>>
  
  
  1.4       +1 -1      modperl-site/guide/hardware.html
  
  Index: hardware.html
  ===================================================================
  RCS file: /export/home/cvs/modperl-site/guide/hardware.html,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- hardware.html	1999/06/19 21:15:09	1.3
  +++ hardware.html	1999/07/02 13:42:27	1.4
  @@ -469,7 +469,7 @@
       <B>
         <FONT SIZE=-1>
   	     Written by <A HREF="help.html#This_document_s_Author">Stas Bekman</A>.
  -	     <BR>Last Modified at 06/19/1999
  +	     <BR>Last Modified at 06/26/1999
         </FONT>
       </B>
     </TD>
  
  
  
  1.15      +1 -1      modperl-site/guide/help.html
  
  Index: help.html
  ===================================================================
  RCS file: /export/home/cvs/modperl-site/guide/help.html,v
  retrieving revision 1.14
  retrieving revision 1.15
  diff -u -r1.14 -r1.15
  --- help.html	1999/06/19 21:15:09	1.14
  +++ help.html	1999/07/02 13:42:27	1.15
  @@ -340,7 +340,7 @@
       <B>
         <FONT SIZE=-1>
   	     Written by <A HREF="help.html#This_document_s_Author">Stas Bekman</A>.
  -	     <BR>Last Modified at 06/19/1999
  +	     <BR>Last Modified at 06/26/1999
         </FONT>
       </B>
     </TD>
  
  
  
  1.18      +135 -122  modperl-site/guide/index.html
  
  Index: index.html
  ===================================================================
  RCS file: /export/home/cvs/modperl-site/guide/index.html,v
  retrieving revision 1.17
  retrieving revision 1.18
  diff -u -r1.17 -r1.18
  --- index.html	1999/06/19 21:15:09	1.17
  +++ index.html	1999/07/02 13:42:28	1.18
  @@ -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.13
  - Jun, 19 1999</B></P></CENTER>
  +<CENTER><P><B>Version 1.14
  + Jul, 2 1999</B></P></CENTER>
    
   <P>
   <HR WIDTH="100%"></P>
  @@ -54,6 +54,98 @@
   
   	<LI><A HREF="start.html#What_s_inside_">What's inside?</A>
   </UL>
  +<P><LI><A HREF="porting.html"><B><FONT SIZE=+1>CGI to mod_perl Porting. mod_perl Coding guidelines.</FONT></B></A></LI><P>
  +<UL>
  +
  +	<LI><A HREF="porting.html#Document_Coverage">Document Coverage</A>
  +	<LI><A HREF="porting.html#Before_you_start_to_code">Before you start to code</A>
  +	<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#_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#Memory_leakage">Memory leakage</A>
  +	</UL>
  +
  +	<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>
  +	</UL>
  +
  +	<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#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>
  +</UL>
  +<P><LI><A HREF="performance.html"><B><FONT SIZE=+1>Performance. Benchmarks.</FONT></B></A></LI><P>
  +<UL>
  +
  +	<LI><A HREF="performance.html#Performance_The_Overall_picture">Performance: The Overall picture</A>
  +	<LI><A HREF="performance.html#Sharing_Memory">Sharing Memory</A>
  +	<LI><A HREF="performance.html#Preload_Perl_modules_at_server_s">Preload Perl modules at server startup</A>
  +	<UL>
  +
  +		<LI><A HREF="performance.html#Preload_Perl_modules_Real_Numb">Preload Perl modules - Real Numbers</A>
  +	</UL>
  +
  +	<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#How_can_I_find_if_my_mod_perl_sc">How can I find if my mod_perl scripts have memory leaks (and where)</A>
  +	<LI><A HREF="performance.html#Limiting_the_size_of_the_process">Limiting the size of the processes</A>
  +	<LI><A HREF="performance.html#Limiting_the_resources_used_by_h">Limiting the resources used by httpd children</A>
  +	<LI><A HREF="performance.html#Limiting_the_request_rate_speed_">Limiting the request rate speed (robots blocking)</A>
  +	<LI><A HREF="performance.html#Benchmarks_Impressing_your_Boss">Benchmarks. Impressing your Boss and Colleagues.</A>
  +	<UL>
  +
  +		<LI><A HREF="performance.html#Developers_Talk">Developers Talk</A>
  +		<LI><A HREF="performance.html#Benchmarking_a_Graphic_hits_coun">Benchmarking a Graphic hits counter with Persistent DB Connection</A>
  +		<LI><A HREF="performance.html#Benchmarking_scripts_with_execut">Benchmarking scripts with execution times below 1 second :)</A>
  +		<LI><A HREF="performance.html#PerlHandler_s_Benchmarking">PerlHandler's Benchmarking</A>
  +	</UL>
  +
  +	<LI><A HREF="performance.html#Tuning_the_Apache_s_configuratio">Tuning the Apache's configuration variables for the best performance</A>
  +	<UL>
  +
  +		<LI><A HREF="performance.html#Tuning_with_ab_ApacheBench">Tuning with ab - ApacheBench </A>
  +		<LI><A HREF="performance.html#Tuning_with_crashme_script">Tuning with crashme script</A>
  +		<LI><A HREF="performance.html#Choosing_MaxClients">Choosing MaxClients</A>
  +		<LI><A HREF="performance.html#Choosing_MaxRequestsPerChild">Choosing MaxRequestsPerChild</A>
  +		<LI><A HREF="performance.html#Choosing_MinSpareServers_MaxSpa">Choosing MinSpareServers, MaxSpareServers and StartServers</A>
  +		<LI><A HREF="performance.html#Summary_of_Benchmarking_to_tune_">Summary of Benchmarking to tune all 5 parameters</A>
  +	</UL>
  +
  +	<LI><A HREF="performance.html#Persistent_DB_Connections">Persistent DB Connections</A>
  +	<LI><A HREF="performance.html#Using_1_under_mod_perl_and_be">Using $|=1 under mod_perl and better print() techniques.</A>
  +	<LI><A HREF="performance.html#More_Reducing_Memory_Usage_Tips">More Reducing Memory Usage Tips</A>
  +	<LI><A HREF="performance.html#Profiling">Profiling</A>
  +	<LI><A HREF="performance.html#CGI_pm_s_object_methods_calls_vs">CGI.pm's object methods calls vs. function calls</A>
  +	<LI><A HREF="performance.html#Sending_plain_HTML_as_a_compress">Sending plain HTML as a compressed output</A>
  +</UL>
   <P><LI><A HREF="strategy.html"><B><FONT SIZE=+1>Choosing the Right Strategy</FONT></B></A></LI><P>
   <UL>
   
  @@ -63,13 +155,12 @@
   	<LI><A HREF="strategy.html#One_Plain_and_One_mod_perl_enabl">One Plain and One mod_perl-enabled Apache Servers</A>
   	<LI><A HREF="strategy.html#One_light_non_Apache_and_One_mod">One light non-Apache and One mod_perl enabled Apache Servers</A>
   	<LI><A HREF="strategy.html#Adding_a_Proxy_Server_in_http_Ac">Adding a Proxy Server in http Accelerator Mode</A>
  -	<LI><A HREF="strategy.html#squid_server">squid server</A>
  -	<LI><A HREF="strategy.html#apache_s_mod_proxy">apache's mod_proxy</A>
  +	<LI><A HREF="strategy.html#The_Squid_Server">The Squid Server</A>
  +	<LI><A HREF="strategy.html#An_Apache_s_mod_proxy">An Apache's mod_proxy</A>
   </UL>
  -<P><LI><A HREF="scenario.html"><B><FONT SIZE=+1>Real World Scenarios Implementaion</FONT></B></A></LI><P>
  +<P><LI><A HREF="scenario.html"><B><FONT SIZE=+1>Real World Scenarios Implementation</FONT></B></A></LI><P>
   <UL>
   
  -	<LI><A HREF="scenario.html#Before_you_dive_into_the_gory_de">Before you dive into the gory details</A>
   	<LI><A HREF="scenario.html#Standalone_mod_perl_Enabled_Apac">Standalone mod_perl Enabled Apache Server</A>
   	<UL>
   
  @@ -85,7 +176,7 @@
   		<UL>
   
   			<LI><A HREF="scenario.html#Building_the_httpd_docs_Server">Building the httpd_docs Server</A>
  -			<LI><A HREF="scenario.html#Building_the_httpd_perl_Server_">Building the httpd_perl Server (mod_perl):</A>
  +			<LI><A HREF="scenario.html#Building_the_httpd_perl_mod_per">Building the httpd_perl (mod_perl enabled) Server</A>
   		</UL>
   
   		<LI><A HREF="scenario.html#Configuration_of_the_servers">Configuration of the servers</A>
  @@ -109,12 +200,12 @@
   	<LI><A HREF="install.html#Configuration_and_Installation">Configuration and Installation</A>
   	<UL>
   
  -		<LI><A HREF="install.html#Perl">Perl</A>
  -		<LI><A HREF="install.html#Apache">Apache</A>
  -		<LI><A HREF="install.html#Mod_Perl">Mod_Perl</A>
  +		<LI><A HREF="install.html#perl">perl</A>
  +		<LI><A HREF="install.html#apache">apache</A>
  +		<LI><A HREF="install.html#mod_perl">mod_perl</A>
   	</UL>
   
  -	<LI><A HREF="install.html#How_can_I_tell_whether_mod_perl_">How can I tell whether mod_perl is really installed</A>
  +	<LI><A HREF="install.html#How_can_I_tell_whether_mod_perl_">How can I tell whether mod_perl is running</A>
   	<UL>
   
   		<LI><A HREF="install.html#Testing_by_checking_the_error_lo">Testing by checking the error_log file</A>
  @@ -146,13 +237,19 @@
   		<LI><A HREF="config.html#Location_Configuration">Location Configuration</A>
   		<LI><A HREF="config.html#PerlFreshRestart">PerlFreshRestart</A>
   		<LI><A HREF="config.html#_perl_status_location">/perl-status location</A>
  +		<UL>
  +
  +			<LI><A HREF="config.html#Configuration">Configuration</A>
  +			<LI><A HREF="config.html#Usage">Usage</A>
  +			<LI><A HREF="config.html#Compiled_Registry_Scripts_sectio">Compiled Registry Scripts section seems to be empty.</A>
  +		</UL>
  +
   		<LI><A HREF="config.html#PerlSetVar_PerlSetEnv_and_PerlP">PerlSetVar, PerlSetEnv and PerlPassEnv</A>
   		<LI><A HREF="config.html#perl_startup_file">perl-startup file</A>
   		<UL>
   
   			<LI><A HREF="config.html#Sample_perl_startup_file">Sample perl-startup file</A>
   			<LI><A HREF="config.html#What_modules_should_you_add_to_t">What modules should you add to the startup file and why.</A>
  -			<LI><A HREF="config.html#Is_it_possible_to_preopen_a_DB_c">Is it possible to preopen a DB connection at the server startup?</A>
   			<LI><A HREF="config.html#The_confusion_with_use_clause_">The confusion with use() clause at the server startup?</A>
   			<LI><A HREF="config.html#The_confusion_with_defining_glob">The confusion with defining globals in startup</A>
   		</UL>
  @@ -185,94 +282,20 @@
   	<LI><A HREF="frequent.html#Coverage">Coverage</A>
   	<LI><A HREF="frequent.html#my_scoped_variable_in_nested_s">my() scoped variable in nested subroutines</A>
   	<LI><A HREF="frequent.html#Segfaults_caused_by_PerlFreshRes">Segfaults caused by PerlFreshRestart</A>
  -</UL>
  -<P><LI><A HREF="porting.html"><B><FONT SIZE=+1>CGI to mod_perl Porting. mod_perl Coding guidelines.</FONT></B></A></LI><P>
  -<UL>
  -
  -	<LI><A HREF="porting.html#Document_Coverage">Document Coverage</A>
  -	<LI><A HREF="porting.html#Before_you_start_to_code">Before you start to code</A>
  -	<LI><A HREF="porting.html#Coding_with_mod_perl">Coding with mod_perl</A>
  -	<UL>
  -
  -		<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#_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>
  -		</UL>
  -
  -		<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#Global_Variables">Global Variables</A>
  -		<LI><A HREF="porting.html#Passing_ENV_variables_to_CGI">Passing ENV variables to CGI</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#Memory_leakage">Memory leakage</A>
  -	</UL>
  -
  -	<LI><A HREF="porting.html#Filehandlers_and_locks_leakages">Filehandlers and locks leakages</A>
  -	<LI><A HREF="porting.html#Sometimes_it_Works_Sometimes_it_">Sometimes it Works Sometimes it does Not (Very important!)</A>
  -	<LI><A HREF="porting.html#The_Script_is_too_dirty_It_does">The Script is too dirty, It does the job and I can't afford rewriting it.</A>
  -	<LI><A HREF="porting.html#Apache_PerlRun_a_closer_look">Apache::PerlRun - a closer look</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>
   </UL>
  -<P><LI><A HREF="performance.html"><B><FONT SIZE=+1>Performance. Benchmarks.</FONT></B></A></LI><P>
  +<P><LI><A HREF="control.html"><B><FONT SIZE=+1>Controlling and Monitoring the Server</FONT></B></A></LI><P>
   <UL>
  -
  -	<LI><A HREF="performance.html#Preload_Perl_modules_at_server_s">Preload Perl modules at server startup</A>
  -	<UL>
  -
  -		<LI><A HREF="performance.html#Preload_Perl_modules_Real_Numb">Preload Perl modules - Real Numbers</A>
  -	</UL>
  -
  -	<LI><A HREF="performance.html#Preload_Registry_Scripts">Preload Registry Scripts</A>
  -	<LI><A HREF="performance.html#Sharing_Memory">Sharing Memory</A>
  -	<LI><A HREF="performance.html#Avoid_Importing_Functions">Avoid Importing Functions</A>
  -	<LI><A HREF="performance.html#How_can_I_find_if_my_modperl_scr">How can I find if my modperl scripts have memory leaks (and where)</A>
  -	<LI><A HREF="performance.html#Limiting_the_size_of_the_process">Limiting the size of the processes</A>
  -	<LI><A HREF="performance.html#Limiting_the_resources_used_by_h">Limiting the resources used by httpd children</A>
  -	<LI><A HREF="performance.html#Limiting_the_request_rate_speed_">Limiting the request rate speed (robots blocking)</A>
  -	<LI><A HREF="performance.html#Benchmarks_Impressing_your_Boss">Benchmarks. Impressing your Boss and Colleagues.</A>
  -	<UL>
  -
  -		<LI><A HREF="performance.html#Developers_Talk">Developers Talk</A>
  -		<LI><A HREF="performance.html#Benchmarking_a_Graphic_hits_coun">Benchmarking a Graphic hits counter with Persistent DB Connection</A>
  -		<LI><A HREF="performance.html#Benchmarking_scripts_with_execut">Benchmarking scripts with execution times below 1 second :)</A>
  -		<LI><A HREF="performance.html#PerlHandler_s_Benchmarking">PerlHandler's Benchmarking</A>
  -	</UL>
  -
  -	<LI><A HREF="performance.html#Tuning_the_Apache_s_configuratio">Tuning the Apache's configuration variables for the best performance</A>
  -	<UL>
   
  -		<LI><A HREF="performance.html#Tuning_with_ab_ApacheBench">Tuning with ab - ApacheBench </A>
  -		<LI><A HREF="performance.html#Tuning_with_crashme_script">Tuning with crashme script</A>
  -		<LI><A HREF="performance.html#Choosing_MaxClients">Choosing MaxClients</A>
  -		<LI><A HREF="performance.html#Choosing_MaxRequestsPerChild">Choosing MaxRequestsPerChild</A>
  -		<LI><A HREF="performance.html#Choosing_MinSpareServers_MaxSpa">Choosing MinSpareServers, MaxSpareServers and StartServers</A>
  -		<LI><A HREF="performance.html#Summary_of_Benchmarking_to_tune_">Summary of Benchmarking to tune all 5 parameters</A>
  -	</UL>
  -
  -	<LI><A HREF="performance.html#Preopen_DB_connection_at_server_">Preopen DB connection at server startup:</A>
  -	<LI><A HREF="performance.html#Persistent_DB_Connections">Persistent DB Connections</A>
  -	<LI><A HREF="performance.html#Using_1_under_mod_perl_and_be">Using $|=1 under mod_perl and better print() techniques.</A>
  -	<LI><A HREF="performance.html#More_Reducing_Memory_Usage_Tips">More Reducing Memory Usage Tips</A>
  -	<LI><A HREF="performance.html#Profiling">Profiling</A>
  -	<LI><A HREF="performance.html#CGI_pm_s_object_methods_calls_vs">CGI.pm's object methods calls vs. function calls</A>
  -	<LI><A HREF="performance.html#Sending_plain_HTML_as_a_compress">Sending plain HTML as a compressed output</A>
  +	<LI><A HREF="control.html#Restarting_techniques">Restarting techniques</A>
  +	<LI><A HREF="control.html#Implications_of_sending_TERM_HU">Implications of sending TERM, HUP, and USR1 to the server</A>
  +	<LI><A HREF="control.html#Using_apachectl_to_control_the_s">Using apachectl to control the server</A>
  +	<LI><A HREF="control.html#SUID_start_up_scripts">SUID start-up scripts</A>
  +	<LI><A HREF="control.html#Monitoring_the_Server_A_watchdo">Monitoring the Server. A watchdog.</A>
  +	<LI><A HREF="control.html#Running_server_in_a_single_mode">Running server in a single mode</A>
  +	<LI><A HREF="control.html#Starting_a_personal_server_for_e">Starting a personal server for each developer</A>
  +	<LI><A HREF="control.html#Wrapper_to_emulate_the_server_en">Wrapper to emulate the server environment</A>
  +	<LI><A HREF="control.html#Log_Rotation">Log Rotation</A>
  +	<LI><A HREF="control.html#Preventing_from_modperl_process_">Preventing from modperl process from going wild</A>
   </UL>
   <P><LI><A HREF="obvious.html"><B><FONT SIZE=+1>Things obvious to others, but not to you</FONT></B></A></LI><P>
   <UL>
  @@ -287,14 +310,6 @@
   		<LI><A HREF="obvious.html#Additional_reading_references">Additional reading references</A>
   	</UL>
   
  -	<LI><A HREF="obvious.html#Reloading_Modules_and_Required_F">Reloading Modules and Required Files</A>
  -	<UL>
  -
  -		<LI><A HREF="obvious.html#Restarting_the_server">Restarting the server</A>
  -		<LI><A HREF="obvious.html#Using_Apache_StatINC">Using Apache::StatINC</A>
  -		<LI><A HREF="obvious.html#Reloading_only_specific_files">Reloading only specific files</A>
  -	</UL>
  -
   	<LI><A HREF="obvious.html#Compiled_Regular_Expressions">Compiled Regular Expressions </A>
   	<LI><A HREF="obvious.html#Debugging_your_code_in_Single_Se">Debugging your code in Single Server Mode</A>
   	<LI><A HREF="obvious.html#_M_and_other_time_file_tests_u">-M and other time() file tests under mod_perl</A>
  @@ -326,20 +341,6 @@
   	<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>
   </UL>
  -<P><LI><A HREF="control.html"><B><FONT SIZE=+1>Controlling and Monitoring the Server</FONT></B></A></LI><P>
  -<UL>
  -
  -	<LI><A HREF="control.html#Restarting_techniques">Restarting techniques</A>
  -	<LI><A HREF="control.html#Implications_of_sending_TERM_HU">Implications of sending TERM, HUP, and USR1 to the server</A>
  -	<LI><A HREF="control.html#Using_apachectl_to_control_the_s">Using apachectl to control the server</A>
  -	<LI><A HREF="control.html#SUID_start_up_scripts">SUID start-up scripts</A>
  -	<LI><A HREF="control.html#Monitoring_the_Server_A_watchdo">Monitoring the Server. A watchdog.</A>
  -	<LI><A HREF="control.html#Running_server_in_a_single_mode">Running server in a single mode</A>
  -	<LI><A HREF="control.html#Starting_a_personal_server_for_e">Starting a personal server for each developer</A>
  -	<LI><A HREF="control.html#Wrapper_to_emulate_the_server_en">Wrapper to emulate the server environment</A>
  -	<LI><A HREF="control.html#Log_Rotation">Log Rotation</A>
  -	<LI><A HREF="control.html#Preventing_from_modperl_process_">Preventing from modperl process from going wild</A>
  -</UL>
   <P><LI><A HREF="security.html"><B><FONT SIZE=+1>Protecting Your Site</FONT></B></A></LI><P>
   <UL>
   
  @@ -531,7 +532,10 @@
   
   <UL>
   
  -<LI><A HREF="all.html"><B>Guide All in One. Ready for Printing</B></A></LI>
  +<LI><A HREF="all.html"><B>Guide All in One. Ready for Printing</B></A>
  +(You better use the Postscript Book -- <A
  +HREF="mod_perl_guide.ps.gz">mod_perl_guide.ps.gz</A>)
  + </LI>
   
   <LI><A HREF="CHANGES"><B>CHANGES</B></A></LI>
   
  @@ -580,11 +584,20 @@
   <TD ALIGN=CENTER VALIGN=CENTER COLSPAN="3">
   <HR></TD>
   </TR>
  -
   <TR ALIGN=CENTER VALIGN=TOP>
  +<TD ALIGN=CENTER VALIGN=CENTER COLSPAN="3">
  +URL: <B>http://perl.apache.org/guide</B><BR>
  +Copyright &copy; 1998, 1999 Stas Bekman. All rights reserved.
  +</TD>
  +</TR>
  +<TR ALIGN=CENTER VALIGN=TOP>
  +<TD ALIGN=CENTER VALIGN=CENTER COLSPAN="3">
  +<HR></TD>
  +</TR>
   
  +<TR ALIGN=CENTER VALIGN=TOP>
   <TD ALIGN=CENTER VALIGN=CENTER><B><FONT SIZE=-1>Written by <A
  -HREF="help.html#This_document_s_Author">Stas Bekman</A>.<BR> Last Modified at 06/19/1999
  +HREF="help.html#This_document_s_Author">Stas Bekman</A>.<BR> Last Modified at 07/02/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.5       +110 -106  modperl-site/guide/install.html
  
  Index: install.html
  ===================================================================
  RCS file: /export/home/cvs/modperl-site/guide/install.html,v
  retrieving revision 1.4
  retrieving revision 1.5
  diff -u -r1.4 -r1.5
  --- install.html	1999/06/19 21:15:10	1.4
  +++ install.html	1999/07/02 13:42:28	1.5
  @@ -29,12 +29,12 @@
   	<LI><A HREF="#Configuration_and_Installation">Configuration and Installation</A>
   	<UL>
   
  -		<LI><A HREF="#Perl">Perl</A>
  -		<LI><A HREF="#Apache">Apache</A>
  -		<LI><A HREF="#Mod_Perl">Mod_Perl</A>
  +		<LI><A HREF="#perl">perl</A>
  +		<LI><A HREF="#apache">apache</A>
  +		<LI><A HREF="#mod_perl">mod_perl</A>
   	</UL>
   
  -	<LI><A HREF="#How_can_I_tell_whether_mod_perl_">How can I tell whether mod_perl is really installed</A>
  +	<LI><A HREF="#How_can_I_tell_whether_mod_perl_">How can I tell whether mod_perl is running</A>
   	<UL>
   
   		<LI><A HREF="#Testing_by_checking_the_error_lo">Testing by checking the error_log file</A>
  @@ -75,11 +75,12 @@
   <CENTER><H1><A NAME="Configuration_and_Installation">Configuration and Installation</A></H1></CENTER>
   <P>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<CENTER><H2><A NAME="Perl">Perl</A></H2></CENTER>
  +<CENTER><H2><A NAME="perl">perl</A></H2></CENTER>
   <P>
  -First install perl. Follow the instructions in the distribution's INSTALL
  -file. During the configuration stage (while running
  -<CODE>./Configure</CODE>), make sure you answer <CODE>YES</CODE> to:
  +Make sure you have perl installed -- the newer stable version you have the
  +better (minimum perl.5.004!). If you don't have it -- install it. Follow
  +the instructions in the distribution's <CODE>INSTALL</CODE>
  +file. During the configuration stage (while running <CODE>./Configure</CODE>), make sure you answer <CODE>YES</CODE> to the question:
   
   <P>
   <PRE>  Do you wish to use dynamic loading? [y]
  @@ -89,23 +90,23 @@
   
   <P>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<CENTER><H2><A NAME="Apache">Apache</A></H2></CENTER>
  +<CENTER><H2><A NAME="apache">apache</A></H2></CENTER>
   <P>
  -It is a good idea to try to install the Apache webserver without mod_perl
  -first. This way, if something going wrong, you will know that it's not the
  -Apache server's problem. But you can skip this stage if you already have a
  -working (non-mod_perl) Apache server, or if you are just the daring type.
  -In any case you should unpack the Apache source distribution, preferably at
  +It is a good idea to try to install the apache webserver without mod_perl
  +first. This way, if something goes wrong, you will know that it's not the
  +apache server's problem. But you can skip this stage if you already have a
  +working (non-mod_perl) apache server, or if you are just the daring type.
  +In any case you should unpack the apache source distribution, preferably at
   the same level as the mod_perl distribution.
   
   <P>
   <PRE>  % ls -l /usr/src
  -  drwxr-xr-x   8 stas  bar         2048 Oct  6 09:46 apache_1.3.6/
  -  drwxr-xr-x  19 stas  bar         4096 Oct  2 14:33 mod_perl-1.19/
  +  drwxr-xr-x   8 stas  bar         2048 Oct  6 09:46 apache_x.x.x/
  +  drwxr-xr-x  19 stas  bar         4096 Oct  2 14:33 mod_perl-x.xx/
   </PRE>
   <P>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<CENTER><H2><A NAME="Mod_Perl">Mod_Perl</A></H2></CENTER>
  +<CENTER><H2><A NAME="mod_perl">mod_perl</A></H2></CENTER>
   <P>
   Now we come to the main point of this document.
   
  @@ -115,70 +116,64 @@
   
   <P>
   As with any perl package, the installation of mod_perl is very easy and
  -standard. <CODE>perldoc INSTALL</CODE> will guide you thru the configuration and installation process.
  +standard. <CODE>perldoc INSTALL</CODE> will guide you through the configuration and the installation processes.
   
   <P>
   The fastest way to install would be:
   
   <P>
  -<PRE>  % perl Makefile.PL APACHE_SRC=../apache_1.3.6/src \
  +<PRE>  % 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
   </PRE>
   <P>
  -(Note: if you use an apache version different then apache_1.3.6, change the
  -version number in the example above and in all later examples
  -appropriately)
  +Note: replace x.x.x with the version numbers you actually use.
   
   <P>
   To change the installation target (either if you are not <CODE>root</CODE> or you need to install a second copy for testing purposes), assuming you
  -use /foo/server as a base directory root, you have to run this:
  +use <CODE>/foo/server</CODE> as a base directory, you have to run this:
   
   <P>
  -<PRE>  % perl Makefile.PL APACHE_SRC=../apache_1.3.6/src \
  +<PRE>  % perl Makefile.PL APACHE_SRC=../apache_x.x.x/src \
       DO_HTTPD=1 PERL_MARK_WHERE=1 EVERYTHING=1 \
       APACHE_PREFIX=/foo/server PREFIX=/foo/server
   </PRE>
   <P>
   Where <CODE>PREFIX</CODE> specifies where to install the perl modules,
  -<CODE>APACHE_PREFIX</CODE> - the same for the apache files.
  +<CODE>APACHE_PREFIX</CODE> -- the same for the apache files.
   
   <P>
  -The next step is to configure the mod_perl sections of the apache conf
  -files. See <A HREF="././config.html#">ModPerlConfiguration</A>
  +The next step is to configure the mod_perl sections of the apache
  +configuration file. (See <A HREF="././config.html#">ModPerlConfiguration</A>).
   
  -
  -
   <P>
  -Fire up the server with <CODE>/foo/server/sbin/apachectl start</CODE>, Watch the error log file if server does not start up (No error message
  -will be printed to the console!)
  +Fire up the server with <CODE>/foo/server/sbin/apachectl start</CODE>, Look for the error reports at the <CODE>error_log</CODE> file in case the server does not start up (No error message will be printed
  +to the console!).
   
   <P>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  -<CENTER><H1><A NAME="How_can_I_tell_whether_mod_perl_">How can I tell whether mod_perl is really installed</A></H1></CENTER>
  +<CENTER><H1><A NAME="How_can_I_tell_whether_mod_perl_">How can I tell whether mod_perl is running</A></H1></CENTER>
   <P>
  -There a few ways. In older versions of apache ( &lt; 1.3.6 ?) you could check that by running <CODE>httpd -v</CODE>, it no longer works. Now you should use <CODE>httpd -l</CODE>. Please notice that it is not enough to have it installed - you should of
  -course configure it and restart the server.
  +There are a few ways. In older versions of apache ( &lt; 1.3.6 ?) you could check that by running <CODE>httpd -v</CODE>, it no longer works. Now you should use <CODE>httpd -l</CODE>. Please notice that it is not enough to have it installed - you should of
  +course configure it for mod_perl and restart the server.
   
   <P>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
   <CENTER><H2><A NAME="Testing_by_checking_the_error_lo">Testing by checking the error_log file</A></H2></CENTER>
   <P>
  -When starting the server, just check the <CODE>error_log</CODE> file for this:
  +When starting the server, just check the <CODE>error_log</CODE> file for the following message:
   
   <P>
  -<PRE>  [Thu Dec  3 17:27:52 1998] [notice] Apache/1.3.1 (Unix) mod_perl/1.15 configured
  +<PRE>  [Thu Dec  3 17:27:52 1998] [notice] Apache/1.3.1 (Unix) mod_perl/1.15 configured 
                                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  -   -- resuming normal operations
  +    -- resuming normal operations
   </PRE>
   <P>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
   <CENTER><H2><A NAME="Testing_by_viewing_perl_status">Testing by viewing /perl-status</A></H2></CENTER>
   <P>
  -Assuming that you have configured the &lt;<CODE>Location /perl-status</CODE>&gt;
  -Section in the server configuration file (refer to
  -<A HREF="././config.html#">ModPerlConfiguration</A>), fetch: <A
  -HREF="http://www.yourserver.com/perl-status">http://www.yourserver.com/perl-status</A>
  +Assuming that you have configured the <CODE>&lt;Location /perl-status</CODE>&gt; section in the server configuration file fetch: <A
  +HREF="http://www.nowhere.com/perl-status">http://www.nowhere.com/perl-status</A>
   using your favorite Netscape browser :-)
   
   <P>
  @@ -192,15 +187,15 @@
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
   <CENTER><H2><A NAME="Testing_via_telnet">Testing via telnet</A></H2></CENTER>
   <P>
  -Knowing the port you have configured Apache to listen on, you can use
  -<CODE>telnet</CODE> to talk directly to the web server.
  +Knowing the port you have configured apache to listen on, you can use
  +<CODE>telnet</CODE> to talk directly to it.
   
   <P>
   Assuming that your mod_perl enabled server listens to port 8080, telnet to
  -your server at port 8080, and type <CODE>HEAD / HTTP/1.0</CODE> then press the &lt;ENTER&gt; key TWICE!
  +your server at port 8080, and type <CODE>HEAD / HTTP/1.0</CODE> then press the &lt;ENTER&gt; key TWICE:
   
   <P>
  -<PRE>  % telnet yourserver.com 8080&lt;ENTER&gt;
  +<PRE>  % telnet localhost 8080&lt;ENTER&gt;
     HEAD / HTTP/1.0&lt;ENTER&gt;&lt;ENTER&gt;
   </PRE>
   <P>
  @@ -216,8 +211,7 @@
     Connection closed.
   </PRE>
   <P>
  -So you see <CODE>Server: Apache/1.3.6 (Unix) mod_perl/1.19</CODE> - which says that you <STRONG>do</STRONG> have mod_perl installed and it is version 1.19. Of course in your case it
  -would be the version you have installed.
  +The line: <CODE>Server: Apache/1.3.6 (Unix) mod_perl/1.19</CODE> --confirms that you <STRONG>do</STRONG> have mod_perl installed and its version is <CODE>1.19</CODE>. Of course in your case it would be the version you have installed.
   
   <P>
   However, just because you have got mod_perl linked in there, that does not
  @@ -235,9 +229,10 @@
   environment.
   
   <P>
  -Copy and paste the script below (no need for perl line!). Let's say you
  -called it test.pl, you saved it into the root of the cgi scripts, and cgi
  -root is mapped directly to /perl of your server.
  +Copy and paste the script below (no need for the first perl calling
  +(shebang) line!). Let's say you named it <CODE>test.pl</CODE>, saved it at the root of the CGI scripts and CGI root is mapped directly
  +to the
  +<CODE>/perl</CODE> location of your server.
   
   <P>
   <PRE>  print &quot;Content-type: text/html\n\n&quot;;
  @@ -249,14 +244,17 @@
     print &quot;&lt;/TABLE&gt;&quot;;
   </PRE>
   <P>
  -Make it executable:
  +Make it readable and executable by server:
   
   <P>
  -<PRE>  % chmod a+x test.pl
  +<PRE>  % chmod a+rx test.pl
   </PRE>
  +<P>
  +(you will want to tune permissions on the public host).
  +
   <P>
  -Now fetch the URL <CODE>http://www.you.com:8080/perl/test.pl</CODE> (replace 8080 with the port your mod_perl enabled server is listening to.
  -You should see something like this (part of the output was snipped).
  +Now fetch the URL <CODE>http://www.nowhere.com:8080/perl/test.pl</CODE> (replace 8080 with the port your mod_perl enabled server is listening to.
  +You should see something like this (the generated output was trimmed):
   
   <P>
   <PRE>  SERVER_SOFTWARE    Apache/1.3.6 (Unix) mod_perl/1.19
  @@ -269,8 +267,10 @@
     [...snipped]
   </PRE>
   <P>
  -Now if I run the same script in mod_cgi mode (configured with /cgi-bin)
  -(you will need to add the perl line <CODE>#!/bin/perl</CODE> for the above script) and fetch <CODE>http://www.you.com/cgi-bin/test.pl</CODE>.
  +Now if I run the same script in mod_cgi mode (configured with
  +<CODE>/cgi-bin</CODE> Alias) (you will need to add the perl invocation line
  +<CODE>#!/bin/perl</CODE> for the above script) and fetch
  +<CODE>http://www.nowhere.com/cgi-bin/test.pl</CODE>.
   
   <P>
   <PRE>  SERVER_SOFTWARE   Apache/1.3.6 (Unix)
  @@ -296,9 +296,11 @@
   <P>
   You might wonder why in the world you would need to know in what mode you
   are running. For example you will want to use <CODE>Apache::exit()</CODE>
  -and not <CODE>CORE::exit()</CODE> in your scripts, but if you think that your script might be used in both
  +and not <CODE>CORE::exit()</CODE> in your modules, but if you think that your script might be used in both
   environments (mod_cgi vs. mod_perl), you will have to override the <CODE>exit()</CODE> subroutine and to make the runtime decision of what method you will use.
  -For reasons and implementations see: <A HREF="././porting.html#Using_exit_">Using exit()</A> and the whole <A HREF="././porting.html#">Writing Mod Perl scripts and Porting plain CGIs to it</A> page.
  +Not that if you run scripts under <CODE>Apache::Registry</CODE> handler, it takes care of overriding the
  +<CODE>exit()</CODE> call for you, so it's not an issue if this is your case. For reasons and
  +implementations see: <A HREF="././porting.html#Using_exit_">Using exit()</A> and the whole <A HREF="././porting.html#">Writing Mod Perl scripts and Porting plain CGIs to it</A> page.
   
   <P>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  @@ -308,32 +310,30 @@
   serving a very simple purpose, they can be helpful in other situations.
   
   <P>
  -Assuming you have the libwww-perl (LWP) package installed (you will need it
  -installed in order to pass mod_perl's <CODE>make test</CODE> anyway):
  +Assuming you have the <CODE>libwww-perl</CODE> (<CODE>LWP</CODE>) package installed (you will need it installed in order to pass mod_perl's <CODE>make test</CODE> anyway):
   
   <P>
  -<PRE>  % lwp-request -e -d www.site.com
  +<PRE>  % lwp-request -e -d <A HREF="http://www.nowhere.com">http://www.nowhere.com</A>
   </PRE>
   <P>
   Will show you all the headers. (The <CODE>-d</CODE> option disables printing the response content.)
   
   <P>
  -<PRE>  % lwp-request -e -d www.site.com | egrep '^Server:'
  +<PRE>  % lwp-request -e -d <A HREF="http://www.nowhere.com">http://www.nowhere.com</A> | egrep '^Server:'
   </PRE>
   <P>
   To see the server's version only.
   
   <P>
  -Again use <CODE>www.site.com:port_number</CODE> if your server is listening to a non-default 80 port.
  +Use <CODE>http://www.nowhere.com:port_number</CODE> if your server is listening to a non-default 80 port.
   
   <P>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
   <CENTER><H1><A NAME="Is_it_possible_to_install_and_us">Is it possible to install and use apache/mod_perl without having a root access?</A></H1></CENTER>
   <P>
  -Yes, no problem with that. Follow the instructions above and when you
  -encounter APACI_ARGS use your home directory (or some other directory which
  -you have write access to as a prefix, for example,
  -<CODE>/home/stas/www</CODE>) and everything will be installed there. There is a chance that some perl
  +Yes, no problem with that. Follow the installation instructions and when
  +you encounter <CODE>APACI_ARGS</CODE> use your home directory (or some other directory which you have write
  +access to) as a prefix, (e.g. <CODE>/home/stas/www</CODE>), and everything will be installed there. There is a chance that some perl
   libs will be not installed on your server by root and you will have to
   install these locally too. See the <A
   HREF="http://www.singlesheaven.com/stas/TULARC/webmaster/myfaq.html#7">http://www.singlesheaven.com/stas/TULARC/webmaster/myfaq.html#7</A>
  @@ -342,29 +342,27 @@
   <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.you.com:8080</CODE> in that case, but that is not a problem since generally users do not
  -directly access URLs to CGI scripts, but rather are directed to them from a
  -link on a web page or as the '<CODE>ACTION</CODE>' of an HTML form, so they should not know at all that the port is
  -different from the default port 80.
  +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
  +access URLs to CGI scripts, but rather are directed to them from a link on
  +a web page or as the '<CODE>ACTION</CODE>' of a HTML form, so they should not know at all that the port is different
  +from the default port 80.
   
   <P>
  -If you want your Apache server to start automatically on system reboot, you
  +If you want your apache server to start automatically on system reboot, you
   will need to invoke the server startup script from somewhere within the
  -init scripts on your host. (This is often somewhere under <CODE>/etc/rc.d</CODE>, but this path can vary depending upon the flavor of Unix you are using.)
  +init scripts on your host. This is often somewhere under <CODE>/etc/rc.d</CODE>, but this path can vary depending upon the flavor of Unix you are using.
   
   <P>
  -One more important thing to keep in mind is system resources. Mod_perl is
  -memory hungry -- if you run a lot of mod_perl processes on that machine
  -(and it's not your own host...), most likely the system administrator of
  -the host will ask you to shutdown your mod_perl server, or to find another
  -home for it. You have a few solutions:
  +One more important thing to keep in mind is system resources. mod_perl is
  +memory hungry -- if you run a lot of mod_perl processes on a public,
  +multiuser (not dedicated) machine -- most likely the system administrator
  +of the host will ask you to use less resources and even to shut down your
  +mod_perl server and to find another home for it. You have a few solutions:
   
   <UL>
   <P><LI>
   <P>
  -Reduce resource usage - see <A HREF="././performance.html#Limiting_the_size_of_the_process">Limiting the size of the processes</A>
  -
  -
  +Reduce resources usage (see <A HREF="././performance.html#Limiting_the_size_of_the_process">Limiting the size of the processes</A>).
   
   <P><LI>
   <P>
  @@ -374,6 +372,8 @@
   <P><LI>
   <P>
   Look for another ISP with lots of resources or one that supports mod_perl.
  +You can find a list of these ISP at <A
  +HREF="http://perl.apache.org">http://perl.apache.org</A> .
   
   </UL>
   <P>
  @@ -382,16 +382,16 @@
   <P>
   It is possible to determine which options were given to modperl's
   <CODE>Makefile.PL</CODE> during the configuration stage, so to be used later in recreating the same
  -build tree when rebuilding the server. This is relevant only if did not use
  -the default config parameters and altered some of them during the
  +build tree when rebuilding the server. This is relevant only if you did not
  +use the default config parameters and altered some of them during the
   configuration stage.
   
   <P>
   I was into this problem many times. I am going to build something by
  -passing some non default parameters to the config script and then later
  +passing some non-default parameters to the config script and then later
   when I need to rebuild the tool either to upgrade it or to make an
  -identical copy at some other machine, I have found that I do not remember
  -what parameters did I altered.
  +identical copy at another machine, I would find that I do not remember what
  +parameters I altered.
   
   <P>
   The best solution for this problem is to prepare the run file with all the
  @@ -399,13 +399,13 @@
   all by hand. So later I will have the script handy to be reused.
   
   <P>
  -mod_perl suggests using the <CODE>makepl_args.mod_perl</CODE> file which comes with mod_perl distribution. This is the file you specify
  -all the parameters you are going to use.
  +mod_perl suggests using the <CODE>makepl_args.mod_perl</CODE> file which comes with mod_perl distribution. This is the file where you
  +should specify all the parameters you are going to use.
   
   <P>
   But if you have found yourself with a compiled tool and no traces of the
  -specified parameters left, you can still find them out if the sources were
  -not <CODE>make clean</CODE>'d. So you will find the apache specific parameters in <CODE>apache_x.x.x/config.status</CODE> and modperl's at in <CODE>mod_perl_x.xx/apaci/mod_perl.config</CODE>.
  +specified parameters left, usually you can still find them out, if the
  +sources were not <CODE>make clean</CODE>'d. You will find the apache specific parameters in <CODE>apache_x.x.x/config.status</CODE> and modperl's at in <CODE>mod_perl_x.xx/apaci/mod_perl.config</CODE>.
   
   <P>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  @@ -414,18 +414,17 @@
   <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>
  -you can use in <CODE>perl Makefile.PL [options]</CODE>.
  +There are two configuration parameters: <CODE>PREP_HTTPD</CODE> and <CODE>DO_HTTPD</CODE>, that you can use in:
   
   <P>
  -<CODE>DO_HTTPD=1</CODE> means default to 'y' for the two prompts (which source tree to configure
  -against and to build the httpd in that tree).
  -<CODE>PREP_HTTPD=1</CODE> just means default 'n' to the second prompt, meaning, do not build httpd
  -(make) in the Apache source tree.
  -
  +<PRE>  perl Makefile.PL [options]
  +</PRE>
   <P>
  -In other words if you use <CODE>PREP_HTTPD=1</CODE> the httpd will be not build. It will be build only if you use <CODE>DO_HTTPD=1</CODE> option and not use
  -<CODE>PREP_HTTPD=1</CODE>.
  +<CODE>DO_HTTPD=1</CODE> means default to '<CODE>y</CODE>' for the two apache's
  +<CODE>configure</CODE> utility prompts: (a) 'which source tree to configure against' and (b)
  +'whether to build the httpd in that tree'. <CODE>PREP_HTTPD=1</CODE> just means default '<CODE>n</CODE>' to the second prompt -- meaning, <EM>do not build httpd (make) in the
  +apache source tree</EM>. In other words if you use <CODE>PREP_HTTPD=1</CODE> the httpd will be not build. It will be build only if you use
  +<CODE>DO_HTTPD=1</CODE> option and not use <CODE>PREP_HTTPD=1</CODE>.
   
   <P>
   If you did not build the httpd, chdir to the apache source, and execute:
  @@ -441,7 +440,7 @@
     make install
   </PRE>
   <P>
  -Note that you will have to do the same if you did not pass
  +Note that you would have to do the same if you do not pass
   <CODE>APACHE_PREFIX=/path_to_installation_prefix</CODE> during the <CODE>perl
   Makefile.PL [options]</CODE> stage.
   
  @@ -450,20 +449,25 @@
   <CENTER><H2><A NAME="mod_perl_c_is_incompatible_with_">mod_perl.c is incompatible with this version of apache</A></H2></CENTER>
   <P>
   You will see this message when you try to run a httpd, if you have had a
  -stale old apache header layout in one of the <CODE>include</CODE> paths. Do
  -<CODE>find</CODE> for <CODE>ap_mmn.h</CODE>, In my case I have had a
  +stale old apache header layout in one of the <CODE>include</CODE> paths during the build process. Do run <CODE>find</CODE> (or <CODE>locate</CODE>) utility in order to locate <CODE>ap_mmn.h</CODE> file. In my case I have had a
   <CODE>/usr/local/include/ap_mmn.h</CODE> which was installed by RedHat install process. If this is the case get rid
   of it, and rebuild it again.
   
  +<P>
  +For all RH fans, before you are going to build the apache by yourself, do:
  +
  +<P>
  +<PRE>  rpm -e apache
  +</PRE>
   <P>
  -For all RH fans, before you are going to build the apache by yourself, do: <CODE>rpm -e apache</CODE> to remove the preinstalled one first!
  +to remove the pre-installed package first!
   
   <P>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
   <CENTER><H2><A NAME="Should_I_rebuild_mod_perl_if_I_h">Should I rebuild mod_perl if I have upgraded my perl?</A></H2></CENTER>
   <P>
  -Yes, you should. You have to rebuild mod_perl since it has a hardcoded
  -<CODE>@INC</CODE> which points to the old perl and it is is probably linked to the an old <CODE>libperl</CODE> library. You can try to modify the <CODE>@INC</CODE> in the startup script (if you keep the old perl version around), but it is
  +Yes, you should. You have to rebuild mod_perl enabled server since it has a
  +hard coded <CODE>@INC</CODE> which points to the old perl and it is is probably linked to the an old <CODE>libperl</CODE> library. You can try to modify the <CODE>@INC</CODE> in the startup script (if you keep the old perl version around), but it is
   better to build a fresh one to save you a mess.
   
   <P>
  @@ -500,7 +504,7 @@
       <B>
         <FONT SIZE=-1>
   	     Written by <A HREF="help.html#This_document_s_Author">Stas Bekman</A>.
  -	     <BR>Last Modified at 06/12/1999
  +	     <BR>Last Modified at 07/02/1999
         </FONT>
       </B>
     </TD>
  
  
  
  1.12      +1 -1      modperl-site/guide/intro.html
  
  Index: intro.html
  ===================================================================
  RCS file: /export/home/cvs/modperl-site/guide/intro.html,v
  retrieving revision 1.11
  retrieving revision 1.12
  diff -u -r1.11 -r1.12
  --- intro.html	1999/06/19 21:15:10	1.11
  +++ intro.html	1999/07/02 13:42:28	1.12
  @@ -291,7 +291,7 @@
       <B>
         <FONT SIZE=-1>
   	     Written by <A HREF="help.html#This_document_s_Author">Stas Bekman</A>.
  -	     <BR>Last Modified at 06/19/1999
  +	     <BR>Last Modified at 06/26/1999
         </FONT>
       </B>
     </TD>
  
  
  
  1.2       +771 -647  modperl-site/guide/mod_perl_guide.ps.gz
  
  	<<Binary file>>
  
  
  1.6       +14 -13    modperl-site/guide/modules.html
  
  Index: modules.html
  ===================================================================
  RCS file: /export/home/cvs/modperl-site/guide/modules.html,v
  retrieving revision 1.5
  retrieving revision 1.6
  diff -u -r1.5 -r1.6
  --- modules.html	1999/06/19 21:15:11	1.5
  +++ modules.html	1999/07/02 13:42:29	1.6
  @@ -186,16 +186,16 @@
   <CENTER><H1><A NAME="Apache_GzipChain_compress_HTM">Apache::GzipChain - compress HTML (or anything) in the OutputChain</A></H1></CENTER>
   <P>
   Have you ever served a huge HTML file (e.g. a file bloated with JavaScript
  -code) and wandered how could you compress it, thus drammatically cutting
  -down the download times. After all java applets can be compressed into a
  -jar and benefit from a faster download. Why cannot we do the same with a
  -plain ASCII (HTML,JS and etc), it is a known fact that ASCII can be
  -compressed 10 times smaller than the original size.
  +code) and wandered how could you send it compressed, thus drammatically
  +cutting down the download times. After all java applets can be compressed
  +into a jar and benefit from a faster download times. Why cannot we do the
  +same with a plain ASCII (HTML,JS and etc), it is a known fact that ASCII
  +text can be compressed by a factor of 10.
   
   <P>
  -<CODE>Apache::GzipChain</CODE> comes to help you with this task. If a client (browser) understands <CODE>gzip</CODE> encoding this module compresses the output and send it downstream. A client
  -decompress the data upon receive and renders the HTML as if it was a plain
  -HTML fetch.
  +<CODE>Apache::GzipChain</CODE> comes to help you with this task. If a client (browser) understands <CODE>gzip</CODE> encoding this module compresses the output and sends it downstream. A
  +client decompresses the data upon receive and renders the HTML as if it was
  +a plain HTML fetch.
   
   <P>
   For example to compress all html files on the fly, do:
  @@ -207,7 +207,7 @@
     &lt;/Files&gt;
   </PRE>
   <P>
  -Remember that it will work only if the browsers claims to accept compressed
  +Remember that it will work only if the browser claims to accept compressed
   input, thru <CODE>Accept-Encoding</CODE> header. <CODE>Apache::GzipChain</CODE>
   keeps a list of user-agents, thus it also looks at <CODE>User-Agent</CODE>
   header, for known to accept compressed output browsers.
  @@ -218,15 +218,16 @@
   
   <P>
   <PRE>  &lt;Location /test&gt;
  -    SetHandler &quot;perl-script&quot;
  +    SetHandler perl-script
       PerlHandler Apache::OutputChain Apache::GzipChain Apache::EmbperlChain Apache::PassFile
     &lt;/Location&gt;
   </PRE>
   <P>
  -Hint: Watch an <CODE>access_log</CODE> file to see how many bytes were actually send.
  +Hint: Watch an <CODE>access_log</CODE> file to see how many bytes were actually send, compare with a regular
  +configuration send.
   
   <P>
  -See the module's documentaion for more details.
  +(See <CODE>perldoc Apache::GzipChain</CODE>).
   
   <P>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  @@ -296,7 +297,7 @@
       <B>
         <FONT SIZE=-1>
   	     Written by <A HREF="help.html#This_document_s_Author">Stas Bekman</A>.
  -	     <BR>Last Modified at 06/15/1999
  +	     <BR>Last Modified at 06/26/1999
         </FONT>
       </B>
     </TD>
  
  
  
  1.6       +1 -1      modperl-site/guide/multiuser.html
  
  Index: multiuser.html
  ===================================================================
  RCS file: /export/home/cvs/modperl-site/guide/multiuser.html,v
  retrieving revision 1.5
  retrieving revision 1.6
  diff -u -r1.5 -r1.6
  --- multiuser.html	1999/06/19 21:15:11	1.5
  +++ multiuser.html	1999/07/02 13:42:29	1.6
  @@ -234,7 +234,7 @@
       <B>
         <FONT SIZE=-1>
   	     Written by <A HREF="help.html#This_document_s_Author">Stas Bekman</A>.
  -	     <BR>Last Modified at 04/19/1999
  +	     <BR>Last Modified at 06/26/1999
         </FONT>
       </B>
     </TD>
  
  
  
  1.15      +123 -219  modperl-site/guide/obvious.html
  
  Index: obvious.html
  ===================================================================
  RCS file: /export/home/cvs/modperl-site/guide/obvious.html,v
  retrieving revision 1.14
  retrieving revision 1.15
  diff -u -r1.14 -r1.15
  --- obvious.html	1999/06/19 21:15:11	1.14
  +++ obvious.html	1999/07/02 13:42:29	1.15
  @@ -22,7 +22,7 @@
   <A HREF="http://perl.apache.org"><IMG SRC="images/mod_perl.gif" ALT="Mod Perl Icon" BORDER=0 HEIGHT=30 WIDTH=90 ALIGN=RIGHT></A>
   Things obvious to others, but not to you</H1>
   <HR WIDTH="100%">
  -	    [    <A HREF="performance.html">Prev</A> |      <A HREF="index.html">Main Page</A> | <A HREF="warnings.html">Next</A>      ]<HR><!-- INDEX BEGIN -->
  +	    [    <A HREF="control.html">Prev</A> |      <A HREF="index.html">Main Page</A> | <A HREF="warnings.html">Next</A>      ]<HR><!-- INDEX BEGIN -->
   <P><B><FONT SIZE=-1>Table of Contents:</FONT></B></P>
   <UL>
   
  @@ -36,14 +36,6 @@
   		<LI><A HREF="#Additional_reading_references">Additional reading references</A>
   	</UL>
   
  -	<LI><A HREF="#Reloading_Modules_and_Required_F">Reloading Modules and Required Files</A>
  -	<UL>
  -
  -		<LI><A HREF="#Restarting_the_server">Restarting the server</A>
  -		<LI><A HREF="#Using_Apache_StatINC">Using Apache::StatINC</A>
  -		<LI><A HREF="#Reloading_only_specific_files">Reloading only specific files</A>
  -	</UL>
  -
   	<LI><A HREF="#Compiled_Regular_Expressions">Compiled Regular Expressions </A>
   	<LI><A HREF="#Debugging_your_code_in_Single_Se">Debugging your code in Single Server Mode</A>
   	<LI><A HREF="#_M_and_other_time_file_tests_u">-M and other time() file tests under mod_perl</A>
  @@ -71,7 +63,7 @@
   <CENTER><H1><A NAME="Coverage">Coverage</A></H1></CENTER>
   <P>
   This document describes ``special'' traps you may encounter when running
  -your plain CGIs under Apache::Registry and Apache::PerlRun.
  +your plain CGIs under <CODE>Apache::Registry</CODE> and <CODE>Apache::PerlRun</CODE>.
   
   <P>
   <P><B><FONT SIZE=-1><A HREF="#toc">[TOC]</A></FONT></B><HR WIDTH="100%"></P>
  @@ -91,8 +83,7 @@
       }
   </PRE>
   <P>
  -However, the script is run under Apache::Registry, it will in fact be
  -repackaged into something like this:
  +However, the script is run under <CODE>Apache::Registry</CODE>, it will in fact be repackaged into something like this:
   
   <P>
   <PRE>  package $mangled_package_name;
  @@ -106,24 +97,24 @@
     }
   </PRE>
   <P>
  -Now <CODE>