1HTML::Mason::Admin(3) User Contributed Perl DocumentationHTML::Mason::Admin(3)
2
3
4

NAME

6       HTML::Mason::Admin - Mason Administrator's Manual
7

DESCRIPTION

9       This manual is written for the sysadmin/webmaster in charge of
10       installing, configuring, or tuning a Mason system.  The bulk of the
11       documentation assumes that you are using mod_perl.  See RUNNING OUTSIDE
12       OF MOD_PERL for more details. For more details on mod_perl, visit the
13       mod_perl website at http://perl.apache.org/.
14

SITE CONFIGURATION METHODS

16       Mason includes a module specifically designed to integrate Mason and
17       mod_perl (1 and 2), "HTML::Mason::ApacheHandler".  By telling mod_perl
18       to hand content requests to this module, you can use Mason to generate
19       web pages.  There are two ways to configure Mason under mod_perl.
20
21       * Basic
22           Mason provides reasonable default behavior under mod_perl, so using
23           Mason can be as simple as adding two directives to your Apache con‐
24           figuration file.  Throughout this document, we will assume that
25           your Apache configuration file is called httpd.conf.  By adding
26           more configuration parameters to this file you can implement more
27           complex behaviors.
28
29       * Advanced
30           If the basic method does not provide enough flexibility for you,
31           you can wrap Mason in a custom mod_perl handler.  The wrapper code
32           you write can create its own Mason objects, or it can take advan‐
33           tage of httpd.conf configuration parameters and let Mason create
34           the objects it needs by itself.
35
36       We recommend that you start with the basic method and work your way
37       forward as the need for flexibility arises.
38
39       Mason is very flexible, and you can replace parts of it by creating
40       your own classes.  This documentation assumes that you are simply using
41       the classes provided in the Mason distribution.  Subclassing is covered
42       in the Subclassing document.  The two topics are orthogonal, as you can
43       mix the configuration techniques discussed here with your own custom
44       subclasses.
45

BASIC CONFIGURATION VIA httpd.conf DIRECTIVES

47       The absolutely most minimal configuration looks like this:
48
49           PerlModule HTML::Mason::ApacheHandler
50
51           <Location />
52             SetHandler   perl-script
53             PerlHandler  HTML::Mason::ApacheHandler
54           </Location>
55
56       This configuration tells Apache to serve all URLs through Mason (see
57       the next section for a more realistic strategy).  We use the PerlModule
58       line to tell mod_perl to load Mason once at startup time, saving time
59       and memory.  This example does not set any Mason configuration parame‐
60       ters, so Mason uses its default values.
61
62       If this is your first time installing and using Mason, we recommend
63       that you use the above configuration in a test webserver to start with.
64       This will let you play with Mason under mod_perl with a minimum of
65       fuss.  Once you've gotten this working, then come back and read the
66       rest of the document for further possibilities.
67
68       Controlling Access via Filename Extension
69
70       As it turns out, serving every URL through Mason is a bad idea for two
71       reasons:
72
73       1.  Mason should be prevented from handling images, tarballs, and other
74           binary files. Not only will performance suffer, but binary files
75           may inadvertently contain a Mason character sequence such as "<%".
76           These files should be instead served by Apache's default content
77           handler.
78
79       2.  Mason should be prevented from serving private (non-top-level)
80           Mason components to users. For example, if you used a utility com‐
81           ponent for performing arbitrary sql queries, you wouldn't want
82           external users to be able to access it via a URL. Requests for pri‐
83           vate components should simply result in a 404 NOT_FOUND.
84
85       The easiest way to distinguish between different types of files is with
86       filename extensions. While many naming schemes are possible, we suggest
87       using "normal" extensions for top-level components and adding an "m"
88       prefix for private components. For example,
89
90                                    Top-level       Private
91
92          Component outputs HTML    .html           .mhtml
93          Component outputs text    .txt            .mtxt
94          Component executes Perl   .pl             .mpl
95
96       This scheme minimizes the chance of confusing browsers about content
97       type, scales well for new classes of content (e.g. .js/.mjs for
98       javascript), and makes transparent the fact that you are using Mason
99       versus some other package.
100
101       Here is a configuration that enforces this naming scheme:
102
103           PerlModule HTML::Mason::ApacheHandler
104
105           <LocationMatch "(\.html⎪\.txt⎪\.pl)$">
106             SetHandler perl-script
107             PerlHandler HTML::Mason::ApacheHandler
108           </LocationMatch>
109
110           <LocationMatch "(\.m(html⎪txt⎪pl)⎪dhandler⎪autohandler)$">
111             SetHandler perl-script
112             PerlInitHandler Apache::Constants::NOT_FOUND
113           </LocationMatch>
114
115       The first block causes URLs ending in .html, .txt, or .pl to be served
116       through Mason. The second block causes requests to private components
117       to return 404 NOT_FOUND, preventing unscrupulous users from even know‐
118       ing which private components exist. Any other file extensions (e.g.
119       .gif, .tgz) will be served by Apache's default content handler.
120
121       You might prefer "FilesMatch" to "LocationMatch". However, be aware
122       that "LocationMatch" will work best in conjunction with Mason's dhan‐
123       dlers.
124
125       Configuration Parameters
126
127       Mason allows you to flexibly configure its behavior via httpd.conf con‐
128       figuration parameters.
129
130       These configuration parameters are set via mod_perl's "PerlSetVar" and
131       "PerlAddVar" directives.  Though these parameters are all strings in
132       your httpd.conf file, Mason treats different directives as containing
133       different types of values:
134
135       * string
136           The variable's value is simply taken literally and used.  The
137           string should be surrounded by quotes if the it contains white‐
138           space.  The quotes will be automatically removed by Apache before
139           Mason sees the variable.
140
141       * boolean
142           The variable's value is used as a boolean, and is subject to Perl's
143           rules on truth/falseness.  It is recommended that you use 0 (false)
144           or 1 (true) for these arguments.
145
146       * code
147           The string is treated as a piece of code and "eval"'ed.  This is
148           used for parameters that expect subroutine references.  For exam‐
149           ple, an anonymous subroutine might look like:
150
151            PerlSetVar  MasonOutMode  "sub { ... }"
152
153           A named subroutine reference would look like this:
154
155            PerlSetVar  MasonOutMode  "\&Some::Module::handle_output"
156
157       * list
158           To set a list parameter, use "PerlAddVar" for the values, like
159           this:
160
161            PerlAddVar  MasonPreloads  /foo/bar/baz.comp
162            PerlAddVar  MasonPreloads  /foo/bar/quux.comp
163
164       * hash_list
165           Just like a list parameter, use "PerlAddVar" for the values.  How‐
166           ever, in the case of a hash_list, each element should be a
167           key/value pair separated by "=>":
168
169            PerlAddVar  MasonDataCacheDefaults  "cache_class => MemoryCache"
170            PerlAddVar  MasonDataCacheDefaults  "namespace => foo"
171
172           Take note that the right hand side of the each pair should not be
173           quoted.
174
175       See HTML::Mason::Params for a full list of parameters, and their asso‐
176       ciated types.
177

