home *** CD-ROM | disk | FTP | other *** search
/ PC Professionell 2004 December / PCpro_2004_12.ISO / files / webserver / tsw / TSW_3.4.0.exe / Apache2 / perl / Admin.pod < prev    next >
Encoding:
Text File  |  2003-12-12  |  36.9 KB  |  1,086 lines

  1. =head1 NAME
  2.  
  3. HTML::Mason::Admin - Mason Administrator's Manual
  4.  
  5. =head1 DESCRIPTION
  6.  
  7. This manual is written for the sysadmin/webmaster in charge of
  8. installing, configuring, or tuning a Mason system.  The bulk of the
  9. documentation assumes that you are using mod_perl.  See L<RUNNING
  10. OUTSIDE OF MOD_PERL|HTML::Mason::Admin/RUNNING OUTSIDE OF MOD_PERL>
  11. for more details. For more details on mod_perl, visit
  12. the mod_perl website at http://perl.apache.org/.
  13.  
  14. =head1 SITE CONFIGURATION METHODS
  15.  
  16. Mason includes module specifically designed to integrate Mason and
  17. mod_perl, C<HTML::Mason::ApacheHandler>.  By telling mod_perl to hand
  18. content requests to this module, you can use Mason to generate web
  19. pages.  There are two ways to configure Mason under mod_perl.
  20.  
  21. =over 4
  22.  
  23. =item * Basic
  24.  
  25. Mason provides reasonable default behavior under mod_perl, so using
  26. Mason can be as simple as adding two directives to your Apache
  27. configuration file.  Throughout this document, we will assume that
  28. your Apache configuration file is called F<httpd.conf>.  By adding
  29. more configuration parameters to this file you can implement more
  30. complex behaviors.
  31.  
  32. =item * Advanced
  33.  
  34. If the basic method does not provide enough flexibility for you, you
  35. can wrap Mason in a custom mod_perl handler.  The wrapper code you
  36. write can create its own Mason objects, or it can take advantage of
  37. F<httpd.conf> configuration parameters and let Mason create the
  38. objects it needs by itself.
  39.  
  40. =back
  41.  
  42. We recommend that you start with the basic method and work your way
  43. forward as the need for flexibility arises.
  44.  
  45. Mason is very flexible, and you can replace parts of it by creating
  46. your own classes.  This documentation assumes that you are simply
  47. using the classes provided in the Mason distribution.  Subclassing is
  48. covered in the L<Subclassing|HTML::Mason::Subclassing> document.  The
  49. two topics are orthogonal, as you can mix the configuration techniques
  50. discussed here with your own custom subclasses.
  51.  
  52. =head1 BASIC CONFIGURATION VIA httpd.conf DIRECTIVES
  53.  
  54. The absolutely most minimal configuration looks like this:
  55.  
  56.     PerlModule HTML::Mason::ApacheHandler
  57.  
  58.     <Location />
  59.       SetHandler   perl-script
  60.       PerlHandler  HTML::Mason::ApacheHandler
  61.     </Location>
  62.  
  63. This configuration tells Apache to serve all URLs through Mason (see
  64. the next section for a more realistic strategy).  We use the
  65. PerlModule line to tell mod_perl to load Mason once at startup time,
  66. saving time and memory.  This example does not set any Mason
  67. configuration parameters, so Mason uses its default values.
  68.  
  69. If this is your first time installing and using Mason, we recommend
  70. that you use the above configuration in a test webserver to start
  71. with.  This will let you play with Mason under mod_perl with a minimum
  72. of fuss.  Once you've gotten this working, then come back and read the
  73. rest of the document for further possibilities.
  74.  
  75. =head2 Controlling Access via Filename Extension
  76.  
  77. As it turns out, serving every URL through Mason is a bad idea for two
  78. reasons:
  79.  
  80. =over
  81.  
  82. =item 1.
  83.  
  84. Mason should be prevented from handling images, tarballs, and other
  85. binary files. Not only will performance suffer, but binary files may
  86. inadvertently contain a Mason character sequence such as "<%". These
  87. files should be instead served by Apache's default content handler.
  88.  
  89. =item 2.
  90.  
  91. Mason should be prevented from serving private (non-top-level) Mason
  92. components to users. For example, if you used a utility component for
  93. performing arbitrary sql queries, you wouldn't want external users to
  94. be able to access it via a URL. Requests for private components should
  95. simply result in a 404 NOT_FOUND.
  96.  
  97. =back
  98.  
  99. The easiest way to distinguish between different types of files is
  100. with filename extensions. While many naming schemes are possible, we
  101. suggest using "normal" extensions for top-level components and
  102. adding an "m" prefix for private components. For example,
  103.  
  104.                              Top-level       Private
  105.  
  106.    Component outputs HTML    .html           .mhtml
  107.    Component outputs text    .txt            .mtxt
  108.    Component executes Perl   .pl             .mpl
  109.  
  110. This scheme minimizes the chance of confusing browsers about content
  111. type, scales well for new classes of content (e.g. .js/.mjs for
  112. javascript), and makes transparent the fact that you are using Mason
  113. versus some other package.
  114.  
  115. Here is a configuration that enforces this naming scheme:
  116.  
  117.     PerlModule HTML::Mason::ApacheHandler
  118.  
  119.     <LocationMatch "(\.html|\.txt|\.pl)$">
  120.       SetHandler perl-script
  121.       PerlHandler HTML::Mason::ApacheHandler
  122.     </LocationMatch>
  123.  
  124.     <LocationMatch "(\.m(html|txt|pl)|dhandler|autohandler)$">
  125.       SetHandler perl-script
  126.       PerlInitHandler Apache::Constants::NOT_FOUND
  127.     </LocationMatch>
  128.  
  129. The first block causes URLs ending in .html, .txt, or .pl to be served
  130. through Mason. The second block causes requests to private components
  131. to return 404 NOT_FOUND, preventing unscrupulous users from even
  132. knowing which private components exist. Any other file extensions
  133. (e.g. .gif, .tgz) will be served by Apache's default content handler.
  134.  
  135. You might prefer C<FilesMatch> to C<LocationMatch>. However, be aware
  136. that C<LocationMatch> will work best in conjunction with Mason's
  137. L<dhandlers|HTML::Mason::Devel/dhandlers>.
  138.  
  139. =head2 Configuration Parameters
  140.  
  141. Mason allows you to flexibly configure its behavior via F<httpd.conf>
  142. configuration parameters.
  143.  
  144. These configuration parameters are set via mod_perl's C<PerlSetVar>
  145. and C<PerlAddVar> directives (the latter is only available in mod_perl
  146. version 1.24 and greater).  Though these parameters are all strings in
  147. your F<httpd.conf> file, Mason treats different directives as
  148. containing different types of values:
  149.  
  150. =over 4
  151.  
  152. =item * string
  153.  
  154. The variable's value is simply taken literally and used.  The string
  155. should be surrounded by quotes if the it contains whitespace.  The
  156. quotes will be automatically removed by Apache before Mason sees the
  157. variable.
  158.  
  159. =item * boolean
  160.  
  161. The variable's value is used as a boolean, and is subject to Perl's
  162. rules on truth/falseness.  It is recommended that you use 0 (false) or
  163. 1 (true) for these arguments.
  164.  
  165. =item * code
  166.  
  167. The string is treated as a piece of code and C<eval>'ed.  This is used
  168. for parameters that expect subroutine references.  For example, an
  169. anonymous subroutine might look like:
  170.  
  171.  PerlSetVar  MasonOutMode  "sub { ... }"
  172.  
  173. A named subroutine reference would look like this:
  174.  
  175.  PerlSetVar  MasonOutMode  "\&Some::Module::handle_output"
  176.  
  177. =item * list
  178.  
  179. To set a list parameter, use C<PerlAddVar> for the values, like this:
  180.  
  181.  PerlAddVar  MasonPreloads  /foo/bar/baz.comp
  182.  PerlAddVar  MasonPreloads  /foo/bar/quux.comp
  183.  
  184. As noted above, C<PerlAddVar> is only available in mod_perl 1.24 and
  185. up.  This means that it is only possible to assign a single value
  186. (using C<PerlSetVar>) to list parameters if you are using a mod_perl
  187. older than 1.24.
  188.  
  189. =item * hash_list
  190.  
  191. Just like a list parameter, use C<PerlAddVar> for the values.
  192. However, in the case of a hash_list, each element should be a
  193. key/value pair separated by "=>":
  194.  
  195.  PerlAddVar  MasonDataCacheDefaults  "cache_class => MemoryCache"
  196.  PerlAddVar  MasonDataCacheDefaults  "namespace => foo"
  197.  
  198. Take note that the right hand side of the each pair should I<not> be
  199. quoted.
  200.  
  201. =back
  202.  
  203. See L<HTML::Mason::Params|HTML::Mason::Params> for a full list
  204. of parameters, and their associated types.
  205.  
  206. =head1 GENERAL SERVER CONFIGURATION
  207.  
  208. =head2 Component Root
  209.  
  210. The component root (L<comp_root|HTML::Mason::Params/comp_root>) marks the top of your component
  211. hierarchy.  When running Mason with the ApacheHandler or CGIHandler
  212. modules, this defaults to your document root.
  213.  
  214. The component root defines how component paths are translated into
  215. real file paths. If your component root is F</usr/local/httpd/docs>, a
  216. component path of F</products/index.html> translates to the file
  217. F</usr/local/httpd/docs/products/index.html>.
  218.  
  219. One cannot call a component outside the component root. If Apache
  220. passes a file through Mason that is outside the component root (say,
  221. as the result of an Alias) you will get a 404 and a warning in the
  222. logs.
  223.  
  224. You may also specify multiple component roots in the spirit of Perl's
  225. C<@INC>. Each root is assigned a key that identifies the root
  226. mnemonically. For example, in F<httpd.conf>:
  227.  
  228.     PerlAddVar  MasonCompRoot  "private => /usr/home/joe/comps"
  229.     PerlAddVar  MasonCompRoot  "main => /usr/local/www/htdocs"
  230.  
  231. This specifies two component roots, a main component tree and a
  232. private tree which overrides certain components.  The order is
  233. respected ala C<@INC>, so I<private> is searched first and I<main>
  234. second.
  235.  
  236. The component root keys must be unique in a case-insensitive
  237. comparison.
  238.  
  239. =head2 Data Directory
  240.  
  241. The data directory (L<data_dir|HTML::Mason::Params/data_dir>) is a writable directory that Mason
  242. uses for various features and optimizations. By default, it is a
  243. directory called "mason" under your Apache server root.  Because Mason
  244. will not use a I<default> data directory under a top-level directory,
  245. you will need to change this on certain systems that assign a
  246. high-level server root such as F</usr> or F</etc>.
  247.  
  248. Mason will create the directory on startup, if necessary, and set its
  249. permissions according to the web server User/Group.
  250.  
  251. =head2 External Modules
  252.  
  253. Components will often need access to external Perl modules. There are
  254. several ways to load them.
  255.  
  256. =over
  257.  
  258. =item *
  259.  
  260. The httpd PerlModule directive:
  261.  
  262.     PerlModule CGI
  263.     PerlModule LWP
  264.  
  265. =item *
  266.  
  267. In the C<< <%once> >> section of the component(s) that use the module.
  268.  
  269.     <%once>
  270.     use CGI ':standard';
  271.     use LWP;
  272.     </%once>
  273.  
  274. =back
  275.  
  276. Each method has its own trade-offs:
  277.  
  278. The first method ensures that the module will be loaded by the Apache
  279. parent process at startup time, saving time and memory.  The second
  280. method, in contrast, will cause the modules to be loaded by each
  281. server child. On the other hand this could save memory if the
  282. component and module are rarely used. See the mod_perl guide's tuning
  283. section and Vivek Khera's mod_perl tuning guide for more details on
  284. this issue.
  285.  
  286. The second method uses the modules from inside the package used by
  287. components (C<HTML::Mason::Commands>), meaning that exported method
  288. names and other symbols will be usable from components.  The first
  289. method, in contrast, will import symbols into the C<main> package. The
  290. significance of this depends on whether the modules export symbols and
  291. whether you want to use them from components.
  292.  
  293. If you want to preload the modules in your F<httpd.conf> file, and
  294. still have them export symbols into the C<HTML::Mason::Commands>
  295. namespace, you can do this:
  296.  
  297.   <Perl>
  298.   { package HTML::Mason::Commands;
  299.     use CGI;
  300.     use LWP;
  301.   }
  302.   </Perl>
  303.  
  304. A Perl section will also work for including local library paths:
  305.  
  306.   <Perl>
  307.   use lib '/path/to/local/lib';
  308.   </Perl>
  309.  
  310. =head2 Allowing Directory Requests
  311.  
  312. By default Mason will decline requests for directories, leaving Apache
  313. to serve up a directory index or a FORBIDDEN as appropriate.
  314. Unfortunately this rule applies even if there is a dhandler in the
  315. directory: F</foo/bar/dhandler> does not get a chance to
  316. handle a request for F</foo/bar/>.
  317.  
  318. If you would like Mason to handle directory requests, set
  319. L<decline_dirs|HTML::Mason::Params/decline_dirs> to 0.  The dhandler that catches a directory request
  320. is responsible for setting a reasonable content type via
  321. C<< $r->content_type() >>
  322.  
  323. =head2 Configuring Virtual Sites
  324.  
  325. These examples extend the single site configurations given so far.
  326.  
  327. =head3 Multiple sites, one component root
  328.  
  329. If you want to share some components between your sites, arrange your
  330. F<httpd.conf> so that all DocumentRoots live under a single component
  331. space:
  332.  
  333.     # Web site #1
  334.     <VirtualHost www.site1.com>
  335.       DocumentRoot  /usr/local/www/htdocs/site1
  336.       <LocationMatch ...>
  337.         SetHandler   perl-script
  338.         PerlHandler  HTML::Mason::ApacheHandler
  339.       </LocationMatch>
  340.     </VirtualHost>
  341.  
  342.     # Web site #2
  343.     <VirtualHost www.site2.com>
  344.       DocumentRoot  /usr/local/www/htdocs/site2
  345.       <LocationMatch ...>
  346.         SetHandler   perl-script
  347.         PerlHandler  HTML::Mason::ApacheHandler
  348.       </LocationMatch>
  349.     </VirtualHost>
  350.  
  351.     # Mason configuration
  352.     PerlSetVar  MasonCompRoot  /usr/local/www/htdocs
  353.     PerlSetVar  MasonDataDir   /usr/local/mason
  354.     PerlModule  HTML::Mason::ApacheHandler
  355.  
  356. The directory structure for this scenario might look like:
  357.  
  358.     /usr/local/www/htdocs/  # component root
  359.         +- shared/          # shared components
  360.         +- site1/           # DocumentRoot for first site
  361.         +- site2/           # DocumentRoot for second site
  362.  
  363. Incoming URLs for each site can only request components in their
  364. respective DocumentRoots, while components internally can call other
  365. components anywhere in the component space. The F<shared/> directory
  366. is a private directory for use by components, inaccessible from the
  367. Web.
  368.  
  369. =head3 Multiple sites, multiple component roots
  370.  
  371. If your sites need to have completely distinct component hierarchies,
  372. e.g. if you are providing Mason ISP services for multiple users, then
  373. the component root must change depending on the site requested.
  374.  
  375.     <VirtualHost www.site1.com>
  376.       DocumentRoot  /usr/local/www/htdocs/site1
  377.  
  378.       # Mason configuration
  379.       PerlSetVar  MasonCompRoot    /usr/local/www/htdocs/site1
  380.       PerlSetVar  MasonDataDir     /usr/local/mason/site1
  381.  
  382.       <LocationMatch ...>
  383.         SetHandler   perl-script
  384.         PerlHandler  HTML::Mason::ApacheHandler
  385.       </LocationMatch>
  386.     </VirtualHost>
  387.  
  388.     # Web site #2
  389.     <VirtualHost www.site2.com>
  390.       DocumentRoot  /usr/local/www/htdocs/site2
  391.  
  392.       # Mason configuration
  393.       PerlSetVar  MasonCompRoot    /usr/local/www/htdocs/site2
  394.       PerlSetVar  MasonDataDir     /usr/local/mason/site2
  395.  
  396.       <LocationMatch ...>
  397.         SetHandler   perl-script
  398.         PerlHandler  HTML::Mason::ApacheHandler
  399.       </LocationMatch>
  400.     </VirtualHost>
  401.  
  402. =head1 ADVANCED CONFIGURATION
  403.  
  404. As mentioned previously, it is possible to write a custom mod_perl
  405. content handler that wraps around Mason and provides basically
  406. unlimited flexibility when handling requests.  In this section, we
  407. show some basic wrappers and re-implement some of the functionality
  408. previously discussed, such as declining image requests and protecting
  409. private components.
  410.  
  411. In addition, we discuss some of the possibilities that become
  412. available when you create a custom wrapper around Mason's request
  413. handling mechanism.  This wrapper generally consists of two parts.
  414. The initialization portion, run at server startup, will load any
  415. needed modules and create objects.  The other portion is the
  416. C<handler()> subroutine, which handles web page requests.
  417.  
  418. =head2 Writing a Wrapper
  419.  
  420. To create a wrapper, you simply need to define a C<handler()>
  421. subroutine in the package of your choice, and tell mod_perl to use it
  422. as a content handler.  The file that defines the C<handler()>
  423. subroutine can be a module, or you can simply load a simple file that
  424. contains this subroutine definition.  The latter solution was, for a
  425. long time, the I<only> way to configure Mason, and the file used was
  426. traditionally called F<handler.pl>.  This file was usually placed in
  427. the Apache configuration directory and was loaded like this:
  428.  
  429.   PerlRequire  handler.pl
  430.  
  431. The F<eg/> directory of the Mason distribution contains a couple
  432. sample F<handler.pl> scripts.  Let's assume that your script, like the
  433. example script, defines a handler in the package C<MyApp::Mason>.  In
  434. this case, your Apache configuration would look like this:
  435.  
  436.   PerlRequire  handler.pl
  437.  
  438.   <LocationMatch ...>
  439.     SetHandler   perl-script
  440.     PerlHandler  MyApp::Mason
  441.   </LocationMatch>
  442.  
  443. You may still see references to a F<handler.pl> file in the Mason
  444. users list archives, as well as the FAQ.  These references will
  445. generally be applicable to any custom code wrapping Mason.
  446.  
  447. =head2 Wrapping with a <Perl> block
  448.  
  449. You can also put your wrapper code in a C<< <Perl> >> block as part of
  450. your F<httpd.conf> file.  The result is no different than loading a
  451. file via the C<PerlRequire> directive.
  452.  
  453. =head2 Wrapping with a Module
  454.  
  455. Remember, this wrapper code doesn't I<have> to be in a file
  456. F<handler.pl>.  You could just as easily create an actual module
  457. called C<MyApp::Mason>, install it just like any other module, and
  458. load it with:
  459.  
  460.   PerlModule  MyApp::Mason
  461.  
  462. The advantage to this approach is that it uses well-known techniques
  463. for creating and installing modules, but it does require a bit more
  464. work than simply dropping a F<handler.pl> file into the Apache
  465. configuration directory.  But because the process is better defined,
  466. it may "feel" more solid to some folks than the F<handler.pl>
  467. approach.
  468.  
  469. =head2 The Wrapper Code
  470.  
  471. Regardless of how you load your wrapper code, it will always work the
  472. same way.  The C<handler()> subroutine should expect to receive the
  473. Apache request object representing the current request.  This request
  474. object is used by the ApacheHandler module to determine what component
  475. is being called.
  476.  
  477. Let's look at the guts of some wrapper code.  Here's a first version:
  478.  
  479.   package MyApp::Mason;
  480.  
  481.   use strict;
  482.   use HTML::Mason::ApacheHandler;
  483.  
  484.   my $ah =
  485.       HTML::Mason::ApacheHandler->new
  486.           ( comp_root => '/path/to/comp/root',
  487.             data_dir  => '/path/to/data/dir' );
  488.  
  489.   sub handler {
  490.       my ($r) = @_;
  491.  
  492.       return $ah->handle_request($r);
  493.   }
  494.  
  495. This wrapper is fully functional, but it doesn't actually do anything
  496. you couldn't do more easily by configuring Mason via the F<httpd.conf>
  497. file.  However, it does serve as a good skeleton to which additional
  498. functionality can easily be added.
  499.  
  500. =head2 External Modules Revisited
  501.  
  502. Since you are loading an arbitrary piece of code to define your
  503. wrapper, you can easily load other modules needed for your application
  504. at the same time.  For example, you might simple add these lines to
  505. the wrapper code above:
  506.  
  507.   {
  508.       package HTML::Mason::Commands;
  509.  
  510.       use MIME::Base64;
  511.   }
  512.  
  513. Explicitly setting the package to C<HTML::Mason::Commands> makes sure
  514. that any symbols that the loaded modules export (constants,
  515. subroutines, etc.) get exported into the namespace under which
  516. components run.  Of course, if you've changed the component namespace,
  517. make sure to change the package name here as well.
  518.  
  519. Alternatively, you might consider creating a separate piece of code to
  520. load the modules you need.  For example, you might create a module
  521. called C<MyApp::MasonInit>:
  522.  
  523.   {
  524.       package HTML::Mason::Commands;
  525.  
  526.       use Apache::Constants qw(:common);
  527.       use Apache::URI;
  528.       use File::Temp;
  529.   }
  530.  
  531.   1;
  532.  
  533. This can be loaded via a C<PerlModule> directive in the F<httpd.conf>
  534. file, or in the wrapper code itself via C<use>.
  535.  
  536. =head3 Example: Controlling access with component attributes
  537.  
  538. An example of something you can only do with wrapper code is deciding
  539. at run-time whether a component can be accessed at the top-level based
  540. on a complex property of the component.  For example, here's a piece
  541. of code that uses the current user and a component's C<access_level>
  542. attribute to control access:
  543.  
  544.   sub handler {
  545.       my ($r) = @_;
  546.  
  547.       my $req = $ah->prepare_request($r);
  548.  
  549.       my $comp = $req->request_comp;
  550.  
  551.       # this is done via magic hand-waving ...
  552.       my $user = get_user_from_cookie();
  553.  
  554.       # remember, attributes are inherited so this could come from a
  555.       # component higher up the inheritance chain
  556.       my $required_access = $comp->attr('access_level');
  557.  
  558.       return NOT_FOUND
  559.           if $user->access_level < $required_access;
  560.  
  561.       return $req->exec;
  562.   }
  563.  
  564. =head2 Wrappers with Virtual Hosts
  565.  
  566. If you had several virtual hosts, each of which had a separate
  567. component root, you'd need to create a separate ApacheHandler object
  568. for each host, one for each host.  Here's some sample code for that:
  569.  
  570.     my %ah;
  571.     foreach my $site ( qw( site1 site2 site3 ) ) {
  572.         $ah{$site} =
  573.             HTML::Mason::ApacheHandler->new
  574.                 ( comp_root => "/usr/local/www/$site",
  575.                   data_dir => "/usr/local/mason/$site" );
  576.     }
  577.  
  578.     sub handler {
  579.         my ($r) = @_;
  580.  
  581.         my $site = $r->dir_config('SiteName');
  582.  
  583.         return DECLINED unless exists $ah{$site};
  584.  
  585.         return $ah{$site}->handle_request($r);
  586.     }
  587.  
  588. This code assumes that you set the C<SiteName> variable via a
  589. C<PerlSetVar> directive in each C<VirtualHost> block, like this:
  590.  
  591.   <VirtualHost site1.example.com>
  592.     PerlSetVar  SiteName  site1
  593.  
  594.     <LocationMatch ...>
  595.       SetHandler   perl-script
  596.       PerlHandler  MyApp::Mason
  597.     </LocationMatch>
  598.   </VirtualHost>
  599.  
  600. =head3 Creating apachehandler objects on the fly
  601.  
  602. You might also consider creating ApacheHandler objects on the fly,
  603. like this:
  604.  
  605.     my %ah;
  606.     sub handler {
  607.         my ($r) = @_;
  608.         my $site = $r->dir_config('SiteName');
  609.  
  610.         return DECLINED unless $site;
  611.  
  612.         unless exists($ah{$site}) {
  613.             $ah{$site} = HTML::Mason::ApacheHandler->new( ... );
  614.         }
  615.  
  616.         $ah{$site}->handle_request($r);
  617.     }
  618.  
  619. This is more flexible but you lose the memory savings of creating all
  620. your objects during server startup.
  621.  
  622. =head3 Other uses for a wrapper
  623.  
  624. If you have some code which must I<always> run after a request, then
  625. the only way to guarantee that this happens is to wrap the C<< $ah->handle_request() >>
  626. call in an C<eval {}> block, and then run the
  627. needed code after the request returns.  You can then handle errors
  628. however you like.
  629.  
  630. =head2 Mixing httpd.conf Configuration with a Wrapper
  631.  
  632. You can take advantage of Mason's F<httpd.conf> configuration system
  633. while at the same time providing your own wrapper code.  The key to
  634. doing this is I<not> creating your own ApacheHandler object.  Instead,
  635. you call the C<< HTML::Mason::ApacheHandler->handler() >> class method
  636. from your C<handler()> subroutine.  Here's a complete wrapper that
  637. does this:
  638.  
  639.   package MyApp::Mason;
  640.  
  641.   use strict;
  642.   use HTML::Mason::ApacheHandler;
  643.  
  644.   sub handler {
  645.       my ($r) = @_;
  646.  
  647.       return HTML::Mason::ApacheHandler->handler($r);
  648.   }
  649.  
  650. The C<< HTML::Mason::ApacheHandler->handler >> method will create an
  651. ApacheHandler object based on the configuration directives it finds in
  652. your F<httpd.conf> file.  Obviously, this wrapper is again a skeleton,
  653. but you could mix and match this wrapper code with any of the code
  654. shown above.
  655.  
  656. Alternately you could subclass the C<HTML::Mason::ApacheHandler>
  657. class, and override the C<handler()> method it provides.  See the
  658. L<Subclassing|HTML::Mason::Subclassing> documentation for more
  659. details.  Of course, you could even create a subclass I<and> write a
  660. wrapper that called it.
  661.  
  662. =head1 DEVELOPMENT
  663.  
  664. This section describes how to set up common developer features.
  665.  
  666. =head2 Global Variables
  667.  
  668. Global variables can make programs harder to read, maintain, and
  669. debug, and this is no less true for Mason components.  Due to the
  670. persistent mod_perl environment, globals require extra initialization
  671. and cleanup care.
  672.  
  673. That said, there are times when it is very useful to make a value
  674. available to all Mason components: a DBI database handle, a hash of
  675. user session information, the server root for forming absolute URLs.
  676.  
  677. Because Mason by default parses components in C<strict> mode, you'll
  678. need to declare a global if you don't want to access it with an
  679. explicit package name. The easiest way to declare a global is with
  680. the L<allow_globals|HTML::Mason::Params/allow_globals> parameter.
  681.  
  682. Since all components run in the same package, you'll be able to set
  683. the global in one component and access it in all the others.
  684.  
  685. Autohandlers are common places to assign values to globals.  Use the
  686. C<< <%once> >> section if the global only needs to be
  687. initialized at load time, or the C<< <%init> >> section if it
  688. needs to be initialized every request.
  689.  
  690. =head2 Sessions
  691.  
  692. Mason does not have a built-in session mechanism, but you can use the
  693. C<MasonX::Request::WithApacheSession> module, available from CPAN, to
  694. add a session to every request.  It can also automatically set and
  695. read cookies containing the session id.
  696.  
  697. =head2 Data Caching
  698.  
  699. Data caching is implemented with DeWitt Clinton's C<Cache::Cache>
  700. module.  For full understanding of this section you should read the
  701. documentation for C<Cache::Cache> as well as for relevant subclasses
  702. (e.g. C<Cache::FileCache>).
  703.  
  704. =over 4
  705.  
  706. =item Cache files
  707.  
  708. By default, C<Cache::FileCache> is the subclass used for data caching,
  709. although this may be overriden by the developer. C<Cache::FileCache>
  710. creates a separate subdirectory for every component that uses caching,
  711. and one file some number of levels underneath that subdirectory for
  712. each cached item.  The root of the cache tree is
  713. L<data_dir|HTML::Mason::Params/data_dir>/C<cache>. The name of the cache subdirectory for a component
  714. is determined by the function C<HTML::Mason::Utils::data_cache_namespace>.
  715.  
  716. =item Default constructor options
  717.  
  718. Ordinarily, when C<< $m->cache >> is called, Mason passes to the cache
  719. constructor the C<namespace>, and C<cache_root> options, along with
  720. any other options given in the C<< $m->cache >> method.
  721.  
  722. You may specify other default constructor options with the
  723. L<data_cache_defaults|HTML::Mason::Params/data_cache_defaults> parameter. For example,
  724.  
  725.     PerlSetVar  MasonDataCacheDefaults  "cache_class => SizeAwareFileCache"
  726.     PerlAddVar  MasonDataCacheDefaults  "cache_depth => 2"
  727.     PerlAddVar  MasonDataCacheDefaults  "default_expires_in => 1 hour"
  728.  
  729. Any options passed to individual C<< $m->cache >> calls override these
  730. defaults.
  731.  
  732. =item Disabling data caching
  733.  
  734. If for some reason you want to disable data caching entirely, set the
  735. default C<cache_class> to "NullCache".  This subclass faithfully
  736. implements the cache API but never stores data.
  737.  
  738. =back
  739.  
  740. =head1 PERFORMANCE
  741.  
  742. This section explains Mason's various performance enhancements and how
  743. to administer them.
  744.  
  745. =head2 Code Cache
  746.  
  747. When Mason loads a component, it places it in a memory cache.
  748.  
  749. The maximum size of the cache is specified with the
  750. L<code_cache_max_size|HTML::Mason::Params/code_cache_max_size> parameter.  When the cache fills up, Mason
  751. frees up space by discarding a number of components. The discard
  752. algorithm is least frequently used (LFU), with a periodic decay to
  753. gradually eliminate old frequency information. In a nutshell, the
  754. components called most often in recent history should remain in the
  755. cache.  Very large components (over 20% of the maximum cache size)
  756. never get cached, on the theory that they would force out too many
  757. other components.
  758.  
  759. Note that the "size" of a component in memory cannot literally be
  760. measured.  It is estimated by the length of the source text plus some
  761. overhead.  Your process growth will not match the code cache
  762. size exactly.
  763.  
  764. You can prepopulate the cache with components that you know will be
  765. accessed often; see L<Preloading Components|"Preloading Components">.
  766. Note that preloaded components possess no special status in the cache
  767. and can be discarded like any others.
  768.  
  769. Naturally, a cache entry is invalidated if the corresponding component
  770. source file changes.
  771.  
  772. To turn off code caching completely, set L<code_cache_max_size|HTML::Mason::Params/code_cache_max_size> to 0.
  773.  
  774. =head2 Object Files
  775.  
  776. The in-memory code cache is only useful on a per-process basis.  Each
  777. process must build and maintain its own cache. Shared memory caches
  778. are conceivable in the future, but even those will not survive between
  779. web server restarts.
  780.  
  781. As a secondary, longer-term cache mechanism, Mason stores a compiled
  782. form of each component in an object file under L<data_dir|HTML::Mason::Params/data_dir>/obj. Any
  783. server process can eval the object file and save time on parsing the
  784. component source file.  The object file is recreated whenever the
  785. source file changes.
  786.  
  787. Besides improving performance, object files can be useful for
  788. debugging.  If you feel the need to see what your source has been
  789. translated into, you can peek inside an object file to see exactly how
  790. Mason converted a given component to a Perl object. This was crucial
  791. for pre-1.10 Mason, in which error line numbers were based on the
  792. object file rather than the source file.
  793.  
  794. If for some reason you don't want Mason to create object files, set
  795. L<use_object_files|HTML::Mason::Params/use_object_files> to 0.
  796.  
  797. =head2 Write a handler subroutine
  798.  
  799. Writing your own C<handler()> subroutine which uses an ApacheHandler
  800. object (or objects) created during server startup is slightly faster
  801. (around 5% or so) than configuring mason via your F<httpd.conf> file
  802. and letting Mason create its own ApacheHandler objects internally.
  803.  
  804. =head2 Static Source Mode
  805.  
  806. As described above, Mason checks the timestamp of a component source
  807. file every time that component is called. This can add up to a lot
  808. of file stats.
  809.  
  810. If you have a live site with infrequent and well-controlled updates,
  811. you may choose to use L<static_source|HTML::Mason::Params/static_source> mode. In this mode Mason will
  812. not check source timestamps when it uses an in-memory cache or object
  813. file.  The disadvantage is that you must remove object files and
  814. restart the server whenever you change component source; however this
  815. process can be easily automated.
  816.  
  817. =head2 Preloading Components
  818.  
  819. You can tell Mason to preload a set of components in the parent
  820. process, rather than loading them on demand, using the L<preloads|HTML::Mason::Params/preloads>
  821. parameter.  Each child server will start with those components loaded
  822. in the memory cache. The trade-offs are:
  823.  
  824. =over
  825.  
  826. =item time
  827.  
  828. a small one-time startup cost, but children save time by not
  829. having to load the components
  830.  
  831. =item memory
  832.  
  833. a fatter initial server, but the memory for preloaded components are
  834. shared by all children.  This is similar to the advantage of using
  835. modules only in the parent process.
  836.  
  837. =back
  838.  
  839. Try to preload components that are used frequently and do not change
  840. often.  (If a preloaded component changes, all the children will have
  841. to reload it from scratch.)
  842.  
  843. =head1 ERROR REPORTING AND EXCEPTIONS
  844.  
  845. When an error occurs, Mason can respond by:
  846.  
  847. =over
  848.  
  849. =item *
  850.  
  851. showing a detailed error message in the browser in HTML.
  852.  
  853. =item *
  854.  
  855. die'ing, which sends a 500 status to the browser and lets the error
  856. message go to the error logs.
  857.  
  858. =back
  859.  
  860. The first behavior is ideal for development, where you want immediate
  861. feedback on the error.  The second behavior is usually desired for
  862. production so that users are not exposed to messy error messages.  You
  863. choose the behavior by setting L<error_mode|HTML::Mason::Params/error_mode> to "output" or "fatal"
  864. respectively.
  865.  
  866. Error formatting is controlled by the L<error_format|HTML::Mason::Params/error_format> parameter.  When
  867. showing errors in the browser, Mason defaults to the "html" format.
  868. When the L<error_mode|HTML::Mason::Params/error_mode> is set to "fatal", the default format is
  869. "line", which puts the entire error message on one line in a format
  870. suitable for web server error logs.  Mason also offers other formats,
  871. which are covered in the L<Request class|HTML::Mason::Request>
  872. documentation.
  873.  
  874. Finally, you can use Apache's C<ErrorDocument> directive to specify a
  875. custom error handler for 500 errors.  In this case, you'd set the
  876. L<error_mode|HTML::Mason::Params/error_mode> to "fatal".  The URL specified by the C<ErrorDocument>
  877. directive could point to a Mason component.
  878.  
  879. =head2 Exceptions Under the Hood
  880.  
  881. The way that Mason really reports errors is through the use of
  882. exception objects, which are implemented with the C<Exception::Class>
  883. module from CPAN, and some custom code in the
  884. L<HTML::Mason::Exceptions|HTML::Mason::Exceptions> module.
  885.  
  886. If, during the execution of a component, execution stops because some
  887. code calls C<die()>, then Mason will catch this exception.  If the
  888. exception being thrown is just a string, then it will be converted to
  889. an C<HTML::Mason::Exception> object.  If the exception being thrown is
  890. an object with a C<rethrow()> method, then this method will be called.
  891. Otherwise, Mason simply leaves the exception untouched and calls
  892. C<die()> again.
  893.  
  894. =head3 Calling a Component to Handle Errors
  895.  
  896. Returning to the topic of wrapper code that we covered earlier, what
  897. if you wanted to handle all request errors by calling an error
  898. handling component?  There is no way to do this without wrapper code.
  899. Here's an example C<handler()> subroutine that does this:
  900.  
  901.     sub handler {
  902.         my ($r) = @_;
  903.  
  904.         my $return = eval { $ah->handle_request($r) };
  905.  
  906.         if ( my $err = $@ )
  907.         {
  908.             $r->pnotes( error => $err );
  909.             $r->filename( $r->document_root . '/error/500.html' );
  910.  
  911.             return $ah->handle_request($r);
  912.         }
  913.  
  914.         return $return;
  915.     }
  916.  
  917. First, we wrap our call to C<< $ah->handle_request() >> in an
  918. C<eval{}> block.  If an error occurs, we store it in the request
  919. object using the C<< $r->pnotes() >> method.  Then we change the
  920. filename property of the Apache request object to point to our
  921. error-handling component and call the C<< $ah->handle_request() >>
  922. method again, passing it the altered request object.  We could have
  923. put the exception in C<< $r->args >>, but we want to leave this
  924. untouched so that the error-handling component can see the original
  925. arguments.
  926.  
  927. Here's what that component error-handling component might look like:
  928.  
  929.  <html>
  930.  <head>
  931.  <title>Error</title>
  932.  </head>
  933.  
  934.  <body>
  935.  
  936.  <p>
  937.  Looks like our application broke.  Whatever you did, don't do it again!
  938.  </p>
  939.  
  940.  <p>
  941.  If you have further questions, please feel free to contact us at <a
  942.  href="mailto:support@example.com">support@example.com</a>.
  943.  </p>
  944.  
  945.  <p><a href="/">Click here</a> to continue.</p>
  946.  
  947.  </body>
  948.  </html>
  949.  
  950.  <%init>
  951.   my $error = $r->pnotes('error');
  952.  
  953.   my $error_text = "Page is " . $r->parsed_uri->unparse . "\n\n";
  954.  
  955.   $error_text .= UNIVERSAL::can( $error, 'as_text' ) ? $error->as_text : $error;
  956.  
  957.   $r->log_error($error_text);
  958.  
  959.   my $mail =
  960.       MIME::Lite->new
  961.           ( From => 'error-handler@example.com',
  962.             To   => 'rt@example.com',
  963.             Subject => 'Application error',
  964.             Data => $error_text,
  965.           );
  966.  
  967.   $r->register_cleanup( sub { $mail->send } );
  968.  </%init>
  969.  
  970.  <%flags>
  971.   inherit => undef
  972.  </%flags>
  973.  
  974. This component does several things.  First of all, it logs the
  975. complete error to the Apache error logs, along with the complete URL,
  976. including query string, that was requested.  The C<< $r->parsed_uri() >>
  977. method that we use above is only available if the C<Apache::URI>
  978. module has been loaded.
  979.  
  980. The component also sends an email containing the error, in this case
  981. to an RT installation, so that the error is logged in a bug tracking
  982. system.  Finally, it displays a less technical error message to the
  983. user.
  984.  
  985. For this to work properly, you must set L<error_mode|HTML::Mason::Params/error_mode> to "fatal", so
  986. that Mason doesn't just display its own HTML error page.
  987.  
  988. =head1 RUNNING OUTSIDE OF MOD_PERL
  989.  
  990. Although Mason is most commonly used in conjunction with mod_perl, the
  991. APIs are flexible enough to use in any environment. Below we describe
  992. the two most common alternative environments, CGI and standalone
  993. scripts.
  994.  
  995. =head2 Using Mason from a CGI Script
  996.  
  997. The easiest way to use Mason via a CGI script is with the L<CGIHandler
  998. module|HTML::Mason::CGIHandler> module.
  999.  
  1000. Here is a skeleton CGI script that calls a component and sends the
  1001. output to the browser.
  1002.  
  1003.     #!/usr/bin/perl
  1004.     use HTML::Mason::CGIHandler;
  1005.  
  1006.     my $h = HTML::Mason::CGIHandler->new
  1007.      (
  1008.       data_dir  => '/home/jethro/code/mason_data',
  1009.      );
  1010.  
  1011.     $h->handle_request;
  1012.  
  1013. The relevant portions of the F<httpd.conf> file look like:
  1014.  
  1015.     DocumentRoot /path/to/comp/root
  1016.     ScriptAlias /cgi-bin/ /path/to/cgi-bin/
  1017.  
  1018.     Action html-mason /cgi-bin/mason_handler.cgi
  1019.     <LocationMatch "\.html$">
  1020.       SetHandler html-mason
  1021.     </LocationMatch>
  1022.  
  1023. This simply causes Apache to call the mason_handler.cgi script every
  1024. time a URL ending in ".html" under the component root is requested.
  1025. This script uses the L<CGIHandler class|HTML::Mason::CGIHandler> to do
  1026. most of the heavy lifting.  See that class's documentation for more
  1027. details.
  1028.  
  1029. =head2 Using Mason from a Standalone Script
  1030.  
  1031. Mason can be used as a pure text templating solution -- like
  1032. Text::Template and its brethren, but with more power (and of course
  1033. more complexity).
  1034.  
  1035. Here is a bare-bones script that calls a component file and sends
  1036. the result to standard output:
  1037.  
  1038.     #!/usr/bin/perl
  1039.     use HTML::Mason;
  1040.     use strict;
  1041.  
  1042.     my $interp = HTML::Mason::Interp->new ();
  1043.     $interp->exec(<path-to-file-from-cwd>, <args>...);
  1044.  
  1045. Because no component root was specified, the root is set to your
  1046. current working directory. (The path supplied to C<exec> still needs
  1047. to start with a slash, even though it is effectively a relative path
  1048. from the current directory.) If you have a well defined and contained
  1049. component tree, you'll probably want to specify a component root.
  1050.  
  1051. Because no data directory was specified, object files will not be
  1052. created and data caching will not work in the default manner. If
  1053. performance is an issue, you will want to specify a data directory.
  1054.  
  1055. Here's a slightly fuller script that specifies a component root and
  1056. data directory, and captures the result in a variable rather than
  1057. sending to standard output:
  1058.  
  1059.     #!/usr/bin/perl
  1060.     use HTML::Mason;
  1061.     use strict;
  1062.  
  1063.     my $outbuf;
  1064.     my $interp = HTML::Mason::Interp->new
  1065.         (comp_root  => '/path/to/comp_root',
  1066.          data_dir   => '/path/to/data_dir',
  1067.          out_method => \$outbuf
  1068.         );
  1069.     $interp->exec(<component-path>, <args>...);
  1070.  
  1071.     # Do something with $outbuf
  1072.  
  1073. =head1 AUTHORS
  1074.  
  1075. Jonathan Swartz <swartz@pobox.com>, Dave Rolsky <autarch@urth.org>, Ken Williams <ken@mathforum.org>
  1076.  
  1077. =head1 SEE ALSO
  1078.  
  1079. L<HTML::Mason|HTML::Mason>,
  1080. L<HTML::Mason::Interp|HTML::Mason::Interp>,
  1081. L<HTML::Mason::ApacheHandler|HTML::Mason::ApacheHandler>,
  1082. L<HTML::Mason::Lexer|HTML::Mason::Lexer>,
  1083. L<HTML::Mason::Compiler|HTML::Mason::Compiler>
  1084.  
  1085. =cut
  1086.