GENERAL SERVER CONFIGURATION

179       Component Root
180
181       The component root (comp_root) marks the top of your component hierar‐
182       chy.  When running Mason with the ApacheHandler or CGIHandler modules,
183       this defaults to your document root.
184
185       The component root defines how component paths are translated into real
186       file paths. If your component root is /usr/local/httpd/docs, a compo‐
187       nent path of /products/index.html translates to the file
188       /usr/local/httpd/docs/products/index.html.
189
190       One cannot call a component outside the component root. If Apache
191       passes a file through Mason that is outside the component root (say, as
192       the result of an Alias) you will get a 404 and a warning in the logs.
193
194       You may also specify multiple component roots in the spirit of Perl's
195       @INC. Each root is assigned a key that identifies the root mnemoni‐
196       cally. For example, in httpd.conf:
197
198           PerlAddVar  MasonCompRoot  "private => /usr/home/joe/comps"
199           PerlAddVar  MasonCompRoot  "main => /usr/local/www/htdocs"
200
201       This specifies two component roots, a main component tree and a private
202       tree which overrides certain components.  The order is respected ala
203       @INC, so private is searched first and main second.
204
205       The component root keys must be unique in a case-insensitive compari‐
206       son. The keys are used in several ways. They help to distinguish compo‐
207       nent caches and object files between different component roots, and
208       they appear in the "title()" of a component.
209
210       Data Directory
211
212       The data directory (data_dir) is a writable directory that Mason uses
213       for various features and optimizations. By default, it is a directory
214       called "mason" under your Apache server root.  Because Mason will not
215       use a default data directory under a top-level directory, you will need
216       to change this on certain systems that assign a high-level server root
217       such as /usr or /etc.
218
219       Mason will create the directory on startup, if necessary, and set its
220       permissions according to the web server User/Group.
221
222       External Modules
223
224       Components will often need access to external Perl modules. There are
225       several ways to load them.
226
227       ·   The httpd PerlModule directive:
228
229               PerlModule CGI
230               PerlModule LWP
231
232       ·   In the "<%once>" section of the component(s) that use the module.
233
234               <%once>
235               use CGI ':standard';
236               use LWP;
237               </%once>
238
239       Each method has its own trade-offs:
240
241       The first method ensures that the module will be loaded by the Apache
242       parent process at startup time, saving time and memory.  The second
243       method, in contrast, will cause the modules to be loaded by each server
244       child. On the other hand this could save memory if the component and
245       module are rarely used. See the mod_perl guide's tuning section and
246       Vivek Khera's mod_perl tuning guide for more details on this issue.
247
248       The second method uses the modules from inside the package used by com‐
249       ponents ("HTML::Mason::Commands"), meaning that exported method names
250       and other symbols will be usable from components.  The first method, in
251       contrast, will import symbols into the "main" package. The significance
252       of this depends on whether the modules export symbols and whether you
253       want to use them from components.
254
255       If you want to preload the modules in your httpd.conf file, and still
256       have them export symbols into the "HTML::Mason::Commands" namespace,
257       you can do this:
258
259         <Perl>
260         { package HTML::Mason::Commands;
261           use CGI;
262           use LWP;
263         }
264         </Perl>
265
266       A Perl section will also work for including local library paths:
267
268         <Perl>
269         use lib '/path/to/local/lib';
270         </Perl>
271
272       Allowing Directory Requests
273
274       By default Mason will decline requests for directories, leaving Apache
275       to serve up a directory index or a FORBIDDEN as appropriate.  Unfortu‐
276       nately this rule applies even if there is a dhandler in the directory:
277       /foo/bar/dhandler does not get a chance to handle a request for
278       /foo/bar/.
279
280       If you would like Mason to handle directory requests, set decline_dirs
281       to 0.  The dhandler that catches a directory request is responsible for
282       setting a reasonable content type via "$r->content_type()"
283
284       Configuring Virtual Sites
285
286       These examples extend the single site configurations given so far.
287
288       Multiple sites, one component root
289
290       If you want to share some components between your sites, arrange your
291       httpd.conf so that all DocumentRoots live under a single component
292       space:
293
294           # Web site #1
295           <VirtualHost www.site1.com>
296             DocumentRoot  /usr/local/www/htdocs/site1
297             <LocationMatch ...>
298               SetHandler   perl-script
299               PerlHandler  HTML::Mason::ApacheHandler
300             </LocationMatch>
301           </VirtualHost>
302
303           # Web site #2
304           <VirtualHost www.site2.com>
305             DocumentRoot  /usr/local/www/htdocs/site2
306             <LocationMatch ...>
307               SetHandler   perl-script
308               PerlHandler  HTML::Mason::ApacheHandler
309             </LocationMatch>
310           </VirtualHost>
311
312           # Mason configuration
313           PerlSetVar  MasonCompRoot  /usr/local/www/htdocs
314           PerlSetVar  MasonDataDir   /usr/local/mason
315           PerlModule  HTML::Mason::ApacheHandler
316
317       The directory structure for this scenario might look like:
318
319           /usr/local/www/htdocs/  # component root
320               +- shared/          # shared components
321               +- site1/           # DocumentRoot for first site
322               +- site2/           # DocumentRoot for second site
323
324       Incoming URLs for each site can only request components in their
325       respective DocumentRoots, while components internally can call other
326       components anywhere in the component space. The shared/ directory is a
327       private directory for use by components, inaccessible from the Web.
328
329       Multiple sites, multiple component roots
330
331       If your sites need to have completely distinct component hierarchies,
332       e.g. if you are providing Mason ISP services for multiple users, then
333       the component root must change depending on the site requested.
334
335           <VirtualHost www.site1.com>
336             DocumentRoot  /usr/local/www/htdocs/site1
337
338             # Mason configuration
339             PerlSetVar  MasonCompRoot    /usr/local/www/htdocs/site1
340             PerlSetVar  MasonDataDir     /usr/local/mason/site1
341
342             <LocationMatch ...>
343               SetHandler   perl-script
344               PerlHandler  HTML::Mason::ApacheHandler
345             </LocationMatch>
346           </VirtualHost>
347
348           # Web site #2
349           <VirtualHost www.site2.com>
350             DocumentRoot  /usr/local/www/htdocs/site2
351
352             # Mason configuration
353             PerlSetVar  MasonCompRoot    /usr/local/www/htdocs/site2
354             PerlSetVar  MasonDataDir     /usr/local/mason/site2
355
356             <LocationMatch ...>
357               SetHandler   perl-script
358               PerlHandler  HTML::Mason::ApacheHandler
359             </LocationMatch>
360           </VirtualHost>
361

ADVANCED CONFIGURATION

363       As mentioned previously, it is possible to write a custom mod_perl con‐
364       tent handler that wraps around Mason and provides basically unlimited
365       flexibility when handling requests.  In this section, we show some
366       basic wrappers and re-implement some of the functionality previously
367       discussed, such as declining image requests and protecting private com‐
368       ponents.
369
370       In addition, we discuss some of the possibilities that become available
371       when you create a custom wrapper around Mason's request handling mecha‐
372       nism.  This wrapper generally consists of two parts.  The initializa‐
373       tion portion, run at server startup, will load any needed modules and
374       create objects.  The other portion is the "handler()" subroutine, which
375       handles web page requests.
376
377       Writing a Wrapper
378
379       To create a wrapper, you simply need to define a "handler()" subroutine
380       in the package of your choice, and tell mod_perl to use it as a content
381       handler.  The file that defines the "handler()" subroutine can be a
382       module, or you can simply load a simple file that contains this subrou‐
383       tine definition.  The latter solution was, for a long time, the only
384       way to configure Mason, and the file used was traditionally called han‐
385       dler.pl.
386
387       Nowadays, we recommend that you create a custom module in the appropri‐
388       ate namespace and define your "handler()" subroutine there.  The advan‐
389       tage to this approach is that it uses well-known techniques for creat‐
390       ing and installing modules, but it does require a bit more work than
391       simply dropping a script file into the Apache configuration directory.
392       But because the process is better defined, it may "feel" more solid to
393       some folks than the script approach.
394
395       The eg/ directory of the Mason distribution contains a couple sample
396       modules that define "handler()" subroutines.  Let's assume that your
397       module, like the example, defines a "handler()" in the package
398       "MyApp::Mason".  In this case, your Apache configuration would look
399       like this:
400
401         PerlModule  MyApp::Mason
402
403         <LocationMatch ...>
404           SetHandler   perl-script
405           PerlHandler  MyApp::Mason
406         </LocationMatch>
407
408       You may still see references to a handler.pl file in the Mason users
409       list archives, as well as the FAQ.  These references will generally be
410       applicable to any custom code wrapping Mason.
411
412       Wrappers and PerlSetVar-style configuration
413
414       Sometimes people attempt to write a wrapper and configure Mason with
415       "PerlSetVar" directives in their Apache configuration file.  This does
416       not work.  When you give mod_perl this configuration:
417
418         PerlHandler HTML::Mason::ApacheHandler
419
420       it will dispatch directly to the "HTML::Mason::ApacheHandler->han‐
421       dler()" method, without ever executing your wrapper code.  However, you
422       can mix the two methods.  See Mixing httpd.conf Configuration with a
423       Wrapper
424
425       Wrapping with a <Perl> block
426
427       You can also put your wrapper code in a "<Perl>" block as part of your
428       httpd.conf file.  The result is no different than loading a file via
429       the "PerlRequire" directive.
430
431       The Wrapper Code
432
433       Regardless of how you load your wrapper code, it will always work the
434       same way.  The "handler()" subroutine should expect to receive the
435       Apache request object representing the current request.  This request
436       object is used by the ApacheHandler module to determine what component
437       is being called.
438
439       Let's look at the guts of some wrapper code.  Here's a first version:
440
441         package MyApp::Mason;
442
443         use strict;
444         use HTML::Mason::ApacheHandler;
445
446         my $ah =
447             HTML::Mason::ApacheHandler->new
448                 ( comp_root => '/path/to/comp/root',
449                   data_dir  => '/path/to/data/dir' );
450
451         sub handler {
452             my ($r) = @_;
453
454             return $ah->handle_request($r);
455         }
456
457       This wrapper is fully functional, but it doesn't actually do anything
458       you couldn't do more easily by configuring Mason via the httpd.conf
459       file.  However, it does serve as a good skeleton to which additional
460       functionality can easily be added.
461
462       External Modules Revisited
463
464       Since you are loading an arbitrary piece of code to define your wrap‐
465       per, you can easily load other modules needed for your application at
466       the same time.  For example, you might simple add these lines to the
467       wrapper code above:
468
469         {
470             package HTML::Mason::Commands;
471
472             use MIME::Base64;
473         }
474
475       Explicitly setting the package to "HTML::Mason::Commands" makes sure
476       that any symbols that the loaded modules export (constants, subrou‐
477       tines, etc.) get exported into the namespace under which components
478       run.  Of course, if you've changed the component namespace, make sure
479       to change the package name here as well.
480
481       Alternatively, you might consider creating a separate piece of code to
482       load the modules you need.  For example, you might create a module
483       called "MyApp::MasonInit":
484
485         {
486             package HTML::Mason::Commands;
487
488             use Apache::Constants qw(:common);
489             use Apache::URI;
490             use File::Temp;
491         }
492
493         1;
494
495       This can be loaded via a "PerlModule" directive in the httpd.conf file,
496       or in the wrapper code itself via "use".
497
498       Example: Controlling access with component attributes
499
500       An example of something you can only do with wrapper code is deciding
501       at run-time whether a component can be accessed at the top-level based
502       on a complex property of the component.  For example, here's a piece of
503       code that uses the current user and a component's "access_level"
504       attribute to control access:
505
506         sub handler {
507             my ($r) = @_;
508
509             my $req = $ah->prepare_request($r);
510
511             my $comp = $req->request_comp;
512
513             # this is done via magic hand-waving ...
514             my $user = get_user_from_cookie();
515
516             # remember, attributes are inherited so this could come from a
517             # component higher up the inheritance chain
518             my $required_access = $comp->attr('access_level');
519
520             return NOT_FOUND
521                 if $user->access_level < $required_access;
522
523             return $req->exec;
524         }
525
526       Wrappers with Virtual Hosts
527
528       If you had several virtual hosts, each of which had a separate compo‐
529       nent root, you'd need to create a separate ApacheHandler object for
530       each host, one for each host.  Here's some sample code for that:
531
532           my %ah;
533           foreach my $site ( qw( site1 site2 site3 ) ) {
534               $ah{$site} =
535                   HTML::Mason::ApacheHandler->new
536                       ( comp_root => "/usr/local/www/$site",
537                         data_dir => "/usr/local/mason/$site" );
538           }
539
540           sub handler {
541               my ($r) = @_;
542
543               my $site = $r->dir_config('SiteName');
544
545               return DECLINED unless exists $ah{$site};
546
547               return $ah{$site}->handle_request($r);
548           }
549
550       This code assumes that you set the "SiteName" variable via a "PerlSet‐
551       Var" directive in each "VirtualHost" block, like this:
552
553         <VirtualHost site1.example.com>
554           PerlSetVar  SiteName  site1
555
556           <LocationMatch ...>
557             SetHandler   perl-script
558             PerlHandler  MyApp::Mason
559           </LocationMatch>
560         </VirtualHost>
561
562       Creating apachehandler objects on the fly
563
564       You might also consider creating ApacheHandler objects on the fly, like
565       this:
566
567           my %ah;
568           sub handler {
569               my ($r) = @_;
570               my $site = $r->dir_config('SiteName');
571
572               return DECLINED unless $site;
573
574               unless exists($ah{$site}) {
575                   $ah{$site} = HTML::Mason::ApacheHandler->new( ... );
576               }
577
578               $ah{$site}->handle_request($r);
579           }
580
581       This is more flexible but you lose the memory savings of creating all
582       your objects during server startup.
583
584       Other uses for a wrapper
585
586       If you have some code which must always run after a request, then the
587       only way to guarantee that this happens is to wrap the "$ah->han‐
588       dle_request()" call in an "eval {}" block, and then run the needed code
589       after the request returns.  You can then handle errors however you
590       like.
591
592       Mixing httpd.conf Configuration with a Wrapper
593
594       You can take advantage of Mason's httpd.conf configuration system while
595       at the same time providing your own wrapper code.  The key to doing
596       this is not creating your own ApacheHandler object.  Instead, you call
597       the "HTML::Mason::ApacheHandler->handler()" class method from your
598       "handler()" subroutine.  Here's a complete wrapper that does this:
599
600         package MyApp::Mason;
601
602         use strict;
603         use HTML::Mason::ApacheHandler;
604
605         sub handler {
606             my ($r) = @_;
607
608             return HTML::Mason::ApacheHandler->handler($r);
609         }
610
611       The "HTML::Mason::ApacheHandler->handler" method will create an
612       ApacheHandler object based on the configuration directives it finds in
613       your httpd.conf file.  Obviously, this wrapper is again a skeleton, but
614       you could mix and match this wrapper code with any of the code shown
615       above.
616
617       Alternately you could subclass the "HTML::Mason::ApacheHandler" class,
618       and override the "handler()" method it provides.  See the Subclassing
619       documentation for more details.  Of course, you could even create a
620       subclass and write a wrapper that called it.
621

DEVELOPMENT

623       This section describes how to set up common developer features.
624
625       Global Variables
626
627       Global variables can make programs harder to read, maintain, and debug,
628       and this is no less true for Mason components.  Due to the persistent
629       mod_perl environment, globals require extra initialization and cleanup
630       care.
631
632       That said, there are times when it is very useful to make a value
633       available to all Mason components: a DBI database handle, a hash of
634       user session information, the server root for forming absolute URLs.
635
636       Because Mason by default parses components in "strict" mode, you'll
637       need to declare a global if you don't want to access it with an
638       explicit package name. The easiest way to declare a global is with the
639       allow_globals parameter.
640
641       Since all components run in the same package, you'll be able to set the
642       global in one component and access it in all the others.
643
644       Autohandlers are common places to assign values to globals.  Use the
645       "<%once>" section if the global only needs to be initialized at load
646       time, or the "<%init>" section if it needs to be initialized every
647       request.
648
649       Sessions
650
651       Mason does not have a built-in session mechanism, but you can use the
652       "MasonX::Request::WithApacheSession" module, available from CPAN, to
653       add a session to every request.  It can also automatically set and read
654       cookies containing the session id.
655
656       Data Caching
657
658       Data caching is implemented with DeWitt Clinton's "Cache::Cache" mod‐
659       ule.  For full understanding of this section you should read the docu‐
660       mentation for "Cache::Cache" as well as for relevant subclasses (e.g.
661       "Cache::FileCache").
662
663       Cache files
664           By default, "Cache::FileCache" is the subclass used for data
665           caching, although this may be overriden by the developer.
666           "Cache::FileCache" creates a separate subdirectory for every compo‐
667           nent that uses caching, and one file some number of levels under‐
668           neath that subdirectory for each cached item.  The root of the
669           cache tree is data_dir/"cache". The name of the cache subdirectory
670           for a component is determined by the function
671           "HTML::Mason::Utils::data_cache_namespace".
672
673       Default constructor options
674           Ordinarily, when "$m->cache" is called, Mason passes to the cache
675           constructor the "namespace", and "cache_root" options, along with
676           any other options given in the "$m->cache" method.
677
678           You may specify other default constructor options with the
679           data_cache_defaults parameter. For example,
680
681               PerlSetVar  MasonDataCacheDefaults  "cache_class => SizeAwareFileCache"
682               PerlAddVar  MasonDataCacheDefaults  "cache_depth => 2"
683               PerlAddVar  MasonDataCacheDefaults  "default_expires_in => 1 hour"
684
685           Any options passed to individual "$m->cache" calls override these
686           defaults.
687
688       Disabling data caching
689           If for some reason you want to disable data caching entirely, set
690           the default "cache_class" to "NullCache".  This subclass faithfully
691           implements the cache API but never stores data.
692

PERFORMANCE

694       This section explains Mason's various performance enhancements and how
695       to administer them. One of the best ways to maximize performance on
696       your production server is run in static_source mode; see the third sub‐
697       section below.
698
699       Code Cache
700
701       When Mason loads a component, it places it in a memory cache. By
702       default, the cache has no limit, but you can specify a maximum number
703       of components to cache with the code_cache_max_size parameter. In this
704       case, Mason will free up space as needed by discarding components. The
705       discard algorithm is least frequently used (LFU), with a periodic decay
706       to gradually eliminate old frequency information. In a nutshell, the
707       components called most often in recent history should remain in the
708       cache.
709
710       Previous versions of Mason attempted to estimate the size of each com‐
711       ponent, but this proved so inaccurate as to be virtually useless for
712       cache policy. The max size is now specified purely in number of compo‐
713       nents.
714
715       Mason can use certain optimizations with an unlimited cache, especially
716       in conjunction with static_source, so don't limit the cache unless
717       experience shows that your servers are growing too large. Many dynamic
718       sites can be served comfortably with all components in memory.
719
720       You can prepopulate the cache with components that you know will be
721       accessed often; see Preloading Components.  Note that preloaded compo‐
722       nents possess no special status in the cache and can be discarded like
723       any others.
724
725       Naturally, a cache entry is invalidated if the corresponding component
726       source file changes.
727
728       To turn off code caching completely, set code_cache_max_size to 0.
729
730       Object Files
731
732       The in-memory code cache is only useful on a per-process basis.  Each
733       process must build and maintain its own cache. Shared memory caches are
734       conceivable in the future, but even those will not survive between web
735       server restarts.
736
737       As a secondary, longer-term cache mechanism, Mason stores a compiled
738       form of each component in an object file under data_dir/obj. Any server
739       process can eval the object file and save time on parsing the component
740       source file.  The object file is recreated whenever the source file
741       changes.
742
743       The object file pathname is formed from three parts:
744
745       * the compiler object_id - this prevents different versions of Mason or
746       compilers from using the same object file, such as after an upgrade
747       * the component path
748       * object_file_extension, by default ".obj"
749
750       Besides improving performance, object files can be useful for debug‐
751       ging.  If you feel the need to see what your source has been translated
752       into, you can peek inside an object file to see exactly how Mason con‐
753       verted a given component to a Perl object. This was crucial for
754       pre-1.10 Mason, in which error line numbers were based on the object
755       file rather than the source file.
756
757       If for some reason you don't want Mason to create object files, set
758       use_object_files to 0.
759
760       Static Source Mode
761
762       In static_source mode, Mason assumes that the component hierarchy is
763       unchanging and thus does not check source timestamps when using an in-
764       memory cached component or object file. This significantly reduces
765       filesystem stats and other overhead. We've seen speedups by a factor of
766       two or three as a result of this mode, though of course YMMV.
767
768       When in static_source mode, you must remove object files and call
769       $interp->flush_code_cache in order for the server to recognize compo‐
770       nent changes. The easiest way to arrange this is to point
771       static_source_touch_file to a file that can be touched whenever compo‐
772       nents change.
773
774       We highly recommend running in this mode in production if you can man‐
775       age it. Many of Mason's future optimizations will be designed for this
776       mode. On development servers, of course, it makes sense to keep this
777       off so that components are reloaded automatically.
778
779       Disabling Autoflush
780
781       To support the dynamic autoflush feature, Mason has to check for aut‐
782       oflush mode after printing every piece of text.  If you can commit to
783       not using autoflush, setting enable_autoflush to 0 will allow Mason to
784       compile components more efficiently. Consider whether a few well-placed
785       "$m->flush_buffer" calls would be just as good as autoflush.
786
787       Write a handler subroutine
788
789       Writing your own "handler()" subroutine which uses an ApacheHandler
790       object (or objects) created during server startup is slightly faster
791       (around 5% or so) than configuring mason via your httpd.conf file and
792       letting Mason create its own ApacheHandler objects internally.
793
794       Preloading Components
795
796       You can tell Mason to preload a set of components in the parent
797       process, rather than loading them on demand, using the preloads parame‐
798       ter.  Each child server will start with those components loaded in the
799       memory cache. The trade-offs are:
800
801       time
802           a small one-time startup cost, but children save time by not having
803           to load the components
804
805       memory
806           a fatter initial server, but the memory for preloaded components
807           are shared by all children.  This is similar to the advantage of
808           using modules only in the parent process.
809
810       Try to preload components that are used frequently and do not change
811       often.  (If a preloaded component changes, all the children will have
812       to reload it from scratch.)
813
814       Preallocating the Output Buffer
815
816       You can set buffer_preallocate_size to set the size of the preallocated
817       output buffer for each request. This can reduce the number of realloca‐
818       tions Perl performs as components output text.
819

ERROR REPORTING AND EXCEPTIONS

821       When an error occurs, Mason can respond by:
822
823       ·   showing a detailed error message in the browser in HTML.
824
825       ·   die'ing, which sends a 500 status to the browser and lets the error
826           message go to the error logs.
827
828       The first behavior is ideal for development, where you want immediate
829       feedback on the error.  The second behavior is usually desired for pro‐
830       duction so that users are not exposed to messy error messages.  You
831       choose the behavior by setting error_mode to "output" or "fatal"
832       respectively.
833
834       Error formatting is controlled by the error_format parameter.  When
835       showing errors in the browser, Mason defaults to the "html" format.
836       When the error_mode is set to "fatal", the default format is "line",
837       which puts the entire error message on one line in a format suitable
838       for web server error logs.  Mason also offers other formats, which are
839       covered in the Request class documentation.
840
841       Finally, you can use Apache's "ErrorDocument" directive to specify a
842       custom error handler for 500 errors.  In this case, you'd set the
843       error_mode to "fatal".  The URL specified by the "ErrorDocument" direc‐
844       tive could point to a Mason component.
845
846       Exceptions Under the Hood
847
848       The way that Mason really reports errors is through the use of excep‐
849       tion objects, which are implemented with the "Exception::Class" module
850       from CPAN, and some custom code in the HTML::Mason::Exceptions module.
851
852       If, during the execution of a component, execution stops because some
853       code calls "die()", then Mason will catch this exception.  If the
854       exception being thrown is just a string, then it will be converted to
855       an "HTML::Mason::Exception" object.  If the exception being thrown is
856       an object with a "rethrow()" method, then this method will be called.
857       Otherwise, Mason simply leaves the exception untouched and calls
858       "die()" again.
859
860       Calling a Component to Handle Errors
861
862       Returning to the topic of wrapper code that we covered earlier, what if
863       you wanted to handle all request errors by calling an error handling
864       component?  There is no way to do this without wrapper code.  Here's an
865       example "handler()" subroutine that does this:
866
867           sub handler {
868               my ($r) = @_;
869
870               my $return = eval { $ah->handle_request($r) };
871
872               if ( my $err = $@ )
873               {
874                   $r->pnotes( error => $err );
875                   $r->filename( $r->document_root . '/error/500.html' );
876
877                   return $ah->handle_request($r);
878               }
879
880               return $return;
881           }
882
883       First, we wrap our call to "$ah->handle_request()" in an "eval{}"
884       block.  If an error occurs, we store it in the request object using the
885       "$r->pnotes()" method.  Then we change the filename property of the
886       Apache request object to point to our error-handling component and call
887       the "$ah->handle_request()" method again, passing it the altered
888       request object.  We could have put the exception in "$r->args", but we
889       want to leave this untouched so that the error-handling component can
890       see the original arguments.
891
892       Here's what that component error-handling component might look like:
893
894        <html>
895        <head>
896        <title>Error</title>
897        </head>
898
899        <body>
900
901        <p>
902        Looks like our application broke.  Whatever you did, don't do it again!
903        </p>
904
905        <p>
906        If you have further questions, please feel free to contact us at <a
907        href="mailto:support@example.com">support@example.com</a>.
908        </p>
909
910        <p><a href="/">Click here</a> to continue.</p>
911
912        </body>
913        </html>
914
915        <%init>
916         my $error = $r->pnotes('error');
917
918         my $error_text = "Page is " . $r->parsed_uri->unparse . "\n\n";
919
920         $error_text .= UNIVERSAL::can( $error, 'as_text' ) ? $error->as_text : $error;
921
922         $r->log_error($error_text);
923
924         my $mail =
925             MIME::Lite->new
926                 ( From => 'error-handler@example.com',
927                   To   => 'rt@example.com',
928                   Subject => 'Application error',
929                   Data => $error_text,
930                 );
931
932         $r->register_cleanup( sub { $mail->send } );
933        </%init>
934
935        <%flags>
936         inherit => undef
937        </%flags>
938
939       This component does several things.  First of all, it logs the complete
940       error to the Apache error logs, along with the complete URL, including
941       query string, that was requested.  The "$r->parsed_uri()" method that
942       we use above is only available if the "Apache::URI" module has been
943       loaded.
944
945       The component also sends an email containing the error, in this case to
946       an RT installation, so that the error is logged in a bug tracking sys‐
947       tem.  Finally, it displays a less technical error message to the user.
948
949       For this to work properly, you must set error_mode to "fatal", so that
950       Mason doesn't just display its own HTML error page.
951

RUNNING OUTSIDE OF MOD_PERL

953       Although Mason is most commonly used in conjunction with mod_perl, the
954       APIs are flexible enough to use in any environment. Below we describe
955       the two most common alternative environments, CGI and standalone
956       scripts.
957
958       Using Mason from a CGI Script
959
960       The easiest way to use Mason via a CGI script is with the CGIHandler
961       module module.
962
963       Here is a skeleton CGI script that calls a component and sends the out‐
964       put to the browser.
965
966           #!/usr/bin/perl
967           use HTML::Mason::CGIHandler;
968
969           my $h = HTML::Mason::CGIHandler->new
970            (
971             data_dir  => '/home/jethro/code/mason_data',
972            );
973
974           $h->handle_request;
975
976       The relevant portions of the httpd.conf file look like:
977
978           DocumentRoot /path/to/comp/root
979           ScriptAlias /cgi-bin/ /path/to/cgi-bin/
980
981           <LocationMatch "\.html$">
982              Action html-mason /cgi-bin/mason_handler.cgi
983              AddHandler html-mason .html
984           </LocationMatch>
985           <LocationMatch "^/cgi-bin/">
986               RemoveHandler .html
987           </LocationMatch>
988           <FilesMatch "(autohandler⎪dhandler)$">
989               Order allow,deny
990               Deny from all
991           </FilesMatch>
992
993       This simply causes Apache to call the mason_handler.cgi script every
994       time a URL ending in ".html" under the component root is requested.
995
996       To exclude certian directories from being under Mason control, you can
997       use something like the following:
998
999           <LocationMatch "^/(dir1⎪dir2⎪dir3)/">
1000               RemoveHandler .html
1001           </LocationMatch>
1002
1003       This script uses the CGIHandler class to do most of the heavy lifting.
1004       See that class's documentation for more details.
1005
1006       Using Mason from a Standalone Script
1007
1008       Mason can be used as a pure text templating solution -- like Text::Tem‐
1009       plate and its brethren, but with more power (and of course more com‐
1010       plexity).
1011
1012       Here is a bare-bones script that calls a component file and sends the
1013       result to standard output:
1014
1015           #!/usr/bin/perl
1016           use HTML::Mason;
1017           use strict;
1018
1019           my $interp = HTML::Mason::Interp->new ();
1020           $interp->exec(<relative path to file>, <args>...);
1021
1022       Because no component root was specified, the root is set to your cur‐
1023       rent working directory.  If you have a well defined and contained com‐
1024       ponent tree, you'll probably want to specify a component root.
1025
1026       Because no data directory was specified, object files will not be cre‐
1027       ated and data caching will not work in the default manner. If perfor‐
1028       mance is an issue, you will want to specify a data directory.
1029
1030       Here's a slightly fuller script that specifies a component root and
1031       data directory, and captures the result in a variable rather than send‐
1032       ing to standard output:
1033
1034           #!/usr/bin/perl
1035           use HTML::Mason;
1036           use strict;
1037
1038           my $outbuf;
1039           my $interp = HTML::Mason::Interp->new
1040               (comp_root  => '/path/to/comp_root',
1041                data_dir   => '/path/to/data_dir',
1042                out_method => \$outbuf
1043               );
1044           $interp->exec(<component-path>, <args>...);
1045
1046           # Do something with $outbuf
1047

AUTHORS

1049       Jonathan Swartz <swartz@pobox.com>, Dave Rolsky <autarch@urth.org>, Ken
1050       Williams <ken@mathforum.org>
1051

SEE ALSO

1053       HTML::Mason, HTML::Mason::Interp, HTML::Mason::ApacheHandler,
1054       HTML::Mason::Lexer, HTML::Mason::Compiler
1055
1056
1057
1058perl v5.8.8                       2007-04-17             HTML::Mason::Admin(3)
Impressum